diff --git a/dal/query/gen.go b/dal/query/gen.go new file mode 100644 index 00000000..59f0e0dc --- /dev/null +++ b/dal/query/gen.go @@ -0,0 +1,103 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "database/sql" + + "gorm.io/gorm" + + "gorm.io/gen" + + "gorm.io/plugin/dbresolver" +) + +var ( + Q = new(Query) + User *user +) + +func SetDefault(db *gorm.DB, opts ...gen.DOOption) { + *Q = *Use(db, opts...) + User = &Q.User +} + +func Use(db *gorm.DB, opts ...gen.DOOption) *Query { + return &Query{ + db: db, + User: newUser(db, opts...), + } +} + +type Query struct { + db *gorm.DB + + User user +} + +func (q *Query) Available() bool { return q.db != nil } + +func (q *Query) clone(db *gorm.DB) *Query { + return &Query{ + db: db, + User: q.User.clone(db), + } +} + +func (q *Query) ReadDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Read)) +} + +func (q *Query) WriteDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Write)) +} + +func (q *Query) ReplaceDB(db *gorm.DB) *Query { + return &Query{ + db: db, + User: q.User.replaceDB(db), + } +} + +type queryCtx struct { + User *userDo +} + +func (q *Query) WithContext(ctx context.Context) *queryCtx { + return &queryCtx{ + User: q.User.WithContext(ctx), + } +} + +func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error { + return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...) +} + +func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx { + tx := q.db.Begin(opts...) + return &QueryTx{Query: q.clone(tx), Error: tx.Error} +} + +type QueryTx struct { + *Query + Error error +} + +func (q *QueryTx) Commit() error { + return q.db.Commit().Error +} + +func (q *QueryTx) Rollback() error { + return q.db.Rollback().Error +} + +func (q *QueryTx) SavePoint(name string) error { + return q.db.SavePoint(name).Error +} + +func (q *QueryTx) RollbackTo(name string) error { + return q.db.RollbackTo(name).Error +} diff --git a/dal/query/gen_test.go b/dal/query/gen_test.go new file mode 100644 index 00000000..40cdc69b --- /dev/null +++ b/dal/query/gen_test.go @@ -0,0 +1,118 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "fmt" + "reflect" + "sync" + "testing" + + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +type Input struct { + Args []interface{} +} + +type Expectation struct { + Ret []interface{} +} + +type TestCase struct { + Input + Expectation +} + +const dbName = "gen_test.db" + +var db *gorm.DB +var once sync.Once + +func init() { + InitializeDB() + db.AutoMigrate(&_another{}) +} + +func InitializeDB() { + once.Do(func() { + var err error + db, err = gorm.Open(sqlite.Open(dbName), &gorm.Config{}) + if err != nil { + panic(fmt.Errorf("open sqlite %q fail: %w", dbName, err)) + } + }) +} + +func assert(t *testing.T, methodName string, res, exp interface{}) { + if !reflect.DeepEqual(res, exp) { + t.Errorf("%v() gotResult = %v, want %v", methodName, res, exp) + } +} + +type _another struct { + ID uint64 `gorm:"primaryKey"` +} + +func (*_another) TableName() string { return "another_for_unit_test" } + +func Test_Available(t *testing.T) { + if !Use(db).Available() { + t.Errorf("query.Available() == false") + } +} + +func Test_WithContext(t *testing.T) { + query := Use(db) + if !query.Available() { + t.Errorf("query Use(db) fail: query.Available() == false") + } + + type Content string + var key, value Content = "gen_tag", "unit_test" + qCtx := query.WithContext(context.WithValue(context.Background(), key, value)) + + for _, ctx := range []context.Context{ + qCtx.User.UnderlyingDB().Statement.Context, + } { + if v := ctx.Value(key); v != value { + t.Errorf("get value from context fail, expect %q, got %q", value, v) + } + } +} + +func Test_Transaction(t *testing.T) { + query := Use(db) + if !query.Available() { + t.Errorf("query Use(db) fail: query.Available() == false") + } + + err := query.Transaction(func(tx *Query) error { return nil }) + if err != nil { + t.Errorf("query.Transaction execute fail: %s", err) + } + + tx := query.Begin() + + err = tx.SavePoint("point") + if err != nil { + t.Errorf("query tx SavePoint fail: %s", err) + } + err = tx.RollbackTo("point") + if err != nil { + t.Errorf("query tx RollbackTo fail: %s", err) + } + err = tx.Commit() + if err != nil { + t.Errorf("query tx Commit fail: %s", err) + } + + err = query.Begin().Rollback() + if err != nil { + t.Errorf("query tx Rollback fail: %s", err) + } +} diff --git a/dal/query/gorm_test_user_tmp.gen.go b/dal/query/gorm_test_user_tmp.gen.go new file mode 100644 index 00000000..0d174105 --- /dev/null +++ b/dal/query/gorm_test_user_tmp.gen.go @@ -0,0 +1,347 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "playground/model" +) + +func newUser(db *gorm.DB, opts ...gen.DOOption) user { + _user := user{} + + _user.userDo.UseDB(db, opts...) + _user.userDo.UseModel(&model.User{}) + + tableName := _user.userDo.TableName() + _user.ALL = field.NewAsterisk(tableName) + _user.ID = field.NewUint(tableName, "id") + _user.CreatedAt = field.NewTime(tableName, "created_at") + _user.UpdatedAt = field.NewTime(tableName, "updated_at") + _user.DeletedAt = field.NewField(tableName, "deleted_at") + _user.Username = field.NewString(tableName, "username") + _user.Status = field.NewInt(tableName, "status") + + _user.fillFieldMap() + + return _user +} + +type user struct { + userDo userDo + + ALL field.Asterisk + ID field.Uint + CreatedAt field.Time + UpdatedAt field.Time + DeletedAt field.Field + Username field.String + Status field.Int + + fieldMap map[string]field.Expr +} + +func (u user) Table(newTableName string) *user { + u.userDo.UseTable(newTableName) + return u.updateTableName(newTableName) +} + +func (u user) As(alias string) *user { + u.userDo.DO = *(u.userDo.As(alias).(*gen.DO)) + return u.updateTableName(alias) +} + +func (u *user) updateTableName(table string) *user { + u.ALL = field.NewAsterisk(table) + u.ID = field.NewUint(table, "id") + u.CreatedAt = field.NewTime(table, "created_at") + u.UpdatedAt = field.NewTime(table, "updated_at") + u.DeletedAt = field.NewField(table, "deleted_at") + u.Username = field.NewString(table, "username") + u.Status = field.NewInt(table, "status") + + u.fillFieldMap() + + return u +} + +func (u *user) WithContext(ctx context.Context) *userDo { return u.userDo.WithContext(ctx) } + +func (u user) TableName() string { return u.userDo.TableName() } + +func (u user) Alias() string { return u.userDo.Alias() } + +func (u user) Columns(cols ...field.Expr) gen.Columns { return u.userDo.Columns(cols...) } + +func (u *user) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := u.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (u *user) fillFieldMap() { + u.fieldMap = make(map[string]field.Expr, 6) + u.fieldMap["id"] = u.ID + u.fieldMap["created_at"] = u.CreatedAt + u.fieldMap["updated_at"] = u.UpdatedAt + u.fieldMap["deleted_at"] = u.DeletedAt + u.fieldMap["username"] = u.Username + u.fieldMap["status"] = u.Status +} + +func (u user) clone(db *gorm.DB) user { + u.userDo.ReplaceConnPool(db.Statement.ConnPool) + return u +} + +func (u user) replaceDB(db *gorm.DB) user { + u.userDo.ReplaceDB(db) + return u +} + +type userDo struct{ gen.DO } + +func (u userDo) Debug() *userDo { + return u.withDO(u.DO.Debug()) +} + +func (u userDo) WithContext(ctx context.Context) *userDo { + return u.withDO(u.DO.WithContext(ctx)) +} + +func (u userDo) ReadDB() *userDo { + return u.Clauses(dbresolver.Read) +} + +func (u userDo) WriteDB() *userDo { + return u.Clauses(dbresolver.Write) +} + +func (u userDo) Session(config *gorm.Session) *userDo { + return u.withDO(u.DO.Session(config)) +} + +func (u userDo) Clauses(conds ...clause.Expression) *userDo { + return u.withDO(u.DO.Clauses(conds...)) +} + +func (u userDo) Returning(value interface{}, columns ...string) *userDo { + return u.withDO(u.DO.Returning(value, columns...)) +} + +func (u userDo) Not(conds ...gen.Condition) *userDo { + return u.withDO(u.DO.Not(conds...)) +} + +func (u userDo) Or(conds ...gen.Condition) *userDo { + return u.withDO(u.DO.Or(conds...)) +} + +func (u userDo) Select(conds ...field.Expr) *userDo { + return u.withDO(u.DO.Select(conds...)) +} + +func (u userDo) Where(conds ...gen.Condition) *userDo { + return u.withDO(u.DO.Where(conds...)) +} + +func (u userDo) Order(conds ...field.Expr) *userDo { + return u.withDO(u.DO.Order(conds...)) +} + +func (u userDo) Distinct(cols ...field.Expr) *userDo { + return u.withDO(u.DO.Distinct(cols...)) +} + +func (u userDo) Omit(cols ...field.Expr) *userDo { + return u.withDO(u.DO.Omit(cols...)) +} + +func (u userDo) Join(table schema.Tabler, on ...field.Expr) *userDo { + return u.withDO(u.DO.Join(table, on...)) +} + +func (u userDo) LeftJoin(table schema.Tabler, on ...field.Expr) *userDo { + return u.withDO(u.DO.LeftJoin(table, on...)) +} + +func (u userDo) RightJoin(table schema.Tabler, on ...field.Expr) *userDo { + return u.withDO(u.DO.RightJoin(table, on...)) +} + +func (u userDo) Group(cols ...field.Expr) *userDo { + return u.withDO(u.DO.Group(cols...)) +} + +func (u userDo) Having(conds ...gen.Condition) *userDo { + return u.withDO(u.DO.Having(conds...)) +} + +func (u userDo) Limit(limit int) *userDo { + return u.withDO(u.DO.Limit(limit)) +} + +func (u userDo) Offset(offset int) *userDo { + return u.withDO(u.DO.Offset(offset)) +} + +func (u userDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *userDo { + return u.withDO(u.DO.Scopes(funcs...)) +} + +func (u userDo) Unscoped() *userDo { + return u.withDO(u.DO.Unscoped()) +} + +func (u userDo) Create(values ...*model.User) error { + if len(values) == 0 { + return nil + } + return u.DO.Create(values) +} + +func (u userDo) CreateInBatches(values []*model.User, batchSize int) error { + return u.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (u userDo) Save(values ...*model.User) error { + if len(values) == 0 { + return nil + } + return u.DO.Save(values) +} + +func (u userDo) First() (*model.User, error) { + if result, err := u.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.User), nil + } +} + +func (u userDo) Take() (*model.User, error) { + if result, err := u.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.User), nil + } +} + +func (u userDo) Last() (*model.User, error) { + if result, err := u.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.User), nil + } +} + +func (u userDo) Find() ([]*model.User, error) { + result, err := u.DO.Find() + return result.([]*model.User), err +} + +func (u userDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.User, err error) { + buf := make([]*model.User, 0, batchSize) + err = u.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (u userDo) FindInBatches(result *[]*model.User, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return u.DO.FindInBatches(result, batchSize, fc) +} + +func (u userDo) Attrs(attrs ...field.AssignExpr) *userDo { + return u.withDO(u.DO.Attrs(attrs...)) +} + +func (u userDo) Assign(attrs ...field.AssignExpr) *userDo { + return u.withDO(u.DO.Assign(attrs...)) +} + +func (u userDo) Joins(fields ...field.RelationField) *userDo { + for _, _f := range fields { + u = *u.withDO(u.DO.Joins(_f)) + } + return &u +} + +func (u userDo) Preload(fields ...field.RelationField) *userDo { + for _, _f := range fields { + u = *u.withDO(u.DO.Preload(_f)) + } + return &u +} + +func (u userDo) FirstOrInit() (*model.User, error) { + if result, err := u.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.User), nil + } +} + +func (u userDo) FirstOrCreate() (*model.User, error) { + if result, err := u.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.User), nil + } +} + +func (u userDo) FindByPage(offset int, limit int) (result []*model.User, count int64, err error) { + result, err = u.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = u.Offset(-1).Limit(-1).Count() + return +} + +func (u userDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = u.Count() + if err != nil { + return + } + + err = u.Offset(offset).Limit(limit).Scan(result) + return +} + +func (u userDo) Scan(result interface{}) (err error) { + return u.DO.Scan(result) +} + +func (u userDo) Delete(models ...*model.User) (result gen.ResultInfo, err error) { + return u.DO.Delete(models) +} + +func (u *userDo) withDO(do gen.Dao) *userDo { + u.DO = *do.(*gen.DO) + return u +} diff --git a/dal/query/gorm_test_user_tmp.gen_test.go b/dal/query/gorm_test_user_tmp.gen_test.go new file mode 100644 index 00000000..2f8f8ba7 --- /dev/null +++ b/dal/query/gorm_test_user_tmp.gen_test.go @@ -0,0 +1,146 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "fmt" + "testing" + + "playground/model" + + "gorm.io/gen" + "gorm.io/gen/field" + "gorm.io/gorm/clause" +) + +func init() { + InitializeDB() + err := db.AutoMigrate(&model.User{}) + if err != nil { + fmt.Printf("Error: AutoMigrate(&model.User{}) fail: %s", err) + } +} + +func Test_userQuery(t *testing.T) { + user := newUser(db) + user = *user.As(user.TableName()) + _do := user.WithContext(context.Background()).Debug() + + primaryKey := field.NewString(user.TableName(), clause.PrimaryKey) + _, err := _do.Unscoped().Where(primaryKey.IsNotNull()).Delete() + if err != nil { + t.Error("clean table fail:", err) + return + } + + _, ok := user.GetFieldByName("") + if ok { + t.Error("GetFieldByName(\"\") from user success") + } + + err = _do.Create(&model.User{}) + if err != nil { + t.Error("create item in table fail:", err) + } + + err = _do.Save(&model.User{}) + if err != nil { + t.Error("create item in table fail:", err) + } + + err = _do.CreateInBatches([]*model.User{{}, {}}, 10) + if err != nil { + t.Error("create item in table fail:", err) + } + + _, err = _do.Select(user.ALL).Take() + if err != nil { + t.Error("Take() on table fail:", err) + } + + _, err = _do.First() + if err != nil { + t.Error("First() on table fail:", err) + } + + _, err = _do.Last() + if err != nil { + t.Error("First() on table fail:", err) + } + + _, err = _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatch() on table fail:", err) + } + + err = _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*model.User{}, 10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatches() on table fail:", err) + } + + _, err = _do.Select(user.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find() + if err != nil { + t.Error("Find() on table fail:", err) + } + + _, err = _do.Distinct(primaryKey).Take() + if err != nil { + t.Error("select Distinct() on table fail:", err) + } + + _, err = _do.Select(user.ALL).Omit(primaryKey).Take() + if err != nil { + t.Error("Omit() on table fail:", err) + } + + _, err = _do.Group(primaryKey).Find() + if err != nil { + t.Error("Group() on table fail:", err) + } + + _, err = _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find() + if err != nil { + t.Error("Scopes() on table fail:", err) + } + + _, _, err = _do.FindByPage(0, 1) + if err != nil { + t.Error("FindByPage() on table fail:", err) + } + + _, err = _do.ScanByPage(&model.User{}, 0, 1) + if err != nil { + t.Error("ScanByPage() on table fail:", err) + } + + _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit() + if err != nil { + t.Error("FirstOrInit() on table fail:", err) + } + + _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate() + if err != nil { + t.Error("FirstOrCreate() on table fail:", err) + } + + var _a _another + var _aPK = field.NewString(_a.TableName(), "id") + + err = _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("Join() on table fail:", err) + } + + err = _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("LeftJoin() on table fail:", err) + } + + _, err = _do.Not().Or().Clauses().Take() + if err != nil { + t.Error("Not/Or/Clauses on table fail:", err) + } +} diff --git a/db.go b/db.go deleted file mode 100644 index ccab03ed..00000000 --- a/db.go +++ /dev/null @@ -1,108 +0,0 @@ -package main - -import ( - "log" - "math/rand" - "os" - "path/filepath" - "time" - - "gorm.io/driver/mysql" - "gorm.io/driver/postgres" - "gorm.io/driver/sqlite" - "gorm.io/driver/sqlserver" - "gorm.io/gorm" - "gorm.io/gorm/logger" -) - -var DB *gorm.DB - -func init() { - var err error - if DB, err = OpenTestConnection(); err != nil { - log.Printf("failed to connect database, got error %v\n", err) - os.Exit(1) - } else { - sqlDB, err := DB.DB() - if err == nil { - err = sqlDB.Ping() - } - - if err != nil { - log.Printf("failed to connect database, got error %v\n", err) - } - - RunMigrations() - if DB.Dialector.Name() == "sqlite" { - DB.Exec("PRAGMA foreign_keys = ON") - } - - DB.Logger = DB.Logger.LogMode(logger.Info) - } -} - -func OpenTestConnection() (db *gorm.DB, err error) { - dbDSN := os.Getenv("GORM_DSN") - switch os.Getenv("GORM_DIALECT") { - case "mysql": - log.Println("testing mysql...") - if dbDSN == "" { - dbDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local" - } - db, err = gorm.Open(mysql.Open(dbDSN), &gorm.Config{}) - case "postgres": - log.Println("testing postgres...") - if dbDSN == "" { - dbDSN = "user=gorm password=gorm host=localhost dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai" - } - db, err = gorm.Open(postgres.Open(dbDSN), &gorm.Config{}) - case "sqlserver": - // CREATE LOGIN gorm WITH PASSWORD = 'LoremIpsum86'; - // CREATE DATABASE gorm; - // USE gorm; - // CREATE USER gorm FROM LOGIN gorm; - // sp_changedbowner 'gorm'; - log.Println("testing sqlserver...") - if dbDSN == "" { - dbDSN = "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" - } - db, err = gorm.Open(sqlserver.Open(dbDSN), &gorm.Config{}) - default: - log.Println("testing sqlite3...") - db, err = gorm.Open(sqlite.Open(filepath.Join(os.TempDir(), "gorm.db")), &gorm.Config{}) - } - - if debug := os.Getenv("DEBUG"); debug == "true" { - db.Logger = db.Logger.LogMode(logger.Info) - } else if debug == "false" { - db.Logger = db.Logger.LogMode(logger.Silent) - } - - return -} - -func RunMigrations() { - var err error - allModels := []interface{}{&User{}, &Account{}, &Pet{}, &Company{}, &Toy{}, &Language{}} - rand.Seed(time.Now().UnixNano()) - rand.Shuffle(len(allModels), func(i, j int) { allModels[i], allModels[j] = allModels[j], allModels[i] }) - - DB.Migrator().DropTable("user_friends", "user_speaks") - - if err = DB.Migrator().DropTable(allModels...); err != nil { - log.Printf("Failed to drop table, got error %v\n", err) - os.Exit(1) - } - - if err = DB.AutoMigrate(allModels...); err != nil { - log.Printf("Failed to auto migrate, but got error %v\n", err) - os.Exit(1) - } - - for _, m := range allModels { - if !DB.Migrator().HasTable(m) { - log.Printf("Failed to create table for %#v\n", m) - os.Exit(1) - } - } -} diff --git a/gen.go b/gen.go index 3127d5d6..ac7d45ab 100644 --- a/gen.go +++ b/gen.go @@ -1,10 +1,18 @@ package main import ( + "gorm.io/driver/mysql" "gorm.io/gen" - "gorm.io/gen/examples/dal" + "gorm.io/gorm" + "playground/model" ) +var db *gorm.DB + +func init() { + db, _ = gorm.Open(mysql.Open("root:secret@(localhost:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local")) +} + func generate() { g := gen.NewGenerator(gen.Config{ OutPath: "./dal/query", @@ -12,10 +20,9 @@ func generate() { WithUnitTest: true, }) - g.UseDB(dal.DB) + g.UseDB(db) - g.ApplyBasic(Company{}, Language{}) // Associations - g.ApplyBasic(g.GenerateModel("user"), g.GenerateModelAs("account", "AccountInfo")) + g.ApplyBasic(model.User{}) g.Execute() } diff --git a/gen_test.go b/gen_test.go new file mode 100644 index 00000000..125f384a --- /dev/null +++ b/gen_test.go @@ -0,0 +1,55 @@ +/** + * @Author: liuzhan (lz@ifreedom.top) + * @Description: gen_test.go + * @Version: 1.0.0 + * @Date: 2024/11/7 15:09 + */ + +package main + +import ( + "context" + "playground/dal/query" + "playground/model" + "testing" +) + +func TestGEN(t *testing.T) { + generate() +} + +func TestPl(t *testing.T) { + ctx := context.Background() + qUser := query.Use(db).User + // 创建一个新的用户 + newUser := &model.User{ + Username: "test", + } + if err := qUser.WithContext(ctx).Create(newUser); err != nil { + t.Error(err) + } + // 更新所有状态为0 + if _, err := qUser.WithContext(ctx).Where(qUser.Status.Gt(0)).Update(qUser.Status, 0); err != nil { + t.Error(err) + } + + // 查询当前用户状态 + user, err := qUser.WithContext(ctx).Debug().Where(qUser.ID.Eq(newUser.ID)).First() + if err != nil { + t.Error(err) + } + t.Logf("befer save status: %d", user.Status) + + // 修改username并使用 save 保存 + user.Username = "test2" + if err = qUser.WithContext(ctx).Debug().Save(user); err != nil { + t.Error(err) + } + + // 查询最新的状态 + user, err = qUser.WithContext(ctx).Where(qUser.ID.Eq(newUser.ID)).First() + if err != nil { + t.Error(err) + } + t.Logf("after save status: %d", user.Status) +} diff --git a/go.mod b/go.mod index 159394d4..b66c052e 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module gorm.io/playground +module playground go 1.20 @@ -7,8 +7,9 @@ require ( gorm.io/driver/postgres v1.5.2 gorm.io/driver/sqlite v1.5.3 gorm.io/driver/sqlserver v1.5.1 - gorm.io/gen v0.3.25 - gorm.io/gorm v1.25.4 + gorm.io/gen v0.3.26 + gorm.io/gorm v1.25.11 + gorm.io/plugin/dbresolver v1.5.0 ) require ( @@ -25,11 +26,8 @@ require ( golang.org/x/crypto v0.14.0 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/sys v0.14.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.17.0 // indirect gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c // indirect gorm.io/hints v1.1.0 // indirect - gorm.io/plugin/dbresolver v1.5.0 // indirect ) - -replace gorm.io/gorm => ./gorm diff --git a/main_test.go b/main_test.go deleted file mode 100644 index 60a388f7..00000000 --- a/main_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "testing" -) - -// GORM_REPO: https://github.com/go-gorm/gorm.git -// GORM_BRANCH: master -// TEST_DRIVERS: sqlite, mysql, postgres, sqlserver - -func TestGORM(t *testing.T) { - user := User{Name: "jinzhu"} - - DB.Create(&user) - - var result User - if err := DB.First(&result, user.ID).Error; err != nil { - t.Errorf("Failed, got error: %v", err) - } -} diff --git a/model/models.go b/model/models.go new file mode 100644 index 00000000..ef4cdfe6 --- /dev/null +++ b/model/models.go @@ -0,0 +1,15 @@ +package model + +import ( + "gorm.io/gorm" +) + +type User struct { + gorm.Model + Username string `gorm:"column:username;not null;" json:"username"` + Status int `gorm:"column:status;not null;default:1" json:"status"` +} + +func (User) TableName() string { + return "gorm_test_user_tmp" +} diff --git a/models.go b/models.go deleted file mode 100644 index 692a6842..00000000 --- a/models.go +++ /dev/null @@ -1,60 +0,0 @@ -package main - -import ( - "database/sql" - "time" - - "gorm.io/gorm" -) - -// User has one `Account` (has one), many `Pets` (has many) and `Toys` (has many - polymorphic) -// He works in a Company (belongs to), he has a Manager (belongs to - single-table), and also managed a Team (has many - single-table) -// He speaks many languages (many to many) and has many friends (many to many - single-table) -// His pet also has one Toy (has one - polymorphic) -type User struct { - gorm.Model - Name string - Age uint - Birthday *time.Time - Account Account - Pets []*Pet - Toys []Toy `gorm:"polymorphic:Owner"` - CompanyID *int - Company Company - ManagerID *uint - Manager *User - Team []User `gorm:"foreignkey:ManagerID"` - Languages []Language `gorm:"many2many:UserSpeak"` - Friends []*User `gorm:"many2many:user_friends"` - Active bool -} - -type Account struct { - gorm.Model - UserID sql.NullInt64 - Number string -} - -type Pet struct { - gorm.Model - UserID *uint - Name string - Toy Toy `gorm:"polymorphic:Owner;"` -} - -type Toy struct { - gorm.Model - Name string - OwnerID string - OwnerType string -} - -type Company struct { - ID int - Name string -} - -type Language struct { - Code string `gorm:"primarykey"` - Name string -}