gorm/search.go
jnfeinstein 429a100856 Add additional methods of specifying the 'select' portion of a query.
This commit adds more ways of specifying selects:

-) You can now pass in a []string.  This is mostly for convenience,
since you may want to dynamically create a list of fields to be
selected.

-) You can now use variables.  This is important because a select
could take user input.  For example, finding a MAX between a record
and a given number could be easily done using select, and then
you don't have to process anything in backend logic.  This is also
necessary to use postgres text search capabilities (which actaully
play nicely with the rest of gorm).

-) You can now chain select calls.  This could be useful in
conjunction with gorm's scopes functionality.
2014-11-17 07:36:26 -05:00

140 lines
3.3 KiB
Go

package gorm
import "fmt"
type search struct {
db *DB
WhereConditions []map[string]interface{}
OrConditions []map[string]interface{}
NotConditions []map[string]interface{}
InitAttrs []interface{}
AssignAttrs []interface{}
HavingCondition map[string]interface{}
Orders []string
Joins string
Selects []map[string]interface{}
Offset string
Limit string
Group string
TableName string
Unscope bool
Raw bool
}
func (s *search) clone() *search {
return &search{
WhereConditions: s.WhereConditions,
OrConditions: s.OrConditions,
NotConditions: s.NotConditions,
InitAttrs: s.InitAttrs,
AssignAttrs: s.AssignAttrs,
HavingCondition: s.HavingCondition,
Orders: s.Orders,
Selects: s.Selects,
Offset: s.Offset,
Limit: s.Limit,
Unscope: s.Unscope,
Group: s.Group,
Joins: s.Joins,
TableName: s.TableName,
Raw: s.Raw,
}
}
func (s *search) where(query interface{}, values ...interface{}) *search {
s.WhereConditions = append(s.WhereConditions, map[string]interface{}{"query": query, "args": values})
return s
}
func (s *search) not(query interface{}, values ...interface{}) *search {
s.NotConditions = append(s.NotConditions, map[string]interface{}{"query": query, "args": values})
return s
}
func (s *search) or(query interface{}, values ...interface{}) *search {
s.OrConditions = append(s.OrConditions, map[string]interface{}{"query": query, "args": values})
return s
}
func (s *search) attrs(attrs ...interface{}) *search {
s.InitAttrs = append(s.InitAttrs, toSearchableMap(attrs...))
return s
}
func (s *search) assign(attrs ...interface{}) *search {
s.AssignAttrs = append(s.AssignAttrs, toSearchableMap(attrs...))
return s
}
func (s *search) order(value string, reorder ...bool) *search {
if len(reorder) > 0 && reorder[0] {
s.Orders = []string{value}
} else {
s.Orders = append(s.Orders, value)
}
return s
}
func (s *search) selects(query interface{}, args ...interface{}) *search {
s.Selects = append(s.Selects, map[string]interface{}{"query": query, "args": args})
return s
}
func (s *search) limit(value interface{}) *search {
s.Limit = s.getInterfaceAsSql(value)
return s
}
func (s *search) offset(value interface{}) *search {
s.Offset = s.getInterfaceAsSql(value)
return s
}
func (s *search) group(query string) *search {
s.Group = s.getInterfaceAsSql(query)
return s
}
func (s *search) having(query string, values ...interface{}) *search {
s.HavingCondition = map[string]interface{}{"query": query, "args": values}
return s
}
func (s *search) includes(value interface{}) *search {
return s
}
func (s *search) joins(query string) *search {
s.Joins = query
return s
}
func (s *search) raw(b bool) *search {
s.Raw = b
return s
}
func (s *search) unscoped() *search {
s.Unscope = true
return s
}
func (s *search) table(name string) *search {
s.TableName = name
return s
}
func (s *search) getInterfaceAsSql(value interface{}) (str string) {
switch value.(type) {
case string, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
str = fmt.Sprintf("%v", value)
default:
s.db.err(InvalidSql)
}
if str == "-1" {
return ""
}
return
}