ORM Senior - SQL Capture - 图1warning

Please note that the principle of SQL capture in the framework is that any SQL statement template generated by SQL operations, along with SQL execution parameters, is intercepted by the framework before being submitted to the underlying database engine and automatically formatted into a human-readable string by the framework component for reference and debugging purposes only and is not the complete SQL statement submitted to the underlying database engine. The captured SQL statements are identical to the SQL statements output when the ORM component is in debugging mode, as they are generated by the same component.

CatchSQL

We can use the gdb.CatchSQL method to capture the list of SQL executed within a specified range. The method is defined as follows:

  1. // CatchSQL catches and returns all sql statements that are EXECUTED in given closure function.
  2. // Be caution that, all the following sql statements should use the context object passing by function `f`.
  3. func CatchSQL(ctx context.Context, f func(ctx context.Context) error) (sqlArray []string, err error)

As you can see, this method uses a closure function to execute SQL statements. All SQL operations executed within the closure function will be recorded and returned as a []string type. Note that the SQL operations executed within the closure should pass the ctx context object, otherwise the statements corresponding to the SQL operations cannot be recorded. Here is an example:

user.sql

  1. CREATE TABLE `user` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `passport` varchar(45) NULL,
  4. `password` char(32) NULL,
  5. `nickname` varchar(45) NULL,
  6. `create_time` timestamp(6) NULL,
  7. PRIMARY KEY (id)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

main.go

  1. package main
  2. import (
  3. "context"
  4. _ "github.com/gogf/gf/contrib/drivers/mysql/v2"
  5. "github.com/gogf/gf/v2/database/gdb"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gctx"
  8. "github.com/gogf/gf/v2/os/gtime"
  9. )
  10. type User struct {
  11. Id int
  12. Passport string
  13. Password string
  14. Nickname string
  15. CreateTime *gtime.Time
  16. }
  17. func initUser(ctx context.Context) error {
  18. _, err := g.Model("user").Ctx(ctx).Data(User{
  19. Id: 1,
  20. Passport: "john",
  21. Password: "12345678",
  22. Nickname: "John",
  23. }).Insert()
  24. return err
  25. }
  26. func main() {
  27. var ctx = gctx.New()
  28. sqlArray, err := gdb.CatchSQL(ctx, func(ctx context.Context) error {
  29. return initUser(ctx)
  30. })
  31. if err != nil {
  32. panic(err)
  33. }
  34. g.Dump(sqlArray)
  35. }

After execution, the terminal outputs:

  1. [
  2. "SHOW FULL COLUMNS FROM `user`",
  3. "INSERT INTO `user`(`id`,`passport`,`password`,`nickname`,`created_at`,`updated_at`) VALUES(1,'john','12345678','John','2023-12-19 21:43:57','2023-12-19 21:43:57') ",
  4. ]

ToSQL

We can use gdb.ToSQL to convert a given SQL operation into an SQL statement without actually executing it. The method is defined as follows:

  1. // ToSQL formats and returns the last one of sql statements in given closure function
  2. // WITHOUT TRULY EXECUTING IT.
  3. // Be caution that, all the following sql statements should use the context object passing by function `f`.
  4. func ToSQL(ctx context.Context, f func(ctx context.Context) error) (sql string, err error)

As you can see, this method estimates SQL statements through a closure function. All SQL operations within the closure function will be estimated, but only the last SQL statement will be returned as a string type. Note that the SQL operations within the closure should pass the ctx context object, otherwise the statements corresponding to the SQL operations cannot be recorded. Here is an example:

user.sql

  1. CREATE TABLE `user` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `passport` varchar(45) NULL,
  4. `password` char(32) NULL,
  5. `nickname` varchar(45) NULL,
  6. `create_time` timestamp(6) NULL,
  7. PRIMARY KEY (id)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

main.go

  1. package main
  2. import (
  3. "context"
  4. _ "github.com/gogf/gf/contrib/drivers/mysql/v2"
  5. "github.com/gogf/gf/v2/database/gdb"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gctx"
  8. "github.com/gogf/gf/v2/os/gtime"
  9. )
  10. type User struct {
  11. Id int
  12. Passport string
  13. Password string
  14. Nickname string
  15. CreateTime *gtime.Time
  16. }
  17. func initUser(ctx context.Context) error {
  18. _, err := g.Model("user").Ctx(ctx).Data(User{
  19. Id: 1,
  20. Passport: "john",
  21. Password: "12345678",
  22. Nickname: "John",
  23. }).Insert()
  24. return err
  25. }
  26. func main() {
  27. var ctx = gctx.New()
  28. sql, err := gdb.ToSQL(ctx, func(ctx context.Context) error {
  29. return initUser(ctx)
  30. })
  31. if err != nil {
  32. panic(err)
  33. }
  34. g.Dump(sql)
  35. }

After execution, the terminal outputs:

  1. "INSERT INTO `user`(`id`,`passport`,`password`,`nickname`,`created_at`,`updated_at`) VALUES(1,'john','12345678','John','2023-12-19 21:49:21','2023-12-19 21:49:21') "