diff --git a/database/gdb/gdb_core.go b/database/gdb/gdb_core.go index ab11e9b66..675dc809f 100644 --- a/database/gdb/gdb_core.go +++ b/database/gdb/gdb_core.go @@ -353,7 +353,7 @@ func (c *Core) Save(table string, data interface{}, batch ...int) (sql.Result, e return c.Model(table).Data(data).Save() } -// DoInsert inserts or updates data for given table. +// DoInsert inserts or updates data forF given table. // This function is usually used for custom interface definition, you do not need call it manually. // The parameter `data` can be type of map/gmap/struct/*struct/[]map/[]struct, etc. // Eg: diff --git a/database/gdb/gdb_driver_mssql.go b/database/gdb/gdb_driver_mssql.go index 24156605c..f56c2f966 100644 --- a/database/gdb/gdb_driver_mssql.go +++ b/database/gdb/gdb_driver_mssql.go @@ -287,3 +287,17 @@ ORDER BY a.id,a.colorder`, } return } + +// DoInsert is not supported in mssql. +func (d *DriverMssql) DoInsert(ctx context.Context, link Link, table string, list List, option DoInsertOption) (result sql.Result, err error) { + switch option.InsertOption { + case insertOptionSave: + return nil, gerror.New(`Save operation is not supported by mssql driver`) + + case insertOptionReplace: + return nil, gerror.New(`Replace operation is not supported by mssql driver`) + + default: + return d.Core.DoInsert(ctx, link, table, list, option) + } +} diff --git a/database/gdb/gdb_driver_oracle.go b/database/gdb/gdb_driver_oracle.go index 8c175f228..7ea5fcd54 100644 --- a/database/gdb/gdb_driver_oracle.go +++ b/database/gdb/gdb_driver_oracle.go @@ -263,7 +263,27 @@ func (d *DriverOracle) getTableUniqueIndex(table string) (fields map[string]map[ return } +// DoInsert inserts or updates data for given table. +// This function is usually used for custom interface definition, you do not need call it manually. +// The parameter `data` can be type of map/gmap/struct/*struct/[]map/[]struct, etc. +// Eg: +// Data(g.Map{"uid": 10000, "name":"john"}) +// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"}) +// +// The parameter `option` values are as follows: +// 0: insert: just insert, if there's unique/primary key in the data, it returns error; +// 1: replace: if there's unique/primary key in the data, it deletes it from table and inserts a new one; +// 2: save: if there's unique/primary key in the data, it updates it or else inserts a new one; +// 3: ignore: if there's unique/primary key in the data, it ignores the inserting; func (d *DriverOracle) DoInsert(ctx context.Context, link Link, table string, list List, option DoInsertOption) (result sql.Result, err error) { + switch option.InsertOption { + case insertOptionSave: + return nil, gerror.New(`Save operation is not supported by mssql driver`) + + case insertOptionReplace: + return nil, gerror.New(`Replace operation is not supported by mssql driver`) + } + var ( keys []string values []string diff --git a/database/gdb/gdb_driver_pgsql.go b/database/gdb/gdb_driver_pgsql.go index 6778ed760..961242426 100644 --- a/database/gdb/gdb_driver_pgsql.go +++ b/database/gdb/gdb_driver_pgsql.go @@ -172,3 +172,17 @@ ORDER BY a.attnum`, } return } + +// DoInsert is not supported in pgsql. +func (d *DriverPgsql) DoInsert(ctx context.Context, link Link, table string, list List, option DoInsertOption) (result sql.Result, err error) { + switch option.InsertOption { + case insertOptionSave: + return nil, gerror.New(`Save operation is not supported by pgsql driver`) + + case insertOptionReplace: + return nil, gerror.New(`Replace operation is not supported by pgsql driver`) + + default: + return d.Core.DoInsert(ctx, link, table, list, option) + } +} diff --git a/database/gdb/gdb_driver_sqlite.go b/database/gdb/gdb_driver_sqlite.go index 1ad0f68b3..132fe5c32 100644 --- a/database/gdb/gdb_driver_sqlite.go +++ b/database/gdb/gdb_driver_sqlite.go @@ -136,3 +136,17 @@ func (d *DriverSqlite) TableFields(ctx context.Context, table string, schema ... } return } + +// DoInsert is not supported in sqlite. +func (d *DriverSqlite) DoInsert(ctx context.Context, link Link, table string, list List, option DoInsertOption) (result sql.Result, err error) { + switch option.InsertOption { + case insertOptionSave: + return nil, gerror.New(`Save operation is not supported by sqlite driver`) + + case insertOptionReplace: + return nil, gerror.New(`Replace operation is not supported by sqlite driver`) + + default: + return d.Core.DoInsert(ctx, link, table, list, option) + } +} diff --git a/database/gdb/gdb_func.go b/database/gdb/gdb_func.go index e2a0b4c17..9d9b35899 100644 --- a/database/gdb/gdb_func.go +++ b/database/gdb/gdb_func.go @@ -70,6 +70,31 @@ var ( structTagPriority = append([]string{OrmTagForStruct}, gconv.StructTagPriority...) ) +// guessPrimaryTableName parses and returns the primary table name. +func (m *Model) guessPrimaryTableName(tableStr string) string { + if tableStr == "" { + return "" + } + var ( + guessedTableName = "" + array1 = gstr.SplitAndTrim(tableStr, ",") + array2 = gstr.SplitAndTrim(array1[0], " ") + array3 = gstr.SplitAndTrim(array2[0], ".") + ) + if len(array3) >= 2 { + guessedTableName = array3[1] + } + guessedTableName = array3[0] + charL, charR := m.db.GetChars() + if charL != "" || charR != "" { + guessedTableName = gstr.Trim(guessedTableName, charL+charR) + } + if !gregex.IsMatchString(regularFieldNameRegPattern, guessedTableName) { + return "" + } + return guessedTableName +} + // getTableNameFromOrmTag retrieves and returns the table name from struct object. func getTableNameFromOrmTag(object interface{}) string { var tableName string diff --git a/database/gdb/gdb_model_fields.go b/database/gdb/gdb_model_fields.go index 88d93ce8e..d959a0224 100644 --- a/database/gdb/gdb_model_fields.go +++ b/database/gdb/gdb_model_fields.go @@ -136,7 +136,7 @@ func (m *Model) GetFieldsExStr(fields string, prefix ...string) string { if len(prefix) > 0 { prefixStr = prefix[0] } - tableFields, err := m.TableFields(m.tables) + tableFields, err := m.TableFields(m.tablesInit) if err != nil { panic(err) } diff --git a/database/gdb/gdb_model_time.go b/database/gdb/gdb_model_time.go index 76c1f0667..0ca2a6877 100644 --- a/database/gdb/gdb_model_time.go +++ b/database/gdb/gdb_model_time.go @@ -40,7 +40,7 @@ func (m *Model) getSoftFieldNameCreated(table ...string) string { if len(table) > 0 { tableName = table[0] } else { - tableName = m.getPrimaryTableName() + tableName = m.tablesInit } config := m.db.GetConfig() if config.CreatedAt != "" { @@ -61,7 +61,7 @@ func (m *Model) getSoftFieldNameUpdated(table ...string) (field string) { if len(table) > 0 { tableName = table[0] } else { - tableName = m.getPrimaryTableName() + tableName = m.tablesInit } config := m.db.GetConfig() if config.UpdatedAt != "" { @@ -82,7 +82,7 @@ func (m *Model) getSoftFieldNameDeleted(table ...string) (field string) { if len(table) > 0 { tableName = table[0] } else { - tableName = m.getPrimaryTableName() + tableName = m.tablesInit } config := m.db.GetConfig() if config.UpdatedAt != "" { @@ -170,17 +170,3 @@ func (m *Model) getConditionOfTableStringForSoftDeleting(s string) string { } return fmt.Sprintf(`%s.%s IS NULL`, m.db.GetCore().QuoteWord(table), m.db.GetCore().QuoteWord(field)) } - -// getPrimaryTableName parses and returns the primary table name. -func (m *Model) getPrimaryTableName() string { - if m.tables == "" { - return "" - } - array1 := gstr.SplitAndTrim(m.tables, ",") - array2 := gstr.SplitAndTrim(array1[0], " ") - array3 := gstr.SplitAndTrim(array2[0], ".") - if len(array3) >= 2 { - return array3[1] - } - return array3[0] -} diff --git a/database/gdb/gdb_model_utility.go b/database/gdb/gdb_model_utility.go index 4c6823850..03f5e1ed3 100644 --- a/database/gdb/gdb_model_utility.go +++ b/database/gdb/gdb_model_utility.go @@ -21,15 +21,12 @@ import ( // schema. // // Also see DriverMysql.TableFields. -func (m *Model) TableFields(table string, schema ...string) (fields map[string]*TableField, err error) { - charL, charR := m.db.GetChars() - if charL != "" || charR != "" { - table = gstr.Trim(table, charL+charR) +func (m *Model) TableFields(tableStr string, schema ...string) (fields map[string]*TableField, err error) { + useSchema := m.schema + if len(schema) > 0 && schema[0] != "" { + useSchema = schema[0] } - if !gregex.IsMatchString(regularFieldNameRegPattern, table) { - return nil, nil - } - return m.db.TableFields(m.GetCtx(), table, schema...) + return m.db.TableFields(m.GetCtx(), m.guessPrimaryTableName(tableStr), useSchema) } // getModel creates and returns a cloned model of current model if `safe` is true, or else it returns