first commit
This commit is contained in:
commit
e7038a44e9
10
README.md
Normal file
10
README.md
Normal file
@ -0,0 +1,10 @@
|
||||
## mdbc
|
||||
|
||||
mdbc: mongodb database connector
|
||||
|
||||
项目命名为mdbc 一个mongodb数据库orm,对官方驱动进行封装,将protobuf的Message和mongodb的Collection进行绑定,实现对Message的操作可以同步到数据库中
|
||||
|
||||
## todo
|
||||
|
||||
- [ ] 完成初始化程序
|
||||
- [ ] 封装CRUD
|
35
autogen_model_model.go
Normal file
35
autogen_model_model.go
Normal file
@ -0,0 +1,35 @@
|
||||
// Code generated by protoc-gen-coco. DO NOT EDIT.
|
||||
// source: model.proto
|
||||
// generate at: 2023-06-18 18:16:24
|
||||
|
||||
package mdbc
|
||||
|
||||
const TableNameModelArticles = "articles"
|
||||
|
||||
func (t *ModelArticles) TableName() string {
|
||||
return "articles"
|
||||
}
|
||||
|
||||
func (m *ModelArticles) GetIdField() string {
|
||||
return "_id"
|
||||
}
|
||||
|
||||
func (m *ModelArticles) GetTitleField() string {
|
||||
return "title"
|
||||
}
|
||||
|
||||
func (m *ModelArticles) GetAvatarUrlField() string {
|
||||
return "avatar_url"
|
||||
}
|
||||
|
||||
func (m *ModelArticles) GetPhoneField() string {
|
||||
return "phone"
|
||||
}
|
||||
|
||||
func (m *ModelArticles) GetCreateTimeField() string {
|
||||
return "create_time"
|
||||
}
|
||||
|
||||
func (m *ModelArticles) GetUpdateTimeField() string {
|
||||
return "update_time"
|
||||
}
|
71
count.go
Normal file
71
count.go
Normal file
@ -0,0 +1,71 @@
|
||||
package mdbc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type countScope struct {
|
||||
*scope
|
||||
*mdbc
|
||||
ctx context.Context
|
||||
limit int64
|
||||
skip int64
|
||||
filter interface{}
|
||||
opts options.CountOptions
|
||||
}
|
||||
|
||||
// SetContext set operate context, default timeout 30s
|
||||
func (cs *countScope) SetContext(ctx context.Context) *countScope {
|
||||
cs.ctx = ctx
|
||||
return cs
|
||||
}
|
||||
|
||||
// SetLimit set filter limit size
|
||||
func (cs *countScope) SetLimit(limit int64) *countScope {
|
||||
cs.limit = limit
|
||||
return cs
|
||||
}
|
||||
|
||||
// SetSkip set filter skip size
|
||||
func (cs *countScope) SetSkip(skip int64) *countScope {
|
||||
cs.skip = skip
|
||||
return cs
|
||||
}
|
||||
|
||||
func (cs *countScope) SetFilter(filter interface{}) *countScope {
|
||||
if filter == nil {
|
||||
cs.filter = bson.M{}
|
||||
return cs
|
||||
}
|
||||
v := reflect.ValueOf(filter)
|
||||
if v.Kind() == reflect.Ptr || v.Kind() == reflect.Map || v.Kind() == reflect.Slice {
|
||||
if v.IsNil() {
|
||||
cs.filter = bson.M{}
|
||||
}
|
||||
}
|
||||
cs.filter = filter
|
||||
return cs
|
||||
}
|
||||
|
||||
func (cs *countScope) mergeOptions() {
|
||||
if cs.ctx == nil {
|
||||
cs.ctx = context.Background()
|
||||
}
|
||||
if cs.filter == nil {
|
||||
cs.filter = bson.M{}
|
||||
}
|
||||
if cs.skip != 0 {
|
||||
cs.opts.Skip = &cs.skip
|
||||
}
|
||||
if cs.limit != 0 {
|
||||
cs.opts.Limit = &cs.limit
|
||||
}
|
||||
}
|
||||
|
||||
func (cs *countScope) Count() (int64, error) {
|
||||
cs.mergeOptions()
|
||||
return cs.database.Collection(cs.tableName).CountDocuments(cs.ctx, cs.filter, &cs.opts)
|
||||
}
|
25
drop.go
Normal file
25
drop.go
Normal file
@ -0,0 +1,25 @@
|
||||
package mdbc
|
||||
|
||||
import "context"
|
||||
|
||||
type dropScope struct {
|
||||
*scope
|
||||
*mdbc
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func (ds *dropScope) SetContext(ctx context.Context) *dropScope {
|
||||
ds.ctx = ctx
|
||||
return ds
|
||||
}
|
||||
|
||||
func (ds *dropScope) mergeOptions() {
|
||||
if ds.ctx == nil {
|
||||
ds.ctx = context.Background()
|
||||
}
|
||||
}
|
||||
|
||||
func (ds *dropScope) Do() error {
|
||||
ds.mergeOptions()
|
||||
return ds.database.Collection(ds.tableName).Drop(ds.ctx)
|
||||
}
|
13
errors.go
Normal file
13
errors.go
Normal file
@ -0,0 +1,13 @@
|
||||
package mdbc
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrorRecordNotFound = errors.New("record not found")
|
||||
ErrorNoInsertDocuments = errors.New("no insert documents")
|
||||
)
|
||||
|
||||
// IsRecordNotFound is record not found
|
||||
func IsRecordNotFound(err error) bool {
|
||||
return errors.Is(err, ErrorRecordNotFound)
|
||||
}
|
30
go.mod
Normal file
30
go.mod
Normal file
@ -0,0 +1,30 @@
|
||||
module gitter.top/coco/mdbc
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.7.0
|
||||
gitter.top/coco/lormatter v0.0.0-20230409145644-f9cb43f740dc
|
||||
gitter.top/common/goref v0.0.0-20230622151024-9b220e13c7cd
|
||||
go.mongodb.org/mongo-driver v1.11.7
|
||||
google.golang.org/protobuf v1.30.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.3 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
77
go.sum
Normal file
77
go.sum
Normal file
@ -0,0 +1,77 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
|
||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
|
||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
gitter.top/coco/lormatter v0.0.0-20230409145644-f9cb43f740dc h1:B0bnfX8Y/dETV+zdcZNCwD/L+DLZN2wSf9szo/fxNCw=
|
||||
gitter.top/coco/lormatter v0.0.0-20230409145644-f9cb43f740dc/go.mod h1:vyfU6MQ56tkoFKSzEzhYSwXjgZHMcu3AViHC3hIyO7I=
|
||||
gitter.top/common/goref v0.0.0-20230622151024-9b220e13c7cd h1:EeOtSwGexcx0u1AE91wnemiOGedENxaKcJUXxpzcgiE=
|
||||
gitter.top/common/goref v0.0.0-20230622151024-9b220e13c7cd/go.mod h1:oK6jZQ/ISS8gZ78rvww6p7FuLUzaJ+S5F5UXSqO7Lr0=
|
||||
go.mongodb.org/mongo-driver v1.11.7 h1:LIwYxASDLGUg/8wOhgOOZhX8tQa/9tgZPgzZoVqJvcs=
|
||||
go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
26
indexes.go
Normal file
26
indexes.go
Normal file
@ -0,0 +1,26 @@
|
||||
package mdbc
|
||||
|
||||
import "context"
|
||||
|
||||
type indexesScope struct {
|
||||
*scope
|
||||
*mdbc
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func (is *indexesScope) SetContext(ctx context.Context) *indexesScope {
|
||||
is.ctx = ctx
|
||||
return is
|
||||
}
|
||||
|
||||
func (is *indexesScope) Create(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (is *indexesScope) Drop(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (is *indexesScope) List(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
103
insert.go
Normal file
103
insert.go
Normal file
@ -0,0 +1,103 @@
|
||||
package mdbc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gitter.top/common/goref"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type insertScope struct {
|
||||
*scope
|
||||
*mdbc
|
||||
ctx context.Context
|
||||
opts any
|
||||
docs any
|
||||
}
|
||||
|
||||
type insert interface {
|
||||
insert(docs any) (*InsertResult, error)
|
||||
}
|
||||
|
||||
type insertOne struct {
|
||||
*insertScope
|
||||
}
|
||||
|
||||
func (io *insertOne) insert(docs any) (*InsertResult, error) {
|
||||
result, err := io.database.Collection(io.tableName).InsertOne(io.ctx, docs, io.opts.(*options.InsertOneOptions))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &InsertResult{id: result.InsertedID}, nil
|
||||
}
|
||||
|
||||
type insertMany struct {
|
||||
*insertScope
|
||||
}
|
||||
|
||||
func (im *insertMany) insert(docs any) (*InsertResult, error) {
|
||||
vals, ok := goref.ToInterfaces(docs)
|
||||
if !ok {
|
||||
return nil, ErrorNoInsertDocuments
|
||||
}
|
||||
result, err := im.database.Collection(im.tableName).InsertMany(im.ctx, vals, im.opts.(*options.InsertManyOptions))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &InsertResult{id: result.InsertedIDs}, nil
|
||||
}
|
||||
|
||||
type InsertResult struct {
|
||||
id interface{}
|
||||
}
|
||||
|
||||
func (ir *InsertResult) GetID() string {
|
||||
val, ok := goref.ToString(ir.id)
|
||||
if !ok {
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func (ir *InsertResult) GetIDs() []string {
|
||||
vals, ok := goref.ToStrings(ir.id)
|
||||
if !ok {
|
||||
}
|
||||
return vals
|
||||
}
|
||||
|
||||
func (is *insertScope) SetContext(ctx context.Context) *insertScope {
|
||||
is.ctx = ctx
|
||||
return is
|
||||
}
|
||||
|
||||
func (is *insertScope) SetInsertOneOptions(opts options.InsertOneOptions) *insertScope {
|
||||
is.opts = opts
|
||||
return is
|
||||
}
|
||||
|
||||
func (is *insertScope) SetInsertManyOptions(opts options.InsertManyOptions) *insertScope {
|
||||
is.opts = opts
|
||||
return is
|
||||
}
|
||||
|
||||
func (is *insertScope) mergeOptions(isMany bool) *insertScope {
|
||||
if is.ctx == nil {
|
||||
is.ctx = context.Background()
|
||||
}
|
||||
if is.opts == nil && isMany {
|
||||
is.opts = &options.InsertManyOptions{}
|
||||
}
|
||||
if is.opts == nil && !isMany {
|
||||
is.opts = &options.InsertOneOptions{}
|
||||
}
|
||||
return is
|
||||
}
|
||||
|
||||
func (is *insertScope) Insert(docs any) (*InsertResult, error) {
|
||||
isMany := goref.IsBaseList(docs)
|
||||
is.mergeOptions(isMany)
|
||||
var action insert = &insertOne{is}
|
||||
if isMany {
|
||||
action = &insertMany{is}
|
||||
}
|
||||
return action.insert(docs)
|
||||
}
|
111
mdbc.go
Normal file
111
mdbc.go
Normal file
@ -0,0 +1,111 @@
|
||||
package mdbc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gitter.top/coco/lormatter"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"go.mongodb.org/mongo-driver/mongo/readpref"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
formatter := &lormatter.Formatter{}
|
||||
logrus.SetFormatter(formatter)
|
||||
logrus.SetReportCaller(true)
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
uri string
|
||||
Username string `json:"username" yaml:"username"`
|
||||
Password string `json:"password" yaml:"password"`
|
||||
Address string `json:"address" yaml:"address"`
|
||||
Port int `json:"port" yaml:"port"`
|
||||
ProcessTimeout int `json:"process_timeout" yaml:"process_timeout"`
|
||||
DbName string `json:"db_name" yaml:"db_name"`
|
||||
ReadPref ReadPref `json:"read_pref" yaml:"read_pref"`
|
||||
}
|
||||
|
||||
func (c *Config) merge() {
|
||||
if c.Address == "" {
|
||||
c.Address = "localhost"
|
||||
}
|
||||
if c.Port == 0 {
|
||||
c.Port = 27017
|
||||
}
|
||||
if c.ProcessTimeout == 0 {
|
||||
c.ProcessTimeout = 30
|
||||
}
|
||||
}
|
||||
|
||||
type mdbc struct {
|
||||
client *mongo.Client
|
||||
database *mongo.Database
|
||||
readpref *readpref.ReadPref
|
||||
}
|
||||
|
||||
func NewMDBC(config *Config) *mdbc {
|
||||
var driver = new(mdbc)
|
||||
var clientOpts = options.Client()
|
||||
config.merge()
|
||||
clientOpts.ApplyURI(applyURI(config.Address, config.Port))
|
||||
if config.Username != "" && config.Password != "" {
|
||||
credential := options.Credential{
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
}
|
||||
clientOpts.SetAuth(credential)
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(config.ProcessTimeout)*time.Second)
|
||||
defer cancel()
|
||||
client, err := mongo.Connect(ctx, clientOpts)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
driver.readpref = readPref(config.ReadPref)
|
||||
if err := client.Ping(context.Background(), driver.readpref); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
driver.client = client
|
||||
if config.DbName != "" {
|
||||
driver.database = client.Database(config.DbName)
|
||||
}
|
||||
return driver
|
||||
}
|
||||
|
||||
// GetClient get raw mongo client
|
||||
func (m *mdbc) GetClient() *mongo.Client {
|
||||
return m.client
|
||||
}
|
||||
|
||||
// GetDatabase get raw mongo database
|
||||
func (m *mdbc) GetDatabase() *mongo.Database {
|
||||
return m.database
|
||||
}
|
||||
|
||||
// BindModel mapping protobuf Message to mongo Collection
|
||||
func (m *mdbc) BindModel(prototype any) Collection {
|
||||
if prototype == nil {
|
||||
panic("model can not be nil")
|
||||
}
|
||||
if _, impled := prototype.(tabler); !impled {
|
||||
panic("model does not implement tabler interface")
|
||||
}
|
||||
protomsg, impled := prototype.(proto.Message)
|
||||
if !impled {
|
||||
panic("model does not implement message interface")
|
||||
}
|
||||
scope := &scope{
|
||||
&model{
|
||||
Type: protomsg,
|
||||
modelKind: reflect.TypeOf(protomsg),
|
||||
modelName: string(protomsg.ProtoReflect().Descriptor().FullName()),
|
||||
tableName: prototype.(tabler).TableName(),
|
||||
},
|
||||
m,
|
||||
}
|
||||
return scope
|
||||
}
|
47
mdbc_test.go
Normal file
47
mdbc_test.go
Normal file
@ -0,0 +1,47 @@
|
||||
package mdbc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gitter.top/common/goref"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func newDriver() *mdbc {
|
||||
return NewMDBC(&Config{
|
||||
Address: "192.168.3.21",
|
||||
Port: 0,
|
||||
Username: "admin",
|
||||
Password: "admin",
|
||||
ProcessTimeout: 0,
|
||||
ReadPref: 0,
|
||||
DbName: "articles",
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewMDBC(t *testing.T) {
|
||||
driver := newDriver()
|
||||
databases, err := driver.GetClient().ListDatabaseNames(context.Background(), bson.D{})
|
||||
assert.NoError(t, err)
|
||||
t.Log(databases)
|
||||
}
|
||||
|
||||
func TestScope_Count(t *testing.T) {
|
||||
driver := newDriver()
|
||||
article := driver.BindModel(&ModelArticles{})
|
||||
value, err := article.Count().SetContext(context.Background()).Count()
|
||||
assert.NoError(t, err)
|
||||
t.Log(value)
|
||||
}
|
||||
|
||||
func TestDropScope_Do(t *testing.T) {
|
||||
driver := newDriver()
|
||||
article := driver.BindModel(&ModelArticles{})
|
||||
err := article.Drop().Do()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestInsertScope_Insert(t *testing.T) {
|
||||
|
||||
}
|
191
model.pb.go
Normal file
191
model.pb.go
Normal file
@ -0,0 +1,191 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.21.5
|
||||
// source: model.proto
|
||||
|
||||
package mdbc
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// @table_name: articles
|
||||
type ModelArticles struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // 主键ID
|
||||
Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` // 标题
|
||||
AvatarUrl string `protobuf:"bytes,5,opt,name=avatar_url,json=avatarUrl,proto3" json:"avatar_url,omitempty"` // 封面
|
||||
Phone string `protobuf:"bytes,6,opt,name=phone,proto3" json:"phone,omitempty"` // 手机号码
|
||||
CreateTime int64 `protobuf:"varint,12,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` // 创建时间
|
||||
UpdateTime int64 `protobuf:"varint,13,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` // 更新时间
|
||||
}
|
||||
|
||||
func (x *ModelArticles) Reset() {
|
||||
*x = ModelArticles{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_model_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ModelArticles) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ModelArticles) ProtoMessage() {}
|
||||
|
||||
func (x *ModelArticles) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_model_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ModelArticles.ProtoReflect.Descriptor instead.
|
||||
func (*ModelArticles) Descriptor() ([]byte, []int) {
|
||||
return file_model_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ModelArticles) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ModelArticles) GetTitle() string {
|
||||
if x != nil {
|
||||
return x.Title
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ModelArticles) GetAvatarUrl() string {
|
||||
if x != nil {
|
||||
return x.AvatarUrl
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ModelArticles) GetPhone() string {
|
||||
if x != nil {
|
||||
return x.Phone
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ModelArticles) GetCreateTime() int64 {
|
||||
if x != nil {
|
||||
return x.CreateTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ModelArticles) GetUpdateTime() int64 {
|
||||
if x != nil {
|
||||
return x.UpdateTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_model_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_model_proto_rawDesc = []byte{
|
||||
0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x6d,
|
||||
0x64, 0x62, 0x63, 0x22, 0xac, 0x01, 0x0a, 0x0d, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x41, 0x72, 0x74,
|
||||
0x69, 0x63, 0x6c, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61,
|
||||
0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68,
|
||||
0x6f, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65,
|
||||
0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18,
|
||||
0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, 0x3b, 0x6d, 0x64, 0x62, 0x63, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_model_proto_rawDescOnce sync.Once
|
||||
file_model_proto_rawDescData = file_model_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_model_proto_rawDescGZIP() []byte {
|
||||
file_model_proto_rawDescOnce.Do(func() {
|
||||
file_model_proto_rawDescData = protoimpl.X.CompressGZIP(file_model_proto_rawDescData)
|
||||
})
|
||||
return file_model_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_model_proto_goTypes = []interface{}{
|
||||
(*ModelArticles)(nil), // 0: mdbc.ModelArticles
|
||||
}
|
||||
var file_model_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_model_proto_init() }
|
||||
func file_model_proto_init() {
|
||||
if File_model_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_model_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ModelArticles); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_model_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_model_proto_goTypes,
|
||||
DependencyIndexes: file_model_proto_depIdxs,
|
||||
MessageInfos: file_model_proto_msgTypes,
|
||||
}.Build()
|
||||
File_model_proto = out.File
|
||||
file_model_proto_rawDesc = nil
|
||||
file_model_proto_goTypes = nil
|
||||
file_model_proto_depIdxs = nil
|
||||
}
|
16
model.proto
Normal file
16
model.proto
Normal file
@ -0,0 +1,16 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package mdbc;
|
||||
|
||||
option go_package = "./;mdbc";
|
||||
|
||||
|
||||
// @table_name: articles
|
||||
message ModelArticles {
|
||||
string id = 1; // 主键ID
|
||||
string title = 2; // 标题
|
||||
string avatar_url = 5; // 封面
|
||||
string phone = 6; // 手机号码
|
||||
int64 create_time = 12; // 创建时间
|
||||
int64 update_time = 13; // 更新时间
|
||||
}
|
30
readpref.go
Normal file
30
readpref.go
Normal file
@ -0,0 +1,30 @@
|
||||
package mdbc
|
||||
|
||||
import "go.mongodb.org/mongo-driver/mongo/readpref"
|
||||
|
||||
type ReadPref uint8
|
||||
|
||||
const (
|
||||
PrimaryMode ReadPref = iota + 1
|
||||
PrimaryPreferredMode
|
||||
SecondaryMode
|
||||
SecondaryPreferredMode
|
||||
NearestMode
|
||||
)
|
||||
|
||||
func readPref(pref ReadPref) *readpref.ReadPref {
|
||||
switch pref {
|
||||
case PrimaryMode:
|
||||
return readpref.Primary()
|
||||
case PrimaryPreferredMode:
|
||||
return readpref.PrimaryPreferred()
|
||||
case SecondaryMode:
|
||||
return readpref.Secondary()
|
||||
case SecondaryPreferredMode:
|
||||
return readpref.SecondaryPreferred()
|
||||
case NearestMode:
|
||||
return readpref.Nearest()
|
||||
default:
|
||||
return readpref.Primary()
|
||||
}
|
||||
}
|
87
scope.go
Normal file
87
scope.go
Normal file
@ -0,0 +1,87 @@
|
||||
package mdbc
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// model props for protobuf Message
|
||||
type model struct {
|
||||
Type proto.Message // model prototype
|
||||
modelKind reflect.Type // model low level type
|
||||
modelName string // model struct name
|
||||
tableName string // model mapping table name
|
||||
}
|
||||
|
||||
// Scope export operation for user
|
||||
type scope struct {
|
||||
*model
|
||||
*mdbc
|
||||
}
|
||||
|
||||
type Collection interface {
|
||||
Aggregate()
|
||||
BulkWrite()
|
||||
Clone()
|
||||
Count() *countScope
|
||||
Delete()
|
||||
Find()
|
||||
Drop() *dropScope
|
||||
Indexes() *indexesScope
|
||||
Insert()
|
||||
Update()
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Aggregate aggregate operate for mongo
|
||||
func (s *scope) Aggregate() {
|
||||
|
||||
}
|
||||
|
||||
func (s *scope) BulkWrite() {
|
||||
|
||||
}
|
||||
|
||||
func (s *scope) Clone() {
|
||||
|
||||
}
|
||||
|
||||
func (s *scope) Count() *countScope {
|
||||
return &countScope{
|
||||
scope: s,
|
||||
mdbc: s.mdbc,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *scope) Delete() {
|
||||
|
||||
}
|
||||
|
||||
func (s *scope) Find() {
|
||||
|
||||
}
|
||||
|
||||
func (s *scope) Drop() *dropScope {
|
||||
return &dropScope{
|
||||
scope: s,
|
||||
mdbc: s.mdbc,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *scope) Indexes() *indexesScope {
|
||||
return &indexesScope{
|
||||
scope: s,
|
||||
mdbc: s.mdbc,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *scope) Insert() {
|
||||
|
||||
}
|
||||
|
||||
func (s *scope) Update() {
|
||||
|
||||
}
|
||||
func (s *scope) Watch() {
|
||||
|
||||
}
|
5
tabler.go
Normal file
5
tabler.go
Normal file
@ -0,0 +1,5 @@
|
||||
package mdbc
|
||||
|
||||
type tabler interface {
|
||||
TableName() string
|
||||
}
|
Loading…
Reference in New Issue
Block a user