swirl/dao/mongo/mongo.go

185 lines
4.1 KiB
Go
Raw Normal View History

2017-09-26 12:50:09 +00:00
package mongo
import (
2021-12-06 12:24:22 +00:00
"context"
"strings"
2017-10-12 03:04:27 +00:00
"time"
2021-12-06 12:24:22 +00:00
"github.com/cuigh/auxo/app"
2017-09-26 12:50:09 +00:00
"github.com/cuigh/auxo/log"
2021-12-23 11:28:31 +00:00
"github.com/cuigh/swirl/dao"
2022-01-06 08:54:14 +00:00
"github.com/cuigh/swirl/misc"
2021-12-06 12:24:22 +00:00
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
2017-09-26 12:50:09 +00:00
)
2021-12-06 12:24:22 +00:00
var indexes = map[string][]mongo.IndexModel{
"chart": {
mongo.IndexModel{Keys: bson.D{{"title", 1}}},
},
"user": {
mongo.IndexModel{
Keys: bson.D{{"login_name", 1}},
Options: options.Index().SetUnique(true),
2017-09-26 12:50:09 +00:00
},
2021-12-06 12:24:22 +00:00
mongo.IndexModel{Keys: bson.D{{"name", 1}}},
2021-12-24 09:24:09 +00:00
mongo.IndexModel{Keys: bson.D{{"tokens.value", 1}}},
2021-12-06 12:24:22 +00:00
},
"role": {
mongo.IndexModel{
Keys: bson.D{{"name", 1}},
Options: options.Index().SetUnique(true),
2017-09-26 12:50:09 +00:00
},
2021-12-06 12:24:22 +00:00
},
"event": {
mongo.IndexModel{Keys: bson.D{{"type", 1}}},
2021-12-24 07:04:15 +00:00
mongo.IndexModel{Keys: bson.D{{"args.name", 1}}},
2021-12-06 12:24:22 +00:00
},
"session": {
mongo.IndexModel{
Keys: bson.D{{"expiry", 1}},
Options: options.Index().SetExpireAfterSeconds(3600),
},
},
2017-09-26 12:50:09 +00:00
}
2021-12-06 12:24:22 +00:00
type Dao struct {
db *mongo.Database
logger log.Logger
2017-09-26 12:50:09 +00:00
}
2021-12-23 11:28:31 +00:00
func New(addr string) (dao.Interface, error) {
2021-12-06 12:24:22 +00:00
db, err := open(addr)
if err != nil {
return nil, err
}
2017-09-26 12:50:09 +00:00
2021-12-06 12:24:22 +00:00
return &Dao{
db: db,
logger: log.Get("mongo"),
}, nil
2017-09-26 12:50:09 +00:00
}
2021-12-06 12:24:22 +00:00
func open(addr string) (*mongo.Database, error) {
db := "swirl"
2017-09-26 12:50:09 +00:00
2021-12-06 12:24:22 +00:00
// compatible with old mgo driver
if !strings.HasPrefix(addr, "mongodb://") && !strings.HasPrefix(addr, "mongodb+srv://") {
addr = "mongodb://" + addr
2017-09-26 12:50:09 +00:00
}
2021-12-06 12:24:22 +00:00
cs, err := connstring.Parse(addr)
2017-09-26 12:50:09 +00:00
if err != nil {
return nil, err
2021-12-06 12:24:22 +00:00
} else if cs.Database != "" {
db = cs.Database
2017-09-26 12:50:09 +00:00
}
2021-12-06 12:24:22 +00:00
opts := &options.ClientOptions{}
opts.ApplyURI(addr)
2022-01-06 08:54:14 +00:00
ctx, cancel := misc.Context(10 * time.Second)
2021-12-06 12:24:22 +00:00
defer cancel()
client, err := mongo.Connect(ctx, opts.SetAppName(app.Name))
if err != nil {
return nil, err
2017-09-26 12:50:09 +00:00
}
2021-12-06 12:24:22 +00:00
return client.Database(db), nil
2017-09-26 12:50:09 +00:00
}
2022-02-10 03:09:03 +00:00
func (d *Dao) Upgrade(ctx context.Context) (err error) {
2021-12-06 12:24:22 +00:00
for name, models := range indexes {
c := d.db.Collection(name)
2022-01-06 08:54:14 +00:00
_, err = c.Indexes().CreateMany(ctx, models)
2021-12-06 12:24:22 +00:00
if err != nil {
return
2017-09-26 12:50:09 +00:00
}
}
2021-12-06 12:24:22 +00:00
return
2017-09-26 12:50:09 +00:00
}
2021-12-06 12:24:22 +00:00
func (d *Dao) find(ctx context.Context, coll string, id interface{}, v interface{}) (found bool, err error) {
err = d.db.Collection(coll).FindOne(ctx, bson.M{"_id": id}).Decode(v)
if err == nil {
found = true
} else if err == mongo.ErrNoDocuments {
err = nil
}
return
}
func (d *Dao) fetch(ctx context.Context, coll string, filter bson.M, records interface{}) (err error) {
var cur *mongo.Cursor
cur, err = d.db.Collection(coll).Find(ctx, filter)
if err != nil {
return
}
defer cur.Close(ctx)
return cur.All(ctx, records)
}
func (d *Dao) search(ctx context.Context, coll string, opts searchOptions, records interface{}) (int, error) {
var (
c = d.db.Collection(coll)
cur *mongo.Cursor
)
// fetch total count
count, err := c.CountDocuments(ctx, opts.filter)
if err != nil {
return 0, err
}
// fetch records
findOpts := options.Find().SetSkip(int64(opts.pageSize * (opts.pageIndex - 1))).SetLimit(int64(opts.pageSize))
if opts.sorter != nil {
findOpts.SetSort(opts.sorter)
}
2022-01-06 08:54:14 +00:00
cur, err = c.Find(ctx, opts.filter, findOpts)
2021-12-06 12:24:22 +00:00
if err != nil {
return 0, err
}
defer cur.Close(ctx)
err = cur.All(ctx, records)
if err != nil {
return 0, err
2017-09-26 12:50:09 +00:00
}
2021-12-06 12:24:22 +00:00
return int(count), nil
}
func (d *Dao) create(ctx context.Context, coll string, doc interface{}) (err error) {
_, err = d.db.Collection(coll).InsertOne(ctx, doc)
return
2017-09-26 12:50:09 +00:00
}
2021-12-06 12:24:22 +00:00
func (d *Dao) update(ctx context.Context, coll string, id interface{}, update interface{}) (err error) {
_, err = d.db.Collection(coll).UpdateByID(ctx, id, update)
return
}
func (d *Dao) upsert(ctx context.Context, coll string, id interface{}, update interface{}) (err error) {
_, err = d.db.Collection(coll).UpdateByID(ctx, id, update, options.Update().SetUpsert(true))
return
}
func (d *Dao) delete(ctx context.Context, coll string, id interface{}) (err error) {
_, err = d.db.Collection(coll).DeleteOne(ctx, bson.M{"_id": id})
return
}
2017-09-26 12:50:09 +00:00
2021-12-06 12:24:22 +00:00
type searchOptions struct {
filter bson.M
sorter bson.M
pageIndex int
pageSize int
2017-09-26 12:50:09 +00:00
}
2021-12-23 11:28:31 +00:00
func init() {
dao.Register("mongo", New)
}