parent
f9bb47b03d
commit
605ec87f65
12
cache.go
12
cache.go
|
@ -11,7 +11,9 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// default cache expired time
|
||||
CacheExpired = 60 * time.Minute
|
||||
// not use now
|
||||
CacheMaxMemory = 256
|
||||
// evey ten minutes to clear all expired nodes
|
||||
CacheGcInterval = 10 * time.Minute
|
||||
|
@ -19,12 +21,15 @@ const (
|
|||
CacheGcMaxRemoved = 20
|
||||
)
|
||||
|
||||
// CacheStore is a interface to store cache
|
||||
type CacheStore interface {
|
||||
Put(key, value interface{}) error
|
||||
Get(key interface{}) (interface{}, error)
|
||||
Del(key interface{}) error
|
||||
}
|
||||
|
||||
// MemoryStore implements CacheStore provide local machine
|
||||
// memory store
|
||||
type MemoryStore struct {
|
||||
store map[interface{}]interface{}
|
||||
mutex sync.RWMutex
|
||||
|
@ -58,6 +63,7 @@ func (s *MemoryStore) Del(key interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Cacher is an interface to provide cache
|
||||
type Cacher interface {
|
||||
GetIds(tableName, sql string) interface{}
|
||||
GetBean(tableName string, id int64) interface{}
|
||||
|
@ -122,9 +128,9 @@ func NewLRUCacher2(store CacheStore, expired time.Duration, max int) *LRUCacher
|
|||
return newLRUCacher(store, expired, 0, max)
|
||||
}
|
||||
|
||||
func NewLRUCacher3(store CacheStore, expired time.Duration, maxSize int) *LRUCacher {
|
||||
return newLRUCacher(store, expired, maxSize, 0)
|
||||
}
|
||||
//func NewLRUCacher3(store CacheStore, expired time.Duration, maxSize int) *LRUCacher {
|
||||
// return newLRUCacher(store, expired, maxSize, 0)
|
||||
//}
|
||||
|
||||
// RunGC run once every m.GcInterval
|
||||
func (m *LRUCacher) RunGC() {
|
||||
|
|
27
engine.go
27
engine.go
|
@ -361,12 +361,14 @@ func (engine *Engine) Join(join_operator, tablename, condition string) *Session
|
|||
return session.Join(join_operator, tablename, condition)
|
||||
}
|
||||
|
||||
// Generate Group By statement
|
||||
func (engine *Engine) GroupBy(keys string) *Session {
|
||||
session := engine.NewSession()
|
||||
session.IsAutoClose = true
|
||||
return session.GroupBy(keys)
|
||||
}
|
||||
|
||||
// Generate Having statement
|
||||
func (engine *Engine) Having(conditions string) *Session {
|
||||
session := engine.NewSession()
|
||||
session.IsAutoClose = true
|
||||
|
@ -763,7 +765,7 @@ func (engine *Engine) dropAll() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = session.DropAll()
|
||||
err = session.dropAll()
|
||||
if err != nil {
|
||||
session.Rollback()
|
||||
return err
|
||||
|
@ -811,64 +813,83 @@ func (engine *Engine) DropTables(beans ...interface{}) error {
|
|||
func (engine *Engine) createAll() error {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.CreateAll()
|
||||
return session.createAll()
|
||||
}
|
||||
|
||||
// Exec raw sql
|
||||
func (engine *Engine) Exec(sql string, args ...interface{}) (sql.Result, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Exec(sql, args...)
|
||||
}
|
||||
|
||||
// Exec a raw sql and return records as []map[string][]byte
|
||||
func (engine *Engine) Query(sql string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Query(sql, paramStr...)
|
||||
}
|
||||
|
||||
// Insert one or more records
|
||||
func (engine *Engine) Insert(beans ...interface{}) (int64, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Insert(beans...)
|
||||
}
|
||||
|
||||
// Insert only one record
|
||||
func (engine *Engine) InsertOne(bean interface{}) (int64, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.InsertOne(bean)
|
||||
}
|
||||
|
||||
// Update records, bean's non-empty fields are updated contents,
|
||||
// condiBean' non-empty filds are conditions
|
||||
// CAUTION:
|
||||
// 1.bool will defaultly be updated content nor conditions
|
||||
// You should call UseBool if you have bool to use.
|
||||
// 2.float32 & float64 may be not inexact as conditions
|
||||
func (engine *Engine) Update(bean interface{}, condiBeans ...interface{}) (int64, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Update(bean, condiBeans...)
|
||||
}
|
||||
|
||||
// Delete records, bean's non-empty fields are conditions
|
||||
func (engine *Engine) Delete(bean interface{}) (int64, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Delete(bean)
|
||||
}
|
||||
|
||||
// Get retrieve one record from table
|
||||
// Get retrieve one record from table, bean's non-empty fields
|
||||
// are conditions
|
||||
func (engine *Engine) Get(bean interface{}) (bool, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Get(bean)
|
||||
}
|
||||
|
||||
// Find retrieve records from table, condiBeans's non-empty fields
|
||||
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
||||
// map[int64]*Struct
|
||||
func (engine *Engine) Find(beans interface{}, condiBeans ...interface{}) error {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Find(beans, condiBeans...)
|
||||
}
|
||||
|
||||
// Iterate record by record handle records from table, bean's non-empty fields
|
||||
// are conditions.
|
||||
func (engine *Engine) Iterate(bean interface{}, fun IterFunc) error {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Iterate(bean, fun)
|
||||
}
|
||||
|
||||
// Count counts the records. bean's non-empty fields
|
||||
// are conditions.
|
||||
func (engine *Engine) Count(bean interface{}) (int64, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
|
|
|
@ -5,10 +5,12 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// Filter is an interface to filter SQL
|
||||
type Filter interface {
|
||||
Do(sql string, session *Session) string
|
||||
}
|
||||
|
||||
// PgSeqFilter filter SQL replace ?, ? ... to $1, $2 ...
|
||||
type PgSeqFilter struct {
|
||||
}
|
||||
|
||||
|
@ -25,6 +27,7 @@ func (s *PgSeqFilter) Do(sql string, session *Session) string {
|
|||
return res
|
||||
}
|
||||
|
||||
// QuoteFilter filter SQL replace ` to database's own quote character
|
||||
type QuoteFilter struct {
|
||||
}
|
||||
|
||||
|
@ -32,6 +35,7 @@ func (s *QuoteFilter) Do(sql string, session *Session) string {
|
|||
return strings.Replace(sql, "`", session.Engine.QuoteStr(), -1)
|
||||
}
|
||||
|
||||
// IdFilter filter SQL replace (id) to primary key column name
|
||||
type IdFilter struct {
|
||||
}
|
||||
|
||||
|
|
17
helpers.go
17
helpers.go
|
@ -44,3 +44,20 @@ func structName(v reflect.Type) string {
|
|||
}
|
||||
return v.Name()
|
||||
}
|
||||
|
||||
func sliceEq(left, right []string) bool {
|
||||
for _, l := range left {
|
||||
var find bool
|
||||
for _, r := range right {
|
||||
if l == r {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !find {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ type IMapper interface {
|
|||
Table2Obj(string) string
|
||||
}
|
||||
|
||||
// SameMapper implements IMapper and provides same name between struct and
|
||||
// database table
|
||||
type SameMapper struct {
|
||||
}
|
||||
|
||||
|
@ -22,6 +24,8 @@ func (m SameMapper) Table2Obj(t string) string {
|
|||
return t
|
||||
}
|
||||
|
||||
// SnakeMapper implements IMapper and provides name transaltion between
|
||||
// struct and database table
|
||||
type SnakeMapper struct {
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,8 @@ func (vs values) Get(k string) (v string) {
|
|||
return vs[k]
|
||||
}
|
||||
|
||||
type Error error
|
||||
|
||||
func errorf(s string, args ...interface{}) {
|
||||
panic(Error(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...))))
|
||||
panic(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...)))
|
||||
}
|
||||
|
||||
func parseOpts(name string, o values) {
|
||||
|
|
66
session.go
66
session.go
|
@ -94,16 +94,25 @@ func (session *Session) Cols(columns ...string) *Session {
|
|||
return session
|
||||
}
|
||||
|
||||
// Xorm automatically retrieve condition according struct, but
|
||||
// if struct has bool field, it will ignore them. So use UseBool
|
||||
// to tell system to do not ignore them.
|
||||
// If no paramters, it will use all the bool field of struct, or
|
||||
// it will use paramters's columns
|
||||
func (session *Session) UseBool(columns ...string) *Session {
|
||||
session.Statement.UseBool(columns...)
|
||||
return session
|
||||
}
|
||||
|
||||
// use for distinct columns. Caution: when you are using cache,
|
||||
// distinct will not be cached because cache system need id,
|
||||
// but distinct will not provide id
|
||||
func (session *Session) Distinct(columns ...string) *Session {
|
||||
session.Statement.Distinct(columns...)
|
||||
return session
|
||||
}
|
||||
|
||||
// Only not use the paramters as select or update columns
|
||||
func (session *Session) Omit(columns ...string) *Session {
|
||||
session.Statement.Omit(columns...)
|
||||
return session
|
||||
|
@ -163,7 +172,7 @@ func (session *Session) Charset(charset string) *Session {
|
|||
return session
|
||||
}
|
||||
|
||||
// Method Cascade
|
||||
// Method Cascade indicates if loading sub Struct
|
||||
func (session *Session) Cascade(trueOrFalse ...bool) *Session {
|
||||
if len(trueOrFalse) >= 1 {
|
||||
session.Statement.UseCascade = trueOrFalse[0]
|
||||
|
@ -184,11 +193,13 @@ func (session *Session) Join(join_operator, tablename, condition string) *Sessio
|
|||
return session
|
||||
}
|
||||
|
||||
// Generate Group By statement
|
||||
func (session *Session) GroupBy(keys string) *Session {
|
||||
session.Statement.GroupBy(keys)
|
||||
return session
|
||||
}
|
||||
|
||||
// Generate Having statement
|
||||
func (session *Session) Having(conditions string) *Session {
|
||||
session.Statement.Having(conditions)
|
||||
return session
|
||||
|
@ -205,6 +216,7 @@ func (session *Session) newDb() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Begin a transaction
|
||||
func (session *Session) Begin() error {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
|
@ -224,6 +236,7 @@ func (session *Session) Begin() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// When using transaction, you can rollback if any error
|
||||
func (session *Session) Rollback() error {
|
||||
if !session.IsAutoCommit && !session.IsCommitedOrRollbacked {
|
||||
session.Engine.LogSQL("ROLL BACK")
|
||||
|
@ -233,6 +246,7 @@ func (session *Session) Rollback() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// When using transaction, Commit will commit all operations.
|
||||
func (session *Session) Commit() error {
|
||||
if !session.IsAutoCommit && !session.IsCommitedOrRollbacked {
|
||||
session.Engine.LogSQL("COMMIT")
|
||||
|
@ -314,6 +328,7 @@ func (session *Session) exec(sql string, args ...interface{}) (sql.Result, error
|
|||
return session.Tx.Exec(sql, args...)
|
||||
}
|
||||
|
||||
// Exec raw sql
|
||||
func (session *Session) Exec(sql string, args ...interface{}) (sql.Result, error) {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
|
@ -343,6 +358,7 @@ func (session *Session) CreateTable(bean interface{}) error {
|
|||
return session.createOneTable()
|
||||
}
|
||||
|
||||
// create indexes
|
||||
func (session *Session) CreateIndexes(bean interface{}) error {
|
||||
session.Statement.RefTable = session.Engine.autoMap(bean)
|
||||
|
||||
|
@ -365,6 +381,7 @@ func (session *Session) CreateIndexes(bean interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// create uniques
|
||||
func (session *Session) CreateUniques(bean interface{}) error {
|
||||
session.Statement.RefTable = session.Engine.autoMap(bean)
|
||||
|
||||
|
@ -393,7 +410,8 @@ func (session *Session) createOneTable() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (session *Session) CreateAll() error {
|
||||
// to be deleted
|
||||
func (session *Session) createAll() error {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -413,6 +431,7 @@ func (session *Session) CreateAll() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// drop indexes
|
||||
func (session *Session) DropIndexes(bean interface{}) error {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
|
@ -700,8 +719,12 @@ func (session *Session) cacheFind(t reflect.Type, sql string, rowsSlicePtr inter
|
|||
return nil
|
||||
}
|
||||
|
||||
// IterFunc only use by Iterate
|
||||
type IterFunc func(idx int, bean interface{}) error
|
||||
|
||||
// Iterate record by record handle records from table, condiBeans's non-empty fields
|
||||
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
||||
// map[int64]*Struct
|
||||
func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
|
@ -765,7 +788,8 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// get retrieve one record from database
|
||||
// get retrieve one record from database, bean's non-empty fields
|
||||
// will be as conditions
|
||||
func (session *Session) Get(bean interface{}) (bool, error) {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
|
@ -814,6 +838,8 @@ func (session *Session) Get(bean interface{}) (bool, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Count counts the records. bean's non-empty fields
|
||||
// are conditions.
|
||||
func (session *Session) Count(bean interface{}) (int64, error) {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
|
@ -851,6 +877,9 @@ func (session *Session) Count(bean interface{}) (int64, error) {
|
|||
return int64(total), err
|
||||
}
|
||||
|
||||
// Find retrieve records from table, condiBeans's non-empty fields
|
||||
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
||||
// map[int64]*Struct
|
||||
func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) error {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
|
@ -959,7 +988,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
|||
return nil
|
||||
}
|
||||
|
||||
// test if database is ok
|
||||
// Test if database is ok
|
||||
func (session *Session) Ping() error {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
|
@ -1021,23 +1050,6 @@ func (session *Session) isIndexExist(tableName, idxName string, unique bool) (bo
|
|||
return len(results) > 0, err
|
||||
}
|
||||
|
||||
func sliceEq(left, right []string) bool {
|
||||
for _, l := range left {
|
||||
var find bool
|
||||
for _, r := range right {
|
||||
if l == r {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !find {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// find if index is exist according cols
|
||||
func (session *Session) isIndexExist2(tableName string, cols []string, unique bool) (bool, error) {
|
||||
indexes, err := session.Engine.dialect.GetIndexes(tableName)
|
||||
|
@ -1106,7 +1118,8 @@ func (session *Session) addUnique(tableName, uqeName string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (session *Session) DropAll() error {
|
||||
// To be deleted
|
||||
func (session *Session) dropAll() error {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -1240,6 +1253,7 @@ func (session *Session) query(sql string, paramStr ...interface{}) (resultsSlice
|
|||
return query(session.Db, sql, paramStr...)
|
||||
}
|
||||
|
||||
// Exec a raw sql and return records as []map[string][]byte
|
||||
func (session *Session) Query(sql string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) {
|
||||
err = session.newDb()
|
||||
if err != nil {
|
||||
|
@ -1399,6 +1413,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
|||
return res.RowsAffected()
|
||||
}
|
||||
|
||||
// Insert multiple records
|
||||
func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
|
@ -1914,6 +1929,12 @@ func (session *Session) cacheUpdate(sql string, args ...interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Update records, bean's non-empty fields are updated contents,
|
||||
// condiBean' non-empty filds are conditions
|
||||
// CAUTION:
|
||||
// 1.bool will defaultly be updated content nor conditions
|
||||
// You should call UseBool if you have bool to use.
|
||||
// 2.float32 & float64 may be not inexact as conditions
|
||||
func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int64, error) {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
|
@ -2068,6 +2089,7 @@ func (session *Session) cacheDelete(sql string, args ...interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Delete records, bean's non-empty fields are conditions
|
||||
func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
|
|
64
statement.go
64
statement.go
|
@ -9,6 +9,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// statement save all the sql info for executing SQL
|
||||
type Statement struct {
|
||||
RefTable *Table
|
||||
Engine *Engine
|
||||
|
@ -39,6 +40,7 @@ type Statement struct {
|
|||
boolColumnMap map[string]bool
|
||||
}
|
||||
|
||||
// init
|
||||
func (statement *Statement) Init() {
|
||||
statement.RefTable = nil
|
||||
statement.Start = 0
|
||||
|
@ -65,41 +67,51 @@ func (statement *Statement) Init() {
|
|||
statement.boolColumnMap = make(map[string]bool)
|
||||
}
|
||||
|
||||
func (statement *Statement) Sql(querystring string, args ...interface{}) {
|
||||
// add the raw sql statement
|
||||
func (statement *Statement) Sql(querystring string, args ...interface{}) *Statement {
|
||||
statement.RawSQL = querystring
|
||||
statement.RawParams = args
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) Where(querystring string, args ...interface{}) {
|
||||
// add Where statment
|
||||
func (statement *Statement) Where(querystring string, args ...interface{}) *Statement {
|
||||
statement.WhereStr = querystring
|
||||
statement.Params = args
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) And(querystring string, args ...interface{}) {
|
||||
// add Where & and statment
|
||||
func (statement *Statement) And(querystring string, args ...interface{}) *Statement {
|
||||
if statement.WhereStr != "" {
|
||||
statement.WhereStr = fmt.Sprintf("(%v) AND (%v)", statement.WhereStr, querystring)
|
||||
} else {
|
||||
statement.WhereStr = querystring
|
||||
}
|
||||
statement.Params = append(statement.Params, args...)
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) Or(querystring string, args ...interface{}) {
|
||||
// add Where & Or statment
|
||||
func (statement *Statement) Or(querystring string, args ...interface{}) *Statement {
|
||||
if statement.WhereStr != "" {
|
||||
statement.WhereStr = fmt.Sprintf("(%v) OR (%v)", statement.WhereStr, querystring)
|
||||
} else {
|
||||
statement.WhereStr = querystring
|
||||
}
|
||||
statement.Params = append(statement.Params, args...)
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) Table(tableNameOrBean interface{}) {
|
||||
// tempororily set table name
|
||||
func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
|
||||
t := rType(tableNameOrBean)
|
||||
if t.Kind() == reflect.String {
|
||||
statement.AltTableName = tableNameOrBean.(string)
|
||||
} else if t.Kind() == reflect.Struct {
|
||||
statement.RefTable = statement.Engine.autoMapType(t)
|
||||
}
|
||||
return statement
|
||||
}
|
||||
|
||||
// Auto generating conditions according a struct
|
||||
|
@ -225,6 +237,7 @@ func buildConditions(engine *Engine, table *Table, bean interface{}, includeVers
|
|||
return colNames, args
|
||||
}
|
||||
|
||||
// return current tableName
|
||||
func (statement *Statement) TableName() string {
|
||||
if statement.AltTableName != "" {
|
||||
return statement.AltTableName
|
||||
|
@ -236,7 +249,8 @@ func (statement *Statement) TableName() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (statement *Statement) Id(id int64) {
|
||||
// Generate "Where id = ? " statment
|
||||
func (statement *Statement) Id(id int64) *Statement {
|
||||
if statement.WhereStr == "" {
|
||||
statement.WhereStr = "(id)=?"
|
||||
statement.Params = []interface{}{id}
|
||||
|
@ -244,9 +258,11 @@ func (statement *Statement) Id(id int64) {
|
|||
statement.WhereStr = statement.WhereStr + " AND (id)=?"
|
||||
statement.Params = append(statement.Params, id)
|
||||
}
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) In(column string, args ...interface{}) {
|
||||
// Generate "Where column IN (?) " statment
|
||||
func (statement *Statement) In(column string, args ...interface{}) *Statement {
|
||||
inStr := fmt.Sprintf("%v IN (%v)", column, strings.Join(makeArray("?", len(args)), ","))
|
||||
if statement.WhereStr == "" {
|
||||
statement.WhereStr = inStr
|
||||
|
@ -255,6 +271,7 @@ func (statement *Statement) In(column string, args ...interface{}) {
|
|||
statement.WhereStr = statement.WhereStr + " AND " + inStr
|
||||
statement.Params = append(statement.Params, args...)
|
||||
}
|
||||
return statement
|
||||
}
|
||||
|
||||
func col2NewCols(columns ...string) []string {
|
||||
|
@ -270,20 +287,25 @@ func col2NewCols(columns ...string) []string {
|
|||
return newColumns
|
||||
}
|
||||
|
||||
func (statement *Statement) Distinct(columns ...string) {
|
||||
// Generate "Distince col1, col2 " statment
|
||||
func (statement *Statement) Distinct(columns ...string) *Statement {
|
||||
statement.IsDistinct = true
|
||||
statement.Cols(columns...)
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) Cols(columns ...string) {
|
||||
// Generate "col1, col2" statement
|
||||
func (statement *Statement) Cols(columns ...string) *Statement {
|
||||
newColumns := col2NewCols(columns...)
|
||||
for _, nc := range newColumns {
|
||||
statement.columnMap[nc] = true
|
||||
}
|
||||
statement.ColumnStr = statement.Engine.Quote(strings.Join(newColumns, statement.Engine.Quote(", ")))
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) UseBool(columns ...string) {
|
||||
// indicates that use bool fields as update contents and query contiditions
|
||||
func (statement *Statement) UseBool(columns ...string) *Statement {
|
||||
if len(columns) > 0 {
|
||||
newColumns := col2NewCols(columns...)
|
||||
for _, nc := range newColumns {
|
||||
|
@ -292,8 +314,10 @@ func (statement *Statement) UseBool(columns ...string) {
|
|||
} else {
|
||||
statement.allUseBool = true
|
||||
}
|
||||
return statement
|
||||
}
|
||||
|
||||
// do not use the columns
|
||||
func (statement *Statement) Omit(columns ...string) {
|
||||
newColumns := col2NewCols(columns...)
|
||||
for _, nc := range newColumns {
|
||||
|
@ -302,37 +326,47 @@ func (statement *Statement) Omit(columns ...string) {
|
|||
statement.OmitStr = statement.Engine.Quote(strings.Join(newColumns, statement.Engine.Quote(", ")))
|
||||
}
|
||||
|
||||
// Generate LIMIT limit statement
|
||||
func (statement *Statement) Top(limit int) *Statement {
|
||||
statement.Limit(limit)
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) Limit(limit int, start ...int) {
|
||||
// Generate LIMIT start, limit statement
|
||||
func (statement *Statement) Limit(limit int, start ...int) *Statement {
|
||||
statement.LimitN = limit
|
||||
if len(start) > 0 {
|
||||
statement.Start = start[0]
|
||||
}
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) OrderBy(order string) {
|
||||
// Generate "Order By order" statement
|
||||
func (statement *Statement) OrderBy(order string) *Statement {
|
||||
statement.OrderStr = order
|
||||
return statement
|
||||
}
|
||||
|
||||
//The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN
|
||||
func (statement *Statement) Join(join_operator, tablename, condition string) {
|
||||
func (statement *Statement) Join(join_operator, tablename, condition string) *Statement {
|
||||
if statement.JoinStr != "" {
|
||||
statement.JoinStr = statement.JoinStr + fmt.Sprintf("%v JOIN %v ON %v", join_operator, tablename, condition)
|
||||
} else {
|
||||
statement.JoinStr = fmt.Sprintf("%v JOIN %v ON %v", join_operator, tablename, condition)
|
||||
}
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) GroupBy(keys string) {
|
||||
// Generate "Group By keys" statement
|
||||
func (statement *Statement) GroupBy(keys string) *Statement {
|
||||
statement.GroupByStr = keys
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) Having(conditions string) {
|
||||
// Generate "Having conditions" statement
|
||||
func (statement *Statement) Having(conditions string) *Statement {
|
||||
statement.HavingStr = fmt.Sprintf("HAVING %v", conditions)
|
||||
return statement
|
||||
}
|
||||
|
||||
func (statement *Statement) genColumnStr() string {
|
||||
|
|
14
table.go
14
table.go
|
@ -6,6 +6,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// xorm SQL types
|
||||
type SQLType struct {
|
||||
Name string
|
||||
DefaultLength int
|
||||
|
@ -143,6 +144,7 @@ func Type2SQLType(t reflect.Type) (st SQLType) {
|
|||
return
|
||||
}
|
||||
|
||||
// default sql type change to go types
|
||||
func SQLType2Type(st SQLType) reflect.Type {
|
||||
name := strings.ToUpper(st.Name)
|
||||
switch name {
|
||||
|
@ -174,18 +176,21 @@ const (
|
|||
UniqueType
|
||||
)
|
||||
|
||||
// database index
|
||||
type Index struct {
|
||||
Name string
|
||||
Type int
|
||||
Cols []string
|
||||
}
|
||||
|
||||
// add columns which will be composite index
|
||||
func (index *Index) AddColumn(cols ...string) {
|
||||
for _, col := range cols {
|
||||
index.Cols = append(index.Cols, col)
|
||||
}
|
||||
}
|
||||
|
||||
// new an index
|
||||
func NewIndex(name string, indexType int) *Index {
|
||||
return &Index{name, indexType, make([]string, 0)}
|
||||
}
|
||||
|
@ -196,6 +201,7 @@ const (
|
|||
ONLYFROMDB
|
||||
)
|
||||
|
||||
// database column
|
||||
type Column struct {
|
||||
Name string
|
||||
FieldName string
|
||||
|
@ -214,6 +220,7 @@ type Column struct {
|
|||
IsVersion bool
|
||||
}
|
||||
|
||||
// generate column description string according dialect
|
||||
func (col *Column) String(d dialect) string {
|
||||
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
||||
|
||||
|
@ -240,6 +247,7 @@ func (col *Column) String(d dialect) string {
|
|||
return sql
|
||||
}
|
||||
|
||||
// return col's filed of struct's value
|
||||
func (col *Column) ValueOf(bean interface{}) reflect.Value {
|
||||
var fieldValue reflect.Value
|
||||
if strings.Contains(col.FieldName, ".") {
|
||||
|
@ -256,6 +264,7 @@ func (col *Column) ValueOf(bean interface{}) reflect.Value {
|
|||
return fieldValue
|
||||
}
|
||||
|
||||
// database table
|
||||
type Table struct {
|
||||
Name string
|
||||
Type reflect.Type
|
||||
|
@ -269,10 +278,12 @@ type Table struct {
|
|||
Cacher Cacher
|
||||
}
|
||||
|
||||
// if has primary key, return column
|
||||
func (table *Table) PKColumn() *Column {
|
||||
return table.Columns[table.PrimaryKey]
|
||||
}
|
||||
|
||||
// add a column to table
|
||||
func (table *Table) AddColumn(col *Column) {
|
||||
table.ColumnsSeq = append(table.ColumnsSeq, col.Name)
|
||||
table.Columns[col.Name] = col
|
||||
|
@ -290,6 +301,7 @@ func (table *Table) AddColumn(col *Column) {
|
|||
}
|
||||
}
|
||||
|
||||
// add an index or an unique to table
|
||||
func (table *Table) AddIndex(index *Index) {
|
||||
table.Indexes[index.Name] = index
|
||||
}
|
||||
|
@ -343,6 +355,8 @@ func (table *Table) genCols(session *Session, bean interface{}, useCol bool, inc
|
|||
return colNames, args, nil
|
||||
}
|
||||
|
||||
// Conversion is an interface. A type implements Conversion will according
|
||||
// the custom method to fill into database and retrieve from database.
|
||||
type Conversion interface {
|
||||
FromDB([]byte) error
|
||||
ToDB() ([]byte, error)
|
||||
|
|
Loading…
Reference in New Issue