diff --git a/container/gvar/gvar_vars.go b/container/gvar/gvar_vars.go index af52f9c698d..101e2f0b872 100644 --- a/container/gvar/gvar_vars.go +++ b/container/gvar/gvar_vars.go @@ -15,14 +15,25 @@ type Vars []*Var // Strings converts and returns `vs` as []string. func (vs Vars) Strings() (s []string) { + s = make([]string, 0, len(vs)) for _, v := range vs { s = append(s, v.String()) } return s } +// Bools converts and returns `vs` as []bool. +func (vs Vars) Bools() (s []bool) { + s = make([]bool, 0, len(vs)) + for _, v := range vs { + s = append(s, v.Bool()) + } + return s +} + // Interfaces converts and returns `vs` as []any. func (vs Vars) Interfaces() (s []any) { + s = make([]any, 0, len(vs)) for _, v := range vs { s = append(s, v.Val()) } @@ -31,6 +42,7 @@ func (vs Vars) Interfaces() (s []any) { // Float32s converts and returns `vs` as []float32. func (vs Vars) Float32s() (s []float32) { + s = make([]float32, 0, len(vs)) for _, v := range vs { s = append(s, v.Float32()) } @@ -39,6 +51,7 @@ func (vs Vars) Float32s() (s []float32) { // Float64s converts and returns `vs` as []float64. func (vs Vars) Float64s() (s []float64) { + s = make([]float64, 0, len(vs)) for _, v := range vs { s = append(s, v.Float64()) } @@ -47,6 +60,7 @@ func (vs Vars) Float64s() (s []float64) { // Ints converts and returns `vs` as []Int. func (vs Vars) Ints() (s []int) { + s = make([]int, 0, len(vs)) for _, v := range vs { s = append(s, v.Int()) } @@ -55,6 +69,7 @@ func (vs Vars) Ints() (s []int) { // Int8s converts and returns `vs` as []int8. func (vs Vars) Int8s() (s []int8) { + s = make([]int8, 0, len(vs)) for _, v := range vs { s = append(s, v.Int8()) } @@ -63,6 +78,7 @@ func (vs Vars) Int8s() (s []int8) { // Int16s converts and returns `vs` as []int16. func (vs Vars) Int16s() (s []int16) { + s = make([]int16, 0, len(vs)) for _, v := range vs { s = append(s, v.Int16()) } @@ -71,6 +87,7 @@ func (vs Vars) Int16s() (s []int16) { // Int32s converts and returns `vs` as []int32. func (vs Vars) Int32s() (s []int32) { + s = make([]int32, 0, len(vs)) for _, v := range vs { s = append(s, v.Int32()) } @@ -79,6 +96,7 @@ func (vs Vars) Int32s() (s []int32) { // Int64s converts and returns `vs` as []int64. func (vs Vars) Int64s() (s []int64) { + s = make([]int64, 0, len(vs)) for _, v := range vs { s = append(s, v.Int64()) } @@ -87,6 +105,7 @@ func (vs Vars) Int64s() (s []int64) { // Uints converts and returns `vs` as []uint. func (vs Vars) Uints() (s []uint) { + s = make([]uint, 0, len(vs)) for _, v := range vs { s = append(s, v.Uint()) } @@ -95,6 +114,7 @@ func (vs Vars) Uints() (s []uint) { // Uint8s converts and returns `vs` as []uint8. func (vs Vars) Uint8s() (s []uint8) { + s = make([]uint8, 0, len(vs)) for _, v := range vs { s = append(s, v.Uint8()) } @@ -103,6 +123,7 @@ func (vs Vars) Uint8s() (s []uint8) { // Uint16s converts and returns `vs` as []uint16. func (vs Vars) Uint16s() (s []uint16) { + s = make([]uint16, 0, len(vs)) for _, v := range vs { s = append(s, v.Uint16()) } @@ -111,6 +132,7 @@ func (vs Vars) Uint16s() (s []uint16) { // Uint32s converts and returns `vs` as []uint32. func (vs Vars) Uint32s() (s []uint32) { + s = make([]uint32, 0, len(vs)) for _, v := range vs { s = append(s, v.Uint32()) } @@ -119,6 +141,7 @@ func (vs Vars) Uint32s() (s []uint32) { // Uint64s converts and returns `vs` as []uint64. func (vs Vars) Uint64s() (s []uint64) { + s = make([]uint64, 0, len(vs)) for _, v := range vs { s = append(s, v.Uint64()) } diff --git a/container/gvar/gvar_z_unit_vars_test.go b/container/gvar/gvar_z_unit_vars_test.go index 4933f540c58..7db2cb421be 100644 --- a/container/gvar/gvar_z_unit_vars_test.go +++ b/container/gvar/gvar_z_unit_vars_test.go @@ -22,6 +22,7 @@ func TestVars(t *testing.T) { gvar.New(3), } t.AssertEQ(vs.Strings(), []string{"1", "2", "3"}) + t.AssertEQ(vs.Bools(), []bool{true, true, true}) t.AssertEQ(vs.Interfaces(), []any{1, 2, 3}) t.AssertEQ(vs.Float32s(), []float32{1, 2, 3}) t.AssertEQ(vs.Float64s(), []float64{1, 2, 3}) @@ -38,6 +39,46 @@ func TestVars(t *testing.T) { }) } +func TestVars_Bools(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + // Test with various boolean-like values + var vs = gvar.Vars{ + gvar.New(true), + gvar.New(false), + gvar.New(1), + gvar.New(0), + gvar.New("true"), + gvar.New("false"), + gvar.New("1"), + gvar.New("0"), + } + expected := []bool{true, false, true, false, true, false, true, false} + t.AssertEQ(vs.Bools(), expected) + }) +} + +func TestVars_Empty(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + // Test with empty Vars + var vs = gvar.Vars{} + t.AssertEQ(vs.Strings(), []string{}) + t.AssertEQ(vs.Bools(), []bool{}) + t.AssertEQ(vs.Interfaces(), []any{}) + t.AssertEQ(vs.Ints(), []int{}) + t.AssertEQ(vs.Float64s(), []float64{}) + }) +} + +func TestVars_SingleElement(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + // Test with single element + var vs = gvar.Vars{gvar.New(42)} + t.AssertEQ(vs.Strings(), []string{"42"}) + t.AssertEQ(vs.Bools(), []bool{true}) + t.AssertEQ(vs.Ints(), []int{42}) + }) +} + func TestVars_Scan(t *testing.T) { gtest.C(t, func(t *gtest.T) { type User struct { diff --git a/database/gdb/gdb.go b/database/gdb/gdb.go index c19ce828dcb..d5925efd2c8 100644 --- a/database/gdb/gdb.go +++ b/database/gdb/gdb.go @@ -181,7 +181,7 @@ type DB interface { // GetArray executes a query and returns the first column of all rows. // It's useful for queries like SELECT id FROM table. - GetArray(ctx context.Context, sql string, args ...any) ([]Value, error) + GetArray(ctx context.Context, sql string, args ...any) (Array, error) // GetCount executes a COUNT query and returns the result as an integer. // It's a convenience method for counting rows. @@ -673,6 +673,9 @@ type ( // Value is the field value type. Value = *gvar.Var + // Array is the field value array type. + Array = gvar.Vars + // Record is the row record of the table. Record map[string]Value diff --git a/database/gdb/gdb_core.go b/database/gdb/gdb_core.go index 7520e42aba8..c335f7f20b0 100644 --- a/database/gdb/gdb_core.go +++ b/database/gdb/gdb_core.go @@ -175,7 +175,7 @@ func (c *Core) GetOne(ctx context.Context, sql string, args ...any) (Record, err // GetArray queries and returns data values as slice from database. // Note that if there are multiple columns in the result, it returns just one column values randomly. -func (c *Core) GetArray(ctx context.Context, sql string, args ...any) ([]Value, error) { +func (c *Core) GetArray(ctx context.Context, sql string, args ...any) (Array, error) { all, err := c.db.DoSelect(ctx, nil, sql, args...) if err != nil { return nil, err diff --git a/database/gdb/gdb_model_select.go b/database/gdb/gdb_model_select.go index 27b18d5e4ec..2e3f7257058 100644 --- a/database/gdb/gdb_model_select.go +++ b/database/gdb/gdb_model_select.go @@ -126,7 +126,7 @@ func (m *Model) One(where ...any) (Record, error) { // 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. -func (m *Model) Array(fieldsAndWhere ...any) ([]Value, error) { +func (m *Model) Array(fieldsAndWhere ...any) (Array, error) { if len(fieldsAndWhere) > 0 { if len(fieldsAndWhere) > 2 { return m.Fields(gconv.String(fieldsAndWhere[0])).Where(fieldsAndWhere[1], fieldsAndWhere[2:]...).Array() diff --git a/database/gdb/gdb_type_result.go b/database/gdb/gdb_type_result.go index d35f7b0d86d..b1c1767aea9 100644 --- a/database/gdb/gdb_type_result.go +++ b/database/gdb/gdb_type_result.go @@ -76,8 +76,8 @@ func (r Result) List() List { // Array retrieves and returns specified column values as slice. // The parameter `field` is optional is the column field is only one. // The default `field` is the first field name of the first item in `Result` if parameter `field` is not given. -func (r Result) Array(field ...string) []Value { - array := make([]Value, len(r)) +func (r Result) Array(field ...string) Array { + array := make(Array, len(r)) if len(r) == 0 { return array } diff --git a/frame/gins/gins_database.go b/frame/gins/gins_database.go index dd04fda10c3..0d420de49c4 100644 --- a/frame/gins/gins_database.go +++ b/frame/gins/gins_database.go @@ -89,7 +89,7 @@ func Database(name ...string) gdb.DB { } } if len(cg) > 0 { - if gdb.GetConfig(group) == nil { + if gcg, _ := gdb.GetConfigGroup(group); gcg == nil { intlog.Printf(ctx, "add configuration for group: %s, %#v", g, cg) if err := gdb.SetConfigGroup(g, cg); err != nil { panic(err) @@ -108,7 +108,7 @@ func Database(name ...string) gdb.DB { cg = append(cg, *node) } if len(cg) > 0 { - if gdb.GetConfig(group) == nil { + if gcg, _ := gdb.GetConfigGroup(group); gcg == nil { intlog.Printf(ctx, "add configuration for group: %s, %#v", gdb.DefaultGroupName, cg) if err := gdb.SetConfigGroup(gdb.DefaultGroupName, cg); err != nil { panic(err)