parent
9ff541c4af
commit
0dce07f1ee
@ -0,0 +1 @@
|
||||
package dorm
|
@ -0,0 +1,8 @@
|
||||
package dorm
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
var (
|
||||
// GormNotFound 没有数据
|
||||
GormNotFound = gorm.ErrRecordNotFound
|
||||
)
|
@ -0,0 +1,60 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type MongoCollectionOptions struct {
|
||||
db *mongo.Client // 驱动
|
||||
configDatabaseName string // 库名
|
||||
dbCollection *mongo.Collection // 集合
|
||||
}
|
||||
|
||||
// Collection 选择集合
|
||||
func (cd *MongoDatabaseOptions) Collection(name string, opts ...*options.CollectionOptions) *MongoCollectionOptions {
|
||||
return &MongoCollectionOptions{
|
||||
db: cd.db, // 驱动
|
||||
configDatabaseName: cd.configDatabaseName, // 库名
|
||||
dbCollection: cd.dbDatabase.Collection(name, opts...), // 集合
|
||||
}
|
||||
}
|
||||
|
||||
// CreateOneIndexes 创建一个索引
|
||||
func (cc *MongoCollectionOptions) CreateOneIndexes(ctx context.Context, key string, value string) (string, error) {
|
||||
return cc.dbCollection.Indexes().CreateOne(ctx, mongo.IndexModel{
|
||||
Keys: bson.D{{
|
||||
Key: key,
|
||||
Value: value,
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
||||
// CreateOneUniqueIndexes 创建一个唯一索引
|
||||
func (cc *MongoCollectionOptions) CreateOneUniqueIndexes(ctx context.Context, key string, value string) (string, error) {
|
||||
return cc.dbCollection.Indexes().CreateOne(ctx, mongo.IndexModel{
|
||||
Keys: bson.D{{
|
||||
Key: key,
|
||||
Value: value,
|
||||
}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
})
|
||||
}
|
||||
|
||||
// CreateOneUniqueIndexesOpts 创建一个索引
|
||||
func (cc *MongoCollectionOptions) CreateOneUniqueIndexesOpts(ctx context.Context, key string, value string, opts *options.IndexOptions) (string, error) {
|
||||
return cc.dbCollection.Indexes().CreateOne(ctx, mongo.IndexModel{
|
||||
Keys: bson.D{{
|
||||
Key: key,
|
||||
Value: value,
|
||||
}},
|
||||
Options: opts,
|
||||
})
|
||||
}
|
||||
|
||||
// CreateManyIndexes 创建多个索引
|
||||
func (cc *MongoCollectionOptions) CreateManyIndexes(ctx context.Context, models []mongo.IndexModel) ([]string, error) {
|
||||
return cc.dbCollection.Indexes().CreateMany(ctx, models)
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
// InsertOne 插入一个文档
|
||||
func (cc *MongoCollectionOptions) InsertOne(ctx context.Context, document interface{}, opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error) {
|
||||
return cc.dbCollection.InsertOne(ctx, document, opts...)
|
||||
}
|
||||
|
||||
// InsertMany 插入多个文档
|
||||
func (cc *MongoCollectionOptions) InsertMany(ctx context.Context, document []interface{}, opts ...*options.InsertManyOptions) (*mongo.InsertManyResult, error) {
|
||||
return cc.dbCollection.InsertMany(ctx, document, opts...)
|
||||
}
|
||||
|
||||
// DeleteOne 删除一个文档
|
||||
func (cc *MongoCollectionOptions) DeleteOne(ctx context.Context, filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
|
||||
return cc.dbCollection.DeleteOne(ctx, filter, opts...)
|
||||
}
|
||||
|
||||
// DeleteMany 删除多个文档
|
||||
func (cc *MongoCollectionOptions) DeleteMany(ctx context.Context, filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
|
||||
return cc.dbCollection.DeleteMany(ctx, filter, opts...)
|
||||
}
|
||||
|
||||
// UpdateByID 按ID更新
|
||||
func (cc *MongoCollectionOptions) UpdateByID(ctx context.Context, id interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
|
||||
return cc.dbCollection.UpdateByID(ctx, id, update, opts...)
|
||||
}
|
||||
|
||||
// UpdateOne 更新一个文档
|
||||
func (cc *MongoCollectionOptions) UpdateOne(ctx context.Context, filter interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
|
||||
return cc.dbCollection.UpdateOne(ctx, filter, update, opts...)
|
||||
}
|
||||
|
||||
// UpdateMany 更新多个文档
|
||||
func (cc *MongoCollectionOptions) UpdateMany(ctx context.Context, filter interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
|
||||
return cc.dbCollection.UpdateMany(ctx, filter, update, opts...)
|
||||
}
|
||||
|
||||
// ReplaceOne 替换一个文档
|
||||
func (cc *MongoCollectionOptions) ReplaceOne(ctx context.Context, filter interface{}, update interface{}, opts ...*options.ReplaceOptions) (*mongo.UpdateResult, error) {
|
||||
return cc.dbCollection.ReplaceOne(ctx, filter, update, opts...)
|
||||
}
|
||||
|
||||
// Aggregate 统计分析
|
||||
func (cc *MongoCollectionOptions) Aggregate(ctx context.Context, pipeline interface{}, opts ...*options.AggregateOptions) (*mongo.Cursor, error) {
|
||||
return cc.dbCollection.Aggregate(ctx, pipeline, opts...)
|
||||
}
|
||||
|
||||
// CountDocuments 计数文档
|
||||
func (cc *MongoCollectionOptions) CountDocuments(ctx context.Context, filter interface{}, opts ...*options.CountOptions) (int64, error) {
|
||||
return cc.dbCollection.CountDocuments(ctx, filter, opts...)
|
||||
}
|
||||
|
||||
// EstimatedDocumentCount 估计文档计数
|
||||
func (cc *MongoCollectionOptions) EstimatedDocumentCount(ctx context.Context, opts ...*options.EstimatedDocumentCountOptions) (int64, error) {
|
||||
return cc.dbCollection.EstimatedDocumentCount(ctx, opts...)
|
||||
}
|
||||
|
||||
func (cc *MongoCollectionOptions) Distinct(ctx context.Context, fieldName string, filter interface{}, opts ...*options.DistinctOptions) ([]interface{}, error) {
|
||||
return cc.dbCollection.Distinct(ctx, fieldName, filter, opts...)
|
||||
}
|
||||
|
||||
// Find 查询多个文档
|
||||
func (cc *MongoCollectionOptions) Find(ctx context.Context, filter interface{}, opts ...*options.FindOptions) (*mongo.Cursor, error) {
|
||||
return cc.dbCollection.Find(ctx, filter, opts...)
|
||||
}
|
||||
|
||||
// FindOne 查询一个文档
|
||||
func (cc *MongoCollectionOptions) FindOne(ctx context.Context, filter interface{}, opts ...*options.FindOneOptions) *mongo.SingleResult {
|
||||
return cc.dbCollection.FindOne(ctx, filter, opts...)
|
||||
}
|
||||
|
||||
func (cc *MongoCollectionOptions) FindOneAndDelete(ctx context.Context, filter interface{}, opts ...*options.FindOneAndDeleteOptions) *mongo.SingleResult {
|
||||
return cc.dbCollection.FindOneAndDelete(ctx, filter, opts...)
|
||||
}
|
||||
|
||||
func (cc *MongoCollectionOptions) FindOneAndReplace(ctx context.Context, filter interface{}, replacement interface{}, opts ...*options.FindOneAndReplaceOptions) *mongo.SingleResult {
|
||||
return cc.dbCollection.FindOneAndReplace(ctx, filter, replacement, opts...)
|
||||
}
|
||||
|
||||
func (cc *MongoCollectionOptions) FindOneAndUpdate(ctx context.Context, filter interface{}, replacement interface{}, opts ...*options.FindOneAndUpdateOptions) *mongo.SingleResult {
|
||||
return cc.dbCollection.FindOneAndUpdate(ctx, filter, replacement, opts...)
|
||||
}
|
||||
|
||||
func (cc *MongoCollectionOptions) Watch(ctx context.Context, pipeline interface{}, opts ...*options.ChangeStreamOptions) (*mongo.ChangeStream, error) {
|
||||
return cc.dbCollection.Watch(ctx, pipeline, opts...)
|
||||
}
|
||||
|
||||
func (cc *MongoCollectionOptions) Indexes(ctx context.Context) mongo.IndexView {
|
||||
return cc.dbCollection.Indexes()
|
||||
}
|
||||
|
||||
func (cc *MongoCollectionOptions) Drop(ctx context.Context) error {
|
||||
return cc.dbCollection.Drop(ctx)
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type FindResult struct {
|
||||
cursor *mongo.Cursor
|
||||
err error
|
||||
}
|
||||
|
||||
func (f *FindResult) Many(result interface{}) error {
|
||||
return f.cursor.All(context.TODO(), result)
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type FindManyResult struct {
|
||||
cursor *mongo.Cursor
|
||||
err error
|
||||
}
|
||||
|
||||
func (f *FindManyResult) Many(result interface{}) error {
|
||||
return f.cursor.All(context.TODO(), result)
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package dorm
|
||||
|
||||
import "go.mongodb.org/mongo-driver/mongo"
|
||||
|
||||
type FindOneResult struct {
|
||||
singleResult *mongo.SingleResult
|
||||
}
|
||||
|
||||
func (f *FindOneResult) One(result interface{}) error {
|
||||
return f.singleResult.Decode(result)
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type MongoDatabaseOptions struct {
|
||||
db *mongo.Client // 驱动
|
||||
configDatabaseName string // 库名
|
||||
dbDatabase *mongo.Database // 数据库
|
||||
}
|
||||
|
||||
// Database 选择数据库
|
||||
func (c *MongoClient) Database(name string, opts ...*options.DatabaseOptions) *MongoDatabaseOptions {
|
||||
return &MongoDatabaseOptions{
|
||||
db: c.db, // 驱动
|
||||
configDatabaseName: c.configDatabaseName, // 库名
|
||||
dbDatabase: c.db.Database(name, opts...), // 数据库
|
||||
}
|
||||
}
|
||||
|
||||
// CreateCollection 创建集合
|
||||
func (cd *MongoDatabaseOptions) CreateCollection(ctx context.Context, name string, opts ...*options.CreateCollectionOptions) error {
|
||||
return cd.dbDatabase.CreateCollection(ctx, name, opts...)
|
||||
}
|
||||
|
||||
// CreateTimeSeriesCollection 创建时间序列集合
|
||||
func (cd *MongoDatabaseOptions) CreateTimeSeriesCollection(ctx context.Context, name string, timeField string) error {
|
||||
return cd.dbDatabase.CreateCollection(ctx, name, options.CreateCollection().SetTimeSeriesOptions(options.TimeSeries().SetTimeField(timeField)))
|
||||
}
|
||||
|
||||
// Model 传入模型自动获取库名和表名
|
||||
// https://studygolang.com/articles/896
|
||||
// DatabaseName 库名
|
||||
// CollectionName 集合名
|
||||
func (c *MongoClient) Model(value interface{}) *MongoCollectionOptions {
|
||||
|
||||
var databaseOptions *MongoDatabaseOptions
|
||||
var collectionOptions *MongoCollectionOptions
|
||||
|
||||
val := reflect.ValueOf(value)
|
||||
|
||||
methodDatabaseNameValue := val.MethodByName("DatabaseName")
|
||||
if methodDatabaseNameValue.IsValid() {
|
||||
databaseName := methodDatabaseNameValue.Call(nil)[0].String()
|
||||
databaseOptions = c.Database(databaseName)
|
||||
} else {
|
||||
databaseOptions = c.Database(c.configDatabaseName)
|
||||
}
|
||||
|
||||
methodCollectionNameValue := val.MethodByName("CollectionName")
|
||||
if methodCollectionNameValue.IsValid() {
|
||||
collectionName := methodCollectionNameValue.Call(nil)[0].String()
|
||||
collectionOptions = databaseOptions.Collection(collectionName)
|
||||
} else {
|
||||
methodTableNameValue := val.MethodByName("TableName")
|
||||
if methodTableNameValue.IsValid() {
|
||||
collectionName := methodTableNameValue.Call(nil)[0].String()
|
||||
collectionOptions = databaseOptions.Collection(collectionName)
|
||||
} else {
|
||||
panic(NoConfigCollectionName)
|
||||
}
|
||||
}
|
||||
|
||||
return collectionOptions
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package dorm
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
NoConfigDatabaseName = errors.New("没有配置库名")
|
||||
NoConfigCollectionName = errors.New("没有配置集合名")
|
||||
)
|
@ -0,0 +1,59 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"log"
|
||||
)
|
||||
|
||||
type MongoSessionOptions struct {
|
||||
db *mongo.Client // 驱动
|
||||
configDatabaseName string // 库名
|
||||
session mongo.Session // 会话
|
||||
sessionContext mongo.SessionContext // 会话上下文
|
||||
}
|
||||
|
||||
// Begin 开始事务,会同时创建开始会话需要在退出时关闭会话
|
||||
func (c *MongoClient) Begin() *MongoSessionOptions {
|
||||
|
||||
var ctx = context.TODO()
|
||||
var err error
|
||||
ms := &MongoSessionOptions{}
|
||||
|
||||
ms.db = c.GetDb()
|
||||
ms.configDatabaseName = c.configDatabaseName
|
||||
|
||||
// 开始会话
|
||||
ms.session, err = ms.db.StartSession()
|
||||
if err != nil {
|
||||
log.Println("开始会话异常:", err)
|
||||
}
|
||||
|
||||
// 会话上下文
|
||||
ms.sessionContext = mongo.NewSessionContext(ctx, ms.session)
|
||||
|
||||
// 会话开启事务
|
||||
err = ms.session.StartTransaction()
|
||||
|
||||
return ms
|
||||
}
|
||||
|
||||
// Rollback 回滚事务
|
||||
func (cs *MongoSessionOptions) Rollback() {
|
||||
var ctx = context.TODO()
|
||||
err := cs.session.AbortTransaction(ctx)
|
||||
if err != nil {
|
||||
log.Println("回滚事务异常:", err)
|
||||
}
|
||||
cs.session.EndSession(ctx)
|
||||
}
|
||||
|
||||
// Commit 提交事务
|
||||
func (cs *MongoSessionOptions) Commit() {
|
||||
var ctx = context.TODO()
|
||||
err := cs.session.CommitTransaction(ctx)
|
||||
if err != nil {
|
||||
log.Println("提交事务异常:", err)
|
||||
}
|
||||
cs.session.EndSession(ctx)
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type MongoSessionCollectionOptions struct {
|
||||
db *mongo.Client // 驱动
|
||||
configDatabaseName string // 库名
|
||||
session mongo.Session // 会话
|
||||
sessionContext mongo.SessionContext // 会话上下文
|
||||
dbCollection *mongo.Collection // 集合
|
||||
}
|
||||
|
||||
// Collection 选择集合
|
||||
func (csd *MongoSessionDatabaseOptions) Collection(name string, opts ...*options.CollectionOptions) *MongoSessionCollectionOptions {
|
||||
return &MongoSessionCollectionOptions{
|
||||
db: csd.db, // 驱动
|
||||
configDatabaseName: csd.configDatabaseName, // 库名
|
||||
session: csd.session, // 会话
|
||||
sessionContext: csd.sessionContext, // 会话上下文
|
||||
dbCollection: csd.dbDatabase.Collection(name, opts...), // 集合
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
// InsertOne 插入一个文档
|
||||
func (csc *MongoSessionCollectionOptions) InsertOne(document interface{}, opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error) {
|
||||
return csc.dbCollection.InsertOne(csc.sessionContext, document, opts...)
|
||||
}
|
||||
|
||||
// InsertMany 插入多个文档
|
||||
func (csc *MongoSessionCollectionOptions) InsertMany(document []interface{}, opts ...*options.InsertManyOptions) (*mongo.InsertManyResult, error) {
|
||||
return csc.dbCollection.InsertMany(csc.sessionContext, document, opts...)
|
||||
}
|
||||
|
||||
// DeleteOne 删除一个文档
|
||||
func (csc *MongoSessionCollectionOptions) DeleteOne(filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
|
||||
return csc.dbCollection.DeleteOne(csc.sessionContext, filter, opts...)
|
||||
}
|
||||
|
||||
// DeleteMany 删除多个文档
|
||||
func (csc *MongoSessionCollectionOptions) DeleteMany(filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
|
||||
return csc.dbCollection.DeleteMany(csc.sessionContext, filter, opts...)
|
||||
}
|
||||
|
||||
// UpdateByID 按ID更新
|
||||
func (csc *MongoSessionCollectionOptions) UpdateByID(id interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
|
||||
return csc.dbCollection.UpdateByID(csc.sessionContext, id, update, opts...)
|
||||
}
|
||||
|
||||
// UpdateOne 更新一个文档
|
||||
func (csc *MongoSessionCollectionOptions) UpdateOne(filter interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
|
||||
return csc.dbCollection.UpdateOne(csc.sessionContext, filter, update, opts...)
|
||||
}
|
||||
|
||||
// UpdateMany 更新多个文档
|
||||
func (csc *MongoSessionCollectionOptions) UpdateMany(filter interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
|
||||
return csc.dbCollection.UpdateMany(csc.sessionContext, filter, update, opts...)
|
||||
}
|
||||
|
||||
// ReplaceOne 替换一个文档
|
||||
func (csc *MongoSessionCollectionOptions) ReplaceOne(filter interface{}, update interface{}, opts ...*options.ReplaceOptions) (*mongo.UpdateResult, error) {
|
||||
return csc.dbCollection.ReplaceOne(csc.sessionContext, filter, update, opts...)
|
||||
}
|
||||
|
||||
// Aggregate 统计分析
|
||||
func (csc *MongoSessionCollectionOptions) Aggregate(pipeline interface{}, opts ...*options.AggregateOptions) (*mongo.Cursor, error) {
|
||||
return csc.dbCollection.Aggregate(csc.sessionContext, pipeline, opts...)
|
||||
}
|
||||
|
||||
// CountDocuments 计数文档
|
||||
func (csc *MongoSessionCollectionOptions) CountDocuments(filter interface{}, opts ...*options.CountOptions) (int64, error) {
|
||||
return csc.dbCollection.CountDocuments(csc.sessionContext, filter, opts...)
|
||||
}
|
||||
|
||||
// EstimatedDocumentCount 估计文档计数
|
||||
func (csc *MongoSessionCollectionOptions) EstimatedDocumentCount(opts ...*options.EstimatedDocumentCountOptions) (int64, error) {
|
||||
return csc.dbCollection.EstimatedDocumentCount(csc.sessionContext, opts...)
|
||||
}
|
||||
|
||||
func (csc *MongoSessionCollectionOptions) Distinct(fieldName string, filter interface{}, opts ...*options.DistinctOptions) ([]interface{}, error) {
|
||||
return csc.dbCollection.Distinct(csc.sessionContext, fieldName, filter, opts...)
|
||||
}
|
||||
|
||||
// Find 查询多个文档
|
||||
func (csc *MongoSessionCollectionOptions) Find(filter interface{}, opts ...*options.FindOptions) (*mongo.Cursor, error) {
|
||||
return csc.dbCollection.Find(csc.sessionContext, filter, opts...)
|
||||
}
|
||||
|
||||
// FindOne 查询一个文档
|
||||
func (csc *MongoSessionCollectionOptions) FindOne(filter interface{}, opts ...*options.FindOneOptions) *mongo.SingleResult {
|
||||
return csc.dbCollection.FindOne(csc.sessionContext, filter, opts...)
|
||||
}
|
||||
|
||||
func (csc *MongoSessionCollectionOptions) FindOneAndDelete(filter interface{}, opts ...*options.FindOneAndDeleteOptions) *mongo.SingleResult {
|
||||
return csc.dbCollection.FindOneAndDelete(csc.sessionContext, filter, opts...)
|
||||
}
|
||||
|
||||
func (csc *MongoSessionCollectionOptions) FindOneAndReplace(filter interface{}, replacement interface{}, opts ...*options.FindOneAndReplaceOptions) *mongo.SingleResult {
|
||||
return csc.dbCollection.FindOneAndReplace(csc.sessionContext, filter, replacement, opts...)
|
||||
}
|
||||
|
||||
func (csc *MongoSessionCollectionOptions) FindOneAndUpdate(filter interface{}, replacement interface{}, opts ...*options.FindOneAndUpdateOptions) *mongo.SingleResult {
|
||||
return csc.dbCollection.FindOneAndUpdate(csc.sessionContext, filter, replacement, opts...)
|
||||
}
|
||||
|
||||
func (csc *MongoSessionCollectionOptions) Watch(pipeline interface{}, opts ...*options.ChangeStreamOptions) (*mongo.ChangeStream, error) {
|
||||
return csc.dbCollection.Watch(csc.sessionContext, pipeline, opts...)
|
||||
}
|
||||
|
||||
func (csc *MongoSessionCollectionOptions) Indexes() mongo.IndexView {
|
||||
return csc.dbCollection.Indexes()
|
||||
}
|
||||
|
||||
func (csc *MongoSessionCollectionOptions) Drop() error {
|
||||
return csc.dbCollection.Drop(csc.sessionContext)
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type MongoSessionDatabaseOptions struct {
|
||||
db *mongo.Client // 驱动
|
||||
configDatabaseName string // 库名
|
||||
session mongo.Session // 会话
|
||||
sessionContext mongo.SessionContext // 会话上下文
|
||||
dbDatabase *mongo.Database // 数据库
|
||||
}
|
||||
|
||||
// Database 选择数据库
|
||||
func (cs *MongoSessionOptions) Database(name string, opts ...*options.DatabaseOptions) *MongoSessionDatabaseOptions {
|
||||
return &MongoSessionDatabaseOptions{
|
||||
db: cs.db, // 驱动
|
||||
configDatabaseName: cs.configDatabaseName, // 库名
|
||||
session: cs.session, // 会话
|
||||
sessionContext: cs.sessionContext, // 会话上下文
|
||||
dbDatabase: cs.db.Database(name, opts...), // 数据库
|
||||
}
|
||||
}
|
||||
|
||||
// Model 传入模型自动获取库名和表名
|
||||
// https://studygolang.com/articles/896
|
||||
// DatabaseName 库名
|
||||
// CollectionName 集合名
|
||||
func (cs *MongoSessionOptions) Model(value interface{}) *MongoSessionCollectionOptions {
|
||||
|
||||
var sessionDatabaseOptions *MongoSessionDatabaseOptions
|
||||
var sessionCollectionOptions *MongoSessionCollectionOptions
|
||||
|
||||
val := reflect.ValueOf(value)
|
||||
|
||||
methodDatabaseNameValue := val.MethodByName("DatabaseName")
|
||||
if methodDatabaseNameValue.IsValid() {
|
||||
databaseName := methodDatabaseNameValue.Call(nil)[0].String()
|
||||
sessionDatabaseOptions = cs.Database(databaseName)
|
||||
} else {
|
||||
sessionDatabaseOptions = cs.Database(cs.configDatabaseName)
|
||||
}
|
||||
|
||||
methodCollectionNameValue := val.MethodByName("CollectionName")
|
||||
if methodCollectionNameValue.IsValid() {
|
||||
collectionName := methodCollectionNameValue.Call(nil)[0].String()
|
||||
sessionCollectionOptions = sessionDatabaseOptions.Collection(collectionName)
|
||||
} else {
|
||||
methodTableNameValue := val.MethodByName("TableName")
|
||||
if methodTableNameValue.IsValid() {
|
||||
collectionName := methodTableNameValue.Call(nil)[0].String()
|
||||
sessionCollectionOptions = sessionDatabaseOptions.Collection(collectionName)
|
||||
} else {
|
||||
panic(NoConfigCollectionName)
|
||||
}
|
||||
}
|
||||
|
||||
return sessionCollectionOptions
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
// GetDb 获取驱动
|
||||
func (cs *MongoSessionOptions) GetDb() *mongo.Client {
|
||||
return cs.db
|
||||
}
|
||||
|
||||
// GetSession 获取会话
|
||||
func (cs *MongoSessionOptions) GetSession() mongo.Session {
|
||||
return cs.session
|
||||
}
|
||||
|
||||
// GetSessionContext 获取会话上下文
|
||||
func (cs *MongoSessionOptions) GetSessionContext() mongo.SessionContext {
|
||||
return cs.sessionContext
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package dorm
|
||||
|
||||
import "reflect"
|
||||
|
||||
// Database 设置库名
|
||||
func (c *MongoClient) Database(databaseName string) *MongoClient {
|
||||
c.databaseName = databaseName
|
||||
return c
|
||||
}
|
||||
|
||||
// Collection 设置表名
|
||||
func (c *MongoClient) Collection(collectionName string) *MongoClient {
|
||||
c.collectionName = collectionName
|
||||
return c
|
||||
}
|
||||
|
||||
// Model 传入模型自动获取库名和表名
|
||||
func (c *MongoClient) Model(value interface{}) *MongoClient {
|
||||
// https://studygolang.com/articles/896
|
||||
val := reflect.ValueOf(value)
|
||||
if methodValue := val.MethodByName("Database"); methodValue.IsValid() {
|
||||
c.databaseName = methodValue.Call(nil)[0].String()
|
||||
}
|
||||
if methodValue := val.MethodByName("TableName"); methodValue.IsValid() {
|
||||
c.collectionName = methodValue.Call(nil)[0].String()
|
||||
}
|
||||
return c
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type MongoTransaction struct {
|
||||
startSession mongo.Session
|
||||
Session mongo.SessionContext
|
||||
db *mongo.Client // 驱动
|
||||
databaseName string // 库名
|
||||
collectionName string // 表名
|
||||
}
|
||||
|
||||
// Begin 开始事务,会同时创建开始会话需要在退出时关闭会话
|
||||
func (c *MongoClient) Begin() (ms MongoTransaction, err error) {
|
||||
|
||||
ms.db = c.Db
|
||||
|
||||
// 开始会话
|
||||
ms.startSession, err = ms.db.StartSession()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 会话上下文
|
||||
ms.Session = mongo.NewSessionContext(context.Background(), ms.startSession)
|
||||
|
||||
// 会话开启事务
|
||||
err = ms.startSession.StartTransaction()
|
||||
return ms, err
|
||||
}
|
||||
|
||||
// Close 关闭会话
|
||||
func (ms *MongoTransaction) Close() {
|
||||
ms.startSession.EndSession(context.TODO())
|
||||
}
|
||||
|
||||
// Rollback 回滚事务
|
||||
func (ms *MongoTransaction) Rollback() error {
|
||||
return ms.startSession.AbortTransaction(context.Background())
|
||||
}
|
||||
|
||||
// Commit 提交事务
|
||||
func (ms *MongoTransaction) Commit() error {
|
||||
return ms.startSession.CommitTransaction(context.Background())
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package dorm
|
||||
|
||||
// 获取库名
|
||||
func (ms *MongoTransaction) getDatabaseName() string {
|
||||
return ms.databaseName
|
||||
}
|
||||
|
||||
// 获取表名
|
||||
func (ms *MongoTransaction) getCollectionName() string {
|
||||
return ms.collectionName
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package dorm
|
||||
|
||||
import "reflect"
|
||||
|
||||
// Database 设置库名
|
||||
func (ms *MongoTransaction) Database(databaseName string) *MongoTransaction {
|
||||
ms.databaseName = databaseName
|
||||
return ms
|
||||
}
|
||||
|
||||
// Collection 设置表名
|
||||
func (ms *MongoTransaction) Collection(collectionName string) *MongoTransaction {
|
||||
ms.collectionName = collectionName
|
||||
return ms
|
||||
}
|
||||
|
||||
// Model 传入模型自动获取库名和表名
|
||||
func (ms *MongoTransaction) Model(value interface{}) *MongoTransaction {
|
||||
// https://studygolang.com/articles/896
|
||||
val := reflect.ValueOf(value)
|
||||
if methodValue := val.MethodByName("Database"); methodValue.IsValid() {
|
||||
ms.databaseName = methodValue.Call(nil)[0].String()
|
||||
}
|
||||
if methodValue := val.MethodByName("TableName"); methodValue.IsValid() {
|
||||
ms.collectionName = methodValue.Call(nil)[0].String()
|
||||
}
|
||||
return ms
|
||||
}
|
@ -0,0 +1 @@
|
||||
package dorm
|
@ -0,0 +1 @@
|
||||
package dorm
|
@ -0,0 +1 @@
|
||||
package dorm
|
@ -0,0 +1,8 @@
|
||||
package dorm
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
// RedisKeysNotFound keys没有数据
|
||||
RedisKeysNotFound = errors.New("ERR wrong number of arguments for 'mget' command")
|
||||
)
|
@ -0,0 +1,73 @@
|
||||
package dorm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/go-redis/redis/v9"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RedisClientLock https://github.com/go-redis/redis
|
||||
type RedisClientLock struct {
|
||||
operation *RedisClient // 操作
|
||||
}
|
||||
|
||||
// NewLock 实例化锁
|
||||
func (r *RedisClient) NewLock() *RedisClientLock {
|
||||
return &RedisClientLock{r}
|
||||
}
|
||||
|
||||
// Lock 上锁
|
||||
// key 锁名
|
||||
// val 锁内容
|
||||
// ttl 锁过期时间
|
||||
func (rl *RedisClientLock) Lock(ctx context.Context, key string, val string, ttl time.Duration) (resp string, err error) {
|
||||
if ttl <= 0 {
|
||||
return resp, errors.New("长期请使用 LockForever 方法")
|
||||
}
|
||||
// 获取
|
||||
get, err := rl.operation.Get(ctx, key).Result()
|
||||
if errors.Is(err, redis.Nil) {
|
||||
// 设置
|
||||
err = rl.operation.Set(ctx, key, val, ttl).Err()
|
||||
if err != nil {
|
||||
return resp, errors.New(fmt.Sprintf("上锁失败:%s", err.Error()))
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
if get != "" {
|
||||
return resp, errors.New("上锁失败,已存在")
|
||||
}
|
||||
return resp, errors.New(fmt.Sprintf("获取异常:%s", err.Error()))
|
||||
}
|
||||
|
||||
// Unlock 解锁
|
||||
// key 锁名
|
||||
func (rl *RedisClientLock) Unlock(ctx context.Context, key string) error {
|
||||
_, err := rl.operation.Del(ctx, key).Result()
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("解锁失败:%s", err.Error()))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// LockForever 永远上锁
|
||||
// key 锁名
|
||||
// val 锁内容
|
||||
func (rl *RedisClientLock) LockForever(ctx context.Context, key string, val string) (resp string, err error) {
|
||||
// 获取
|
||||
get, err := rl.operation.Get(ctx, key).Result()
|
||||
if errors.Is(err, redis.Nil) {
|
||||
// 设置
|
||||
err = rl.operation.Set(ctx, key, val, 0).Err()
|
||||
if err != nil {
|
||||
return resp, errors.New(fmt.Sprintf("上锁失败:%s", err.Error()))
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
if get != "" {
|
||||
return resp, errors.New("上锁失败,已存在")
|
||||
}
|
||||
return resp, errors.New(fmt.Sprintf("获取异常:%s", err.Error()))
|
||||
}
|
@ -0,0 +1 @@
|
||||
package dorm
|
@ -0,0 +1 @@
|
||||
package dorm
|
@ -0,0 +1 @@
|
||||
package dorm
|
@ -0,0 +1 @@
|
||||
package dorm
|
@ -0,0 +1 @@
|
||||
package dorm
|
@ -0,0 +1,76 @@
|
||||
package dorm
|
||||
|
||||
// Bool 复制 bool 对象,并返回复制体
|
||||
func Bool(b bool) bool {
|
||||
return b
|
||||
}
|
||||
|
||||
// Uint8 复制 int8 对象,并返回复制体
|
||||
func Uint8(ui uint8) uint8 {
|
||||
return ui
|
||||
}
|
||||
|
||||
// Uint16 复制 uint16 对象,并返回复制体
|
||||
func Uint16(ui uint16) uint16 {
|
||||
return ui
|
||||
}
|
||||
|
||||
// Uint32 复制 uint32 对象,并返回复制体
|
||||
func Uint32(ui uint32) uint32 {
|
||||
return ui
|
||||
}
|
||||
|
||||
// Uint64 复制 uint64 对象,并返回复制体
|
||||
func Uint64(ui uint64) uint64 {
|
||||
return ui
|
||||
}
|
||||
|
||||
// Int8 复制 int8 对象,并返回复制体
|
||||
func Int8(i int8) int8 {
|
||||
return i
|
||||
}
|
||||
|
||||
// Int16 复制 int16 对象,并返回复制体
|
||||
func Int16(i int16) int16 {
|
||||
return i
|
||||
}
|
||||
|
||||
// Int32 复制 int64 对象,并返回复制体
|
||||
func Int32(i int32) int32 {
|
||||
return i
|
||||
}
|
||||
|
||||
// Int64 复制 int64 对象,并返回复制体
|
||||
func Int64(i int64) int64 {
|
||||
return i
|
||||
}
|
||||
|
||||
// Float32 复制 float32 对象,并返回复制体
|
||||
func Float32(f float32) float32 {
|
||||
return f
|
||||
}
|
||||
|
||||
// Float64 复制 float64 对象,并返回复制体
|
||||
func Float64(f float64) float64 {
|
||||
return f
|
||||
}
|
||||
|
||||
// String 复制 string 对象,并返回复制体
|
||||
func String(s string) string {
|
||||
return s
|
||||
}
|
||||
|
||||
// Int 复制 int 对象,并返回复制体
|
||||
func Int(i int) int {
|
||||
return i
|
||||
}
|
||||
|
||||
// Uint 复制 uint 对象,并返回复制体
|
||||
func Uint(ui uint) uint {
|
||||
return ui
|
||||
}
|
||||
|
||||
// Any 复制 any 对象,并返回复制体
|
||||
func Any(a any) any {
|
||||
return a
|
||||
}
|
Loading…
Reference in new issue