initial
This commit is contained in:
251
api/handler/data.go
Normal file
251
api/handler/data.go
Normal file
@ -0,0 +1,251 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"git.icod.de/dalu/refdata/api/repo"
|
||||
"git.icod.de/dalu/refdata/model"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (h *Handler) DataRoutes(api *gin.RouterGroup) {
|
||||
dataRoutes := api.Group("/data")
|
||||
dataRoutes.GET("/", h.FindData)
|
||||
dataRoutes.POST("/", h.CreateData)
|
||||
dataRoutes.PUT("/:id", h.UpdateData)
|
||||
dataRoutes.DELETE("/:id", h.RemoveData)
|
||||
}
|
||||
|
||||
func (h *Handler) FindData(cx *gin.Context) {
|
||||
switch cx.Query("response_type") {
|
||||
case "list":
|
||||
h.ListData(cx)
|
||||
case "one":
|
||||
h.GetData(cx)
|
||||
default:
|
||||
cx.AbortWithStatus(400)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) ListData(cx *gin.Context) {
|
||||
p := new(repo.DataListParams)
|
||||
|
||||
startQuery := cx.Query("start")
|
||||
if startQuery != "" {
|
||||
start, e := strconv.Atoi(startQuery)
|
||||
if e != nil {
|
||||
cx.AbortWithStatus(400)
|
||||
return
|
||||
}
|
||||
p.Start = start
|
||||
}
|
||||
|
||||
limitQuery := cx.Query("limit")
|
||||
if limitQuery != "" {
|
||||
limit, e := strconv.Atoi(limitQuery)
|
||||
if e != nil {
|
||||
cx.AbortWithStatus(400)
|
||||
return
|
||||
}
|
||||
p.Limit = limit
|
||||
}
|
||||
p.Sort = cx.Query("sort")
|
||||
|
||||
name := cx.Query("name")
|
||||
address := cx.Query("address")
|
||||
location := cx.Query("location")
|
||||
age := cx.Query("age")
|
||||
price := cx.Query("price")
|
||||
|
||||
// string
|
||||
if name == "1" {
|
||||
p.Name = true
|
||||
p.NameQuery = repo.DataNameQuery{}
|
||||
p.NameQuery.Operation = cx.Query("name.operation")
|
||||
p.NameQuery.Query = cx.Query("name.query")
|
||||
p.NameQuery.Options = cx.Query("name.options")
|
||||
}
|
||||
|
||||
// string
|
||||
if address == "1" {
|
||||
p.Address = true
|
||||
p.AddressQuery = repo.DataAddressQuery{}
|
||||
p.AddressQuery.Operation = cx.Query("address.operation")
|
||||
p.AddressQuery.Query = cx.Query("address.query")
|
||||
p.AddressQuery.Options = cx.Query("address.options")
|
||||
}
|
||||
|
||||
// string
|
||||
if location == "1" {
|
||||
p.Location = true
|
||||
p.LocationQuery = repo.DataLocationQuery{}
|
||||
p.LocationQuery.Operation = cx.Query("location.operation")
|
||||
p.LocationQuery.Query = cx.Query("location.query")
|
||||
p.LocationQuery.Options = cx.Query("location.options")
|
||||
}
|
||||
|
||||
if age == "1" {
|
||||
p.Age = true
|
||||
p.AgeQuery = repo.DataAgeQuery{}
|
||||
p.AgeQuery.Operation = cx.Query("age.operation")
|
||||
|
||||
from, e := strconv.ParseInt(cx.Query("age.from"), 10, 64)
|
||||
if e != nil {
|
||||
cx.AbortWithStatus(400)
|
||||
return
|
||||
}
|
||||
to, e := strconv.ParseInt(cx.Query("age.from"), 10, 64)
|
||||
if e != nil {
|
||||
cx.AbortWithStatus(400)
|
||||
return
|
||||
}
|
||||
p.AgeQuery.From = from
|
||||
p.AgeQuery.To = to
|
||||
}
|
||||
|
||||
if price == "1" {
|
||||
p.Price = true
|
||||
p.PriceQuery = repo.DataPriceQuery{}
|
||||
from, e := strconv.ParseFloat(cx.Query("age.from"), 64)
|
||||
if e != nil {
|
||||
cx.AbortWithStatus(400)
|
||||
return
|
||||
}
|
||||
to, e := strconv.ParseFloat(cx.Query("age.from"), 64)
|
||||
if e != nil {
|
||||
cx.AbortWithStatus(400)
|
||||
return
|
||||
}
|
||||
p.PriceQuery.From = from
|
||||
p.PriceQuery.To = to
|
||||
}
|
||||
|
||||
m, e := h.dataRepo.List(p)
|
||||
if e != nil {
|
||||
cx.AbortWithError(500, e)
|
||||
return
|
||||
}
|
||||
cx.SecureJSON(200, m)
|
||||
}
|
||||
|
||||
func (h *Handler) GetData(cx *gin.Context) {
|
||||
p := new(repo.DataGetParams)
|
||||
|
||||
id := cx.Query("id")
|
||||
name := cx.Query("name")
|
||||
address := cx.Query("address")
|
||||
location := cx.Query("location")
|
||||
age := cx.Query("age")
|
||||
price := cx.Query("price")
|
||||
|
||||
// id
|
||||
if id == "1" {
|
||||
p.Id = true
|
||||
p.IdQuery = repo.DataIdQuery{}
|
||||
p.IdQuery.Id = cx.Query("id.query")
|
||||
}
|
||||
|
||||
// string
|
||||
if name == "1" {
|
||||
p.Name = true
|
||||
p.NameQuery = repo.DataNameQuery{}
|
||||
p.NameQuery.Operation = cx.Query("name.operation")
|
||||
p.NameQuery.Query = cx.Query("name.query")
|
||||
p.NameQuery.Options = cx.Query("name.options")
|
||||
}
|
||||
|
||||
// string
|
||||
if address == "1" {
|
||||
p.Address = true
|
||||
p.AddressQuery = repo.DataAddressQuery{}
|
||||
p.AddressQuery.Operation = cx.Query("address.operation")
|
||||
p.AddressQuery.Query = cx.Query("address.query")
|
||||
p.AddressQuery.Options = cx.Query("address.options")
|
||||
}
|
||||
|
||||
// string
|
||||
if location == "1" {
|
||||
p.Location = true
|
||||
p.LocationQuery = repo.DataLocationQuery{}
|
||||
p.LocationQuery.Operation = cx.Query("location.operation")
|
||||
p.LocationQuery.Query = cx.Query("location.query")
|
||||
p.LocationQuery.Options = cx.Query("location.options")
|
||||
}
|
||||
|
||||
// int64
|
||||
if age == "1" {
|
||||
p.Age = true
|
||||
p.AgeQuery = repo.DataAgeQuery{}
|
||||
p.AgeQuery.Operation = cx.Query("age.operation")
|
||||
|
||||
from, e := strconv.ParseInt(cx.Query("age.from"), 10, 64)
|
||||
if e != nil {
|
||||
cx.AbortWithStatus(400)
|
||||
return
|
||||
}
|
||||
to, e := strconv.ParseInt(cx.Query("age.from"), 10, 64)
|
||||
if e != nil {
|
||||
cx.AbortWithStatus(400)
|
||||
return
|
||||
}
|
||||
p.AgeQuery.From = from
|
||||
p.AgeQuery.To = to
|
||||
}
|
||||
|
||||
// float64
|
||||
if price == "1" {
|
||||
p.Price = true
|
||||
p.PriceQuery = repo.DataPriceQuery{}
|
||||
from, e := strconv.ParseFloat(cx.Query("age.from"), 64)
|
||||
if e != nil {
|
||||
cx.AbortWithStatus(400)
|
||||
return
|
||||
}
|
||||
to, e := strconv.ParseFloat(cx.Query("age.from"), 64)
|
||||
if e != nil {
|
||||
cx.AbortWithStatus(400)
|
||||
return
|
||||
}
|
||||
p.PriceQuery.From = from
|
||||
p.PriceQuery.To = to
|
||||
}
|
||||
|
||||
m, e := h.dataRepo.Get(p)
|
||||
if e != nil {
|
||||
cx.AbortWithError(500, e)
|
||||
return
|
||||
}
|
||||
cx.SecureJSON(200, m)
|
||||
}
|
||||
|
||||
func (h *Handler) CreateData(cx *gin.Context) {
|
||||
m := new(model.Data)
|
||||
if e := cx.BindJSON(m); e != nil {
|
||||
return
|
||||
}
|
||||
if e := h.dataRepo.Create(m); e != nil {
|
||||
cx.AbortWithError(500, e)
|
||||
return
|
||||
}
|
||||
cx.SecureJSON(201, map[string]interface{}{})
|
||||
}
|
||||
|
||||
func (h *Handler) UpdateData(cx *gin.Context) {
|
||||
m := new(model.Data)
|
||||
if e := cx.BindJSON(m); e != nil {
|
||||
return
|
||||
}
|
||||
if e := h.dataRepo.UpdateId(cx.Param("id"), m); e != nil {
|
||||
cx.AbortWithError(500, e)
|
||||
return
|
||||
}
|
||||
cx.SecureJSON(200, map[string]interface{}{})
|
||||
}
|
||||
|
||||
func (h *Handler) RemoveData(cx *gin.Context) {
|
||||
if e := h.dataRepo.RemoveId(cx.Param("id")); e != nil {
|
||||
cx.AbortWithError(500, e)
|
||||
return
|
||||
}
|
||||
cx.SecureJSON(200, map[string]interface{}{})
|
||||
}
|
13
api/handler/handler.go
Normal file
13
api/handler/handler.go
Normal file
@ -0,0 +1,13 @@
|
||||
package handler
|
||||
|
||||
import "git.icod.de/dalu/refdata/api/repo"
|
||||
|
||||
type Handler struct {
|
||||
dataRepo *repo.DataRepository
|
||||
}
|
||||
|
||||
func NewHandler(dataRepo *repo.DataRepository) *Handler {
|
||||
h := new(Handler)
|
||||
h.dataRepo = dataRepo
|
||||
return h
|
||||
}
|
383
api/repo/data.go
Normal file
383
api/repo/data.go
Normal file
@ -0,0 +1,383 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.icod.de/dalu/refdata/model"
|
||||
"github.com/globalsign/mgo"
|
||||
"github.com/globalsign/mgo/bson"
|
||||
)
|
||||
|
||||
//
|
||||
type DataIdQuery struct {
|
||||
Id string
|
||||
}
|
||||
|
||||
// string
|
||||
type DataNameQuery struct {
|
||||
Operation string
|
||||
Query string
|
||||
Options string
|
||||
}
|
||||
|
||||
// string
|
||||
type DataAddressQuery struct {
|
||||
Operation string
|
||||
Query string
|
||||
Options string
|
||||
}
|
||||
|
||||
// string
|
||||
type DataLocationQuery struct {
|
||||
Operation string
|
||||
Query string
|
||||
Options string
|
||||
}
|
||||
|
||||
// int
|
||||
type DataAgeQuery struct {
|
||||
Operation string
|
||||
From int64
|
||||
To int64
|
||||
}
|
||||
|
||||
// float64
|
||||
type DataPriceQuery struct {
|
||||
Operation string
|
||||
From float64
|
||||
To float64
|
||||
}
|
||||
|
||||
type DataListParams struct {
|
||||
Start int
|
||||
Limit int
|
||||
Sort string
|
||||
|
||||
Name bool
|
||||
Address bool
|
||||
Location bool
|
||||
Age bool
|
||||
Price bool
|
||||
|
||||
NameQuery DataNameQuery
|
||||
AddressQuery DataAddressQuery
|
||||
LocationQuery DataLocationQuery
|
||||
AgeQuery DataAgeQuery
|
||||
PriceQuery DataPriceQuery
|
||||
}
|
||||
|
||||
type DataGetParams struct {
|
||||
Id bool
|
||||
Name bool
|
||||
Address bool
|
||||
Location bool
|
||||
Age bool
|
||||
Price bool
|
||||
|
||||
IdQuery DataIdQuery
|
||||
NameQuery DataNameQuery
|
||||
AddressQuery DataAddressQuery
|
||||
LocationQuery DataLocationQuery
|
||||
AgeQuery DataAgeQuery
|
||||
PriceQuery DataPriceQuery
|
||||
}
|
||||
|
||||
type DataRepository struct {
|
||||
ms *mgo.Session
|
||||
|
||||
database string
|
||||
collection string
|
||||
}
|
||||
|
||||
func NewDataRepository(ms *mgo.Session, db, c string) *DataRepository {
|
||||
r := new(DataRepository)
|
||||
r.ms = ms.Clone()
|
||||
r.database = db
|
||||
r.collection = c
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *DataRepository) Close() {
|
||||
r.ms.Close()
|
||||
}
|
||||
|
||||
func (r *DataRepository) List(p *DataListParams) ([]*model.Data, error) {
|
||||
ms := r.ms.Copy()
|
||||
defer ms.Close()
|
||||
|
||||
c := ms.DB(r.database).C(r.collection)
|
||||
|
||||
q := bson.M{}
|
||||
|
||||
// string
|
||||
if p.Name {
|
||||
switch p.NameQuery.Operation {
|
||||
case "eq":
|
||||
q["name"] = p.NameQuery.Query
|
||||
case "regex":
|
||||
q["name"] = bson.RegEx{Pattern: p.NameQuery.Query, Options: p.NameQuery.Options}
|
||||
}
|
||||
}
|
||||
|
||||
// string
|
||||
if p.Address {
|
||||
switch p.AddressQuery.Operation {
|
||||
case "eq":
|
||||
q["address"] = p.AddressQuery.Query
|
||||
case "regex":
|
||||
q["address"] = bson.RegEx{Pattern: p.AddressQuery.Query, Options: p.AddressQuery.Options}
|
||||
}
|
||||
}
|
||||
|
||||
// int64
|
||||
if p.Age {
|
||||
switch p.AgeQuery.Operation {
|
||||
case "eq":
|
||||
q["age"] = p.AgeQuery.From
|
||||
case "gt-lt":
|
||||
q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lt": p.AgeQuery.To}
|
||||
case "gte-lte":
|
||||
q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lte": p.AgeQuery.To}
|
||||
case "gte-lt":
|
||||
q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lt": p.AgeQuery.To}
|
||||
case "gt-lte":
|
||||
q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lte": p.AgeQuery.To}
|
||||
}
|
||||
}
|
||||
|
||||
// string
|
||||
if p.Location {
|
||||
switch p.LocationQuery.Operation {
|
||||
case "eq":
|
||||
q["address"] = p.LocationQuery.Query
|
||||
case "regex":
|
||||
q["address"] = bson.RegEx{Pattern: p.LocationQuery.Query, Options: p.LocationQuery.Options}
|
||||
}
|
||||
}
|
||||
|
||||
if p.Price {
|
||||
switch p.PriceQuery.Operation {
|
||||
case "eq":
|
||||
q["age"] = p.PriceQuery.From
|
||||
case "gt-lt":
|
||||
q["age"] = bson.M{"$gt": p.PriceQuery.From, "$lt": p.PriceQuery.To}
|
||||
case "gte-lte":
|
||||
q["age"] = bson.M{"$gte": p.PriceQuery.From, "$lte": p.PriceQuery.To}
|
||||
case "gte-lt":
|
||||
q["age"] = bson.M{"$gte": p.PriceQuery.From, "$lt": p.PriceQuery.To}
|
||||
case "gt-lte":
|
||||
q["age"] = bson.M{"$gt": p.PriceQuery.From, "$lte": p.PriceQuery.To}
|
||||
}
|
||||
}
|
||||
|
||||
var m []*model.Data
|
||||
rq := c.Find(q)
|
||||
|
||||
if p.Sort != "" {
|
||||
rq = rq.Sort(p.Sort)
|
||||
}
|
||||
|
||||
if p.Start > 0 && p.Limit > 0 {
|
||||
rq = rq.Skip(p.Start).Limit(p.Limit)
|
||||
} else if p.Start > 0 && p.Limit < 1 {
|
||||
rq = rq.Skip(p.Start)
|
||||
} else if p.Start < 1 && p.Limit > 0 {
|
||||
rq = rq.Limit(p.Limit)
|
||||
}
|
||||
|
||||
if e := rq.All(&m); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (r *DataRepository) Get(p *DataGetParams) (*model.Data, error) {
|
||||
ms := r.ms.Copy()
|
||||
defer ms.Close()
|
||||
|
||||
c := ms.DB(r.database).C(r.collection)
|
||||
|
||||
q := bson.M{}
|
||||
|
||||
// id
|
||||
if p.Id {
|
||||
q["_id"] = bson.ObjectIdHex(p.IdQuery.Id)
|
||||
}
|
||||
|
||||
// string
|
||||
if p.Name {
|
||||
switch p.NameQuery.Operation {
|
||||
case "eq":
|
||||
q["name"] = p.NameQuery.Query
|
||||
case "regex":
|
||||
q["name"] = bson.RegEx{Pattern: p.NameQuery.Query, Options: p.NameQuery.Options}
|
||||
}
|
||||
}
|
||||
|
||||
// string
|
||||
if p.Address {
|
||||
switch p.AddressQuery.Operation {
|
||||
case "eq":
|
||||
q["address"] = p.AddressQuery.Query
|
||||
case "regex":
|
||||
q["address"] = bson.RegEx{Pattern: p.AddressQuery.Query, Options: p.AddressQuery.Options}
|
||||
}
|
||||
}
|
||||
|
||||
// int64
|
||||
if p.Age {
|
||||
switch p.AgeQuery.Operation {
|
||||
case "eq":
|
||||
q["age"] = p.AgeQuery.From
|
||||
case "gt-lt":
|
||||
q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lt": p.AgeQuery.To}
|
||||
case "gte-lte":
|
||||
q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lte": p.AgeQuery.To}
|
||||
case "gte-lt":
|
||||
q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lt": p.AgeQuery.To}
|
||||
case "gt-lte":
|
||||
q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lte": p.AgeQuery.To}
|
||||
}
|
||||
}
|
||||
|
||||
// string
|
||||
if p.Location {
|
||||
switch p.LocationQuery.Operation {
|
||||
case "eq":
|
||||
q["address"] = p.LocationQuery.Query
|
||||
case "regex":
|
||||
q["address"] = bson.RegEx{Pattern: p.LocationQuery.Query, Options: p.LocationQuery.Options}
|
||||
}
|
||||
}
|
||||
|
||||
if p.Price {
|
||||
switch p.PriceQuery.Operation {
|
||||
case "eq":
|
||||
q["age"] = p.PriceQuery.From
|
||||
case "gt-lt":
|
||||
q["age"] = bson.M{"$gt": p.PriceQuery.From, "$lt": p.PriceQuery.To}
|
||||
case "gte-lte":
|
||||
q["age"] = bson.M{"$gte": p.PriceQuery.From, "$lte": p.PriceQuery.To}
|
||||
case "gte-lt":
|
||||
q["age"] = bson.M{"$gte": p.PriceQuery.From, "$lt": p.PriceQuery.To}
|
||||
case "gt-lte":
|
||||
q["age"] = bson.M{"$gt": p.PriceQuery.From, "$lte": p.PriceQuery.To}
|
||||
}
|
||||
}
|
||||
|
||||
m := new(model.Data)
|
||||
rq := c.Find(q)
|
||||
|
||||
if e := rq.All(m); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (r *DataRepository) GetCount(p *DataGetParams) (int, error) {
|
||||
ms := r.ms.Copy()
|
||||
defer ms.Close()
|
||||
|
||||
c := ms.DB(r.database).C(r.collection)
|
||||
|
||||
q := bson.M{}
|
||||
|
||||
// id
|
||||
if p.Id {
|
||||
q["_id"] = bson.ObjectIdHex(p.IdQuery.Id)
|
||||
}
|
||||
|
||||
// string
|
||||
if p.Name {
|
||||
switch p.NameQuery.Operation {
|
||||
case "eq":
|
||||
q["name"] = p.NameQuery.Query
|
||||
case "regex":
|
||||
q["name"] = bson.RegEx{Pattern: p.NameQuery.Query, Options: p.NameQuery.Options}
|
||||
}
|
||||
}
|
||||
|
||||
// string
|
||||
if p.Address {
|
||||
switch p.AddressQuery.Operation {
|
||||
case "eq":
|
||||
q["address"] = p.AddressQuery.Query
|
||||
case "regex":
|
||||
q["address"] = bson.RegEx{Pattern: p.AddressQuery.Query, Options: p.AddressQuery.Options}
|
||||
}
|
||||
}
|
||||
|
||||
// int64
|
||||
if p.Age {
|
||||
switch p.AgeQuery.Operation {
|
||||
case "eq":
|
||||
q["age"] = p.AgeQuery.From
|
||||
case "gt-lt":
|
||||
q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lt": p.AgeQuery.To}
|
||||
case "gte-lte":
|
||||
q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lte": p.AgeQuery.To}
|
||||
case "gte-lt":
|
||||
q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lt": p.AgeQuery.To}
|
||||
case "gt-lte":
|
||||
q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lte": p.AgeQuery.To}
|
||||
}
|
||||
}
|
||||
|
||||
// string
|
||||
if p.Location {
|
||||
switch p.LocationQuery.Operation {
|
||||
case "eq":
|
||||
q["address"] = p.LocationQuery.Query
|
||||
case "regex":
|
||||
q["address"] = bson.RegEx{Pattern: p.LocationQuery.Query, Options: p.LocationQuery.Options}
|
||||
}
|
||||
}
|
||||
|
||||
if p.Price {
|
||||
switch p.PriceQuery.Operation {
|
||||
case "eq":
|
||||
q["age"] = p.PriceQuery.From
|
||||
case "gt-lt":
|
||||
q["age"] = bson.M{"$gt": p.PriceQuery.From, "$lt": p.PriceQuery.To}
|
||||
case "gte-lte":
|
||||
q["age"] = bson.M{"$gte": p.PriceQuery.From, "$lte": p.PriceQuery.To}
|
||||
case "gte-lt":
|
||||
q["age"] = bson.M{"$gte": p.PriceQuery.From, "$lt": p.PriceQuery.To}
|
||||
case "gt-lte":
|
||||
q["age"] = bson.M{"$gt": p.PriceQuery.From, "$lte": p.PriceQuery.To}
|
||||
}
|
||||
}
|
||||
|
||||
rq := c.Find(q)
|
||||
return rq.Count()
|
||||
}
|
||||
|
||||
func (r *DataRepository) Create(m *model.Data) error {
|
||||
ms := r.ms.Copy()
|
||||
defer ms.Close()
|
||||
c := ms.DB(r.database).C(r.collection)
|
||||
return c.Insert(m)
|
||||
}
|
||||
|
||||
func (r *DataRepository) UpdateId(id string, m *model.Data) error {
|
||||
if !bson.IsObjectIdHex(id) {
|
||||
return errors.New(fmt.Sprintf("%s is not an ObjectId", id))
|
||||
}
|
||||
ms := r.ms.Copy()
|
||||
defer ms.Close()
|
||||
c := ms.DB(r.database).C(r.collection)
|
||||
return c.UpdateId(bson.ObjectIdHex(id), m)
|
||||
}
|
||||
|
||||
func (r *DataRepository) RemoveId(id string) error {
|
||||
if !bson.IsObjectIdHex(id) {
|
||||
return errors.New(fmt.Sprintf("%s is not an ObjectId", id))
|
||||
}
|
||||
ms := r.ms.Copy()
|
||||
defer ms.Close()
|
||||
c := ms.DB(r.database).C(r.collection)
|
||||
return c.RemoveId(bson.ObjectIdHex(id))
|
||||
}
|
Reference in New Issue
Block a user