mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
improve gdb/ghttp/gins; fix issue in gstr
This commit is contained in:
@ -21,65 +21,53 @@ var (
|
||||
Table = "gf_article"
|
||||
// Model is the model object of gf_article.
|
||||
Model = &arModel{g.DB("default").Table(Table).Safe()}
|
||||
// Primary is the primary key name of table gf_article.
|
||||
Primary = gdb.GetPrimaryKey(new(Entity))
|
||||
)
|
||||
|
||||
// FindOne retrieves and returns a single Entity by a primary key or where conditions by
|
||||
// Model.Where. The optional parameter <where> is like follows:
|
||||
// 123, []int{1, 2, 3}, "john", []string{"john", "smith"}
|
||||
// g.Map{"id": g.Slice{1,2,3}}, g.Map{"id": 1, "name": "john"}, etc.
|
||||
//
|
||||
// Note that it differs with Mode.One is that any single where condition parameter will
|
||||
// be treated as the value of the primary key in FindOne, but a string condition in
|
||||
// Model.One. That is, if primary key is "id" and given <where> parameter as "123", the
|
||||
// FindOne function treats it as "id=123", but Model.One treats it as "123", just a string.
|
||||
// FindOne is a convenience method for Model.FindOne.
|
||||
// See Model.FindOne.
|
||||
func FindOne(where ...interface{}) (*Entity, error) {
|
||||
return Model.One(gdb.GetPrimaryKeyCondition(Primary, where...)...)
|
||||
return Model.FindOne(where...)
|
||||
}
|
||||
|
||||
// FindAll retrieves and returns multiple Entity by a primary key or where conditions by
|
||||
// Model.Where. Also see FindOne.
|
||||
// FindAll is a convenience method for Model.FindAll.
|
||||
// See Model.FindAll.
|
||||
func FindAll(where ...interface{}) ([]*Entity, error) {
|
||||
return Model.All(gdb.GetPrimaryKeyCondition(Primary, where...)...)
|
||||
return Model.FindAll(where...)
|
||||
}
|
||||
|
||||
// FindValue retrieves and returns single field value by a primary key or where conditions by
|
||||
// Model.Where. Also see FindOne.
|
||||
// FindValue is a convenience method for Model.FindValue.
|
||||
// See Model.FindValue.
|
||||
func FindValue(fieldsAndWhere ...interface{}) (gdb.Value, error) {
|
||||
if len(fieldsAndWhere) == 2 {
|
||||
return Model.Value(append(fieldsAndWhere[0:1], gdb.GetPrimaryKeyCondition(Primary, fieldsAndWhere[1:]...)...)...)
|
||||
}
|
||||
return Model.Value(fieldsAndWhere...)
|
||||
return Model.FindValue(fieldsAndWhere...)
|
||||
}
|
||||
|
||||
// FindCount retrieves and returns the record number by a primary key or where conditions by
|
||||
// Model.Where. Also see FindOne.
|
||||
// FindCount is a convenience method for Model.FindCount.
|
||||
// See Model.FindCount.
|
||||
func FindCount(where ...interface{}) (int, error) {
|
||||
return Model.Count(gdb.GetPrimaryKeyCondition(Primary, where...)...)
|
||||
return Model.FindCount(where...)
|
||||
}
|
||||
|
||||
// Insert is alias of Model.Insert.
|
||||
// Insert is a convenience method for Model.Insert.
|
||||
func Insert(data ...interface{}) (result sql.Result, err error) {
|
||||
return Model.Insert(data...)
|
||||
}
|
||||
|
||||
// Replace is alias of Model.Replace.
|
||||
// Replace is a convenience method for Model.Replace.
|
||||
func Replace(data ...interface{}) (result sql.Result, err error) {
|
||||
return Model.Replace(data...)
|
||||
}
|
||||
|
||||
// Save is alias of Model.Save.
|
||||
// Save is a convenience method for Model.Save.
|
||||
func Save(data ...interface{}) (result sql.Result, err error) {
|
||||
return Model.Save(data...)
|
||||
}
|
||||
|
||||
// Update is alias of Model.Update.
|
||||
// Update is a convenience method for Model.Update.
|
||||
func Update(dataAndWhere ...interface{}) (result sql.Result, err error) {
|
||||
return Model.Update(dataAndWhere...)
|
||||
}
|
||||
|
||||
// Delete is alias of Model.Delete.
|
||||
// Delete is a convenience method for Model.Delete.
|
||||
func Delete(where ...interface{}) (result sql.Result, err error) {
|
||||
return Model.Delete(where...)
|
||||
}
|
||||
@ -166,14 +154,14 @@ func (m *arModel) Or(where interface{}, args ...interface{}) *arModel {
|
||||
return &arModel{m.M.Or(where, args...)}
|
||||
}
|
||||
|
||||
// GroupBy sets the "GROUP BY" statement for the model.
|
||||
func (m *arModel) GroupBy(groupBy string) *arModel {
|
||||
return &arModel{m.M.GroupBy(groupBy)}
|
||||
// Group sets the "GROUP BY" statement for the model.
|
||||
func (m *arModel) Group(groupBy string) *arModel {
|
||||
return &arModel{m.M.Group(groupBy)}
|
||||
}
|
||||
|
||||
// OrderBy sets the "ORDER BY" statement for the model.
|
||||
func (m *arModel) OrderBy(orderBy string) *arModel {
|
||||
return &arModel{m.M.OrderBy(orderBy)}
|
||||
// Order sets the "ORDER BY" statement for the model.
|
||||
func (m *arModel) Order(orderBy string) *arModel {
|
||||
return &arModel{m.M.Order(orderBy)}
|
||||
}
|
||||
|
||||
// Limit sets the "LIMIT" statement for the model.
|
||||
@ -190,11 +178,11 @@ func (m *arModel) Offset(offset int) *arModel {
|
||||
return &arModel{m.M.Offset(offset)}
|
||||
}
|
||||
|
||||
// ForPage sets the paging number for the 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 start from 0 for "LIMIT" statement.
|
||||
func (m *arModel) ForPage(page, limit int) *arModel {
|
||||
return &arModel{m.M.ForPage(page, limit)}
|
||||
func (m *arModel) Page(page, limit int) *arModel {
|
||||
return &arModel{m.M.Page(page, limit)}
|
||||
}
|
||||
|
||||
// Batch sets the batch operation number for the model.
|
||||
@ -321,6 +309,46 @@ func (m *arModel) Value(fieldsAndWhere ...interface{}) (gdb.Value, error) {
|
||||
return m.M.Value(fieldsAndWhere...)
|
||||
}
|
||||
|
||||
// FindOne retrieves and returns a single Record by Model.WherePri and Model.One.
|
||||
// Also see Model.WherePri and Model.One.
|
||||
func (m *arModel) FindOne(where ...interface{}) (*Entity, error) {
|
||||
one, err := m.M.FindOne(where...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var entity *Entity
|
||||
if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
|
||||
return nil, err
|
||||
}
|
||||
return entity, nil
|
||||
}
|
||||
|
||||
// FindAll retrieves and returns Result by by Model.WherePri and Model.All.
|
||||
// Also see Model.WherePri and Model.All.
|
||||
func (m *arModel) FindAll(where ...interface{}) ([]*Entity, error) {
|
||||
all, err := m.M.FindAll(where...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var entities []*Entity
|
||||
if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
|
||||
return nil, err
|
||||
}
|
||||
return entities, nil
|
||||
}
|
||||
|
||||
// FindValue retrieves and returns single field value by Model.WherePri and Model.Value.
|
||||
// Also see Model.WherePri and Model.Value.
|
||||
func (m *arModel) FindValue(fieldsAndWhere ...interface{}) (gdb.Value, error) {
|
||||
return m.M.FindValue(fieldsAndWhere...)
|
||||
}
|
||||
|
||||
// FindCount retrieves and returns the record number by Model.WherePri and Model.Count.
|
||||
// Also see Model.WherePri and Model.Count.
|
||||
func (m *arModel) FindCount(where ...interface{}) (int, error) {
|
||||
return m.M.FindCount(where...)
|
||||
}
|
||||
|
||||
// Chunk iterates the table with given size and callback function.
|
||||
func (m *arModel) Chunk(limit int, callback func(entities []*Entity, err error) bool) {
|
||||
m.M.Chunk(limit, func(result gdb.Result, err error) bool {
|
||||
|
||||
@ -1,48 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/container/garray"
|
||||
"github.com/gogf/gf/container/glist"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// concurrent-safe list.
|
||||
l := glist.NewFrom(garray.NewArrayRange(1, 10, 1).Slice(), true)
|
||||
// iterate reading from head.
|
||||
l.RLockFunc(func(list *list.List) {
|
||||
length := list.Len()
|
||||
if length > 0 {
|
||||
for i, e := 0, list.Front(); i < length; i, e = i+1, e.Next() {
|
||||
fmt.Print(e.Value)
|
||||
}
|
||||
}
|
||||
})
|
||||
fmt.Println()
|
||||
// iterate reading from tail.
|
||||
l.RLockFunc(func(list *list.List) {
|
||||
length := list.Len()
|
||||
if length > 0 {
|
||||
for i, e := 0, list.Back(); i < length; i, e = i+1, e.Prev() {
|
||||
fmt.Print(e.Value)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
fmt.Println()
|
||||
|
||||
// iterate writing from head.
|
||||
l.LockFunc(func(list *list.List) {
|
||||
length := list.Len()
|
||||
if length > 0 {
|
||||
for i, e := 0, list.Front(); i < length; i, e = i+1, e.Next() {
|
||||
if e.Value == 6 {
|
||||
e.Value = "M"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
fmt.Println(l)
|
||||
a := "aaaaa_post"
|
||||
b := "aaaaa_"
|
||||
c := gstr.TrimLeftStr(a, b)
|
||||
fmt.Println(c)
|
||||
}
|
||||
|
||||
@ -222,7 +222,7 @@ func New(name ...string) (db DB, err error) {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, errors.New(fmt.Sprintf("empty database configuration for item name '%s'", group))
|
||||
return nil, errors.New(fmt.Sprintf(`database configuration node "%s" is not found`, group))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -156,7 +156,6 @@ func GetPrimaryKeyCondition(primary string, where ...interface{}) (newWhereCondi
|
||||
}
|
||||
}
|
||||
return where
|
||||
|
||||
}
|
||||
|
||||
// 获得orm标签与属性的映射关系
|
||||
|
||||
@ -10,14 +10,13 @@ import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/container/gmap"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/container/gset"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
|
||||
"github.com/gogf/gf/container/gmap"
|
||||
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
)
|
||||
|
||||
@ -289,6 +288,18 @@ func (m *Model) Where(where interface{}, args ...interface{}) *Model {
|
||||
return model
|
||||
}
|
||||
|
||||
// WherePri does the same logic as Model.Where except that if the parameter <where>
|
||||
// is a single condition like int/string/float/slice, it treats the condition as the primary
|
||||
// key value. That is, if primary key is "id" and given <where> parameter as "123", the
|
||||
// WherePri function treats it as "id=123", but Model.Where treats it as string "123".
|
||||
func (m *Model) WherePri(where interface{}, args ...interface{}) *Model {
|
||||
if len(args) > 0 {
|
||||
return m.Where(where, args...)
|
||||
}
|
||||
newWhere := GetPrimaryKeyCondition(m.getPrimaryKey(), where)
|
||||
return m.Where(newWhere[0], newWhere[1:]...)
|
||||
}
|
||||
|
||||
// And adds "AND" condition to the where statement.
|
||||
func (m *Model) And(where interface{}, args ...interface{}) *Model {
|
||||
model := m.getModel()
|
||||
@ -317,20 +328,34 @@ func (m *Model) Or(where interface{}, args ...interface{}) *Model {
|
||||
return model
|
||||
}
|
||||
|
||||
// GroupBy sets the "GROUP BY" statement for the model.
|
||||
func (m *Model) GroupBy(groupBy string) *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
|
||||
}
|
||||
|
||||
// OrderBy sets the "ORDER BY" statement for the model.
|
||||
func (m *Model) OrderBy(orderBy string) *Model {
|
||||
// GroupBy is alias of Model.Group.
|
||||
// See Model.Group.
|
||||
// Deprecated.
|
||||
func (m *Model) GroupBy(groupBy string) *Model {
|
||||
return m.Group(groupBy)
|
||||
}
|
||||
|
||||
// Order sets the "ORDER BY" statement for the model.
|
||||
func (m *Model) Order(orderBy string) *Model {
|
||||
model := m.getModel()
|
||||
model.orderBy = m.db.quoteString(orderBy)
|
||||
return model
|
||||
}
|
||||
|
||||
// OrderBy is alias of Model.Order.
|
||||
// See Model.Order.
|
||||
// Deprecated.
|
||||
func (m *Model) OrderBy(orderBy string) *Model {
|
||||
return m.Order(orderBy)
|
||||
}
|
||||
|
||||
// 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]"
|
||||
@ -355,16 +380,23 @@ func (m *Model) Offset(offset int) *Model {
|
||||
return model
|
||||
}
|
||||
|
||||
// ForPage sets the paging number for the 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 start from 0 for "LIMIT" statement.
|
||||
func (m *Model) ForPage(page, limit int) *Model {
|
||||
func (m *Model) Page(page, limit int) *Model {
|
||||
model := m.getModel()
|
||||
model.start = (page - 1) * limit
|
||||
model.limit = limit
|
||||
return model
|
||||
}
|
||||
|
||||
// ForPage is alias of Model.Page.
|
||||
// See Model.Page.
|
||||
// Deprecated.
|
||||
func (m *Model) ForPage(page, limit int) *Model {
|
||||
return m.Page(page, limit)
|
||||
}
|
||||
|
||||
// Batch sets the batch operation number for the model.
|
||||
func (m *Model) Batch(batch int) *Model {
|
||||
model := m.getModel()
|
||||
@ -446,50 +478,6 @@ func (m *Model) Data(data ...interface{}) *Model {
|
||||
return model
|
||||
}
|
||||
|
||||
// filterDataForInsertOrUpdate does filter feature with data for inserting/updating operations.
|
||||
// Note that, it does not filter list item, which is also type of map, for "omit empty" feature.
|
||||
func (m *Model) filterDataForInsertOrUpdate(data interface{}) interface{} {
|
||||
if list, ok := m.data.(List); ok {
|
||||
for k, item := range list {
|
||||
list[k] = m.doFilterDataMapForInsertOrUpdate(item, false)
|
||||
}
|
||||
return list
|
||||
} else if item, ok := m.data.(Map); ok {
|
||||
return m.doFilterDataMapForInsertOrUpdate(item, true)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// doFilterDataMapForInsertOrUpdate does the filter features for map.
|
||||
// Note that, it does not filter list item, which is also type of map, for "omit empty" feature.
|
||||
func (m *Model) doFilterDataMapForInsertOrUpdate(data Map, allowOmitEmpty bool) Map {
|
||||
if m.filter {
|
||||
data = m.db.filterFields(m.tables, data)
|
||||
}
|
||||
// Remove key-value pairs of which the value is empty.
|
||||
if allowOmitEmpty && m.option&OPTION_OMITEMPTY > 0 {
|
||||
m := gmap.NewStrAnyMapFrom(data)
|
||||
m.FilterEmpty()
|
||||
data = m.Map()
|
||||
}
|
||||
|
||||
if len(m.fields) > 0 && m.fields != "*" {
|
||||
// Keep specified fields.
|
||||
set := gset.NewStrSetFrom(gstr.SplitAndTrim(m.fields, ","))
|
||||
for k := range data {
|
||||
if !set.Contains(k) {
|
||||
delete(data, k)
|
||||
}
|
||||
}
|
||||
} else if len(m.fieldsEx) > 0 {
|
||||
// Filter specified fields.
|
||||
for _, v := range gstr.SplitAndTrim(m.fieldsEx, ",") {
|
||||
delete(data, v)
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// Insert does "INSERT INTO ..." statement for the model.
|
||||
// The optional parameter <data> is the same as the parameter of Model.Data function,
|
||||
// see Model.Data.
|
||||
@ -637,7 +625,7 @@ func (m *Model) Update(dataAndWhere ...interface{}) (result sql.Result, err erro
|
||||
if m.data == nil {
|
||||
return nil, errors.New("updating table with empty data")
|
||||
}
|
||||
condition, conditionArgs := m.formatCondition()
|
||||
condition, conditionArgs := m.formatCondition(false)
|
||||
return m.db.doUpdate(
|
||||
m.getLink(),
|
||||
m.tables,
|
||||
@ -659,7 +647,7 @@ func (m *Model) Delete(where ...interface{}) (result sql.Result, err error) {
|
||||
m.checkAndRemoveCache()
|
||||
}
|
||||
}()
|
||||
condition, conditionArgs := m.formatCondition()
|
||||
condition, conditionArgs := m.formatCondition(false)
|
||||
return m.db.doDelete(m.getLink(), m.tables, condition, conditionArgs...)
|
||||
}
|
||||
|
||||
@ -680,7 +668,7 @@ func (m *Model) All(where ...interface{}) (Result, error) {
|
||||
if len(where) > 0 {
|
||||
return m.Where(where[0], where[1:]...).All()
|
||||
}
|
||||
condition, conditionArgs := m.formatCondition()
|
||||
condition, conditionArgs := m.formatCondition(false)
|
||||
return m.getAll(fmt.Sprintf("SELECT %s FROM %s%s", m.fields, m.tables, condition), conditionArgs...)
|
||||
}
|
||||
|
||||
@ -690,12 +678,16 @@ func (m *Model) All(where ...interface{}) (Result, error) {
|
||||
// The optional parameter <where> is the same as the parameter of Model.Where function,
|
||||
// see Model.Where.
|
||||
func (m *Model) One(where ...interface{}) (Record, error) {
|
||||
list, err := m.All(where...)
|
||||
if len(where) > 0 {
|
||||
return m.Where(where[0], where[1:]...).One()
|
||||
}
|
||||
condition, conditionArgs := m.formatCondition(true)
|
||||
all, err := m.getAll(fmt.Sprintf("SELECT %s FROM %s%s", m.fields, m.tables, condition), conditionArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(list) > 0 {
|
||||
return list[0], nil
|
||||
if len(all) > 0 {
|
||||
return all[0], nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
@ -833,7 +825,7 @@ func (m *Model) Count(where ...interface{}) (int, error) {
|
||||
} else {
|
||||
m.fields = fmt.Sprintf(`COUNT(%s)`, m.fields)
|
||||
}
|
||||
condition, conditionArgs := m.formatCondition()
|
||||
condition, conditionArgs := m.formatCondition(false)
|
||||
s := fmt.Sprintf("SELECT %s FROM %s %s", m.fields, m.tables, condition)
|
||||
if len(m.groupBy) > 0 {
|
||||
s = fmt.Sprintf("SELECT COUNT(1) FROM (%s) count_alias", s)
|
||||
@ -850,6 +842,116 @@ func (m *Model) Count(where ...interface{}) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if len(where) > 0 {
|
||||
return m.WherePri(where[0], where[1:]...).One()
|
||||
}
|
||||
return m.One()
|
||||
}
|
||||
|
||||
// FindAll retrieves and returns Result by by Model.WherePri and Model.All.
|
||||
// Also see Model.WherePri and Model.All.
|
||||
func (m *Model) FindAll(where ...interface{}) (Result, error) {
|
||||
if len(where) > 0 {
|
||||
return m.WherePri(where[0], where[1:]...).All()
|
||||
}
|
||||
return m.All()
|
||||
}
|
||||
|
||||
// FindValue retrieves and returns single field value by Model.WherePri and Model.Value.
|
||||
// Also see Model.WherePri and Model.Value.
|
||||
func (m *Model) FindValue(fieldsAndWhere ...interface{}) (Value, error) {
|
||||
if len(fieldsAndWhere) >= 2 {
|
||||
return m.WherePri(fieldsAndWhere[1], fieldsAndWhere[2:]...).Fields(gconv.String(fieldsAndWhere[0])).Value()
|
||||
}
|
||||
if len(fieldsAndWhere) == 1 {
|
||||
return m.Fields(gconv.String(fieldsAndWhere[0])).Value()
|
||||
}
|
||||
return m.Value()
|
||||
}
|
||||
|
||||
// FindCount retrieves and returns the record number by Model.WherePri and Model.Count.
|
||||
// Also see Model.WherePri and Model.Count.
|
||||
func (m *Model) FindCount(where ...interface{}) (int, error) {
|
||||
if len(where) > 0 {
|
||||
return m.WherePri(where[0], where[1:]...).Count()
|
||||
}
|
||||
return m.Count()
|
||||
}
|
||||
|
||||
// Chunk iterates the table with given size and callback function.
|
||||
func (m *Model) Chunk(limit int, callback func(result Result, err error) bool) {
|
||||
page := m.start
|
||||
if page == 0 {
|
||||
page = 1
|
||||
}
|
||||
model := m
|
||||
for {
|
||||
model = model.Page(page, limit)
|
||||
data, err := model.All()
|
||||
if err != nil {
|
||||
callback(nil, err)
|
||||
break
|
||||
}
|
||||
if len(data) == 0 {
|
||||
break
|
||||
}
|
||||
if callback(data, err) == false {
|
||||
break
|
||||
}
|
||||
if len(data) < limit {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
}
|
||||
|
||||
// filterDataForInsertOrUpdate does filter feature with data for inserting/updating operations.
|
||||
// Note that, it does not filter list item, which is also type of map, for "omit empty" feature.
|
||||
func (m *Model) filterDataForInsertOrUpdate(data interface{}) interface{} {
|
||||
if list, ok := m.data.(List); ok {
|
||||
for k, item := range list {
|
||||
list[k] = m.doFilterDataMapForInsertOrUpdate(item, false)
|
||||
}
|
||||
return list
|
||||
} else if item, ok := m.data.(Map); ok {
|
||||
return m.doFilterDataMapForInsertOrUpdate(item, true)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// doFilterDataMapForInsertOrUpdate does the filter features for map.
|
||||
// Note that, it does not filter list item, which is also type of map, for "omit empty" feature.
|
||||
func (m *Model) doFilterDataMapForInsertOrUpdate(data Map, allowOmitEmpty bool) Map {
|
||||
if m.filter {
|
||||
data = m.db.filterFields(m.tables, data)
|
||||
}
|
||||
// Remove key-value pairs of which the value is empty.
|
||||
if allowOmitEmpty && m.option&OPTION_OMITEMPTY > 0 {
|
||||
m := gmap.NewStrAnyMapFrom(data)
|
||||
m.FilterEmpty()
|
||||
data = m.Map()
|
||||
}
|
||||
|
||||
if len(m.fields) > 0 && m.fields != "*" {
|
||||
// Keep specified fields.
|
||||
set := gset.NewStrSetFrom(gstr.SplitAndTrim(m.fields, ","))
|
||||
for k := range data {
|
||||
if !set.Contains(k) {
|
||||
delete(data, k)
|
||||
}
|
||||
}
|
||||
} else if len(m.fieldsEx) > 0 {
|
||||
// Filter specified fields.
|
||||
for _, v := range gstr.SplitAndTrim(m.fieldsEx, ",") {
|
||||
delete(data, v)
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// getLink returns the underlying database link object with configured <linkType> attribute.
|
||||
func (m *Model) getLink() dbLink {
|
||||
if m.tx != nil {
|
||||
@ -891,6 +993,23 @@ func (m *Model) getAll(query string, args ...interface{}) (result Result, err er
|
||||
return result, err
|
||||
}
|
||||
|
||||
// getPrimaryKey retrieves and returns the primary key name of the model table.
|
||||
// It parses m.tables to retrieve the primary table name, supporting m.tables like:
|
||||
// "user", "user u", "user as u, user_detail as ud".
|
||||
func (m *Model) getPrimaryKey() string {
|
||||
table := gstr.SplitAndTrim(m.tables, " ")[0]
|
||||
tableFields, err := m.db.TableFields(table)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
for name, field := range tableFields {
|
||||
if gstr.ContainsI(field.Key, "pri") {
|
||||
return name
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// checkAndRemoveCache checks and remove the cache if necessary.
|
||||
func (m *Model) checkAndRemoveCache() {
|
||||
if m.cacheEnabled && m.cacheDuration < 0 && len(m.cacheName) > 0 {
|
||||
@ -900,7 +1019,9 @@ func (m *Model) checkAndRemoveCache() {
|
||||
|
||||
// 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>.
|
||||
func (m *Model) formatCondition() (condition string, conditionArgs []interface{}) {
|
||||
//
|
||||
// The parameter <limit> specifies whether limits querying only one record if m.limit is not set.
|
||||
func (m *Model) formatCondition(limit bool) (condition string, conditionArgs []interface{}) {
|
||||
var where string
|
||||
if len(m.whereHolder) > 0 {
|
||||
for _, v := range m.whereHolder {
|
||||
@ -955,36 +1076,11 @@ func (m *Model) formatCondition() (condition string, conditionArgs []interface{}
|
||||
} else {
|
||||
condition += fmt.Sprintf(" LIMIT %d", m.limit)
|
||||
}
|
||||
} else if limit {
|
||||
condition += " LIMIT 1"
|
||||
}
|
||||
if m.offset >= 0 {
|
||||
condition += fmt.Sprintf(" OFFSET %d", m.offset)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Chunk iterates the table with given size and callback function.
|
||||
func (m *Model) Chunk(limit int, callback func(result Result, err error) bool) {
|
||||
page := m.start
|
||||
if page == 0 {
|
||||
page = 1
|
||||
}
|
||||
model := m
|
||||
for {
|
||||
model = model.ForPage(page, limit)
|
||||
data, err := model.All()
|
||||
if err != nil {
|
||||
callback(nil, err)
|
||||
break
|
||||
}
|
||||
if len(data) == 0 {
|
||||
break
|
||||
}
|
||||
if callback(data, err) == false {
|
||||
break
|
||||
}
|
||||
if len(data) < limit {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,7 +200,7 @@ func Test_Model_Update(t *testing.T) {
|
||||
defer dropTable(table)
|
||||
// UPDATE...LIMIT
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).Data("nickname", "T100").OrderBy("id desc").Limit(2).Update()
|
||||
result, err := db.Table(table).Data("nickname", "T100").Order("id desc").Limit(2).Update()
|
||||
gtest.Assert(err, nil)
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 2)
|
||||
@ -246,10 +246,10 @@ func Test_Model_Clone(t *testing.T) {
|
||||
count, err := md.Count()
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
record, err := md.OrderBy("id DESC").One()
|
||||
record, err := md.Order("id DESC").One()
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
result, err := md.OrderBy("id ASC").All()
|
||||
result, err := md.Order("id ASC").All()
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
gtest.Assert(count, 2)
|
||||
@ -327,7 +327,7 @@ func Test_Model_Safe(t *testing.T) {
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(count, 2)
|
||||
|
||||
all, err := md2.OrderBy("id asc").All()
|
||||
all, err := md2.Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(all), 2)
|
||||
gtest.Assert(all[0]["id"].Int(), 1)
|
||||
@ -342,7 +342,7 @@ func Test_Model_Safe(t *testing.T) {
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(count, 3)
|
||||
|
||||
all, err = md3.OrderBy("id asc").All()
|
||||
all, err = md3.Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(all), 3)
|
||||
gtest.Assert(all[0]["id"].Int(), 4)
|
||||
@ -371,6 +371,44 @@ func Test_Model_All(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Model_FindAll(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).FindAll(5)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 1)
|
||||
gtest.Assert(result[0]["id"].Int(), 5)
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).Order("id asc").FindAll("id", 8)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 1)
|
||||
gtest.Assert(result[0]["id"].Int(), 8)
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).Order("id asc").FindAll(g.Slice{3, 9})
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["id"].Int(), 3)
|
||||
gtest.Assert(result[1]["id"].Int(), 9)
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).FindAll()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), INIT_DATA_SIZE)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).Where("id<0").FindAll()
|
||||
gtest.Assert(result, nil)
|
||||
gtest.Assert(err, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Model_One(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
@ -387,9 +425,45 @@ func Test_Model_One(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Model_FindOne(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
gtest.Case(t, func() {
|
||||
record, err := db.Table(table).FindOne(1)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(record["nickname"].String(), "name_1")
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
record, err := db.Table(table).FindOne(3)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(record["nickname"].String(), "name_3")
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
record, err := db.Table(table).Where("id", 1).FindOne()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(record["nickname"].String(), "name_1")
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
record, err := db.Table(table).FindOne("id", 9)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(record["nickname"].String(), "name_9")
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
record, err := db.Table(table).Where("id", 0).FindOne()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(record, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Model_Value(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
gtest.Case(t, func() {
|
||||
value, err := db.Table(table).Fields("nickname").Where("id", 1).Value()
|
||||
gtest.Assert(err, nil)
|
||||
@ -403,6 +477,35 @@ func Test_Model_Value(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Model_FindValue(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
gtest.Case(t, func() {
|
||||
value, err := db.Table(table).FindValue("nickname", 1)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(value.String(), "name_1")
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
value, err := db.Table(table).Order("id desc").FindValue("nickname")
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(value.String(), "name_10")
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
value, err := db.Table(table).Fields("nickname").Where("id", 1).FindValue()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(value.String(), "name_1")
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
value, err := db.Table(table).Fields("nickname").Where("id", 0).FindValue()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(value, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Model_Count(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
@ -413,6 +516,26 @@ func Test_Model_Count(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Model_FindCount(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
gtest.Case(t, func() {
|
||||
count, err := db.Table(table).FindCount(g.Slice{1, 3})
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(count, 2)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
count, err := db.Table(table).FindCount(g.Slice{1, 300000})
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(count, 1)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
count, err := db.Table(table).FindCount()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(count, INIT_DATA_SIZE)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Model_Select(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
@ -514,7 +637,7 @@ func Test_Model_Structs(t *testing.T) {
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
var users []User
|
||||
err := db.Table(table).OrderBy("id asc").Structs(&users)
|
||||
err := db.Table(table).Order("id asc").Structs(&users)
|
||||
if err != nil {
|
||||
gtest.Error(err)
|
||||
}
|
||||
@ -537,7 +660,7 @@ func Test_Model_Structs(t *testing.T) {
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var users []*User
|
||||
err := db.Table(table).OrderBy("id asc").Structs(&users)
|
||||
err := db.Table(table).Order("id asc").Structs(&users)
|
||||
if err != nil {
|
||||
gtest.Error(err)
|
||||
}
|
||||
@ -560,7 +683,7 @@ func Test_Model_Structs(t *testing.T) {
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var users []*User
|
||||
err := db.Table(table).OrderBy("id asc").Scan(&users)
|
||||
err := db.Table(table).Order("id asc").Scan(&users)
|
||||
if err != nil {
|
||||
gtest.Error(err)
|
||||
}
|
||||
@ -629,7 +752,7 @@ func Test_Model_Scan(t *testing.T) {
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
var users []User
|
||||
err := db.Table(table).OrderBy("id asc").Scan(&users)
|
||||
err := db.Table(table).Order("id asc").Scan(&users)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(users), INIT_DATA_SIZE)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
@ -649,7 +772,7 @@ func Test_Model_Scan(t *testing.T) {
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var users []*User
|
||||
err := db.Table(table).OrderBy("id asc").Scan(&users)
|
||||
err := db.Table(table).Order("id asc").Scan(&users)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(users), INIT_DATA_SIZE)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
@ -683,7 +806,7 @@ func Test_Model_OrderBy(t *testing.T) {
|
||||
defer dropTable(table)
|
||||
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).OrderBy("id DESC").Select()
|
||||
result, err := db.Table(table).Order("id DESC").Select()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), INIT_DATA_SIZE)
|
||||
gtest.Assert(result[0]["nickname"].String(), fmt.Sprintf("name_%d", INIT_DATA_SIZE))
|
||||
@ -724,7 +847,7 @@ func Test_Model_Where(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).Where(g.Map{
|
||||
"passport like": "user_1%",
|
||||
}).OrderBy("id asc").All()
|
||||
}).Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0].GMap().Get("id"), 1)
|
||||
@ -870,7 +993,7 @@ func Test_Model_Where(t *testing.T) {
|
||||
"create_time > 0": nil,
|
||||
"id": g.Slice{1, 2, 3},
|
||||
}
|
||||
result, err := db.Table(table).Where(conditions).OrderBy("id asc").All()
|
||||
result, err := db.Table(table).Where(conditions).Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 3)
|
||||
gtest.Assert(result[0]["id"].Int(), 1)
|
||||
@ -885,7 +1008,7 @@ func Test_Model_Where(t *testing.T) {
|
||||
"create_time > ?": 0,
|
||||
"id in(?)": g.Slice{1, 2, 3},
|
||||
}
|
||||
result, err := db.Table(table).Where(conditions).OrderBy("id asc").All()
|
||||
result, err := db.Table(table).Where(conditions).Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 3)
|
||||
gtest.Assert(result[0]["id"].Int(), 1)
|
||||
@ -906,7 +1029,7 @@ func Test_Model_Where(t *testing.T) {
|
||||
})
|
||||
// slice single
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).Where("id IN(?)", g.Slice{1, 3}).OrderBy("id ASC").All()
|
||||
result, err := db.Table(table).Where("id IN(?)", g.Slice{1, 3}).Order("id ASC").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["id"].Int(), 1)
|
||||
@ -914,7 +1037,7 @@ func Test_Model_Where(t *testing.T) {
|
||||
})
|
||||
// slice + string
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).Where("nickname=? AND id IN(?)", "name_3", g.Slice{1, 3}).OrderBy("id ASC").All()
|
||||
result, err := db.Table(table).Where("nickname=? AND id IN(?)", "name_3", g.Slice{1, 3}).Order("id ASC").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 1)
|
||||
gtest.Assert(result[0]["id"].Int(), 3)
|
||||
@ -924,7 +1047,7 @@ func Test_Model_Where(t *testing.T) {
|
||||
result, err := db.Table(table).Where(g.Map{
|
||||
"id": g.Slice{1, 3},
|
||||
"nickname": "name_3",
|
||||
}).OrderBy("id ASC").All()
|
||||
}).Order("id ASC").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 1)
|
||||
gtest.Assert(result[0]["id"].Int(), 3)
|
||||
@ -938,7 +1061,265 @@ func Test_Model_Where(t *testing.T) {
|
||||
result, err := db.Table(table).Where(User{
|
||||
Ids: []int{1, 3},
|
||||
Nickname: "name_3",
|
||||
}).OrderBy("id ASC").All()
|
||||
}).Order("id ASC").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 1)
|
||||
gtest.Assert(result[0]["id"].Int(), 3)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Model_WherePri(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
// primary key
|
||||
gtest.Case(t, func() {
|
||||
one, err := db.Table(table).WherePri(3).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNE(one, nil)
|
||||
gtest.Assert(one["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
all, err := db.Table(table).WherePri(g.Slice{3, 9}).Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(all), 2)
|
||||
gtest.Assert(all[0]["id"].Int(), 3)
|
||||
gtest.Assert(all[1]["id"].Int(), 9)
|
||||
})
|
||||
|
||||
// string
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id=? and nickname=?", 3, "name_3").One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertGT(len(result), 0)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
// slice parameter
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id=? and nickname=?", g.Slice{3, "name_3"}).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertGT(len(result), 0)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
// map like
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(g.Map{
|
||||
"passport like": "user_1%",
|
||||
}).Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0].GMap().Get("id"), 1)
|
||||
gtest.Assert(result[1].GMap().Get("id"), 10)
|
||||
})
|
||||
// map + slice parameter
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(g.Map{
|
||||
"id": g.Slice{1, 2, 3},
|
||||
"passport": g.Slice{"user_2", "user_3"},
|
||||
}).And("id=? and nickname=?", g.Slice{3, "name_3"}).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertGT(len(result), 0)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(g.Map{
|
||||
"id": g.Slice{1, 2, 3},
|
||||
"passport": g.Slice{"user_2", "user_3"},
|
||||
}).Or("nickname=?", g.Slice{"name_4"}).And("id", 3).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertGT(len(result), 0)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id=3", g.Slice{}).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertGT(len(result), 0)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id=?", g.Slice{3}).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertGT(len(result), 0)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id", 3).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertGT(len(result), 0)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id", 3).WherePri("nickname", "name_3").One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id", 3).And("nickname", "name_3").One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id", 30).Or("nickname", "name_3").One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id", 30).Or("nickname", "name_3").And("id>?", 1).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id", 30).Or("nickname", "name_3").And("id>", 1).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
// slice
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id=? AND nickname=?", g.Slice{3, "name_3"}...).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id=? AND nickname=?", g.Slice{3, "name_3"}).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("passport like ? and nickname like ?", g.Slice{"user_3", "name_3"}).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
// map
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(g.Map{"id": 3, "nickname": "name_3"}).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
// map key operator
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(g.Map{"id>": 1, "id<": 3}).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 2)
|
||||
})
|
||||
|
||||
// gmap.Map
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(gmap.NewFrom(g.MapAnyAny{"id": 3, "nickname": "name_3"})).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
// gmap.Map key operator
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(gmap.NewFrom(g.MapAnyAny{"id>": 1, "id<": 3})).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 2)
|
||||
})
|
||||
|
||||
// list map
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(gmap.NewListMapFrom(g.MapAnyAny{"id": 3, "nickname": "name_3"})).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
// list map key operator
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(gmap.NewListMapFrom(g.MapAnyAny{"id>": 1, "id<": 3})).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 2)
|
||||
})
|
||||
|
||||
// tree map
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(gmap.NewTreeMapFrom(gutil.ComparatorString, g.MapAnyAny{"id": 3, "nickname": "name_3"})).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
// tree map key operator
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(gmap.NewTreeMapFrom(gutil.ComparatorString, g.MapAnyAny{"id>": 1, "id<": 3})).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 2)
|
||||
})
|
||||
|
||||
// complicated where 1
|
||||
gtest.Case(t, func() {
|
||||
//db.SetDebug(true)
|
||||
conditions := g.Map{
|
||||
"nickname like ?": "%name%",
|
||||
"id between ? and ?": g.Slice{1, 3},
|
||||
"id > 0": nil,
|
||||
"create_time > 0": nil,
|
||||
"id": g.Slice{1, 2, 3},
|
||||
}
|
||||
result, err := db.Table(table).WherePri(conditions).Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 3)
|
||||
gtest.Assert(result[0]["id"].Int(), 1)
|
||||
})
|
||||
// complicated where 2
|
||||
gtest.Case(t, func() {
|
||||
//db.SetDebug(true)
|
||||
conditions := g.Map{
|
||||
"nickname like ?": "%name%",
|
||||
"id between ? and ?": g.Slice{1, 3},
|
||||
"id >= ?": 1,
|
||||
"create_time > ?": 0,
|
||||
"id in(?)": g.Slice{1, 2, 3},
|
||||
}
|
||||
result, err := db.Table(table).WherePri(conditions).Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 3)
|
||||
gtest.Assert(result[0]["id"].Int(), 1)
|
||||
})
|
||||
// struct
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int `json:"id"`
|
||||
Nickname string `gconv:"nickname"`
|
||||
}
|
||||
result, err := db.Table(table).WherePri(User{3, "name_3"}).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
|
||||
result, err = db.Table(table).WherePri(&User{3, "name_3"}).One()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(result["id"].Int(), 3)
|
||||
})
|
||||
// slice single
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("id IN(?)", g.Slice{1, 3}).Order("id ASC").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["id"].Int(), 1)
|
||||
gtest.Assert(result[1]["id"].Int(), 3)
|
||||
})
|
||||
// slice + string
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri("nickname=? AND id IN(?)", "name_3", g.Slice{1, 3}).Order("id ASC").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 1)
|
||||
gtest.Assert(result[0]["id"].Int(), 3)
|
||||
})
|
||||
// slice + map
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table(table).WherePri(g.Map{
|
||||
"id": g.Slice{1, 3},
|
||||
"nickname": "name_3",
|
||||
}).Order("id ASC").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 1)
|
||||
gtest.Assert(result[0]["id"].Int(), 3)
|
||||
})
|
||||
// slice + struct
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Ids []int `json:"id"`
|
||||
Nickname string `gconv:"nickname"`
|
||||
}
|
||||
result, err := db.Table(table).WherePri(User{
|
||||
Ids: []int{1, 3},
|
||||
Nickname: "name_3",
|
||||
}).Order("id ASC").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 1)
|
||||
gtest.Assert(result[0]["id"].Int(), 3)
|
||||
@ -969,7 +1350,7 @@ func Test_Model_Offset(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
result, err := db.Table(table).Limit(2).Offset(5).OrderBy("id").Select()
|
||||
result, err := db.Table(table).Limit(2).Offset(5).Order("id").Select()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["id"], 6)
|
||||
@ -980,7 +1361,7 @@ func Test_Model_ForPage(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
result, err := db.Table(table).ForPage(3, 3).OrderBy("id").Select()
|
||||
result, err := db.Table(table).ForPage(3, 3).Order("id").Select()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 3)
|
||||
gtest.Assert(result[0]["id"], 7)
|
||||
@ -1153,7 +1534,7 @@ func Test_Model_Option_List(t *testing.T) {
|
||||
gtest.Assert(err, nil)
|
||||
n, _ := r.RowsAffected()
|
||||
gtest.Assert(n, 2)
|
||||
list, err := db.Table(table).OrderBy("id asc").All()
|
||||
list, err := db.Table(table).Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(list), 2)
|
||||
gtest.Assert(list[0]["id"].String(), "1")
|
||||
@ -1187,7 +1568,7 @@ func Test_Model_Option_List(t *testing.T) {
|
||||
gtest.Assert(err, nil)
|
||||
n, _ := r.RowsAffected()
|
||||
gtest.Assert(n, 2)
|
||||
list, err := db.Table(table).OrderBy("id asc").All()
|
||||
list, err := db.Table(table).Order("id asc").All()
|
||||
g.Dump(list)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(list), 2)
|
||||
@ -1232,7 +1613,7 @@ func Test_Model_FieldsEx(t *testing.T) {
|
||||
defer dropTable(table)
|
||||
// Select.
|
||||
gtest.Case(t, func() {
|
||||
r, err := db.Table(table).FieldsEx("create_time, id").Where("id in (?)", g.Slice{1, 2}).OrderBy("id asc").All()
|
||||
r, err := db.Table(table).FieldsEx("create_time, id").Where("id in (?)", g.Slice{1, 2}).Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(r), 2)
|
||||
gtest.Assert(len(r[0]), 3)
|
||||
@ -1268,7 +1649,7 @@ func Test_Model_Prefix(t *testing.T) {
|
||||
defer dropTable(PREFIX1 + table)
|
||||
// Select.
|
||||
gtest.Case(t, func() {
|
||||
r, err := db.Table(table).Where("id in (?)", g.Slice{1, 2}).OrderBy("id asc").All()
|
||||
r, err := db.Table(table).Where("id in (?)", g.Slice{1, 2}).Order("id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(r), 2)
|
||||
gtest.Assert(r[0]["id"], "1")
|
||||
@ -1276,7 +1657,7 @@ func Test_Model_Prefix(t *testing.T) {
|
||||
})
|
||||
// Select with alias.
|
||||
gtest.Case(t, func() {
|
||||
r, err := db.Table(table+" as u").Where("u.id in (?)", g.Slice{1, 2}).OrderBy("u.id asc").All()
|
||||
r, err := db.Table(table+" as u").Where("u.id in (?)", g.Slice{1, 2}).Order("u.id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(r), 2)
|
||||
gtest.Assert(r[0]["id"], "1")
|
||||
@ -1284,7 +1665,7 @@ func Test_Model_Prefix(t *testing.T) {
|
||||
})
|
||||
// Select with alias and join statement.
|
||||
gtest.Case(t, func() {
|
||||
r, err := db.Table(table+" as u1").LeftJoin(table+" as u2", "u2.id=u1.id").Where("u1.id in (?)", g.Slice{1, 2}).OrderBy("u1.id asc").All()
|
||||
r, err := db.Table(table+" as u1").LeftJoin(table+" as u2", "u2.id=u1.id").Where("u1.id in (?)", g.Slice{1, 2}).Order("u1.id asc").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(r), 2)
|
||||
gtest.Assert(r[0]["id"], "1")
|
||||
|
||||
@ -5,6 +5,9 @@
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
// Package gins provides instances and core components management.
|
||||
//
|
||||
// Note that it should not used glog.Panic* functions for panics if you do not want
|
||||
// to log all the panics.
|
||||
package gins
|
||||
|
||||
import (
|
||||
@ -103,7 +106,7 @@ func View(name ...string) *gview.View {
|
||||
}
|
||||
if m != nil {
|
||||
if err := view.SetConfigWithMap(m); err != nil {
|
||||
glog.Panic(err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,7 +153,7 @@ func Log(name ...string) *glog.Logger {
|
||||
}
|
||||
if m != nil {
|
||||
if err := logger.SetConfigWithMap(m); err != nil {
|
||||
glog.Panic(err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,15 +175,15 @@ func Database(name ...string) gdb.DB {
|
||||
if gdb.GetConfig(group) != nil {
|
||||
db, err := gdb.Instance(group)
|
||||
if err != nil {
|
||||
glog.Panic(err)
|
||||
panic(err)
|
||||
}
|
||||
return db
|
||||
}
|
||||
m := config.GetMap("database")
|
||||
if m == nil {
|
||||
glog.Panic(`database init failed: "database" node not found, is config file or configuration missing?`)
|
||||
panic(`database init failed: "database" node not found, is config file or configuration missing?`)
|
||||
}
|
||||
// Parse <m> as map-slice.
|
||||
// Parse <m> as map-slice and adds it to gdb's global configurations.
|
||||
for group, groupConfig := range m {
|
||||
cg := gdb.ConfigGroup{}
|
||||
switch value := groupConfig.(type) {
|
||||
@ -199,14 +202,15 @@ func Database(name ...string) gdb.DB {
|
||||
gdb.SetConfigGroup(group, cg)
|
||||
}
|
||||
}
|
||||
// Parse <m> as a single node configuration.
|
||||
// Parse <m> as a single node configuration,
|
||||
// which is the default group configuration.
|
||||
if node := parseDBConfigNode(m); node != nil {
|
||||
cg := gdb.ConfigGroup{}
|
||||
if node.LinkInfo != "" || node.Host != "" {
|
||||
cg = append(cg, *node)
|
||||
}
|
||||
if len(cg) > 0 {
|
||||
gdb.SetConfigGroup(group, cg)
|
||||
gdb.SetConfigGroup(gdb.DEFAULT_GROUP_NAME, cg)
|
||||
}
|
||||
}
|
||||
addConfigMonitor(instanceKey, config)
|
||||
@ -219,12 +223,12 @@ func Database(name ...string) gdb.DB {
|
||||
}
|
||||
if m != nil {
|
||||
if err := db.GetLogger().SetConfigWithMap(m); err != nil {
|
||||
glog.Panic(err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return db
|
||||
} else {
|
||||
glog.Panic(err)
|
||||
panic(err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -242,7 +246,7 @@ func parseDBConfigNode(value interface{}) *gdb.ConfigNode {
|
||||
node := &gdb.ConfigNode{}
|
||||
err := gconv.Struct(nodeMap, node)
|
||||
if err != nil {
|
||||
glog.Panic(err)
|
||||
panic(err)
|
||||
}
|
||||
if _, v := gutil.MapPossibleItemByKey(nodeMap, "link"); v != nil {
|
||||
node.LinkInfo = gconv.String(v)
|
||||
@ -282,15 +286,15 @@ func Redis(name ...string) *gredis.Redis {
|
||||
if v, ok := m[group]; ok {
|
||||
redisConfig, err := gredis.ConfigFromStr(gconv.String(v))
|
||||
if err != nil {
|
||||
glog.Panic(err)
|
||||
panic(err)
|
||||
}
|
||||
addConfigMonitor(instanceKey, config)
|
||||
return gredis.New(redisConfig)
|
||||
} else {
|
||||
glog.Panicf(`configuration for redis not found for group "%s"`, group)
|
||||
panic(fmt.Sprintf(`configuration for redis not found for group "%s"`, group))
|
||||
}
|
||||
} else {
|
||||
glog.Panicf(`incomplete configuration for redis: "redis" node not found in config file "%s"`, config.FilePath())
|
||||
panic(fmt.Sprintf(`incomplete configuration for redis: "redis" node not found in config file "%s"`, config.FilePath()))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -8,5 +8,7 @@
|
||||
package ghttp
|
||||
|
||||
var (
|
||||
// paramTagPriority is the priority tag array for request parameter
|
||||
// to struct field mapping.
|
||||
paramTagPriority = []string{"param", "params", "p"}
|
||||
)
|
||||
|
||||
@ -6,122 +6,182 @@
|
||||
|
||||
package ghttp
|
||||
|
||||
// Get is a convenience method for sending GET request.
|
||||
// NOTE that remembers CLOSING the response object when it'll never be used.
|
||||
func Get(url string) (*ClientResponse, error) {
|
||||
return DoRequest("GET", url)
|
||||
}
|
||||
|
||||
// Put is a convenience method for sending PUT request.
|
||||
// NOTE that remembers CLOSING the response object when it'll never be used.
|
||||
func Put(url string, data ...interface{}) (*ClientResponse, error) {
|
||||
return DoRequest("PUT", url, data...)
|
||||
}
|
||||
|
||||
// Post is a convenience method for sending POST request.
|
||||
// NOTE that remembers CLOSING the response object when it'll never be used.
|
||||
func Post(url string, data ...interface{}) (*ClientResponse, error) {
|
||||
return DoRequest("POST", url, data...)
|
||||
}
|
||||
|
||||
// Delete is a convenience method for sending DELETE request.
|
||||
// NOTE that remembers CLOSING the response object when it'll never be used.
|
||||
func Delete(url string, data ...interface{}) (*ClientResponse, error) {
|
||||
return DoRequest("DELETE", url, data...)
|
||||
}
|
||||
|
||||
// Head is a convenience method for sending HEAD request.
|
||||
// NOTE that remembers CLOSING the response object when it'll never be used.
|
||||
func Head(url string, data ...interface{}) (*ClientResponse, error) {
|
||||
return DoRequest("HEAD", url, data...)
|
||||
}
|
||||
|
||||
// Patch is a convenience method for sending PATCH request.
|
||||
// NOTE that remembers CLOSING the response object when it'll never be used.
|
||||
func Patch(url string, data ...interface{}) (*ClientResponse, error) {
|
||||
return DoRequest("PATCH", url, data...)
|
||||
}
|
||||
|
||||
// Connect is a convenience method for sending CONNECT request.
|
||||
// NOTE that remembers CLOSING the response object when it'll never be used.
|
||||
func Connect(url string, data ...interface{}) (*ClientResponse, error) {
|
||||
return DoRequest("CONNECT", url, data...)
|
||||
}
|
||||
|
||||
// Options is a convenience method for sending OPTIONS request.
|
||||
// NOTE that remembers CLOSING the response object when it'll never be used.
|
||||
func Options(url string, data ...interface{}) (*ClientResponse, error) {
|
||||
return DoRequest("OPTIONS", url, data...)
|
||||
}
|
||||
|
||||
// Trace is a convenience method for sending TRACE request.
|
||||
// NOTE that remembers CLOSING the response object when it'll never be used.
|
||||
func Trace(url string, data ...interface{}) (*ClientResponse, error) {
|
||||
return DoRequest("TRACE", url, data...)
|
||||
}
|
||||
|
||||
// DoRequest is a convenience method for sending custom http method request.
|
||||
// NOTE that remembers CLOSING the response object when it'll never be used.
|
||||
func DoRequest(method, url string, data ...interface{}) (*ClientResponse, error) {
|
||||
return NewClient().DoRequest(method, url, data...)
|
||||
}
|
||||
|
||||
// GetContent is a convenience method for sending GET request, which retrieves and returns
|
||||
// the result content and automatically closes response object.
|
||||
func GetContent(url string, data ...interface{}) string {
|
||||
return RequestContent("GET", url, data...)
|
||||
}
|
||||
|
||||
// PutContent is a convenience method for sending PUT request, which retrieves and returns
|
||||
// the result content and automatically closes response object.
|
||||
func PutContent(url string, data ...interface{}) string {
|
||||
return RequestContent("PUT", url, data...)
|
||||
}
|
||||
|
||||
// PostContent is a convenience method for sending POST request, which retrieves and returns
|
||||
// the result content and automatically closes response object.
|
||||
func PostContent(url string, data ...interface{}) string {
|
||||
return RequestContent("POST", url, data...)
|
||||
}
|
||||
|
||||
// DeleteContent is a convenience method for sending DELETE request, which retrieves and returns
|
||||
// the result content and automatically closes response object.
|
||||
func DeleteContent(url string, data ...interface{}) string {
|
||||
return RequestContent("DELETE", url, data...)
|
||||
}
|
||||
|
||||
// HeadContent is a convenience method for sending HEAD request, which retrieves and returns
|
||||
// the result content and automatically closes response object.
|
||||
func HeadContent(url string, data ...interface{}) string {
|
||||
return RequestContent("HEAD", url, data...)
|
||||
}
|
||||
|
||||
// PatchContent is a convenience method for sending PATCH request, which retrieves and returns
|
||||
// the result content and automatically closes response object.
|
||||
func PatchContent(url string, data ...interface{}) string {
|
||||
return RequestContent("PATCH", url, data...)
|
||||
}
|
||||
|
||||
// ConnectContent is a convenience method for sending CONNECT request, which retrieves and returns
|
||||
// the result content and automatically closes response object.
|
||||
func ConnectContent(url string, data ...interface{}) string {
|
||||
return RequestContent("CONNECT", url, data...)
|
||||
}
|
||||
|
||||
// OptionsContent is a convenience method for sending OPTIONS request, which retrieves and returns
|
||||
// the result content and automatically closes response object.
|
||||
func OptionsContent(url string, data ...interface{}) string {
|
||||
return RequestContent("OPTIONS", url, data...)
|
||||
}
|
||||
|
||||
// TraceContent is a convenience method for sending TRACE request, which retrieves and returns
|
||||
// the result content and automatically closes response object.
|
||||
func TraceContent(url string, data ...interface{}) string {
|
||||
return RequestContent("TRACE", url, data...)
|
||||
}
|
||||
|
||||
// RequestContent is a convenience method for sending custom http method request, which
|
||||
// retrieves and returns the result content and automatically closes response object.
|
||||
func RequestContent(method string, url string, data ...interface{}) string {
|
||||
return NewClient().RequestContent(method, url, data...)
|
||||
}
|
||||
|
||||
// GetBytes is a convenience method for sending GET request, which retrieves and returns
|
||||
// the result content as bytes and automatically closes response object.
|
||||
func GetBytes(url string, data ...interface{}) []byte {
|
||||
return RequestBytes("GET", url, data...)
|
||||
}
|
||||
|
||||
// PutBytes is a convenience method for sending PUT request, which retrieves and returns
|
||||
// the result content as bytes and automatically closes response object.
|
||||
func PutBytes(url string, data ...interface{}) []byte {
|
||||
return RequestBytes("PUT", url, data...)
|
||||
}
|
||||
|
||||
// PostBytes is a convenience method for sending POST request, which retrieves and returns
|
||||
// the result content as bytes and automatically closes response object.
|
||||
func PostBytes(url string, data ...interface{}) []byte {
|
||||
return RequestBytes("POST", url, data...)
|
||||
}
|
||||
|
||||
// DeleteBytes is a convenience method for sending DELETE request, which retrieves and returns
|
||||
// the result content as bytes and automatically closes response object.
|
||||
func DeleteBytes(url string, data ...interface{}) []byte {
|
||||
return RequestBytes("DELETE", url, data...)
|
||||
}
|
||||
|
||||
// HeadBytes is a convenience method for sending HEAD request, which retrieves and returns
|
||||
// the result content as bytes and automatically closes response object.
|
||||
func HeadBytes(url string, data ...interface{}) []byte {
|
||||
return RequestBytes("HEAD", url, data...)
|
||||
}
|
||||
|
||||
// PatchBytes is a convenience method for sending PATCH request, which retrieves and returns
|
||||
// the result content as bytes and automatically closes response object.
|
||||
func PatchBytes(url string, data ...interface{}) []byte {
|
||||
return RequestBytes("PATCH", url, data...)
|
||||
}
|
||||
|
||||
// ConnectBytes is a convenience method for sending CONNECT request, which retrieves and returns
|
||||
// the result content as bytes and automatically closes response object.
|
||||
func ConnectBytes(url string, data ...interface{}) []byte {
|
||||
return RequestBytes("CONNECT", url, data...)
|
||||
}
|
||||
|
||||
// OptionsBytes is a convenience method for sending OPTIONS request, which retrieves and returns
|
||||
// the result content as bytes and automatically closes response object.
|
||||
func OptionsBytes(url string, data ...interface{}) []byte {
|
||||
return RequestBytes("OPTIONS", url, data...)
|
||||
}
|
||||
|
||||
// TraceBytes is a convenience method for sending TRACE request, which retrieves and returns
|
||||
// the result content as bytes and automatically closes response object.
|
||||
func TraceBytes(url string, data ...interface{}) []byte {
|
||||
return RequestBytes("TRACE", url, data...)
|
||||
}
|
||||
|
||||
// RequestBytes is a convenience method for sending custom http method request, which
|
||||
// retrieves and returns the result content as bytes and automatically closes response object.
|
||||
func RequestBytes(method string, url string, data ...interface{}) []byte {
|
||||
return NewClient().RequestBytes(method, url, data...)
|
||||
}
|
||||
|
||||
@ -6,44 +6,53 @@
|
||||
|
||||
package ghttp
|
||||
|
||||
// GetBytes sends a GET request, retrieves and returns the result content as bytes.
|
||||
func (c *Client) GetBytes(url string, data ...interface{}) []byte {
|
||||
return c.RequestBytes("GET", url, data...)
|
||||
}
|
||||
|
||||
// PutBytes sends a PUT request, retrieves and returns the result content as bytes.
|
||||
func (c *Client) PutBytes(url string, data ...interface{}) []byte {
|
||||
return c.RequestBytes("PUT", url, data...)
|
||||
}
|
||||
|
||||
// PostBytes sends a POST request, retrieves and returns the result content as bytes.
|
||||
func (c *Client) PostBytes(url string, data ...interface{}) []byte {
|
||||
return c.RequestBytes("POST", url, data...)
|
||||
}
|
||||
|
||||
// DeleteBytes sends a DELETE request, retrieves and returns the result content as bytes.
|
||||
func (c *Client) DeleteBytes(url string, data ...interface{}) []byte {
|
||||
return c.RequestBytes("DELETE", url, data...)
|
||||
}
|
||||
|
||||
// HeadBytes sends a HEAD request, retrieves and returns the result content as bytes.
|
||||
func (c *Client) HeadBytes(url string, data ...interface{}) []byte {
|
||||
return c.RequestBytes("HEAD", url, data...)
|
||||
}
|
||||
|
||||
// PatchBytes sends a PATCH request, retrieves and returns the result content as bytes.
|
||||
func (c *Client) PatchBytes(url string, data ...interface{}) []byte {
|
||||
return c.RequestBytes("PATCH", url, data...)
|
||||
}
|
||||
|
||||
// ConnectBytes sends a CONNECT request, retrieves and returns the result content as bytes.
|
||||
func (c *Client) ConnectBytes(url string, data ...interface{}) []byte {
|
||||
return c.RequestBytes("CONNECT", url, data...)
|
||||
}
|
||||
|
||||
// OptionsBytes sends a OPTIONS request, retrieves and returns the result content as bytes.
|
||||
func (c *Client) OptionsBytes(url string, data ...interface{}) []byte {
|
||||
return c.RequestBytes("OPTIONS", url, data...)
|
||||
}
|
||||
|
||||
// TraceBytes sends a TRACE request, retrieves and returns the result content as bytes.
|
||||
func (c *Client) TraceBytes(url string, data ...interface{}) []byte {
|
||||
return c.RequestBytes("TRACE", url, data...)
|
||||
}
|
||||
|
||||
// RequestBytes sends request using given HTTP method and data and returns the binary as bytes.
|
||||
// It reads and closes the response object internally automatically.
|
||||
// RequestBytes sends request using given HTTP method and data, retrieves returns the result
|
||||
// as bytes. It reads and closes the response object internally automatically.
|
||||
func (c *Client) RequestBytes(method string, url string, data ...interface{}) []byte {
|
||||
response, err := c.DoRequest(method, url, data...)
|
||||
if err != nil {
|
||||
|
||||
@ -128,8 +128,15 @@ func (r *Request) GetMapStrStr(def ...map[string]interface{}) map[string]string
|
||||
return r.GetRequestMapStrStr(def...)
|
||||
}
|
||||
|
||||
// GetStruct is alias of GetRequestToStruct.
|
||||
// See GetRequestToStruct.
|
||||
func (r *Request) GetStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
return r.GetRequestToStruct(pointer, mapping...)
|
||||
}
|
||||
|
||||
// GetToStruct is alias of GetRequestToStruct.
|
||||
// See GetRequestToStruct.
|
||||
// Deprecated.
|
||||
func (r *Request) GetToStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
return r.GetRequestToStruct(pointer, mapping...)
|
||||
}
|
||||
|
||||
@ -154,10 +154,10 @@ func (r *Request) GetFormMapStrVar(kvMap ...map[string]interface{}) map[string]*
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetFormToStruct retrieves all form parameters passed from client and converts them to
|
||||
// GetFormStruct retrieves all form parameters passed from client and converts them to
|
||||
// given struct object. Note that the parameter <pointer> is a pointer to the struct object.
|
||||
// The optional parameter <mapping> is used to specify the key to attribute mapping.
|
||||
func (r *Request) GetFormToStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
func (r *Request) GetFormStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
r.ParseForm()
|
||||
tagMap := structs.TagMapName(pointer, paramTagPriority, true)
|
||||
if len(mapping) > 0 {
|
||||
@ -167,3 +167,9 @@ func (r *Request) GetFormToStruct(pointer interface{}, mapping ...map[string]str
|
||||
}
|
||||
return gconv.StructDeep(r.formMap, pointer, tagMap)
|
||||
}
|
||||
|
||||
// GetFormToStruct is alias of GetFormStruct. See GetFormStruct.
|
||||
// Deprecated.
|
||||
func (r *Request) GetFormToStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
return r.GetFormStruct(pointer, mapping...)
|
||||
}
|
||||
|
||||
@ -174,11 +174,11 @@ func (r *Request) GetPostMapStrVar(kvMap ...map[string]interface{}) map[string]*
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetPostToStruct retrieves all parameters in the form and body passed from client
|
||||
// GetPostStruct retrieves all parameters in the form and body passed from client
|
||||
// and converts them to given struct object. Note that the parameter <pointer> is a pointer
|
||||
// to the struct object. The optional parameter <mapping> is used to specify the key to
|
||||
// attribute mapping.
|
||||
func (r *Request) GetPostToStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
func (r *Request) GetPostStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
tagMap := structs.TagMapName(pointer, paramTagPriority, true)
|
||||
if len(mapping) > 0 {
|
||||
for k, v := range mapping[0] {
|
||||
@ -187,3 +187,9 @@ func (r *Request) GetPostToStruct(pointer interface{}, mapping ...map[string]str
|
||||
}
|
||||
return gconv.StructDeep(r.GetPostMap(), pointer, tagMap)
|
||||
}
|
||||
|
||||
// GetPostToStruct is alias of GetQueryStruct. See GetPostStruct.
|
||||
// Deprecated.
|
||||
func (r *Request) GetPostToStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
return r.GetPostStruct(pointer, mapping...)
|
||||
}
|
||||
|
||||
@ -188,11 +188,11 @@ func (r *Request) GetQueryMapStrVar(kvMap ...map[string]interface{}) map[string]
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetQueryToStruct retrieves all parameters passed from client using HTTP GET method
|
||||
// GetQueryStruct retrieves all parameters passed from client using HTTP GET method
|
||||
// and converts them to given struct object. Note that the parameter <pointer> is a pointer
|
||||
// to the struct object. The optional parameter <mapping> is used to specify the key to
|
||||
// attribute mapping.
|
||||
func (r *Request) GetQueryToStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
func (r *Request) GetQueryStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
r.ParseQuery()
|
||||
tagMap := structs.TagMapName(pointer, paramTagPriority, true)
|
||||
if len(mapping) > 0 {
|
||||
@ -202,3 +202,9 @@ func (r *Request) GetQueryToStruct(pointer interface{}, mapping ...map[string]st
|
||||
}
|
||||
return gconv.StructDeep(r.GetQueryMap(), pointer, tagMap)
|
||||
}
|
||||
|
||||
// GetQueryToStruct is alias of GetQueryStruct. See GetQueryStruct.
|
||||
// Deprecated.
|
||||
func (r *Request) GetQueryToStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
return r.GetQueryStruct(pointer, mapping...)
|
||||
}
|
||||
|
||||
@ -263,10 +263,10 @@ func (r *Request) GetRequestMapStrVar(kvMap ...map[string]interface{}) map[strin
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRequestToStruct retrieves all parameters passed from client no matter what HTTP method the client is using,
|
||||
// GetRequestStruct retrieves all parameters passed from client no matter what HTTP method the client is using,
|
||||
// and converts them to given struct object. Note that the parameter <pointer> is a pointer to the struct object.
|
||||
// The optional parameter <mapping> is used to specify the key to attribute mapping.
|
||||
func (r *Request) GetRequestToStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
func (r *Request) GetRequestStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
tagMap := structs.TagMapName(pointer, paramTagPriority, true)
|
||||
if len(mapping) > 0 {
|
||||
for k, v := range mapping[0] {
|
||||
@ -275,3 +275,9 @@ func (r *Request) GetRequestToStruct(pointer interface{}, mapping ...map[string]
|
||||
}
|
||||
return gconv.StructDeep(r.GetRequestMap(), pointer, tagMap)
|
||||
}
|
||||
|
||||
// GetRequestToStruct is alias of GetRequestStruct. See GetRequestStruct.
|
||||
// Deprecated.
|
||||
func (r *Request) GetRequestToStruct(pointer interface{}, mapping ...map[string]string) error {
|
||||
return r.GetRequestStruct(pointer, mapping...)
|
||||
}
|
||||
|
||||
@ -335,31 +335,20 @@ func (s *Server) dumpRouterMap() {
|
||||
if s.config.DumpRouterMap && len(s.routesMap) > 0 {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
table := tablewriter.NewWriter(buffer)
|
||||
table.SetHeader([]string{"SERVER", "ADDRESS", "DOMAIN", "METHOD", "P", "ROUTE", "HANDLER", "MIDDLEWARE"})
|
||||
table.SetHeader([]string{"SERVER", "DOMAIN", "ADDRESS", "METHOD", "ROUTE", "HANDLER", "MIDDLEWARE"})
|
||||
table.SetRowLine(true)
|
||||
table.SetBorder(false)
|
||||
table.SetCenterSeparator("|")
|
||||
table.SetColumnAlignment([]int{
|
||||
tablewriter.ALIGN_CENTER,
|
||||
tablewriter.ALIGN_CENTER,
|
||||
tablewriter.ALIGN_CENTER,
|
||||
tablewriter.ALIGN_CENTER,
|
||||
tablewriter.ALIGN_CENTER,
|
||||
tablewriter.ALIGN_LEFT,
|
||||
tablewriter.ALIGN_LEFT,
|
||||
tablewriter.ALIGN_LEFT,
|
||||
})
|
||||
|
||||
for _, item := range s.GetRouterArray() {
|
||||
data := make([]string, 8)
|
||||
data := make([]string, 7)
|
||||
data[0] = item.Server
|
||||
data[1] = item.Address
|
||||
data[2] = item.Domain
|
||||
data[1] = item.Domain
|
||||
data[2] = item.Address
|
||||
data[3] = item.Method
|
||||
data[4] = gconv.String(len(strings.Split(item.Route, "/")) - 1 + item.Priority)
|
||||
data[5] = item.Route
|
||||
data[6] = item.handler.itemName
|
||||
data[7] = item.Middleware
|
||||
data[4] = item.Route
|
||||
data[5] = item.handler.itemName
|
||||
data[6] = item.Middleware
|
||||
table.Append(data)
|
||||
}
|
||||
table.Render()
|
||||
|
||||
@ -63,7 +63,7 @@ func receiveTcpListening() {
|
||||
}
|
||||
// Save the port to the pid file.
|
||||
if err := gfile.PutContents(getCommFilePath(Pid()), gconv.String(i)); err != nil {
|
||||
glog.Panic(err)
|
||||
panic(err)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ package gsession
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/container/gmap"
|
||||
"github.com/gogf/gf/internal/intlog"
|
||||
"os"
|
||||
@ -22,8 +23,6 @@ import (
|
||||
|
||||
"github.com/gogf/gf/os/gtime"
|
||||
|
||||
"github.com/gogf/gf/os/glog"
|
||||
|
||||
"github.com/gogf/gf/os/gfile"
|
||||
)
|
||||
|
||||
@ -39,7 +38,7 @@ var (
|
||||
DefaultStorageFilePath = gfile.Join(gfile.TempDir(), "gsessions")
|
||||
DefaultStorageFileCryptoKey = []byte("Session storage file crypto key!")
|
||||
DefaultStorageFileCryptoEnabled = false
|
||||
DefaultStorageFileLoopInterval = time.Minute
|
||||
DefaultStorageFileLoopInterval = 10 * time.Second
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -55,15 +54,15 @@ func NewStorageFile(path ...string) *StorageFile {
|
||||
if len(path) > 0 && path[0] != "" {
|
||||
storagePath, _ = gfile.Search(path[0])
|
||||
if storagePath == "" {
|
||||
glog.Panicf("'%s' does not exist", path[0])
|
||||
panic(fmt.Sprintf(fmt.Sprintf("'%s' does not exist", path[0])))
|
||||
}
|
||||
if !gfile.IsWritable(storagePath) {
|
||||
glog.Panicf("'%s' is not writable", path[0])
|
||||
panic(fmt.Sprintf("'%s' is not writable", path[0]))
|
||||
}
|
||||
}
|
||||
if storagePath != "" {
|
||||
if err := gfile.Mkdir(storagePath); err != nil {
|
||||
glog.Panicf("mkdir '%s' failed: %v", path[0], err)
|
||||
panic(fmt.Sprintf("mkdir '%s' failed: %v", path[0], err))
|
||||
}
|
||||
}
|
||||
s := &StorageFile{
|
||||
|
||||
@ -53,8 +53,9 @@ func TrimLeft(str string, characterMask ...string) string {
|
||||
// TrimLeftStr strips all of the given <cut> string from the beginning of a string.
|
||||
// Note that it does not strips the whitespaces of its beginning.
|
||||
func TrimLeftStr(str string, cut string) string {
|
||||
for str[0:len(cut)] == cut {
|
||||
str = str[len(cut):]
|
||||
var lenCut = len(cut)
|
||||
for len(str) >= lenCut && str[0:lenCut] == cut {
|
||||
str = str[lenCut:]
|
||||
}
|
||||
return str
|
||||
}
|
||||
@ -71,14 +72,12 @@ func TrimRight(str string, characterMask ...string) string {
|
||||
// TrimRightStr strips all of the given <cut> string from the end of a string.
|
||||
// Note that it does not strips the whitespaces of its end.
|
||||
func TrimRightStr(str string, cut string) string {
|
||||
var length int
|
||||
for {
|
||||
length = len(str)
|
||||
if str[length-len(cut):length] == cut {
|
||||
str = str[:length-len(cut)]
|
||||
} else {
|
||||
break
|
||||
}
|
||||
var lenStr = len(str)
|
||||
var lenCut = len(cut)
|
||||
for lenStr >= lenCut && str[lenStr-lenCut:lenStr] == cut {
|
||||
lenStr = lenStr - lenCut
|
||||
str = str[:lenStr]
|
||||
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
@ -41,9 +41,11 @@ func Test_TrimRight(t *testing.T) {
|
||||
func Test_TrimRightStr(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
gtest.Assert(gstr.TrimRightStr("gogo我爱gogo", "go"), "gogo我爱")
|
||||
gtest.Assert(gstr.TrimRightStr("gogo我爱gogo", "go我爱gogo"), "go")
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
gtest.Assert(gstr.TrimRightStr("我爱中国人", "人"), "我爱中国")
|
||||
gtest.Assert(gstr.TrimRightStr("我爱中国人", "爱中国人"), "我")
|
||||
})
|
||||
}
|
||||
|
||||
@ -57,8 +59,10 @@ func Test_TrimLeft(t *testing.T) {
|
||||
func Test_TrimLeftStr(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
gtest.Assert(gstr.TrimLeftStr("gogo我爱gogo", "go"), "我爱gogo")
|
||||
gtest.Assert(gstr.TrimLeftStr("gogo我爱gogo", "gogo我爱go"), "go")
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
gtest.Assert(gstr.TrimLeftStr("我爱中国人", "我爱"), "中国人")
|
||||
gtest.Assert(gstr.TrimLeftStr("我爱中国人", "我爱中国"), "人")
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user