From f4b6ae069ce1cc45baff02b4d8b24e89f85f4a4f Mon Sep 17 00:00:00 2001 From: Nash Tsai Date: Fri, 16 May 2014 23:42:47 +0800 Subject: [PATCH 01/11] tidy up logSQL --- session.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/session.go b/session.go index 68cd8d22..e35b37c2 100644 --- a/session.go +++ b/session.go @@ -431,7 +431,7 @@ func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, er sqlStr = filter.Do(sqlStr, session.Engine.dialect, session.Statement.RefTable) } - session.Engine.logSQL(sqlStr, args) + session.Engine.logSQL(sqlStr, args...) if session.IsAutoCommit { return session.innerExec(sqlStr, args...) @@ -1734,7 +1734,7 @@ func (session *Session) queryPreprocess(sqlStr *string, paramStr ...interface{}) *sqlStr = filter.Do(*sqlStr, session.Engine.dialect, session.Statement.RefTable) } - session.Engine.logSQL(*sqlStr, paramStr) + session.Engine.logSQL(*sqlStr, paramStr...) } func (session *Session) query(sqlStr string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) { From be48dbc82de2e8f86134e955ffd9333cb3209d90 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 21 May 2014 22:34:48 +0800 Subject: [PATCH 02/11] add Conversion usage on Quickstart docs --- VERSION | 2 +- docs/QuickStart.md | 4 +++- docs/QuickStartCN.md | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index eb1bde3d..79201455 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -xorm v0.4.0 RC1 +xorm v0.4.0 diff --git a/docs/QuickStart.md b/docs/QuickStart.md index 434e3f2d..89ed0fe2 100644 --- a/docs/QuickStart.md +++ b/docs/QuickStart.md @@ -224,6 +224,8 @@ type Conversion interface { } ``` +- 5. If one struct has a Conversion field, so we need set an implementation to the field before get data from database. We can implement `BeforeSet(name string, cell xorm.Cell)` on struct to do this. For example: [testConversion](https://github.com/go-xorm/tests/blob/master/base.go#L1826) + ## 3. database meta information @@ -510,7 +512,7 @@ total, err := engine.Where("id >?", 1).Count(user) ``` -## 6.更新数据 +## 6.Update 更新数据使用`Update`方法,Update方法的第一个参数为需要更新的内容,可以为一个结构体指针或者一个Map[string]interface{}类型。当传入的为结构体指针时,只有非空和0的field才会被作为更新的字段。当传入的为Map类型时,key为数据库Column的名字,value为要更新的内容。 diff --git a/docs/QuickStartCN.md b/docs/QuickStartCN.md index 638bc50d..9af08f1d 100644 --- a/docs/QuickStartCN.md +++ b/docs/QuickStartCN.md @@ -224,6 +224,8 @@ type Conversion interface { } ``` +- 5.如果一个结构体包含一个Conversion的接口类型,那么在获取数据时,必须要预先设置一个实现此接口的struct或者struct的指针。此时可以在此struct中实现`BeforeSet(name string, cell xorm.Cell)`方法来进行预先给Conversion赋值。例子参见 [testConversion](https://github.com/go-xorm/tests/blob/master/base.go#L1826) + ### 2.4.Go与字段类型对应表 From e4f05916cb0242b8dd5946ae17e572ff16c0bcf0 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 23 May 2014 14:18:45 +0800 Subject: [PATCH 03/11] add support for Join --- engine.go | 8 +----- session.go | 81 ++++++++++++++++++++++++++-------------------------- statement.go | 27 +++++++++++------- 3 files changed, 59 insertions(+), 57 deletions(-) diff --git a/engine.go b/engine.go index 107a9d69..e265a5f9 100644 --- a/engine.go +++ b/engine.go @@ -590,15 +590,10 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table { continue } if strings.ToUpper(tags[0]) == "EXTENDS" { - - //fieldValue = reflect.Indirect(fieldValue) - //fmt.Println("----", fieldValue.Kind()) if fieldValue.Kind() == reflect.Struct { - //parentTable := mappingTable(fieldType, tableMapper, colMapper, dialect, tagId) parentTable := engine.mapType(fieldValue) for _, col := range parentTable.Columns() { col.FieldName = fmt.Sprintf("%v.%v", t.Field(i).Name, col.FieldName) - //fmt.Println("---", col.FieldName) table.AddColumn(col) } @@ -610,7 +605,6 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table { if !fieldValue.IsValid() || fieldValue.IsNil() { fieldValue = reflect.New(f).Elem() } - //fmt.Println("00000", fieldValue) } parentTable := engine.mapType(fieldValue) @@ -732,7 +726,7 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table { if col.Length2 == 0 { col.Length2 = col.SQLType.DefaultLength2 } - //fmt.Println("======", col) + if col.Name == "" { col.Name = engine.ColumnMapper.Obj2Table(t.Field(i).Name) } diff --git a/session.go b/session.go index e35b37c2..591850af 100644 --- a/session.go +++ b/session.go @@ -599,7 +599,6 @@ func (statement *Statement) convertIdSql(sqlStr string) string { if len(sqls) != 2 { return "" } - //fmt.Println("-----", col) newsql := fmt.Sprintf("SELECT %v.%v FROM %v", statement.Engine.Quote(statement.TableName()), statement.Engine.Quote(col.Name), sqls[1]) return newsql @@ -728,7 +727,6 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in ids = make([]core.PK, 0) if len(resultsSlice) > 0 { for _, data := range resultsSlice { - //fmt.Println(data) var id int64 if v, ok := data[session.Statement.RefTable.PrimaryKeys[0]]; !ok { return errors.New("no id") @@ -939,7 +937,9 @@ func (session *Session) Get(bean interface{}) (bool, error) { var sqlStr string var args []interface{} - session.Statement.RefTable = session.Engine.autoMap(bean) + if session.Statement.RefTable == nil { + session.Statement.RefTable = session.Engine.autoMap(bean) + } if session.Statement.RawSQL == "" { sqlStr, args = session.Statement.genGetSql(bean) @@ -948,10 +948,12 @@ func (session *Session) Get(bean interface{}) (bool, error) { args = session.Statement.RawParams } - if cacher := session.Engine.getCacher2(session.Statement.RefTable); cacher != nil && session.Statement.UseCache { - has, err := session.cacheGet(bean, sqlStr, args...) - if err != ErrCacheFailed { - return has, err + if session.Statement.JoinStr == "" { + if cacher := session.Engine.getCacher2(session.Statement.RefTable); cacher != nil && session.Statement.UseCache { + has, err := session.cacheGet(bean, sqlStr, args...) + if err != ErrCacheFailed { + return has, err + } } } @@ -1073,8 +1075,14 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) var args []interface{} if session.Statement.RawSQL == "" { var columnStr string = session.Statement.ColumnStr - if columnStr == "" { - columnStr = session.Statement.genColumnStr() + if session.Statement.JoinStr == "" { + if columnStr == "" { + columnStr = session.Statement.genColumnStr() + } + } else { + if columnStr == "" { + columnStr = "*" + } } session.Statement.attachInSql() @@ -1086,15 +1094,17 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) args = session.Statement.RawParams } - if cacher := session.Engine.getCacher2(table); cacher != nil && - session.Statement.UseCache && - !session.Statement.IsDistinct { - err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...) - if err != ErrCacheFailed { - return err + if session.Statement.JoinStr == "" { + if cacher := session.Engine.getCacher2(table); cacher != nil && + session.Statement.UseCache && + !session.Statement.IsDistinct { + 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") } - err = nil // !nashtsai! reset err to nil for ErrCacheFailed - session.Engine.LogWarn("Cache Find Failed") } if sliceValue.Kind() != reflect.Map { @@ -1102,14 +1112,6 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) var stmt *core.Stmt session.queryPreprocess(&sqlStr, args...) - // err = session.queryRows(&stmt, &rawRows, sqlStr, args...) - // if err != nil { - // return err - // } - // if stmt != nil { - // defer stmt.Close() - // } - // defer rawRows.Close() if session.IsAutoCommit { stmt, err = session.doPrepare(sqlStr) @@ -1311,7 +1313,6 @@ func (session *Session) addColumn(colName string) error { if session.IsAutoClose { defer session.Close() } - //fmt.Println(session.Statement.RefTable) col := session.Statement.RefTable.GetColumn(colName) sql, args := session.Statement.genAddColumnStr(col) @@ -1344,7 +1345,6 @@ func (session *Session) addUnique(tableName, uqeName string) error { if session.IsAutoClose { defer session.Close() } - //fmt.Println(uqeName, session.Statement.RefTable.Uniques) index := session.Statement.RefTable.Indexes[uqeName] sqlStr := session.Engine.dialect.CreateIndexSql(tableName, index) _, err = session.exec(sqlStr) @@ -1402,9 +1402,9 @@ func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, er return result, nil } -func (session *Session) getField(dataStruct *reflect.Value, key string, table *core.Table) *reflect.Value { +func (session *Session) getField(dataStruct *reflect.Value, key string, table *core.Table, idx int) *reflect.Value { var col *core.Column - if col = table.GetColumn(key); col == nil { + if col = table.GetColumnIdx(key, idx); col == nil { session.Engine.LogWarn(fmt.Sprintf("table %v's has not column %v. %v", table.Name, key, table.Columns())) return nil } @@ -1448,13 +1448,22 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i } } + var tempMap = make(map[string]int) for ii, key := range fields { - if fieldValue := session.getField(&dataStruct, key, table); fieldValue != nil { + var idx int + var ok bool + if idx, ok = tempMap[strings.ToLower(key)]; !ok { + idx = 0 + } else { + idx = idx + 1 + } + tempMap[strings.ToLower(key)] = idx + + if fieldValue := session.getField(&dataStruct, key, table, idx); fieldValue != nil { rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii])) //if row is null then ignore if rawValue.Interface() == nil { - //fmt.Println("ignore ...", key, rawValue) continue } @@ -1485,9 +1494,6 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i vv := reflect.ValueOf(rawValue.Interface()) fieldType := fieldValue.Type() - - //fmt.Println("column name:", key, ", fieldType:", fieldType.String()) - hasAssigned := false switch fieldType.Kind() { @@ -1767,7 +1773,6 @@ func query(db *core.DB, sqlStr string, params ...interface{}) (resultsSlice []ma return nil, err } defer rows.Close() - //fmt.Println(rows) return rows2maps(rows) } @@ -2034,11 +2039,9 @@ func (session *Session) byte2Time(col *core.Column, data []byte) (outTime time.T } sdata = strings.TrimSpace(sdata) - //fmt.Println(sdata) if session.Engine.dialect.DBType() == core.MYSQL && len(sdata) > 8 { sdata = sdata[len(sdata)-8:] } - //fmt.Println(sdata) st := fmt.Sprintf("2006-01-02 %v", sdata) x, err = time.ParseInLocation("2006-01-02 15:04:05", st, session.Engine.TZLocation) @@ -2069,7 +2072,6 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value, key := col.Name fieldType := fieldValue.Type() - //fmt.Println("column name:", key, ", fieldType:", fieldType.String()) switch fieldType.Kind() { case reflect.Complex64, reflect.Complex128: x := reflect.New(fieldType) @@ -2578,7 +2580,6 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) { } colPlaces := strings.Repeat("?, ", len(colNames)) - //fmt.Println(colNames, args) colPlaces = colPlaces[0 : len(colPlaces)-2] sqlStr := fmt.Sprintf("INSERT INTO %v%v%v (%v%v%v) VALUES (%v)", @@ -2988,7 +2989,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 if session.Statement.UseAutoTime && table.Updated != "" { colNames = append(colNames, session.Engine.Quote(table.Updated)+" = ?") - args = append(args, session.Engine.NowTime(table.Columns()[strings.ToLower(table.Updated)].SQLType.Name)) + args = append(args, session.Engine.NowTime(table.UpdatedColumn().SQLType.Name)) } //for update action to like "column = column + ?" diff --git a/statement.go b/statement.go index 707f9c1d..c19247a2 100644 --- a/statement.go +++ b/statement.go @@ -277,8 +277,7 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, if !includeAutoIncr && col.IsAutoIncrement { continue } - // - //fmt.Println(engine.dialect.DBType(), Text) + if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text { continue } @@ -382,7 +381,6 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, continue } val = engine.FormatTime(col.SQLType.Name, t) - //fmt.Println("-------", t, val, col.Name) } else { engine.autoMapType(fieldValue) if table, ok := engine.Tables[fieldValue.Type()]; ok { @@ -470,8 +468,7 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{}, if !includeAutoIncr && col.IsAutoIncrement { continue } - // - //fmt.Println(engine.dialect.DBType(), Text) + if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text { continue } @@ -555,7 +552,6 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{}, continue } val = engine.FormatTime(col.SQLType.Name, t) - //fmt.Println("-------", t, val, col.Name) } else { engine.autoMapType(fieldValue) if table, ok := engine.Tables[fieldValue.Type()]; ok { @@ -948,8 +944,13 @@ func (s *Statement) genDropSQL() string { } func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) { - table := statement.Engine.autoMap(bean) - statement.RefTable = table + var table *core.Table + if statement.RefTable == nil { + table = statement.Engine.autoMap(bean) + statement.RefTable = table + } else { + table = statement.RefTable + } colNames, args := buildConditions(statement.Engine, table, bean, true, true, false, true, statement.allUseBool, statement.useAllCols, @@ -959,8 +960,14 @@ func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) statement.BeanArgs = args var columnStr string = statement.ColumnStr - if columnStr == "" { - columnStr = statement.genColumnStr() + if statement.JoinStr == "" { + if columnStr == "" { + columnStr = statement.genColumnStr() + } + } else { + if columnStr == "" { + columnStr = "*" + } } statement.attachInSql() // !admpub! fix bug:Iterate func missing "... IN (...)" From 929df107f1cf5e308774acfb085bbfbe90960ae1 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 23 May 2014 14:45:49 +0800 Subject: [PATCH 04/11] improved docs --- docs/ChangelogCN.md | 2 +- docs/QuickStart.md | 37 ++++++++++++++++++++++++++++++++++++- docs/QuickStartCN.md | 26 ++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/docs/ChangelogCN.md b/docs/ChangelogCN.md index 1ea3f748..246fa35d 100644 --- a/docs/ChangelogCN.md +++ b/docs/ChangelogCN.md @@ -4,7 +4,7 @@ 新特性: * 移动xorm cmd [github.com/go-xorm/cmd](github.com/go-xorm/cmd) * 在重构一般DB操作核心库 [github.com/go-xorm/core](https://github.com/go-xorm/core) - * 移动测试github.com/复XORM/测试 [github.com/go-xorm/tests](github.com/go-xorm/tests) + * 移动测试github.com/XORM/tests [github.com/go-xorm/tests](github.com/go-xorm/tests) 改进: * Prepared statement 缓存 diff --git a/docs/QuickStart.md b/docs/QuickStart.md index 89ed0fe2..b9e12f40 100644 --- a/docs/QuickStart.md +++ b/docs/QuickStart.md @@ -693,7 +693,7 @@ Please visit [https://github.com/go-xorm/xorm/tree/master/examples](https://gith ## 15.FAQ -1.How the xorm tag use both with json? +* How the xorm tag use both with json? Use space. @@ -702,3 +702,38 @@ type User struct { Name string `json:"name" xorm:"name"` } ``` + +* Does xorm support composite primary key? + + Yes. You can use pk tag. All fields have tag will as one primary key by fields order on struct. When use, you can use xorm.PK{1, 2}. For example: `Id(xorm.PK{1, 2})`. + +* How to use join? + + We can use Join() and extends tag to do join operation. For example: + + type Userinfo struct { + Id int64 + Name string + DetailId int64 + } + + type Userdetail struct { + Id int64 + Gender int + } + + type User struct { + Userinfo `xorm:"extends"` + Userdetail `xorm:"extends"` + } + + var users = make([]User, 0) + err := engine.Table(&Userinfo{}).Join("LEFT", "userdetail", "userinfo.detail_id = userdetail.id").Find(&users) + + //assert(User.Userinfo.Id != 0 && User.Userdetail.Id != 0) + +Of course, If join statment is very long, you could directly use Sql(): + + err := engine.Sql("select * from userinfo, userdetail where userinfo.detail_id = userdetail.id").Find(&users) + + //assert(User.Userinfo.Id != 0 && User.Userdetail.Id != 0) diff --git a/docs/QuickStartCN.md b/docs/QuickStartCN.md index 9af08f1d..ac06c193 100644 --- a/docs/QuickStartCN.md +++ b/docs/QuickStartCN.md @@ -830,6 +830,32 @@ money float64 `xorm:"Numeric"` 答:支持。在定义时,如果有多个字段标记了pk,则这些字段自动成为复合主键,顺序为在struct中出现的顺序。在使用Id方法时,可以用`Id(xorm.PK{1, 2})`的方式来用。 +* xorm如何使用Join? + +答:一般我们配合Join()和extends标记来进行,比如我们要对两个表进行Join操作,我们可以这样: + + type Userinfo struct { + Id int64 + Name string + DetailId int64 + } + + type Userdetail struct { + Id int64 + Gender int + } + + type User struct { + Userinfo `xorm:"extends"` + Userdetail `xorm:"extends"` + } + + var users = make([]User, 0) + err := engine.Table(&Userinfo{}).Join("LEFT", "userdetail", "userinfo.detail_id = userdetail.id").Find(&users) + +当然,如果Join语句比较复杂,我们也可以直接用Sql函数 + + err := engine.Sql("select * from userinfo, userdetail where userinfo.detail_id = userdetail.id").Find(&users) ## 17.讨论 From 66e697d3b1b9600ad00197c5af682ab73c73ddf2 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 23 May 2014 15:01:41 +0800 Subject: [PATCH 05/11] improved docs --- docs/QuickStart.md | 2 ++ docs/QuickStartCN.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/QuickStart.md b/docs/QuickStart.md index b9e12f40..47aa98dc 100644 --- a/docs/QuickStart.md +++ b/docs/QuickStart.md @@ -732,6 +732,8 @@ type User struct { //assert(User.Userinfo.Id != 0 && User.Userdetail.Id != 0) +Please notice that Userinfo field on User should be before Userdetail because of the order on join SQL stsatement. If the order is wrong, the same name field may be set a wrong value. + Of course, If join statment is very long, you could directly use Sql(): err := engine.Sql("select * from userinfo, userdetail where userinfo.detail_id = userdetail.id").Find(&users) diff --git a/docs/QuickStartCN.md b/docs/QuickStartCN.md index ac06c193..366a6cad 100644 --- a/docs/QuickStartCN.md +++ b/docs/QuickStartCN.md @@ -853,6 +853,8 @@ money float64 `xorm:"Numeric"` var users = make([]User, 0) err := engine.Table(&Userinfo{}).Join("LEFT", "userdetail", "userinfo.detail_id = userdetail.id").Find(&users) +请注意这里的Userinfo在User中的位置必须在Userdetail的前面,因为他在join语句中的顺序在userdetail前面。如果顺序不对,那么对于同名的列,有可能会赋值出错。 + 当然,如果Join语句比较复杂,我们也可以直接用Sql函数 err := engine.Sql("select * from userinfo, userdetail where userinfo.detail_id = userdetail.id").Find(&users) From bfeb6ea19f439e841fe9de1052c71ef0885253f1 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 24 May 2014 16:05:48 +0800 Subject: [PATCH 06/11] bug fixed & new Import func --- engine.go | 31 +++++++++++++++++++++++-------- sqlite3_dialect.go | 6 ++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/engine.go b/engine.go index e265a5f9..d2db0cc7 100644 --- a/engine.go +++ b/engine.go @@ -31,6 +31,7 @@ type Engine struct { mutex *sync.RWMutex Cacher core.Cacher + ShowInfo bool ShowSQL bool ShowErr bool ShowDebug bool @@ -190,7 +191,9 @@ func (engine *Engine) LogError(contents ...interface{}) { // logging error func (engine *Engine) LogInfo(contents ...interface{}) { - engine.Logger.Info(fmt.Sprintln(contents...)) + if engine.ShowInfo { + engine.Logger.Info(fmt.Sprintln(contents...)) + } } // logging debug @@ -325,10 +328,19 @@ func (engine *Engine) DumpAll(w io.Writer) error { } else if col.SQLType.IsText() || col.SQLType.IsTime() { var v = fmt.Sprintf("%s", d) temp += ", '" + strings.Replace(v, "'", "''", -1) + "'" - } else if col.SQLType.IsBlob() /*reflect.TypeOf(d).Kind() == reflect.Slice*/ { - temp += fmt.Sprintf(", %s", engine.dialect.FormatBytes(d.([]byte))) + } else if col.SQLType.IsBlob() /**/ { + if reflect.TypeOf(d).Kind() == reflect.Slice { + temp += fmt.Sprintf(", %s", engine.dialect.FormatBytes(d.([]byte))) + } else if reflect.TypeOf(d).Kind() == reflect.String { + temp += fmt.Sprintf(", '%s'", d.(string)) + } } else { - temp += fmt.Sprintf(", %s", d) + s := fmt.Sprintf("%v", d) + if strings.Contains(s, ":") || strings.Contains(s, "-") { + temp += fmt.Sprintf(", '%s'", s) + } else { + temp += fmt.Sprintf(", %s", s) + } } } _, err = io.WriteString(w, temp[2:]+");\n\n") @@ -1160,17 +1172,20 @@ func (engine *Engine) Count(bean interface{}) (int64, error) { } // Import SQL DDL file -func (engine *Engine) Import(ddlPath string) ([]sql.Result, error) { - +func (engine *Engine) ImportFile(ddlPath string) ([]sql.Result, error) { file, err := os.Open(ddlPath) if err != nil { return nil, err } defer file.Close() + return engine.Import(file) +} +// Import SQL DDL file +func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) { var results []sql.Result var lastError error - scanner := bufio.NewScanner(file) + scanner := bufio.NewScanner(r) semiColSpliter := func(data []byte, atEOF bool) (advance int, token []byte, err error) { if atEOF && len(data) == 0 { @@ -1191,7 +1206,7 @@ func (engine *Engine) Import(ddlPath string) ([]sql.Result, error) { session := engine.NewSession() defer session.Close() - err = session.newDb() + err := session.newDb() if err != nil { return results, err } diff --git a/sqlite3_dialect.go b/sqlite3_dialect.go index c6123dcb..0626cf4e 100644 --- a/sqlite3_dialect.go +++ b/sqlite3_dialect.go @@ -1,6 +1,7 @@ package xorm import ( + "errors" "fmt" "strings" @@ -120,6 +121,11 @@ func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Colu if err != nil { return nil, nil, err } + break + } + + if name == "" { + return nil, nil, errors.New("no table named " + tableName) } nStart := strings.Index(name, "(") From bd1487ba5558424d9f191c922be397cb006e1242 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 29 May 2014 16:53:23 +0800 Subject: [PATCH 07/11] bug fixed --- mssql_dialect.go | 6 +++--- mysql_dialect.go | 7 ++++--- oracle_dialect.go | 6 +++--- postgres_dialect.go | 6 +++--- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/mssql_dialect.go b/mssql_dialect.go index ebc35164..5cd2f52b 100644 --- a/mssql_dialect.go +++ b/mssql_dialect.go @@ -62,10 +62,10 @@ func (db *mssql) SqlType(c *core.Column) string { var hasLen1 bool = (c.Length > 0) var hasLen2 bool = (c.Length2 > 0) - if hasLen1 { - res += "(" + strconv.Itoa(c.Length) + ")" - } else if hasLen2 { + if hasLen2 { res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" + } else if hasLen1 { + res += "(" + strconv.Itoa(c.Length) + ")" } return res } diff --git a/mysql_dialect.go b/mysql_dialect.go index e76830ab..4e430165 100644 --- a/mysql_dialect.go +++ b/mysql_dialect.go @@ -70,10 +70,11 @@ func (db *mysql) SqlType(c *core.Column) string { var hasLen1 bool = (c.Length > 0) var hasLen2 bool = (c.Length2 > 0) - if hasLen1 { - res += "(" + strconv.Itoa(c.Length) + ")" - } else if hasLen2 { + + if hasLen2 { res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" + } else if hasLen1 { + res += "(" + strconv.Itoa(c.Length) + ")" } return res } diff --git a/oracle_dialect.go b/oracle_dialect.go index 73300c1a..e23ab297 100644 --- a/oracle_dialect.go +++ b/oracle_dialect.go @@ -44,10 +44,10 @@ func (db *oracle) SqlType(c *core.Column) string { var hasLen1 bool = (c.Length > 0) var hasLen2 bool = (c.Length2 > 0) - if hasLen1 { - res += "(" + strconv.Itoa(c.Length) + ")" - } else if hasLen2 { + if hasLen2 { res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" + } else if hasLen1 { + res += "(" + strconv.Itoa(c.Length) + ")" } return res } diff --git a/postgres_dialect.go b/postgres_dialect.go index 58e8da4f..61e75881 100644 --- a/postgres_dialect.go +++ b/postgres_dialect.go @@ -59,10 +59,10 @@ func (db *postgres) SqlType(c *core.Column) string { var hasLen1 bool = (c.Length > 0) var hasLen2 bool = (c.Length2 > 0) - if hasLen1 { - res += "(" + strconv.Itoa(c.Length) + ")" - } else if hasLen2 { + if hasLen2 { res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" + } else if hasLen1 { + res += "(" + strconv.Itoa(c.Length) + ")" } return res } From 62e3e1508ea80ef9d1ef1298af8f1f7fea860425 Mon Sep 17 00:00:00 2001 From: Alfred Hall Date: Fri, 30 May 2014 16:28:51 +0000 Subject: [PATCH 08/11] Satisfies the issue mentioned in #110. Introduces flag AutoResetStatement which is by default true, but setting it to false means the statement doesn't get reset. Calling .Init() or setting the flag back to true ensures normal behaviour. Signed-off-by: Alfred Hall --- session.go | 63 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/session.go b/session.go index 591850af..01319376 100644 --- a/session.go +++ b/session.go @@ -26,6 +26,10 @@ type Session struct { TransType string IsAutoClose bool + // Automatically reset the statement after operations that execute a SQL + // query such as Count(), Find(), Get(), ... + AutoResetStatement bool + // !nashtsai! storing these beans due to yet committed tx afterInsertBeans map[interface{}]*[]func(interface{}) afterUpdateBeans map[interface{}]*[]func(interface{}) @@ -45,6 +49,7 @@ func (session *Session) Init() { session.IsAutoCommit = true session.IsCommitedOrRollbacked = false session.IsAutoClose = false + session.AutoResetStatement = true // !nashtsai! is lazy init better? session.afterInsertBeans = make(map[interface{}]*[]func(interface{}), 0) @@ -69,6 +74,12 @@ func (session *Session) Close() { } } +func (session *Session) resetStatement() { + if session.AutoResetStatement { + session.Statement.Init() + } +} + // Method Sql provides raw sql input parameter. When you have a complex SQL statement // and cannot use Where, Id, In and etc. Methods to describe, you can use Sql. func (session *Session) Sql(querystring string, args ...interface{}) *Session { @@ -445,7 +456,7 @@ func (session *Session) Exec(sqlStr string, args ...interface{}) (sql.Result, er if err != nil { return nil, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -461,7 +472,7 @@ func (session *Session) CreateTable(bean interface{}) error { if err != nil { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -477,7 +488,7 @@ func (session *Session) CreateIndexes(bean interface{}) error { if err != nil { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -500,7 +511,7 @@ func (session *Session) CreateUniques(bean interface{}) error { if err != nil { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -528,7 +539,7 @@ func (session *Session) createAll() error { if err != nil { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -549,7 +560,7 @@ func (session *Session) DropIndexes(bean interface{}) error { if err != nil { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -571,13 +582,13 @@ func (session *Session) DropTable(bean interface{}) error { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } t := reflect.Indirect(reflect.ValueOf(bean)).Type() - defer session.Statement.Init() + defer session.resetStatement() if t.Kind() == reflect.String { session.Statement.AltTableName = bean.(string) } else if t.Kind() == reflect.Struct { @@ -928,7 +939,7 @@ func (session *Session) Get(bean interface{}) (bool, error) { return false, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -993,7 +1004,7 @@ func (session *Session) Count(bean interface{}) (int64, error) { return 0, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1032,7 +1043,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) if err != nil { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1228,7 +1239,7 @@ func (session *Session) Ping() error { if err != nil { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1241,7 +1252,7 @@ func (session *Session) isColumnExist(tableName string, col *core.Column) (bool, if err != nil { return false, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1256,7 +1267,7 @@ func (session *Session) isTableExist(tableName string) (bool, error) { if err != nil { return false, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1270,7 +1281,7 @@ func (session *Session) isIndexExist(tableName, idxName string, unique bool) (bo if err != nil { return false, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1309,7 +1320,7 @@ func (session *Session) addColumn(colName string) error { if err != nil { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1325,7 +1336,7 @@ func (session *Session) addIndex(tableName, idxName string) error { if err != nil { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1341,7 +1352,7 @@ func (session *Session) addUnique(tableName, uqeName string) error { if err != nil { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1357,7 +1368,7 @@ func (session *Session) dropAll() error { if err != nil { return err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1782,7 +1793,7 @@ func (session *Session) Query(sqlStr string, paramStr ...interface{}) (resultsSl if err != nil { return nil, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1798,7 +1809,7 @@ func (session *Session) Insert(beans ...interface{}) (int64, error) { if err != nil { return 0, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -1985,7 +1996,7 @@ func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) { if err != nil { return 0, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -2749,7 +2760,7 @@ func (session *Session) InsertOne(bean interface{}) (int64, error) { if err != nil { return 0, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -2935,7 +2946,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 if err != nil { return 0, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } @@ -3010,7 +3021,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 var condition = "" session.Statement.processIdParam() st := session.Statement - defer session.Statement.Init() + defer session.resetStatement() if st.WhereStr != "" { condition = fmt.Sprintf("%v", st.WhereStr) } @@ -3188,7 +3199,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) { if err != nil { return 0, err } - defer session.Statement.Init() + defer session.resetStatement() if session.IsAutoClose { defer session.Close() } From 6384ada2bba6a5fa4245dd93a03f9de5c88df51b Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 31 May 2014 12:19:46 +0800 Subject: [PATCH 09/11] bug fixed --- engine.go | 10 +++++++--- session.go | 1 + statement.go | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/engine.go b/engine.go index d2db0cc7..77a636d4 100644 --- a/engine.go +++ b/engine.go @@ -134,8 +134,8 @@ func (engine *Engine) NoCascade() *Session { // Set a table use a special cacher func (engine *Engine) MapCacher(bean interface{}, cacher core.Cacher) { v := rValue(bean) - engine.autoMapType(v) - engine.Tables[v.Type()].Cacher = cacher + tb := engine.autoMapType(v) + tb.Cacher = cacher } // NewDB provides an interface to operate database directly @@ -483,7 +483,7 @@ func (engine *Engine) Desc(colNames ...string) *Session { return session.Desc(colNames...) } -// Method Asc will generate "ORDER BY column1 DESC, column2 Asc" +// Method Asc will generate "ORDER BY column1,column2 Asc" // This method can chainable use. // // engine.Desc("name").Asc("age").Find(&users) @@ -561,6 +561,7 @@ func (engine *Engine) newTable() *core.Table { } func (engine *Engine) mapType(v reflect.Value) *core.Table { + fmt.Println("has", v.NumField(), "fields") t := v.Type() table := engine.newTable() method := v.MethodByName("TableName") @@ -587,10 +588,12 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table { for i := 0; i < t.NumField(); i++ { tag := t.Field(i).Tag + ormTagStr := tag.Get(engine.TagIdentifier) var col *core.Column fieldValue := v.Field(i) fieldType := fieldValue.Type() + fmt.Println(table.Name, "===", t.Field(i).Name) if ormTagStr != "" { col = &core.Column{FieldName: t.Field(i).Name, Nullable: true, IsPrimaryKey: false, @@ -764,6 +767,7 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table { sqlType = core.SQLType{core.Text, 0, 0} } else { sqlType = core.Type2SQLType(fieldType) + fmt.Println(t.Field(i).Name, "...", sqlType) } col = core.NewColumn(engine.ColumnMapper.Obj2Table(t.Field(i).Name), t.Field(i).Name, sqlType, sqlType.DefaultLength, diff --git a/session.go b/session.go index 591850af..cfa5696e 100644 --- a/session.go +++ b/session.go @@ -3333,6 +3333,7 @@ func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, args = append(args, session.Engine.NowTime(col.SQLType.Name)) } else if col.IsVersion && session.Statement.checkVersion { args = append(args, 1) + //} else if !col.DefaultIsEmpty { } else { arg, err := session.value2Interface(col, fieldValue) if err != nil { diff --git a/statement.go b/statement.go index c19247a2..865e67d3 100644 --- a/statement.go +++ b/statement.go @@ -264,6 +264,7 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, colNames := make([]string, 0) var args = make([]interface{}, 0) + fmt.Println(table.ColumnsSeq()) for _, col := range table.Columns() { if !includeVersion && col.IsVersion { continue @@ -281,6 +282,7 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text { continue } + fmt.Println("===", col.Name) fieldValuePtr, err := col.ValueOf(bean) if err != nil { engine.LogError(err) @@ -291,6 +293,7 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, fieldType := reflect.TypeOf(fieldValue.Interface()) requiredField := useAllCols + includeNil := useAllCols if b, ok := mustColumnMap[strings.ToLower(col.Name)]; ok { if b { requiredField = true @@ -323,9 +326,11 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, goto APPEND } + fmt.Println(col.Name, "is", fieldValue) if fieldType.Kind() == reflect.Ptr { if fieldValue.IsNil() { if includeNil { + fmt.Println(col.Name, "is nil") args = append(args, nil) colNames = append(colNames, fmt.Sprintf("%v=?", engine.Quote(col.Name))) } From 23d0d656dae27043649457fe31fdd49676052bb1 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 31 May 2014 12:22:06 +0800 Subject: [PATCH 10/11] ShowSQL bug fixed --- engine.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine.go b/engine.go index d2db0cc7..46180438 100644 --- a/engine.go +++ b/engine.go @@ -175,9 +175,9 @@ func (engine *Engine) Ping() error { func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) { if engine.ShowSQL { if len(sqlArgs) > 0 { - engine.LogInfo("[sql]", sqlStr, "[args]", sqlArgs) + engine.Logger.Info(fmt.Sprintln("[sql]", sqlStr, "[args]", sqlArgs)) } else { - engine.LogInfo("[sql]", sqlStr) + engine.Logger.Info(fmt.Sprintln("[sql]", sqlStr)) } } } From 6d1a0ac0b0a8b354671be541d930a003c085d7b1 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 11 Jun 2014 14:01:14 +0800 Subject: [PATCH 11/11] add Sync2 for a new sync database struct methods --- engine.go | 135 +++++++++++++++++++++++++++++++++++++++++++- postgres_dialect.go | 40 ++++++++----- statement.go | 5 +- 3 files changed, 158 insertions(+), 22 deletions(-) diff --git a/engine.go b/engine.go index 77a636d4..51b64502 100644 --- a/engine.go +++ b/engine.go @@ -561,7 +561,6 @@ func (engine *Engine) newTable() *core.Table { } func (engine *Engine) mapType(v reflect.Value) *core.Table { - fmt.Println("has", v.NumField(), "fields") t := v.Type() table := engine.newTable() method := v.MethodByName("TableName") @@ -593,7 +592,6 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table { var col *core.Column fieldValue := v.Field(i) fieldType := fieldValue.Type() - fmt.Println(table.Name, "===", t.Field(i).Name) if ormTagStr != "" { col = &core.Column{FieldName: t.Field(i).Name, Nullable: true, IsPrimaryKey: false, @@ -767,7 +765,6 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table { sqlType = core.SQLType{core.Text, 0, 0} } else { sqlType = core.Type2SQLType(fieldType) - fmt.Println(t.Field(i).Name, "...", sqlType) } col = core.NewColumn(engine.ColumnMapper.Obj2Table(t.Field(i).Name), t.Field(i).Name, sqlType, sqlType.DefaultLength, @@ -1016,6 +1013,138 @@ func (engine *Engine) Sync(beans ...interface{}) error { return nil } +func (engine *Engine) Sync2(beans ...interface{}) error { + tables, err := engine.DBMetas() + if err != nil { + return err + } + + for _, bean := range beans { + table := engine.autoMap(bean) + + var oriTable *core.Table + for _, tb := range tables { + if tb.Name == table.Name { + oriTable = tb + break + } + } + + if oriTable == nil { + err = engine.CreateTables(bean) + if err != nil { + return err + } + + err = engine.CreateUniques(bean) + if err != nil { + return err + } + + err = engine.CreateIndexes(bean) + if err != nil { + return err + } + } else { + for _, col := range table.Columns() { + var oriCol *core.Column + for _, col2 := range oriTable.Columns() { + if col.Name == col2.Name { + oriCol = col2 + break + } + } + + if oriCol != nil { + if col.SQLType.Name != oriCol.SQLType.Name { + if col.SQLType.Name == core.Text && + oriCol.SQLType.Name == core.Varchar { + // currently only support mysql + if engine.dialect.DBType() == core.MYSQL { + _, err = engine.Exec(engine.dialect.ModifyColumnSql(table.Name, col)) + } else { + engine.LogWarn("Table %s Column %s Old data type is %s, new data type is %s", + table.Name, col.Name, oriCol.SQLType.Name, col.SQLType.Name) + } + } else { + engine.LogWarn("Table %s Column %s Old data type is %s, new data type is %s", + table.Name, col.Name, oriCol.SQLType.Name, col.SQLType.Name) + } + } + if col.Default != oriCol.Default { + engine.LogWarn("Table %s Column %s Old default is %s, new default is %s", + table.Name, col.Name, oriCol.Default, col.Default) + } + if col.Nullable != oriCol.Nullable { + engine.LogWarn("Table %s Column %s Old nullable is %v, new nullable is %v", + table.Name, col.Name, oriCol.Nullable, col.Nullable) + } + } else { + session := engine.NewSession() + session.Statement.RefTable = table + defer session.Close() + err = session.addColumn(col.Name) + } + if err != nil { + return err + } + } + + var foundIndexNames = make(map[string]bool) + + for name, index := range table.Indexes { + var oriIndex *core.Index + for name2, index2 := range oriTable.Indexes { + if index.Equal(index2) { + oriIndex = index2 + foundIndexNames[name2] = true + break + } + } + + if oriIndex != nil { + if oriIndex.Type != index.Type { + sql := engine.dialect.DropIndexSql(table.Name, oriIndex) + _, err = engine.Exec(sql) + if err != nil { + return err + } + oriIndex = nil + } + } + + if oriIndex == nil { + if index.Type == core.UniqueType { + session := engine.NewSession() + session.Statement.RefTable = table + defer session.Close() + err = session.addUnique(table.Name, name) + } else if index.Type == core.IndexType { + session := engine.NewSession() + session.Statement.RefTable = table + defer session.Close() + err = session.addIndex(table.Name, name) + } + if err != nil { + return err + } + } + } + + for name2, index2 := range oriTable.Indexes { + if _, ok := foundIndexNames[name2]; !ok { + sql := engine.dialect.DropIndexSql(table.Name, index2) + _, err = engine.Exec(sql) + if err != nil { + return err + } + } + } + } + } + return nil +} + func (engine *Engine) unMap(beans ...interface{}) (e error) { engine.mutex.Lock() defer engine.mutex.Unlock() diff --git a/postgres_dialect.go b/postgres_dialect.go index 61e75881..a088664c 100644 --- a/postgres_dialect.go +++ b/postgres_dialect.go @@ -108,10 +108,28 @@ func (db *postgres) TableCheckSql(tableName string) (string, []interface{}) { " AND column_name = ?", args }*/ +func (db *postgres) ModifyColumnSql(tableName string, col *core.Column) string { + return fmt.Sprintf("alter table %s ALTER COLUMN %s TYPE %s", + tableName, col.Name, db.SqlType(col)) +} + +func (db *postgres) DropIndexSql(tableName string, index *core.Index) string { + quote := db.Quote + //var unique string + var idxName string = index.Name + if !strings.HasPrefix(idxName, "UQE_") && + !strings.HasPrefix(idxName, "IDX_") { + if index.Type == core.UniqueType { + idxName = fmt.Sprintf("UQE_%v_%v", tableName, index.Name) + } else { + idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name) + } + } + return fmt.Sprintf("DROP INDEX %v", quote(idxName)) +} + func (db *postgres) IsColumnExist(tableName string, col *core.Column) (bool, error) { args := []interface{}{tableName, col.Name} - - //query := "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ?" query := "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = $1" + " AND column_name = $2" rows, err := db.DB().Query(query, args...) @@ -120,10 +138,7 @@ func (db *postgres) IsColumnExist(tableName string, col *core.Column) (bool, err } defer rows.Close() - if rows.Next() { - return true, nil - } - return false, nil + return rows.Next(), nil } func (db *postgres) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { @@ -169,11 +184,7 @@ func (db *postgres) GetColumns(tableName string) ([]string, map[string]*core.Col } } - if isNullable == "YES" { - col.Nullable = true - } else { - col.Nullable = false - } + col.Nullable = (isNullable == "YES") switch dataType { case "character varying", "character": @@ -257,7 +268,9 @@ func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) return nil, err } indexName = strings.Trim(indexName, `" `) - + if strings.HasSuffix(indexName, "_pkey") { + continue + } if strings.HasPrefix(indexdef, "CREATE UNIQUE INDEX") { indexType = core.UniqueType } else { @@ -266,9 +279,6 @@ func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) cs := strings.Split(indexdef, "(") colNames = strings.Split(cs[1][0:len(cs[1])-1], ",") - if strings.HasSuffix(indexName, "_pkey") { - continue - } if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { newIdxName := indexName[5+len(tableName) : len(indexName)] if newIdxName != "" { diff --git a/statement.go b/statement.go index 865e67d3..33aa20a7 100644 --- a/statement.go +++ b/statement.go @@ -264,7 +264,6 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, colNames := make([]string, 0) var args = make([]interface{}, 0) - fmt.Println(table.ColumnsSeq()) for _, col := range table.Columns() { if !includeVersion && col.IsVersion { continue @@ -282,7 +281,7 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text { continue } - fmt.Println("===", col.Name) + fieldValuePtr, err := col.ValueOf(bean) if err != nil { engine.LogError(err) @@ -326,11 +325,9 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, goto APPEND } - fmt.Println(col.Name, "is", fieldValue) if fieldType.Kind() == reflect.Ptr { if fieldValue.IsNil() { if includeNil { - fmt.Println(col.Name, "is nil") args = append(args, nil) colNames = append(colNames, fmt.Sprintf("%v=?", engine.Quote(col.Name))) }