From 5ab959ba58d360a4f4f6af867683b74767ba5b2e Mon Sep 17 00:00:00 2001 From: John Guo Date: Wed, 16 Feb 2022 00:26:06 +0800 Subject: [PATCH] fix issue #1554 --- database/gdb/gdb.go | 10 +++--- database/gdb/gdb_core.go | 4 +-- database/gdb/gdb_core_config.go | 9 +---- database/gdb/gdb_driver_mysql.go | 2 +- database/gdb/gdb_model.go | 1 + database/gdb/gdb_model_select.go | 6 +++- database/gdb/gdb_schema.go | 43 ++++++----------------- database/gdb/gdb_z_init_test.go | 6 ++-- database/gdb/gdb_z_mysql_internal_test.go | 4 +-- database/gdb/gdb_z_mysql_model_test.go | 25 +++++++------ 10 files changed, 41 insertions(+), 69 deletions(-) diff --git a/database/gdb/gdb.go b/database/gdb/gdb.go index 7c8a2905e..3db918764 100644 --- a/database/gdb/gdb.go +++ b/database/gdb/gdb.go @@ -48,12 +48,12 @@ type DB interface { // Also see Core.Schema. Schema(schema string) *Schema - // With creates and returns an ORM model based on meta data of given object. + // With creates and returns an ORM model based on metadata of given object. // Also see Core.With. With(objects ...interface{}) *Model // Open creates a raw connection object for database with given node configuration. - // Note that it is not recommended using the this function manually. + // Note that it is not recommended using the function manually. // Also see DriverMysql.Open. Open(config *ConfigNode) (*sql.DB, error) @@ -145,7 +145,6 @@ type DB interface { GetCache() *gcache.Cache // See Core.GetCache. SetDebug(debug bool) // See Core.SetDebug. GetDebug() bool // See Core.GetDebug. - SetSchema(schema string) // See Core.SetSchema. GetSchema() string // See Core.GetSchema. GetPrefix() string // See Core.GetPrefix. GetGroup() string // See Core.GetGroup. @@ -176,10 +175,10 @@ type Core struct { db DB // DB interface object. ctx context.Context // Context for chaining operation only. Do not set a default value in Core initialization. group string // Configuration group name. + schema string // Custom schema for this object. debug *gtype.Bool // Enable debug mode for the database, which can be changed in runtime. cache *gcache.Cache // Cache manager, SQL result cache only. links *gmap.StrAnyMap // links caches all created links by node. - schema *gtype.String // Custom schema for this object. logger *glog.Logger // Logger for logging functionality. config *ConfigNode // Current config node. } @@ -399,7 +398,6 @@ func doNewByNode(node ConfigNode, group string) (db DB, err error) { debug: gtype.NewBool(), cache: gcache.New(), links: gmap.NewStrAnyMap(true), - schema: gtype.NewString(), logger: glog.New(), config: &node, } @@ -536,7 +534,7 @@ func (c *Core) getSqlDb(master bool, schema ...string) (sqlDb *sql.DB, err error node.Charset = defaultCharset } // Changes the schema. - nodeSchema := c.schema.Val() + nodeSchema := c.schema if len(schema) > 0 && schema[0] != "" { nodeSchema = schema[0] } diff --git a/database/gdb/gdb_core.go b/database/gdb/gdb_core.go index 018fb8ff6..255b67c77 100644 --- a/database/gdb/gdb_core.go +++ b/database/gdb/gdb_core.go @@ -125,7 +125,7 @@ func (c *Core) Master(schema ...string) (*sql.DB, error) { if len(schema) > 0 && schema[0] != "" { useSchema = schema[0] } else { - useSchema = c.schema.Val() + useSchema = c.schema } return c.getSqlDb(true, useSchema) } @@ -137,7 +137,7 @@ func (c *Core) Slave(schema ...string) (*sql.DB, error) { if len(schema) > 0 && schema[0] != "" { useSchema = schema[0] } else { - useSchema = c.schema.Val() + useSchema = c.schema } return c.getSqlDb(false, useSchema) } diff --git a/database/gdb/gdb_core_config.go b/database/gdb/gdb_core_config.go index c08e5bb4a..451a14926 100644 --- a/database/gdb/gdb_core_config.go +++ b/database/gdb/gdb_core_config.go @@ -230,14 +230,7 @@ func (c *Core) GetPrefix() string { return c.config.Prefix } -// SetSchema changes the schema for this database connection object. -// Importantly note that when schema configuration changed for the database, -// it affects all operations on the database object in the future. -func (c *Core) SetSchema(schema string) { - c.schema.Set(schema) -} - // GetSchema returns the schema configured. func (c *Core) GetSchema() string { - return c.schema.Val() + return c.schema } diff --git a/database/gdb/gdb_driver_mysql.go b/database/gdb/gdb_driver_mysql.go index 66589d88e..cbfff2434 100644 --- a/database/gdb/gdb_driver_mysql.go +++ b/database/gdb/gdb_driver_mysql.go @@ -133,7 +133,7 @@ func (d *DriverMysql) TableFields(ctx context.Context, table string, schema ...s "function TableFields supports only single table operations", ) } - useSchema := d.schema.Val() + useSchema := d.schema if len(schema) > 0 && schema[0] != "" { useSchema = schema[0] } diff --git a/database/gdb/gdb_model.go b/database/gdb/gdb_model.go index c51fe2d7b..b1c1e8196 100644 --- a/database/gdb/gdb_model.go +++ b/database/gdb/gdb_model.go @@ -132,6 +132,7 @@ func (c *Core) Model(tableNameQueryOrStruct ...interface{}) *Model { } m := &Model{ db: c.db, + schema: c.schema, tablesInit: tableStr, tables: tableStr, fields: defaultFields, diff --git a/database/gdb/gdb_model_select.go b/database/gdb/gdb_model_select.go index e1ce7e64d..2fcc84b2d 100644 --- a/database/gdb/gdb_model_select.go +++ b/database/gdb/gdb_model_select.go @@ -513,7 +513,11 @@ func (m *Model) doGetAllBySql(sql string, args ...interface{}) (result Result, e if m.cacheEnabled && m.tx == nil { cacheKey = m.cacheOption.Name if len(cacheKey) == 0 { - cacheKey = "GCache:" + gmd5.MustEncryptString(sql+", @PARAMS:"+gconv.String(args)) + cacheKey = fmt.Sprintf( + `GCache@Schema(%s):%s`, + m.db.GetSchema(), + gmd5.MustEncryptString(sql+", @PARAMS:"+gconv.String(args)), + ) } if v, _ := cacheObj.Get(ctx, cacheKey); !v.IsNil() { if result, ok = v.Val().(Result); ok { diff --git a/database/gdb/gdb_schema.go b/database/gdb/gdb_schema.go index 242b15a52..75012e3dc 100644 --- a/database/gdb/gdb_schema.go +++ b/database/gdb/gdb_schema.go @@ -8,46 +8,23 @@ package gdb // Schema is a schema object from which it can then create a Model. type Schema struct { - db DB - tx *TX - schema string + DB } // Schema creates and returns a schema. func (c *Core) Schema(schema string) *Schema { - return &Schema{ - db: c.db, - schema: schema, - } -} - -// Schema creates and returns a initialization model from schema, -// from which it can then create a Model. -func (tx *TX) Schema(schema string) *Schema { - return &Schema{ - tx: tx, - schema: schema, - } -} - -// Model creates and returns a new ORM model. -// The parameter `tables` can be more than one table names, like : -// "user", "user u", "user, user_detail", "user u, user_detail ud". -func (s *Schema) Model(table string) *Model { - var m *Model - if s.tx != nil { - m = s.tx.Model(table) - } else { - m = s.db.Model(table) - } // Do not change the schema of the original db, // it here creates a new db and changes its schema. - db, err := NewByGroup(m.db.GetGroup()) + db, err := NewByGroup(c.GetGroup()) if err != nil { panic(err) } - db.SetSchema(s.schema) - m.db = db - m.schema = s.schema - return m + core := db.GetCore() + // Different schema share some same objects. + core.logger = c.logger + core.cache = c.cache + core.schema = schema + return &Schema{ + DB: db, + } } diff --git a/database/gdb/gdb_z_init_test.go b/database/gdb/gdb_z_init_test.go index cf4fbcc59..a7541c8a3 100644 --- a/database/gdb/gdb_z_init_test.go +++ b/database/gdb/gdb_z_init_test.go @@ -81,7 +81,7 @@ func init() { if _, err := db.Exec(ctx, fmt.Sprintf(schemaTemplate, TestSchema2)); err != nil { gtest.Error(err) } - db.SetSchema(TestSchema1) + db = db.Schema(TestSchema1) // Prefix db. if r, err := gdb.NewByGroup("prefix"); err != nil { @@ -95,7 +95,7 @@ func init() { if _, err := dbPrefix.Exec(ctx, fmt.Sprintf(schemaTemplate, TestSchema2)); err != nil { gtest.Error(err) } - dbPrefix.SetSchema(TestSchema1) + dbPrefix = dbPrefix.Schema(TestSchema1) // Invalid db. if r, err := gdb.NewByGroup("nodeinvalid"); err != nil { @@ -103,7 +103,7 @@ func init() { } else { dbInvalid = r } - dbInvalid.SetSchema(TestSchema1) + dbInvalid = dbInvalid.Schema(TestSchema1) } func createTable(table ...string) string { diff --git a/database/gdb/gdb_z_mysql_internal_test.go b/database/gdb/gdb_z_mysql_internal_test.go index 208562567..4bbedc16c 100644 --- a/database/gdb/gdb_z_mysql_internal_test.go +++ b/database/gdb/gdb_z_mysql_internal_test.go @@ -57,10 +57,10 @@ func init() { db = r } schemaTemplate := "CREATE DATABASE IF NOT EXISTS `%s` CHARACTER SET UTF8" - if _, err := db.Exec(ctx, fmt.Sprintf(schemaTemplate, SCHEMA)); err != nil { + if _, err = db.Exec(ctx, fmt.Sprintf(schemaTemplate, SCHEMA)); err != nil { gtest.Error(err) } - db.SetSchema(SCHEMA) + db = db.Schema(SCHEMA) } func dropTable(table string) { diff --git a/database/gdb/gdb_z_mysql_model_test.go b/database/gdb/gdb_z_mysql_model_test.go index 4303b3230..7af800d37 100644 --- a/database/gdb/gdb_z_mysql_model_test.go +++ b/database/gdb/gdb_z_mysql_model_test.go @@ -2255,22 +2255,21 @@ func Test_Model_Prefix(t *testing.T) { func Test_Model_Schema1(t *testing.T) { // db.SetDebug(true) - db.SetSchema(TestSchema1) + db = db.Schema(TestSchema1) table := fmt.Sprintf(`%s_%s`, TableName, gtime.TimestampNanoStr()) createInitTableWithDb(db, table) - db.SetSchema(TestSchema2) + db = db.Schema(TestSchema2) createInitTableWithDb(db, table) defer func() { - db.SetSchema(TestSchema1) + db = db.Schema(TestSchema1) dropTableWithDb(db, table) - db.SetSchema(TestSchema2) + db = db.Schema(TestSchema2) dropTableWithDb(db, table) - - db.SetSchema(TestSchema1) + db = db.Schema(TestSchema1) }() // Method. gtest.C(t, func(t *gtest.T) { - db.SetSchema(TestSchema1) + db = db.Schema(TestSchema1) r, err := db.Model(table).Update(g.Map{"nickname": "name_100"}, "id=1") t.AssertNil(err) n, _ := r.RowsAffected() @@ -2280,7 +2279,7 @@ func Test_Model_Schema1(t *testing.T) { t.AssertNil(err) t.Assert(v.String(), "name_100") - db.SetSchema(TestSchema2) + db = db.Schema(TestSchema2) v, err = db.Model(table).Value("nickname", "id=1") t.AssertNil(err) t.Assert(v.String(), "name_1") @@ -2334,18 +2333,18 @@ func Test_Model_Schema1(t *testing.T) { func Test_Model_Schema2(t *testing.T) { // db.SetDebug(true) - db.SetSchema(TestSchema1) + db = db.Schema(TestSchema1) table := fmt.Sprintf(`%s_%s`, TableName, gtime.TimestampNanoStr()) createInitTableWithDb(db, table) - db.SetSchema(TestSchema2) + db = db.Schema(TestSchema2) createInitTableWithDb(db, table) defer func() { - db.SetSchema(TestSchema1) + db = db.Schema(TestSchema1) dropTableWithDb(db, table) - db.SetSchema(TestSchema2) + db = db.Schema(TestSchema2) dropTableWithDb(db, table) - db.SetSchema(TestSchema1) + db = db.Schema(TestSchema1) }() // Schema. gtest.C(t, func(t *gtest.T) {