From f2ff39264f331ebcfd5f5f24fc44a92e121ed85d Mon Sep 17 00:00:00 2001 From: hzmnet Date: Thu, 25 Jun 2015 03:23:36 +0800 Subject: [PATCH 1/9] add INHERITS add INHERITS --- engine.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/engine.go b/engine.go index 4081ec14..690f4288 100644 --- a/engine.go +++ b/engine.go @@ -751,6 +751,16 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table { if tags[0] == "-" { continue } + + // by hzm + if strings.ToUpper(tags[0]) == "INHERITS" { + engine.LogInfo(tags[0]) + if fieldValue.Kind() == reflect.Struct { + table.AddInherit(engine.TableMapper.Obj2Table(fieldType.Name())) + } + continue + } + if strings.ToUpper(tags[0]) == "EXTENDS" { if fieldValue.Kind() == reflect.Struct { parentTable := engine.mapType(fieldValue) From 4cc9187876cbdb7b3c1f2364aec157dc66abdfe8 Mon Sep 17 00:00:00 2001 From: hzmnet Date: Mon, 29 Jun 2015 00:20:31 +0800 Subject: [PATCH 2/9] Cols("*") error when my code Cols("*") it will Gen. Sql like SELECT "*" FROM. it is no work in postgresql. --- statement.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/statement.go b/statement.go index 0a8de1ee..66ced20f 100644 --- a/statement.go +++ b/statement.go @@ -49,7 +49,7 @@ type Statement struct { GroupByStr string HavingStr string ColumnStr string - selectStr string + selectStr string columnMap map[string]bool useAllCols bool OmitStr string @@ -416,7 +416,7 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{}, var colName string if addedTableName { - colName = engine.Quote(tableName)+"."+engine.Quote(col.Name) + colName = engine.Quote(tableName) + "." + engine.Quote(col.Name) } else { colName = engine.Quote(col.Name) } @@ -428,7 +428,7 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{}, } if col.IsDeleted && !unscoped { // tag "deleted" is enabled - colNames = append(colNames, fmt.Sprintf("(%v IS NULL or %v = '0001-01-01 00:00:00')", + colNames = append(colNames, fmt.Sprintf("(%v IS NULL or %v = '0001-01-01 00:00:00')", colName, colName)) } @@ -782,7 +782,15 @@ func (statement *Statement) Cols(columns ...string) *Statement { for _, nc := range newColumns { statement.columnMap[strings.ToLower(nc)] = true } - statement.ColumnStr = statement.Engine.Quote(strings.Join(newColumns, statement.Engine.Quote(", "))) + + // by hzm + if len(newColumns) == 1 { + statement.ColumnStr = newColumns + + } else { + statement.ColumnStr = statement.Engine.Quote(strings.Join(newColumns, statement.Engine.Quote(", "))) + } + if strings.Contains(statement.ColumnStr, ".") { statement.ColumnStr = strings.Replace(statement.ColumnStr, ".", statement.Engine.Quote("."), -1) } From 36b2721255a3089af2596d166ab91ab655c9caf3 Mon Sep 17 00:00:00 2001 From: hzmnet Date: Mon, 29 Jun 2015 00:40:20 +0800 Subject: [PATCH 3/9] change --- statement.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/statement.go b/statement.go index 66ced20f..951ddf05 100644 --- a/statement.go +++ b/statement.go @@ -785,7 +785,7 @@ func (statement *Statement) Cols(columns ...string) *Statement { // by hzm if len(newColumns) == 1 { - statement.ColumnStr = newColumns + statement.ColumnStr = newColumns[0] } else { statement.ColumnStr = statement.Engine.Quote(strings.Join(newColumns, statement.Engine.Quote(", "))) From e6d380aaecc331c4df1e040b054e3656955de640 Mon Sep 17 00:00:00 2001 From: hzmnet Date: Mon, 29 Jun 2015 22:45:14 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=A7=E6=89=BF?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E6=98=A0=E5=B0=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改继承无法映射问题 --- engine.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/engine.go b/engine.go index 690f4288..dd18fdf5 100644 --- a/engine.go +++ b/engine.go @@ -756,6 +756,12 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table { if strings.ToUpper(tags[0]) == "INHERITS" { engine.LogInfo(tags[0]) if fieldValue.Kind() == reflect.Struct { + // 保留为了Find()映射数据 + parentTable := engine.mapType(fieldValue) + for _, col := range parentTable.Columns() { + col.FieldName = fmt.Sprintf("%v.%v", t.Field(i).Name, col.FieldName) + table.AddColumn(col) + } table.AddInherit(engine.TableMapper.Obj2Table(fieldType.Name())) } continue From 24f47dd41d7cf4a66bacb72ca938aef677df30b4 Mon Sep 17 00:00:00 2001 From: hzmnet Date: Mon, 2 Nov 2015 18:30:05 +0800 Subject: [PATCH 5/9] Add FindMap --- session.go | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/session.go b/session.go index a1984805..b798a354 100644 --- a/session.go +++ b/session.go @@ -1368,6 +1368,117 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) return nil } + +func (session *Session) FindMap(rowsSlicePtr interface{}, condiBean ...interface{}) error { + defer session.resetStatement() + if session.IsAutoClose { + defer session.Close() + } + + sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) + if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map { + return errors.New("needs a pointer to a slice or a map") + } + + sliceElementType := sliceValue.Type().Elem() + fmt.Println("sliceValue.Kind()", sliceValue.Kind(), sliceElementType) + + fmt.Println("sliceValue.Kind()") + /* + if len(condiBean) > 0 { + colNames, args := buildConditions(session.Engine, table, condiBean[0], true, true, + false, true, session.Statement.allUseBool, session.Statement.useAllCols, + session.Statement.unscoped, session.Statement.mustColumnMap) + session.Statement.ConditionStr = strings.Join(colNames, " AND ") + session.Statement.BeanArgs = args + } else { + // !oinume! Add " IS NULL" to WHERE whatever condiBean is given. + // See https://github.com/go-xorm/xorm/issues/179 + if col := table.DeletedColumn(); col != nil && !session.Statement.unscoped { // tag "deleted" is enabled + session.Statement.ConditionStr = fmt.Sprintf("(%v IS NULL or %v = '0001-01-01 00:00:00') ", + session.Engine.Quote(col.Name), session.Engine.Quote(col.Name)) + } + }*/ + fmt.Println("sliceValue.Kind()") + var sqlStr string + var args []interface{} + if session.Statement.RawSQL == "" { + var columnStr string = session.Statement.ColumnStr + if session.Statement.JoinStr == "" { + if columnStr == "" { + if session.Statement.GroupByStr != "" { + columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1)) + } else { + columnStr = session.Statement.genColumnStr() + } + } + } else { + if columnStr == "" { + if session.Statement.GroupByStr != "" { + columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1)) + } else { + columnStr = "*" + } + } + } + + session.Statement.attachInSql() + + sqlStr = session.Statement.genSelectSql(columnStr) + args = append(session.Statement.Params, session.Statement.BeanArgs...) + // for mssql and use limit + qs := strings.Count(sqlStr, "?") + if len(args)*2 == qs { + args = append(args, args...) + } + } else { + sqlStr = session.Statement.RawSQL + args = session.Statement.RawParams + } + fmt.Println("sliceValue.Kind()") + // var err error + /* + if session.Statement.JoinStr == "" { + if cacher := session.Engine.getCacher2(table); cacher != nil && + session.Statement.UseCache && + !session.Statement.IsDistinct && + !session.Statement.unscoped { + err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...) + if err != ErrCacheFailed { + return err + } + err = nil // !nashtsai! reset err to nil for ErrCacheFailed + session.Engine.LogWarn("Cache Find Failed") + } + } + */ + + fmt.Println("sliceValue.Kind()", sliceValue.Kind()) + if sliceValue.Kind() != reflect.Map { + fmt.Println("sliceValue.Type()", sliceValue.Index(0).Type(), reflect.TypeOf(make(map[string]interface{})).Name()) + + if sliceValue.Index(0).Type() == reflect.TypeOf(make(map[string][]byte)) { + fmt.Println("sliceValue.Type()OK") + resultsSlice, err := session.query(sqlStr, args...) + if err != nil { + fmt.Println("sliceValue.Type()err", err.Error()) + return err + } + + for _, results := range resultsSlice { + fmt.Println("sliceValue.Type()OK", results) + sliceValue.Set(reflect.Append(sliceValue, reflect.Indirect(reflect.ValueOf(results)))) + } + + } else { + fmt.Println("sliceValue.Index(0).Type() == reflect.TypeOf(make(map[string]interface{}))") + } + } else { + fmt.Println("sliceValue.Kind() != reflect.Map") + } + return nil +} + // func (session *Session) queryRows(rawStmt **sql.Stmt, rawRows **sql.Rows, sqlStr string, args ...interface{}) error { // var err error // if session.IsAutoCommit { From 54996fd3c7826b3268202a60e9b0c2da00ccae05 Mon Sep 17 00:00:00 2001 From: hzmnet Date: Tue, 3 Nov 2015 00:32:19 +0800 Subject: [PATCH 6/9] query return map[string]string --- session.go | 538 +++++++++++++++++++++++++++++------------------------ 1 file changed, 296 insertions(+), 242 deletions(-) diff --git a/session.go b/session.go index b798a354..11f72b2f 100644 --- a/session.go +++ b/session.go @@ -1,7 +1,3 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - package xorm import ( @@ -49,8 +45,8 @@ type Session struct { // Method Init reset the session as the init status. func (session *Session) Init() { + session.Statement = Statement{Engine: session.Engine} session.Statement.Init() - session.Statement.Engine = session.Engine session.IsAutoCommit = true session.IsCommitedOrRollbacked = false session.IsAutoClose = false @@ -71,15 +67,11 @@ func (session *Session) Close() { } if session.db != nil { - // When Close be called, if session is a transaction and do not call - // Commit or Rollback, then call Rollback. - if session.Tx != nil && !session.IsCommitedOrRollbacked { - session.Rollback() - } + //session.Engine.Pool.ReleaseDB(session.Engine, session.Db) + session.db = nil session.Tx = nil session.stmtCache = nil session.Init() - session.db = nil } } @@ -172,12 +164,6 @@ func (session *Session) SetExpr(column string, expression string) *Session { return session } -// Method Cols provides some columns to special -func (session *Session) Select(str string) *Session { - session.Statement.Select(str) - return session -} - // Method Cols provides some columns to special func (session *Session) Cols(columns ...string) *Session { session.Statement.Cols(columns...) @@ -223,12 +209,6 @@ func (session *Session) Omit(columns ...string) *Session { return session } -// Set null when column is zero-value and nullable for update -func (session *Session) Nullable(columns ...string) *Session { - session.Statement.Nullable(columns...) - return session -} - // Method NoAutoTime means do not automatically give created field and updated field // the current time on the current session temporarily func (session *Session) NoAutoTime() *Session { @@ -633,20 +613,11 @@ func (statement *Statement) convertIdSql(sqlStr string) string { return "" } -func (session *Session) canCache() bool { - if session.Statement.RefTable == nil || - session.Statement.JoinStr != "" || - session.Statement.RawSQL != "" || - session.Tx != nil || - len(session.Statement.selectStr) > 0 { - return false - } - return true -} - func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interface{}) (has bool, err error) { // if has no reftable, then don't use cache currently - if !session.canCache() { + if session.Statement.RefTable == nil || + session.Statement.JoinStr != "" || + session.Statement.RawSQL != "" { return false, ErrCacheFailed } @@ -744,7 +715,7 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf } func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr interface{}, args ...interface{}) (err error) { - if !session.canCache() || + if session.Statement.RefTable == nil || indexNoCase(sqlStr, "having") != -1 || indexNoCase(sqlStr, "group by") != -1 { return ErrCacheFailed @@ -888,7 +859,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in } temps[ididxes[sid]] = bean - session.Engine.LogDebug("[cacheFind] cache bean:", tableName, id, bean, temps) + session.Engine.LogDebug("[cacheFind] cache bean:", tableName, id, bean) cacher.PutBean(tableName, sid, bean) } } @@ -896,7 +867,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in for j := 0; j < len(temps); j++ { bean := temps[j] if bean == nil { - session.Engine.LogWarn("[cacheFind] cache no hit:", tableName, ids[j], temps) + session.Engine.LogWarn("[cacheFind] cache no hit:", tableName, ides[j]) // return errors.New("cache error") // !nashtsai! no need to return error, but continue instead continue } @@ -1021,9 +992,9 @@ func (session *Session) Get(bean interface{}) (bool, error) { var err error session.queryPreprocess(&sqlStr, args...) if session.IsAutoCommit { - stmt, errPrepare := session.doPrepare(sqlStr) - if errPrepare != nil { - return false, errPrepare + stmt, err := session.doPrepare(sqlStr) + if err != nil { + return false, err } // defer stmt.Close() // !nashtsai! don't close due to stmt is cached and bounded to this session rawRows, err = stmt.Query(args...) @@ -1148,10 +1119,7 @@ func Atot(s string, tp reflect.Type) (interface{}, error) { return result, nil } -// 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 { +func (session *Session) FindMap(rowsSlicePtr interface{}, condiBean ...interface{}) error { defer session.resetStatement() if session.IsAutoClose { defer session.Close() @@ -1163,65 +1131,43 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) } sliceElementType := sliceValue.Type().Elem() - var table *core.Table - if session.Statement.RefTable == nil { - if sliceElementType.Kind() == reflect.Ptr { - if sliceElementType.Elem().Kind() == reflect.Struct { - pv := reflect.New(sliceElementType.Elem()) - table = session.Engine.autoMapType(pv.Elem()) - } else { - return errors.New("slice type") - } - } else if sliceElementType.Kind() == reflect.Struct { - pv := reflect.New(sliceElementType) - table = session.Engine.autoMapType(pv.Elem()) + //fmt.Println("sliceValue.Kind()", sliceValue.Kind(), sliceElementType) + + //fmt.Println("sliceValue.Kind()") + /* + if len(condiBean) > 0 { + colNames, args := buildConditions(session.Engine, table, condiBean[0], true, true, + false, true, session.Statement.allUseBool, session.Statement.useAllCols, + session.Statement.unscoped, session.Statement.mustColumnMap) + session.Statement.ConditionStr = strings.Join(colNames, " AND ") + session.Statement.BeanArgs = args } else { - return errors.New("slice type") - } - session.Statement.RefTable = table - } else { - table = session.Statement.RefTable - } - - if len(condiBean) > 0 { - var addedTableName = (len(session.Statement.JoinStr) > 0) - colNames, args := buildConditions(session.Engine, table, condiBean[0], true, true, - false, true, session.Statement.allUseBool, session.Statement.useAllCols, - session.Statement.unscoped, session.Statement.mustColumnMap, - session.Statement.TableName(), addedTableName) - session.Statement.ConditionStr = strings.Join(colNames, " AND ") - session.Statement.BeanArgs = args - } else { - // !oinume! Add " IS NULL" to WHERE whatever condiBean is given. - // See https://github.com/go-xorm/xorm/issues/179 - if col := table.DeletedColumn(); col != nil && !session.Statement.unscoped { // tag "deleted" is enabled - session.Statement.ConditionStr = fmt.Sprintf("(%v IS NULL or %v = '0001-01-01 00:00:00') ", - session.Engine.Quote(col.Name), session.Engine.Quote(col.Name)) - } - } - + // !oinume! Add " IS NULL" to WHERE whatever condiBean is given. + // See https://github.com/go-xorm/xorm/issues/179 + if col := table.DeletedColumn(); col != nil && !session.Statement.unscoped { // tag "deleted" is enabled + session.Statement.ConditionStr = fmt.Sprintf("(%v IS NULL or %v = '0001-01-01 00:00:00') ", + session.Engine.Quote(col.Name), session.Engine.Quote(col.Name)) + } + }*/ + //fmt.Println("sliceValue.Kind()") var sqlStr string var args []interface{} if session.Statement.RawSQL == "" { var columnStr string = session.Statement.ColumnStr - if len(session.Statement.selectStr) > 0 { - columnStr = session.Statement.selectStr - } else { - if session.Statement.JoinStr == "" { - if columnStr == "" { - if session.Statement.GroupByStr != "" { - columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1)) - } else { - columnStr = session.Statement.genColumnStr() - } + if session.Statement.JoinStr == "" { + if columnStr == "" { + if session.Statement.GroupByStr != "" { + columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1)) + } else { + columnStr = session.Statement.genColumnStr() } - } else { - if columnStr == "" { - if session.Statement.GroupByStr != "" { - columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1)) - } else { - columnStr = "*" - } + } + } else { + if columnStr == "" { + if session.Statement.GroupByStr != "" { + columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1)) + } else { + columnStr = "*" } } } @@ -1239,7 +1185,182 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) sqlStr = session.Statement.RawSQL args = session.Statement.RawParams } + //fmt.Println("sliceValue.Kind()") + // var err error + /* + if session.Statement.JoinStr == "" { + if cacher := session.Engine.getCacher2(table); cacher != nil && + session.Statement.UseCache && + !session.Statement.IsDistinct && + !session.Statement.unscoped { + err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...) + if err != ErrCacheFailed { + return err + } + err = nil // !nashtsai! reset err to nil for ErrCacheFailed + session.Engine.LogWarn("Cache Find Failed") + } + } + */ + //fmt.Println("sliceValue.Kind()", sliceValue.Kind()) + if sliceValue.Kind() != reflect.Map { + fmt.Println("sliceValue.Type()", sliceValue.Type(), reflect.TypeOf(make(map[string]interface{})).Name()) + + if sliceElementType == reflect.TypeOf(make(map[string]interface{})) { + //fmt.Println("sliceValue.Type()OK") + resultsSlice, err := session.queryX(sqlStr, args...) + if err != nil { + fmt.Println("sliceValue.Type()err", err.Error()) + return err + } + + for _, results := range resultsSlice { + //fmt.Println("sliceValue.Type()OK", results) + lRec := make(map[string]interface{}) + for key, val := range results { + lRec[key] = val + /* + lValPr := reflect.Indirect(reflect.ValueOf(val)) + lVal := reflect.ValueOf(lValPr.Interface()) + fmt.Println(key, lVal.Type()) + switch reflect.TypeOf(val).Kind() { + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + //str = strconv.FormatInt(lVal.Int(), 10) + lRec[key] = lVal.Int() + fmt.Println(key, lVal.Int()) + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + //str = strconv.FormatUint(lVal.Uint(), 10) + lRec[key] = lVal.Uint() + fmt.Println(key, lVal.Uint()) + case reflect.Float32, reflect.Float64: + //str = strconv.FormatFloat(lVal.Float(), 'f', -1, 64) + lRec[key] = lVal.Float() + fmt.Println(key, lVal.Float()) + case reflect.Slice: + + fmt.Println(key, lVal) + /*if lVal.Elem().Kind() == reflect.Uint8 { + // result[key] = string(reflect.ValueOf(val).Interface().([]byte)) + // fmt.Println(key, aa.Kind()) + break + }*/ + /* + case reflect.String: + //str = lVal.String() + lRec[key] = lVal.String() + fmt.Println(key, lVal.String()) + //时间类型 + case reflect.Struct: + if val, ok := lVal.Interface().(time.Time); ok { + lRec[key] = val //lVal.Interface().(time.Time) + fmt.Println(key, val, lVal.Interface().(time.Time)) + } + + default: + fmt.Println(key, lVal.Kind()) + } + */ + } + sliceValue.Set(reflect.Append(sliceValue, reflect.Indirect(reflect.ValueOf(lRec)))) + } + + } else { + fmt.Println("sliceValue.Index(0).Type() == reflect.TypeOf(make(map[string]interface{}))") + } + } else { + fmt.Println("sliceValue.Kind() != reflect.Map") + } + return nil +} + +// 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 { + defer session.resetStatement() + if session.IsAutoClose { + defer session.Close() + } + + sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) + if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map { + return errors.New("needs a pointer to a slice or a map") + } + + sliceElementType := sliceValue.Type().Elem() + + var table *core.Table + if session.Statement.RefTable == nil { + if sliceElementType.Kind() == reflect.Ptr { + if sliceElementType.Elem().Kind() == reflect.Struct { + pv := reflect.New(sliceElementType.Elem()) + table = session.Engine.autoMapType(pv.Elem()) + } else { + + } + } else if sliceElementType.Kind() == reflect.Struct { + pv := reflect.New(sliceElementType) + table = session.Engine.autoMapType(pv.Elem()) + } else { + return errors.New("slice type") + } + session.Statement.RefTable = table + } else { + table = session.Statement.RefTable + } + fmt.Println("sliceValue.Kind()") + if len(condiBean) > 0 { + colNames, args := buildConditions(session.Engine, table, condiBean[0], true, true, + false, true, session.Statement.allUseBool, session.Statement.useAllCols, + session.Statement.unscoped, session.Statement.mustColumnMap) + session.Statement.ConditionStr = strings.Join(colNames, " AND ") + session.Statement.BeanArgs = args + } else { + // !oinume! Add " IS NULL" to WHERE whatever condiBean is given. + // See https://github.com/go-xorm/xorm/issues/179 + if col := table.DeletedColumn(); col != nil && !session.Statement.unscoped { // tag "deleted" is enabled + session.Statement.ConditionStr = fmt.Sprintf("(%v IS NULL or %v = '0001-01-01 00:00:00') ", + session.Engine.Quote(col.Name), session.Engine.Quote(col.Name)) + } + } + fmt.Println("sliceValue.Kind()") + var sqlStr string + var args []interface{} + if session.Statement.RawSQL == "" { + var columnStr string = session.Statement.ColumnStr + if session.Statement.JoinStr == "" { + if columnStr == "" { + if session.Statement.GroupByStr != "" { + columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1)) + } else { + columnStr = session.Statement.genColumnStr() + } + } + } else { + if columnStr == "" { + if session.Statement.GroupByStr != "" { + columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1)) + } else { + columnStr = "*" + } + } + } + + session.Statement.attachInSql() + + sqlStr = session.Statement.genSelectSql(columnStr) + args = append(session.Statement.Params, session.Statement.BeanArgs...) + // for mssql and use limit + qs := strings.Count(sqlStr, "?") + if len(args)*2 == qs { + args = append(args, args...) + } + } else { + sqlStr = session.Statement.RawSQL + args = session.Statement.RawParams + } + fmt.Println("sliceValue.Kind()") var err error if session.Statement.JoinStr == "" { if cacher := session.Engine.getCacher2(table); cacher != nil && @@ -1255,7 +1376,9 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) } } + fmt.Println("sliceValue.Kind()", sliceValue.Kind()) if sliceValue.Kind() != reflect.Map { + var rawRows *core.Rows var stmt *core.Stmt @@ -1316,6 +1439,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) table := session.Engine.autoMapType(dataStruct) return session.rows2Beans(rawRows, fields, fieldsCount, table, newElemFunc, sliceValueSetFunc) + } else { resultsSlice, err := session.query(sqlStr, args...) if err != nil { @@ -1331,6 +1455,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) } else { newValue = reflect.New(sliceElementType) } + err := session.scanMapIntoStruct(newValue.Interface(), results) if err != nil { return err @@ -1364,117 +1489,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) sliceValue.SetMapIndex(reflect.ValueOf(key), reflect.Indirect(reflect.ValueOf(newValue.Interface()))) } } - } - return nil -} - -func (session *Session) FindMap(rowsSlicePtr interface{}, condiBean ...interface{}) error { - defer session.resetStatement() - if session.IsAutoClose { - defer session.Close() - } - - sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) - if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map { - return errors.New("needs a pointer to a slice or a map") - } - - sliceElementType := sliceValue.Type().Elem() - fmt.Println("sliceValue.Kind()", sliceValue.Kind(), sliceElementType) - - fmt.Println("sliceValue.Kind()") - /* - if len(condiBean) > 0 { - colNames, args := buildConditions(session.Engine, table, condiBean[0], true, true, - false, true, session.Statement.allUseBool, session.Statement.useAllCols, - session.Statement.unscoped, session.Statement.mustColumnMap) - session.Statement.ConditionStr = strings.Join(colNames, " AND ") - session.Statement.BeanArgs = args - } else { - // !oinume! Add " IS NULL" to WHERE whatever condiBean is given. - // See https://github.com/go-xorm/xorm/issues/179 - if col := table.DeletedColumn(); col != nil && !session.Statement.unscoped { // tag "deleted" is enabled - session.Statement.ConditionStr = fmt.Sprintf("(%v IS NULL or %v = '0001-01-01 00:00:00') ", - session.Engine.Quote(col.Name), session.Engine.Quote(col.Name)) - } - }*/ - fmt.Println("sliceValue.Kind()") - var sqlStr string - var args []interface{} - if session.Statement.RawSQL == "" { - var columnStr string = session.Statement.ColumnStr - if session.Statement.JoinStr == "" { - if columnStr == "" { - if session.Statement.GroupByStr != "" { - columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1)) - } else { - columnStr = session.Statement.genColumnStr() - } - } - } else { - if columnStr == "" { - if session.Statement.GroupByStr != "" { - columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1)) - } else { - columnStr = "*" - } - } - } - - session.Statement.attachInSql() - - sqlStr = session.Statement.genSelectSql(columnStr) - args = append(session.Statement.Params, session.Statement.BeanArgs...) - // for mssql and use limit - qs := strings.Count(sqlStr, "?") - if len(args)*2 == qs { - args = append(args, args...) - } - } else { - sqlStr = session.Statement.RawSQL - args = session.Statement.RawParams - } - fmt.Println("sliceValue.Kind()") - // var err error - /* - if session.Statement.JoinStr == "" { - if cacher := session.Engine.getCacher2(table); cacher != nil && - session.Statement.UseCache && - !session.Statement.IsDistinct && - !session.Statement.unscoped { - err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...) - if err != ErrCacheFailed { - return err - } - err = nil // !nashtsai! reset err to nil for ErrCacheFailed - session.Engine.LogWarn("Cache Find Failed") - } - } - */ - - fmt.Println("sliceValue.Kind()", sliceValue.Kind()) - if sliceValue.Kind() != reflect.Map { - fmt.Println("sliceValue.Type()", sliceValue.Index(0).Type(), reflect.TypeOf(make(map[string]interface{})).Name()) - - if sliceValue.Index(0).Type() == reflect.TypeOf(make(map[string][]byte)) { - fmt.Println("sliceValue.Type()OK") - resultsSlice, err := session.query(sqlStr, args...) - if err != nil { - fmt.Println("sliceValue.Type()err", err.Error()) - return err - } - - for _, results := range resultsSlice { - fmt.Println("sliceValue.Type()OK", results) - sliceValue.Set(reflect.Append(sliceValue, reflect.Indirect(reflect.ValueOf(results)))) - } - - } else { - fmt.Println("sliceValue.Index(0).Type() == reflect.TypeOf(make(map[string]interface{}))") - } - } else { - fmt.Println("sliceValue.Kind() != reflect.Map") } return nil } @@ -2083,6 +2098,48 @@ func (session *Session) txQuery(tx *core.Tx, sqlStr string, params ...interface{ return rows2maps(rows) } +func (session *Session) queryX(sqlStr string, paramStr ...interface{}) (resultsSlice []map[string]string, err error) { + + session.queryPreprocess(&sqlStr, paramStr...) + + if session.IsAutoCommit { + return session.innerQuery2(session.DB(), sqlStr, paramStr...) + } + return session.txQuery2(session.Tx, sqlStr, paramStr...) +} + +func (session *Session) txQuery2(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string]string, err error) { + rows, err := tx.Query(sqlStr, params...) + if err != nil { + return nil, err + } + defer rows.Close() + + return rows2Strings(rows) +} + +func (session *Session) innerQuery2(db *core.DB, sqlStr string, params ...interface{}) (resultsSlice []map[string]string, err error) { + stmt, rows, err := session.Engine.LogSQLQueryTime(sqlStr, params, func() (*core.Stmt, *core.Rows, error) { + stmt, err := db.Prepare(sqlStr) + if err != nil { + return stmt, nil, err + } + rows, err := stmt.Query(params...) + + return stmt, rows, err + }) + if rows != nil { + defer rows.Close() + } + if stmt != nil { + defer stmt.Close() + } + if err != nil { + return nil, err + } + return rows2Strings(rows) +} + func (session *Session) innerQuery(db *core.DB, sqlStr string, params ...interface{}) (resultsSlice []map[string][]byte, err error) { stmt, rows, err := session.Engine.LogSQLQueryTime(sqlStr, params, func() (*core.Stmt, *core.Rows, error) { stmt, err := db.Prepare(sqlStr) @@ -2498,6 +2555,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value, } else { x = 0 } + //fmt.Println("######", x, data) } else if strings.HasPrefix(sdata, "0x") { x, err = strconv.ParseInt(sdata, 16, 64) } else if strings.HasPrefix(sdata, "0") { @@ -2746,6 +2804,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value, } else { x = 0 } + //fmt.Println("######", x, data) } else if strings.HasPrefix(sdata, "0x") { x, err = strconv.ParseInt(sdata, 16, 64) } else if strings.HasPrefix(sdata, "0") { @@ -2771,6 +2830,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value, } else { x = 0 } + //fmt.Println("######", x, data) } else if strings.HasPrefix(sdata, "0x") { x1, err = strconv.ParseInt(sdata, 16, 64) x = int(x1) @@ -2799,6 +2859,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value, } else { x = 0 } + //fmt.Println("######", x, data) } else if strings.HasPrefix(sdata, "0x") { x1, err = strconv.ParseInt(sdata, 16, 64) x = int32(x1) @@ -2827,6 +2888,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value, } else { x = 0 } + //fmt.Println("######", x, data) } else if strings.HasPrefix(sdata, "0x") { x1, err = strconv.ParseInt(sdata, 16, 64) x = int8(x1) @@ -2855,6 +2917,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value, } else { x = 0 } + //fmt.Println("######", x, data) } else if strings.HasPrefix(sdata, "0x") { x1, err = strconv.ParseInt(sdata, 16, 64) x = int16(x1) @@ -3032,15 +3095,20 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val case reflect.String: return fieldValue.String(), nil case reflect.Struct: - if fieldType.ConvertibleTo(core.TimeType) { - t := fieldValue.Convert(core.TimeType).Interface().(time.Time) - if session.Engine.dialect.DBType() == core.MSSQL { - if t.IsZero() { - return nil, nil + if fieldType == core.TimeType { + switch fieldValue.Interface().(type) { + case time.Time: + t := fieldValue.Interface().(time.Time) + if session.Engine.dialect.DBType() == core.MSSQL { + if t.IsZero() { + return nil, nil + } } + tf := session.Engine.FormatTime(col.SQLType.Name, t) + return tf, nil + default: + return fieldValue.Interface(), nil } - tf := session.Engine.FormatTime(col.SQLType.Name, t) - return tf, nil } if fieldTable, ok := session.Engine.Tables[fieldValue.Type()]; ok { if len(fieldTable.PrimaryKeys) == 1 { @@ -3050,7 +3118,7 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val return 0, fmt.Errorf("no primary key for col %v", col.Name) } } else { - return 0, fmt.Errorf("Unsupported type %v", fieldValue.Type()) + return 0, fmt.Errorf("Unsupported type %v\n", fieldValue.Type()) } case reflect.Complex64, reflect.Complex128: bytes, err := json.Marshal(fieldValue.Interface()) @@ -3368,8 +3436,7 @@ func (session *Session) cacheInsert(tables ...string) error { } func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error { - if session.Statement.RefTable == nil || - session.Tx != nil { + if session.Statement.RefTable == nil || len(session.Statement.RefTable.PrimaryKeys) != 1 { return ErrCacheFailed } @@ -3525,8 +3592,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 if session.Statement.ColumnStr == "" { colNames, args = buildUpdates(session.Engine, table, bean, false, false, false, false, session.Statement.allUseBool, session.Statement.useAllCols, - session.Statement.mustColumnMap, session.Statement.nullableMap, - session.Statement.columnMap, true) + session.Statement.mustColumnMap, session.Statement.columnMap, true) } else { colNames, args, err = genCols(table, session, bean, true, true) if err != nil { @@ -3587,7 +3653,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 if len(condiBean) > 0 { condiColNames, condiArgs = buildConditions(session.Engine, session.Statement.RefTable, condiBean[0], true, true, false, true, session.Statement.allUseBool, session.Statement.useAllCols, - session.Statement.unscoped, session.Statement.mustColumnMap, session.Statement.TableName(), false) + session.Statement.unscoped, session.Statement.mustColumnMap) } var condition = "" @@ -3720,8 +3786,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 } func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error { - if session.Statement.RefTable == nil || - session.Tx != nil { + if session.Statement.RefTable == nil || len(session.Statement.RefTable.PrimaryKeys) != 1 { return ErrCacheFailed } @@ -3746,25 +3811,15 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error { if len(resultsSlice) > 0 { for _, data := range resultsSlice { var id int64 - var pk core.PK = make([]interface{}, 0) - for _, col := range session.Statement.RefTable.PKColumns() { - if v, ok := data[col.Name]; !ok { - return errors.New("no id") - } else { - if col.SQLType.IsText() { - pk = append(pk, string(v)) - } else if col.SQLType.IsNumeric() { - id, err = strconv.ParseInt(string(v), 10, 64) - if err != nil { - return err - } - pk = append(pk, id) - } else { - return errors.New("not supported primary key type") - } + if v, ok := data[session.Statement.RefTable.PrimaryKeys[0]]; !ok { + return errors.New("no id") + } else { + id, err = strconv.ParseInt(string(v), 10, 64) + if err != nil { + return err } } - ids = append(ids, pk) + ids = append(ids, core.PK{id}) } } } /*else { @@ -3807,8 +3862,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) { session.Statement.RefTable = table colNames, args := buildConditions(session.Engine, table, bean, true, true, false, true, session.Statement.allUseBool, session.Statement.useAllCols, - session.Statement.unscoped, session.Statement.mustColumnMap, - session.Statement.TableName(), false) + session.Statement.unscoped, session.Statement.mustColumnMap) var condition = "" var andStr = session.Engine.dialect.AndStr() From 8cbe7b1c7eba1e8fd27cc6587632435cbbc5b865 Mon Sep 17 00:00:00 2001 From: hzmnet Date: Tue, 3 Nov 2015 00:47:22 +0800 Subject: [PATCH 7/9] change time format --- helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers.go b/helpers.go index 7e8978f0..b5e320bc 100644 --- a/helpers.go +++ b/helpers.go @@ -142,7 +142,7 @@ func reflect2value(rawValue *reflect.Value) (str string, err error) { //时间类型 case reflect.Struct: if aa.ConvertibleTo(core.TimeType) { - str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano) + str = vv.Convert(core.TimeType).Interface().(time.Time).Format("2006-01-02 15:04:05") } else { err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) } From b6410df10adf916fd2919297a21438dbfbf73483 Mon Sep 17 00:00:00 2001 From: hzmnet Date: Tue, 3 Nov 2015 01:26:19 +0800 Subject: [PATCH 8/9] ads --- session.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/session.go b/session.go index a8824e28..e65b9c9f 100644 --- a/session.go +++ b/session.go @@ -1540,7 +1540,10 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) sliceValue.SetMapIndex(reflect.ValueOf(key), reflect.Indirect(reflect.ValueOf(newValue.Interface()))) } } +<<<<<<< HEAD +======= +>>>>>>> parent of 24f47dd... Add FindMap } return nil } From e069ded38339dc1c4c4d6957f71160372e6686f6 Mon Sep 17 00:00:00 2001 From: hzmnet Date: Tue, 3 Nov 2015 01:26:24 +0800 Subject: [PATCH 9/9] Revert "ads" This reverts commit b6410df10adf916fd2919297a21438dbfbf73483. --- session.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/session.go b/session.go index e65b9c9f..a8824e28 100644 --- a/session.go +++ b/session.go @@ -1540,10 +1540,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) sliceValue.SetMapIndex(reflect.ValueOf(key), reflect.Indirect(reflect.ValueOf(newValue.Interface()))) } } -<<<<<<< HEAD -======= ->>>>>>> parent of 24f47dd... Add FindMap } return nil }