2021-01-17 21:46:25 +08:00
|
|
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
|
|
|
|
// 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 (
|
2022-03-24 15:33:30 +08:00
|
|
|
"context"
|
2020-03-13 17:21:30 +08:00
|
|
|
"fmt"
|
2021-05-21 13:25:53 +08:00
|
|
|
"reflect"
|
|
|
|
|
|
2021-10-11 21:41:56 +08:00
|
|
|
"github.com/gogf/gf/v2/container/gset"
|
2024-10-08 20:42:06 +08:00
|
|
|
"github.com/gogf/gf/v2/encoding/gjson"
|
2021-11-13 23:23:55 +08:00
|
|
|
"github.com/gogf/gf/v2/errors/gcode"
|
|
|
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
2022-03-11 10:24:42 +08:00
|
|
|
"github.com/gogf/gf/v2/internal/reflection"
|
2021-10-11 21:41:56 +08:00
|
|
|
"github.com/gogf/gf/v2/text/gstr"
|
|
|
|
|
"github.com/gogf/gf/v2/util/gconv"
|
2020-03-13 17:21:30 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// All does "SELECT FROM ..." statement for the model.
|
|
|
|
|
// It retrieves the records from table and returns the result as slice type.
|
|
|
|
|
// It returns nil if there's no record retrieved with the given conditions from table.
|
|
|
|
|
//
|
2021-02-08 17:57:21 +08:00
|
|
|
// The optional parameter `where` is the same as the parameter of Model.Where function,
|
2020-03-13 17:21:30 +08:00
|
|
|
// see Model.Where.
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) All(where ...any) (Result, error) {
|
2022-03-24 17:51:49 +08:00
|
|
|
var ctx = m.GetCtx()
|
2024-12-01 23:47:51 +08:00
|
|
|
return m.doGetAll(ctx, SelectTypeDefault, false, where...)
|
2020-07-15 09:15:03 +08:00
|
|
|
}
|
|
|
|
|
|
2023-06-01 21:33:40 +08:00
|
|
|
// AllAndCount retrieves all records and the total count of records from the model.
|
|
|
|
|
// If useFieldForCount is true, it will use the fields specified in the model for counting;
|
|
|
|
|
// otherwise, it will use a constant value of 1 for counting.
|
|
|
|
|
// It returns the result as a slice of records, the total count of records, and an error if any.
|
|
|
|
|
// The where parameter is an optional list of conditions to use when retrieving records.
|
|
|
|
|
//
|
|
|
|
|
// Example:
|
|
|
|
|
//
|
|
|
|
|
// var model Model
|
|
|
|
|
// var result Result
|
|
|
|
|
// var count int
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
// where := []any{"name = ?", "John"}
|
2023-06-01 21:33:40 +08:00
|
|
|
// result, count, err := model.AllAndCount(true)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// // Handle error.
|
|
|
|
|
// }
|
|
|
|
|
// fmt.Println(result, count)
|
|
|
|
|
func (m *Model) AllAndCount(useFieldForCount bool) (result Result, totalCount int, err error) {
|
|
|
|
|
// Clone the model for counting
|
|
|
|
|
countModel := m.Clone()
|
|
|
|
|
|
2026-02-27 16:12:58 +08:00
|
|
|
// Decide how to build the COUNT() expression:
|
|
|
|
|
// - If caller explicitly wants to use the single field expression for counting,
|
|
|
|
|
// honor it (e.g. Fields("DISTINCT col") with useFieldForCount = true).
|
|
|
|
|
// - Otherwise, clear fields to let Count() use its default COUNT(1),
|
|
|
|
|
// avoiding invalid COUNT(field1, field2, ...) with multiple fields,
|
|
|
|
|
// or incorrect COUNT(DISTINCT 1) when Distinct() is set.
|
|
|
|
|
if useFieldForCount && len(m.fields) == 1 {
|
|
|
|
|
countModel.fields = m.fields
|
|
|
|
|
} else {
|
|
|
|
|
countModel.fields = nil
|
2023-06-01 21:33:40 +08:00
|
|
|
}
|
fix(database/gdb): Resolve the cache error overwriting caused by the use of fixed cache keys in pagination queries. (#4339)
```golang
func main() {
adapter := gcache.NewAdapterRedis(g.Redis())
g.DB().GetCache().SetAdapter(adapter)
result, count, err := g.Model("TBL_USER").Cache(gdb.CacheOption{
Duration: 100 * time.Minute,
Name: "VIP",
}).AllAndCount(false)
g.DumpJson(result)
fmt.Println(count, err)
}
```
执行这段查询后`g.DumpJson(result)`的结果是`[
{
"COUNT(1)": 5
}
]`,但是正确结果应该是五条用户信息,查看源代码后发现先执行的count查询和后来select查询都是直接使用了`VIP`这个缓存key,在redis中实际缓存key是`SelectCache:VIP`,第二步查询select获得的是count查询的缓存,所以查询结果是错的。
因此为`Model`增加一个`PageCache`方法允许用户分别设置`count query`和`data query`的缓存参数
```golang
// PageCache sets the cache feature for pagination queries. It allows to configure
// separate cache options for count query and data query in pagination.
//
// Note that, the cache feature is disabled if the model is performing select statement
// on a transaction.
func (m *Model) PageCache(countOption CacheOption, dataOption CacheOption) *Model {
model := m.getModel()
model.pageCacheOption = []CacheOption{countOption, dataOption}
model.cacheEnabled = true
return model
}
```
然后`AllAndCount`在查询时分别给两个查询设置对应的缓存参数`ScanAndCount`同理
```golang
// AllAndCount retrieves all records and the total count of records from the model.
// If useFieldForCount is true, it will use the fields specified in the model for counting;
// otherwise, it will use a constant value of 1 for counting.
// It returns the result as a slice of records, the total count of records, and an error if any.
// The where parameter is an optional list of conditions to use when retrieving records.
//
// Example:
//
// var model Model
// var result Result
// var count int
// where := []any{"name = ?", "John"}
// result, count, err := model.AllAndCount(true)
// if err != nil {
// // Handle error.
// }
// fmt.Println(result, count)
func (m *Model) AllAndCount(useFieldForCount bool) (result Result, totalCount int, err error) {
// Clone the model for counting
countModel := m.Clone()
// If useFieldForCount is false, set the fields to a constant value of 1 for counting
if !useFieldForCount {
countModel.fields = []any{Raw("1")}
}
if len(m.pageCacheOption) > 0 {
countModel = countModel.Cache(m.pageCacheOption[0])
}
// Get the total count of records
totalCount, err = countModel.Count()
if err != nil {
return
}
// If the total count is 0, there are no records to retrieve, so return early
if totalCount == 0 {
return
}
resultModel := m.Clone()
if len(m.pageCacheOption) > 1 {
resultModel = resultModel.Cache(m.pageCacheOption[1])
}
// Retrieve all records
result, err = resultModel.doGetAll(m.GetCtx(), SelectTypeDefault, false)
return
}
```
---------
Co-authored-by: houseme <housemecn@gmail.com>
2026-01-16 10:33:05 +08:00
|
|
|
if len(m.pageCacheOption) > 0 {
|
|
|
|
|
countModel = countModel.Cache(m.pageCacheOption[0])
|
|
|
|
|
}
|
2023-06-01 21:33:40 +08:00
|
|
|
|
|
|
|
|
// Get the total count of records
|
|
|
|
|
totalCount, err = countModel.Count()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the total count is 0, there are no records to retrieve, so return early
|
|
|
|
|
if totalCount == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
fix(database/gdb): Resolve the cache error overwriting caused by the use of fixed cache keys in pagination queries. (#4339)
```golang
func main() {
adapter := gcache.NewAdapterRedis(g.Redis())
g.DB().GetCache().SetAdapter(adapter)
result, count, err := g.Model("TBL_USER").Cache(gdb.CacheOption{
Duration: 100 * time.Minute,
Name: "VIP",
}).AllAndCount(false)
g.DumpJson(result)
fmt.Println(count, err)
}
```
执行这段查询后`g.DumpJson(result)`的结果是`[
{
"COUNT(1)": 5
}
]`,但是正确结果应该是五条用户信息,查看源代码后发现先执行的count查询和后来select查询都是直接使用了`VIP`这个缓存key,在redis中实际缓存key是`SelectCache:VIP`,第二步查询select获得的是count查询的缓存,所以查询结果是错的。
因此为`Model`增加一个`PageCache`方法允许用户分别设置`count query`和`data query`的缓存参数
```golang
// PageCache sets the cache feature for pagination queries. It allows to configure
// separate cache options for count query and data query in pagination.
//
// Note that, the cache feature is disabled if the model is performing select statement
// on a transaction.
func (m *Model) PageCache(countOption CacheOption, dataOption CacheOption) *Model {
model := m.getModel()
model.pageCacheOption = []CacheOption{countOption, dataOption}
model.cacheEnabled = true
return model
}
```
然后`AllAndCount`在查询时分别给两个查询设置对应的缓存参数`ScanAndCount`同理
```golang
// AllAndCount retrieves all records and the total count of records from the model.
// If useFieldForCount is true, it will use the fields specified in the model for counting;
// otherwise, it will use a constant value of 1 for counting.
// It returns the result as a slice of records, the total count of records, and an error if any.
// The where parameter is an optional list of conditions to use when retrieving records.
//
// Example:
//
// var model Model
// var result Result
// var count int
// where := []any{"name = ?", "John"}
// result, count, err := model.AllAndCount(true)
// if err != nil {
// // Handle error.
// }
// fmt.Println(result, count)
func (m *Model) AllAndCount(useFieldForCount bool) (result Result, totalCount int, err error) {
// Clone the model for counting
countModel := m.Clone()
// If useFieldForCount is false, set the fields to a constant value of 1 for counting
if !useFieldForCount {
countModel.fields = []any{Raw("1")}
}
if len(m.pageCacheOption) > 0 {
countModel = countModel.Cache(m.pageCacheOption[0])
}
// Get the total count of records
totalCount, err = countModel.Count()
if err != nil {
return
}
// If the total count is 0, there are no records to retrieve, so return early
if totalCount == 0 {
return
}
resultModel := m.Clone()
if len(m.pageCacheOption) > 1 {
resultModel = resultModel.Cache(m.pageCacheOption[1])
}
// Retrieve all records
result, err = resultModel.doGetAll(m.GetCtx(), SelectTypeDefault, false)
return
}
```
---------
Co-authored-by: houseme <housemecn@gmail.com>
2026-01-16 10:33:05 +08:00
|
|
|
resultModel := m.Clone()
|
|
|
|
|
if len(m.pageCacheOption) > 1 {
|
|
|
|
|
resultModel = resultModel.Cache(m.pageCacheOption[1])
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-01 21:33:40 +08:00
|
|
|
// Retrieve all records
|
fix(database/gdb): Resolve the cache error overwriting caused by the use of fixed cache keys in pagination queries. (#4339)
```golang
func main() {
adapter := gcache.NewAdapterRedis(g.Redis())
g.DB().GetCache().SetAdapter(adapter)
result, count, err := g.Model("TBL_USER").Cache(gdb.CacheOption{
Duration: 100 * time.Minute,
Name: "VIP",
}).AllAndCount(false)
g.DumpJson(result)
fmt.Println(count, err)
}
```
执行这段查询后`g.DumpJson(result)`的结果是`[
{
"COUNT(1)": 5
}
]`,但是正确结果应该是五条用户信息,查看源代码后发现先执行的count查询和后来select查询都是直接使用了`VIP`这个缓存key,在redis中实际缓存key是`SelectCache:VIP`,第二步查询select获得的是count查询的缓存,所以查询结果是错的。
因此为`Model`增加一个`PageCache`方法允许用户分别设置`count query`和`data query`的缓存参数
```golang
// PageCache sets the cache feature for pagination queries. It allows to configure
// separate cache options for count query and data query in pagination.
//
// Note that, the cache feature is disabled if the model is performing select statement
// on a transaction.
func (m *Model) PageCache(countOption CacheOption, dataOption CacheOption) *Model {
model := m.getModel()
model.pageCacheOption = []CacheOption{countOption, dataOption}
model.cacheEnabled = true
return model
}
```
然后`AllAndCount`在查询时分别给两个查询设置对应的缓存参数`ScanAndCount`同理
```golang
// AllAndCount retrieves all records and the total count of records from the model.
// If useFieldForCount is true, it will use the fields specified in the model for counting;
// otherwise, it will use a constant value of 1 for counting.
// It returns the result as a slice of records, the total count of records, and an error if any.
// The where parameter is an optional list of conditions to use when retrieving records.
//
// Example:
//
// var model Model
// var result Result
// var count int
// where := []any{"name = ?", "John"}
// result, count, err := model.AllAndCount(true)
// if err != nil {
// // Handle error.
// }
// fmt.Println(result, count)
func (m *Model) AllAndCount(useFieldForCount bool) (result Result, totalCount int, err error) {
// Clone the model for counting
countModel := m.Clone()
// If useFieldForCount is false, set the fields to a constant value of 1 for counting
if !useFieldForCount {
countModel.fields = []any{Raw("1")}
}
if len(m.pageCacheOption) > 0 {
countModel = countModel.Cache(m.pageCacheOption[0])
}
// Get the total count of records
totalCount, err = countModel.Count()
if err != nil {
return
}
// If the total count is 0, there are no records to retrieve, so return early
if totalCount == 0 {
return
}
resultModel := m.Clone()
if len(m.pageCacheOption) > 1 {
resultModel = resultModel.Cache(m.pageCacheOption[1])
}
// Retrieve all records
result, err = resultModel.doGetAll(m.GetCtx(), SelectTypeDefault, false)
return
}
```
---------
Co-authored-by: houseme <housemecn@gmail.com>
2026-01-16 10:33:05 +08:00
|
|
|
result, err = resultModel.doGetAll(m.GetCtx(), SelectTypeDefault, false)
|
2023-06-01 21:33:40 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-01 10:33:33 +08:00
|
|
|
// Chunk iterates the query result with given `size` and `handler` function.
|
|
|
|
|
func (m *Model) Chunk(size int, handler ChunkHandler) {
|
2020-03-13 17:21:30 +08:00
|
|
|
page := m.start
|
2020-11-26 14:26:32 +08:00
|
|
|
if page <= 0 {
|
2020-03-13 17:21:30 +08:00
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
model := m
|
|
|
|
|
for {
|
2021-08-01 10:33:33 +08:00
|
|
|
model = model.Page(page, size)
|
2020-03-13 17:21:30 +08:00
|
|
|
data, err := model.All()
|
|
|
|
|
if err != nil {
|
2021-08-01 10:33:33 +08:00
|
|
|
handler(nil, err)
|
2020-03-13 17:21:30 +08:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
if len(data) == 0 {
|
|
|
|
|
break
|
|
|
|
|
}
|
2022-11-01 20:12:21 +08:00
|
|
|
if !handler(data, err) {
|
2020-03-13 17:21:30 +08:00
|
|
|
break
|
|
|
|
|
}
|
2021-08-01 10:33:33 +08:00
|
|
|
if len(data) < size {
|
2020-03-13 17:21:30 +08:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
page++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// One retrieves one record from table and returns the result as map type.
|
|
|
|
|
// It returns nil if there's no record retrieved with the given conditions from table.
|
|
|
|
|
//
|
2021-02-08 17:57:21 +08:00
|
|
|
// The optional parameter `where` is the same as the parameter of Model.Where function,
|
2020-03-13 17:21:30 +08:00
|
|
|
// see Model.Where.
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) One(where ...any) (Record, error) {
|
2022-03-24 17:51:49 +08:00
|
|
|
var ctx = m.GetCtx()
|
2020-03-13 17:21:30 +08:00
|
|
|
if len(where) > 0 {
|
|
|
|
|
return m.Where(where[0], where[1:]...).One()
|
|
|
|
|
}
|
2024-12-01 23:47:51 +08:00
|
|
|
all, err := m.doGetAll(ctx, SelectTypeDefault, true)
|
2020-03-13 17:21:30 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if len(all) > 0 {
|
|
|
|
|
return all[0], nil
|
|
|
|
|
}
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Array queries and returns data values as slice from database.
|
2021-05-02 12:17:06 +08:00
|
|
|
// Note that if there are multiple columns in the result, it returns just one column values randomly.
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
2021-02-08 17:57:21 +08:00
|
|
|
// If the optional parameter `fieldsAndWhere` is given, the fieldsAndWhere[0] is the selected fields
|
2020-03-13 17:21:30 +08:00
|
|
|
// and fieldsAndWhere[1:] is treated as where condition fields.
|
|
|
|
|
// Also see Model.Fields and Model.Where functions.
|
2025-09-28 17:08:37 +08:00
|
|
|
func (m *Model) Array(fieldsAndWhere ...any) (Array, error) {
|
2020-03-13 17:21:30 +08:00
|
|
|
if len(fieldsAndWhere) > 0 {
|
|
|
|
|
if len(fieldsAndWhere) > 2 {
|
|
|
|
|
return m.Fields(gconv.String(fieldsAndWhere[0])).Where(fieldsAndWhere[1], fieldsAndWhere[2:]...).Array()
|
|
|
|
|
} else if len(fieldsAndWhere) == 2 {
|
|
|
|
|
return m.Fields(gconv.String(fieldsAndWhere[0])).Where(fieldsAndWhere[1]).Array()
|
|
|
|
|
} else {
|
|
|
|
|
return m.Fields(gconv.String(fieldsAndWhere[0])).Array()
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-01 23:47:51 +08:00
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
field string
|
|
|
|
|
core = m.db.GetCore()
|
|
|
|
|
ctx = core.injectInternalColumn(m.GetCtx())
|
|
|
|
|
)
|
|
|
|
|
all, err := m.doGetAll(ctx, SelectTypeArray, false)
|
2020-03-13 17:21:30 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2023-04-28 14:55:37 +08:00
|
|
|
if len(all) > 0 {
|
2024-12-01 23:47:51 +08:00
|
|
|
internalData := core.getInternalColumnFromCtx(ctx)
|
|
|
|
|
if internalData == nil {
|
|
|
|
|
return nil, gerror.NewCode(
|
|
|
|
|
gcode.CodeInternalError,
|
|
|
|
|
`query count error: the internal context data is missing. there's internal issue should be fixed`,
|
2023-04-28 14:55:37 +08:00
|
|
|
)
|
|
|
|
|
}
|
2024-12-01 23:47:51 +08:00
|
|
|
// If FirstResultColumn present, it returns the value of the first record of the first field.
|
|
|
|
|
// It means it use no cache mechanism, while cache mechanism makes `internalData` missing.
|
|
|
|
|
field = internalData.FirstResultColumn
|
|
|
|
|
if field == "" {
|
|
|
|
|
// Fields number check.
|
|
|
|
|
var recordFields = m.getRecordFields(all[0])
|
|
|
|
|
if len(recordFields) == 1 {
|
|
|
|
|
field = recordFields[0]
|
|
|
|
|
} else {
|
|
|
|
|
// it returns error if there are multiple fields in the result record.
|
|
|
|
|
return nil, gerror.NewCodef(
|
|
|
|
|
gcode.CodeInvalidParameter,
|
|
|
|
|
`invalid fields for "Array" operation, result fields number "%d"%s, but expect one`,
|
|
|
|
|
len(recordFields),
|
|
|
|
|
gjson.MustEncodeString(recordFields),
|
|
|
|
|
)
|
|
|
|
|
}
|
2024-10-08 20:42:06 +08:00
|
|
|
}
|
2023-04-28 14:55:37 +08:00
|
|
|
}
|
|
|
|
|
return all.Array(field), nil
|
2020-03-13 17:21:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Struct retrieves one record from table and converts it into given struct.
|
2021-02-08 17:57:21 +08:00
|
|
|
// The parameter `pointer` should be type of *struct/**struct. If type **struct is given,
|
2020-03-13 17:21:30 +08:00
|
|
|
// it can create the struct internally during converting.
|
|
|
|
|
//
|
2021-02-08 17:57:21 +08:00
|
|
|
// The optional parameter `where` is the same as the parameter of Model.Where function,
|
2020-03-13 17:21:30 +08:00
|
|
|
// see Model.Where.
|
|
|
|
|
//
|
2021-06-22 21:48:56 +08:00
|
|
|
// Note that it returns sql.ErrNoRows if the given parameter `pointer` pointed to a variable that has
|
|
|
|
|
// default value and there's no record retrieved with the given conditions from table.
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
2021-06-22 21:48:56 +08:00
|
|
|
// Example:
|
2020-03-13 17:21:30 +08:00
|
|
|
// user := new(User)
|
2021-06-22 21:48:56 +08:00
|
|
|
// err := db.Model("user").Where("id", 1).Scan(user)
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
|
|
|
|
// user := (*User)(nil)
|
2021-11-16 17:21:13 +08:00
|
|
|
// err := db.Model("user").Where("id", 1).Scan(&user).
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) doStruct(pointer any, where ...any) error {
|
2021-06-22 21:48:56 +08:00
|
|
|
model := m
|
|
|
|
|
// Auto selecting fields by struct attributes.
|
2024-10-21 09:22:31 +08:00
|
|
|
if len(model.fieldsEx) == 0 && len(model.fields) == 0 {
|
2021-09-15 22:28:26 +08:00
|
|
|
if v, ok := pointer.(reflect.Value); ok {
|
|
|
|
|
model = m.Fields(v.Interface())
|
|
|
|
|
} else {
|
|
|
|
|
model = m.Fields(pointer)
|
|
|
|
|
}
|
2021-06-22 21:48:56 +08:00
|
|
|
}
|
|
|
|
|
one, err := model.One(where...)
|
2020-03-13 17:21:30 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2021-02-08 17:57:21 +08:00
|
|
|
if err = one.Struct(pointer); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2021-06-22 21:48:56 +08:00
|
|
|
return model.doWithScanStruct(pointer)
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-13 17:21:30 +08:00
|
|
|
// Structs retrieves records from table and converts them into given struct slice.
|
2021-02-08 17:57:21 +08:00
|
|
|
// The parameter `pointer` should be type of *[]struct/*[]*struct. It can create and fill the struct
|
2020-03-13 17:21:30 +08:00
|
|
|
// slice internally during converting.
|
|
|
|
|
//
|
2021-02-08 17:57:21 +08:00
|
|
|
// The optional parameter `where` is the same as the parameter of Model.Where function,
|
2020-03-13 17:21:30 +08:00
|
|
|
// see Model.Where.
|
|
|
|
|
//
|
2021-06-22 21:48:56 +08:00
|
|
|
// Note that it returns sql.ErrNoRows if the given parameter `pointer` pointed to a variable that has
|
|
|
|
|
// default value and there's no record retrieved with the given conditions from table.
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
2021-06-22 21:48:56 +08:00
|
|
|
// Example:
|
2020-03-13 17:21:30 +08:00
|
|
|
// users := ([]User)(nil)
|
2021-06-22 21:48:56 +08:00
|
|
|
// err := db.Model("user").Scan(&users)
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
|
|
|
|
// users := ([]*User)(nil)
|
2021-11-16 17:21:13 +08:00
|
|
|
// err := db.Model("user").Scan(&users).
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) doStructs(pointer any, where ...any) error {
|
2021-06-22 21:48:56 +08:00
|
|
|
model := m
|
|
|
|
|
// Auto selecting fields by struct attributes.
|
2024-10-21 09:22:31 +08:00
|
|
|
if len(model.fieldsEx) == 0 && len(model.fields) == 0 {
|
2021-09-15 22:28:26 +08:00
|
|
|
if v, ok := pointer.(reflect.Value); ok {
|
|
|
|
|
model = m.Fields(
|
|
|
|
|
reflect.New(
|
|
|
|
|
v.Type().Elem(),
|
|
|
|
|
).Interface(),
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
model = m.Fields(
|
|
|
|
|
reflect.New(
|
|
|
|
|
reflect.ValueOf(pointer).Elem().Type().Elem(),
|
|
|
|
|
).Interface(),
|
|
|
|
|
)
|
|
|
|
|
}
|
2021-06-22 21:48:56 +08:00
|
|
|
}
|
|
|
|
|
all, err := model.All(where...)
|
2020-03-13 17:21:30 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2021-02-09 18:00:43 +08:00
|
|
|
if err = all.Structs(pointer); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2021-06-22 21:48:56 +08:00
|
|
|
return model.doWithScanStructs(pointer)
|
2020-03-13 17:21:30 +08:00
|
|
|
}
|
|
|
|
|
|
2021-02-08 17:57:21 +08:00
|
|
|
// Scan automatically calls Struct or Structs function according to the type of parameter `pointer`.
|
2021-06-22 21:48:56 +08:00
|
|
|
// It calls function doStruct if `pointer` is type of *struct/**struct.
|
|
|
|
|
// It calls function doStructs if `pointer` is type of *[]struct/*[]*struct.
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
2021-06-22 21:48:56 +08:00
|
|
|
// The optional parameter `where` is the same as the parameter of Model.Where function, see Model.Where.
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
2021-06-22 21:48:56 +08:00
|
|
|
// Note that it returns sql.ErrNoRows if the given parameter `pointer` pointed to a variable that has
|
|
|
|
|
// default value and there's no record retrieved with the given conditions from table.
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
2021-06-22 21:48:56 +08:00
|
|
|
// Example:
|
2020-03-13 17:21:30 +08:00
|
|
|
// user := new(User)
|
2020-12-29 13:30:15 +08:00
|
|
|
// err := db.Model("user").Where("id", 1).Scan(user)
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
|
|
|
|
// user := (*User)(nil)
|
2020-12-29 13:30:15 +08:00
|
|
|
// err := db.Model("user").Where("id", 1).Scan(&user)
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
|
|
|
|
// users := ([]User)(nil)
|
2020-12-29 13:30:15 +08:00
|
|
|
// err := db.Model("user").Scan(&users)
|
2020-03-13 17:21:30 +08:00
|
|
|
//
|
|
|
|
|
// users := ([]*User)(nil)
|
2021-11-16 17:21:13 +08:00
|
|
|
// err := db.Model("user").Scan(&users).
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) Scan(pointer any, where ...any) error {
|
2022-03-11 10:24:42 +08:00
|
|
|
reflectInfo := reflection.OriginTypeAndKind(pointer)
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
if reflectInfo.InputKind != reflect.Pointer {
|
2021-10-28 23:18:23 +08:00
|
|
|
return gerror.NewCode(
|
|
|
|
|
gcode.CodeInvalidParameter,
|
|
|
|
|
`the parameter "pointer" for function Scan should type of pointer`,
|
|
|
|
|
)
|
2021-06-22 21:48:56 +08:00
|
|
|
}
|
2021-10-28 23:18:23 +08:00
|
|
|
switch reflectInfo.OriginKind {
|
2021-06-22 21:48:56 +08:00
|
|
|
case reflect.Slice, reflect.Array:
|
|
|
|
|
return m.doStructs(pointer, where...)
|
|
|
|
|
|
|
|
|
|
case reflect.Struct, reflect.Invalid:
|
|
|
|
|
return m.doStruct(pointer, where...)
|
|
|
|
|
|
|
|
|
|
default:
|
2021-07-20 23:02:02 +08:00
|
|
|
return gerror.NewCode(
|
2021-08-24 21:18:59 +08:00
|
|
|
gcode.CodeInvalidParameter,
|
2021-07-20 23:02:02 +08:00
|
|
|
`element of parameter "pointer" for function Scan should type of struct/*struct/[]struct/[]*struct`,
|
|
|
|
|
)
|
2020-03-13 17:21:30 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-06-01 21:33:40 +08:00
|
|
|
|
2024-11-23 18:35:02 +08:00
|
|
|
// ScanAndCount scans a single record or record array that matches the given conditions and counts the total number
|
|
|
|
|
// of records that match those conditions.
|
|
|
|
|
//
|
|
|
|
|
// If `useFieldForCount` is true, it will use the fields specified in the model for counting;
|
|
|
|
|
// The `pointer` parameter is a pointer to a struct that the scanned data will be stored in.
|
|
|
|
|
// The `totalCount` parameter is a pointer to an integer that will be set to the total number of records that match the given conditions.
|
2023-06-01 21:33:40 +08:00
|
|
|
// The where parameter is an optional list of conditions to use when retrieving records.
|
|
|
|
|
//
|
|
|
|
|
// Example:
|
|
|
|
|
//
|
|
|
|
|
// var count int
|
|
|
|
|
// user := new(User)
|
|
|
|
|
// err := db.Model("user").Where("id", 1).ScanAndCount(user,&count,true)
|
|
|
|
|
// fmt.Println(user, count)
|
|
|
|
|
//
|
|
|
|
|
// Example Join:
|
|
|
|
|
//
|
|
|
|
|
// type User struct {
|
|
|
|
|
// Id int
|
|
|
|
|
// Passport string
|
|
|
|
|
// Name string
|
|
|
|
|
// Age int
|
|
|
|
|
// }
|
|
|
|
|
// var users []User
|
|
|
|
|
// var count int
|
|
|
|
|
// db.Model(table).As("u1").
|
|
|
|
|
// LeftJoin(tableName2, "u2", "u2.id=u1.id").
|
|
|
|
|
// Fields("u1.passport,u1.id,u2.name,u2.age").
|
|
|
|
|
// Where("u1.id<2").
|
|
|
|
|
// ScanAndCount(&users, &count, false)
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) ScanAndCount(pointer any, totalCount *int, useFieldForCount bool) (err error) {
|
2023-11-08 21:26:51 +08:00
|
|
|
// support Fields with *, example: .Fields("a.*, b.name"). Count sql is select count(1) from xxx
|
2023-06-01 21:33:40 +08:00
|
|
|
countModel := m.Clone()
|
2026-02-27 16:12:58 +08:00
|
|
|
// Decide how to build the COUNT() expression:
|
|
|
|
|
// - If caller explicitly wants to use the single field expression for counting,
|
|
|
|
|
// honor it (e.g. Fields("DISTINCT col") with useFieldForCount = true).
|
|
|
|
|
// - Otherwise, clear fields to let Count() use its default COUNT(1),
|
|
|
|
|
// avoiding invalid COUNT(field1, field2, ...) with multiple fields,
|
|
|
|
|
// or incorrect COUNT(DISTINCT 1) when Distinct() is set.
|
|
|
|
|
if useFieldForCount && len(m.fields) == 1 {
|
|
|
|
|
countModel.fields = m.fields
|
|
|
|
|
} else {
|
|
|
|
|
countModel.fields = nil
|
2023-06-01 21:33:40 +08:00
|
|
|
}
|
fix(database/gdb): Resolve the cache error overwriting caused by the use of fixed cache keys in pagination queries. (#4339)
```golang
func main() {
adapter := gcache.NewAdapterRedis(g.Redis())
g.DB().GetCache().SetAdapter(adapter)
result, count, err := g.Model("TBL_USER").Cache(gdb.CacheOption{
Duration: 100 * time.Minute,
Name: "VIP",
}).AllAndCount(false)
g.DumpJson(result)
fmt.Println(count, err)
}
```
执行这段查询后`g.DumpJson(result)`的结果是`[
{
"COUNT(1)": 5
}
]`,但是正确结果应该是五条用户信息,查看源代码后发现先执行的count查询和后来select查询都是直接使用了`VIP`这个缓存key,在redis中实际缓存key是`SelectCache:VIP`,第二步查询select获得的是count查询的缓存,所以查询结果是错的。
因此为`Model`增加一个`PageCache`方法允许用户分别设置`count query`和`data query`的缓存参数
```golang
// PageCache sets the cache feature for pagination queries. It allows to configure
// separate cache options for count query and data query in pagination.
//
// Note that, the cache feature is disabled if the model is performing select statement
// on a transaction.
func (m *Model) PageCache(countOption CacheOption, dataOption CacheOption) *Model {
model := m.getModel()
model.pageCacheOption = []CacheOption{countOption, dataOption}
model.cacheEnabled = true
return model
}
```
然后`AllAndCount`在查询时分别给两个查询设置对应的缓存参数`ScanAndCount`同理
```golang
// AllAndCount retrieves all records and the total count of records from the model.
// If useFieldForCount is true, it will use the fields specified in the model for counting;
// otherwise, it will use a constant value of 1 for counting.
// It returns the result as a slice of records, the total count of records, and an error if any.
// The where parameter is an optional list of conditions to use when retrieving records.
//
// Example:
//
// var model Model
// var result Result
// var count int
// where := []any{"name = ?", "John"}
// result, count, err := model.AllAndCount(true)
// if err != nil {
// // Handle error.
// }
// fmt.Println(result, count)
func (m *Model) AllAndCount(useFieldForCount bool) (result Result, totalCount int, err error) {
// Clone the model for counting
countModel := m.Clone()
// If useFieldForCount is false, set the fields to a constant value of 1 for counting
if !useFieldForCount {
countModel.fields = []any{Raw("1")}
}
if len(m.pageCacheOption) > 0 {
countModel = countModel.Cache(m.pageCacheOption[0])
}
// Get the total count of records
totalCount, err = countModel.Count()
if err != nil {
return
}
// If the total count is 0, there are no records to retrieve, so return early
if totalCount == 0 {
return
}
resultModel := m.Clone()
if len(m.pageCacheOption) > 1 {
resultModel = resultModel.Cache(m.pageCacheOption[1])
}
// Retrieve all records
result, err = resultModel.doGetAll(m.GetCtx(), SelectTypeDefault, false)
return
}
```
---------
Co-authored-by: houseme <housemecn@gmail.com>
2026-01-16 10:33:05 +08:00
|
|
|
if len(m.pageCacheOption) > 0 {
|
|
|
|
|
countModel = countModel.Cache(m.pageCacheOption[0])
|
|
|
|
|
}
|
2023-06-01 21:33:40 +08:00
|
|
|
// Get the total count of records
|
|
|
|
|
*totalCount, err = countModel.Count()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the total count is 0, there are no records to retrieve, so return early
|
|
|
|
|
if *totalCount == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
fix(database/gdb): Resolve the cache error overwriting caused by the use of fixed cache keys in pagination queries. (#4339)
```golang
func main() {
adapter := gcache.NewAdapterRedis(g.Redis())
g.DB().GetCache().SetAdapter(adapter)
result, count, err := g.Model("TBL_USER").Cache(gdb.CacheOption{
Duration: 100 * time.Minute,
Name: "VIP",
}).AllAndCount(false)
g.DumpJson(result)
fmt.Println(count, err)
}
```
执行这段查询后`g.DumpJson(result)`的结果是`[
{
"COUNT(1)": 5
}
]`,但是正确结果应该是五条用户信息,查看源代码后发现先执行的count查询和后来select查询都是直接使用了`VIP`这个缓存key,在redis中实际缓存key是`SelectCache:VIP`,第二步查询select获得的是count查询的缓存,所以查询结果是错的。
因此为`Model`增加一个`PageCache`方法允许用户分别设置`count query`和`data query`的缓存参数
```golang
// PageCache sets the cache feature for pagination queries. It allows to configure
// separate cache options for count query and data query in pagination.
//
// Note that, the cache feature is disabled if the model is performing select statement
// on a transaction.
func (m *Model) PageCache(countOption CacheOption, dataOption CacheOption) *Model {
model := m.getModel()
model.pageCacheOption = []CacheOption{countOption, dataOption}
model.cacheEnabled = true
return model
}
```
然后`AllAndCount`在查询时分别给两个查询设置对应的缓存参数`ScanAndCount`同理
```golang
// AllAndCount retrieves all records and the total count of records from the model.
// If useFieldForCount is true, it will use the fields specified in the model for counting;
// otherwise, it will use a constant value of 1 for counting.
// It returns the result as a slice of records, the total count of records, and an error if any.
// The where parameter is an optional list of conditions to use when retrieving records.
//
// Example:
//
// var model Model
// var result Result
// var count int
// where := []any{"name = ?", "John"}
// result, count, err := model.AllAndCount(true)
// if err != nil {
// // Handle error.
// }
// fmt.Println(result, count)
func (m *Model) AllAndCount(useFieldForCount bool) (result Result, totalCount int, err error) {
// Clone the model for counting
countModel := m.Clone()
// If useFieldForCount is false, set the fields to a constant value of 1 for counting
if !useFieldForCount {
countModel.fields = []any{Raw("1")}
}
if len(m.pageCacheOption) > 0 {
countModel = countModel.Cache(m.pageCacheOption[0])
}
// Get the total count of records
totalCount, err = countModel.Count()
if err != nil {
return
}
// If the total count is 0, there are no records to retrieve, so return early
if totalCount == 0 {
return
}
resultModel := m.Clone()
if len(m.pageCacheOption) > 1 {
resultModel = resultModel.Cache(m.pageCacheOption[1])
}
// Retrieve all records
result, err = resultModel.doGetAll(m.GetCtx(), SelectTypeDefault, false)
return
}
```
---------
Co-authored-by: houseme <housemecn@gmail.com>
2026-01-16 10:33:05 +08:00
|
|
|
scanModel := m.Clone()
|
|
|
|
|
if len(m.pageCacheOption) > 1 {
|
|
|
|
|
scanModel = scanModel.Cache(m.pageCacheOption[1])
|
|
|
|
|
}
|
|
|
|
|
err = scanModel.Scan(pointer)
|
2023-06-01 21:33:40 +08:00
|
|
|
return
|
|
|
|
|
}
|
2020-03-13 17:21:30 +08:00
|
|
|
|
2021-02-08 17:57:21 +08:00
|
|
|
// ScanList converts `r` to struct slice which contains other complex struct attributes.
|
|
|
|
|
// Note that the parameter `listPointer` should be type of *[]struct/*[]*struct.
|
2020-07-05 11:54:37 +08:00
|
|
|
//
|
2021-11-05 01:07:06 +08:00
|
|
|
// See Result.ScanList.
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) ScanList(structSlicePointer any, bindToAttrName string, relationAttrNameAndFields ...string) (err error) {
|
2022-01-15 21:38:15 +08:00
|
|
|
var result Result
|
2021-11-23 15:28:40 +08:00
|
|
|
out, err := checkGetSliceElementInfoForScanList(structSlicePointer, bindToAttrName)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2024-10-21 09:22:31 +08:00
|
|
|
if len(m.fields) > 0 || len(m.fieldsEx) != 0 {
|
2022-01-15 21:38:15 +08:00
|
|
|
// There are custom fields.
|
|
|
|
|
result, err = m.All()
|
|
|
|
|
} else {
|
|
|
|
|
// Filter fields using temporary created struct using reflect.New.
|
|
|
|
|
result, err = m.Fields(reflect.New(out.BindToAttrType).Interface()).All()
|
|
|
|
|
}
|
2020-07-05 11:54:37 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2021-11-05 01:07:06 +08:00
|
|
|
var (
|
|
|
|
|
relationAttrName string
|
|
|
|
|
relationFields string
|
|
|
|
|
)
|
|
|
|
|
switch len(relationAttrNameAndFields) {
|
|
|
|
|
case 2:
|
|
|
|
|
relationAttrName = relationAttrNameAndFields[0]
|
|
|
|
|
relationFields = relationAttrNameAndFields[1]
|
|
|
|
|
case 1:
|
|
|
|
|
relationFields = relationAttrNameAndFields[0]
|
|
|
|
|
}
|
2021-11-23 15:28:40 +08:00
|
|
|
return doScanList(doScanListInput{
|
|
|
|
|
Model: m,
|
|
|
|
|
Result: result,
|
|
|
|
|
StructSlicePointer: structSlicePointer,
|
|
|
|
|
StructSliceValue: out.SliceReflectValue,
|
|
|
|
|
BindToAttrName: bindToAttrName,
|
|
|
|
|
RelationAttrName: relationAttrName,
|
|
|
|
|
RelationFields: relationFields,
|
|
|
|
|
})
|
2020-07-05 11:54:37 +08:00
|
|
|
}
|
|
|
|
|
|
2022-11-16 10:04:49 +08:00
|
|
|
// Value retrieves a specified record value from table and returns the result as interface type.
|
|
|
|
|
// It returns nil if there's no record found with the given conditions from table.
|
|
|
|
|
//
|
|
|
|
|
// If the optional parameter `fieldsAndWhere` is given, the fieldsAndWhere[0] is the selected fields
|
|
|
|
|
// and fieldsAndWhere[1:] is treated as where condition fields.
|
|
|
|
|
// Also see Model.Fields and Model.Where functions.
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) Value(fieldsAndWhere ...any) (Value, error) {
|
2024-04-16 19:31:06 +08:00
|
|
|
var (
|
|
|
|
|
core = m.db.GetCore()
|
|
|
|
|
ctx = core.injectInternalColumn(m.GetCtx())
|
|
|
|
|
)
|
2022-11-16 10:04:49 +08:00
|
|
|
if len(fieldsAndWhere) > 0 {
|
|
|
|
|
if len(fieldsAndWhere) > 2 {
|
|
|
|
|
return m.Fields(gconv.String(fieldsAndWhere[0])).Where(fieldsAndWhere[1], fieldsAndWhere[2:]...).Value()
|
|
|
|
|
} else if len(fieldsAndWhere) == 2 {
|
|
|
|
|
return m.Fields(gconv.String(fieldsAndWhere[0])).Where(fieldsAndWhere[1]).Value()
|
|
|
|
|
} else {
|
|
|
|
|
return m.Fields(gconv.String(fieldsAndWhere[0])).Value()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var (
|
2024-12-01 23:47:51 +08:00
|
|
|
sqlWithHolder, holderArgs = m.getFormattedSqlAndArgs(ctx, SelectTypeValue, true)
|
|
|
|
|
all, err = m.doGetAllBySql(ctx, SelectTypeValue, sqlWithHolder, holderArgs...)
|
2022-11-16 10:04:49 +08:00
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if len(all) > 0 {
|
2024-12-01 23:47:51 +08:00
|
|
|
internalData := core.getInternalColumnFromCtx(ctx)
|
|
|
|
|
if internalData == nil {
|
|
|
|
|
return nil, gerror.NewCode(
|
|
|
|
|
gcode.CodeInternalError,
|
|
|
|
|
`query count error: the internal context data is missing. there's internal issue should be fixed`,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
// If FirstResultColumn present, it returns the value of the first record of the first field.
|
|
|
|
|
// It means it use no cache mechanism, while cache mechanism makes `internalData` missing.
|
|
|
|
|
if v, ok := all[0][internalData.FirstResultColumn]; ok {
|
|
|
|
|
return v, nil
|
|
|
|
|
}
|
|
|
|
|
// Fields number check.
|
2024-10-08 20:42:06 +08:00
|
|
|
var recordFields = m.getRecordFields(all[0])
|
|
|
|
|
if len(recordFields) == 1 {
|
|
|
|
|
for _, v := range all[0] {
|
2022-11-16 10:04:49 +08:00
|
|
|
return v, nil
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-08 20:42:06 +08:00
|
|
|
// it returns error if there are multiple fields in the result record.
|
|
|
|
|
return nil, gerror.NewCodef(
|
|
|
|
|
gcode.CodeInvalidParameter,
|
|
|
|
|
`invalid fields for "Value" operation, result fields number "%d"%s, but expect one`,
|
|
|
|
|
len(recordFields),
|
|
|
|
|
gjson.MustEncodeString(recordFields),
|
|
|
|
|
)
|
2022-11-16 10:04:49 +08:00
|
|
|
}
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-08 20:42:06 +08:00
|
|
|
func (m *Model) getRecordFields(record Record) []string {
|
|
|
|
|
if len(record) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
var fields = make([]string, 0)
|
|
|
|
|
for k := range record {
|
|
|
|
|
fields = append(fields, k)
|
|
|
|
|
}
|
|
|
|
|
return fields
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-13 17:21:30 +08:00
|
|
|
// Count does "SELECT COUNT(x) FROM ..." statement for the model.
|
2021-02-08 17:57:21 +08:00
|
|
|
// The optional parameter `where` is the same as the parameter of Model.Where function,
|
2020-03-13 17:21:30 +08:00
|
|
|
// see Model.Where.
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) Count(where ...any) (int, error) {
|
2024-04-16 19:31:06 +08:00
|
|
|
var (
|
|
|
|
|
core = m.db.GetCore()
|
|
|
|
|
ctx = core.injectInternalColumn(m.GetCtx())
|
|
|
|
|
)
|
2020-03-13 17:21:30 +08:00
|
|
|
if len(where) > 0 {
|
|
|
|
|
return m.Where(where[0], where[1:]...).Count()
|
|
|
|
|
}
|
2021-05-27 22:18:16 +08:00
|
|
|
var (
|
2024-12-01 23:47:51 +08:00
|
|
|
sqlWithHolder, holderArgs = m.getFormattedSqlAndArgs(ctx, SelectTypeCount, false)
|
|
|
|
|
all, err = m.doGetAllBySql(ctx, SelectTypeCount, sqlWithHolder, holderArgs...)
|
2021-05-27 22:18:16 +08:00
|
|
|
)
|
2020-03-13 17:21:30 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
2022-03-24 15:33:30 +08:00
|
|
|
if len(all) > 0 {
|
2024-12-01 23:47:51 +08:00
|
|
|
internalData := core.getInternalColumnFromCtx(ctx)
|
|
|
|
|
if internalData == nil {
|
|
|
|
|
return 0, gerror.NewCode(
|
|
|
|
|
gcode.CodeInternalError,
|
|
|
|
|
`query count error: the internal context data is missing. there's internal issue should be fixed`,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
// If FirstResultColumn present, it returns the value of the first record of the first field.
|
|
|
|
|
// It means it use no cache mechanism, while cache mechanism makes `internalData` missing.
|
|
|
|
|
if v, ok := all[0][internalData.FirstResultColumn]; ok {
|
|
|
|
|
return v.Int(), nil
|
|
|
|
|
}
|
|
|
|
|
// Fields number check.
|
2024-10-08 20:42:06 +08:00
|
|
|
var recordFields = m.getRecordFields(all[0])
|
|
|
|
|
if len(recordFields) == 1 {
|
|
|
|
|
for _, v := range all[0] {
|
2022-12-30 16:54:43 +08:00
|
|
|
return v.Int(), nil
|
2022-03-24 15:33:30 +08:00
|
|
|
}
|
2020-03-13 17:21:30 +08:00
|
|
|
}
|
2024-10-08 20:42:06 +08:00
|
|
|
// it returns error if there are multiple fields in the result record.
|
|
|
|
|
return 0, gerror.NewCodef(
|
|
|
|
|
gcode.CodeInvalidParameter,
|
|
|
|
|
`invalid fields for "Count" operation, result fields number "%d"%s, but expect one`,
|
|
|
|
|
len(recordFields),
|
|
|
|
|
gjson.MustEncodeString(recordFields),
|
|
|
|
|
)
|
2020-03-13 17:21:30 +08:00
|
|
|
}
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-24 15:29:03 +08:00
|
|
|
// Exist does "SELECT 1 FROM ... LIMIT 1" statement for the model.
|
|
|
|
|
// The optional parameter `where` is the same as the parameter of Model.Where function,
|
|
|
|
|
// see Model.Where.
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) Exist(where ...any) (bool, error) {
|
2024-10-24 15:29:03 +08:00
|
|
|
if len(where) > 0 {
|
|
|
|
|
return m.Where(where[0], where[1:]...).Exist()
|
|
|
|
|
}
|
|
|
|
|
one, err := m.Fields(Raw("1")).One()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return false, err
|
|
|
|
|
}
|
|
|
|
|
for _, val := range one {
|
|
|
|
|
if val.Bool() {
|
|
|
|
|
return true, nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false, nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-02 12:17:06 +08:00
|
|
|
// CountColumn does "SELECT COUNT(x) FROM ..." statement for the model.
|
2022-12-30 16:54:43 +08:00
|
|
|
func (m *Model) CountColumn(column string) (int, error) {
|
2021-05-02 12:17:06 +08:00
|
|
|
if len(column) == 0 {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
|
|
|
|
return m.Fields(column).Count()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Min does "SELECT MIN(x) FROM ..." statement for the model.
|
|
|
|
|
func (m *Model) Min(column string) (float64, error) {
|
|
|
|
|
if len(column) == 0 {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
2021-11-17 21:29:46 +08:00
|
|
|
value, err := m.Fields(fmt.Sprintf(`MIN(%s)`, m.QuoteWord(column))).Value()
|
2021-05-02 12:17:06 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
return value.Float64(), err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Max does "SELECT MAX(x) FROM ..." statement for the model.
|
|
|
|
|
func (m *Model) Max(column string) (float64, error) {
|
|
|
|
|
if len(column) == 0 {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
2021-11-17 21:29:46 +08:00
|
|
|
value, err := m.Fields(fmt.Sprintf(`MAX(%s)`, m.QuoteWord(column))).Value()
|
2021-05-02 12:17:06 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
return value.Float64(), err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Avg does "SELECT AVG(x) FROM ..." statement for the model.
|
|
|
|
|
func (m *Model) Avg(column string) (float64, error) {
|
|
|
|
|
if len(column) == 0 {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
2021-11-17 21:29:46 +08:00
|
|
|
value, err := m.Fields(fmt.Sprintf(`AVG(%s)`, m.QuoteWord(column))).Value()
|
2021-05-02 12:17:06 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
return value.Float64(), err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sum does "SELECT SUM(x) FROM ..." statement for the model.
|
|
|
|
|
func (m *Model) Sum(column string) (float64, error) {
|
|
|
|
|
if len(column) == 0 {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
2021-11-17 21:29:46 +08:00
|
|
|
value, err := m.Fields(fmt.Sprintf(`SUM(%s)`, m.QuoteWord(column))).Value()
|
2021-05-02 12:17:06 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
return value.Float64(), err
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-06 23:06:39 +08:00
|
|
|
// Union does "(SELECT xxx FROM xxx) UNION (SELECT xxx FROM xxx) ..." statement for the model.
|
|
|
|
|
func (m *Model) Union(unions ...*Model) *Model {
|
|
|
|
|
return m.db.Union(unions...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UnionAll does "(SELECT xxx FROM xxx) UNION ALL (SELECT xxx FROM xxx) ..." statement for the model.
|
|
|
|
|
func (m *Model) UnionAll(unions ...*Model) *Model {
|
|
|
|
|
return m.db.UnionAll(unions...)
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-17 22:01:17 +08:00
|
|
|
// Limit sets the "LIMIT" statement for the model.
|
|
|
|
|
// The parameter `limit` can be either one or two number, if passed two number is passed,
|
|
|
|
|
// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
|
|
|
|
|
// statement.
|
2026-02-27 16:00:53 +08:00
|
|
|
// Note: Negative values are treated as zero.
|
2021-11-17 22:01:17 +08:00
|
|
|
func (m *Model) Limit(limit ...int) *Model {
|
|
|
|
|
model := m.getModel()
|
|
|
|
|
switch len(limit) {
|
|
|
|
|
case 1:
|
2026-02-27 16:00:53 +08:00
|
|
|
if limit[0] < 0 {
|
|
|
|
|
limit[0] = 0
|
|
|
|
|
}
|
2021-11-17 22:01:17 +08:00
|
|
|
model.limit = limit[0]
|
|
|
|
|
case 2:
|
2026-02-27 16:00:53 +08:00
|
|
|
if limit[0] < 0 {
|
|
|
|
|
limit[0] = 0
|
|
|
|
|
}
|
|
|
|
|
if limit[1] < 0 {
|
|
|
|
|
limit[1] = 0
|
|
|
|
|
}
|
2021-11-17 22:01:17 +08:00
|
|
|
model.start = limit[0]
|
|
|
|
|
model.limit = limit[1]
|
|
|
|
|
}
|
|
|
|
|
return model
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Offset sets the "OFFSET" statement for the model.
|
|
|
|
|
// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
|
2026-02-27 16:00:53 +08:00
|
|
|
// Note: Negative values are treated as zero.
|
2021-11-17 22:01:17 +08:00
|
|
|
func (m *Model) Offset(offset int) *Model {
|
|
|
|
|
model := m.getModel()
|
2026-02-27 16:00:53 +08:00
|
|
|
if offset < 0 {
|
|
|
|
|
offset = 0
|
|
|
|
|
}
|
2021-11-17 22:01:17 +08:00
|
|
|
model.offset = offset
|
|
|
|
|
return model
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Distinct forces the query to only return distinct results.
|
|
|
|
|
func (m *Model) Distinct() *Model {
|
|
|
|
|
model := m.getModel()
|
|
|
|
|
model.distinct = "DISTINCT "
|
|
|
|
|
return model
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Page sets the paging number for the model.
|
|
|
|
|
// The parameter `page` is started from 1 for paging.
|
|
|
|
|
// Note that, it differs that the Limit function starts from 0 for "LIMIT" statement.
|
2026-02-27 16:00:53 +08:00
|
|
|
// Note: Negative limit values are treated as zero.
|
2021-11-17 22:01:17 +08:00
|
|
|
func (m *Model) Page(page, limit int) *Model {
|
|
|
|
|
model := m.getModel()
|
|
|
|
|
if page <= 0 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
2026-02-27 16:00:53 +08:00
|
|
|
if limit < 0 {
|
|
|
|
|
limit = 0
|
|
|
|
|
}
|
2021-11-17 22:01:17 +08:00
|
|
|
model.start = (page - 1) * limit
|
|
|
|
|
model.limit = limit
|
|
|
|
|
return model
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Having sets the having statement for the model.
|
|
|
|
|
// The parameters of this function usage are as the same as function Where.
|
|
|
|
|
// See Where.
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) Having(having any, args ...any) *Model {
|
2021-11-17 22:01:17 +08:00
|
|
|
model := m.getModel()
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
model.having = []any{
|
2021-11-17 22:01:17 +08:00
|
|
|
having, args,
|
|
|
|
|
}
|
|
|
|
|
return model
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-16 10:04:49 +08:00
|
|
|
// doGetAll does "SELECT FROM ..." statement for the model.
|
|
|
|
|
// It retrieves the records from table and returns the result as slice type.
|
|
|
|
|
// It returns nil if there's no record retrieved with the given conditions from table.
|
|
|
|
|
//
|
|
|
|
|
// The parameter `limit1` specifies whether limits querying only one record if m.limit is not set.
|
|
|
|
|
// The optional parameter `where` is the same as the parameter of Model.Where function,
|
|
|
|
|
// see Model.Where.
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) doGetAll(ctx context.Context, selectType SelectType, limit1 bool, where ...any) (Result, error) {
|
2022-11-16 10:04:49 +08:00
|
|
|
if len(where) > 0 {
|
|
|
|
|
return m.Where(where[0], where[1:]...).All()
|
|
|
|
|
}
|
2024-12-01 23:47:51 +08:00
|
|
|
sqlWithHolder, holderArgs := m.getFormattedSqlAndArgs(ctx, selectType, limit1)
|
|
|
|
|
return m.doGetAllBySql(ctx, selectType, sqlWithHolder, holderArgs...)
|
2022-11-16 10:04:49 +08:00
|
|
|
}
|
|
|
|
|
|
2020-07-15 09:15:03 +08:00
|
|
|
// doGetAllBySql does the select statement on the database.
|
2024-10-21 09:22:31 +08:00
|
|
|
func (m *Model) doGetAllBySql(
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
ctx context.Context, selectType SelectType, sql string, args ...any,
|
2024-10-21 09:22:31 +08:00
|
|
|
) (result Result, err error) {
|
2022-03-31 15:42:12 +08:00
|
|
|
if result, err = m.getSelectResultFromCache(ctx, sql, args...); err != nil || result != nil {
|
|
|
|
|
return
|
2020-04-26 21:31:55 +08:00
|
|
|
}
|
2022-03-14 23:47:55 +08:00
|
|
|
|
|
|
|
|
in := &HookSelectInput{
|
|
|
|
|
internalParamHookSelect: internalParamHookSelect{
|
|
|
|
|
internalParamHook: internalParamHook{
|
2022-05-09 14:22:28 +08:00
|
|
|
link: m.getLink(false),
|
2022-03-14 23:47:55 +08:00
|
|
|
},
|
2022-03-24 15:33:30 +08:00
|
|
|
handler: m.hookHandler.Select,
|
2022-03-14 23:47:55 +08:00
|
|
|
},
|
2024-12-01 23:47:51 +08:00
|
|
|
Model: m,
|
|
|
|
|
Table: m.tables,
|
2024-12-09 23:12:20 +08:00
|
|
|
Schema: m.schema,
|
2024-12-01 23:47:51 +08:00
|
|
|
Sql: sql,
|
|
|
|
|
Args: m.mergeArguments(args),
|
|
|
|
|
SelectType: selectType,
|
2022-03-14 23:47:55 +08:00
|
|
|
}
|
2022-03-31 15:42:12 +08:00
|
|
|
if result, err = in.Next(ctx); err != nil {
|
|
|
|
|
return
|
2020-04-26 21:31:55 +08:00
|
|
|
}
|
2022-03-31 15:42:12 +08:00
|
|
|
|
2024-12-01 23:47:51 +08:00
|
|
|
err = m.saveSelectResultToCache(ctx, selectType, result, sql, args...)
|
2022-03-31 15:42:12 +08:00
|
|
|
return
|
2020-04-26 21:31:55 +08:00
|
|
|
}
|
2021-05-27 22:18:16 +08:00
|
|
|
|
2023-02-08 19:08:10 +08:00
|
|
|
func (m *Model) getFormattedSqlAndArgs(
|
2024-12-01 23:47:51 +08:00
|
|
|
ctx context.Context, selectType SelectType, limit1 bool,
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
) (sqlWithHolder string, holderArgs []any) {
|
2024-12-01 23:47:51 +08:00
|
|
|
switch selectType {
|
|
|
|
|
case SelectTypeCount:
|
2022-03-24 15:33:30 +08:00
|
|
|
queryFields := "COUNT(1)"
|
2024-10-21 09:22:31 +08:00
|
|
|
if len(m.fields) > 0 {
|
2021-05-27 22:18:16 +08:00
|
|
|
// DO NOT quote the m.fields here, in case of fields like:
|
|
|
|
|
// DISTINCT t.user_id uid
|
2024-10-21 09:22:31 +08:00
|
|
|
queryFields = fmt.Sprintf(`COUNT(%s%s)`, m.distinct, m.getFieldsAsStr())
|
2021-05-27 22:18:16 +08:00
|
|
|
}
|
2021-06-21 19:21:38 +08:00
|
|
|
// Raw SQL Model.
|
|
|
|
|
if m.rawSql != "" {
|
2026-01-16 13:05:33 +08:00
|
|
|
conditionWhere, conditionExtra, conditionArgs := m.formatCondition(ctx, false, true)
|
|
|
|
|
sqlWithHolder = fmt.Sprintf(
|
|
|
|
|
"SELECT %s FROM (%s%s) AS T",
|
|
|
|
|
queryFields, m.rawSql, conditionWhere+conditionExtra,
|
|
|
|
|
)
|
|
|
|
|
return sqlWithHolder, conditionArgs
|
2021-06-21 19:21:38 +08:00
|
|
|
}
|
2022-03-24 17:51:49 +08:00
|
|
|
conditionWhere, conditionExtra, conditionArgs := m.formatCondition(ctx, false, true)
|
2022-03-24 15:33:30 +08:00
|
|
|
sqlWithHolder = fmt.Sprintf("SELECT %s FROM %s%s", queryFields, m.tables, conditionWhere+conditionExtra)
|
2021-05-27 22:18:16 +08:00
|
|
|
if len(m.groupBy) > 0 {
|
|
|
|
|
sqlWithHolder = fmt.Sprintf("SELECT COUNT(1) FROM (%s) count_alias", sqlWithHolder)
|
|
|
|
|
}
|
|
|
|
|
return sqlWithHolder, conditionArgs
|
|
|
|
|
|
|
|
|
|
default:
|
2022-03-24 17:51:49 +08:00
|
|
|
conditionWhere, conditionExtra, conditionArgs := m.formatCondition(ctx, limit1, false)
|
2021-06-06 23:06:39 +08:00
|
|
|
// Raw SQL Model, especially for UNION/UNION ALL featured SQL.
|
|
|
|
|
if m.rawSql != "" {
|
|
|
|
|
sqlWithHolder = fmt.Sprintf(
|
|
|
|
|
"%s%s",
|
|
|
|
|
m.rawSql,
|
|
|
|
|
conditionWhere+conditionExtra,
|
|
|
|
|
)
|
|
|
|
|
return sqlWithHolder, conditionArgs
|
|
|
|
|
}
|
2021-05-27 22:18:16 +08:00
|
|
|
// DO NOT quote the m.fields where, in case of fields like:
|
|
|
|
|
// DISTINCT t.user_id uid
|
|
|
|
|
sqlWithHolder = fmt.Sprintf(
|
|
|
|
|
"SELECT %s%s FROM %s%s",
|
2022-03-24 15:33:30 +08:00
|
|
|
m.distinct, m.getFieldsFiltered(), m.tables, conditionWhere+conditionExtra,
|
2021-05-27 22:18:16 +08:00
|
|
|
)
|
|
|
|
|
return sqlWithHolder, conditionArgs
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-17 22:01:17 +08:00
|
|
|
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
func (m *Model) getHolderAndArgsAsSubModel(ctx context.Context) (holder string, args []any) {
|
2023-02-08 19:08:10 +08:00
|
|
|
holder, args = m.getFormattedSqlAndArgs(
|
2024-12-01 23:47:51 +08:00
|
|
|
ctx, SelectTypeDefault, false,
|
2023-02-08 19:08:10 +08:00
|
|
|
)
|
|
|
|
|
args = m.mergeArguments(args)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-30 15:53:56 +08:00
|
|
|
func (m *Model) getAutoPrefix() string {
|
2021-11-17 22:01:17 +08:00
|
|
|
autoPrefix := ""
|
|
|
|
|
if gstr.Contains(m.tables, " JOIN ") {
|
2025-12-26 16:43:19 +08:00
|
|
|
autoPrefix = m.QuoteWord(
|
|
|
|
|
m.db.GetCore().guessPrimaryTableName(m.tablesInit),
|
|
|
|
|
)
|
2021-11-17 22:01:17 +08:00
|
|
|
}
|
2022-04-30 15:53:56 +08:00
|
|
|
return autoPrefix
|
|
|
|
|
}
|
2021-11-17 22:01:17 +08:00
|
|
|
|
2024-10-21 09:22:31 +08:00
|
|
|
func (m *Model) getFieldsAsStr() string {
|
|
|
|
|
var (
|
|
|
|
|
fieldsStr string
|
|
|
|
|
)
|
|
|
|
|
for _, v := range m.fields {
|
|
|
|
|
field := gconv.String(v)
|
|
|
|
|
switch {
|
|
|
|
|
case gstr.ContainsAny(field, "()"):
|
|
|
|
|
case gstr.ContainsAny(field, ". "):
|
|
|
|
|
default:
|
|
|
|
|
switch v.(type) {
|
|
|
|
|
case Raw, *Raw:
|
|
|
|
|
default:
|
2025-11-21 17:27:09 +08:00
|
|
|
field = m.QuoteWord(field)
|
2024-10-21 09:22:31 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if fieldsStr != "" {
|
|
|
|
|
fieldsStr += ","
|
|
|
|
|
}
|
|
|
|
|
fieldsStr += field
|
|
|
|
|
}
|
|
|
|
|
return fieldsStr
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-16 10:04:49 +08:00
|
|
|
// getFieldsFiltered checks the fields and fieldsEx attributes, filters and returns the fields that will
|
|
|
|
|
// really be committed to underlying database driver.
|
|
|
|
|
func (m *Model) getFieldsFiltered() string {
|
2024-10-21 09:22:31 +08:00
|
|
|
if len(m.fieldsEx) == 0 && len(m.fields) == 0 {
|
|
|
|
|
return defaultField
|
|
|
|
|
}
|
|
|
|
|
if len(m.fieldsEx) == 0 && len(m.fields) > 0 {
|
|
|
|
|
return m.getFieldsAsStr()
|
2022-11-16 10:04:49 +08:00
|
|
|
}
|
|
|
|
|
var (
|
|
|
|
|
fieldsArray []string
|
2024-10-21 09:22:31 +08:00
|
|
|
fieldsExSet = gset.NewStrSetFrom(gconv.Strings(m.fieldsEx))
|
2022-11-16 10:04:49 +08:00
|
|
|
)
|
2024-10-21 09:22:31 +08:00
|
|
|
if len(m.fields) > 0 {
|
2022-11-16 10:04:49 +08:00
|
|
|
// Filter custom fields with fieldEx.
|
|
|
|
|
fieldsArray = make([]string, 0, 8)
|
2024-10-21 09:22:31 +08:00
|
|
|
for _, v := range m.fields {
|
|
|
|
|
field := gconv.String(v)
|
|
|
|
|
fieldsArray = append(fieldsArray, field[gstr.PosR(field, "-")+1:])
|
2022-11-16 10:04:49 +08:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if gstr.Contains(m.tables, " ") {
|
|
|
|
|
panic("function FieldsEx supports only single table operations")
|
|
|
|
|
}
|
|
|
|
|
// Filter table fields with fieldEx.
|
|
|
|
|
tableFields, err := m.TableFields(m.tablesInit)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
if len(tableFields) == 0 {
|
|
|
|
|
panic(fmt.Sprintf(`empty table fields for table "%s"`, m.tables))
|
|
|
|
|
}
|
|
|
|
|
fieldsArray = make([]string, len(tableFields))
|
|
|
|
|
for k, v := range tableFields {
|
|
|
|
|
fieldsArray[v.Index] = k
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
newFields := ""
|
|
|
|
|
for _, k := range fieldsArray {
|
|
|
|
|
if fieldsExSet.Contains(k) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if len(newFields) > 0 {
|
|
|
|
|
newFields += ","
|
|
|
|
|
}
|
2025-11-21 17:27:09 +08:00
|
|
|
newFields += m.QuoteWord(k)
|
2022-11-16 10:04:49 +08:00
|
|
|
}
|
|
|
|
|
return newFields
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-30 15:53:56 +08:00
|
|
|
// formatCondition formats where arguments of the model and returns a new condition sql and its arguments.
|
|
|
|
|
// Note that this function does not change any attribute value of the `m`.
|
|
|
|
|
//
|
|
|
|
|
// The parameter `limit1` specifies whether limits querying only one record if m.limit is not set.
|
2023-02-15 09:45:40 +08:00
|
|
|
func (m *Model) formatCondition(
|
|
|
|
|
ctx context.Context, limit1 bool, isCountStatement bool,
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
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.
2025-08-28 16:53:19 +08:00
|
|
|
) (conditionWhere string, conditionExtra string, conditionArgs []any) {
|
2022-04-30 15:53:56 +08:00
|
|
|
var autoPrefix = m.getAutoPrefix()
|
2021-11-17 22:01:17 +08:00
|
|
|
// GROUP BY.
|
|
|
|
|
if m.groupBy != "" {
|
|
|
|
|
conditionExtra += " GROUP BY " + m.groupBy
|
|
|
|
|
}
|
2022-04-30 15:53:56 +08:00
|
|
|
// WHERE
|
|
|
|
|
conditionWhere, conditionArgs = m.whereBuilder.Build()
|
feat(database/gdb): Optimize SoftTime feature (#4559)
本次PR主要针对GoFrame ORM中的软删除`SoftTime`功能进行了优化
- 新增`SoftTimeFieldType`枚举类型,用于区分创建、更新、删除三种不同的软时间字段
- 替代之前使用的魔数方式,提高类型安全性
- 将原有的6个方法精简为4个方法, 合并了三个几乎相同的`GetFieldNameAndTypeFor*`方法为统一的方法
This pull request refactors and simplifies the "soft time"
(created/updated/deleted timestamp) handling logic in the database
layer, making the codebase more maintainable and extensible. The changes
consolidate multiple similar methods into general-purpose ones, improve
cache key generation, and clarify the logic for generating and applying
soft time field values and conditions.
Key changes include:
**Soft Time API Refactoring and Simplification**
- Consolidated multiple methods (`GetFieldNameAndTypeForCreate`,
`GetFieldNameAndTypeForUpdate`, `GetFieldNameAndTypeForDelete`) into a
single, parameterized method `GetFieldInfo`, reducing code duplication
and making it easier to support new soft time field types. The interface
and implementation for soft time maintenance (`iSoftTimeMaintainer`,
`softTimeMaintainer`) have been updated accordingly.
[[1]](diffhunk://#diff-6c1d606032d981a7b8aecd3a7167823f76b69407a29eb9a244175a82f59965d8L46-R66)
[[2]](diffhunk://#diff-6c1d606032d981a7b8aecd3a7167823f76b69407a29eb9a244175a82f59965d8L105-R180)
- Combined and renamed methods for generating soft time field values and
delete conditions, such as merging
`GetValueByFieldTypeForCreateOrUpdate` into `GetFieldValue`, and
`GetWhereConditionForDelete` into `GetDeleteCondition`. Related usages
throughout the codebase have been updated to use the new methods.
[[1]](diffhunk://#diff-6c1d606032d981a7b8aecd3a7167823f76b69407a29eb9a244175a82f59965d8L255-R206)
[[2]](diffhunk://#diff-97beb485550e4381182a04bbb857a25b7f4ecd4a594dff8ac884cfaae38f3046L34-R35)
[[3]](diffhunk://#diff-97beb485550e4381182a04bbb857a25b7f4ecd4a594dff8ac884cfaae38f3046L55-R55)
[[4]](diffhunk://#diff-88304ddb7791aedbd83dafb68374aecab286d1356a7f2f149a8e57ac1a7f40b4L265-R267)
[[5]](diffhunk://#diff-88304ddb7791aedbd83dafb68374aecab286d1356a7f2f149a8e57ac1a7f40b4L298-R311)
[[6]](diffhunk://#diff-d4f6e0370e049dea52f3db9a13c64e2cfb2f7ef012433186e21179149b626d0fL944-R944)
**Soft Delete Logic Improvements**
- Refactored the logic for building soft delete WHERE conditions and
generating update data, with clearer and more robust handling of field
types and prefixes. Introduced helper methods like
`buildDeleteCondition`, `GetDeleteData`, and improved error logging for
invalid field types.
[[1]](diffhunk://#diff-6c1d606032d981a7b8aecd3a7167823f76b69407a29eb9a244175a82f59965d8L287-R234)
[[2]](diffhunk://#diff-6c1d606032d981a7b8aecd3a7167823f76b69407a29eb9a244175a82f59965d8L313-R395)
**Cache Key Generation Enhancements**
- Added dedicated helper functions for generating cache keys for table
names, table fields, select queries, and soft time field/type lookups,
improving cache consistency and code readability.
[[1]](diffhunk://#diff-d57d57e6f9b342ba6fa30c4bb413e2f4f3514a8cd5ad36949eef126e5f8b7ac9R969)
[[2]](diffhunk://#diff-d57d57e6f9b342ba6fa30c4bb413e2f4f3514a8cd5ad36949eef126e5f8b7ac9R980)
[[3]](diffhunk://#diff-d57d57e6f9b342ba6fa30c4bb413e2f4f3514a8cd5ad36949eef126e5f8b7ac9R993-R1002)
[[4]](diffhunk://#diff-b1bbe5e3995261813e4e0ac6ffee8a37c236eaa2759f2bd82e211711695a70bcL790-R790)
**General Code Cleanup**
- Removed redundant code, clarified comments, and improved naming
throughout the affected files, making the code easier to follow and
maintain.
[[1]](diffhunk://#diff-6c1d606032d981a7b8aecd3a7167823f76b69407a29eb9a244175a82f59965d8L105-R180)
[[2]](diffhunk://#diff-6c1d606032d981a7b8aecd3a7167823f76b69407a29eb9a244175a82f59965d8L255-R206)
Let me know if you'd like a walkthrough of any specific part of the
refactored soft time logic!
2025-12-12 15:14:21 +08:00
|
|
|
softDeletingCondition := m.softTimeMaintainer().GetDeleteCondition(ctx)
|
2022-05-06 22:21:43 +08:00
|
|
|
if m.rawSql != "" && conditionWhere != "" {
|
|
|
|
|
if gstr.ContainsI(m.rawSql, " WHERE ") {
|
|
|
|
|
conditionWhere = " AND " + conditionWhere
|
|
|
|
|
} else {
|
|
|
|
|
conditionWhere = " WHERE " + conditionWhere
|
|
|
|
|
}
|
|
|
|
|
} else if !m.unscoped && softDeletingCondition != "" {
|
|
|
|
|
if conditionWhere == "" {
|
|
|
|
|
conditionWhere = fmt.Sprintf(` WHERE %s`, softDeletingCondition)
|
|
|
|
|
} else {
|
|
|
|
|
conditionWhere = fmt.Sprintf(` WHERE (%s) AND %s`, conditionWhere, softDeletingCondition)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if conditionWhere != "" {
|
|
|
|
|
conditionWhere = " WHERE " + conditionWhere
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-17 22:01:17 +08:00
|
|
|
// HAVING.
|
|
|
|
|
if len(m.having) > 0 {
|
2022-04-30 15:53:56 +08:00
|
|
|
havingHolder := WhereHolder{
|
2021-12-28 17:15:01 +08:00
|
|
|
Where: m.having[0],
|
|
|
|
|
Args: gconv.Interfaces(m.having[1]),
|
|
|
|
|
Prefix: autoPrefix,
|
|
|
|
|
}
|
2022-03-24 17:51:49 +08:00
|
|
|
havingStr, havingArgs := formatWhereHolder(ctx, m.db, formatWhereHolderInput{
|
2022-04-30 15:53:56 +08:00
|
|
|
WhereHolder: havingHolder,
|
|
|
|
|
OmitNil: m.option&optionOmitNilWhere > 0,
|
|
|
|
|
OmitEmpty: m.option&optionOmitEmptyWhere > 0,
|
|
|
|
|
Schema: m.schema,
|
|
|
|
|
Table: m.tables,
|
2021-11-17 22:01:17 +08:00
|
|
|
})
|
|
|
|
|
if len(havingStr) > 0 {
|
|
|
|
|
conditionExtra += " HAVING " + havingStr
|
|
|
|
|
conditionArgs = append(conditionArgs, havingArgs...)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// ORDER BY.
|
2023-11-16 20:15:48 +08:00
|
|
|
if !isCountStatement { // The count statement of sqlserver cannot contain the order by statement
|
|
|
|
|
if m.orderBy != "" {
|
|
|
|
|
conditionExtra += " ORDER BY " + m.orderBy
|
|
|
|
|
}
|
2021-11-17 22:01:17 +08:00
|
|
|
}
|
|
|
|
|
// LIMIT.
|
|
|
|
|
if !isCountStatement {
|
|
|
|
|
if m.limit != 0 {
|
|
|
|
|
if m.start >= 0 {
|
|
|
|
|
conditionExtra += fmt.Sprintf(" LIMIT %d,%d", m.start, m.limit)
|
|
|
|
|
} else {
|
|
|
|
|
conditionExtra += fmt.Sprintf(" LIMIT %d", m.limit)
|
|
|
|
|
}
|
|
|
|
|
} else if limit1 {
|
|
|
|
|
conditionExtra += " LIMIT 1"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if m.offset >= 0 {
|
|
|
|
|
conditionExtra += fmt.Sprintf(" OFFSET %d", m.offset)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if m.lockInfo != "" {
|
|
|
|
|
conditionExtra += " " + m.lockInfo
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|