Merge remote-tracking branch 'origin/master' into feature/cacher-tag
This commit is contained in:
commit
48798e566f
53
engine.go
53
engine.go
|
@ -31,13 +31,16 @@ type Engine struct {
|
||||||
mutex *sync.RWMutex
|
mutex *sync.RWMutex
|
||||||
Cacher core.Cacher
|
Cacher core.Cacher
|
||||||
|
|
||||||
|
ShowSQL bool
|
||||||
|
|
||||||
|
// !nashtsai! TODO ought to deprecate these but having logger to control its log level
|
||||||
ShowInfo bool
|
ShowInfo bool
|
||||||
ShowSQL bool
|
|
||||||
ShowErr bool
|
ShowErr bool
|
||||||
ShowDebug bool
|
ShowDebug bool
|
||||||
ShowWarn bool
|
ShowWarn bool
|
||||||
|
// --
|
||||||
|
|
||||||
Logger ILogger // io.Writer
|
Logger core.ILogger
|
||||||
TZLocation *time.Location
|
TZLocation *time.Location
|
||||||
|
|
||||||
disableGlobalCache bool
|
disableGlobalCache bool
|
||||||
|
@ -182,6 +185,7 @@ func (engine *Engine) Ping() error {
|
||||||
// logging sql
|
// logging sql
|
||||||
func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) {
|
func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) {
|
||||||
if engine.ShowSQL {
|
if engine.ShowSQL {
|
||||||
|
overrideLogLevel(LOG_INFO)
|
||||||
if len(sqlArgs) > 0 {
|
if len(sqlArgs) > 0 {
|
||||||
engine.Logger.Info(fmt.Sprintf("[sql] %v [args] %v", sqlStr, sqlArgs))
|
engine.Logger.Info(fmt.Sprintf("[sql] %v [args] %v", sqlStr, sqlArgs))
|
||||||
} else {
|
} else {
|
||||||
|
@ -215,54 +219,73 @@ func (engine *Engine) LogSQLExecutionTime(sqlStr string, args interface{}, execu
|
||||||
}
|
}
|
||||||
|
|
||||||
// logging error
|
// logging error
|
||||||
|
func (engine *Engine) overrideLogLevel(overrideLevel core.LogLevel) {
|
||||||
|
logLevel := engine.Logger.Level()
|
||||||
|
if logLevel == core.LOG_UNKNOWN {
|
||||||
|
// intend to left empty
|
||||||
|
}
|
||||||
|
else if logLevel < core.overrideLevel { // TODO can remove if deprecated engine.ShowErr
|
||||||
|
engine.Logger.SetLevel(LOG_ERR) // try override logger's log level
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (engine *Engine) LogError(contents ...interface{}) {
|
func (engine *Engine) LogError(contents ...interface{}) {
|
||||||
if engine.ShowErr {
|
if engine.ShowErr {
|
||||||
engine.Logger.Err(fmt.Sprint(contents...))
|
overrideLogLevel(LOG_ERR)
|
||||||
|
engine.Logger.Err(contents...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) LogErrorf(format string, contents ...interface{}) {
|
func (engine *Engine) LogErrorf(format string, contents ...interface{}) {
|
||||||
if engine.ShowErr {
|
if engine.ShowErr {
|
||||||
engine.Logger.Err(fmt.Sprintf(format, contents...))
|
overrideLogLevel(LOG_ERR)
|
||||||
|
engine.Logger.Errf(format, contents...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// logging info
|
// logging info
|
||||||
func (engine *Engine) LogInfo(contents ...interface{}) {
|
func (engine *Engine) LogInfo(contents ...interface{}) {
|
||||||
if engine.ShowInfo {
|
if engine.ShowInfo {
|
||||||
engine.Logger.Info(fmt.Sprint(contents...))
|
overrideLogLevel(LOG_INFO)
|
||||||
|
engine.Logger.Info(contents...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) LogInfof(format string, contents ...interface{}) {
|
func (engine *Engine) LogInfof(format string, contents ...interface{}) {
|
||||||
if engine.ShowErr {
|
if engine.ShowErr {
|
||||||
engine.Logger.Info(fmt.Sprintf(format, contents...))
|
overrideLogLevel(LOG_INFO)
|
||||||
|
engine.Logger.Infof(format, contents...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// logging debug
|
// logging debug
|
||||||
func (engine *Engine) LogDebug(contents ...interface{}) {
|
func (engine *Engine) LogDebug(contents ...interface{}) {
|
||||||
if engine.ShowDebug {
|
if engine.ShowDebug {
|
||||||
engine.Logger.Debug(fmt.Sprint(contents...))
|
overrideLogLevel(LOG_DEBUG)
|
||||||
|
engine.Logger.Debug(contents...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) LogDebugf(format string, contents ...interface{}) {
|
func (engine *Engine) LogDebugf(format string, contents ...interface{}) {
|
||||||
if engine.ShowDebug {
|
if engine.ShowDebug {
|
||||||
engine.Logger.Debug(fmt.Sprintf(format, contents...))
|
overrideLogLevel(LOG_DEBUG)
|
||||||
|
engine.Logger.Debugf(format, contents...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// logging warn
|
// logging warn
|
||||||
func (engine *Engine) LogWarn(contents ...interface{}) {
|
func (engine *Engine) LogWarn(contents ...interface{}) {
|
||||||
if engine.ShowWarn {
|
if engine.ShowWarn {
|
||||||
engine.Logger.Warning(fmt.Sprint(contents...))
|
overrideLogLevel(LOG_WARNING)
|
||||||
|
engine.Logger.Warning(contents...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) LogWarnf(format string, contents ...interface{}) {
|
func (engine *Engine) LogWarnf(format string, contents ...interface{}) {
|
||||||
if engine.ShowWarn {
|
if engine.ShowWarn {
|
||||||
engine.Logger.Warning(fmt.Sprintf(format, contents...))
|
overrideLogLevel(LOG_WARNING)
|
||||||
|
engine.Logger.Warningf(format, contents...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1467,8 +1490,16 @@ func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
|
||||||
return results, lastError
|
return results, lastError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
NULL_TIME time.Time
|
||||||
|
)
|
||||||
|
|
||||||
func (engine *Engine) TZTime(t time.Time) time.Time {
|
func (engine *Engine) TZTime(t time.Time) time.Time {
|
||||||
return t.In(engine.TZLocation)
|
|
||||||
|
if NULL_TIME != t { // if time is not initialized it's not suitable for Time.In()
|
||||||
|
return t.In(engine.TZLocation)
|
||||||
|
}
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) NowTime(sqlTypeName string) interface{} {
|
func (engine *Engine) NowTime(sqlTypeName string) interface{} {
|
||||||
|
|
96
logger.go
96
logger.go
|
@ -4,57 +4,103 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"github.com/go-xorm/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
// logger interface, log/syslog conform with this interface
|
const (
|
||||||
type ILogger interface {
|
DEFAULT_LOG_PREFIX = "[xorm]"
|
||||||
Debug(m string) (err error)
|
DEFAULT_LOG_FLAG = log.Ldate | log.Lmicroseconds
|
||||||
Err(m string) (err error)
|
DEFAULT_LOG_LEVEL = core.LOG_DEBUG
|
||||||
Info(m string) (err error)
|
)
|
||||||
Warning(m string) (err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type SimpleLogger struct {
|
type SimpleLogger struct {
|
||||||
DEBUG *log.Logger
|
DEBUG *log.Logger
|
||||||
ERR *log.Logger
|
ERR *log.Logger
|
||||||
INFO *log.Logger
|
INFO *log.Logger
|
||||||
WARN *log.Logger
|
WARN *log.Logger
|
||||||
|
level core.LogLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSimpleLogger(out io.Writer) *SimpleLogger {
|
func NewSimpleLogger(out io.Writer) *SimpleLogger {
|
||||||
return &SimpleLogger{
|
return NewSimpleLogger2(out, DEFAULT_LOG_PREFIX, DEFAULT_LOG_FLAG)
|
||||||
DEBUG: log.New(out, "[xorm] [debug] ", log.Ldate|log.Lmicroseconds),
|
|
||||||
ERR: log.New(out, "[xorm] [error] ", log.Ldate|log.Lmicroseconds),
|
|
||||||
INFO: log.New(out, "[xorm] [info] ", log.Ldate|log.Lmicroseconds),
|
|
||||||
WARN: log.New(out, "[xorm] [warn] ", log.Ldate|log.Lmicroseconds),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSimpleLogger2(out io.Writer, prefix string, flag int) *SimpleLogger {
|
func NewSimpleLogger2(out io.Writer, prefix string, flag int) *SimpleLogger {
|
||||||
|
return NewSimpleLogger3(out, prefix, flag, DEFAULT_LOG_LEVEL)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSimpleLogger3(out io.Writer, prefix string, flag int, l core.LogLevel) *SimpleLogger {
|
||||||
return &SimpleLogger{
|
return &SimpleLogger{
|
||||||
DEBUG: log.New(out, fmt.Sprintf("%s [debug] ", prefix), log.Ldate|log.Lmicroseconds),
|
DEBUG: log.New(out, fmt.Sprintf("%s [debug] ", prefix), flag),
|
||||||
ERR: log.New(out, fmt.Sprintf("%s [error] ", prefix), log.Ldate|log.Lmicroseconds),
|
ERR: log.New(out, fmt.Sprintf("%s [error] ", prefix), flag),
|
||||||
INFO: log.New(out, fmt.Sprintf("%s [info] ", prefix), log.Ldate|log.Lmicroseconds),
|
INFO: log.New(out, fmt.Sprintf("%s [info] ", prefix), flag),
|
||||||
WARN: log.New(out, fmt.Sprintf("%s [warn] ", prefix), log.Ldate|log.Lmicroseconds),
|
WARN: log.New(out, fmt.Sprintf("%s [warn] ", prefix), flag),
|
||||||
|
level: l,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SimpleLogger) Debug(m string) (err error) {
|
func (s *SimpleLogger) Err(v ...interface{}) (err error) {
|
||||||
s.DEBUG.Println(m)
|
if s.level > core.LOG_OFF && s.level <= core.LOG_ERR {
|
||||||
|
s.ERR.Println(v...)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SimpleLogger) Err(m string) (err error) {
|
func (s *SimpleLogger) Errf(format string, v ...interface{}) (err error) {
|
||||||
s.ERR.Println(m)
|
if s.level > core.LOG_OFF && s.level <= core.LOG_ERR {
|
||||||
|
s.ERR.Printf(format, v...)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SimpleLogger) Info(m string) (err error) {
|
func (s *SimpleLogger) Debug(v ...interface{}) (err error) {
|
||||||
s.INFO.Println(m)
|
if s.level > core.LOG_OFF && s.level <= core.LOG_DEBUG {
|
||||||
|
s.DEBUG.Println(v...)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SimpleLogger) Warning(m string) (err error) {
|
func (s *SimpleLogger) Debugf(format string, v ...interface{}) (err error) {
|
||||||
s.WARN.Println(m)
|
if s.level > core.LOG_OFF && s.level >= core.LOG_DEBUG {
|
||||||
|
s.DEBUG.Printf(format, v...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SimpleLogger) Info(v ...interface{}) (err error) {
|
||||||
|
if s.level > core.LOG_OFF && s.level >= core.LOG_INFO {
|
||||||
|
s.INFO.Println(v...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SimpleLogger) Infof(format string, v ...interface{}) (err error) {
|
||||||
|
if s.level > core.LOG_OFF && s.level >= core.LOG_INFO {
|
||||||
|
s.INFO.Printf(format, v...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SimpleLogger) Warning(v ...interface{}) (err error) {
|
||||||
|
if s.level > core.LOG_OFF && s.level >= core.LOG_WARNING {
|
||||||
|
s.WARN.Println(v...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SimpleLogger) Warningf(format string, v ...interface{}) (err error) {
|
||||||
|
if s.level > core.LOG_OFF && s.level >= core.LOG_WARNING {
|
||||||
|
s.WARN.Printf(format, v...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SimpleLogger) Level() core.LogLevel {
|
||||||
|
return s.level
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SimpleLogger) SetLevel(l core.LogLevel) (err error) {
|
||||||
|
s.level = l
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ type LRUCacher struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLRUCacher(store core.CacheStore, maxElementSize int) *LRUCacher {
|
func NewLRUCacher(store core.CacheStore, maxElementSize int) *LRUCacher {
|
||||||
return NewLRUCacher2(store, 0, maxElementSize)
|
return NewLRUCacher2(store, 3600*time.Second, maxElementSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLRUCacher2(store core.CacheStore, expired time.Duration, maxElementSize int) *LRUCacher {
|
func NewLRUCacher2(store core.CacheStore, expired time.Duration, maxElementSize int) *LRUCacher {
|
||||||
|
|
|
@ -56,24 +56,20 @@ func (db *mysql) SqlType(c *core.Column) string {
|
||||||
case core.Enum: //mysql enum
|
case core.Enum: //mysql enum
|
||||||
res = core.Enum
|
res = core.Enum
|
||||||
res += "("
|
res += "("
|
||||||
for v, k := range c.EnumOptions {
|
opts := ""
|
||||||
if k > 0 {
|
for v, _ := range c.EnumOptions {
|
||||||
res += fmt.Sprintf(",'%v'", v)
|
opts += fmt.Sprintf(",'%v'", v)
|
||||||
} else {
|
|
||||||
res += fmt.Sprintf("'%v'", v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
res += strings.TrimLeft(opts,",")
|
||||||
res += ")"
|
res += ")"
|
||||||
case core.Set: //mysql set
|
case core.Set: //mysql set
|
||||||
res = core.Set
|
res = core.Set
|
||||||
res += "("
|
res += "("
|
||||||
for v, k := range c.SetOptions {
|
opts := ""
|
||||||
if k > 0 {
|
for v, _ := range c.SetOptions {
|
||||||
res += fmt.Sprintf(",'%v'", v)
|
opts += fmt.Sprintf(",'%v'", v)
|
||||||
} else {
|
|
||||||
res += fmt.Sprintf("'%v'", v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
res += strings.TrimLeft(opts,",")
|
||||||
res += ")"
|
res += ")"
|
||||||
default:
|
default:
|
||||||
res = t
|
res = t
|
||||||
|
|
55
session.go
55
session.go
|
@ -219,12 +219,7 @@ func (session *Session) OrderBy(order string) *Session {
|
||||||
|
|
||||||
// Method Desc provide desc order by query condition, the input parameters are columns.
|
// Method Desc provide desc order by query condition, the input parameters are columns.
|
||||||
func (session *Session) Desc(colNames ...string) *Session {
|
func (session *Session) Desc(colNames ...string) *Session {
|
||||||
if session.Statement.OrderStr != "" {
|
session.Statement.Desc(colNames...)
|
||||||
session.Statement.OrderStr += ", "
|
|
||||||
}
|
|
||||||
newColNames := col2NewCols(colNames...)
|
|
||||||
sqlStr := strings.Join(newColNames, session.Engine.Quote(" DESC, "))
|
|
||||||
session.Statement.OrderStr += session.Engine.Quote(sqlStr) + " DESC"
|
|
||||||
return session
|
return session
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,8 +845,9 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
for j := 0; j < len(temps); j++ {
|
for j := 0; j < len(temps); j++ {
|
||||||
bean := temps[j]
|
bean := temps[j]
|
||||||
if bean == nil {
|
if bean == nil {
|
||||||
session.Engine.LogError("[xorm:cacheFind] cache error:", tableName, ides[j], bean)
|
session.Engine.LogWarn("[xorm:cacheFind] cache no hit:", tableName, ides[j])
|
||||||
return errors.New("cache error")
|
// return errors.New("cache error") // !nashtsai! no need to return error, but continue instead
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if sliceValue.Kind() == reflect.Slice {
|
if sliceValue.Kind() == reflect.Slice {
|
||||||
if t.Kind() == reflect.Ptr {
|
if t.Kind() == reflect.Ptr {
|
||||||
|
@ -1186,16 +1182,15 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for rawRows.Next() {
|
var newValue reflect.Value = newElemFunc()
|
||||||
var newValue reflect.Value = newElemFunc()
|
dataStruct := rValue(newValue.Interface())
|
||||||
if sliceValueSetFunc != nil {
|
if dataStruct.Kind() != reflect.Struct {
|
||||||
err := session.row2Bean(rawRows, fields, fieldsCount, newValue.Interface())
|
return errors.New("Expected a pointer to a struct")
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
sliceValueSetFunc(&newValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table := session.Engine.autoMapType(dataStruct)
|
||||||
|
|
||||||
|
return session.rows2Beans(rawRows, fields, fieldsCount, table, newElemFunc, sliceValueSetFunc)
|
||||||
} else {
|
} else {
|
||||||
resultsSlice, err := session.query(sqlStr, args...)
|
resultsSlice, err := session.query(sqlStr, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1452,6 +1447,24 @@ func (session *Session) getField(dataStruct *reflect.Value, key string, table *c
|
||||||
|
|
||||||
type Cell *interface{}
|
type Cell *interface{}
|
||||||
|
|
||||||
|
func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount int,
|
||||||
|
table *core.Table, newElemFunc func() reflect.Value,
|
||||||
|
sliceValueSetFunc func(*reflect.Value)) error {
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var newValue reflect.Value = newElemFunc()
|
||||||
|
bean := newValue.Interface()
|
||||||
|
dataStruct := rValue(bean)
|
||||||
|
err := session._row2Bean(rows, fields, fieldsCount, bean, &dataStruct, table)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sliceValueSetFunc(&newValue)
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}) error {
|
func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}) error {
|
||||||
dataStruct := rValue(bean)
|
dataStruct := rValue(bean)
|
||||||
if dataStruct.Kind() != reflect.Struct {
|
if dataStruct.Kind() != reflect.Struct {
|
||||||
|
@ -1459,8 +1472,12 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i
|
||||||
}
|
}
|
||||||
|
|
||||||
table := session.Engine.autoMapType(dataStruct)
|
table := session.Engine.autoMapType(dataStruct)
|
||||||
|
return session._row2Bean(rows, fields, fieldsCount, bean, &dataStruct, table)
|
||||||
|
}
|
||||||
|
|
||||||
scanResults := make([]interface{}, len(fields))
|
func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}, dataStruct *reflect.Value, table *core.Table) error {
|
||||||
|
|
||||||
|
scanResults := make([]interface{}, fieldsCount)
|
||||||
for i := 0; i < len(fields); i++ {
|
for i := 0; i < len(fields); i++ {
|
||||||
var cell interface{}
|
var cell interface{}
|
||||||
scanResults[i] = &cell
|
scanResults[i] = &cell
|
||||||
|
@ -1486,7 +1503,7 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i
|
||||||
}
|
}
|
||||||
tempMap[strings.ToLower(key)] = idx
|
tempMap[strings.ToLower(key)] = idx
|
||||||
|
|
||||||
if fieldValue := session.getField(&dataStruct, key, table, idx); fieldValue != nil {
|
if fieldValue := session.getField(dataStruct, key, table, idx); fieldValue != nil {
|
||||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii]))
|
rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii]))
|
||||||
|
|
||||||
//if row is null then ignore
|
//if row is null then ignore
|
||||||
|
|
47
statement.go
47
statement.go
|
@ -2,6 +2,7 @@ package xorm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -87,6 +88,7 @@ func (statement *Statement) Init() {
|
||||||
statement.UseAutoTime = true
|
statement.UseAutoTime = true
|
||||||
statement.IsDistinct = false
|
statement.IsDistinct = false
|
||||||
statement.allUseBool = false
|
statement.allUseBool = false
|
||||||
|
statement.useAllCols = false
|
||||||
statement.mustColumnMap = make(map[string]bool)
|
statement.mustColumnMap = make(map[string]bool)
|
||||||
statement.checkVersion = true
|
statement.checkVersion = true
|
||||||
statement.inColumns = make(map[string]*inParam)
|
statement.inColumns = make(map[string]*inParam)
|
||||||
|
@ -771,6 +773,27 @@ func col2NewCols(columns ...string) []string {
|
||||||
return newColumns
|
return newColumns
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (statement *Statement) col2NewColsWithQuote(columns ...string) []string {
|
||||||
|
newColumns := make([]string, 0)
|
||||||
|
for _, col := range columns {
|
||||||
|
strings.Replace(col, "`", "", -1)
|
||||||
|
strings.Replace(col, statement.Engine.QuoteStr(), "", -1)
|
||||||
|
ccols := strings.Split(col, ",")
|
||||||
|
for _, c := range ccols {
|
||||||
|
fields := strings.Split(strings.TrimSpace(c), ".")
|
||||||
|
if len(fields) == 1 {
|
||||||
|
newColumns = append(newColumns, statement.Engine.Quote(fields[0]))
|
||||||
|
} else if len(fields) == 2 {
|
||||||
|
newColumns = append(newColumns, statement.Engine.Quote(fields[0])+"."+
|
||||||
|
statement.Engine.Quote(fields[1]))
|
||||||
|
} else {
|
||||||
|
panic(errors.New("unwanted colnames"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newColumns
|
||||||
|
}
|
||||||
|
|
||||||
// Generate "Distince col1, col2 " statment
|
// Generate "Distince col1, col2 " statment
|
||||||
func (statement *Statement) Distinct(columns ...string) *Statement {
|
func (statement *Statement) Distinct(columns ...string) *Statement {
|
||||||
statement.IsDistinct = true
|
statement.IsDistinct = true
|
||||||
|
@ -851,10 +874,34 @@ func (statement *Statement) Limit(limit int, start ...int) *Statement {
|
||||||
|
|
||||||
// Generate "Order By order" statement
|
// Generate "Order By order" statement
|
||||||
func (statement *Statement) OrderBy(order string) *Statement {
|
func (statement *Statement) OrderBy(order string) *Statement {
|
||||||
|
if statement.OrderStr != "" {
|
||||||
|
statement.OrderStr += ", "
|
||||||
|
}
|
||||||
statement.OrderStr = order
|
statement.OrderStr = order
|
||||||
return statement
|
return statement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (statement *Statement) Desc(colNames ...string) *Statement {
|
||||||
|
if statement.OrderStr != "" {
|
||||||
|
statement.OrderStr += ", "
|
||||||
|
}
|
||||||
|
newColNames := statement.col2NewColsWithQuote(colNames...)
|
||||||
|
sqlStr := strings.Join(newColNames, " DESC, ")
|
||||||
|
statement.OrderStr += sqlStr + " DESC"
|
||||||
|
return statement
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Asc provide asc order by query condition, the input parameters are columns.
|
||||||
|
func (statement *Statement) Asc(colNames ...string) *Statement {
|
||||||
|
if statement.OrderStr != "" {
|
||||||
|
statement.OrderStr += ", "
|
||||||
|
}
|
||||||
|
newColNames := statement.col2NewColsWithQuote(colNames...)
|
||||||
|
sqlStr := strings.Join(newColNames, " ASC, ")
|
||||||
|
statement.OrderStr += sqlStr + " ASC"
|
||||||
|
return statement
|
||||||
|
}
|
||||||
|
|
||||||
//The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN
|
//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) *Statement {
|
func (statement *Statement) Join(join_operator, tablename, condition string) *Statement {
|
||||||
if statement.JoinStr != "" {
|
if statement.JoinStr != "" {
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
// +build !windows,!nacl,!plan9
|
||||||
|
|
||||||
|
package xorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log/syslog"
|
||||||
|
|
||||||
|
"github.com/go-xorm/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SyslogLogger struct {
|
||||||
|
w *syslog.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSyslogLogger(w *syslog.Writer) *SyslogLogger {
|
||||||
|
return &SyslogLogger{w: w}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyslogLogger) Debug(v ...interface{}) (err error) {
|
||||||
|
return s.w.Debug(fmt.Sprint(v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyslogLogger) Debugf(format string, v ...interface{}) (err error) {
|
||||||
|
return s.w.Debug(fmt.Sprintf(format, v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyslogLogger) Err(v ...interface{}) (err error) {
|
||||||
|
return s.w.Err(fmt.Sprint(v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyslogLogger) Errf(format string, v ...interface{}) (err error) {
|
||||||
|
return s.w.Err(fmt.Sprintf(format, v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyslogLogger) Info(v ...interface{}) (err error) {
|
||||||
|
return s.w.Info(fmt.Sprint(v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyslogLogger) Infof(format string, v ...interface{}) (err error) {
|
||||||
|
return s.w.Info(fmt.Sprintf(format, v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyslogLogger) Warning(v ...interface{}) (err error) {
|
||||||
|
return s.w.Warning(fmt.Sprint(v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyslogLogger) Warningf(format string, v ...interface{}) (err error) {
|
||||||
|
return s.w.Warning(fmt.Sprintf(format, v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyslogLogger) Level() core.LogLevel {
|
||||||
|
return core.LOG_UNKNOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLevel always return error, as current log/syslog package doesn't allow to set priority level after syslog.Writer created
|
||||||
|
func (s *SyslogLogger) SetLevel(l core.LogLevel) (err error) {
|
||||||
|
return fmt.Errorf("unable to set syslog level")
|
||||||
|
}
|
Loading…
Reference in New Issue