Skip to main content
Version: 2.8.x(Latest)
warning

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:

// CatchSQL catches and returns all sql statements that are EXECUTED in given closure function.
// Be caution that, all the following sql statements should use the context object passing by function `f`.
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

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

main.go

package main

import (
"context"

_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gtime"
)

type User struct {
Id int
Passport string
Password string
Nickname string
CreateTime *gtime.Time
}

func initUser(ctx context.Context) error {
_, err := g.Model("user").Ctx(ctx).Data(User{
Id: 1,
Passport: "john",
Password: "12345678",
Nickname: "John",
}).Insert()
return err
}

func main() {
var ctx = gctx.New()
sqlArray, err := gdb.CatchSQL(ctx, func(ctx context.Context) error {
return initUser(ctx)
})
if err != nil {
panic(err)
}
g.Dump(sqlArray)
}

After execution, the terminal outputs:

[
"SHOW FULL COLUMNS FROM `user`",
"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') ",
]

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:

// ToSQL formats and returns the last one of sql statements in given closure function
// WITHOUT TRULY EXECUTING IT.
// Be caution that, all the following sql statements should use the context object passing by function `f`.
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

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

main.go

package main

import (
"context"

_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gtime"
)

type User struct {
Id int
Passport string
Password string
Nickname string
CreateTime *gtime.Time
}

func initUser(ctx context.Context) error {
_, err := g.Model("user").Ctx(ctx).Data(User{
Id: 1,
Passport: "john",
Password: "12345678",
Nickname: "John",
}).Insert()
return err
}

func main() {
var ctx = gctx.New()
sql, err := gdb.ToSQL(ctx, func(ctx context.Context) error {
return initUser(ctx)
})
if err != nil {
panic(err)
}
g.Dump(sql)
}

After execution, the terminal outputs:

"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') "