add more Where*/Min/Max/Avg/Sum/CountColumn/Increment/Decrement/OrderAsc/OrderDesc/OrderRandom functions and associated unit testing cases for package gdb

This commit is contained in:
John Guo
2021-05-02 12:17:06 +08:00
parent d7eb1cca07
commit bd84b97614
9 changed files with 579 additions and 49 deletions

View File

@ -812,13 +812,19 @@ func (c *Core) DoUpdate(link Link, table string, data interface{}, condition str
switch value := v.(type) {
case *Counter:
if value.Value != 0 {
column := c.db.QuoteWord(value.Field)
column := k
if value.Field != "" {
column = c.db.QuoteWord(value.Field)
}
fields = append(fields, fmt.Sprintf("%s=%s+?", column, column))
params = append(params, value.Value)
}
case Counter:
if value.Value != 0 {
column := c.db.QuoteWord(value.Field)
column := k
if value.Field != "" {
column = c.db.QuoteWord(value.Field)
}
fields = append(fields, fmt.Sprintf("%s=%s+?", column, column))
params = append(params, value.Value)
}
@ -829,7 +835,6 @@ func (c *Core) DoUpdate(link Link, table string, data interface{}, condition str
fields = append(fields, c.db.QuoteWord(k)+"=?")
params = append(params, v)
}
}
}
updates = strings.Join(fields, ",")

View File

@ -39,6 +39,7 @@ type Model struct {
data interface{} // Data for operation, which can be type of map/[]map/struct/*struct/string, etc.
batch int // Batch number for batch Insert/Replace/Save operations.
filter bool // Filter data and where key-value pairs according to the fields of the table.
distinct string // Force the query to only return distinct results.
lockInfo string // Lock for update or in shared lock.
cacheEnabled bool // Enable sql result cache feature.
cacheDuration time.Duration // Cache TTL duration.

View File

@ -7,6 +7,7 @@
package gdb
import (
"fmt"
"strings"
)
@ -58,7 +59,125 @@ func (m *Model) WherePri(where interface{}, args ...interface{}) *Model {
return m.Where(newWhere[0], newWhere[1:]...)
}
// WhereBetween builds `xxx BETWEEN x AND y` statement.
func (m *Model) WhereBetween(column string, min, max interface{}) *Model {
return m.Where(fmt.Sprintf(`%s BETWEEN ? AND ?`, m.db.QuoteWord(column)), min, max)
}
// WhereLike builds `xxx LIKE x` statement.
func (m *Model) WhereLike(column string, like interface{}) *Model {
return m.Where(fmt.Sprintf(`%s LIKE ?`, m.db.QuoteWord(column)), like)
}
// WhereIn builds `xxx IN (x)` statement.
func (m *Model) WhereIn(column string, in interface{}) *Model {
return m.Where(fmt.Sprintf(`%s IN (?)`, m.db.QuoteWord(column)), in)
}
// WhereNull builds `xxx IS NULL` statement.
func (m *Model) WhereNull(columns ...string) *Model {
model := m
for _, column := range columns {
model = m.Where(fmt.Sprintf(`%s IS NULL`, m.db.QuoteWord(column)))
}
return model
}
// WhereNotBetween builds `xxx NOT BETWEEN x AND y` statement.
func (m *Model) WhereNotBetween(column string, min, max interface{}) *Model {
return m.Where(fmt.Sprintf(`%s NOT BETWEEN ? AND ?`, m.db.QuoteWord(column)), min, max)
}
// WhereNotLike builds `xxx NOT LIKE x` statement.
func (m *Model) WhereNotLike(column string, like interface{}) *Model {
return m.Where(fmt.Sprintf(`%s NOT LIKE ?`, m.db.QuoteWord(column)), like)
}
// WhereNotIn builds `xxx NOT IN (x)` statement.
func (m *Model) WhereNotIn(column string, in interface{}) *Model {
return m.Where(fmt.Sprintf(`%s NOT IN (?)`, m.db.QuoteWord(column)), in)
}
// WhereNotNull builds `xxx IS NOT NULL` statement.
func (m *Model) WhereNotNull(columns ...string) *Model {
model := m
for _, column := range columns {
model = m.Where(fmt.Sprintf(`%s IS NOT NULL`, m.db.QuoteWord(column)))
}
return model
}
// WhereOr adds "OR" condition to the where statement.
func (m *Model) WhereOr(where interface{}, args ...interface{}) *Model {
model := m.getModel()
if model.whereHolder == nil {
model.whereHolder = make([]*whereHolder, 0)
}
model.whereHolder = append(model.whereHolder, &whereHolder{
operator: whereHolderOr,
where: where,
args: args,
})
return model
}
// WhereOrBetween builds `xxx BETWEEN x AND y` statement in `OR` conditions.
func (m *Model) WhereOrBetween(column string, min, max interface{}) *Model {
return m.WhereOr(fmt.Sprintf(`%s BETWEEN ? AND ?`, m.db.QuoteWord(column)), min, max)
}
// WhereOrLike builds `xxx LIKE x` statement in `OR` conditions.
func (m *Model) WhereOrLike(column string, like interface{}) *Model {
return m.WhereOr(fmt.Sprintf(`%s LIKE ?`, m.db.QuoteWord(column)), like)
}
// WhereOrIn builds `xxx IN (x)` statement in `OR` conditions.
func (m *Model) WhereOrIn(column string, in interface{}) *Model {
return m.WhereOr(fmt.Sprintf(`%s IN (?)`, m.db.QuoteWord(column)), in)
}
// WhereOrNull builds `xxx IS NULL` statement in `OR` conditions.
func (m *Model) WhereOrNull(columns ...string) *Model {
model := m
for _, column := range columns {
model = m.WhereOr(fmt.Sprintf(`%s IS NULL`, m.db.QuoteWord(column)))
}
return model
}
// WhereOrNotBetween builds `xxx NOT BETWEEN x AND y` statement in `OR` conditions.
func (m *Model) WhereOrNotBetween(column string, min, max interface{}) *Model {
return m.WhereOr(fmt.Sprintf(`%s NOT BETWEEN ? AND ?`, m.db.QuoteWord(column)), min, max)
}
// WhereOrNotLike builds `xxx NOT LIKE x` statement in `OR` conditions.
func (m *Model) WhereOrNotLike(column string, like interface{}) *Model {
return m.WhereOr(fmt.Sprintf(`%s NOT LIKE ?`, m.db.QuoteWord(column)), like)
}
// WhereOrNotIn builds `xxx NOT IN (x)` statement.
func (m *Model) WhereOrNotIn(column string, in interface{}) *Model {
return m.WhereOr(fmt.Sprintf(`%s NOT IN (?)`, m.db.QuoteWord(column)), in)
}
// WhereOrNotNull builds `xxx IS NOT NULL` statement in `OR` conditions.
func (m *Model) WhereOrNotNull(columns ...string) *Model {
model := m
for _, column := range columns {
model = m.WhereOr(fmt.Sprintf(`%s IS NOT NULL`, m.db.QuoteWord(column)))
}
return model
}
// Group sets the "GROUP BY" statement for the model.
func (m *Model) Group(groupBy string) *Model {
model := m.getModel()
model.groupBy = m.db.QuoteString(groupBy)
return model
}
// And adds "AND" condition to the where statement.
// Deprecated, use Where instead.
func (m *Model) And(where interface{}, args ...interface{}) *Model {
model := m.getModel()
if model.whereHolder == nil {
@ -73,24 +192,9 @@ func (m *Model) And(where interface{}, args ...interface{}) *Model {
}
// Or adds "OR" condition to the where statement.
// Deprecated, use WhereOr instead.
func (m *Model) Or(where interface{}, args ...interface{}) *Model {
model := m.getModel()
if model.whereHolder == nil {
model.whereHolder = make([]*whereHolder, 0)
}
model.whereHolder = append(model.whereHolder, &whereHolder{
operator: whereHolderOr,
where: where,
args: args,
})
return model
}
// Group sets the "GROUP BY" statement for the model.
func (m *Model) Group(groupBy string) *Model {
model := m.getModel()
model.groupBy = m.db.QuoteString(groupBy)
return model
return m.WhereOr(where, args...)
}
// GroupBy is alias of Model.Group.
@ -102,11 +206,41 @@ func (m *Model) GroupBy(groupBy string) *Model {
// Order sets the "ORDER BY" statement for the model.
func (m *Model) Order(orderBy ...string) *Model {
if len(orderBy) == 0 {
return m
}
model := m.getModel()
model.orderBy = m.db.QuoteString(strings.Join(orderBy, " "))
return model
}
// OrderAsc sets the "ORDER BY xxx ASC" statement for the model.
func (m *Model) OrderAsc(column string) *Model {
if len(column) == 0 {
return m
}
model := m.getModel()
model.orderBy = m.db.QuoteWord(column) + " ASC"
return model
}
// OrderDesc sets the "ORDER BY xxx DESC" statement for the model.
func (m *Model) OrderDesc(column string) *Model {
if len(column) == 0 {
return m
}
model := m.getModel()
model.orderBy = m.db.QuoteWord(column) + " DESC"
return model
}
// OrderRandom sets the "ORDER BY RANDOM()" statement for the model.
func (m *Model) OrderRandom(orderBy ...string) *Model {
model := m.getModel()
model.orderBy = "RAND()"
return model
}
// OrderBy is alias of Model.Order.
// See Model.Order.
// Deprecated, use Order instead.
@ -138,6 +272,13 @@ func (m *Model) Offset(offset int) *Model {
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.

View File

@ -14,17 +14,6 @@ import (
"github.com/gogf/gf/util/gutil"
)
// Filter marks filtering the fields which does not exist in the fields of the operated table.
// Note that this function supports only single table operations.
func (m *Model) Filter() *Model {
if gstr.Contains(m.tables, " ") {
panic("function Filter supports only single table operations")
}
model := m.getModel()
model.filter = true
return model
}
// Fields sets the operation fields of the model, multiple fields joined using char ','.
// The parameter `fieldNamesOrMapStruct` can be type of string/map/*map/struct/*struct.
func (m *Model) Fields(fieldNamesOrMapStruct ...interface{}) *Model {
@ -81,13 +70,25 @@ func (m *Model) FieldsEx(fieldNamesOrMapStruct ...interface{}) *Model {
return m
}
// Filter marks filtering the fields which does not exist in the fields of the operated table.
// Note that this function supports only single table operations.
func (m *Model) Filter() *Model {
if gstr.Contains(m.tables, " ") {
panic("function Filter supports only single table operations")
}
model := m.getModel()
model.filter = true
return model
}
// FieldsStr retrieves and returns all fields from the table, joined with char ','.
// The optional parameter `prefix` specifies the prefix for each field, eg: FieldsStr("u.").
// Deprecated, use GetFieldsStr instead.
// This function name confuses the user that it was a chaining function.
func (m *Model) FieldsStr(prefix ...string) string {
return m.GetFieldsStr(prefix...)
}
// FieldsStr retrieves and returns all fields from the table, joined with char ','.
// GetFieldsStr retrieves and returns all fields from the table, joined with char ','.
// The optional parameter `prefix` specifies the prefix for each field, eg: FieldsStr("u.").
func (m *Model) GetFieldsStr(prefix ...string) string {
prefixStr := ""
@ -116,13 +117,16 @@ func (m *Model) GetFieldsStr(prefix ...string) string {
return newFields
}
// FieldsExStr retrieves and returns fields which are not in parameter `fields` from the table,
// joined with char ','.
// The parameter `fields` specifies the fields that are excluded.
// The optional parameter `prefix` specifies the prefix for each field, eg: FieldsExStr("id", "u.").
// Deprecated, use GetFieldsExStr instead.
// This function name confuses the user that it was a chaining function.
func (m *Model) FieldsExStr(fields string, prefix ...string) string {
return m.GetFieldsExStr(fields, prefix...)
}
// FieldsExStr retrieves and returns fields which are not in parameter `fields` from the table,
// GetFieldsExStr retrieves and returns fields which are not in parameter `fields` from the table,
// joined with char ','.
// The parameter `fields` specifies the fields that are excluded.
// The optional parameter `prefix` specifies the prefix for each field, eg: FieldsExStr("id", "u.").

View File

@ -109,6 +109,18 @@ func (m *Model) Insert(data ...interface{}) (result sql.Result, err error) {
return m.doInsertWithOption(insertOptionDefault)
}
// InsertAndGetId performs action Insert and returns the last insert id that automatically generated.
func (m *Model) InsertAndGetId(data ...interface{}) (lastInsertId int64, err error) {
if len(data) > 0 {
return m.Data(data...).InsertAndGetId()
}
result, err := m.doInsertWithOption(insertOptionDefault)
if err != nil {
return 0, err
}
return result.LastInsertId()
}
// InsertIgnore does "INSERT IGNORE INTO ..." statement for the model.
// The optional parameter `data` is the same as the parameter of Model.Data function,
// see Model.Data.

View File

@ -19,7 +19,7 @@ import (
// Select is alias of Model.All.
// See Model.All.
// Deprecated.
// Deprecated, use All instead.
func (m *Model) Select(where ...interface{}) (Result, error) {
return m.All(where...)
}
@ -50,7 +50,8 @@ func (m *Model) doGetAll(limit1 bool, where ...interface{}) (Result, error) {
// DISTINCT t.user_id uid
return m.doGetAllBySql(
fmt.Sprintf(
"SELECT %s FROM %s%s",
"SELECT %s%s FROM %s%s",
m.distinct,
m.getFieldsFiltered(),
m.tables,
conditionWhere+conditionExtra,
@ -182,7 +183,7 @@ func (m *Model) Value(fieldsAndWhere ...interface{}) (Value, error) {
}
// Array queries and returns data values as slice from database.
// Note that if there're multiple columns in the result, it returns just one column values randomly.
// Note that if there are multiple columns in the result, it returns just one column values randomly.
//
// If the optional parameter `fieldsAndWhere` is given, the fieldsAndWhere[0] is the selected fields
// and fieldsAndWhere[1:] is treated as where condition fields.
@ -334,7 +335,7 @@ func (m *Model) Count(where ...interface{}) (int, error) {
if m.fields != "" && m.fields != "*" {
// DO NOT quote the m.fields here, in case of fields like:
// DISTINCT t.user_id uid
countFields = fmt.Sprintf(`COUNT(%s)`, m.fields)
countFields = fmt.Sprintf(`COUNT(%s%s)`, m.distinct, m.fields)
}
conditionWhere, conditionExtra, conditionArgs := m.formatCondition(false, true)
s := fmt.Sprintf("SELECT %s FROM %s%s", countFields, m.tables, conditionWhere+conditionExtra)
@ -353,6 +354,62 @@ func (m *Model) Count(where ...interface{}) (int, error) {
return 0, nil
}
// CountColumn does "SELECT COUNT(x) FROM ..." statement for the model.
func (m *Model) CountColumn(column string) (int, error) {
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
}
value, err := m.Fields(fmt.Sprintf(`MIN(%s)`, m.db.QuoteWord(column))).Value()
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
}
value, err := m.Fields(fmt.Sprintf(`MAX(%s)`, m.db.QuoteWord(column))).Value()
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
}
value, err := m.Fields(fmt.Sprintf(`AVG(%s)`, m.db.QuoteWord(column))).Value()
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
}
value, err := m.Fields(fmt.Sprintf(`SUM(%s)`, m.db.QuoteWord(column))).Value()
if err != nil {
return 0, err
}
return value.Float64(), err
}
// FindOne retrieves and returns a single Record by Model.WherePri and Model.One.
// Also see Model.WherePri and Model.One.
func (m *Model) FindOne(where ...interface{}) (Record, error) {

View File

@ -89,3 +89,19 @@ func (m *Model) Update(dataAndWhere ...interface{}) (result sql.Result, err erro
m.mergeArguments(conditionArgs)...,
)
}
// Increment increments a column's value by a given amount.
func (m *Model) Increment(column string, amount float64) (sql.Result, error) {
return m.getModel().Data(column, &Counter{
Field: column,
Value: amount,
}).Update()
}
// Decrement decrements a column's value by a given amount.
func (m *Model) Decrement(column string, amount float64) (sql.Result, error) {
return m.getModel().Data(column, &Counter{
Field: column,
Value: -amount,
}).Update()
}

View File

@ -18,16 +18,6 @@ import (
"time"
)
// getModel creates and returns a cloned model of current model if `safe` is true, or else it returns
// the current model.
func (m *Model) getModel() *Model {
if !m.safe {
return m
} else {
return m.Clone()
}
}
// TableFields retrieves and returns the fields information of specified table of current
// schema.
//
@ -47,6 +37,16 @@ func (m *Model) TableFields(table string, schema ...string) (fields map[string]*
return m.db.TableFields(link, table, schema...)
}
// getModel creates and returns a cloned model of current model if `safe` is true, or else it returns
// the current model.
func (m *Model) getModel() *Model {
if !m.safe {
return m
} else {
return m.Clone()
}
}
// mappingAndFilterToTableFields mappings and changes given field name to really table field name.
// Eg:
// ID -> id

View File

@ -2778,6 +2778,11 @@ func Test_Model_Distinct(t *testing.T) {
t.AssertNil(err)
t.Assert(len(all), 2)
})
gtest.C(t, func(t *gtest.T) {
count, err := db.Model(table).Where("id > 1").Distinct().Count()
t.AssertNil(err)
t.Assert(count, 9)
})
}
func Test_Model_Min_Max(t *testing.T) {
@ -3321,3 +3326,292 @@ func Test_Model_Fields_AutoFilterInJoinStatement(t *testing.T) {
t.Assert(one["number"].String(), "n")
})
}
func Test_Model_WhereIn(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereIn("id", g.Slice{1, 2, 3, 4}).WhereIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), 2)
t.Assert(result[0]["id"], 3)
t.Assert(result[1]["id"], 4)
})
}
func Test_Model_WhereNotIn(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereNotIn("id", g.Slice{1, 2, 3, 4}).WhereNotIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), 5)
t.Assert(result[0]["id"], 6)
t.Assert(result[1]["id"], 7)
})
}
func Test_Model_WhereOrIn(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereOrIn("id", g.Slice{1, 2, 3, 4}).WhereOrIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), 5)
t.Assert(result[0]["id"], 1)
t.Assert(result[4]["id"], 5)
})
}
func Test_Model_WhereOrNotIn(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereOrNotIn("id", g.Slice{1, 2, 3, 4}).WhereOrNotIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), 8)
t.Assert(result[0]["id"], 1)
t.Assert(result[4]["id"], 7)
})
}
func Test_Model_WhereBetween(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereBetween("id", 1, 4).WhereBetween("id", 3, 5).OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), 2)
t.Assert(result[0]["id"], 3)
t.Assert(result[1]["id"], 4)
})
}
func Test_Model_WhereNotBetween(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereNotBetween("id", 2, 8).WhereNotBetween("id", 3, 100).OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), 1)
t.Assert(result[0]["id"], 1)
})
}
func Test_Model_WhereOrBetween(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereOrBetween("id", 1, 4).WhereOrBetween("id", 3, 5).OrderDesc("id").All()
t.AssertNil(err)
t.Assert(len(result), 5)
t.Assert(result[0]["id"], 5)
t.Assert(result[4]["id"], 1)
})
}
func Test_Model_WhereOrNotBetween(t *testing.T) {
table := createInitTable()
defer dropTable(table)
//db.SetDebug(true)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereOrNotBetween("id", 1, 4).WhereOrNotBetween("id", 3, 5).OrderDesc("id").All()
t.AssertNil(err)
t.Assert(len(result), 8)
t.Assert(result[0]["id"], 10)
t.Assert(result[4]["id"], 6)
})
}
func Test_Model_WhereLike(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereLike("nickname", "name%").OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), TableSize)
t.Assert(result[0]["id"], 1)
t.Assert(result[TableSize-1]["id"], TableSize)
})
}
func Test_Model_WhereNotLike(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereNotLike("nickname", "name%").OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), 0)
})
}
func Test_Model_WhereOrLike(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereOrLike("nickname", "namexxx%").WhereOrLike("nickname", "name%").OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), TableSize)
t.Assert(result[0]["id"], 1)
t.Assert(result[TableSize-1]["id"], TableSize)
})
}
func Test_Model_WhereOrNotLike(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereOrNotLike("nickname", "namexxx%").WhereOrNotLike("nickname", "name%").OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), TableSize)
t.Assert(result[0]["id"], 1)
t.Assert(result[TableSize-1]["id"], TableSize)
})
}
func Test_Model_WhereNull(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereNull("nickname").WhereNull("passport").OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), 0)
})
}
func Test_Model_WhereNotNull(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereNotNull("nickname").WhereNotNull("passport").OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), TableSize)
t.Assert(result[0]["id"], 1)
t.Assert(result[TableSize-1]["id"], TableSize)
})
}
func Test_Model_WhereOrNull(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereOrNull("nickname").WhereOrNull("passport").OrderAsc("id").OrderRandom().All()
t.AssertNil(err)
t.Assert(len(result), 0)
})
}
func Test_Model_WhereOrNotNull(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereOrNotNull("nickname").WhereOrNotNull("passport").OrderAsc("id").All()
t.AssertNil(err)
t.Assert(len(result), TableSize)
t.Assert(result[0]["id"], 1)
t.Assert(result[TableSize-1]["id"], TableSize)
})
}
func Test_Model_Min_Max_Avg_Sum(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).Min("id")
t.AssertNil(err)
t.Assert(result, 1)
})
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).Max("id")
t.AssertNil(err)
t.Assert(result, TableSize)
})
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).Avg("id")
t.AssertNil(err)
t.Assert(result, 5.5)
})
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).Sum("id")
t.AssertNil(err)
t.Assert(result, 55)
})
}
func Test_Model_CountColumn(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).CountColumn("id")
t.AssertNil(err)
t.Assert(result, TableSize)
})
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).WhereIn("id", g.Slice{1, 2, 3}).CountColumn("id")
t.AssertNil(err)
t.Assert(result, 3)
})
}
func Test_Model_InsertAndGetId(t *testing.T) {
table := createTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
id, err := db.Model(table).Data(g.Map{
"id": 1,
"passport": "user_1",
"password": "pass_1",
"nickname": "name_1",
}).InsertAndGetId()
t.AssertNil(err)
t.Assert(id, 1)
})
gtest.C(t, func(t *gtest.T) {
id, err := db.Model(table).Data(g.Map{
"passport": "user_2",
"password": "pass_2",
"nickname": "name_2",
}).InsertAndGetId()
t.AssertNil(err)
t.Assert(id, 2)
})
}
func Test_Model_Increment_Decrement(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).Where("id", 1).Increment("id", 100)
t.AssertNil(err)
rows, _ := result.RowsAffected()
t.Assert(rows, 1)
})
gtest.C(t, func(t *gtest.T) {
result, err := db.Model(table).Where("id", 101).Decrement("id", 10)
t.AssertNil(err)
rows, _ := result.RowsAffected()
t.Assert(rows, 1)
})
gtest.C(t, func(t *gtest.T) {
count, err := db.Model(table).Where("id", 91).Count()
t.AssertNil(err)
t.Assert(count, 1)
})
}