diff --git a/models/action.go b/models/action.go
index 32b3dbd7bc..8793a4a24d 100644
--- a/models/action.go
+++ b/models/action.go
@@ -86,13 +86,7 @@ type Action struct {
 	IsPrivate   bool      `xorm:"INDEX NOT NULL DEFAULT false"`
 	Content     string    `xorm:"TEXT"`
 	Created     time.Time `xorm:"-"`
-	CreatedUnix int64     `xorm:"INDEX"`
-}
-
-// BeforeInsert will be invoked by XORM before inserting a record
-// representing this object.
-func (a *Action) BeforeInsert() {
-	a.CreatedUnix = time.Now().Unix()
+	CreatedUnix int64     `xorm:"INDEX created"`
 }
 
 // AfterSet updates the webhook object upon setting a column.
diff --git a/models/admin.go b/models/admin.go
index f8645202d8..eb78f6e865 100644
--- a/models/admin.go
+++ b/models/admin.go
@@ -29,12 +29,7 @@ type Notice struct {
 	Type        NoticeType
 	Description string    `xorm:"TEXT"`
 	Created     time.Time `xorm:"-"`
-	CreatedUnix int64     `xorm:"INDEX"`
-}
-
-// BeforeInsert is invoked from XORM before inserting an object of this type.
-func (n *Notice) BeforeInsert() {
-	n.CreatedUnix = time.Now().Unix()
+	CreatedUnix int64     `xorm:"INDEX created"`
 }
 
 // AfterSet is invoked from XORM after setting the value of a field of this object.
diff --git a/models/attachment.go b/models/attachment.go
index 3b3521bf60..2731ca4b7a 100644
--- a/models/attachment.go
+++ b/models/attachment.go
@@ -28,12 +28,7 @@ type Attachment struct {
 	Name          string
 	DownloadCount int64     `xorm:"DEFAULT 0"`
 	Created       time.Time `xorm:"-"`
-	CreatedUnix   int64
-}
-
-// BeforeInsert is invoked from XORM before inserting an object of this type.
-func (a *Attachment) BeforeInsert() {
-	a.CreatedUnix = time.Now().Unix()
+	CreatedUnix   int64     `xorm:"created"`
 }
 
 // AfterSet is invoked from XORM after setting the value of a field of
diff --git a/models/branches.go b/models/branches.go
index 6115f9c687..4461da0067 100644
--- a/models/branches.go
+++ b/models/branches.go
@@ -22,20 +22,9 @@ type ProtectedBranch struct {
 	BranchName  string `xorm:"UNIQUE(s)"`
 	CanPush     bool
 	Created     time.Time `xorm:"-"`
-	CreatedUnix int64
+	CreatedUnix int64     `xorm:"created"`
 	Updated     time.Time `xorm:"-"`
-	UpdatedUnix int64
-}
-
-// BeforeInsert before protected branch insert create and update time
-func (protectBranch *ProtectedBranch) BeforeInsert() {
-	protectBranch.CreatedUnix = time.Now().Unix()
-	protectBranch.UpdatedUnix = protectBranch.CreatedUnix
-}
-
-// BeforeUpdate before protected branch update time
-func (protectBranch *ProtectedBranch) BeforeUpdate() {
-	protectBranch.UpdatedUnix = time.Now().Unix()
+	UpdatedUnix int64     `xorm:"updated"`
 }
 
 // GetProtectedBranchByRepoID getting protected branch by repo ID
diff --git a/models/issue.go b/models/issue.go
index 8723dda913..2b71e0776d 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -54,23 +54,16 @@ type Issue struct {
 	Deadline     time.Time `xorm:"-"`
 	DeadlineUnix int64     `xorm:"INDEX"`
 	Created      time.Time `xorm:"-"`
-	CreatedUnix  int64     `xorm:"INDEX"`
+	CreatedUnix  int64     `xorm:"INDEX created"`
 	Updated      time.Time `xorm:"-"`
-	UpdatedUnix  int64     `xorm:"INDEX"`
+	UpdatedUnix  int64     `xorm:"INDEX updated"`
 
 	Attachments []*Attachment `xorm:"-"`
 	Comments    []*Comment    `xorm:"-"`
 }
 
-// BeforeInsert is invoked from XORM before inserting an object of this type.
-func (issue *Issue) BeforeInsert() {
-	issue.CreatedUnix = time.Now().Unix()
-	issue.UpdatedUnix = issue.CreatedUnix
-}
-
 // BeforeUpdate is invoked from XORM before updating this object.
 func (issue *Issue) BeforeUpdate() {
-	issue.UpdatedUnix = time.Now().Unix()
 	issue.DeadlineUnix = issue.Deadline.Unix()
 }
 
@@ -581,7 +574,6 @@ func (issue *Issue) ReadBy(userID int64) error {
 }
 
 func updateIssueCols(e Engine, issue *Issue, cols ...string) error {
-	cols = append(cols, "updated_unix")
 	if _, err := e.Id(issue.ID).Cols(cols...).Update(issue); err != nil {
 		return err
 	}
diff --git a/models/issue_comment.go b/models/issue_comment.go
index fe2223e9d2..6c9c75b1e4 100644
--- a/models/issue_comment.go
+++ b/models/issue_comment.go
@@ -99,9 +99,9 @@ type Comment struct {
 	RenderedContent string `xorm:"-"`
 
 	Created     time.Time `xorm:"-"`
-	CreatedUnix int64     `xorm:"INDEX"`
+	CreatedUnix int64     `xorm:"INDEX created"`
 	Updated     time.Time `xorm:"-"`
-	UpdatedUnix int64     `xorm:"INDEX"`
+	UpdatedUnix int64     `xorm:"INDEX updated"`
 
 	// Reference issue in commit message
 	CommitSHA string `xorm:"VARCHAR(40)"`
@@ -112,18 +112,6 @@ type Comment struct {
 	ShowTag CommentTag `xorm:"-"`
 }
 
-// BeforeInsert will be invoked by XORM before inserting a record
-// representing this object.
-func (c *Comment) BeforeInsert() {
-	c.CreatedUnix = time.Now().Unix()
-	c.UpdatedUnix = c.CreatedUnix
-}
-
-// BeforeUpdate is invoked from XORM before updating this object.
-func (c *Comment) BeforeUpdate() {
-	c.UpdatedUnix = time.Now().Unix()
-}
-
 // AfterSet is invoked from XORM after setting the value of a field of this object.
 func (c *Comment) AfterSet(colName string, _ xorm.Cell) {
 	var err error
diff --git a/models/lfs.go b/models/lfs.go
index f908cae1f2..be99306d75 100644
--- a/models/lfs.go
+++ b/models/lfs.go
@@ -2,8 +2,9 @@ package models
 
 import (
 	"errors"
-	"github.com/go-xorm/xorm"
 	"time"
+
+	"github.com/go-xorm/xorm"
 )
 
 // LFSMetaObject stores metadata for LFS tracked files.
@@ -14,7 +15,7 @@ type LFSMetaObject struct {
 	RepositoryID int64     `xorm:"UNIQUE(s) INDEX NOT NULL"`
 	Existing     bool      `xorm:"-"`
 	Created      time.Time `xorm:"-"`
-	CreatedUnix  int64
+	CreatedUnix  int64     `xorm:"created"`
 }
 
 // LFSTokenResponse defines the JSON structure in which the JWT token is stored.
@@ -108,11 +109,6 @@ func RemoveLFSMetaObjectByOid(oid string) error {
 	return sess.Commit()
 }
 
-// BeforeInsert sets the time at which the LFSMetaObject was created.
-func (m *LFSMetaObject) BeforeInsert() {
-	m.CreatedUnix = time.Now().Unix()
-}
-
 // AfterSet stores the LFSMetaObject creation time in the database as local time.
 func (m *LFSMetaObject) AfterSet(colName string, _ xorm.Cell) {
 	switch colName {
diff --git a/models/login_source.go b/models/login_source.go
index e4dc77714c..186a5e0514 100644
--- a/models/login_source.go
+++ b/models/login_source.go
@@ -148,20 +148,9 @@ type LoginSource struct {
 	Cfg           core.Conversion `xorm:"TEXT"`
 
 	Created     time.Time `xorm:"-"`
-	CreatedUnix int64     `xorm:"INDEX"`
+	CreatedUnix int64     `xorm:"INDEX created"`
 	Updated     time.Time `xorm:"-"`
-	UpdatedUnix int64     `xorm:"INDEX"`
-}
-
-// BeforeInsert is invoked from XORM before inserting an object of this type.
-func (source *LoginSource) BeforeInsert() {
-	source.CreatedUnix = time.Now().Unix()
-	source.UpdatedUnix = source.CreatedUnix
-}
-
-// BeforeUpdate is invoked from XORM before updating this object.
-func (source *LoginSource) BeforeUpdate() {
-	source.UpdatedUnix = time.Now().Unix()
+	UpdatedUnix int64     `xorm:"INDEX updated"`
 }
 
 // Cell2Int64 converts a xorm.Cell type to int64,
diff --git a/models/models.go b/models/models.go
index 0bcb3674da..1e64f70f4f 100644
--- a/models/models.go
+++ b/models/models.go
@@ -241,6 +241,7 @@ func NewTestEngine(x *xorm.Engine) (err error) {
 
 	x.SetMapper(core.GonicMapper{})
 	x.SetLogger(log.XORMLogger)
+	x.ShowSQL(!setting.ProdMode)
 	return x.StoreEngine("InnoDB").Sync2(tables...)
 }
 
diff --git a/models/repo.go b/models/repo.go
index 1cce3854ee..a2e63e2af7 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -211,20 +211,9 @@ type Repository struct {
 	Size     int64       `xorm:"NOT NULL DEFAULT 0"`
 
 	Created     time.Time `xorm:"-"`
-	CreatedUnix int64     `xorm:"INDEX"`
+	CreatedUnix int64     `xorm:"INDEX created"`
 	Updated     time.Time `xorm:"-"`
-	UpdatedUnix int64     `xorm:"INDEX"`
-}
-
-// BeforeInsert is invoked from XORM before inserting an object of this type.
-func (repo *Repository) BeforeInsert() {
-	repo.CreatedUnix = time.Now().Unix()
-	repo.UpdatedUnix = repo.CreatedUnix
-}
-
-// BeforeUpdate is invoked from XORM before updating this object.
-func (repo *Repository) BeforeUpdate() {
-	repo.UpdatedUnix = time.Now().Unix()
+	UpdatedUnix int64     `xorm:"INDEX updated"`
 }
 
 // AfterSet is invoked from XORM after setting the value of a field of this object.
diff --git a/models/repo_mirror.go b/models/repo_mirror.go
index 4588597743..526b7cd02e 100644
--- a/models/repo_mirror.go
+++ b/models/repo_mirror.go
@@ -40,18 +40,26 @@ type Mirror struct {
 
 // BeforeInsert will be invoked by XORM before inserting a record
 func (m *Mirror) BeforeInsert() {
-	m.UpdatedUnix = time.Now().Unix()
-	m.NextUpdateUnix = m.NextUpdate.Unix()
+	if m != nil {
+		m.UpdatedUnix = time.Now().Unix()
+		m.NextUpdateUnix = m.NextUpdate.Unix()
+	}
 }
 
 // BeforeUpdate is invoked from XORM before updating this object.
 func (m *Mirror) BeforeUpdate() {
-	m.UpdatedUnix = time.Now().Unix()
-	m.NextUpdateUnix = m.NextUpdate.Unix()
+	if m != nil {
+		m.UpdatedUnix = time.Now().Unix()
+		m.NextUpdateUnix = m.NextUpdate.Unix()
+	}
 }
 
 // AfterSet is invoked from XORM after setting the value of a field of this object.
 func (m *Mirror) AfterSet(colName string, _ xorm.Cell) {
+	if m == nil {
+		return
+	}
+
 	var err error
 	switch colName {
 	case "repo_id":
diff --git a/models/ssh_key.go b/models/ssh_key.go
index 649c50be6c..873eab3bf3 100644
--- a/models/ssh_key.go
+++ b/models/ssh_key.go
@@ -55,21 +55,11 @@ type PublicKey struct {
 	Type        KeyType    `xorm:"NOT NULL DEFAULT 1"`
 
 	Created           time.Time `xorm:"-"`
-	CreatedUnix       int64
+	CreatedUnix       int64     `xorm:"created"`
 	Updated           time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
-	UpdatedUnix       int64
-	HasRecentActivity bool `xorm:"-"`
-	HasUsed           bool `xorm:"-"`
-}
-
-// BeforeInsert will be invoked by XORM before inserting a record
-func (key *PublicKey) BeforeInsert() {
-	key.CreatedUnix = time.Now().Unix()
-}
-
-// BeforeUpdate is invoked from XORM before updating this object.
-func (key *PublicKey) BeforeUpdate() {
-	key.UpdatedUnix = time.Now().Unix()
+	UpdatedUnix       int64     `xorm:"updated"`
+	HasRecentActivity bool      `xorm:"-"`
+	HasUsed           bool      `xorm:"-"`
 }
 
 // AfterSet is invoked from XORM after setting the value of a field of this object.
@@ -633,21 +623,11 @@ type DeployKey struct {
 	Content     string `xorm:"-"`
 
 	Created           time.Time `xorm:"-"`
-	CreatedUnix       int64
+	CreatedUnix       int64     `xorm:"created"`
 	Updated           time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
-	UpdatedUnix       int64
-	HasRecentActivity bool `xorm:"-"`
-	HasUsed           bool `xorm:"-"`
-}
-
-// BeforeInsert will be invoked by XORM before inserting a record
-func (key *DeployKey) BeforeInsert() {
-	key.CreatedUnix = time.Now().Unix()
-}
-
-// BeforeUpdate is invoked from XORM before updating this object.
-func (key *DeployKey) BeforeUpdate() {
-	key.UpdatedUnix = time.Now().Unix()
+	UpdatedUnix       int64     `xorm:"updated"`
+	HasRecentActivity bool      `xorm:"-"`
+	HasUsed           bool      `xorm:"-"`
 }
 
 // AfterSet is invoked from XORM after setting the value of a field of this object.
diff --git a/models/status.go b/models/status.go
index 2ce588bea5..e300c763ff 100644
--- a/models/status.go
+++ b/models/status.go
@@ -66,20 +66,9 @@ type CommitStatus struct {
 	CreatorID   int64
 
 	Created     time.Time `xorm:"-"`
-	CreatedUnix int64     `xorm:"INDEX"`
+	CreatedUnix int64     `xorm:"INDEX created"`
 	Updated     time.Time `xorm:"-"`
-	UpdatedUnix int64     `xorm:"INDEX"`
-}
-
-// BeforeInsert is invoked from XORM before inserting an object of this type.
-func (status *CommitStatus) BeforeInsert() {
-	status.CreatedUnix = time.Now().Unix()
-	status.UpdatedUnix = status.CreatedUnix
-}
-
-// BeforeUpdate is invoked from XORM before updating this object.
-func (status *CommitStatus) BeforeUpdate() {
-	status.UpdatedUnix = time.Now().Unix()
+	UpdatedUnix int64     `xorm:"INDEX updated"`
 }
 
 // AfterSet is invoked from XORM after setting the value of a field of
diff --git a/models/token.go b/models/token.go
index b2e0a28a5a..d4b86eb3ae 100644
--- a/models/token.go
+++ b/models/token.go
@@ -21,23 +21,13 @@ type AccessToken struct {
 	Sha1 string `xorm:"UNIQUE VARCHAR(40)"`
 
 	Created           time.Time `xorm:"-"`
-	CreatedUnix       int64     `xorm:"INDEX"`
+	CreatedUnix       int64     `xorm:"INDEX created"`
 	Updated           time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
-	UpdatedUnix       int64     `xorm:"INDEX"`
+	UpdatedUnix       int64     `xorm:"INDEX updated"`
 	HasRecentActivity bool      `xorm:"-"`
 	HasUsed           bool      `xorm:"-"`
 }
 
-// BeforeInsert will be invoked by XORM before inserting a record representing this object.
-func (t *AccessToken) BeforeInsert() {
-	t.CreatedUnix = time.Now().Unix()
-}
-
-// BeforeUpdate is invoked from XORM before updating this object.
-func (t *AccessToken) BeforeUpdate() {
-	t.UpdatedUnix = time.Now().Unix()
-}
-
 // AfterSet is invoked from XORM after setting the value of a field of this object.
 func (t *AccessToken) AfterSet(colName string, _ xorm.Cell) {
 	switch colName {
diff --git a/models/twofactor.go b/models/twofactor.go
index 4c0d3702db..c983b56a5c 100644
--- a/models/twofactor.go
+++ b/models/twofactor.go
@@ -26,19 +26,9 @@ type TwoFactor struct {
 	ScratchToken string
 
 	Created     time.Time `xorm:"-"`
-	CreatedUnix int64     `xorm:"INDEX"`
+	CreatedUnix int64     `xorm:"INDEX created"`
 	Updated     time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
-	UpdatedUnix int64     `xorm:"INDEX"`
-}
-
-// BeforeInsert will be invoked by XORM before inserting a record representing this object.
-func (t *TwoFactor) BeforeInsert() {
-	t.CreatedUnix = time.Now().Unix()
-}
-
-// BeforeUpdate is invoked from XORM before updating this object.
-func (t *TwoFactor) BeforeUpdate() {
-	t.UpdatedUnix = time.Now().Unix()
+	UpdatedUnix int64     `xorm:"INDEX updated"`
 }
 
 // AfterSet is invoked from XORM after setting the value of a field of this object.
diff --git a/models/unit_tests.go b/models/unit_tests.go
index 315627d8e0..ce328b579d 100644
--- a/models/unit_tests.go
+++ b/models/unit_tests.go
@@ -28,6 +28,7 @@ func CreateTestEngine(fixturesDir string) error {
 	if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
 		return err
 	}
+	x.ShowSQL(true)
 
 	return InitFixtures(&testfixtures.SQLite{}, fixturesDir)
 }
diff --git a/models/user.go b/models/user.go
index 1e2502ebc0..f6d7051013 100644
--- a/models/user.go
+++ b/models/user.go
@@ -94,9 +94,9 @@ type User struct {
 	Salt             string `xorm:"VARCHAR(10)"`
 
 	Created       time.Time `xorm:"-"`
-	CreatedUnix   int64     `xorm:"INDEX"`
+	CreatedUnix   int64     `xorm:"INDEX created"`
 	Updated       time.Time `xorm:"-"`
-	UpdatedUnix   int64     `xorm:"INDEX"`
+	UpdatedUnix   int64     `xorm:"INDEX updated"`
 	LastLogin     time.Time `xorm:"-"`
 	LastLoginUnix int64     `xorm:"INDEX"`
 
@@ -135,18 +135,11 @@ type User struct {
 	DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"`
 }
 
-// BeforeInsert is invoked from XORM before inserting an object of this type.
-func (u *User) BeforeInsert() {
-	u.CreatedUnix = time.Now().Unix()
-	u.UpdatedUnix = u.CreatedUnix
-}
-
 // BeforeUpdate is invoked from XORM before updating this object.
 func (u *User) BeforeUpdate() {
 	if u.MaxRepoCreation < -1 {
 		u.MaxRepoCreation = -1
 	}
-	u.UpdatedUnix = time.Now().Unix()
 }
 
 // SetLastLogin set time to last login
@@ -897,7 +890,6 @@ func UpdateUserCols(u *User, cols ...string) error {
 	u.Website = base.TruncateString(u.Website, 255)
 	u.Description = base.TruncateString(u.Description, 255)
 
-	cols = append(cols, "updated_unix")
 	_, err := x.Id(u.ID).Cols(cols...).Update(u)
 	return err
 }
diff --git a/models/webhook.go b/models/webhook.go
index fa0c498f33..bc7926c233 100644
--- a/models/webhook.go
+++ b/models/webhook.go
@@ -107,22 +107,9 @@ type Webhook struct {
 	LastStatus   HookStatus // Last delivery status
 
 	Created     time.Time `xorm:"-"`
-	CreatedUnix int64     `xorm:"INDEX"`
+	CreatedUnix int64     `xorm:"INDEX created"`
 	Updated     time.Time `xorm:"-"`
-	UpdatedUnix int64     `xorm:"INDEX"`
-}
-
-// BeforeInsert will be invoked by XORM before inserting a record
-// representing this object
-func (w *Webhook) BeforeInsert() {
-	w.CreatedUnix = time.Now().Unix()
-	w.UpdatedUnix = w.CreatedUnix
-}
-
-// BeforeUpdate will be invoked by XORM before updating a record
-// representing this object
-func (w *Webhook) BeforeUpdate() {
-	w.UpdatedUnix = time.Now().Unix()
+	UpdatedUnix int64     `xorm:"INDEX updated"`
 }
 
 // AfterSet updates the webhook object upon setting a column
diff --git a/vendor/github.com/go-xorm/core/type.go b/vendor/github.com/go-xorm/core/type.go
index 8604822517..8010a2220f 100644
--- a/vendor/github.com/go-xorm/core/type.go
+++ b/vendor/github.com/go-xorm/core/type.go
@@ -100,7 +100,8 @@ var (
 	LongBlob   = "LONGBLOB"
 	Bytea      = "BYTEA"
 
-	Bool = "BOOL"
+	Bool    = "BOOL"
+	Boolean = "BOOLEAN"
 
 	Serial    = "SERIAL"
 	BigSerial = "BIGSERIAL"
@@ -163,7 +164,7 @@ var (
 	uintTypes = sort.StringSlice{"*uint", "*uint16", "*uint32", "*uint8"}
 )
 
-// !nashtsai! treat following var as interal const values, these are used for reflect.TypeOf comparision
+// !nashtsai! treat following var as interal const values, these are used for reflect.TypeOf comparison
 var (
 	c_EMPTY_STRING       string
 	c_BOOL_DEFAULT       bool
diff --git a/vendor/github.com/go-xorm/xorm/README.md b/vendor/github.com/go-xorm/xorm/README.md
index bf35488903..c8c43894c3 100644
--- a/vendor/github.com/go-xorm/xorm/README.md
+++ b/vendor/github.com/go-xorm/xorm/README.md
@@ -34,7 +34,7 @@ Drivers for Go's sql package which currently support database/sql includes:
 
 * Mysql: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
 
-* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/godrv)
+* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/tree/master/godrv)
 
 * Postgres: [github.com/lib/pq](https://github.com/lib/pq)
 
diff --git a/vendor/github.com/go-xorm/xorm/cache_lru.go b/vendor/github.com/go-xorm/xorm/cache_lru.go
index 4a74504351..c9672cebe4 100644
--- a/vendor/github.com/go-xorm/xorm/cache_lru.go
+++ b/vendor/github.com/go-xorm/xorm/cache_lru.go
@@ -15,13 +15,12 @@ import (
 
 // LRUCacher implments cache object facilities
 type LRUCacher struct {
-	idList   *list.List
-	sqlList  *list.List
-	idIndex  map[string]map[string]*list.Element
-	sqlIndex map[string]map[string]*list.Element
-	store    core.CacheStore
-	mutex    sync.Mutex
-	// maxSize    int
+	idList         *list.List
+	sqlList        *list.List
+	idIndex        map[string]map[string]*list.Element
+	sqlIndex       map[string]map[string]*list.Element
+	store          core.CacheStore
+	mutex          sync.Mutex
 	MaxElementSize int
 	Expired        time.Duration
 	GcInterval     time.Duration
@@ -54,8 +53,6 @@ func (m *LRUCacher) RunGC() {
 
 // GC check ids lit and sql list to remove all element expired
 func (m *LRUCacher) GC() {
-	//fmt.Println("begin gc ...")
-	//defer fmt.Println("end gc ...")
 	m.mutex.Lock()
 	defer m.mutex.Unlock()
 	var removedNum int
@@ -64,12 +61,10 @@ func (m *LRUCacher) GC() {
 			time.Now().Sub(e.Value.(*idNode).lastVisit) > m.Expired {
 			removedNum++
 			next := e.Next()
-			//fmt.Println("removing ...", e.Value)
 			node := e.Value.(*idNode)
 			m.delBean(node.tbName, node.id)
 			e = next
 		} else {
-			//fmt.Printf("removing %d cache nodes ..., left %d\n", removedNum, m.idList.Len())
 			break
 		}
 	}
@@ -80,12 +75,10 @@ func (m *LRUCacher) GC() {
 			time.Now().Sub(e.Value.(*sqlNode).lastVisit) > m.Expired {
 			removedNum++
 			next := e.Next()
-			//fmt.Println("removing ...", e.Value)
 			node := e.Value.(*sqlNode)
 			m.delIds(node.tbName, node.sql)
 			e = next
 		} else {
-			//fmt.Printf("removing %d cache nodes ..., left %d\n", removedNum, m.sqlList.Len())
 			break
 		}
 	}
@@ -116,7 +109,6 @@ func (m *LRUCacher) GetIds(tableName, sql string) interface{} {
 	}
 
 	m.delIds(tableName, sql)
-
 	return nil
 }
 
@@ -134,7 +126,6 @@ func (m *LRUCacher) GetBean(tableName string, id string) interface{} {
 			// if expired, remove the node and return nil
 			if time.Now().Sub(lastTime) > m.Expired {
 				m.delBean(tableName, id)
-				//m.clearIds(tableName)
 				return nil
 			}
 			m.idList.MoveToBack(el)
@@ -148,7 +139,6 @@ func (m *LRUCacher) GetBean(tableName string, id string) interface{} {
 
 	// store bean is not exist, then remove memory's index
 	m.delBean(tableName, id)
-	//m.clearIds(tableName)
 	return nil
 }
 
@@ -166,8 +156,8 @@ func (m *LRUCacher) clearIds(tableName string) {
 // ClearIds clears all sql-ids mapping on table tableName from cache
 func (m *LRUCacher) ClearIds(tableName string) {
 	m.mutex.Lock()
-	defer m.mutex.Unlock()
 	m.clearIds(tableName)
+	m.mutex.Unlock()
 }
 
 func (m *LRUCacher) clearBeans(tableName string) {
@@ -184,14 +174,13 @@ func (m *LRUCacher) clearBeans(tableName string) {
 // ClearBeans clears all beans in some table
 func (m *LRUCacher) ClearBeans(tableName string) {
 	m.mutex.Lock()
-	defer m.mutex.Unlock()
 	m.clearBeans(tableName)
+	m.mutex.Unlock()
 }
 
 // PutIds pus ids into table
 func (m *LRUCacher) PutIds(tableName, sql string, ids interface{}) {
 	m.mutex.Lock()
-	defer m.mutex.Unlock()
 	if _, ok := m.sqlIndex[tableName]; !ok {
 		m.sqlIndex[tableName] = make(map[string]*list.Element)
 	}
@@ -207,12 +196,12 @@ func (m *LRUCacher) PutIds(tableName, sql string, ids interface{}) {
 		node := e.Value.(*sqlNode)
 		m.delIds(node.tbName, node.sql)
 	}
+	m.mutex.Unlock()
 }
 
 // PutBean puts beans into table
 func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) {
 	m.mutex.Lock()
-	defer m.mutex.Unlock()
 	var el *list.Element
 	var ok bool
 
@@ -229,6 +218,7 @@ func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) {
 		node := e.Value.(*idNode)
 		m.delBean(node.tbName, node.id)
 	}
+	m.mutex.Unlock()
 }
 
 func (m *LRUCacher) delIds(tableName, sql string) {
@@ -244,8 +234,8 @@ func (m *LRUCacher) delIds(tableName, sql string) {
 // DelIds deletes ids
 func (m *LRUCacher) DelIds(tableName, sql string) {
 	m.mutex.Lock()
-	defer m.mutex.Unlock()
 	m.delIds(tableName, sql)
+	m.mutex.Unlock()
 }
 
 func (m *LRUCacher) delBean(tableName string, id string) {
@@ -261,8 +251,8 @@ func (m *LRUCacher) delBean(tableName string, id string) {
 // DelBean deletes beans in some table
 func (m *LRUCacher) DelBean(tableName string, id string) {
 	m.mutex.Lock()
-	defer m.mutex.Unlock()
 	m.delBean(tableName, id)
+	m.mutex.Unlock()
 }
 
 type idNode struct {
diff --git a/vendor/github.com/go-xorm/xorm/circle.yml b/vendor/github.com/go-xorm/xorm/circle.yml
index e81bdb0e30..69fc7164ba 100644
--- a/vendor/github.com/go-xorm/xorm/circle.yml
+++ b/vendor/github.com/go-xorm/xorm/circle.yml
@@ -21,7 +21,16 @@ database:
 test:
   override:
     # './...' is a relative pattern which means all subdirectories
-    - go test -v -race -db="sqlite3::mysql::mymysql::postgres" -conn_str="./test.db::root:@/xorm_test::xorm_test/root/::dbname=xorm_test sslmode=disable" -coverprofile=coverage.txt -covermode=atomic
+    - go get -u github.com/wadey/gocovmerge;
+    - go test -v -race -db="sqlite3" -conn_str="./test.db" -coverprofile=coverage1-1.txt -covermode=atomic
+    - go test -v -race -db="sqlite3" -conn_str="./test.db" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic
+    - go test -v -race -db="mysql" -conn_str="root:@/xorm_test" -coverprofile=coverage2-1.txt -covermode=atomic
+    - go test -v -race -db="mysql" -conn_str="root:@/xorm_test" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic
+    - go test -v -race -db="mymysql" -conn_str="xorm_test/root/" -coverprofile=coverage3-1.txt -covermode=atomic
+    - go test -v -race -db="mymysql" -conn_str="xorm_test/root/" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic
+    - go test -v -race -db="postgres" -conn_str="dbname=xorm_test sslmode=disable" -coverprofile=coverage4-1.txt -covermode=atomic
+    - go test -v -race -db="postgres" -conn_str="dbname=xorm_test sslmode=disable" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic
+    - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt > coverage.txt
     - cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./sqlite3.sh
     - cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./mysql.sh
     - cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./postgres.sh
diff --git a/vendor/github.com/go-xorm/xorm/convert.go b/vendor/github.com/go-xorm/xorm/convert.go
index fbd24b5b38..0504bef155 100644
--- a/vendor/github.com/go-xorm/xorm/convert.go
+++ b/vendor/github.com/go-xorm/xorm/convert.go
@@ -334,3 +334,15 @@ func convertInt(v interface{}) (int64, error) {
 	}
 	return 0, fmt.Errorf("unsupported type: %v", v)
 }
+
+func asBool(bs []byte) (bool, error) {
+	if len(bs) == 0 {
+		return false, nil
+	}
+	if bs[0] == 0x00 {
+		return false, nil
+	} else if bs[0] == 0x01 {
+		return true, nil
+	}
+	return strconv.ParseBool(string(bs))
+}
diff --git a/vendor/github.com/go-xorm/xorm/dialect_postgres.go b/vendor/github.com/go-xorm/xorm/dialect_postgres.go
index 1d4daa2798..3f5c526f72 100644
--- a/vendor/github.com/go-xorm/xorm/dialect_postgres.go
+++ b/vendor/github.com/go-xorm/xorm/dialect_postgres.go
@@ -781,6 +781,9 @@ func (db *postgres) SqlType(c *core.Column) string {
 	case core.TinyInt:
 		res = core.SmallInt
 		return res
+	case core.Bit:
+		res = core.Boolean
+		return res
 	case core.MediumInt, core.Int, core.Integer:
 		if c.IsAutoIncrement {
 			return core.Serial
diff --git a/vendor/github.com/go-xorm/xorm/doc.go b/vendor/github.com/go-xorm/xorm/doc.go
index bf412bdaa8..a687e69476 100644
--- a/vendor/github.com/go-xorm/xorm/doc.go
+++ b/vendor/github.com/go-xorm/xorm/doc.go
@@ -90,7 +90,7 @@ another is Rows
 
 5. Update one or more records
 
-    affected, err := engine.Id(...).Update(&user)
+    affected, err := engine.ID(...).Update(&user)
     // UPDATE user SET ...
 
 6. Delete one or more records, Delete MUST has condition
diff --git a/vendor/github.com/go-xorm/xorm/engine.go b/vendor/github.com/go-xorm/xorm/engine.go
index cfa0933ee3..0d34bf962b 100644
--- a/vendor/github.com/go-xorm/xorm/engine.go
+++ b/vendor/github.com/go-xorm/xorm/engine.go
@@ -273,36 +273,6 @@ func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) {
 	}
 }
 
-func (engine *Engine) logSQLQueryTime(sqlStr string, args []interface{}, executionBlock func() (*core.Stmt, *core.Rows, error)) (*core.Stmt, *core.Rows, error) {
-	if engine.showSQL && engine.showExecTime {
-		b4ExecTime := time.Now()
-		stmt, res, err := executionBlock()
-		execDuration := time.Since(b4ExecTime)
-		if len(args) > 0 {
-			engine.logger.Infof("[SQL] %s %v - took: %v", sqlStr, args, execDuration)
-		} else {
-			engine.logger.Infof("[SQL] %s - took: %v", sqlStr, execDuration)
-		}
-		return stmt, res, err
-	}
-	return executionBlock()
-}
-
-func (engine *Engine) logSQLExecutionTime(sqlStr string, args []interface{}, executionBlock func() (sql.Result, error)) (sql.Result, error) {
-	if engine.showSQL && engine.showExecTime {
-		b4ExecTime := time.Now()
-		res, err := executionBlock()
-		execDuration := time.Since(b4ExecTime)
-		if len(args) > 0 {
-			engine.logger.Infof("[sql] %s [args] %v - took: %v", sqlStr, args, execDuration)
-		} else {
-			engine.logger.Infof("[sql] %s - took: %v", sqlStr, execDuration)
-		}
-		return res, err
-	}
-	return executionBlock()
-}
-
 // 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.
 //
@@ -1384,6 +1354,13 @@ func (engine *Engine) QueryString(sqlStr string, args ...interface{}) ([]map[str
 	return session.QueryString(sqlStr, args...)
 }
 
+// QueryInterface runs a raw sql and return records as []map[string]interface{}
+func (engine *Engine) QueryInterface(sqlStr string, args ...interface{}) ([]map[string]interface{}, error) {
+	session := engine.NewSession()
+	defer session.Close()
+	return session.QueryInterface(sqlStr, args...)
+}
+
 // Insert one or more records
 func (engine *Engine) Insert(beans ...interface{}) (int64, error) {
 	session := engine.NewSession()
diff --git a/vendor/github.com/go-xorm/xorm/rows.go b/vendor/github.com/go-xorm/xorm/rows.go
index 444e3d435a..258d9f2797 100644
--- a/vendor/github.com/go-xorm/xorm/rows.go
+++ b/vendor/github.com/go-xorm/xorm/rows.go
@@ -17,7 +17,6 @@ type Rows struct {
 	NoTypeCheck bool
 
 	session   *Session
-	stmt      *core.Stmt
 	rows      *core.Rows
 	fields    []string
 	beanType  reflect.Type
@@ -29,8 +28,6 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
 	rows.session = session
 	rows.beanType = reflect.Indirect(reflect.ValueOf(bean)).Type()
 
-	defer rows.session.resetStatement()
-
 	var sqlStr string
 	var args []interface{}
 	var err error
@@ -53,32 +50,11 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
 		args = rows.session.statement.RawParams
 	}
 
-	for _, filter := range rows.session.engine.dialect.Filters() {
-		sqlStr = filter.Do(sqlStr, session.engine.dialect, rows.session.statement.RefTable)
-	}
-
-	rows.session.saveLastSQL(sqlStr, args...)
-	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
-			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.rows, err = rows.session.queryRows(sqlStr, args...)
+	if err != nil {
+		rows.lastError = err
+		rows.Close()
+		return nil, err
 	}
 
 	rows.fields, err = rows.rows.Columns()
@@ -142,17 +118,10 @@ func (rows *Rows) Close() error {
 		if rows.rows != nil {
 			rows.lastError = rows.rows.Close()
 			if rows.lastError != nil {
-				defer rows.stmt.Close()
 				return rows.lastError
 			}
 		}
-		if rows.stmt != nil {
-			rows.lastError = rows.stmt.Close()
-		}
 	} else {
-		if rows.stmt != nil {
-			defer rows.stmt.Close()
-		}
 		if rows.rows != nil {
 			defer rows.rows.Close()
 		}
diff --git a/vendor/github.com/go-xorm/xorm/session.go b/vendor/github.com/go-xorm/xorm/session.go
index 9d04140279..c69ac9e5c0 100644
--- a/vendor/github.com/go-xorm/xorm/session.go
+++ b/vendor/github.com/go-xorm/xorm/session.go
@@ -303,6 +303,7 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount
 		var newValue = newElemFunc(fields)
 		bean := newValue.Interface()
 		dataStruct := rValue(bean)
+
 		// handle beforeClosures
 		scanResults, err := session.row2Slice(rows, fields, fieldsCount, bean)
 		if err != nil {
@@ -312,7 +313,6 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount
 		if err != nil {
 			return err
 		}
-
 		err = sliceValueSetFunc(&newValue, pk)
 		if err != nil {
 			return err
@@ -631,9 +631,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, f
 						// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
 						// property to be fetched lazily
 						structInter := reflect.New(fieldValue.Type())
-						newsession := session.engine.NewSession()
-						defer newsession.Close()
-						has, err := newsession.ID(pk).NoCascade().Get(structInter.Interface())
+						has, err := session.ID(pk).NoCascade().get(structInter.Interface())
 						if err != nil {
 							return nil, err
 						}
@@ -777,14 +775,6 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, f
 	return pk, nil
 }
 
-func (session *Session) queryPreprocess(sqlStr *string, paramStr ...interface{}) {
-	for _, filter := range session.engine.dialect.Filters() {
-		*sqlStr = filter.Do(*sqlStr, session.engine.dialect, session.statement.RefTable)
-	}
-
-	session.saveLastSQL(*sqlStr, paramStr...)
-}
-
 // saveLastSQL stores executed query information
 func (session *Session) saveLastSQL(sql string, args ...interface{}) {
 	session.lastSQL = sql
diff --git a/vendor/github.com/go-xorm/xorm/session_convert.go b/vendor/github.com/go-xorm/xorm/session_convert.go
index 85002d27ca..f2c949bac8 100644
--- a/vendor/github.com/go-xorm/xorm/session_convert.go
+++ b/vendor/github.com/go-xorm/xorm/session_convert.go
@@ -144,8 +144,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
 	case reflect.String:
 		fieldValue.SetString(string(data))
 	case reflect.Bool:
-		d := string(data)
-		v, err := strconv.ParseBool(d)
+		v, err := asBool(data)
 		if err != nil {
 			return fmt.Errorf("arg %v as bool: %s", key, err.Error())
 		}
@@ -227,9 +226,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
 					// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
 					// property to be fetched lazily
 					structInter := reflect.New(fieldValue.Type())
-					newsession := session.engine.NewSession()
-					defer newsession.Close()
-					has, err := newsession.Id(pk).NoCascade().Get(structInter.Interface())
+					has, err := session.ID(pk).NoCascade().get(structInter.Interface())
 					if err != nil {
 						return err
 					}
@@ -510,9 +507,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
 						// !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
 						// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
 						// property to be fetched lazily
-						newsession := session.engine.NewSession()
-						defer newsession.Close()
-						has, err := newsession.Id(pk).NoCascade().Get(structInter.Interface())
+						has, err := session.ID(pk).NoCascade().get(structInter.Interface())
 						if err != nil {
 							return err
 						}
diff --git a/vendor/github.com/go-xorm/xorm/session_delete.go b/vendor/github.com/go-xorm/xorm/session_delete.go
index 9fd7b8aff8..1d7d662cd6 100644
--- a/vendor/github.com/go-xorm/xorm/session_delete.go
+++ b/vendor/github.com/go-xorm/xorm/session_delete.go
@@ -12,14 +12,14 @@ import (
 	"github.com/go-xorm/core"
 )
 
-func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
-	if session.statement.RefTable == nil ||
+func (session *Session) cacheDelete(table *core.Table, tableName, sqlStr string, args ...interface{}) error {
+	if table == nil ||
 		session.tx != nil {
 		return ErrCacheFailed
 	}
 
 	for _, filter := range session.engine.dialect.Filters() {
-		sqlStr = filter.Do(sqlStr, session.engine.dialect, session.statement.RefTable)
+		sqlStr = filter.Do(sqlStr, session.engine.dialect, table)
 	}
 
 	newsql := session.statement.convertIDSQL(sqlStr)
@@ -27,11 +27,11 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
 		return ErrCacheFailed
 	}
 
-	cacher := session.engine.getCacher2(session.statement.RefTable)
-	tableName := session.statement.TableName()
+	cacher := session.engine.getCacher2(table)
+	pkColumns := table.PKColumns()
 	ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
 	if err != nil {
-		resultsSlice, err := session.query(newsql, args...)
+		resultsSlice, err := session.queryBytes(newsql, args...)
 		if err != nil {
 			return err
 		}
@@ -40,7 +40,7 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
 			for _, data := range resultsSlice {
 				var id int64
 				var pk core.PK = make([]interface{}, 0)
-				for _, col := range session.statement.RefTable.PKColumns() {
+				for _, col := range pkColumns {
 					if v, ok := data[col.Name]; !ok {
 						return errors.New("no id")
 					} else if col.SQLType.IsText() {
@@ -58,27 +58,23 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
 				ids = append(ids, pk)
 			}
 		}
-	} /*else {
-	    session.engine.LogDebug("delete cache sql %v", newsql)
-	    cacher.DelIds(tableName, genSqlKey(newsql, args))
-	}*/
+	}
 
 	for _, id := range ids {
-		session.engine.logger.Debug("[cacheDelete] delete cache obj", tableName, id)
+		session.engine.logger.Debug("[cacheDelete] delete cache obj:", tableName, id)
 		sid, err := id.ToString()
 		if err != nil {
 			return err
 		}
 		cacher.DelBean(tableName, sid)
 	}
-	session.engine.logger.Debug("[cacheDelete] clear cache sql", tableName)
+	session.engine.logger.Debug("[cacheDelete] clear cache table:", tableName)
 	cacher.ClearIds(tableName)
 	return nil
 }
 
 // Delete records, bean's non-empty fields are conditions
 func (session *Session) Delete(bean interface{}) (int64, error) {
-	defer session.resetStatement()
 	if session.isAutoClose {
 		defer session.Close()
 	}
@@ -86,7 +82,6 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
 	if err := session.statement.setRefValue(rValue(bean)); err != nil {
 		return 0, err
 	}
-	var table = session.statement.RefTable
 
 	// handle before delete processors
 	for _, closure := range session.beforeClosures {
@@ -106,7 +101,9 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
 		return 0, ErrNeedDeletedCond
 	}
 
-	var tableName = session.engine.Quote(session.statement.TableName())
+	var tableNameNoQuote = session.statement.TableName()
+	var tableName = session.engine.Quote(tableNameNoQuote)
+	var table = session.statement.RefTable
 	var deleteSQL string
 	if len(condSQL) > 0 {
 		deleteSQL = fmt.Sprintf("DELETE FROM %v WHERE %v", tableName, condSQL)
@@ -202,10 +199,11 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
 		})
 	}
 
-	if cacher := session.engine.getCacher2(session.statement.RefTable); cacher != nil && session.statement.UseCache {
-		session.cacheDelete(deleteSQL, argsForCache...)
+	if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
+		session.cacheDelete(table, tableNameNoQuote, deleteSQL, argsForCache...)
 	}
 
+	session.statement.RefTable = table
 	res, err := session.exec(realSQL, condArgs...)
 	if err != nil {
 		return 0, err
diff --git a/vendor/github.com/go-xorm/xorm/session_exist.go b/vendor/github.com/go-xorm/xorm/session_exist.go
index 91d1cd601a..049c1ddff1 100644
--- a/vendor/github.com/go-xorm/xorm/session_exist.go
+++ b/vendor/github.com/go-xorm/xorm/session_exist.go
@@ -10,12 +10,10 @@ import (
 	"reflect"
 
 	"github.com/go-xorm/builder"
-	"github.com/go-xorm/core"
 )
 
 // Exist returns true if the record exist otherwise return false
 func (session *Session) Exist(bean ...interface{}) (bool, error) {
-	defer session.resetStatement()
 	if session.isAutoClose {
 		defer session.Close()
 	}
@@ -69,19 +67,11 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) {
 		args = session.statement.RawParams
 	}
 
-	session.queryPreprocess(&sqlStr, args...)
-
-	var rawRows *core.Rows
-	if session.isAutoCommit {
-		_, rawRows, err = session.innerQuery(sqlStr, args...)
-	} else {
-		rawRows, err = session.tx.Query(sqlStr, args...)
-	}
+	rows, err := session.queryRows(sqlStr, args...)
 	if err != nil {
 		return false, err
 	}
+	defer rows.Close()
 
-	defer rawRows.Close()
-
-	return rawRows.Next(), nil
+	return rows.Next(), nil
 }
diff --git a/vendor/github.com/go-xorm/xorm/session_find.go b/vendor/github.com/go-xorm/xorm/session_find.go
index 42b3506eb0..05ec724f99 100644
--- a/vendor/github.com/go-xorm/xorm/session_find.go
+++ b/vendor/github.com/go-xorm/xorm/session_find.go
@@ -23,11 +23,13 @@ const (
 // 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()
 	}
+	return session.find(rowsSlicePtr, condiBean...)
+}
 
+func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error {
 	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")
@@ -157,21 +159,13 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
 }
 
 func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Value, sqlStr string, args ...interface{}) error {
-	var rawRows *core.Rows
-	var err error
-
-	session.queryPreprocess(&sqlStr, args...)
-	if session.isAutoCommit {
-		_, rawRows, err = session.innerQuery(sqlStr, args...)
-	} else {
-		rawRows, err = session.tx.Query(sqlStr, args...)
-	}
+	rows, err := session.queryRows(sqlStr, args...)
 	if err != nil {
 		return err
 	}
-	defer rawRows.Close()
+	defer rows.Close()
 
-	fields, err := rawRows.Columns()
+	fields, err := rows.Columns()
 	if err != nil {
 		return err
 	}
@@ -245,20 +239,20 @@ func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Va
 		if err != nil {
 			return err
 		}
-		return session.rows2Beans(rawRows, fields, len(fields), tb, newElemFunc, containerValueSetFunc)
+		return session.rows2Beans(rows, fields, len(fields), tb, newElemFunc, containerValueSetFunc)
 	}
 
-	for rawRows.Next() {
+	for rows.Next() {
 		var newValue = newElemFunc(fields)
 		bean := newValue.Interface()
 
 		switch elemType.Kind() {
 		case reflect.Slice:
-			err = rawRows.ScanSlice(bean)
+			err = rows.ScanSlice(bean)
 		case reflect.Map:
-			err = rawRows.ScanMap(bean)
+			err = rows.ScanMap(bean)
 		default:
-			err = rawRows.Scan(bean)
+			err = rows.Scan(bean)
 		}
 
 		if err != nil {
@@ -299,12 +293,11 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
 	}
 
 	tableName := session.statement.TableName()
-
 	table := session.statement.RefTable
 	cacher := session.engine.getCacher2(table)
 	ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
 	if err != nil {
-		rows, err := session.DB().Query(newsql, args...)
+		rows, err := session.queryRows(newsql, args...)
 		if err != nil {
 			return err
 		}
@@ -334,13 +327,13 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
 			ids = append(ids, pk)
 		}
 
-		session.engine.logger.Debug("[cacheFind] cache sql:", ids, tableName, newsql, args)
+		session.engine.logger.Debug("[cacheFind] cache sql:", ids, tableName, sqlStr, newsql, args)
 		err = core.PutCacheSql(cacher, ids, tableName, newsql, args)
 		if err != nil {
 			return err
 		}
 	} else {
-		session.engine.logger.Debug("[cacheFind] cache hit sql:", newsql, args)
+		session.engine.logger.Debug("[cacheFind] cache hit sql:", tableName, sqlStr, newsql, args)
 	}
 
 	sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
@@ -355,7 +348,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
 			return err
 		}
 		bean := cacher.GetBean(tableName, sid)
-		if bean == nil {
+		if bean == nil || reflect.ValueOf(bean).Elem().Type() != t {
 			ides = append(ides, id)
 			ididxes[sid] = idx
 		} else {
@@ -376,9 +369,6 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
 	}
 
 	if len(ides) > 0 {
-		newSession := session.engine.NewSession()
-		defer newSession.Close()
-
 		slices := reflect.New(reflect.SliceOf(t))
 		beans := slices.Interface()
 
@@ -388,18 +378,18 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
 				ff = append(ff, ie[0])
 			}
 
-			newSession.In("`"+table.PrimaryKeys[0]+"`", ff...)
+			session.In("`"+table.PrimaryKeys[0]+"`", ff...)
 		} else {
 			for _, ie := range ides {
 				cond := builder.NewCond()
 				for i, name := range table.PrimaryKeys {
 					cond = cond.And(builder.Eq{"`" + name + "`": ie[i]})
 				}
-				newSession.Or(cond)
+				session.Or(cond)
 			}
 		}
 
-		err = newSession.NoCache().Find(beans)
+		err = session.NoCache().Table(tableName).find(beans)
 		if err != nil {
 			return err
 		}
diff --git a/vendor/github.com/go-xorm/xorm/session_get.go b/vendor/github.com/go-xorm/xorm/session_get.go
index d5f768c69d..1f1e61cdd2 100644
--- a/vendor/github.com/go-xorm/xorm/session_get.go
+++ b/vendor/github.com/go-xorm/xorm/session_get.go
@@ -15,11 +15,13 @@ import (
 // Get retrieve one record from database, bean's non-empty fields
 // will be as conditions
 func (session *Session) Get(bean interface{}) (bool, error) {
-	defer session.resetStatement()
 	if session.isAutoClose {
 		defer session.Close()
 	}
+	return session.get(bean)
+}
 
+func (session *Session) get(bean interface{}) (bool, error) {
 	beanValue := reflect.ValueOf(bean)
 	if beanValue.Kind() != reflect.Ptr {
 		return false, errors.New("needs a pointer to a value")
@@ -51,8 +53,10 @@ func (session *Session) Get(bean interface{}) (bool, error) {
 		args = session.statement.RawParams
 	}
 
+	table := session.statement.RefTable
+
 	if session.canCache() && beanValue.Elem().Kind() == reflect.Struct {
-		if cacher := session.engine.getCacher2(session.statement.RefTable); cacher != nil &&
+		if cacher := session.engine.getCacher2(table); cacher != nil &&
 			!session.statement.unscoped {
 			has, err := session.cacheGet(bean, sqlStr, args...)
 			if err != ErrCacheFailed {
@@ -61,54 +65,43 @@ func (session *Session) Get(bean interface{}) (bool, error) {
 		}
 	}
 
-	return session.nocacheGet(beanValue.Elem().Kind(), bean, sqlStr, args...)
+	return session.nocacheGet(beanValue.Elem().Kind(), table, bean, sqlStr, args...)
 }
 
-func (session *Session) nocacheGet(beanKind reflect.Kind, bean interface{}, sqlStr string, args ...interface{}) (bool, error) {
-	session.queryPreprocess(&sqlStr, args...)
-
-	var rawRows *core.Rows
-	var err error
-	if session.isAutoCommit {
-		_, rawRows, err = session.innerQuery(sqlStr, args...)
-	} else {
-		rawRows, err = session.tx.Query(sqlStr, args...)
-	}
+func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bean interface{}, sqlStr string, args ...interface{}) (bool, error) {
+	rows, err := session.queryRows(sqlStr, args...)
 	if err != nil {
 		return false, err
 	}
+	defer rows.Close()
 
-	defer rawRows.Close()
-
-	if !rawRows.Next() {
+	if !rows.Next() {
 		return false, nil
 	}
 
 	switch beanKind {
 	case reflect.Struct:
-		fields, err := rawRows.Columns()
+		fields, err := rows.Columns()
 		if err != nil {
-			// WARN: Alougth rawRows return true, but get fields failed
+			// WARN: Alougth rows return true, but get fields failed
 			return true, err
 		}
-		dataStruct := rValue(bean)
-		if err := session.statement.setRefValue(dataStruct); err != nil {
-			return false, err
-		}
 
-		scanResults, err := session.row2Slice(rawRows, fields, len(fields), bean)
+		scanResults, err := session.row2Slice(rows, fields, len(fields), bean)
 		if err != nil {
 			return false, err
 		}
-		rawRows.Close()
+		// close it before covert data
+		rows.Close()
 
-		_, err = session.slice2Bean(scanResults, fields, len(fields), bean, &dataStruct, session.statement.RefTable)
+		dataStruct := rValue(bean)
+		_, err = session.slice2Bean(scanResults, fields, len(fields), bean, &dataStruct, table)
 	case reflect.Slice:
-		err = rawRows.ScanSlice(bean)
+		err = rows.ScanSlice(bean)
 	case reflect.Map:
-		err = rawRows.ScanMap(bean)
+		err = rows.ScanMap(bean)
 	default:
-		err = rawRows.Scan(bean)
+		err = rows.Scan(bean)
 	}
 
 	return true, err
@@ -131,11 +124,11 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
 	cacher := session.engine.getCacher2(session.statement.RefTable)
 	tableName := session.statement.TableName()
 	session.engine.logger.Debug("[cacheGet] find sql:", newsql, args)
-	ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
 	table := session.statement.RefTable
+	ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
 	if err != nil {
 		var res = make([]string, len(table.PrimaryKeys))
-		rows, err := session.DB().Query(newsql, args...)
+		rows, err := session.NoCache().queryRows(newsql, args...)
 		if err != nil {
 			return false, err
 		}
@@ -172,7 +165,7 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
 			return false, err
 		}
 	} else {
-		session.engine.logger.Debug("[cacheGet] cache hit sql:", newsql)
+		session.engine.logger.Debug("[cacheGet] cache hit sql:", newsql, ids)
 	}
 
 	if len(ids) > 0 {
@@ -186,7 +179,7 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
 		cacheBean := cacher.GetBean(tableName, sid)
 		if cacheBean == nil {
 			cacheBean = bean
-			has, err = session.nocacheGet(reflect.Struct, cacheBean, sqlStr, args...)
+			has, err = session.nocacheGet(reflect.Struct, table, cacheBean, sqlStr, args...)
 			if err != nil || !has {
 				return has, err
 			}
diff --git a/vendor/github.com/go-xorm/xorm/session_insert.go b/vendor/github.com/go-xorm/xorm/session_insert.go
index 02edf57440..705f6a8959 100644
--- a/vendor/github.com/go-xorm/xorm/session_insert.go
+++ b/vendor/github.com/go-xorm/xorm/session_insert.go
@@ -22,7 +22,6 @@ func (session *Session) Insert(beans ...interface{}) (int64, error) {
 	if session.isAutoClose {
 		defer session.Close()
 	}
-	defer session.resetStatement()
 
 	for _, bean := range beans {
 		sliceValue := reflect.Indirect(reflect.ValueOf(bean))
@@ -214,22 +213,23 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
 
 	var sql = "INSERT INTO %s (%v%v%v) VALUES (%v)"
 	var statement string
+	var tableName = session.statement.TableName()
 	if session.engine.dialect.DBType() == core.ORACLE {
 		sql = "INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL"
 		temp := fmt.Sprintf(") INTO %s (%v%v%v) VALUES (",
-			session.engine.Quote(session.statement.TableName()),
+			session.engine.Quote(tableName),
 			session.engine.QuoteStr(),
 			strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
 			session.engine.QuoteStr())
 		statement = fmt.Sprintf(sql,
-			session.engine.Quote(session.statement.TableName()),
+			session.engine.Quote(tableName),
 			session.engine.QuoteStr(),
 			strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
 			session.engine.QuoteStr(),
 			strings.Join(colMultiPlaces, temp))
 	} else {
 		statement = fmt.Sprintf(sql,
-			session.engine.Quote(session.statement.TableName()),
+			session.engine.Quote(tableName),
 			session.engine.QuoteStr(),
 			strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
 			session.engine.QuoteStr(),
@@ -241,7 +241,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
 	}
 
 	if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
-		session.cacheInsert(session.statement.TableName())
+		session.cacheInsert(table, tableName)
 	}
 
 	lenAfterClosures := len(session.afterClosures)
@@ -280,7 +280,6 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
 
 // InsertMulti insert multiple records
 func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) {
-	defer session.resetStatement()
 	if session.isAutoClose {
 		defer session.Close()
 	}
@@ -349,18 +348,19 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
 	}
 
 	var sqlStr string
+	var tableName = session.statement.TableName()
 	if len(colPlaces) > 0 {
 		sqlStr = fmt.Sprintf("INSERT INTO %s (%v%v%v) VALUES (%v)",
-			session.engine.Quote(session.statement.TableName()),
+			session.engine.Quote(tableName),
 			session.engine.QuoteStr(),
 			strings.Join(colNames, session.engine.Quote(", ")),
 			session.engine.QuoteStr(),
 			colPlaces)
 	} else {
 		if session.engine.dialect.DBType() == core.MYSQL {
-			sqlStr = fmt.Sprintf("INSERT INTO %s VALUES ()", session.engine.Quote(session.statement.TableName()))
+			sqlStr = fmt.Sprintf("INSERT INTO %s VALUES ()", session.engine.Quote(tableName))
 		} else {
-			sqlStr = fmt.Sprintf("INSERT INTO %s DEFAULT VALUES", session.engine.Quote(session.statement.TableName()))
+			sqlStr = fmt.Sprintf("INSERT INTO %s DEFAULT VALUES", session.engine.Quote(tableName))
 		}
 	}
 
@@ -395,7 +395,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
 	// for postgres, many of them didn't implement lastInsertId, so we should
 	// implemented it ourself.
 	if session.engine.dialect.DBType() == core.ORACLE && len(table.AutoIncrement) > 0 {
-		res, err := session.query("select seq_atable.currval from dual", args...)
+		res, err := session.queryBytes("select seq_atable.currval from dual", args...)
 		if err != nil {
 			return 0, err
 		}
@@ -403,7 +403,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
 		handleAfterInsertProcessorFunc(bean)
 
 		if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
-			session.cacheInsert(session.statement.TableName())
+			session.cacheInsert(table, tableName)
 		}
 
 		if table.Version != "" && session.statement.checkVersion {
@@ -440,7 +440,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
 	} else if session.engine.dialect.DBType() == core.POSTGRES && len(table.AutoIncrement) > 0 {
 		//assert table.AutoIncrement != ""
 		sqlStr = sqlStr + " RETURNING " + session.engine.Quote(table.AutoIncrement)
-		res, err := session.query(sqlStr, args...)
+		res, err := session.queryBytes(sqlStr, args...)
 
 		if err != nil {
 			return 0, err
@@ -448,7 +448,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
 		handleAfterInsertProcessorFunc(bean)
 
 		if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
-			session.cacheInsert(session.statement.TableName())
+			session.cacheInsert(table, tableName)
 		}
 
 		if table.Version != "" && session.statement.checkVersion {
@@ -491,7 +491,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
 		defer handleAfterInsertProcessorFunc(bean)
 
 		if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
-			session.cacheInsert(session.statement.TableName())
+			session.cacheInsert(table, tableName)
 		}
 
 		if table.Version != "" && session.statement.checkVersion {
@@ -532,7 +532,6 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
 // The in parameter bean must a struct or a point to struct. The return
 // parameter is inserted and error
 func (session *Session) InsertOne(bean interface{}) (int64, error) {
-	defer session.resetStatement()
 	if session.isAutoClose {
 		defer session.Close()
 	}
@@ -540,14 +539,12 @@ func (session *Session) InsertOne(bean interface{}) (int64, error) {
 	return session.innerInsert(bean)
 }
 
-func (session *Session) cacheInsert(tables ...string) error {
-	if session.statement.RefTable == nil {
+func (session *Session) cacheInsert(table *core.Table, tables ...string) error {
+	if table == nil {
 		return ErrCacheFailed
 	}
 
-	table := session.statement.RefTable
 	cacher := session.engine.getCacher2(table)
-
 	for _, t := range tables {
 		session.engine.logger.Debug("[cache] clear sql:", t)
 		cacher.ClearIds(t)
diff --git a/vendor/github.com/go-xorm/xorm/session_iterate.go b/vendor/github.com/go-xorm/xorm/session_iterate.go
index 7c14809590..a2f957a271 100644
--- a/vendor/github.com/go-xorm/xorm/session_iterate.go
+++ b/vendor/github.com/go-xorm/xorm/session_iterate.go
@@ -19,6 +19,10 @@ func (session *Session) Rows(bean interface{}) (*Rows, error) {
 // are conditions. beans could be []Struct, []*Struct, map[int64]Struct
 // map[int64]*Struct
 func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
+	if session.isAutoClose {
+		defer session.Close()
+	}
+
 	rows, err := session.Rows(bean)
 	if err != nil {
 		return err
diff --git a/vendor/github.com/go-xorm/xorm/session_query.go b/vendor/github.com/go-xorm/xorm/session_query.go
new file mode 100644
index 0000000000..a693bace3f
--- /dev/null
+++ b/vendor/github.com/go-xorm/xorm/session_query.go
@@ -0,0 +1,177 @@
+// Copyright 2017 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 (
+	"fmt"
+	"reflect"
+	"strconv"
+	"time"
+
+	"github.com/go-xorm/core"
+)
+
+// Query runs a raw sql and return records as []map[string][]byte
+func (session *Session) Query(sqlStr string, args ...interface{}) ([]map[string][]byte, error) {
+	if session.isAutoClose {
+		defer session.Close()
+	}
+
+	return session.queryBytes(sqlStr, args...)
+}
+
+func value2String(rawValue *reflect.Value) (str string, err error) {
+	aa := reflect.TypeOf((*rawValue).Interface())
+	vv := reflect.ValueOf((*rawValue).Interface())
+	switch aa.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		str = strconv.FormatInt(vv.Int(), 10)
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		str = strconv.FormatUint(vv.Uint(), 10)
+	case reflect.Float32, reflect.Float64:
+		str = strconv.FormatFloat(vv.Float(), 'f', -1, 64)
+	case reflect.String:
+		str = vv.String()
+	case reflect.Array, reflect.Slice:
+		switch aa.Elem().Kind() {
+		case reflect.Uint8:
+			data := rawValue.Interface().([]byte)
+			str = string(data)
+			if str == "\x00" {
+				str = "0"
+			}
+		default:
+			err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
+		}
+	// time type
+	case reflect.Struct:
+		if aa.ConvertibleTo(core.TimeType) {
+			str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano)
+		} else {
+			err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
+		}
+	case reflect.Bool:
+		str = strconv.FormatBool(vv.Bool())
+	case reflect.Complex128, reflect.Complex64:
+		str = fmt.Sprintf("%v", vv.Complex())
+	/* TODO: unsupported types below
+	   case reflect.Map:
+	   case reflect.Ptr:
+	   case reflect.Uintptr:
+	   case reflect.UnsafePointer:
+	   case reflect.Chan, reflect.Func, reflect.Interface:
+	*/
+	default:
+		err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
+	}
+	return
+}
+
+func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) {
+	result := make(map[string]string)
+	scanResultContainers := make([]interface{}, len(fields))
+	for i := 0; i < len(fields); i++ {
+		var scanResultContainer interface{}
+		scanResultContainers[i] = &scanResultContainer
+	}
+	if err := rows.Scan(scanResultContainers...); err != nil {
+		return nil, err
+	}
+
+	for ii, key := range fields {
+		rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
+		// if row is null then as empty string
+		if rawValue.Interface() == nil {
+			result[key] = ""
+			continue
+		}
+
+		if data, err := value2String(&rawValue); err == nil {
+			result[key] = data
+		} else {
+			return nil, err
+		}
+	}
+	return result, nil
+}
+
+func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
+	fields, err := rows.Columns()
+	if err != nil {
+		return nil, err
+	}
+	for rows.Next() {
+		result, err := row2mapStr(rows, fields)
+		if err != nil {
+			return nil, err
+		}
+		resultsSlice = append(resultsSlice, result)
+	}
+
+	return resultsSlice, nil
+}
+
+// QueryString runs a raw sql and return records as []map[string]string
+func (session *Session) QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) {
+	if session.isAutoClose {
+		defer session.Close()
+	}
+
+	rows, err := session.queryRows(sqlStr, args...)
+	if err != nil {
+		return nil, err
+	}
+	defer rows.Close()
+
+	return rows2Strings(rows)
+}
+
+func row2mapInterface(rows *core.Rows, fields []string) (resultsMap map[string]interface{}, err error) {
+	resultsMap = make(map[string]interface{}, len(fields))
+	scanResultContainers := make([]interface{}, len(fields))
+	for i := 0; i < len(fields); i++ {
+		var scanResultContainer interface{}
+		scanResultContainers[i] = &scanResultContainer
+	}
+	if err := rows.Scan(scanResultContainers...); err != nil {
+		return nil, err
+	}
+
+	for ii, key := range fields {
+		resultsMap[key] = reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])).Interface()
+	}
+	return
+}
+
+func rows2Interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, err error) {
+	fields, err := rows.Columns()
+	if err != nil {
+		return nil, err
+	}
+	for rows.Next() {
+		result, err := row2mapInterface(rows, fields)
+		if err != nil {
+			return nil, err
+		}
+		resultsSlice = append(resultsSlice, result)
+	}
+
+	return resultsSlice, nil
+}
+
+// QueryInterface runs a raw sql and return records as []map[string]interface{}
+func (session *Session) QueryInterface(sqlStr string, args ...interface{}) ([]map[string]interface{}, error) {
+	if session.isAutoClose {
+		defer session.Close()
+	}
+
+	rows, err := session.queryRows(sqlStr, args...)
+	if err != nil {
+		return nil, err
+	}
+	defer rows.Close()
+
+	return rows2Interfaces(rows)
+}
diff --git a/vendor/github.com/go-xorm/xorm/session_raw.go b/vendor/github.com/go-xorm/xorm/session_raw.go
index 05223c465e..c225598e60 100644
--- a/vendor/github.com/go-xorm/xorm/session_raw.go
+++ b/vendor/github.com/go-xorm/xorm/session_raw.go
@@ -6,61 +6,113 @@ package xorm
 
 import (
 	"database/sql"
-	"fmt"
 	"reflect"
-	"strconv"
 	"time"
 
 	"github.com/go-xorm/core"
 )
 
-func (session *Session) query(sqlStr string, paramStr ...interface{}) ([]map[string][]byte, error) {
-	session.queryPreprocess(&sqlStr, paramStr...)
-
-	if session.isAutoCommit {
-		return session.innerQuery2(sqlStr, paramStr...)
+func (session *Session) queryPreprocess(sqlStr *string, paramStr ...interface{}) {
+	for _, filter := range session.engine.dialect.Filters() {
+		*sqlStr = filter.Do(*sqlStr, session.engine.dialect, session.statement.RefTable)
 	}
-	return session.txQuery(session.tx, sqlStr, paramStr...)
+
+	session.lastSQL = *sqlStr
+	session.lastSQLArgs = paramStr
 }
 
-func (session *Session) txQuery(tx *core.Tx, sqlStr string, params ...interface{}) ([]map[string][]byte, error) {
-	rows, err := tx.Query(sqlStr, params...)
+func (session *Session) queryRows(sqlStr string, args ...interface{}) (*core.Rows, error) {
+	defer session.resetStatement()
+
+	session.queryPreprocess(&sqlStr, args...)
+
+	if session.engine.showSQL {
+		if session.engine.showExecTime {
+			b4ExecTime := time.Now()
+			defer func() {
+				execDuration := time.Since(b4ExecTime)
+				if len(args) > 0 {
+					session.engine.logger.Infof("[SQL] %s %#v - took: %v", sqlStr, args, execDuration)
+				} else {
+					session.engine.logger.Infof("[SQL] %s - took: %v", sqlStr, execDuration)
+				}
+			}()
+		} else {
+			if len(args) > 0 {
+				session.engine.logger.Infof("[SQL] %v %#v", sqlStr, args)
+			} else {
+				session.engine.logger.Infof("[SQL] %v", sqlStr)
+			}
+		}
+	}
+
+	if session.isAutoCommit {
+		if session.prepareStmt {
+			// don't clear stmt since session will cache them
+			stmt, err := session.doPrepare(sqlStr)
+			if err != nil {
+				return nil, err
+			}
+
+			rows, err := stmt.Query(args...)
+			if err != nil {
+				return nil, err
+			}
+			return rows, nil
+		}
+
+		rows, err := session.DB().Query(sqlStr, args...)
+		if err != nil {
+			return nil, err
+		}
+		return rows, nil
+	}
+
+	rows, err := session.tx.Query(sqlStr, args...)
 	if err != nil {
 		return nil, err
 	}
-	defer rows.Close()
-
-	return rows2maps(rows)
+	return rows, nil
 }
 
-func (session *Session) innerQuery(sqlStr string, params ...interface{}) (*core.Stmt, *core.Rows, error) {
-	var callback func() (*core.Stmt, *core.Rows, error)
-	if session.prepareStmt {
-		callback = func() (*core.Stmt, *core.Rows, error) {
-			stmt, err := session.doPrepare(sqlStr)
-			if err != nil {
-				return nil, nil, err
-			}
-			rows, err := stmt.Query(params...)
-			if err != nil {
-				return nil, nil, err
-			}
-			return stmt, rows, nil
-		}
-	} else {
-		callback = func() (*core.Stmt, *core.Rows, error) {
-			rows, err := session.DB().Query(sqlStr, params...)
-			if err != nil {
-				return nil, nil, err
-			}
-			return nil, rows, err
-		}
-	}
-	stmt, rows, err := session.engine.logSQLQueryTime(sqlStr, params, callback)
+func (session *Session) queryRow(sqlStr string, args ...interface{}) *core.Row {
+	return core.NewRow(session.queryRows(sqlStr, args...))
+}
+
+func value2Bytes(rawValue *reflect.Value) ([]byte, error) {
+	str, err := value2String(rawValue)
 	if err != nil {
-		return nil, nil, err
+		return nil, err
 	}
-	return stmt, rows, nil
+	return []byte(str), nil
+}
+
+func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) {
+	result := make(map[string][]byte)
+	scanResultContainers := make([]interface{}, len(fields))
+	for i := 0; i < len(fields); i++ {
+		var scanResultContainer interface{}
+		scanResultContainers[i] = &scanResultContainer
+	}
+	if err := rows.Scan(scanResultContainers...); err != nil {
+		return nil, err
+	}
+
+	for ii, key := range fields {
+		rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
+		//if row is null then ignore
+		if rawValue.Interface() == nil {
+			result[key] = []byte{}
+			continue
+		}
+
+		if data, err := value2Bytes(&rawValue); err == nil {
+			result[key] = data
+		} else {
+			return nil, err // !nashtsai! REVIEW, should return err or just error log?
+		}
+	}
+	return result, nil
 }
 
 func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) {
@@ -79,197 +131,45 @@ func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) {
 	return resultsSlice, nil
 }
 
-func value2Bytes(rawValue *reflect.Value) (data []byte, err error) {
-	var str string
-	str, err = reflect2value(rawValue)
-	if err != nil {
-		return
-	}
-	data = []byte(str)
-	return
-}
-
-func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) {
-	result := make(map[string][]byte)
-	scanResultContainers := make([]interface{}, len(fields))
-	for i := 0; i < len(fields); i++ {
-		var scanResultContainer interface{}
-		scanResultContainers[i] = &scanResultContainer
-	}
-	if err := rows.Scan(scanResultContainers...); err != nil {
-		return nil, err
-	}
-
-	for ii, key := range fields {
-		rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
-		//if row is null then ignore
-		if rawValue.Interface() == nil {
-			//fmt.Println("ignore ...", key, rawValue)
-			continue
-		}
-
-		if data, err := value2Bytes(&rawValue); err == nil {
-			result[key] = data
-		} else {
-			return nil, err // !nashtsai! REVIEW, should return err or just error log?
-		}
-	}
-	return result, nil
-}
-
-func (session *Session) innerQuery2(sqlStr string, params ...interface{}) ([]map[string][]byte, error) {
-	_, rows, err := session.innerQuery(sqlStr, params...)
-	if rows != nil {
-		defer rows.Close()
-	}
+func (session *Session) queryBytes(sqlStr string, args ...interface{}) ([]map[string][]byte, error) {
+	rows, err := session.queryRows(sqlStr, args...)
 	if err != nil {
 		return nil, err
 	}
+	defer rows.Close()
+
 	return rows2maps(rows)
 }
 
-// Query runs a raw sql and return records as []map[string][]byte
-func (session *Session) Query(sqlStr string, paramStr ...interface{}) ([]map[string][]byte, error) {
+func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, error) {
 	defer session.resetStatement()
-	if session.isAutoClose {
-		defer session.Close()
-	}
-
-	return session.query(sqlStr, paramStr...)
-}
-
-func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
-	fields, err := rows.Columns()
-	if err != nil {
-		return nil, err
-	}
-	for rows.Next() {
-		result, err := row2mapStr(rows, fields)
-		if err != nil {
-			return nil, err
-		}
-		resultsSlice = append(resultsSlice, result)
-	}
-
-	return resultsSlice, nil
-}
-
-func reflect2value(rawValue *reflect.Value) (str string, err error) {
-	aa := reflect.TypeOf((*rawValue).Interface())
-	vv := reflect.ValueOf((*rawValue).Interface())
-	switch aa.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		str = strconv.FormatInt(vv.Int(), 10)
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-		str = strconv.FormatUint(vv.Uint(), 10)
-	case reflect.Float32, reflect.Float64:
-		str = strconv.FormatFloat(vv.Float(), 'f', -1, 64)
-	case reflect.String:
-		str = vv.String()
-	case reflect.Array, reflect.Slice:
-		switch aa.Elem().Kind() {
-		case reflect.Uint8:
-			data := rawValue.Interface().([]byte)
-			str = string(data)
-		default:
-			err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
-		}
-	// time type
-	case reflect.Struct:
-		if aa.ConvertibleTo(core.TimeType) {
-			str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano)
-		} else {
-			err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
-		}
-	case reflect.Bool:
-		str = strconv.FormatBool(vv.Bool())
-	case reflect.Complex128, reflect.Complex64:
-		str = fmt.Sprintf("%v", vv.Complex())
-	/* TODO: unsupported types below
-	   case reflect.Map:
-	   case reflect.Ptr:
-	   case reflect.Uintptr:
-	   case reflect.UnsafePointer:
-	   case reflect.Chan, reflect.Func, reflect.Interface:
-	*/
-	default:
-		err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
-	}
-	return
-}
-
-func value2String(rawValue *reflect.Value) (data string, err error) {
-	data, err = reflect2value(rawValue)
-	if err != nil {
-		return
-	}
-	return
-}
-
-func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) {
-	result := make(map[string]string)
-	scanResultContainers := make([]interface{}, len(fields))
-	for i := 0; i < len(fields); i++ {
-		var scanResultContainer interface{}
-		scanResultContainers[i] = &scanResultContainer
-	}
-	if err := rows.Scan(scanResultContainers...); err != nil {
-		return nil, err
-	}
-
-	for ii, key := range fields {
-		rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
-		//if row is null then ignore
-		if rawValue.Interface() == nil {
-			//fmt.Println("ignore ...", key, rawValue)
-			continue
-		}
-
-		if data, err := value2String(&rawValue); err == nil {
-			result[key] = data
-		} else {
-			return nil, err // !nashtsai! REVIEW, should return err or just error log?
-		}
-	}
-	return result, nil
-}
-
-func txQuery2(tx *core.Tx, sqlStr string, params ...interface{}) ([]map[string]string, error) {
-	rows, err := tx.Query(sqlStr, params...)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-
-	return rows2Strings(rows)
-}
-
-func query2(db *core.DB, sqlStr string, params ...interface{}) ([]map[string]string, error) {
-	rows, err := db.Query(sqlStr, params...)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-	return rows2Strings(rows)
-}
-
-// QueryString runs a raw sql and return records as []map[string]string
-func (session *Session) QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) {
-	defer session.resetStatement()
-	if session.isAutoClose {
-		defer session.Close()
-	}
 
 	session.queryPreprocess(&sqlStr, args...)
 
-	if session.isAutoCommit {
-		return query2(session.DB(), sqlStr, args...)
+	if session.engine.showSQL {
+		if session.engine.showExecTime {
+			b4ExecTime := time.Now()
+			defer func() {
+				execDuration := time.Since(b4ExecTime)
+				if len(args) > 0 {
+					session.engine.logger.Infof("[SQL] %s %#v - took: %v", sqlStr, args, execDuration)
+				} else {
+					session.engine.logger.Infof("[SQL] %s - took: %v", sqlStr, execDuration)
+				}
+			}()
+		} else {
+			if len(args) > 0 {
+				session.engine.logger.Infof("[SQL] %v %#v", sqlStr, args)
+			} else {
+				session.engine.logger.Infof("[SQL] %v", sqlStr)
+			}
+		}
+	}
+
+	if !session.isAutoCommit {
+		return session.tx.Exec(sqlStr, args...)
 	}
-	return txQuery2(session.tx, sqlStr, args...)
-}
 
-// Execute sql
-func (session *Session) innerExec(sqlStr string, args ...interface{}) (sql.Result, error) {
 	if session.prepareStmt {
 		stmt, err := session.doPrepare(sqlStr)
 		if err != nil {
@@ -286,32 +186,8 @@ func (session *Session) innerExec(sqlStr string, args ...interface{}) (sql.Resul
 	return session.DB().Exec(sqlStr, args...)
 }
 
-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)
-	}
-
-	session.saveLastSQL(sqlStr, args...)
-
-	return session.engine.logSQLExecutionTime(sqlStr, args, func() (sql.Result, error) {
-		if session.isAutoCommit {
-			// FIXME: oci8 can not auto commit (github.com/mattn/go-oci8)
-			if session.engine.dialect.DBType() == core.ORACLE {
-				session.Begin()
-				r, err := session.tx.Exec(sqlStr, args...)
-				session.Commit()
-				return r, err
-			}
-			return session.innerExec(sqlStr, args...)
-		}
-		return session.tx.Exec(sqlStr, args...)
-	})
-}
-
 // Exec raw sql
 func (session *Session) Exec(sqlStr string, args ...interface{}) (sql.Result, error) {
-	defer session.resetStatement()
 	if session.isAutoClose {
 		defer session.Close()
 	}
diff --git a/vendor/github.com/go-xorm/xorm/session_schema.go b/vendor/github.com/go-xorm/xorm/session_schema.go
index c1d5088d78..a2708b736c 100644
--- a/vendor/github.com/go-xorm/xorm/session_schema.go
+++ b/vendor/github.com/go-xorm/xorm/session_schema.go
@@ -16,7 +16,6 @@ import (
 
 // Ping test if database is ok
 func (session *Session) Ping() error {
-	defer session.resetStatement()
 	if session.isAutoClose {
 		defer session.Close()
 	}
@@ -35,7 +34,6 @@ func (session *Session) CreateTable(bean interface{}) error {
 }
 
 func (session *Session) createTable(bean interface{}) error {
-	defer session.resetStatement()
 	v := rValue(bean)
 	if err := session.statement.setRefValue(v); err != nil {
 		return err
@@ -56,7 +54,6 @@ func (session *Session) CreateIndexes(bean interface{}) error {
 }
 
 func (session *Session) createIndexes(bean interface{}) error {
-	defer session.resetStatement()
 	v := rValue(bean)
 	if err := session.statement.setRefValue(v); err != nil {
 		return err
@@ -81,7 +78,6 @@ func (session *Session) CreateUniques(bean interface{}) error {
 }
 
 func (session *Session) createUniques(bean interface{}) error {
-	defer session.resetStatement()
 	v := rValue(bean)
 	if err := session.statement.setRefValue(v); err != nil {
 		return err
@@ -107,7 +103,6 @@ func (session *Session) DropIndexes(bean interface{}) error {
 }
 
 func (session *Session) dropIndexes(bean interface{}) error {
-	defer session.resetStatement()
 	v := rValue(bean)
 	if err := session.statement.setRefValue(v); err != nil {
 		return err
@@ -133,7 +128,6 @@ func (session *Session) DropTable(beanOrTableName interface{}) error {
 }
 
 func (session *Session) dropTable(beanOrTableName interface{}) error {
-	defer session.resetStatement()
 	tableName, err := session.engine.tableName(beanOrTableName)
 	if err != nil {
 		return err
@@ -142,7 +136,7 @@ func (session *Session) dropTable(beanOrTableName interface{}) error {
 	var needDrop = true
 	if !session.engine.dialect.SupportDropIfExists() {
 		sqlStr, args := session.engine.dialect.TableCheckSql(tableName)
-		results, err := session.query(sqlStr, args...)
+		results, err := session.queryBytes(sqlStr, args...)
 		if err != nil {
 			return err
 		}
@@ -172,9 +166,8 @@ func (session *Session) IsTableExist(beanOrTableName interface{}) (bool, error)
 }
 
 func (session *Session) isTableExist(tableName string) (bool, error) {
-	defer session.resetStatement()
 	sqlStr, args := session.engine.dialect.TableCheckSql(tableName)
-	results, err := session.query(sqlStr, args...)
+	results, err := session.queryBytes(sqlStr, args...)
 	return len(results) > 0, err
 }
 
@@ -196,12 +189,9 @@ func (session *Session) IsTableEmpty(bean interface{}) (bool, error) {
 }
 
 func (session *Session) isTableEmpty(tableName string) (bool, error) {
-	defer session.resetStatement()
-
 	var total int64
 	sqlStr := fmt.Sprintf("select count(*) from %s", session.engine.Quote(tableName))
-	err := session.DB().QueryRow(sqlStr).Scan(&total)
-	session.saveLastSQL(sqlStr)
+	err := session.queryRow(sqlStr).Scan(&total)
 	if err != nil {
 		if err == sql.ErrNoRows {
 			err = nil
@@ -214,8 +204,6 @@ func (session *Session) isTableEmpty(tableName string) (bool, error) {
 
 // find if index is exist according cols
 func (session *Session) isIndexExist2(tableName string, cols []string, unique bool) (bool, error) {
-	defer session.resetStatement()
-
 	indexes, err := session.engine.dialect.GetIndexes(tableName)
 	if err != nil {
 		return false, err
@@ -233,8 +221,6 @@ func (session *Session) isIndexExist2(tableName string, cols []string, unique bo
 }
 
 func (session *Session) addColumn(colName string) error {
-	defer session.resetStatement()
-
 	col := session.statement.RefTable.GetColumn(colName)
 	sql, args := session.statement.genAddColumnStr(col)
 	_, err := session.exec(sql, args...)
@@ -242,18 +228,13 @@ func (session *Session) addColumn(colName string) error {
 }
 
 func (session *Session) addIndex(tableName, idxName string) error {
-	defer session.resetStatement()
-
 	index := session.statement.RefTable.Indexes[idxName]
 	sqlStr := session.engine.dialect.CreateIndexSql(tableName, index)
-
 	_, err := session.exec(sqlStr)
 	return err
 }
 
 func (session *Session) addUnique(tableName, uqeName string) error {
-	defer session.resetStatement()
-
 	index := session.statement.RefTable.Indexes[uqeName]
 	sqlStr := session.engine.dialect.CreateIndexSql(tableName, index)
 	_, err := session.exec(sqlStr)
diff --git a/vendor/github.com/go-xorm/xorm/session_stats.go b/vendor/github.com/go-xorm/xorm/session_stats.go
index df02e95a8a..c2cac83069 100644
--- a/vendor/github.com/go-xorm/xorm/session_stats.go
+++ b/vendor/github.com/go-xorm/xorm/session_stats.go
@@ -13,7 +13,6 @@ import (
 // Count counts the records. bean's non-empty fields
 // are conditions.
 func (session *Session) Count(bean ...interface{}) (int64, error) {
-	defer session.resetStatement()
 	if session.isAutoClose {
 		defer session.Close()
 	}
@@ -31,15 +30,8 @@ func (session *Session) Count(bean ...interface{}) (int64, error) {
 		args = session.statement.RawParams
 	}
 
-	session.queryPreprocess(&sqlStr, args...)
-
 	var total int64
-	if session.isAutoCommit {
-		err = session.DB().QueryRow(sqlStr, args...).Scan(&total)
-	} else {
-		err = session.tx.QueryRow(sqlStr, args...).Scan(&total)
-	}
-
+	err = session.queryRow(sqlStr, args...).Scan(&total)
 	if err == sql.ErrNoRows || err == nil {
 		return total, nil
 	}
@@ -49,7 +41,6 @@ func (session *Session) Count(bean ...interface{}) (int64, error) {
 
 // sum call sum some column. bean's non-empty fields are conditions.
 func (session *Session) sum(res interface{}, bean interface{}, columnNames ...string) error {
-	defer session.resetStatement()
 	if session.isAutoClose {
 		defer session.Close()
 	}
@@ -73,22 +64,11 @@ func (session *Session) sum(res interface{}, bean interface{}, columnNames ...st
 		args = session.statement.RawParams
 	}
 
-	session.queryPreprocess(&sqlStr, args...)
-
 	if isSlice {
-		if session.isAutoCommit {
-			err = session.DB().QueryRow(sqlStr, args...).ScanSlice(res)
-		} else {
-			err = session.tx.QueryRow(sqlStr, args...).ScanSlice(res)
-		}
+		err = session.queryRow(sqlStr, args...).ScanSlice(res)
 	} else {
-		if session.isAutoCommit {
-			err = session.DB().QueryRow(sqlStr, args...).Scan(res)
-		} else {
-			err = session.tx.QueryRow(sqlStr, args...).Scan(res)
-		}
+		err = session.queryRow(sqlStr, args...).Scan(res)
 	}
-
 	if err == sql.ErrNoRows || err == nil {
 		return nil
 	}
diff --git a/vendor/github.com/go-xorm/xorm/session_update.go b/vendor/github.com/go-xorm/xorm/session_update.go
index e80cd0b577..6e9d11681c 100644
--- a/vendor/github.com/go-xorm/xorm/session_update.go
+++ b/vendor/github.com/go-xorm/xorm/session_update.go
@@ -15,8 +15,8 @@ import (
 	"github.com/go-xorm/core"
 )
 
-func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error {
-	if session.statement.RefTable == nil ||
+func (session *Session) cacheUpdate(table *core.Table, tableName, sqlStr string, args ...interface{}) error {
+	if table == nil ||
 		session.tx != nil {
 		return ErrCacheFailed
 	}
@@ -26,7 +26,7 @@ func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error {
 		return ErrCacheFailed
 	}
 	for _, filter := range session.engine.dialect.Filters() {
-		newsql = filter.Do(newsql, session.engine.dialect, session.statement.RefTable)
+		newsql = filter.Do(newsql, session.engine.dialect, table)
 	}
 	session.engine.logger.Debug("[cacheUpdate] new sql", oldhead, newsql)
 
@@ -39,13 +39,12 @@ func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error {
 			nStart = strings.Count(oldhead, "$")
 		}
 	}
-	table := session.statement.RefTable
+
 	cacher := session.engine.getCacher2(table)
-	tableName := session.statement.TableName()
 	session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:])
 	ids, err := core.GetCacheSql(cacher, tableName, newsql, args[nStart:])
 	if err != nil {
-		rows, err := session.DB().Query(newsql, args[nStart:]...)
+		rows, err := session.NoCache().queryRows(newsql, args[nStart:]...)
 		if err != nil {
 			return err
 		}
@@ -144,7 +143,6 @@ func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error {
 //         You should call UseBool if you have bool to use.
 //        2.float32 & float64 may be not inexact as conditions
 func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int64, error) {
-	defer session.resetStatement()
 	if session.isAutoClose {
 		defer session.Close()
 	}
@@ -249,8 +247,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
 		}
 	}
 
-	st := session.statement
-	defer session.resetStatement()
+	st := &session.statement
 
 	var sqlStr string
 	var condArgs []interface{}
@@ -282,6 +279,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
 		condSQL = condSQL + fmt.Sprintf(" ORDER BY %v", st.OrderStr)
 	}
 
+	var tableName = session.statement.TableName()
 	// TODO: Oracle support needed
 	var top string
 	if st.LimitN > 0 {
@@ -290,7 +288,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
 		} else if st.Engine.dialect.DBType() == core.SQLITE {
 			tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
 			cond = cond.And(builder.Expr(fmt.Sprintf("rowid IN (SELECT rowid FROM %v %v)",
-				session.engine.Quote(session.statement.TableName()), tempCondSQL), condArgs...))
+				session.engine.Quote(tableName), tempCondSQL), condArgs...))
 			condSQL, condArgs, err = builder.ToSQL(cond)
 			if err != nil {
 				return 0, err
@@ -301,7 +299,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
 		} else if st.Engine.dialect.DBType() == core.POSTGRES {
 			tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
 			cond = cond.And(builder.Expr(fmt.Sprintf("CTID IN (SELECT CTID FROM %v %v)",
-				session.engine.Quote(session.statement.TableName()), tempCondSQL), condArgs...))
+				session.engine.Quote(tableName), tempCondSQL), condArgs...))
 			condSQL, condArgs, err = builder.ToSQL(cond)
 			if err != nil {
 				return 0, err
@@ -315,7 +313,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
 				table != nil && len(table.PrimaryKeys) == 1 {
 				cond = builder.Expr(fmt.Sprintf("%s IN (SELECT TOP (%d) %s FROM %v%v)",
 					table.PrimaryKeys[0], st.LimitN, table.PrimaryKeys[0],
-					session.engine.Quote(session.statement.TableName()), condSQL), condArgs...)
+					session.engine.Quote(tableName), condSQL), condArgs...)
 
 				condSQL, condArgs, err = builder.ToSQL(cond)
 				if err != nil {
@@ -336,7 +334,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
 
 	sqlStr = fmt.Sprintf("UPDATE %v%v SET %v %v",
 		top,
-		session.engine.Quote(session.statement.TableName()),
+		session.engine.Quote(tableName),
 		strings.Join(colNames, ", "),
 		condSQL)
 
@@ -351,8 +349,9 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
 
 	if table != nil {
 		if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
-			cacher.ClearIds(session.statement.TableName())
-			cacher.ClearBeans(session.statement.TableName())
+			//session.cacheUpdate(table, tableName, sqlStr, args...)
+			cacher.ClearIds(tableName)
+			cacher.ClearBeans(tableName)
 		}
 	}
 
@@ -362,7 +361,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
 			closure(bean)
 		}
 		if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok {
-			session.engine.logger.Debug("[event]", session.statement.TableName(), " has after update processor")
+			session.engine.logger.Debug("[event]", tableName, " has after update processor")
 			processor.AfterUpdate()
 		}
 	} else {
diff --git a/vendor/github.com/go-xorm/xorm/statement.go b/vendor/github.com/go-xorm/xorm/statement.go
index 50008d1dd8..dc8a0c9b23 100644
--- a/vendor/github.com/go-xorm/xorm/statement.go
+++ b/vendor/github.com/go-xorm/xorm/statement.go
@@ -1205,7 +1205,8 @@ func (statement *Statement) convertIDSQL(sqlStr string) string {
 			top = fmt.Sprintf("TOP %d ", statement.LimitN)
 		}
 
-		return fmt.Sprintf("SELECT %s%s FROM %v", top, colstrs, sqls[1])
+		newsql := fmt.Sprintf("SELECT %s%s FROM %v", top, colstrs, sqls[1])
+		return newsql
 	}
 	return ""
 }
diff --git a/vendor/github.com/go-xorm/xorm/test_mssql_cache.sh b/vendor/github.com/go-xorm/xorm/test_mssql_cache.sh
new file mode 100755
index 0000000000..76efd6ca0a
--- /dev/null
+++ b/vendor/github.com/go-xorm/xorm/test_mssql_cache.sh
@@ -0,0 +1 @@
+go test -db=mssql -conn_str="server=192.168.1.58;user id=sa;password=123456;database=xorm_test" -cache=true
\ No newline at end of file
diff --git a/vendor/github.com/go-xorm/xorm/test_mymysql_cache.sh b/vendor/github.com/go-xorm/xorm/test_mymysql_cache.sh
new file mode 100755
index 0000000000..0100286d65
--- /dev/null
+++ b/vendor/github.com/go-xorm/xorm/test_mymysql_cache.sh
@@ -0,0 +1 @@
+go test -db=mymysql -conn_str="xorm_test/root/" -cache=true
\ No newline at end of file
diff --git a/vendor/github.com/go-xorm/xorm/test_mysql_cache.sh b/vendor/github.com/go-xorm/xorm/test_mysql_cache.sh
new file mode 100755
index 0000000000..c542e73594
--- /dev/null
+++ b/vendor/github.com/go-xorm/xorm/test_mysql_cache.sh
@@ -0,0 +1 @@
+go test -db=mysql -conn_str="root:@/xorm_test" -cache=true
\ No newline at end of file
diff --git a/vendor/github.com/go-xorm/xorm/test_postgres_cache.sh b/vendor/github.com/go-xorm/xorm/test_postgres_cache.sh
new file mode 100755
index 0000000000..462fc948cb
--- /dev/null
+++ b/vendor/github.com/go-xorm/xorm/test_postgres_cache.sh
@@ -0,0 +1 @@
+go test -db=postgres -conn_str="dbname=xorm_test sslmode=disable" -cache=true
\ No newline at end of file
diff --git a/vendor/github.com/go-xorm/xorm/test_sqlite_cache.sh b/vendor/github.com/go-xorm/xorm/test_sqlite_cache.sh
new file mode 100755
index 0000000000..75a054c3f1
--- /dev/null
+++ b/vendor/github.com/go-xorm/xorm/test_sqlite_cache.sh
@@ -0,0 +1 @@
+go test -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" -cache=true
\ No newline at end of file
diff --git a/vendor/github.com/go-xorm/xorm/xorm.go b/vendor/github.com/go-xorm/xorm/xorm.go
index 4434c7ff37..4fdadf2fad 100644
--- a/vendor/github.com/go-xorm/xorm/xorm.go
+++ b/vendor/github.com/go-xorm/xorm/xorm.go
@@ -17,7 +17,7 @@ import (
 
 const (
 	// Version show the xorm's version
-	Version string = "0.6.3.0713"
+	Version string = "0.6.4.0910"
 )
 
 func regDrvsNDialects() bool {
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 5fd393b8be..7c4c157f39 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -456,10 +456,10 @@
 			"revisionTime": "2017-05-19T03:21:30Z"
 		},
 		{
-			"checksumSHA1": "KOHXTLwpgTMxBB9aGF2aIxkWdm8=",
+			"checksumSHA1": "HMavuxvDhKOwmbbFnYt9hfT6jE0=",
 			"path": "github.com/go-xorm/core",
-			"revision": "71c1070a861118827352b1394eb86cbfeef5c513",
-			"revisionTime": "2017-08-22T05:50:40Z"
+			"revision": "da1adaf7a28ca792961721a34e6e04945200c890",
+			"revisionTime": "2017-09-09T08:56:53Z"
 		},
 		{
 			"checksumSHA1": "k52lEKLp8j5M+jFpe+3u+bIFpxQ=",
@@ -468,10 +468,10 @@
 			"revisionTime": "2016-08-11T02:11:45Z"
 		},
 		{
-			"checksumSHA1": "0F65zfDi1ys3KD/wMKtxC2k13DA=",
+			"checksumSHA1": "SoZDnkd5NdwE0g4MY1nTAl8ZtPo=",
 			"path": "github.com/go-xorm/xorm",
-			"revision": "a10b5aba4bb97b30daa74e7c0363d3084ede0514",
-			"revisionTime": "2017-08-20T09:05:42Z"
+			"revision": "c29485f954ed6495861c0098f9a1642a467299c8",
+			"revisionTime": "2017-09-10T12:58:18Z"
 		},
 		{
 			"checksumSHA1": "1ft/4j5MFa7C9dPI9whL03HSUzk=",