diff --git a/.example/database/gdb/driver/driver/driver.go b/.example/database/gdb/driver/driver/driver.go index acb2bca93..f672730d4 100644 --- a/.example/database/gdb/driver/driver/driver.go +++ b/.example/database/gdb/driver/driver/driver.go @@ -15,9 +15,9 @@ import ( // MyDriver is a custom database driver, which is used for testing only. // For simplifying the unit testing case purpose, MyDriver struct inherits the mysql driver -// gdb.DriverMysql and overwrites its function HandleSqlBeforeCommit. -// So if there's any sql execution, it goes through MyDriver.HandleSqlBeforeCommit firstly and -// then gdb.DriverMysql.HandleSqlBeforeCommit. +// gdb.DriverMysql and overwrites its functions DoQuery and DoExec. +// So if there's any sql execution, it goes through MyDriver.DoQuery/MyDriver.DoExec firstly +// and then gdb.DriverMysql.DoQuery/gdb.DriverMysql.DoExec. // You can call it sql "HOOK" or "HiJack" as your will. type MyDriver struct { *gdb.DriverMysql diff --git a/database/gdb/gdb_driver_mssql.go b/database/gdb/gdb_driver_mssql.go index d90ac1f4d..391705a02 100644 --- a/database/gdb/gdb_driver_mssql.go +++ b/database/gdb/gdb_driver_mssql.go @@ -71,6 +71,8 @@ func (d *DriverMssql) HandleSqlBeforeCommit(link Link, sql string, args []interf return d.parseSql(str), args } +// parseSql does some replacement of the sql before commits it to underlying driver, +// for support of microsoft sql server. func (d *DriverMssql) parseSql(sql string) string { // SELECT * FROM USER WHERE ID=1 LIMIT 1 if m, _ := gregex.MatchString(`^SELECT(.+)LIMIT 1$`, sql); len(m) > 1 { @@ -91,22 +93,20 @@ func (d *DriverMssql) parseSql(sql string) string { index++ switch keyword { case "SELECT": - // 不含LIMIT关键字则不处理 + // LIMIT statement checks. if len(res) < 2 || (strings.HasPrefix(res[index][0], "LIMIT") == false && strings.HasPrefix(res[index][0], "limit") == false) { break } - // 不含LIMIT则不处理 if gregex.IsMatchString("((?i)SELECT)(.+)((?i)LIMIT)", sql) == false { break } - // 判断SQL中是否含有order by + // ORDER BY statement checks. selectStr := "" orderStr := "" haveOrder := gregex.IsMatchString("((?i)SELECT)(.+)((?i)ORDER BY)", sql) if haveOrder { - // 取order by 前面的字符串 queryExpr, _ := gregex.MatchString("((?i)SELECT)(.+)((?i)ORDER BY)", sql) if len(queryExpr) != 4 || strings.EqualFold(queryExpr[1], "SELECT") == false || @@ -114,8 +114,6 @@ func (d *DriverMssql) parseSql(sql string) string { break } selectStr = queryExpr[2] - - // 取order by表达式的值 orderExpr, _ := gregex.MatchString("((?i)ORDER BY)(.+)((?i)LIMIT)", sql) if len(orderExpr) != 4 || strings.EqualFold(orderExpr[1], "ORDER BY") == false || @@ -132,8 +130,6 @@ func (d *DriverMssql) parseSql(sql string) string { } selectStr = queryExpr[2] } - - // 取limit后面的取值范围 first, limit := 0, 0 for i := 1; i < len(res[index]); i++ { if len(strings.TrimSpace(res[index][i])) == 0 { @@ -147,7 +143,6 @@ func (d *DriverMssql) parseSql(sql string) string { break } } - if haveOrder { sql = fmt.Sprintf( "SELECT * FROM "+ diff --git a/database/gdb/gdb_driver_oracle.go b/database/gdb/gdb_driver_oracle.go index 72eaa5603..d6ccd40fe 100644 --- a/database/gdb/gdb_driver_oracle.go +++ b/database/gdb/gdb_driver_oracle.go @@ -75,6 +75,8 @@ func (d *DriverOracle) HandleSqlBeforeCommit(link Link, sql string, args []inter return d.parseSql(str), args } +// parseSql does some replacement of the sql before commits it to underlying driver, +// for support of oracle server. func (d *DriverOracle) parseSql(sql string) string { patten := `^\s*(?i)(SELECT)|(LIMIT\s*(\d+)\s*,\s*(\d+))` if gregex.IsMatchString(patten, sql) == false { @@ -93,22 +95,18 @@ func (d *DriverOracle) parseSql(sql string) string { index++ switch keyword { case "SELECT": - // 不含LIMIT关键字则不处理 - if len(res) < 2 || (strings.HasPrefix(res[index][0], "LIMIT") == false && strings.HasPrefix(res[index][0], "limit") == false) { + if len(res) < 2 || (strings.HasPrefix(res[index][0], "LIMIT") == false && + strings.HasPrefix(res[index][0], "limit") == false) { break } - - // 取limit前面的字符串 if gregex.IsMatchString("((?i)SELECT)(.+)((?i)LIMIT)", sql) == false { break } - queryExpr, _ := gregex.MatchString("((?i)SELECT)(.+)((?i)LIMIT)", sql) - if len(queryExpr) != 4 || strings.EqualFold(queryExpr[1], "SELECT") == false || strings.EqualFold(queryExpr[3], "LIMIT") == false { + if len(queryExpr) != 4 || strings.EqualFold(queryExpr[1], "SELECT") == false || + strings.EqualFold(queryExpr[3], "LIMIT") == false { break } - - // 取limit后面的取值范围 first, limit := 0, 0 for i := 1; i < len(res[index]); i++ { if len(strings.TrimSpace(res[index][i])) == 0 { @@ -121,10 +119,10 @@ func (d *DriverOracle) parseSql(sql string) string { break } } - - // 也可以使用between,据说这种写法的性能会比between好点,里层SQL中的ROWNUM_ >= limit可以缩小查询后的数据集规模 sql = fmt.Sprintf( - "SELECT * FROM (SELECT GFORM.*, ROWNUM ROWNUM_ FROM (%s %s) GFORM WHERE ROWNUM <= %d) WHERE ROWNUM_ >= %d", + "SELECT * FROM "+ + "(SELECT GFORM.*, ROWNUM ROWNUM_ FROM (%s %s) GFORM WHERE ROWNUM <= %d)"+ + " WHERE ROWNUM_ >= %d", queryExpr[1], queryExpr[2], limit, first, ) } diff --git a/database/gdb/gdb_driver_sqlite.go b/database/gdb/gdb_driver_sqlite.go index 5a17fddeb..c433fcba3 100644 --- a/database/gdb/gdb_driver_sqlite.go +++ b/database/gdb/gdb_driver_sqlite.go @@ -59,8 +59,8 @@ func (d *DriverSqlite) GetChars() (charLeft string, charRight string) { } // HandleSqlBeforeCommit deals with the sql string before commits it to underlying sql driver. -// @todo 需要增加对Save方法的支持,可使用正则来实现替换, -// @todo 将ON DUPLICATE KEY UPDATE触发器修改为两条SQL语句(INSERT OR IGNORE & UPDATE) +// TODO 需要增加对Save方法的支持,可使用正则来实现替换, +// TODO 将ON DUPLICATE KEY UPDATE触发器修改为两条SQL语句(INSERT OR IGNORE & UPDATE) func (d *DriverSqlite) HandleSqlBeforeCommit(link Link, sql string, args []interface{}) (string, []interface{}) { return sql, args }