From 8aa7f0835090b208fe74f8ec763da7a260e7201b Mon Sep 17 00:00:00 2001 From: John Guo Date: Fri, 4 Jun 2021 09:54:19 +0800 Subject: [PATCH] improve DB interface for package gdb --- .example/database/gdb/driver/driver/driver.go | 15 +++++---------- database/gdb/gdb.go | 13 +++++++++++++ database/gdb/gdb_core.go | 18 +++++++++--------- database/gdb/gdb_core_transaction.go | 6 +++--- database/gdb/gdb_core_underlying.go | 6 +++--- database/gdb/gdb_model_delete.go | 4 ++-- database/gdb/gdb_model_insert.go | 4 ++-- database/gdb/gdb_model_select.go | 2 +- database/gdb/gdb_model_update.go | 2 +- 9 files changed, 39 insertions(+), 31 deletions(-) diff --git a/.example/database/gdb/driver/driver/driver.go b/.example/database/gdb/driver/driver/driver.go index 5fd86304d..71af8399d 100644 --- a/.example/database/gdb/driver/driver/driver.go +++ b/.example/database/gdb/driver/driver/driver.go @@ -1,12 +1,7 @@ -// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://github.com/gogf/gf. - package driver import ( + "context" "database/sql" "github.com/gogf/gf/database/gdb" "github.com/gogf/gf/os/gtime" @@ -47,9 +42,9 @@ func (d *MyDriver) New(core *gdb.Core, node *gdb.ConfigNode) (gdb.DB, error) { // DoQuery commits the sql string and its arguments to underlying driver // through given link object and returns the execution result. -func (d *MyDriver) DoQuery(link gdb.Link, sql string, args ...interface{}) (rows *sql.Rows, err error) { +func (d *MyDriver) DoQuery(ctx context.Context, link gdb.Link, sql string, args ...interface{}) (rows *sql.Rows, err error) { tsMilli := gtime.TimestampMilli() - rows, err = d.DriverMysql.DoQuery(link, sql, args...) + rows, err = d.DriverMysql.DoQuery(ctx, link, sql, args...) link.Exec( "INSERT INTO `monitor`(`sql`,`cost`,`time`,`error`) VALUES(?,?,?,?)", gdb.FormatSqlWithArgs(sql, args), @@ -62,9 +57,9 @@ func (d *MyDriver) DoQuery(link gdb.Link, sql string, args ...interface{}) (rows // DoExec commits the query string and its arguments to underlying driver // through given link object and returns the execution result. -func (d *MyDriver) DoExec(link gdb.Link, sql string, args ...interface{}) (result sql.Result, err error) { +func (d *MyDriver) DoExec(ctx context.Context, link gdb.Link, sql string, args ...interface{}) (result sql.Result, err error) { tsMilli := gtime.TimestampMilli() - result, err = d.DriverMysql.DoExec(link, sql, args...) + result, err = d.DriverMysql.DoExec(ctx, link, sql, args...) link.Exec( "INSERT INTO `monitor`(`sql`,`cost`,`time`,`error`) VALUES(?,?,?,?)", gdb.FormatSqlWithArgs(sql, args), diff --git a/database/gdb/gdb.go b/database/gdb/gdb.go index d543bdb11..ab415021a 100644 --- a/database/gdb/gdb.go +++ b/database/gdb/gdb.go @@ -96,6 +96,19 @@ type DB interface { Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error) // See Core.Update. Delete(table string, condition interface{}, args ...interface{}) (sql.Result, error) // See Core.Delete. + // =========================================================================== + // Internal APIs for CURD, which can be overwrote for custom CURD implements. + // =========================================================================== + + DoQuery(ctx context.Context, link Link, sql string, args ...interface{}) (rows *sql.Rows, err error) // See Core.DoQuery. + DoExec(ctx context.Context, link Link, sql string, args ...interface{}) (result sql.Result, err error) // See Core.DoExec. + DoPrepare(ctx context.Context, link Link, sql string) (*Stmt, error) // See Core.DoPrepare. + DoGetAll(ctx context.Context, link Link, sql string, args ...interface{}) (result Result, err error) // See Core.DoGetAll. + DoInsert(ctx context.Context, link Link, table string, data interface{}, option int, batch ...int) (result sql.Result, err error) // See Core.DoInsert. + DoBatchInsert(ctx context.Context, link Link, table string, list interface{}, option int, batch ...int) (result sql.Result, err error) // See Core.DoBatchInsert. + DoUpdate(ctx context.Context, link Link, table string, data interface{}, condition string, args ...interface{}) (result sql.Result, err error) // See Core.DoUpdate. + DoDelete(ctx context.Context, link Link, table string, condition string, args ...interface{}) (result sql.Result, err error) // See Core.DoDelete. + // =========================================================================== // Query APIs for convenience purpose. // =========================================================================== diff --git a/database/gdb/gdb_core.go b/database/gdb/gdb_core.go index a275ef2bd..84d50bbd9 100644 --- a/database/gdb/gdb_core.go +++ b/database/gdb/gdb_core.go @@ -119,12 +119,12 @@ func (c *Core) Slave(schema ...string) (*sql.DB, error) { // GetAll queries and returns data records from database. func (c *Core) GetAll(sql string, args ...interface{}) (Result, error) { - return c.DoGetAll(c.GetCtx(), nil, sql, args...) + return c.db.DoGetAll(c.GetCtx(), nil, sql, args...) } // DoGetAll queries and returns data records from database. func (c *Core) DoGetAll(ctx context.Context, link Link, sql string, args ...interface{}) (result Result, err error) { - rows, err := c.DoQuery(ctx, link, sql, args...) + rows, err := c.db.DoQuery(ctx, link, sql, args...) if err != nil || rows == nil { return nil, err } @@ -147,7 +147,7 @@ func (c *Core) GetOne(sql string, args ...interface{}) (Record, error) { // GetArray queries and returns data values as slice from database. // Note that if there are multiple columns in the result, it returns just one column values randomly. func (c *Core) GetArray(sql string, args ...interface{}) ([]Value, error) { - all, err := c.DoGetAll(c.GetCtx(), nil, sql, args...) + all, err := c.db.DoGetAll(c.GetCtx(), nil, sql, args...) if err != nil { return nil, err } @@ -347,10 +347,10 @@ func (c *Core) DoInsert(ctx context.Context, link Link, table string, data inter } switch reflectKind { case reflect.Slice, reflect.Array: - return c.DoBatchInsert(ctx, link, table, data, option, batch...) + return c.db.DoBatchInsert(ctx, link, table, data, option, batch...) case reflect.Struct: if _, ok := data.(apiInterfaces); ok { - return c.DoBatchInsert(ctx, link, table, data, option, batch...) + return c.db.DoBatchInsert(ctx, link, table, data, option, batch...) } else { dataMap = ConvertDataForTableRecord(data) } @@ -399,7 +399,7 @@ func (c *Core) DoInsert(ctx context.Context, link Link, table string, data inter return nil, err } } - return c.DoExec(ctx, link, fmt.Sprintf( + return c.db.DoExec(ctx, link, fmt.Sprintf( "%s INTO %s(%s) VALUES(%s) %s", operation, table, strings.Join(fields, ","), strings.Join(values, ","), updateStr, @@ -556,7 +556,7 @@ func (c *Core) DoBatchInsert(ctx context.Context, link Link, table string, list } valueHolder = append(valueHolder, "("+gstr.Join(values, ",")+")") if len(valueHolder) == batchNum || (i == listMapLen-1 && len(valueHolder) > 0) { - r, err := c.DoExec(ctx, link, fmt.Sprintf( + r, err := c.db.DoExec(ctx, link, fmt.Sprintf( "%s INTO %s(%s) VALUES%s %s", operation, table, keysStr, gstr.Join(valueHolder, ","), @@ -663,7 +663,7 @@ func (c *Core) DoUpdate(ctx context.Context, link Link, table string, data inter return nil, err } } - return c.DoExec(ctx, link, fmt.Sprintf("UPDATE %s SET %s%s", table, updates, condition), args...) + return c.db.DoExec(ctx, link, fmt.Sprintf("UPDATE %s SET %s%s", table, updates, condition), args...) } // Delete does "DELETE FROM ... " statement for the table. @@ -690,7 +690,7 @@ func (c *Core) DoDelete(ctx context.Context, link Link, table string, condition } } table = c.QuotePrefixTableName(table) - return c.DoExec(ctx, link, fmt.Sprintf("DELETE FROM %s%s", table, condition), args...) + return c.db.DoExec(ctx, link, fmt.Sprintf("DELETE FROM %s%s", table, condition), args...) } // convertRowsToResult converts underlying data record type sql.Rows to Result type. diff --git a/database/gdb/gdb_core_transaction.go b/database/gdb/gdb_core_transaction.go index 4636d9166..d9e575ce8 100644 --- a/database/gdb/gdb_core_transaction.go +++ b/database/gdb/gdb_core_transaction.go @@ -317,13 +317,13 @@ func (tx *TX) Transaction(ctx context.Context, f func(ctx context.Context, tx *T // Query does query operation on transaction. // See Core.Query. func (tx *TX) Query(sql string, args ...interface{}) (rows *sql.Rows, err error) { - return tx.db.GetCore().DoQuery(tx.ctx, &txLink{tx.tx}, sql, args...) + return tx.db.DoQuery(tx.ctx, &txLink{tx.tx}, sql, args...) } // Exec does none query operation on transaction. // See Core.Exec. func (tx *TX) Exec(sql string, args ...interface{}) (sql.Result, error) { - return tx.db.GetCore().DoExec(tx.ctx, &txLink{tx.tx}, sql, args...) + return tx.db.DoExec(tx.ctx, &txLink{tx.tx}, sql, args...) } // Prepare creates a prepared statement for later queries or executions. @@ -332,7 +332,7 @@ func (tx *TX) Exec(sql string, args ...interface{}) (sql.Result, error) { // The caller must call the statement's Close method // when the statement is no longer needed. func (tx *TX) Prepare(sql string) (*Stmt, error) { - return tx.db.GetCore().DoPrepare(tx.ctx, &txLink{tx.tx}, sql) + return tx.db.DoPrepare(tx.ctx, &txLink{tx.tx}, sql) } // GetAll queries and returns data records from database. diff --git a/database/gdb/gdb_core_underlying.go b/database/gdb/gdb_core_underlying.go index 316127df0..baa0e5027 100644 --- a/database/gdb/gdb_core_underlying.go +++ b/database/gdb/gdb_core_underlying.go @@ -17,7 +17,7 @@ import ( // Query commits one query SQL to underlying driver and returns the execution result. // It is most commonly used for data querying. func (c *Core) Query(sql string, args ...interface{}) (rows *sql.Rows, err error) { - return c.DoQuery(c.GetCtx(), nil, sql, args...) + return c.db.DoQuery(c.GetCtx(), nil, sql, args...) } // DoQuery commits the sql string and its arguments to underlying driver @@ -69,7 +69,7 @@ func (c *Core) DoQuery(ctx context.Context, link Link, sql string, args ...inter // Exec commits one query SQL to underlying driver and returns the execution result. // It is most commonly used for data inserting and updating. func (c *Core) Exec(sql string, args ...interface{}) (result sql.Result, err error) { - return c.DoExec(c.GetCtx(), nil, sql, args...) + return c.db.DoExec(c.GetCtx(), nil, sql, args...) } // DoExec commits the sql string and its arguments to underlying driver @@ -142,7 +142,7 @@ func (c *Core) Prepare(sql string, execOnMaster ...bool) (*Stmt, error) { return nil, err } } - return c.DoPrepare(c.GetCtx(), link, sql) + return c.db.DoPrepare(c.GetCtx(), link, sql) } // DoPrepare calls prepare function on given link object and returns the statement object. diff --git a/database/gdb/gdb_model_delete.go b/database/gdb/gdb_model_delete.go index 2ce680444..1e08d68da 100644 --- a/database/gdb/gdb_model_delete.go +++ b/database/gdb/gdb_model_delete.go @@ -33,7 +33,7 @@ func (m *Model) Delete(where ...interface{}) (result sql.Result, err error) { ) // Soft deleting. if !m.unscoped && fieldNameDelete != "" { - return m.db.GetCore().DoUpdate( + return m.db.DoUpdate( m.GetCtx(), m.getLink(true), m.tables, @@ -46,5 +46,5 @@ func (m *Model) Delete(where ...interface{}) (result sql.Result, err error) { if !gstr.ContainsI(conditionStr, " WHERE ") { return nil, gerror.New("there should be WHERE condition statement for DELETE operation") } - return m.db.GetCore().DoDelete(m.GetCtx(), m.getLink(true), m.tables, conditionStr, conditionArgs...) + return m.db.DoDelete(m.GetCtx(), m.getLink(true), m.tables, conditionStr, conditionArgs...) } diff --git a/database/gdb/gdb_model_insert.go b/database/gdb/gdb_model_insert.go index 3062354fa..09001e7d3 100644 --- a/database/gdb/gdb_model_insert.go +++ b/database/gdb/gdb_model_insert.go @@ -195,7 +195,7 @@ func (m *Model) doInsertWithOption(option int) (result sql.Result, err error) { list[k] = v } } - return m.db.GetCore().DoBatchInsert( + return m.db.DoBatchInsert( m.GetCtx(), m.getLink(true), m.tables, @@ -221,7 +221,7 @@ func (m *Model) doInsertWithOption(option int) (result sql.Result, err error) { data[fieldNameUpdate] = nowString } } - return m.db.GetCore().DoInsert( + return m.db.DoInsert( m.GetCtx(), m.getLink(true), m.tables, diff --git a/database/gdb/gdb_model_select.go b/database/gdb/gdb_model_select.go index 041cb65e9..ff366f218 100644 --- a/database/gdb/gdb_model_select.go +++ b/database/gdb/gdb_model_select.go @@ -483,7 +483,7 @@ func (m *Model) doGetAllBySql(sql string, args ...interface{}) (result Result, e } } } - result, err = m.db.GetCore().DoGetAll( + result, err = m.db.DoGetAll( m.GetCtx(), m.getLink(false), sql, m.mergeArguments(args)..., ) // Cache the result. diff --git a/database/gdb/gdb_model_update.go b/database/gdb/gdb_model_update.go index 8252789e3..b32d1f5f8 100644 --- a/database/gdb/gdb_model_update.go +++ b/database/gdb/gdb_model_update.go @@ -82,7 +82,7 @@ func (m *Model) Update(dataAndWhere ...interface{}) (result sql.Result, err erro if !gstr.ContainsI(conditionStr, " WHERE ") { return nil, gerror.New("there should be WHERE condition statement for UPDATE operation") } - return m.db.GetCore().DoUpdate( + return m.db.DoUpdate( m.GetCtx(), m.getLink(true), m.tables,