Browse Source

bug fixed

xormplus 9 years ago
parent
commit
b5a7f8a37c
5 changed files with 207 additions and 168 deletions
  1. 88 61
      engine.go
  2. 25 29
      rows.go
  3. 90 74
      session.go
  4. 3 3
      test/xorm_test.go
  5. 1 1
      xorm.go

+ 88 - 61
engine.go

@@ -164,11 +164,16 @@ func (engine *Engine) quoteTable(keyName string) string {
 	return engine.dialect.QuoteStr() + keyName + engine.dialect.QuoteStr()
 }
 
-// SqlType A simple wrapper to dialect's core.SqlType method
+// SqlType will be depracated, please use SQLType instead
 func (engine *Engine) SqlType(c *core.Column) string {
 	return engine.dialect.SqlType(c)
 }
 
+// SQLType A simple wrapper to dialect's core.SqlType method
+func (engine *Engine) SQLType(c *core.Column) string {
+	return engine.dialect.SqlType(c)
+}
+
 // AutoIncrStr Database's autoincrement statement
 func (engine *Engine) AutoIncrStr() string {
 	return engine.dialect.AutoIncrStr()
@@ -268,9 +273,8 @@ func (engine *Engine) logSQLQueryTime(sqlStr string, args []interface{}, executi
 			engine.logger.Infof("[sql] %s - took: %v", sqlStr, execDuration)
 		}
 		return stmt, res, err
-	} else {
-		return executionBlock()
 	}
+	return executionBlock()
 }
 
 func (engine *Engine) logSQLExecutionTime(sqlStr string, args []interface{}, executionBlock func() (sql.Result, error)) (sql.Result, error) {
@@ -284,23 +288,30 @@ func (engine *Engine) logSQLExecutionTime(sqlStr string, args []interface{}, exe
 			engine.logger.Infof("[sql] %s - took: %v", sqlStr, execDuration)
 		}
 		return res, err
-	} else {
-		return executionBlock()
 	}
+	return executionBlock()
+
+}
+
+// Sql will be depracated, please use SQL instead
+func (engine *Engine) Sql(querystring string, args ...interface{}) *Session {
+	session := engine.NewSession()
+	session.IsAutoClose = true
+	session.IsSqlFuc = true
+	return session.Sql(querystring, args...)
 }
 
-// Sql method let's you manualy write raw sql and operate
+// SQL method let's you manualy write raw SQL and operate
 // For example:
 //
-//         engine.Sql("select * from user").Find(&users)
+//         engine.SQL("select * from user").Find(&users)
 //
 // This    code will execute "select * from user" and set the records to users
-//
-func (engine *Engine) Sql(querystring string, args ...interface{}) *Session {
+func (engine *Engine) SQL(querystring string, args ...interface{}) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	session.IsSqlFuc = true
-	return session.Sql(querystring, args...)
+	return session.SQL(querystring, args...)
 }
 
 // NoAutoTime Default if your struct has "created" or "updated" filed tag, the fields
@@ -622,7 +633,7 @@ func (engine *Engine) dumpTables(tables []*core.Table, w io.Writer, tp ...core.D
 	return nil
 }
 
-// use cascade or not
+// Cascade use cascade or not
 func (engine *Engine) Cascade(trueOrFalse ...bool) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
@@ -636,42 +647,49 @@ func (engine *Engine) Where(querystring string, args ...interface{}) *Session {
 	return session.Where(querystring, args...)
 }
 
-// Id mehtod provoide a condition as (id) = ?
+// Id will be depracated, please use ID instead
 func (engine *Engine) Id(id interface{}) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Id(id)
 }
 
-// Apply before Processor, affected bean is passed to closure arg
+// ID mehtod provoide a condition as (id) = ?
+func (engine *Engine) ID(id interface{}) *Session {
+	session := engine.NewSession()
+	session.IsAutoClose = true
+	return session.ID(id)
+}
+
+// Before apply before Processor, affected bean is passed to closure arg
 func (engine *Engine) Before(closures func(interface{})) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Before(closures)
 }
 
-// Apply after insert Processor, affected bean is passed to closure arg
+// After apply after insert Processor, affected bean is passed to closure arg
 func (engine *Engine) After(closures func(interface{})) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.After(closures)
 }
 
-// set charset when create table, only support mysql now
+// Charset set charset when create table, only support mysql now
 func (engine *Engine) Charset(charset string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Charset(charset)
 }
 
-// set store engine when create table, only support mysql now
+// StoreEngine set store engine when create table, only support mysql now
 func (engine *Engine) StoreEngine(storeEngine string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.StoreEngine(storeEngine)
 }
 
-// use for distinct columns. Caution: when you are using cache,
+// Distinct use for distinct columns. Caution: when you are using cache,
 // distinct will not be cached because cache system need id,
 // but distinct will not provide id
 func (engine *Engine) Distinct(columns ...string) *Session {
@@ -680,32 +698,35 @@ func (engine *Engine) Distinct(columns ...string) *Session {
 	return session.Distinct(columns...)
 }
 
+// Select customerize your select columns or contents
 func (engine *Engine) Select(str string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Select(str)
 }
 
-// only use the paramters as select or update columns
+// Cols only use the paramters as select or update columns
 func (engine *Engine) Cols(columns ...string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Cols(columns...)
 }
 
+// AllCols indicates that all columns should be use
 func (engine *Engine) AllCols() *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.AllCols()
 }
 
+// MustCols specify some columns must use even if they are empty
 func (engine *Engine) MustCols(columns ...string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.MustCols(columns...)
 }
 
-// Xorm automatically retrieve condition according struct, but
+// UseBool xorm automatically retrieve condition according struct, but
 // if struct has bool field, it will ignore them. So use UseBool
 // to tell system to do not ignore them.
 // If no paramters, it will use all the bool field of struct, or
@@ -716,78 +737,77 @@ func (engine *Engine) UseBool(columns ...string) *Session {
 	return session.UseBool(columns...)
 }
 
-// Only not use the paramters as select or update columns
+// Omit only not use the paramters as select or update columns
 func (engine *Engine) Omit(columns ...string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Omit(columns...)
 }
 
-// Set null when column is zero-value and nullable for update
+// Nullable set null when column is zero-value and nullable for update
 func (engine *Engine) Nullable(columns ...string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Nullable(columns...)
 }
 
-// This method will generate "column IN (?, ?)"
+// In will generate "column IN (?, ?)"
 func (engine *Engine) In(column string, args ...interface{}) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.In(column, args...)
 }
 
-// Method Inc provides a update string like "column = column + ?"
+// Incr provides a update string like "column = column + ?"
 func (engine *Engine) Incr(column string, arg ...interface{}) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Incr(column, arg...)
 }
 
-// Method Decr provides a update string like "column = column - ?"
+// Decr provides a update string like "column = column - ?"
 func (engine *Engine) Decr(column string, arg ...interface{}) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Decr(column, arg...)
 }
 
-// Method SetExpr provides a update string like "column = {expression}"
+// SetExpr provides a update string like "column = {expression}"
 func (engine *Engine) SetExpr(column string, expression string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.SetExpr(column, expression)
 }
 
-// Temporarily change the Get, Find, Update's table
+// Table temporarily change the Get, Find, Update's table
 func (engine *Engine) Table(tableNameOrBean interface{}) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Table(tableNameOrBean)
 }
 
-// set the table alias
+// Alias set the table alias
 func (engine *Engine) Alias(alias string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Alias(alias)
 }
 
-// This method will generate "LIMIT start, limit"
+// Limit will generate "LIMIT start, limit"
 func (engine *Engine) Limit(limit int, start ...int) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Limit(limit, start...)
 }
 
-// Method Desc will generate "ORDER BY column1 DESC, column2 DESC"
-// This will
+// Desc will generate "ORDER BY column1 DESC, column2 DESC"
 func (engine *Engine) Desc(colNames ...string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.Desc(colNames...)
 }
 
-// Method Asc will generate "ORDER BY column1,column2 Asc"
+// Asc will generate "ORDER BY column1,column2 Asc"
 // This method can chainable use.
 //
 //        engine.Desc("name").Asc("age").Find(&users)
@@ -799,28 +819,28 @@ func (engine *Engine) Asc(colNames ...string) *Session {
 	return session.Asc(colNames...)
 }
 
-// Method OrderBy will generate "ORDER BY order"
+// OrderBy will generate "ORDER BY order"
 func (engine *Engine) OrderBy(order string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.OrderBy(order)
 }
 
-// The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN
-func (engine *Engine) Join(join_operator string, tablename interface{}, condition string, args ...interface{}) *Session {
+// Join the join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN
+func (engine *Engine) Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
-	return session.Join(join_operator, tablename, condition, args...)
+	return session.Join(joinOperator, tablename, condition, args...)
 }
 
-// Generate Group By statement
+// GroupBy generate group by statement
 func (engine *Engine) GroupBy(keys string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
 	return session.GroupBy(keys)
 }
 
-// Generate Having statement
+// Having generate having statement
 func (engine *Engine) Having(conditions string) *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true
@@ -846,17 +866,20 @@ func (engine *Engine) autoMapType(v reflect.Value) *core.Table {
 	return table
 }
 
+// GobRegister register one struct to gob for cache use
 func (engine *Engine) GobRegister(v interface{}) *Engine {
 	//fmt.Printf("Type: %[1]T => Data: %[1]#v\n", v)
 	gob.Register(v)
 	return engine
 }
 
+// Table table struct
 type Table struct {
 	*core.Table
 	Name string
 }
 
+// TableInfo get table info according to bean's content
 func (engine *Engine) TableInfo(bean interface{}) *Table {
 	v := rValue(bean)
 	return &Table{engine.autoMapType(v), engine.tbName(v)}
@@ -883,6 +906,7 @@ func (engine *Engine) newTable() *core.Table {
 	return table
 }
 
+// TableName table name interface to define customerize table name
 type TableName interface {
 	TableName() string
 }
@@ -1039,7 +1063,7 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
 								preKey = k
 								continue
 							}
-							col.SQLType = core.SQLType{fs[0], 0, 0}
+							col.SQLType = core.SQLType{Name: fs[0]}
 							if fs[0] == core.Enum && fs[1][0] == '\'' { //enum
 								options := strings.Split(fs[1][0:len(fs[1])-1], ",")
 								col.EnumOptions = make(map[string]int)
@@ -1076,7 +1100,7 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
 							}
 						} else {
 							if _, ok := core.SqlTypes[k]; ok {
-								col.SQLType = core.SQLType{k, 0, 0}
+								col.SQLType = core.SQLType{Name: k}
 							} else if key != col.Default {
 								col.Name = key
 							}
@@ -1113,11 +1137,11 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
 			var sqlType core.SQLType
 			if fieldValue.CanAddr() {
 				if _, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
-					sqlType = core.SQLType{core.Text, 0, 0}
+					sqlType = core.SQLType{Name: core.Text}
 				}
 			}
 			if _, ok := fieldValue.Interface().(core.Conversion); ok {
-				sqlType = core.SQLType{core.Text, 0, 0}
+				sqlType = core.SQLType{Name: core.Text}
 			} else {
 				sqlType = core.Type2SQLType(fieldType)
 			}
@@ -1173,24 +1197,26 @@ func (engine *Engine) mapping(beans ...interface{}) (e error) {
 	return
 }
 
-// If a table has any reocrd
+// IsTableEmpty if a table has any reocrd
 func (engine *Engine) IsTableEmpty(bean interface{}) (bool, error) {
 	session := engine.NewSession()
 	defer session.Close()
 	return session.IsTableEmpty(bean)
 }
 
-// If a table is exist
+// IsTableExist if a table is exist
 func (engine *Engine) IsTableExist(beanOrTableName interface{}) (bool, error) {
 	session := engine.NewSession()
 	defer session.Close()
 	return session.IsTableExist(beanOrTableName)
 }
 
+// IdOf get id from one struct
 func (engine *Engine) IdOf(bean interface{}) core.PK {
 	return engine.IdOfV(reflect.ValueOf(bean))
 }
 
+// IdOfV get id from one value of struct
 func (engine *Engine) IdOfV(rv reflect.Value) core.PK {
 	v := reflect.Indirect(rv)
 	table := engine.autoMapType(v)
@@ -1209,14 +1235,14 @@ func (engine *Engine) IdOfV(rv reflect.Value) core.PK {
 	return core.PK(pk)
 }
 
-// create indexes
+// CreateIndexes create indexes
 func (engine *Engine) CreateIndexes(bean interface{}) error {
 	session := engine.NewSession()
 	defer session.Close()
 	return session.CreateIndexes(bean)
 }
 
-// create uniques
+// CreateUniques create uniques
 func (engine *Engine) CreateUniques(bean interface{}) error {
 	session := engine.NewSession()
 	defer session.Close()
@@ -1234,7 +1260,7 @@ func (engine *Engine) getCacher(v reflect.Value) core.Cacher {
 	return engine.Cacher
 }
 
-// If enabled cache, clear the cache bean
+// ClearCacheBean if enabled cache, clear the cache bean
 func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
 	v := rValue(bean)
 	t := v.Type()
@@ -1254,7 +1280,7 @@ func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
 	return nil
 }
 
-// If enabled cache, clear some tables' cache
+// ClearCache if enabled cache, clear some tables' cache
 func (engine *Engine) ClearCache(beans ...interface{}) error {
 	for _, bean := range beans {
 		v := rValue(bean)
@@ -1373,6 +1399,7 @@ func (engine *Engine) Sync(beans ...interface{}) error {
 	return nil
 }
 
+// Sync2 synchronize structs to database tables
 func (engine *Engine) Sync2(beans ...interface{}) error {
 	s := engine.NewSession()
 	defer s.Close()
@@ -1428,6 +1455,7 @@ func (engine *Engine) CreateTables(beans ...interface{}) error {
 	return session.Commit()
 }
 
+// DropTables drop specify tables
 func (engine *Engine) DropTables(beans ...interface{}) error {
 	session := engine.NewSession()
 	defer session.Close()
@@ -1460,7 +1488,7 @@ func (engine *Engine) Exec(sql string, args ...interface{}) (sql.Result, error)
 	return session.Exec(sql, args...)
 }
 
-// Exec a raw sql and return records as []map[string][]byte
+// Query a raw sql and return records as []map[string][]byte
 func (engine *Engine) Query(sql string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) {
 	session := engine.NewSession()
 	defer session.Close()
@@ -1481,7 +1509,7 @@ func (engine *Engine) Insert(beans ...interface{}) (int64, error) {
 	return session.Insert(beans...)
 }
 
-// Insert only one record
+// InsertOne insert only one record
 func (engine *Engine) InsertOne(bean interface{}) (int64, error) {
 	session := engine.NewSession()
 	defer session.Close()
@@ -1532,15 +1560,14 @@ func (engine *Engine) Iterate(bean interface{}, fun IterFunc) error {
 	return session.Iterate(bean, fun)
 }
 
-// Return sql.Rows compatible Rows obj, as a forward Iterator object for iterating record by record, bean's non-empty fields
+// Rows return sql.Rows compatible Rows obj, as a forward Iterator object for iterating record by record, bean's non-empty fields
 // are conditions.
 func (engine *Engine) Rows(bean interface{}) (*Rows, error) {
 	session := engine.NewSession()
 	return session.Rows(bean)
 }
 
-// Count counts the records. bean's non-empty fields
-// are conditions.
+// Count counts the records. bean's non-empty fields are conditions.
 func (engine *Engine) Count(bean interface{}) (int64, error) {
 	session := engine.NewSession()
 	defer session.Close()
@@ -1568,7 +1595,7 @@ func (engine *Engine) SumsInt(bean interface{}, colNames ...string) ([]int64, er
 	return session.SumsInt(bean, colNames...)
 }
 
-// Import SQL DDL file
+// ImportFile SQL DDL file
 func (engine *Engine) ImportFile(ddlPath string) ([]sql.Result, error) {
 	file, err := os.Open(ddlPath)
 	if err != nil {
@@ -1578,7 +1605,7 @@ func (engine *Engine) ImportFile(ddlPath string) ([]sql.Result, error) {
 	return engine.Import(file)
 }
 
-// Import SQL DDL file
+// Import SQL DDL from io.Reader
 func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
 	var results []sql.Result
 	var lastError error
@@ -1609,7 +1636,7 @@ func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
 			results = append(results, result)
 			if err != nil {
 				return nil, err
-				lastError = err
+				//lastError = err
 			}
 		}
 	}
@@ -1617,27 +1644,27 @@ func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
 	return results, lastError
 }
 
-var (
-	NULL_TIME time.Time
-)
-
+// TZTime change one time to xorm time location
 func (engine *Engine) TZTime(t time.Time) time.Time {
-	if NULL_TIME != t { // if time is not initialized it's not suitable for Time.In()
+	if !t.IsZero() { // if time is not initialized it's not suitable for Time.In()
 		return t.In(engine.TZLocation)
 	}
 	return t
 }
 
+// NowTime return current time
 func (engine *Engine) NowTime(sqlTypeName string) interface{} {
 	t := time.Now()
 	return engine.FormatTime(sqlTypeName, t)
 }
 
+// NowTime2 return current time
 func (engine *Engine) NowTime2(sqlTypeName string) (interface{}, time.Time) {
 	t := time.Now()
 	return engine.FormatTime(sqlTypeName, t), t
 }
 
+// FormatTime format time
 func (engine *Engine) FormatTime(sqlTypeName string, t time.Time) (v interface{}) {
 	return engine.formatTime(engine.TZLocation, sqlTypeName, t)
 }
@@ -1688,7 +1715,7 @@ func (engine *Engine) formatTime(tz *time.Location, sqlTypeName string, t time.T
 	return
 }
 
-// Always disable struct tag "deleted"
+// Unscoped always disable struct tag "deleted"
 func (engine *Engine) Unscoped() *Session {
 	session := engine.NewSession()
 	session.IsAutoClose = true

+ 25 - 29
rows.go

@@ -12,6 +12,7 @@ import (
 	"github.com/xormplus/core"
 )
 
+// Rows rows wrapper a rows to
 type Rows struct {
 	NoTypeCheck bool
 
@@ -52,24 +53,33 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
 
 	rows.session.saveLastSQL(sqlStr, args)
 	var err error
-	rows.stmt, err = rows.session.DB().Prepare(sqlStr)
-	if err != nil {
-		rows.lastError = err
-		defer rows.Close()
-		return nil, err
-	}
+	if rows.session.prepareStmt {
+		rows.stmt, err = rows.session.DB().Prepare(sqlStr)
+		if err != nil {
+			rows.lastError = err
+			rows.Close()
+			return nil, err
+		}
 
-	rows.rows, err = rows.stmt.Query(args...)
-	if err != nil {
-		rows.lastError = err
-		defer rows.Close()
-		return nil, err
+		rows.rows, err = rows.stmt.Query(args...)
+		if err != nil {
+			rows.lastError = err
+			rows.Close()
+			return nil, err
+		}
+	} else {
+		rows.rows, err = rows.session.DB().Query(sqlStr, args...)
+		if err != nil {
+			rows.lastError = err
+			rows.Close()
+			return nil, err
+		}
 	}
 
 	rows.fields, err = rows.rows.Columns()
 	if err != nil {
 		rows.lastError = err
-		defer rows.Close()
+		rows.Close()
 		return nil, err
 	}
 	rows.fieldsCount = len(rows.fields)
@@ -77,7 +87,7 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
 	return rows, nil
 }
 
-// move cursor to next record, return false if end has reached
+// Next move cursor to next record, return false if end has reached
 func (rows *Rows) Next() bool {
 	if rows.lastError == nil && rows.rows != nil {
 		hasNext := rows.rows.Next()
@@ -94,7 +104,7 @@ func (rows *Rows) Err() error {
 	return rows.lastError
 }
 
-// scan row record to bean properties
+// Scan row record to bean properties
 func (rows *Rows) Scan(bean interface{}) error {
 	if rows.lastError != nil {
 		return rows.lastError
@@ -105,23 +115,9 @@ func (rows *Rows) Scan(bean interface{}) error {
 	}
 
 	return rows.session.row2Bean(rows.rows, rows.fields, rows.fieldsCount, bean)
-
-	// result, err := row2map(rows.rows, rows.fields) // !nashtsai! TODO remove row2map then scanMapIntoStruct conversation for better performance
-	// if err == nil {
-	// 	err = rows.session.scanMapIntoStruct(bean, result)
-	// }
-	// return err
 }
 
-// // Columns returns the column names. Columns returns an error if the rows are closed, or if the rows are from QueryRow and there was a deferred error.
-// func (rows *Rows) Columns() ([]string, error) {
-// 	if rows.lastError == nil && rows.rows != nil {
-// 		return rows.rows.Columns()
-// 	}
-// 	return nil, rows.lastError
-// }
-
-// close session if session.IsAutoClose is true, and claimed any opened resources
+// Close session if session.IsAutoClose is true, and claimed any opened resources
 func (rows *Rows) Close() error {
 	if rows.session.IsAutoClose {
 		defer rows.session.Close()

+ 90 - 74
session.go

@@ -108,19 +108,25 @@ func (session *Session) resetStatement() {
 	}
 }
 
-// Prepare
+// Prepare set a flag to session that should be prepare statment before execute query
 func (session *Session) Prepare() *Session {
 	session.prepareStmt = true
 	return session
 }
 
-// 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.
+// Sql will be deprecated, please use SQL instead.
 func (session *Session) Sql(querystring string, args ...interface{}) *Session {
 	session.Statement.Sql(querystring, args...)
 	return session
 }
 
+// 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 {
+	session.Statement.Sql(querystring, args...)
+	return session
+}
+
 // Where provides custom query condition.
 func (session *Session) Where(querystring string, args ...interface{}) *Session {
 	session.Statement.Where(querystring, args...)
@@ -139,12 +145,18 @@ func (session *Session) Or(querystring string, args ...interface{}) *Session {
 	return session
 }
 
-// Id provides converting id as a query condition
+// Id will be deprecated, please use ID instead
 func (session *Session) Id(id interface{}) *Session {
 	session.Statement.Id(id)
 	return session
 }
 
+// ID provides converting id as a query condition
+func (session *Session) ID(id interface{}) *Session {
+	session.Statement.Id(id)
+	return session
+}
+
 // Before Apply before Processor, affected bean is passed to closure arg
 func (session *Session) Before(closures func(interface{})) *Session {
 	if closures != nil {
@@ -215,13 +227,13 @@ func (session *Session) AllCols() *Session {
 	return session
 }
 
-// MustCols
+// MustCols specify some columns must use even if they are empty
 func (session *Session) MustCols(columns ...string) *Session {
 	session.Statement.MustCols(columns...)
 	return session
 }
 
-// NoCascade
+// NoCascade indicate that no cascade load child object
 func (session *Session) NoCascade() *Session {
 	session.Statement.UseCascade = false
 	return session
@@ -276,44 +288,44 @@ func (session *Session) NoAutoCondition(no ...bool) *Session {
 	return session
 }
 
-// Method Limit provide limit and offset query condition
+// Limit provide limit and offset query condition
 func (session *Session) Limit(limit int, start ...int) *Session {
 	session.Statement.Limit(limit, start...)
 	return session
 }
 
-// Method OrderBy provide order by query condition, the input parameter is the content
+// OrderBy provide order by query condition, the input parameter is the content
 // after order by on a sql statement.
 func (session *Session) OrderBy(order string) *Session {
 	session.Statement.OrderBy(order)
 	return session
 }
 
-// Method Desc provide desc order by query condition, the input parameters are columns.
+// Desc provide desc order by query condition, the input parameters are columns.
 func (session *Session) Desc(colNames ...string) *Session {
 	session.Statement.Desc(colNames...)
 	return session
 }
 
-// Method Asc provide asc order by query condition, the input parameters are columns.
+// Asc provide asc order by query condition, the input parameters are columns.
 func (session *Session) Asc(colNames ...string) *Session {
 	session.Statement.Asc(colNames...)
 	return session
 }
 
-// Method StoreEngine is only avialble mysql dialect currently
+// StoreEngine is only avialble mysql dialect currently
 func (session *Session) StoreEngine(storeEngine string) *Session {
 	session.Statement.StoreEngine = storeEngine
 	return session
 }
 
-// Method Charset is only avialble mysql dialect currently
+// Charset is only avialble mysql dialect currently
 func (session *Session) Charset(charset string) *Session {
 	session.Statement.Charset = charset
 	return session
 }
 
-// Method Cascade indicates if loading sub Struct
+// Cascade indicates if loading sub Struct
 func (session *Session) Cascade(trueOrFalse ...bool) *Session {
 	if len(trueOrFalse) >= 1 {
 		session.Statement.UseCascade = trueOrFalse[0]
@@ -505,6 +517,7 @@ func (session *Session) innerExec(sqlStr string, args ...interface{}) (sql.Resul
 
 func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, error) {
 	for _, filter := range session.Engine.dialect.Filters() {
+		// TODO: for table name, it's no need to RefTable
 		sqlStr = filter.Do(sqlStr, session.Engine.dialect, session.Statement.RefTable)
 	}
 
@@ -612,7 +625,7 @@ func (session *Session) createAll() error {
 	return nil
 }
 
-// drop indexes
+// DropIndexes drop indexes
 func (session *Session) DropIndexes(bean interface{}) error {
 	v := rValue(bean)
 	session.Statement.setRefValue(v)
@@ -632,7 +645,7 @@ func (session *Session) DropIndexes(bean interface{}) error {
 	return nil
 }
 
-// drop table will drop table if exist, if drop failed, it will return error
+// DropTable drop table will drop table if exist, if drop failed, it will return error
 func (session *Session) DropTable(beanOrTableName interface{}) error {
 	tableName, err := session.Engine.tableName(beanOrTableName)
 	if err != nil {
@@ -839,8 +852,8 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
 	sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
 
 	ididxes := make(map[string]int)
-	var ides []core.PK = make([]core.PK, 0)
-	var temps []interface{} = make([]interface{}, len(ids))
+	var ides []core.PK
+	var temps = make([]interface{}, len(ids))
 
 	for idx, id := range ids {
 		sid, err := id.ToString()
@@ -1016,16 +1029,15 @@ func (session *Session) Get(bean interface{}) (bool, error) {
 	}
 
 	session.Statement.setRefValue(rValue(bean))
-	if len(session.Statement.TableName()) <= 0 {
-		return false, ErrTableNotFound
-	}
-
-	session.Statement.Limit(1)
 
 	var sqlStr string
 	var args []interface{}
 
 	if session.Statement.RawSQL == "" {
+		if len(session.Statement.TableName()) <= 0 {
+			return false, ErrTableNotFound
+		}
+		session.Statement.Limit(1)
 		sqlStr, args = session.Statement.genGetSql(bean)
 	} else {
 		sqlStr = session.Statement.RawSQL
@@ -1163,6 +1175,7 @@ func (session *Session) Sums(bean interface{}, columnNames ...string) ([]float64
 	return res, nil
 }
 
+// SumsInt sum specify columns and return as []int64 instead of []float64
 func (session *Session) SumsInt(bean interface{}, columnNames ...string) ([]int64, error) {
 	defer session.resetStatement()
 	if session.IsAutoClose {
@@ -1226,10 +1239,6 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
 		}
 	}
 
-	if len(session.Statement.TableName()) <= 0 {
-		return ErrTableNotFound
-	}
-
 	var table = session.Statement.RefTable
 
 	var addedTableName = (len(session.Statement.JoinStr) > 0)
@@ -1257,6 +1266,10 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
 	var sqlStr string
 	var args []interface{}
 	if session.Statement.RawSQL == "" {
+		if len(session.Statement.TableName()) <= 0 {
+			return ErrTableNotFound
+		}
+
 		var columnStr = session.Statement.ColumnStr
 		if len(session.Statement.selectStr) > 0 {
 			columnStr = session.Statement.selectStr
@@ -1527,9 +1540,8 @@ func (session *Session) isIndexExist2(tableName string, cols []string, unique bo
 		if sliceEq(index.Cols, cols) {
 			if unique {
 				return index.Type == core.UniqueType, nil
-			} else {
-				return index.Type == core.IndexType, nil
 			}
+			return index.Type == core.IndexType, nil
 		}
 	}
 	return false, nil
@@ -1610,6 +1622,7 @@ func (session *Session) getField(dataStruct *reflect.Value, key string, table *c
 	return fieldValue
 }
 
+// Cell cell is a result of one column field
 type Cell *interface{}
 
 func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount int,
@@ -1960,7 +1973,7 @@ func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount
 								//fieldValue.Set(reflect.ValueOf(v))
 								fieldValue.Set(structInter.Elem())
 							} else {
-								return errors.New("cascade obj is not exist!")
+								return errors.New("cascade obj is not exist")
 							}
 						}
 					} else {
@@ -3599,7 +3612,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
 		}
 	}
 
-	var sqlStr, inSql string
+	var sqlStr, inSQL string
 	var inArgs []interface{}
 	doIncVer := false
 	var verValue *reflect.Value
@@ -3610,12 +3623,12 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
 		} else {
 			condition = fmt.Sprintf("WHERE %v = ?", session.Engine.Quote(table.Version))
 		}
-		inSql, inArgs = session.Statement.genInSql()
-		if len(inSql) > 0 {
+		inSQL, inArgs = session.Statement.genInSql()
+		if len(inSQL) > 0 {
 			if condition != "" {
-				condition += " " + session.Engine.Dialect().AndStr() + " " + inSql
+				condition += " " + session.Engine.Dialect().AndStr() + " " + inSQL
 			} else {
-				condition = "WHERE " + inSql
+				condition = "WHERE " + inSQL
 			}
 		}
 
@@ -3640,12 +3653,12 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
 		if condition != "" {
 			condition = "WHERE " + condition
 		}
-		inSql, inArgs = session.Statement.genInSql()
-		if len(inSql) > 0 {
+		inSQL, inArgs = session.Statement.genInSql()
+		if len(inSQL) > 0 {
 			if condition != "" {
-				condition += " " + session.Engine.Dialect().AndStr() + " " + inSql
+				condition += " " + session.Engine.Dialect().AndStr() + " " + inSQL
 			} else {
-				condition = "WHERE " + inSql
+				condition = "WHERE " + inSQL
 			}
 		}
 
@@ -3815,62 +3828,62 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
 	} else {
 		condition = strings.Join(colNames, " "+andStr+" ")
 	}
-	inSql, inArgs := session.Statement.genInSql()
-	if len(inSql) > 0 {
+	inSQL, inArgs := session.Statement.genInSql()
+	if len(inSQL) > 0 {
 		if len(condition) > 0 {
 			condition += " " + andStr + " "
 		}
-		condition += inSql
+		condition += inSQL
 		args = append(args, inArgs...)
 	}
 	if len(condition) == 0 && session.Statement.LimitN == 0 {
 		return 0, ErrNeedDeletedCond
 	}
 
-	var deleteSql, realSql string
+	var deleteSQL, realSQL string
 	var tableName = session.Engine.Quote(session.Statement.TableName())
 
 	if len(condition) > 0 {
-		deleteSql = fmt.Sprintf("DELETE FROM %v WHERE %v", tableName, condition)
+		deleteSQL = fmt.Sprintf("DELETE FROM %v WHERE %v", tableName, condition)
 	} else {
-		deleteSql = fmt.Sprintf("DELETE FROM %v", tableName)
+		deleteSQL = fmt.Sprintf("DELETE FROM %v", tableName)
 	}
 
-	var orderSql string
+	var orderSQL string
 	if len(session.Statement.OrderStr) > 0 {
-		orderSql += fmt.Sprintf(" ORDER BY %s", session.Statement.OrderStr)
+		orderSQL += fmt.Sprintf(" ORDER BY %s", session.Statement.OrderStr)
 	}
 	if session.Statement.LimitN > 0 {
-		orderSql += fmt.Sprintf(" LIMIT %d", session.Statement.LimitN)
+		orderSQL += fmt.Sprintf(" LIMIT %d", session.Statement.LimitN)
 	}
 
-	if len(orderSql) > 0 {
+	if len(orderSQL) > 0 {
 		switch session.Engine.dialect.DBType() {
 		case core.POSTGRES:
-			inSql := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSql)
+			inSQL := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSQL)
 			if len(condition) > 0 {
-				deleteSql += " AND " + inSql
+				deleteSQL += " AND " + inSQL
 			} else {
-				deleteSql += " WHERE " + inSql
+				deleteSQL += " WHERE " + inSQL
 			}
 		case core.SQLITE:
-			inSql := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSql)
+			inSQL := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSQL)
 			if len(condition) > 0 {
-				deleteSql += " AND " + inSql
+				deleteSQL += " AND " + inSQL
 			} else {
-				deleteSql += " WHERE " + inSql
+				deleteSQL += " WHERE " + inSQL
 			}
 		// TODO: how to handle delete limit on mssql?
 		case core.MSSQL:
 			return 0, ErrNotImplemented
 		default:
-			deleteSql += orderSql
+			deleteSQL += orderSQL
 		}
 	}
 
 	argsForCache := make([]interface{}, 0, len(args)*2)
 	if session.Statement.unscoped || table.DeletedColumn() == nil { // tag "deleted" is disabled
-		realSql = deleteSql
+		realSQL = deleteSQL
 		copy(argsForCache, args)
 		argsForCache = append(session.Statement.Params, argsForCache...)
 	} else {
@@ -3879,32 +3892,32 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
 		argsForCache = append(session.Statement.Params, argsForCache...)
 
 		deletedColumn := table.DeletedColumn()
-		realSql = fmt.Sprintf("UPDATE %v SET %v = ? WHERE %v",
+		realSQL = fmt.Sprintf("UPDATE %v SET %v = ? WHERE %v",
 			session.Engine.Quote(session.Statement.TableName()),
 			session.Engine.Quote(deletedColumn.Name),
 			condition)
 
-		if len(orderSql) > 0 {
+		if len(orderSQL) > 0 {
 			switch session.Engine.dialect.DBType() {
 			case core.POSTGRES:
-				inSql := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSql)
+				inSQL := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSQL)
 				if len(condition) > 0 {
-					realSql += " AND " + inSql
+					realSQL += " AND " + inSQL
 				} else {
-					realSql += " WHERE " + inSql
+					realSQL += " WHERE " + inSQL
 				}
 			case core.SQLITE:
-				inSql := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSql)
+				inSQL := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSQL)
 				if len(condition) > 0 {
-					realSql += " AND " + inSql
+					realSQL += " AND " + inSQL
 				} else {
-					realSql += " WHERE " + inSql
+					realSQL += " WHERE " + inSQL
 				}
 			// TODO: how to handle delete limit on mssql?
 			case core.MSSQL:
 				return 0, ErrNotImplemented
 			default:
-				realSql += orderSql
+				realSQL += orderSQL
 			}
 		}
 
@@ -3926,10 +3939,10 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
 	args = append(session.Statement.Params, args...)
 
 	if cacher := session.Engine.getCacher2(session.Statement.RefTable); cacher != nil && session.Statement.UseCache {
-		session.cacheDelete(deleteSql, argsForCache...)
+		session.cacheDelete(deleteSQL, argsForCache...)
 	}
 
-	res, err := session.exec(realSql, args...)
+	res, err := session.exec(realSQL, args...)
 	if err != nil {
 		return 0, err
 	}
@@ -3986,8 +3999,8 @@ func (session *Session) tbNameNoSchema(table *core.Table) string {
 }
 
 // Sync2 synchronize structs to database tables
-func (s *Session) Sync2(beans ...interface{}) error {
-	engine := s.Engine
+func (session *Session) Sync2(beans ...interface{}) error {
+	engine := session.Engine
 
 	tables, err := engine.DBMetas()
 	if err != nil {
@@ -4000,7 +4013,7 @@ func (s *Session) Sync2(beans ...interface{}) error {
 		v := rValue(bean)
 		table := engine.mapType(v)
 		structTables = append(structTables, table)
-		var tbName = s.tbNameNoSchema(table)
+		var tbName = session.tbNameNoSchema(table)
 
 		var oriTable *core.Table
 		for _, tb := range tables {
@@ -4011,17 +4024,17 @@ func (s *Session) Sync2(beans ...interface{}) error {
 		}
 
 		if oriTable == nil {
-			err = s.StoreEngine(s.Statement.StoreEngine).CreateTable(bean)
+			err = session.StoreEngine(session.Statement.StoreEngine).CreateTable(bean)
 			if err != nil {
 				return err
 			}
 
-			err = s.CreateUniques(bean)
+			err = session.CreateUniques(bean)
 			if err != nil {
 				return err
 			}
 
-			err = s.CreateIndexes(bean)
+			err = session.CreateIndexes(bean)
 			if err != nil {
 				return err
 			}
@@ -4085,6 +4098,7 @@ func (s *Session) Sync2(beans ...interface{}) error {
 				} else {
 					session := engine.NewSession()
 					session.Statement.RefTable = table
+					session.Statement.tableName = tbName
 					defer session.Close()
 					err = session.addColumn(col.Name)
 				}
@@ -4136,11 +4150,13 @@ func (s *Session) Sync2(beans ...interface{}) error {
 				if index.Type == core.UniqueType {
 					session := engine.NewSession()
 					session.Statement.RefTable = table
+					session.Statement.tableName = tbName
 					defer session.Close()
 					err = session.addUnique(tbName, name)
 				} else if index.Type == core.IndexType {
 					session := engine.NewSession()
 					session.Statement.RefTable = table
+					session.Statement.tableName = tbName
 					defer session.Close()
 					err = session.addIndex(tbName, name)
 				}
@@ -4154,7 +4170,7 @@ func (s *Session) Sync2(beans ...interface{}) error {
 	for _, table := range tables {
 		var oriTable *core.Table
 		for _, structTable := range structTables {
-			if equalNoCase(table.Name, s.tbNameNoSchema(structTable)) {
+			if equalNoCase(table.Name, session.tbNameNoSchema(structTable)) {
 				oriTable = structTable
 				break
 			}

+ 3 - 3
test/xorm_test.go

@@ -483,7 +483,7 @@ func Test_Query(t *testing.T) {
 
 func Test_Sql_Execute(t *testing.T) {
 
-	result, err := db.Sql("INSERT INTO categories VALUES (?, ?, ?, ?, ?)", 18, "xiaozhang", 1, 1, 1).Execute()
+	result, err := db.Sql("INSERT INTO categories VALUES (?, ?, ?, ?, ?)", 138, "xiaozhang", 1, 1, 1).Execute()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -493,7 +493,7 @@ func Test_Sql_Execute(t *testing.T) {
 
 func Test_SqlMapClient_Execute(t *testing.T) {
 	db.AddSql("Test_SqlMapClient_Execute", "INSERT INTO categories VALUES (?id, ?name, ?counts, ?orders, ?pid)")
-	result, err := db.SqlMapClient("Test_SqlMapClient_Execute", &map[string]interface{}{"id": 19, "name": "xiaowang", "counts": 1, "orders": 1, "pid": 1}).Execute()
+	result, err := db.SqlMapClient("Test_SqlMapClient_Execute", &map[string]interface{}{"id": 139, "name": "xiaowang", "counts": 1, "orders": 1, "pid": 1}).Execute()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -503,7 +503,7 @@ func Test_SqlMapClient_Execute(t *testing.T) {
 
 func Test_SqlTemplateClientt_Execute(t *testing.T) {
 	db.AddSqlTemplate("Test_SqlTemplateClientt_Execute", "INSERT INTO categories VALUES (?id, ?name, ?counts, ?orders, ?pid)")
-	result, err := db.SqlTemplateClient("Test_SqlTemplateClientt_Execute", &map[string]interface{}{"id": 20, "name": "laowang", "counts": 1, "orders": 1, "pid": 1}).Execute()
+	result, err := db.SqlTemplateClient("Test_SqlTemplateClientt_Execute", &map[string]interface{}{"id": 230, "name": "laowang", "counts": 1, "orders": 1, "pid": 1}).Execute()
 	if err != nil {
 		t.Fatal(err)
 	}

+ 1 - 1
xorm.go

@@ -17,7 +17,7 @@ import (
 
 const (
 	// Version show the xorm's version
-	Version string = "0.5.5.0709"
+	Version string = "0.5.5.0711"
 )
 
 func regDrvsNDialects() bool {