mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
This pull request standardizes the use of the Go 1.18+ `any` type alias
instead of `interface{}` throughout the codebase. The change improves
code readability and aligns with modern Go best practices. The update
touches many files, including core data structures, code generation
templates, logging utilities, and test data, ensuring consistency across
all usages.
**Type alias migration to `any`:**
* Replaced all instances of `interface{}` with `any` in core data
structures such as `garray` and in generated model structs (e.g.,
`TableUser`, `User1`, `User2`) to modernize type usage.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
* Updated function signatures, method parameters, and return types from
`interface{}` to `any` in various parts of the codebase, including code
generation, service logic, and logging utilities (e.g., `mlog`).
[[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74)
[[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
[[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107)
[[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121)
[[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112)
[[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36)
[[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74)
[[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96)
**Generated code and templates:**
* Adjusted generated files and code generation templates to output `any`
instead of `interface{}` for relevant struct fields and function
signatures, ensuring that new code generation aligns with the updated
convention.
[[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
[[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
**Container and utility updates:**
* Refactored the `garray` container implementation and related
constructors/methods to use `[]any` instead of `[]interface{}`, along
with corresponding function signatures.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52)
[[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62)
[[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86)
[[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97)
[[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114)
[[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124)
[[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143)
[[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167)
These changes collectively modernize the codebase and prepare it for
future Go developments by using the idiomatic `any` type.
294 lines
8.8 KiB
Go
294 lines
8.8 KiB
Go
// 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 gdb
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
"github.com/gogf/gf/v2/container/gvar"
|
|
"github.com/gogf/gf/v2/text/gregex"
|
|
"github.com/gogf/gf/v2/text/gstr"
|
|
)
|
|
|
|
type (
|
|
HookFuncSelect func(ctx context.Context, in *HookSelectInput) (result Result, err error)
|
|
HookFuncInsert func(ctx context.Context, in *HookInsertInput) (result sql.Result, err error)
|
|
HookFuncUpdate func(ctx context.Context, in *HookUpdateInput) (result sql.Result, err error)
|
|
HookFuncDelete func(ctx context.Context, in *HookDeleteInput) (result sql.Result, err error)
|
|
)
|
|
|
|
// HookHandler manages all supported hook functions for Model.
|
|
type HookHandler struct {
|
|
Select HookFuncSelect
|
|
Insert HookFuncInsert
|
|
Update HookFuncUpdate
|
|
Delete HookFuncDelete
|
|
}
|
|
|
|
// internalParamHook manages all internal parameters for hook operations.
|
|
// The `internal` obviously means you cannot access these parameters outside this package.
|
|
type internalParamHook struct {
|
|
link Link // Connection object from third party sql driver.
|
|
handlerCalled bool // Simple mark for custom handler called, in case of recursive calling.
|
|
removedWhere bool // Removed mark for condition string that was removed `WHERE` prefix.
|
|
originalTableName *gvar.Var // The original table name.
|
|
originalSchemaName *gvar.Var // The original schema name.
|
|
}
|
|
|
|
type internalParamHookSelect struct {
|
|
internalParamHook
|
|
handler HookFuncSelect
|
|
}
|
|
|
|
type internalParamHookInsert struct {
|
|
internalParamHook
|
|
handler HookFuncInsert
|
|
}
|
|
|
|
type internalParamHookUpdate struct {
|
|
internalParamHook
|
|
handler HookFuncUpdate
|
|
}
|
|
|
|
type internalParamHookDelete struct {
|
|
internalParamHook
|
|
handler HookFuncDelete
|
|
}
|
|
|
|
// HookSelectInput holds the parameters for select hook operation.
|
|
// Note that, COUNT statement will also be hooked by this feature,
|
|
// which is usually not be interesting for upper business hook handler.
|
|
type HookSelectInput struct {
|
|
internalParamHookSelect
|
|
Model *Model // Current operation Model.
|
|
Table string // The table name that to be used. Update this attribute to change target table name.
|
|
Schema string // The schema name that to be used. Update this attribute to change target schema name.
|
|
Sql string // The sql string that to be committed.
|
|
Args []any // The arguments of sql.
|
|
SelectType SelectType // The type of this SELECT operation.
|
|
}
|
|
|
|
// HookInsertInput holds the parameters for insert hook operation.
|
|
type HookInsertInput struct {
|
|
internalParamHookInsert
|
|
Model *Model // Current operation Model.
|
|
Table string // The table name that to be used. Update this attribute to change target table name.
|
|
Schema string // The schema name that to be used. Update this attribute to change target schema name.
|
|
Data List // The data records list to be inserted/saved into table.
|
|
Option DoInsertOption // The extra option for data inserting.
|
|
}
|
|
|
|
// HookUpdateInput holds the parameters for update hook operation.
|
|
type HookUpdateInput struct {
|
|
internalParamHookUpdate
|
|
Model *Model // Current operation Model.
|
|
Table string // The table name that to be used. Update this attribute to change target table name.
|
|
Schema string // The schema name that to be used. Update this attribute to change target schema name.
|
|
Data any // Data can be type of: map[string]any/string. You can use type assertion on `Data`.
|
|
Condition string // The where condition string for updating.
|
|
Args []any // The arguments for sql place-holders.
|
|
}
|
|
|
|
// HookDeleteInput holds the parameters for delete hook operation.
|
|
type HookDeleteInput struct {
|
|
internalParamHookDelete
|
|
Model *Model // Current operation Model.
|
|
Table string // The table name that to be used. Update this attribute to change target table name.
|
|
Schema string // The schema name that to be used. Update this attribute to change target schema name.
|
|
Condition string // The where condition string for deleting.
|
|
Args []any // The arguments for sql place-holders.
|
|
}
|
|
|
|
const (
|
|
whereKeyInCondition = " WHERE "
|
|
)
|
|
|
|
// IsTransaction checks and returns whether current operation is during transaction.
|
|
func (h *internalParamHook) IsTransaction() bool {
|
|
return h.link.IsTransaction()
|
|
}
|
|
|
|
// Next calls the next hook handler.
|
|
func (h *HookSelectInput) Next(ctx context.Context) (result Result, err error) {
|
|
if h.originalTableName.IsNil() {
|
|
h.originalTableName = gvar.New(h.Table)
|
|
}
|
|
if h.originalSchemaName.IsNil() {
|
|
h.originalSchemaName = gvar.New(h.Schema)
|
|
}
|
|
|
|
// Sharding feature.
|
|
h.Schema, err = h.Model.getActualSchema(ctx, h.Schema)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
h.Table, err = h.Model.getActualTable(ctx, h.Table)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Custom hook handler call.
|
|
if h.handler != nil && !h.handlerCalled {
|
|
h.handlerCalled = true
|
|
return h.handler(ctx, h)
|
|
}
|
|
var toBeCommittedSql = h.Sql
|
|
// Table change.
|
|
if h.Table != h.originalTableName.String() {
|
|
toBeCommittedSql, err = gregex.ReplaceStringFuncMatch(
|
|
`(?i) FROM ([\S]+)`,
|
|
toBeCommittedSql,
|
|
func(match []string) string {
|
|
charL, charR := h.Model.db.GetChars()
|
|
return fmt.Sprintf(` FROM %s%s%s`, charL, h.Table, charR)
|
|
},
|
|
)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
// Schema change.
|
|
if h.Schema != "" && h.Schema != h.originalSchemaName.String() {
|
|
h.link, err = h.Model.db.GetCore().SlaveLink(h.Schema)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
return h.Model.db.DoSelect(ctx, h.link, toBeCommittedSql, h.Args...)
|
|
}
|
|
|
|
// Next calls the next hook handler.
|
|
func (h *HookInsertInput) Next(ctx context.Context) (result sql.Result, err error) {
|
|
if h.originalTableName.IsNil() {
|
|
h.originalTableName = gvar.New(h.Table)
|
|
}
|
|
if h.originalSchemaName.IsNil() {
|
|
h.originalSchemaName = gvar.New(h.Schema)
|
|
}
|
|
|
|
// Sharding feature.
|
|
h.Schema, err = h.Model.getActualSchema(ctx, h.Schema)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
h.Table, err = h.Model.getActualTable(ctx, h.Table)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if h.handler != nil && !h.handlerCalled {
|
|
h.handlerCalled = true
|
|
return h.handler(ctx, h)
|
|
}
|
|
|
|
// No need to handle table change.
|
|
|
|
// Schema change.
|
|
if h.Schema != "" && h.Schema != h.originalSchemaName.String() {
|
|
h.link, err = h.Model.db.GetCore().MasterLink(h.Schema)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
return h.Model.db.DoInsert(ctx, h.link, h.Table, h.Data, h.Option)
|
|
}
|
|
|
|
// Next calls the next hook handler.
|
|
func (h *HookUpdateInput) Next(ctx context.Context) (result sql.Result, err error) {
|
|
if h.originalTableName.IsNil() {
|
|
h.originalTableName = gvar.New(h.Table)
|
|
}
|
|
if h.originalSchemaName.IsNil() {
|
|
h.originalSchemaName = gvar.New(h.Schema)
|
|
}
|
|
|
|
// Sharding feature.
|
|
h.Schema, err = h.Model.getActualSchema(ctx, h.Schema)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
h.Table, err = h.Model.getActualTable(ctx, h.Table)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if h.handler != nil && !h.handlerCalled {
|
|
h.handlerCalled = true
|
|
if gstr.HasPrefix(h.Condition, whereKeyInCondition) {
|
|
h.removedWhere = true
|
|
h.Condition = gstr.TrimLeftStr(h.Condition, whereKeyInCondition)
|
|
}
|
|
return h.handler(ctx, h)
|
|
}
|
|
if h.removedWhere {
|
|
h.Condition = whereKeyInCondition + h.Condition
|
|
}
|
|
|
|
// No need to handle table change.
|
|
|
|
// Schema change.
|
|
if h.Schema != "" && h.Schema != h.originalSchemaName.String() {
|
|
h.link, err = h.Model.db.GetCore().MasterLink(h.Schema)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
return h.Model.db.DoUpdate(ctx, h.link, h.Table, h.Data, h.Condition, h.Args...)
|
|
}
|
|
|
|
// Next calls the next hook handler.
|
|
func (h *HookDeleteInput) Next(ctx context.Context) (result sql.Result, err error) {
|
|
if h.originalTableName.IsNil() {
|
|
h.originalTableName = gvar.New(h.Table)
|
|
}
|
|
if h.originalSchemaName.IsNil() {
|
|
h.originalSchemaName = gvar.New(h.Schema)
|
|
}
|
|
|
|
// Sharding feature.
|
|
h.Schema, err = h.Model.getActualSchema(ctx, h.Schema)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
h.Table, err = h.Model.getActualTable(ctx, h.Table)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if h.handler != nil && !h.handlerCalled {
|
|
h.handlerCalled = true
|
|
if gstr.HasPrefix(h.Condition, whereKeyInCondition) {
|
|
h.removedWhere = true
|
|
h.Condition = gstr.TrimLeftStr(h.Condition, whereKeyInCondition)
|
|
}
|
|
return h.handler(ctx, h)
|
|
}
|
|
if h.removedWhere {
|
|
h.Condition = whereKeyInCondition + h.Condition
|
|
}
|
|
|
|
// No need to handle table change.
|
|
|
|
// Schema change.
|
|
if h.Schema != "" && h.Schema != h.originalSchemaName.String() {
|
|
h.link, err = h.Model.db.GetCore().MasterLink(h.Schema)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
return h.Model.db.DoDelete(ctx, h.link, h.Table, h.Condition, h.Args...)
|
|
}
|
|
|
|
// Hook sets the hook functions for current model.
|
|
func (m *Model) Hook(hook HookHandler) *Model {
|
|
model := m.getModel()
|
|
model.hookHandler = hook
|
|
return model
|
|
}
|