Use created & updated instead BeforeInsert & BeforeUpdate (#2482)
* use created & updated instead BeforeInsert & BeforeUpdate * fix vendor checksum * only show generated SQL when development mode * remove extra update column updated_unix * remove trace configrelease/v1.15
parent
4c2b1be3a4
commit
005900baea
|
@ -86,13 +86,7 @@ type Action struct {
|
||||||
IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"`
|
IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"`
|
||||||
Content string `xorm:"TEXT"`
|
Content string `xorm:"TEXT"`
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
CreatedUnix int64 `xorm:"INDEX created"`
|
||||||
}
|
|
||||||
|
|
||||||
// BeforeInsert will be invoked by XORM before inserting a record
|
|
||||||
// representing this object.
|
|
||||||
func (a *Action) BeforeInsert() {
|
|
||||||
a.CreatedUnix = time.Now().Unix()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AfterSet updates the webhook object upon setting a column.
|
// AfterSet updates the webhook object upon setting a column.
|
||||||
|
|
|
@ -29,12 +29,7 @@ type Notice struct {
|
||||||
Type NoticeType
|
Type NoticeType
|
||||||
Description string `xorm:"TEXT"`
|
Description string `xorm:"TEXT"`
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
CreatedUnix int64 `xorm:"INDEX created"`
|
||||||
}
|
|
||||||
|
|
||||||
// BeforeInsert is invoked from XORM before inserting an object of this type.
|
|
||||||
func (n *Notice) BeforeInsert() {
|
|
||||||
n.CreatedUnix = time.Now().Unix()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
||||||
|
|
|
@ -28,12 +28,7 @@ type Attachment struct {
|
||||||
Name string
|
Name string
|
||||||
DownloadCount int64 `xorm:"DEFAULT 0"`
|
DownloadCount int64 `xorm:"DEFAULT 0"`
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64
|
CreatedUnix int64 `xorm:"created"`
|
||||||
}
|
|
||||||
|
|
||||||
// BeforeInsert is invoked from XORM before inserting an object of this type.
|
|
||||||
func (a *Attachment) BeforeInsert() {
|
|
||||||
a.CreatedUnix = time.Now().Unix()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AfterSet is invoked from XORM after setting the value of a field of
|
// AfterSet is invoked from XORM after setting the value of a field of
|
||||||
|
|
|
@ -22,20 +22,9 @@ type ProtectedBranch struct {
|
||||||
BranchName string `xorm:"UNIQUE(s)"`
|
BranchName string `xorm:"UNIQUE(s)"`
|
||||||
CanPush bool
|
CanPush bool
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64
|
CreatedUnix int64 `xorm:"created"`
|
||||||
Updated time.Time `xorm:"-"`
|
Updated time.Time `xorm:"-"`
|
||||||
UpdatedUnix int64
|
UpdatedUnix int64 `xorm:"updated"`
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProtectedBranchByRepoID getting protected branch by repo ID
|
// GetProtectedBranchByRepoID getting protected branch by repo ID
|
||||||
|
|
|
@ -54,23 +54,16 @@ type Issue struct {
|
||||||
Deadline time.Time `xorm:"-"`
|
Deadline time.Time `xorm:"-"`
|
||||||
DeadlineUnix int64 `xorm:"INDEX"`
|
DeadlineUnix int64 `xorm:"INDEX"`
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
CreatedUnix int64 `xorm:"INDEX created"`
|
||||||
Updated time.Time `xorm:"-"`
|
Updated time.Time `xorm:"-"`
|
||||||
UpdatedUnix int64 `xorm:"INDEX"`
|
UpdatedUnix int64 `xorm:"INDEX updated"`
|
||||||
|
|
||||||
Attachments []*Attachment `xorm:"-"`
|
Attachments []*Attachment `xorm:"-"`
|
||||||
Comments []*Comment `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.
|
// BeforeUpdate is invoked from XORM before updating this object.
|
||||||
func (issue *Issue) BeforeUpdate() {
|
func (issue *Issue) BeforeUpdate() {
|
||||||
issue.UpdatedUnix = time.Now().Unix()
|
|
||||||
issue.DeadlineUnix = issue.Deadline.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 {
|
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 {
|
if _, err := e.Id(issue.ID).Cols(cols...).Update(issue); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,9 +99,9 @@ type Comment struct {
|
||||||
RenderedContent string `xorm:"-"`
|
RenderedContent string `xorm:"-"`
|
||||||
|
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
CreatedUnix int64 `xorm:"INDEX created"`
|
||||||
Updated time.Time `xorm:"-"`
|
Updated time.Time `xorm:"-"`
|
||||||
UpdatedUnix int64 `xorm:"INDEX"`
|
UpdatedUnix int64 `xorm:"INDEX updated"`
|
||||||
|
|
||||||
// Reference issue in commit message
|
// Reference issue in commit message
|
||||||
CommitSHA string `xorm:"VARCHAR(40)"`
|
CommitSHA string `xorm:"VARCHAR(40)"`
|
||||||
|
@ -112,18 +112,6 @@ type Comment struct {
|
||||||
ShowTag CommentTag `xorm:"-"`
|
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.
|
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
||||||
func (c *Comment) AfterSet(colName string, _ xorm.Cell) {
|
func (c *Comment) AfterSet(colName string, _ xorm.Cell) {
|
||||||
var err error
|
var err error
|
||||||
|
|
|
@ -2,8 +2,9 @@ package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/go-xorm/xorm"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-xorm/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LFSMetaObject stores metadata for LFS tracked files.
|
// LFSMetaObject stores metadata for LFS tracked files.
|
||||||
|
@ -14,7 +15,7 @@ type LFSMetaObject struct {
|
||||||
RepositoryID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
RepositoryID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||||
Existing bool `xorm:"-"`
|
Existing bool `xorm:"-"`
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64
|
CreatedUnix int64 `xorm:"created"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LFSTokenResponse defines the JSON structure in which the JWT token is stored.
|
// LFSTokenResponse defines the JSON structure in which the JWT token is stored.
|
||||||
|
@ -108,11 +109,6 @@ func RemoveLFSMetaObjectByOid(oid string) error {
|
||||||
return sess.Commit()
|
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.
|
// AfterSet stores the LFSMetaObject creation time in the database as local time.
|
||||||
func (m *LFSMetaObject) AfterSet(colName string, _ xorm.Cell) {
|
func (m *LFSMetaObject) AfterSet(colName string, _ xorm.Cell) {
|
||||||
switch colName {
|
switch colName {
|
||||||
|
|
|
@ -148,20 +148,9 @@ type LoginSource struct {
|
||||||
Cfg core.Conversion `xorm:"TEXT"`
|
Cfg core.Conversion `xorm:"TEXT"`
|
||||||
|
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
CreatedUnix int64 `xorm:"INDEX created"`
|
||||||
Updated time.Time `xorm:"-"`
|
Updated time.Time `xorm:"-"`
|
||||||
UpdatedUnix int64 `xorm:"INDEX"`
|
UpdatedUnix int64 `xorm:"INDEX updated"`
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cell2Int64 converts a xorm.Cell type to int64,
|
// Cell2Int64 converts a xorm.Cell type to int64,
|
||||||
|
|
|
@ -241,6 +241,7 @@ func NewTestEngine(x *xorm.Engine) (err error) {
|
||||||
|
|
||||||
x.SetMapper(core.GonicMapper{})
|
x.SetMapper(core.GonicMapper{})
|
||||||
x.SetLogger(log.XORMLogger)
|
x.SetLogger(log.XORMLogger)
|
||||||
|
x.ShowSQL(!setting.ProdMode)
|
||||||
return x.StoreEngine("InnoDB").Sync2(tables...)
|
return x.StoreEngine("InnoDB").Sync2(tables...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -211,20 +211,9 @@ type Repository struct {
|
||||||
Size int64 `xorm:"NOT NULL DEFAULT 0"`
|
Size int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||||
|
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
CreatedUnix int64 `xorm:"INDEX created"`
|
||||||
Updated time.Time `xorm:"-"`
|
Updated time.Time `xorm:"-"`
|
||||||
UpdatedUnix int64 `xorm:"INDEX"`
|
UpdatedUnix int64 `xorm:"INDEX updated"`
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
||||||
|
|
|
@ -40,18 +40,26 @@ type Mirror struct {
|
||||||
|
|
||||||
// BeforeInsert will be invoked by XORM before inserting a record
|
// BeforeInsert will be invoked by XORM before inserting a record
|
||||||
func (m *Mirror) BeforeInsert() {
|
func (m *Mirror) BeforeInsert() {
|
||||||
m.UpdatedUnix = time.Now().Unix()
|
if m != nil {
|
||||||
m.NextUpdateUnix = m.NextUpdate.Unix()
|
m.UpdatedUnix = time.Now().Unix()
|
||||||
|
m.NextUpdateUnix = m.NextUpdate.Unix()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeforeUpdate is invoked from XORM before updating this object.
|
// BeforeUpdate is invoked from XORM before updating this object.
|
||||||
func (m *Mirror) BeforeUpdate() {
|
func (m *Mirror) BeforeUpdate() {
|
||||||
m.UpdatedUnix = time.Now().Unix()
|
if m != nil {
|
||||||
m.NextUpdateUnix = m.NextUpdate.Unix()
|
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.
|
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
||||||
func (m *Mirror) AfterSet(colName string, _ xorm.Cell) {
|
func (m *Mirror) AfterSet(colName string, _ xorm.Cell) {
|
||||||
|
if m == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
switch colName {
|
switch colName {
|
||||||
case "repo_id":
|
case "repo_id":
|
||||||
|
|
|
@ -55,21 +55,11 @@ type PublicKey struct {
|
||||||
Type KeyType `xorm:"NOT NULL DEFAULT 1"`
|
Type KeyType `xorm:"NOT NULL DEFAULT 1"`
|
||||||
|
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64
|
CreatedUnix int64 `xorm:"created"`
|
||||||
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
|
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
|
||||||
UpdatedUnix int64
|
UpdatedUnix int64 `xorm:"updated"`
|
||||||
HasRecentActivity bool `xorm:"-"`
|
HasRecentActivity bool `xorm:"-"`
|
||||||
HasUsed 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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
// 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:"-"`
|
Content string `xorm:"-"`
|
||||||
|
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64
|
CreatedUnix int64 `xorm:"created"`
|
||||||
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
|
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
|
||||||
UpdatedUnix int64
|
UpdatedUnix int64 `xorm:"updated"`
|
||||||
HasRecentActivity bool `xorm:"-"`
|
HasRecentActivity bool `xorm:"-"`
|
||||||
HasUsed 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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
||||||
|
|
|
@ -66,20 +66,9 @@ type CommitStatus struct {
|
||||||
CreatorID int64
|
CreatorID int64
|
||||||
|
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
CreatedUnix int64 `xorm:"INDEX created"`
|
||||||
Updated time.Time `xorm:"-"`
|
Updated time.Time `xorm:"-"`
|
||||||
UpdatedUnix int64 `xorm:"INDEX"`
|
UpdatedUnix int64 `xorm:"INDEX updated"`
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AfterSet is invoked from XORM after setting the value of a field of
|
// AfterSet is invoked from XORM after setting the value of a field of
|
||||||
|
|
|
@ -21,23 +21,13 @@ type AccessToken struct {
|
||||||
Sha1 string `xorm:"UNIQUE VARCHAR(40)"`
|
Sha1 string `xorm:"UNIQUE VARCHAR(40)"`
|
||||||
|
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
CreatedUnix int64 `xorm:"INDEX created"`
|
||||||
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
|
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
|
||||||
UpdatedUnix int64 `xorm:"INDEX"`
|
UpdatedUnix int64 `xorm:"INDEX updated"`
|
||||||
HasRecentActivity bool `xorm:"-"`
|
HasRecentActivity bool `xorm:"-"`
|
||||||
HasUsed 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.
|
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
||||||
func (t *AccessToken) AfterSet(colName string, _ xorm.Cell) {
|
func (t *AccessToken) AfterSet(colName string, _ xorm.Cell) {
|
||||||
switch colName {
|
switch colName {
|
||||||
|
|
|
@ -26,19 +26,9 @@ type TwoFactor struct {
|
||||||
ScratchToken string
|
ScratchToken string
|
||||||
|
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
CreatedUnix int64 `xorm:"INDEX created"`
|
||||||
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
|
Updated time.Time `xorm:"-"` // Note: Updated must below Created for AfterSet.
|
||||||
UpdatedUnix int64 `xorm:"INDEX"`
|
UpdatedUnix int64 `xorm:"INDEX updated"`
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
// AfterSet is invoked from XORM after setting the value of a field of this object.
|
||||||
|
|
|
@ -28,6 +28,7 @@ func CreateTestEngine(fixturesDir string) error {
|
||||||
if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
|
if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
x.ShowSQL(true)
|
||||||
|
|
||||||
return InitFixtures(&testfixtures.SQLite{}, fixturesDir)
|
return InitFixtures(&testfixtures.SQLite{}, fixturesDir)
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,9 +94,9 @@ type User struct {
|
||||||
Salt string `xorm:"VARCHAR(10)"`
|
Salt string `xorm:"VARCHAR(10)"`
|
||||||
|
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
CreatedUnix int64 `xorm:"INDEX created"`
|
||||||
Updated time.Time `xorm:"-"`
|
Updated time.Time `xorm:"-"`
|
||||||
UpdatedUnix int64 `xorm:"INDEX"`
|
UpdatedUnix int64 `xorm:"INDEX updated"`
|
||||||
LastLogin time.Time `xorm:"-"`
|
LastLogin time.Time `xorm:"-"`
|
||||||
LastLoginUnix int64 `xorm:"INDEX"`
|
LastLoginUnix int64 `xorm:"INDEX"`
|
||||||
|
|
||||||
|
@ -135,18 +135,11 @@ type User struct {
|
||||||
DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"`
|
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.
|
// BeforeUpdate is invoked from XORM before updating this object.
|
||||||
func (u *User) BeforeUpdate() {
|
func (u *User) BeforeUpdate() {
|
||||||
if u.MaxRepoCreation < -1 {
|
if u.MaxRepoCreation < -1 {
|
||||||
u.MaxRepoCreation = -1
|
u.MaxRepoCreation = -1
|
||||||
}
|
}
|
||||||
u.UpdatedUnix = time.Now().Unix()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLastLogin set time to last login
|
// 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.Website = base.TruncateString(u.Website, 255)
|
||||||
u.Description = base.TruncateString(u.Description, 255)
|
u.Description = base.TruncateString(u.Description, 255)
|
||||||
|
|
||||||
cols = append(cols, "updated_unix")
|
|
||||||
_, err := x.Id(u.ID).Cols(cols...).Update(u)
|
_, err := x.Id(u.ID).Cols(cols...).Update(u)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,22 +107,9 @@ type Webhook struct {
|
||||||
LastStatus HookStatus // Last delivery status
|
LastStatus HookStatus // Last delivery status
|
||||||
|
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
CreatedUnix int64 `xorm:"INDEX created"`
|
||||||
Updated time.Time `xorm:"-"`
|
Updated time.Time `xorm:"-"`
|
||||||
UpdatedUnix int64 `xorm:"INDEX"`
|
UpdatedUnix int64 `xorm:"INDEX updated"`
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AfterSet updates the webhook object upon setting a column
|
// AfterSet updates the webhook object upon setting a column
|
||||||
|
|
|
@ -100,7 +100,8 @@ var (
|
||||||
LongBlob = "LONGBLOB"
|
LongBlob = "LONGBLOB"
|
||||||
Bytea = "BYTEA"
|
Bytea = "BYTEA"
|
||||||
|
|
||||||
Bool = "BOOL"
|
Bool = "BOOL"
|
||||||
|
Boolean = "BOOLEAN"
|
||||||
|
|
||||||
Serial = "SERIAL"
|
Serial = "SERIAL"
|
||||||
BigSerial = "BIGSERIAL"
|
BigSerial = "BIGSERIAL"
|
||||||
|
@ -163,7 +164,7 @@ var (
|
||||||
uintTypes = sort.StringSlice{"*uint", "*uint16", "*uint32", "*uint8"}
|
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 (
|
var (
|
||||||
c_EMPTY_STRING string
|
c_EMPTY_STRING string
|
||||||
c_BOOL_DEFAULT bool
|
c_BOOL_DEFAULT bool
|
||||||
|
|
|
@ -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)
|
* 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)
|
* Postgres: [github.com/lib/pq](https://github.com/lib/pq)
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,12 @@ import (
|
||||||
|
|
||||||
// LRUCacher implments cache object facilities
|
// LRUCacher implments cache object facilities
|
||||||
type LRUCacher struct {
|
type LRUCacher struct {
|
||||||
idList *list.List
|
idList *list.List
|
||||||
sqlList *list.List
|
sqlList *list.List
|
||||||
idIndex map[string]map[string]*list.Element
|
idIndex map[string]map[string]*list.Element
|
||||||
sqlIndex map[string]map[string]*list.Element
|
sqlIndex map[string]map[string]*list.Element
|
||||||
store core.CacheStore
|
store core.CacheStore
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
// maxSize int
|
|
||||||
MaxElementSize int
|
MaxElementSize int
|
||||||
Expired time.Duration
|
Expired time.Duration
|
||||||
GcInterval 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
|
// GC check ids lit and sql list to remove all element expired
|
||||||
func (m *LRUCacher) GC() {
|
func (m *LRUCacher) GC() {
|
||||||
//fmt.Println("begin gc ...")
|
|
||||||
//defer fmt.Println("end gc ...")
|
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
defer m.mutex.Unlock()
|
||||||
var removedNum int
|
var removedNum int
|
||||||
|
@ -64,12 +61,10 @@ func (m *LRUCacher) GC() {
|
||||||
time.Now().Sub(e.Value.(*idNode).lastVisit) > m.Expired {
|
time.Now().Sub(e.Value.(*idNode).lastVisit) > m.Expired {
|
||||||
removedNum++
|
removedNum++
|
||||||
next := e.Next()
|
next := e.Next()
|
||||||
//fmt.Println("removing ...", e.Value)
|
|
||||||
node := e.Value.(*idNode)
|
node := e.Value.(*idNode)
|
||||||
m.delBean(node.tbName, node.id)
|
m.delBean(node.tbName, node.id)
|
||||||
e = next
|
e = next
|
||||||
} else {
|
} else {
|
||||||
//fmt.Printf("removing %d cache nodes ..., left %d\n", removedNum, m.idList.Len())
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,12 +75,10 @@ func (m *LRUCacher) GC() {
|
||||||
time.Now().Sub(e.Value.(*sqlNode).lastVisit) > m.Expired {
|
time.Now().Sub(e.Value.(*sqlNode).lastVisit) > m.Expired {
|
||||||
removedNum++
|
removedNum++
|
||||||
next := e.Next()
|
next := e.Next()
|
||||||
//fmt.Println("removing ...", e.Value)
|
|
||||||
node := e.Value.(*sqlNode)
|
node := e.Value.(*sqlNode)
|
||||||
m.delIds(node.tbName, node.sql)
|
m.delIds(node.tbName, node.sql)
|
||||||
e = next
|
e = next
|
||||||
} else {
|
} else {
|
||||||
//fmt.Printf("removing %d cache nodes ..., left %d\n", removedNum, m.sqlList.Len())
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,7 +109,6 @@ func (m *LRUCacher) GetIds(tableName, sql string) interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
m.delIds(tableName, sql)
|
m.delIds(tableName, sql)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +126,6 @@ func (m *LRUCacher) GetBean(tableName string, id string) interface{} {
|
||||||
// if expired, remove the node and return nil
|
// if expired, remove the node and return nil
|
||||||
if time.Now().Sub(lastTime) > m.Expired {
|
if time.Now().Sub(lastTime) > m.Expired {
|
||||||
m.delBean(tableName, id)
|
m.delBean(tableName, id)
|
||||||
//m.clearIds(tableName)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
m.idList.MoveToBack(el)
|
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
|
// store bean is not exist, then remove memory's index
|
||||||
m.delBean(tableName, id)
|
m.delBean(tableName, id)
|
||||||
//m.clearIds(tableName)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,8 +156,8 @@ func (m *LRUCacher) clearIds(tableName string) {
|
||||||
// ClearIds clears all sql-ids mapping on table tableName from cache
|
// ClearIds clears all sql-ids mapping on table tableName from cache
|
||||||
func (m *LRUCacher) ClearIds(tableName string) {
|
func (m *LRUCacher) ClearIds(tableName string) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
m.clearIds(tableName)
|
m.clearIds(tableName)
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LRUCacher) clearBeans(tableName string) {
|
func (m *LRUCacher) clearBeans(tableName string) {
|
||||||
|
@ -184,14 +174,13 @@ func (m *LRUCacher) clearBeans(tableName string) {
|
||||||
// ClearBeans clears all beans in some table
|
// ClearBeans clears all beans in some table
|
||||||
func (m *LRUCacher) ClearBeans(tableName string) {
|
func (m *LRUCacher) ClearBeans(tableName string) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
m.clearBeans(tableName)
|
m.clearBeans(tableName)
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutIds pus ids into table
|
// PutIds pus ids into table
|
||||||
func (m *LRUCacher) PutIds(tableName, sql string, ids interface{}) {
|
func (m *LRUCacher) PutIds(tableName, sql string, ids interface{}) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
if _, ok := m.sqlIndex[tableName]; !ok {
|
if _, ok := m.sqlIndex[tableName]; !ok {
|
||||||
m.sqlIndex[tableName] = make(map[string]*list.Element)
|
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)
|
node := e.Value.(*sqlNode)
|
||||||
m.delIds(node.tbName, node.sql)
|
m.delIds(node.tbName, node.sql)
|
||||||
}
|
}
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutBean puts beans into table
|
// PutBean puts beans into table
|
||||||
func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) {
|
func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
var el *list.Element
|
var el *list.Element
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
|
@ -229,6 +218,7 @@ func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) {
|
||||||
node := e.Value.(*idNode)
|
node := e.Value.(*idNode)
|
||||||
m.delBean(node.tbName, node.id)
|
m.delBean(node.tbName, node.id)
|
||||||
}
|
}
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LRUCacher) delIds(tableName, sql string) {
|
func (m *LRUCacher) delIds(tableName, sql string) {
|
||||||
|
@ -244,8 +234,8 @@ func (m *LRUCacher) delIds(tableName, sql string) {
|
||||||
// DelIds deletes ids
|
// DelIds deletes ids
|
||||||
func (m *LRUCacher) DelIds(tableName, sql string) {
|
func (m *LRUCacher) DelIds(tableName, sql string) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
m.delIds(tableName, sql)
|
m.delIds(tableName, sql)
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LRUCacher) delBean(tableName string, id string) {
|
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
|
// DelBean deletes beans in some table
|
||||||
func (m *LRUCacher) DelBean(tableName string, id string) {
|
func (m *LRUCacher) DelBean(tableName string, id string) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
m.delBean(tableName, id)
|
m.delBean(tableName, id)
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
type idNode struct {
|
type idNode struct {
|
||||||
|
|
|
@ -21,7 +21,16 @@ database:
|
||||||
test:
|
test:
|
||||||
override:
|
override:
|
||||||
# './...' is a relative pattern which means all subdirectories
|
# './...' 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 && ./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 && ./mysql.sh
|
||||||
- cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./postgres.sh
|
- cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./postgres.sh
|
||||||
|
|
|
@ -334,3 +334,15 @@ func convertInt(v interface{}) (int64, error) {
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unsupported type: %v", v)
|
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))
|
||||||
|
}
|
||||||
|
|
|
@ -781,6 +781,9 @@ func (db *postgres) SqlType(c *core.Column) string {
|
||||||
case core.TinyInt:
|
case core.TinyInt:
|
||||||
res = core.SmallInt
|
res = core.SmallInt
|
||||||
return res
|
return res
|
||||||
|
case core.Bit:
|
||||||
|
res = core.Boolean
|
||||||
|
return res
|
||||||
case core.MediumInt, core.Int, core.Integer:
|
case core.MediumInt, core.Int, core.Integer:
|
||||||
if c.IsAutoIncrement {
|
if c.IsAutoIncrement {
|
||||||
return core.Serial
|
return core.Serial
|
||||||
|
|
|
@ -90,7 +90,7 @@ another is Rows
|
||||||
|
|
||||||
5. Update one or more records
|
5. Update one or more records
|
||||||
|
|
||||||
affected, err := engine.Id(...).Update(&user)
|
affected, err := engine.ID(...).Update(&user)
|
||||||
// UPDATE user SET ...
|
// UPDATE user SET ...
|
||||||
|
|
||||||
6. Delete one or more records, Delete MUST has condition
|
6. Delete one or more records, Delete MUST has condition
|
||||||
|
|
|
@ -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
|
// 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.
|
// 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...)
|
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
|
// Insert one or more records
|
||||||
func (engine *Engine) Insert(beans ...interface{}) (int64, error) {
|
func (engine *Engine) Insert(beans ...interface{}) (int64, error) {
|
||||||
session := engine.NewSession()
|
session := engine.NewSession()
|
||||||
|
|
|
@ -17,7 +17,6 @@ type Rows struct {
|
||||||
NoTypeCheck bool
|
NoTypeCheck bool
|
||||||
|
|
||||||
session *Session
|
session *Session
|
||||||
stmt *core.Stmt
|
|
||||||
rows *core.Rows
|
rows *core.Rows
|
||||||
fields []string
|
fields []string
|
||||||
beanType reflect.Type
|
beanType reflect.Type
|
||||||
|
@ -29,8 +28,6 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
|
||||||
rows.session = session
|
rows.session = session
|
||||||
rows.beanType = reflect.Indirect(reflect.ValueOf(bean)).Type()
|
rows.beanType = reflect.Indirect(reflect.ValueOf(bean)).Type()
|
||||||
|
|
||||||
defer rows.session.resetStatement()
|
|
||||||
|
|
||||||
var sqlStr string
|
var sqlStr string
|
||||||
var args []interface{}
|
var args []interface{}
|
||||||
var err error
|
var err error
|
||||||
|
@ -53,32 +50,11 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
|
||||||
args = rows.session.statement.RawParams
|
args = rows.session.statement.RawParams
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, filter := range rows.session.engine.dialect.Filters() {
|
rows.rows, err = rows.session.queryRows(sqlStr, args...)
|
||||||
sqlStr = filter.Do(sqlStr, session.engine.dialect, rows.session.statement.RefTable)
|
if err != nil {
|
||||||
}
|
rows.lastError = err
|
||||||
|
rows.Close()
|
||||||
rows.session.saveLastSQL(sqlStr, args...)
|
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
|
|
||||||
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()
|
rows.fields, err = rows.rows.Columns()
|
||||||
|
@ -142,17 +118,10 @@ func (rows *Rows) Close() error {
|
||||||
if rows.rows != nil {
|
if rows.rows != nil {
|
||||||
rows.lastError = rows.rows.Close()
|
rows.lastError = rows.rows.Close()
|
||||||
if rows.lastError != nil {
|
if rows.lastError != nil {
|
||||||
defer rows.stmt.Close()
|
|
||||||
return rows.lastError
|
return rows.lastError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if rows.stmt != nil {
|
|
||||||
rows.lastError = rows.stmt.Close()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if rows.stmt != nil {
|
|
||||||
defer rows.stmt.Close()
|
|
||||||
}
|
|
||||||
if rows.rows != nil {
|
if rows.rows != nil {
|
||||||
defer rows.rows.Close()
|
defer rows.rows.Close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -303,6 +303,7 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount
|
||||||
var newValue = newElemFunc(fields)
|
var newValue = newElemFunc(fields)
|
||||||
bean := newValue.Interface()
|
bean := newValue.Interface()
|
||||||
dataStruct := rValue(bean)
|
dataStruct := rValue(bean)
|
||||||
|
|
||||||
// handle beforeClosures
|
// handle beforeClosures
|
||||||
scanResults, err := session.row2Slice(rows, fields, fieldsCount, bean)
|
scanResults, err := session.row2Slice(rows, fields, fieldsCount, bean)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -312,7 +313,6 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = sliceValueSetFunc(&newValue, pk)
|
err = sliceValueSetFunc(&newValue, pk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
|
||||||
// property to be fetched lazily
|
// property to be fetched lazily
|
||||||
structInter := reflect.New(fieldValue.Type())
|
structInter := reflect.New(fieldValue.Type())
|
||||||
newsession := session.engine.NewSession()
|
has, err := session.ID(pk).NoCascade().get(structInter.Interface())
|
||||||
defer newsession.Close()
|
|
||||||
has, err := newsession.ID(pk).NoCascade().Get(structInter.Interface())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -777,14 +775,6 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, f
|
||||||
return pk, nil
|
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
|
// saveLastSQL stores executed query information
|
||||||
func (session *Session) saveLastSQL(sql string, args ...interface{}) {
|
func (session *Session) saveLastSQL(sql string, args ...interface{}) {
|
||||||
session.lastSQL = sql
|
session.lastSQL = sql
|
||||||
|
|
|
@ -144,8 +144,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
fieldValue.SetString(string(data))
|
fieldValue.SetString(string(data))
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
d := string(data)
|
v, err := asBool(data)
|
||||||
v, err := strconv.ParseBool(d)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("arg %v as bool: %s", key, err.Error())
|
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
|
// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
|
||||||
// property to be fetched lazily
|
// property to be fetched lazily
|
||||||
structInter := reflect.New(fieldValue.Type())
|
structInter := reflect.New(fieldValue.Type())
|
||||||
newsession := session.engine.NewSession()
|
has, err := session.ID(pk).NoCascade().get(structInter.Interface())
|
||||||
defer newsession.Close()
|
|
||||||
has, err := newsession.Id(pk).NoCascade().Get(structInter.Interface())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
// !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
|
// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
|
||||||
// property to be fetched lazily
|
// property to be fetched lazily
|
||||||
newsession := session.engine.NewSession()
|
has, err := session.ID(pk).NoCascade().get(structInter.Interface())
|
||||||
defer newsession.Close()
|
|
||||||
has, err := newsession.Id(pk).NoCascade().Get(structInter.Interface())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,14 @@ import (
|
||||||
"github.com/go-xorm/core"
|
"github.com/go-xorm/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
|
func (session *Session) cacheDelete(table *core.Table, tableName, sqlStr string, args ...interface{}) error {
|
||||||
if session.statement.RefTable == nil ||
|
if table == nil ||
|
||||||
session.tx != nil {
|
session.tx != nil {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, filter := range session.engine.dialect.Filters() {
|
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)
|
newsql := session.statement.convertIDSQL(sqlStr)
|
||||||
|
@ -27,11 +27,11 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
cacher := session.engine.getCacher2(session.statement.RefTable)
|
cacher := session.engine.getCacher2(table)
|
||||||
tableName := session.statement.TableName()
|
pkColumns := table.PKColumns()
|
||||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resultsSlice, err := session.query(newsql, args...)
|
resultsSlice, err := session.queryBytes(newsql, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
|
||||||
for _, data := range resultsSlice {
|
for _, data := range resultsSlice {
|
||||||
var id int64
|
var id int64
|
||||||
var pk core.PK = make([]interface{}, 0)
|
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 {
|
if v, ok := data[col.Name]; !ok {
|
||||||
return errors.New("no id")
|
return errors.New("no id")
|
||||||
} else if col.SQLType.IsText() {
|
} else if col.SQLType.IsText() {
|
||||||
|
@ -58,27 +58,23 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
|
||||||
ids = append(ids, pk)
|
ids = append(ids, pk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /*else {
|
}
|
||||||
session.engine.LogDebug("delete cache sql %v", newsql)
|
|
||||||
cacher.DelIds(tableName, genSqlKey(newsql, args))
|
|
||||||
}*/
|
|
||||||
|
|
||||||
for _, id := range ids {
|
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()
|
sid, err := id.ToString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cacher.DelBean(tableName, sid)
|
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)
|
cacher.ClearIds(tableName)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete records, bean's non-empty fields are conditions
|
// Delete records, bean's non-empty fields are conditions
|
||||||
func (session *Session) Delete(bean interface{}) (int64, error) {
|
func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||||
defer session.resetStatement()
|
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
|
@ -86,7 +82,6 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||||
if err := session.statement.setRefValue(rValue(bean)); err != nil {
|
if err := session.statement.setRefValue(rValue(bean)); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
var table = session.statement.RefTable
|
|
||||||
|
|
||||||
// handle before delete processors
|
// handle before delete processors
|
||||||
for _, closure := range session.beforeClosures {
|
for _, closure := range session.beforeClosures {
|
||||||
|
@ -106,7 +101,9 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||||
return 0, ErrNeedDeletedCond
|
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
|
var deleteSQL string
|
||||||
if len(condSQL) > 0 {
|
if len(condSQL) > 0 {
|
||||||
deleteSQL = fmt.Sprintf("DELETE FROM %v WHERE %v", tableName, condSQL)
|
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 {
|
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||||
session.cacheDelete(deleteSQL, argsForCache...)
|
session.cacheDelete(table, tableNameNoQuote, deleteSQL, argsForCache...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.statement.RefTable = table
|
||||||
res, err := session.exec(realSQL, condArgs...)
|
res, err := session.exec(realSQL, condArgs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
|
@ -10,12 +10,10 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/go-xorm/builder"
|
"github.com/go-xorm/builder"
|
||||||
"github.com/go-xorm/core"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Exist returns true if the record exist otherwise return false
|
// Exist returns true if the record exist otherwise return false
|
||||||
func (session *Session) Exist(bean ...interface{}) (bool, error) {
|
func (session *Session) Exist(bean ...interface{}) (bool, error) {
|
||||||
defer session.resetStatement()
|
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
|
@ -69,19 +67,11 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) {
|
||||||
args = session.statement.RawParams
|
args = session.statement.RawParams
|
||||||
}
|
}
|
||||||
|
|
||||||
session.queryPreprocess(&sqlStr, args...)
|
rows, err := session.queryRows(sqlStr, args...)
|
||||||
|
|
||||||
var rawRows *core.Rows
|
|
||||||
if session.isAutoCommit {
|
|
||||||
_, rawRows, err = session.innerQuery(sqlStr, args...)
|
|
||||||
} else {
|
|
||||||
rawRows, err = session.tx.Query(sqlStr, args...)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
defer rawRows.Close()
|
return rows.Next(), nil
|
||||||
|
|
||||||
return rawRows.Next(), nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,13 @@ const (
|
||||||
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
||||||
// map[int64]*Struct
|
// map[int64]*Struct
|
||||||
func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) error {
|
func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) error {
|
||||||
defer session.resetStatement()
|
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
|
return session.find(rowsSlicePtr, condiBean...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error {
|
||||||
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
|
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
|
||||||
if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map {
|
if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map {
|
||||||
return errors.New("needs a pointer to a slice or a 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 {
|
func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Value, sqlStr string, args ...interface{}) error {
|
||||||
var rawRows *core.Rows
|
rows, err := session.queryRows(sqlStr, args...)
|
||||||
var err error
|
|
||||||
|
|
||||||
session.queryPreprocess(&sqlStr, args...)
|
|
||||||
if session.isAutoCommit {
|
|
||||||
_, rawRows, err = session.innerQuery(sqlStr, args...)
|
|
||||||
} else {
|
|
||||||
rawRows, err = session.tx.Query(sqlStr, args...)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer rawRows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
fields, err := rawRows.Columns()
|
fields, err := rows.Columns()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -245,20 +239,20 @@ func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Va
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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)
|
var newValue = newElemFunc(fields)
|
||||||
bean := newValue.Interface()
|
bean := newValue.Interface()
|
||||||
|
|
||||||
switch elemType.Kind() {
|
switch elemType.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
err = rawRows.ScanSlice(bean)
|
err = rows.ScanSlice(bean)
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
err = rawRows.ScanMap(bean)
|
err = rows.ScanMap(bean)
|
||||||
default:
|
default:
|
||||||
err = rawRows.Scan(bean)
|
err = rows.Scan(bean)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -299,12 +293,11 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
}
|
}
|
||||||
|
|
||||||
tableName := session.statement.TableName()
|
tableName := session.statement.TableName()
|
||||||
|
|
||||||
table := session.statement.RefTable
|
table := session.statement.RefTable
|
||||||
cacher := session.engine.getCacher2(table)
|
cacher := session.engine.getCacher2(table)
|
||||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rows, err := session.DB().Query(newsql, args...)
|
rows, err := session.queryRows(newsql, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -334,13 +327,13 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
ids = append(ids, pk)
|
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)
|
err = core.PutCacheSql(cacher, ids, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} 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))
|
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
|
||||||
|
@ -355,7 +348,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
bean := cacher.GetBean(tableName, sid)
|
bean := cacher.GetBean(tableName, sid)
|
||||||
if bean == nil {
|
if bean == nil || reflect.ValueOf(bean).Elem().Type() != t {
|
||||||
ides = append(ides, id)
|
ides = append(ides, id)
|
||||||
ididxes[sid] = idx
|
ididxes[sid] = idx
|
||||||
} else {
|
} else {
|
||||||
|
@ -376,9 +369,6 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ides) > 0 {
|
if len(ides) > 0 {
|
||||||
newSession := session.engine.NewSession()
|
|
||||||
defer newSession.Close()
|
|
||||||
|
|
||||||
slices := reflect.New(reflect.SliceOf(t))
|
slices := reflect.New(reflect.SliceOf(t))
|
||||||
beans := slices.Interface()
|
beans := slices.Interface()
|
||||||
|
|
||||||
|
@ -388,18 +378,18 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
ff = append(ff, ie[0])
|
ff = append(ff, ie[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
newSession.In("`"+table.PrimaryKeys[0]+"`", ff...)
|
session.In("`"+table.PrimaryKeys[0]+"`", ff...)
|
||||||
} else {
|
} else {
|
||||||
for _, ie := range ides {
|
for _, ie := range ides {
|
||||||
cond := builder.NewCond()
|
cond := builder.NewCond()
|
||||||
for i, name := range table.PrimaryKeys {
|
for i, name := range table.PrimaryKeys {
|
||||||
cond = cond.And(builder.Eq{"`" + name + "`": ie[i]})
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,13 @@ import (
|
||||||
// Get retrieve one record from database, bean's non-empty fields
|
// Get retrieve one record from database, bean's non-empty fields
|
||||||
// will be as conditions
|
// will be as conditions
|
||||||
func (session *Session) Get(bean interface{}) (bool, error) {
|
func (session *Session) Get(bean interface{}) (bool, error) {
|
||||||
defer session.resetStatement()
|
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
|
return session.get(bean)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (session *Session) get(bean interface{}) (bool, error) {
|
||||||
beanValue := reflect.ValueOf(bean)
|
beanValue := reflect.ValueOf(bean)
|
||||||
if beanValue.Kind() != reflect.Ptr {
|
if beanValue.Kind() != reflect.Ptr {
|
||||||
return false, errors.New("needs a pointer to a value")
|
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
|
args = session.statement.RawParams
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table := session.statement.RefTable
|
||||||
|
|
||||||
if session.canCache() && beanValue.Elem().Kind() == reflect.Struct {
|
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 {
|
!session.statement.unscoped {
|
||||||
has, err := session.cacheGet(bean, sqlStr, args...)
|
has, err := session.cacheGet(bean, sqlStr, args...)
|
||||||
if err != ErrCacheFailed {
|
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) {
|
func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bean interface{}, sqlStr string, args ...interface{}) (bool, error) {
|
||||||
session.queryPreprocess(&sqlStr, args...)
|
rows, err := session.queryRows(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...)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
defer rawRows.Close()
|
if !rows.Next() {
|
||||||
|
|
||||||
if !rawRows.Next() {
|
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch beanKind {
|
switch beanKind {
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
fields, err := rawRows.Columns()
|
fields, err := rows.Columns()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// WARN: Alougth rawRows return true, but get fields failed
|
// WARN: Alougth rows return true, but get fields failed
|
||||||
return true, err
|
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 {
|
if err != nil {
|
||||||
return false, err
|
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:
|
case reflect.Slice:
|
||||||
err = rawRows.ScanSlice(bean)
|
err = rows.ScanSlice(bean)
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
err = rawRows.ScanMap(bean)
|
err = rows.ScanMap(bean)
|
||||||
default:
|
default:
|
||||||
err = rawRows.Scan(bean)
|
err = rows.Scan(bean)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, err
|
return true, err
|
||||||
|
@ -131,11 +124,11 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
|
||||||
cacher := session.engine.getCacher2(session.statement.RefTable)
|
cacher := session.engine.getCacher2(session.statement.RefTable)
|
||||||
tableName := session.statement.TableName()
|
tableName := session.statement.TableName()
|
||||||
session.engine.logger.Debug("[cacheGet] find sql:", newsql, args)
|
session.engine.logger.Debug("[cacheGet] find sql:", newsql, args)
|
||||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
|
||||||
table := session.statement.RefTable
|
table := session.statement.RefTable
|
||||||
|
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var res = make([]string, len(table.PrimaryKeys))
|
var res = make([]string, len(table.PrimaryKeys))
|
||||||
rows, err := session.DB().Query(newsql, args...)
|
rows, err := session.NoCache().queryRows(newsql, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -172,7 +165,7 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
session.engine.logger.Debug("[cacheGet] cache hit sql:", newsql)
|
session.engine.logger.Debug("[cacheGet] cache hit sql:", newsql, ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ids) > 0 {
|
if len(ids) > 0 {
|
||||||
|
@ -186,7 +179,7 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
|
||||||
cacheBean := cacher.GetBean(tableName, sid)
|
cacheBean := cacher.GetBean(tableName, sid)
|
||||||
if cacheBean == nil {
|
if cacheBean == nil {
|
||||||
cacheBean = bean
|
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 {
|
if err != nil || !has {
|
||||||
return has, err
|
return has, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ func (session *Session) Insert(beans ...interface{}) (int64, error) {
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
defer session.resetStatement()
|
|
||||||
|
|
||||||
for _, bean := range beans {
|
for _, bean := range beans {
|
||||||
sliceValue := reflect.Indirect(reflect.ValueOf(bean))
|
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 sql = "INSERT INTO %s (%v%v%v) VALUES (%v)"
|
||||||
var statement string
|
var statement string
|
||||||
|
var tableName = session.statement.TableName()
|
||||||
if session.engine.dialect.DBType() == core.ORACLE {
|
if session.engine.dialect.DBType() == core.ORACLE {
|
||||||
sql = "INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL"
|
sql = "INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL"
|
||||||
temp := fmt.Sprintf(") INTO %s (%v%v%v) VALUES (",
|
temp := fmt.Sprintf(") INTO %s (%v%v%v) VALUES (",
|
||||||
session.engine.Quote(session.statement.TableName()),
|
session.engine.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||||
session.engine.QuoteStr())
|
session.engine.QuoteStr())
|
||||||
statement = fmt.Sprintf(sql,
|
statement = fmt.Sprintf(sql,
|
||||||
session.engine.Quote(session.statement.TableName()),
|
session.engine.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
strings.Join(colMultiPlaces, temp))
|
strings.Join(colMultiPlaces, temp))
|
||||||
} else {
|
} else {
|
||||||
statement = fmt.Sprintf(sql,
|
statement = fmt.Sprintf(sql,
|
||||||
session.engine.Quote(session.statement.TableName()),
|
session.engine.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
strings.Join(colNames, session.engine.QuoteStr()+", "+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 {
|
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||||
session.cacheInsert(session.statement.TableName())
|
session.cacheInsert(table, tableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
lenAfterClosures := len(session.afterClosures)
|
lenAfterClosures := len(session.afterClosures)
|
||||||
|
@ -280,7 +280,6 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||||
|
|
||||||
// InsertMulti insert multiple records
|
// InsertMulti insert multiple records
|
||||||
func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) {
|
func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) {
|
||||||
defer session.resetStatement()
|
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
|
@ -349,18 +348,19 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var sqlStr string
|
var sqlStr string
|
||||||
|
var tableName = session.statement.TableName()
|
||||||
if len(colPlaces) > 0 {
|
if len(colPlaces) > 0 {
|
||||||
sqlStr = fmt.Sprintf("INSERT INTO %s (%v%v%v) VALUES (%v)",
|
sqlStr = fmt.Sprintf("INSERT INTO %s (%v%v%v) VALUES (%v)",
|
||||||
session.engine.Quote(session.statement.TableName()),
|
session.engine.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
strings.Join(colNames, session.engine.Quote(", ")),
|
strings.Join(colNames, session.engine.Quote(", ")),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
colPlaces)
|
colPlaces)
|
||||||
} else {
|
} else {
|
||||||
if session.engine.dialect.DBType() == core.MYSQL {
|
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 {
|
} 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
|
// for postgres, many of them didn't implement lastInsertId, so we should
|
||||||
// implemented it ourself.
|
// implemented it ourself.
|
||||||
if session.engine.dialect.DBType() == core.ORACLE && len(table.AutoIncrement) > 0 {
|
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 {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -403,7 +403,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
handleAfterInsertProcessorFunc(bean)
|
handleAfterInsertProcessorFunc(bean)
|
||||||
|
|
||||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
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 {
|
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 {
|
} else if session.engine.dialect.DBType() == core.POSTGRES && len(table.AutoIncrement) > 0 {
|
||||||
//assert table.AutoIncrement != ""
|
//assert table.AutoIncrement != ""
|
||||||
sqlStr = sqlStr + " RETURNING " + session.engine.Quote(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 {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -448,7 +448,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
handleAfterInsertProcessorFunc(bean)
|
handleAfterInsertProcessorFunc(bean)
|
||||||
|
|
||||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
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 {
|
if table.Version != "" && session.statement.checkVersion {
|
||||||
|
@ -491,7 +491,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
defer handleAfterInsertProcessorFunc(bean)
|
defer handleAfterInsertProcessorFunc(bean)
|
||||||
|
|
||||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
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 {
|
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
|
// The in parameter bean must a struct or a point to struct. The return
|
||||||
// parameter is inserted and error
|
// parameter is inserted and error
|
||||||
func (session *Session) InsertOne(bean interface{}) (int64, error) {
|
func (session *Session) InsertOne(bean interface{}) (int64, error) {
|
||||||
defer session.resetStatement()
|
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
|
@ -540,14 +539,12 @@ func (session *Session) InsertOne(bean interface{}) (int64, error) {
|
||||||
return session.innerInsert(bean)
|
return session.innerInsert(bean)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) cacheInsert(tables ...string) error {
|
func (session *Session) cacheInsert(table *core.Table, tables ...string) error {
|
||||||
if session.statement.RefTable == nil {
|
if table == nil {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
table := session.statement.RefTable
|
|
||||||
cacher := session.engine.getCacher2(table)
|
cacher := session.engine.getCacher2(table)
|
||||||
|
|
||||||
for _, t := range tables {
|
for _, t := range tables {
|
||||||
session.engine.logger.Debug("[cache] clear sql:", t)
|
session.engine.logger.Debug("[cache] clear sql:", t)
|
||||||
cacher.ClearIds(t)
|
cacher.ClearIds(t)
|
||||||
|
|
|
@ -19,6 +19,10 @@ func (session *Session) Rows(bean interface{}) (*Rows, error) {
|
||||||
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
||||||
// map[int64]*Struct
|
// map[int64]*Struct
|
||||||
func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
|
func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
|
||||||
|
if session.isAutoClose {
|
||||||
|
defer session.Close()
|
||||||
|
}
|
||||||
|
|
||||||
rows, err := session.Rows(bean)
|
rows, err := session.Rows(bean)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -6,61 +6,113 @@ package xorm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-xorm/core"
|
"github.com/go-xorm/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (session *Session) query(sqlStr string, paramStr ...interface{}) ([]map[string][]byte, error) {
|
func (session *Session) queryPreprocess(sqlStr *string, paramStr ...interface{}) {
|
||||||
session.queryPreprocess(&sqlStr, paramStr...)
|
for _, filter := range session.engine.dialect.Filters() {
|
||||||
|
*sqlStr = filter.Do(*sqlStr, session.engine.dialect, session.statement.RefTable)
|
||||||
if session.isAutoCommit {
|
|
||||||
return session.innerQuery2(sqlStr, paramStr...)
|
|
||||||
}
|
}
|
||||||
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) {
|
func (session *Session) queryRows(sqlStr string, args ...interface{}) (*core.Rows, error) {
|
||||||
rows, err := tx.Query(sqlStr, params...)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
return rows, nil
|
||||||
|
|
||||||
return rows2maps(rows)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) innerQuery(sqlStr string, params ...interface{}) (*core.Stmt, *core.Rows, error) {
|
func (session *Session) queryRow(sqlStr string, args ...interface{}) *core.Row {
|
||||||
var callback func() (*core.Stmt, *core.Rows, error)
|
return core.NewRow(session.queryRows(sqlStr, args...))
|
||||||
if session.prepareStmt {
|
}
|
||||||
callback = func() (*core.Stmt, *core.Rows, error) {
|
|
||||||
stmt, err := session.doPrepare(sqlStr)
|
func value2Bytes(rawValue *reflect.Value) ([]byte, error) {
|
||||||
if err != nil {
|
str, err := value2String(rawValue)
|
||||||
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)
|
|
||||||
if err != nil {
|
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) {
|
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
|
return resultsSlice, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func value2Bytes(rawValue *reflect.Value) (data []byte, err error) {
|
func (session *Session) queryBytes(sqlStr string, args ...interface{}) ([]map[string][]byte, error) {
|
||||||
var str string
|
rows, err := session.queryRows(sqlStr, args...)
|
||||||
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()
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
return rows2maps(rows)
|
return rows2maps(rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query runs a raw sql and return records as []map[string][]byte
|
func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, error) {
|
||||||
func (session *Session) Query(sqlStr string, paramStr ...interface{}) ([]map[string][]byte, error) {
|
|
||||||
defer session.resetStatement()
|
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...)
|
session.queryPreprocess(&sqlStr, args...)
|
||||||
|
|
||||||
if session.isAutoCommit {
|
if session.engine.showSQL {
|
||||||
return query2(session.DB(), sqlStr, args...)
|
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 {
|
if session.prepareStmt {
|
||||||
stmt, err := session.doPrepare(sqlStr)
|
stmt, err := session.doPrepare(sqlStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -286,32 +186,8 @@ func (session *Session) innerExec(sqlStr string, args ...interface{}) (sql.Resul
|
||||||
return session.DB().Exec(sqlStr, args...)
|
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
|
// Exec raw sql
|
||||||
func (session *Session) Exec(sqlStr string, args ...interface{}) (sql.Result, error) {
|
func (session *Session) Exec(sqlStr string, args ...interface{}) (sql.Result, error) {
|
||||||
defer session.resetStatement()
|
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import (
|
||||||
|
|
||||||
// Ping test if database is ok
|
// Ping test if database is ok
|
||||||
func (session *Session) Ping() error {
|
func (session *Session) Ping() error {
|
||||||
defer session.resetStatement()
|
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
|
@ -35,7 +34,6 @@ func (session *Session) CreateTable(bean interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) createTable(bean interface{}) error {
|
func (session *Session) createTable(bean interface{}) error {
|
||||||
defer session.resetStatement()
|
|
||||||
v := rValue(bean)
|
v := rValue(bean)
|
||||||
if err := session.statement.setRefValue(v); err != nil {
|
if err := session.statement.setRefValue(v); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -56,7 +54,6 @@ func (session *Session) CreateIndexes(bean interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) createIndexes(bean interface{}) error {
|
func (session *Session) createIndexes(bean interface{}) error {
|
||||||
defer session.resetStatement()
|
|
||||||
v := rValue(bean)
|
v := rValue(bean)
|
||||||
if err := session.statement.setRefValue(v); err != nil {
|
if err := session.statement.setRefValue(v); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -81,7 +78,6 @@ func (session *Session) CreateUniques(bean interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) createUniques(bean interface{}) error {
|
func (session *Session) createUniques(bean interface{}) error {
|
||||||
defer session.resetStatement()
|
|
||||||
v := rValue(bean)
|
v := rValue(bean)
|
||||||
if err := session.statement.setRefValue(v); err != nil {
|
if err := session.statement.setRefValue(v); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -107,7 +103,6 @@ func (session *Session) DropIndexes(bean interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) dropIndexes(bean interface{}) error {
|
func (session *Session) dropIndexes(bean interface{}) error {
|
||||||
defer session.resetStatement()
|
|
||||||
v := rValue(bean)
|
v := rValue(bean)
|
||||||
if err := session.statement.setRefValue(v); err != nil {
|
if err := session.statement.setRefValue(v); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -133,7 +128,6 @@ func (session *Session) DropTable(beanOrTableName interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) dropTable(beanOrTableName interface{}) error {
|
func (session *Session) dropTable(beanOrTableName interface{}) error {
|
||||||
defer session.resetStatement()
|
|
||||||
tableName, err := session.engine.tableName(beanOrTableName)
|
tableName, err := session.engine.tableName(beanOrTableName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -142,7 +136,7 @@ func (session *Session) dropTable(beanOrTableName interface{}) error {
|
||||||
var needDrop = true
|
var needDrop = true
|
||||||
if !session.engine.dialect.SupportDropIfExists() {
|
if !session.engine.dialect.SupportDropIfExists() {
|
||||||
sqlStr, args := session.engine.dialect.TableCheckSql(tableName)
|
sqlStr, args := session.engine.dialect.TableCheckSql(tableName)
|
||||||
results, err := session.query(sqlStr, args...)
|
results, err := session.queryBytes(sqlStr, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -172,9 +166,8 @@ func (session *Session) IsTableExist(beanOrTableName interface{}) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) isTableExist(tableName string) (bool, error) {
|
func (session *Session) isTableExist(tableName string) (bool, error) {
|
||||||
defer session.resetStatement()
|
|
||||||
sqlStr, args := session.engine.dialect.TableCheckSql(tableName)
|
sqlStr, args := session.engine.dialect.TableCheckSql(tableName)
|
||||||
results, err := session.query(sqlStr, args...)
|
results, err := session.queryBytes(sqlStr, args...)
|
||||||
return len(results) > 0, err
|
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) {
|
func (session *Session) isTableEmpty(tableName string) (bool, error) {
|
||||||
defer session.resetStatement()
|
|
||||||
|
|
||||||
var total int64
|
var total int64
|
||||||
sqlStr := fmt.Sprintf("select count(*) from %s", session.engine.Quote(tableName))
|
sqlStr := fmt.Sprintf("select count(*) from %s", session.engine.Quote(tableName))
|
||||||
err := session.DB().QueryRow(sqlStr).Scan(&total)
|
err := session.queryRow(sqlStr).Scan(&total)
|
||||||
session.saveLastSQL(sqlStr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
err = nil
|
err = nil
|
||||||
|
@ -214,8 +204,6 @@ func (session *Session) isTableEmpty(tableName string) (bool, error) {
|
||||||
|
|
||||||
// find if index is exist according cols
|
// find if index is exist according cols
|
||||||
func (session *Session) isIndexExist2(tableName string, cols []string, unique bool) (bool, error) {
|
func (session *Session) isIndexExist2(tableName string, cols []string, unique bool) (bool, error) {
|
||||||
defer session.resetStatement()
|
|
||||||
|
|
||||||
indexes, err := session.engine.dialect.GetIndexes(tableName)
|
indexes, err := session.engine.dialect.GetIndexes(tableName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -233,8 +221,6 @@ func (session *Session) isIndexExist2(tableName string, cols []string, unique bo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) addColumn(colName string) error {
|
func (session *Session) addColumn(colName string) error {
|
||||||
defer session.resetStatement()
|
|
||||||
|
|
||||||
col := session.statement.RefTable.GetColumn(colName)
|
col := session.statement.RefTable.GetColumn(colName)
|
||||||
sql, args := session.statement.genAddColumnStr(col)
|
sql, args := session.statement.genAddColumnStr(col)
|
||||||
_, err := session.exec(sql, args...)
|
_, err := session.exec(sql, args...)
|
||||||
|
@ -242,18 +228,13 @@ func (session *Session) addColumn(colName string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) addIndex(tableName, idxName string) error {
|
func (session *Session) addIndex(tableName, idxName string) error {
|
||||||
defer session.resetStatement()
|
|
||||||
|
|
||||||
index := session.statement.RefTable.Indexes[idxName]
|
index := session.statement.RefTable.Indexes[idxName]
|
||||||
sqlStr := session.engine.dialect.CreateIndexSql(tableName, index)
|
sqlStr := session.engine.dialect.CreateIndexSql(tableName, index)
|
||||||
|
|
||||||
_, err := session.exec(sqlStr)
|
_, err := session.exec(sqlStr)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) addUnique(tableName, uqeName string) error {
|
func (session *Session) addUnique(tableName, uqeName string) error {
|
||||||
defer session.resetStatement()
|
|
||||||
|
|
||||||
index := session.statement.RefTable.Indexes[uqeName]
|
index := session.statement.RefTable.Indexes[uqeName]
|
||||||
sqlStr := session.engine.dialect.CreateIndexSql(tableName, index)
|
sqlStr := session.engine.dialect.CreateIndexSql(tableName, index)
|
||||||
_, err := session.exec(sqlStr)
|
_, err := session.exec(sqlStr)
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
// Count counts the records. bean's non-empty fields
|
// Count counts the records. bean's non-empty fields
|
||||||
// are conditions.
|
// are conditions.
|
||||||
func (session *Session) Count(bean ...interface{}) (int64, error) {
|
func (session *Session) Count(bean ...interface{}) (int64, error) {
|
||||||
defer session.resetStatement()
|
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
|
@ -31,15 +30,8 @@ func (session *Session) Count(bean ...interface{}) (int64, error) {
|
||||||
args = session.statement.RawParams
|
args = session.statement.RawParams
|
||||||
}
|
}
|
||||||
|
|
||||||
session.queryPreprocess(&sqlStr, args...)
|
|
||||||
|
|
||||||
var total int64
|
var total int64
|
||||||
if session.isAutoCommit {
|
err = session.queryRow(sqlStr, args...).Scan(&total)
|
||||||
err = session.DB().QueryRow(sqlStr, args...).Scan(&total)
|
|
||||||
} else {
|
|
||||||
err = session.tx.QueryRow(sqlStr, args...).Scan(&total)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err == sql.ErrNoRows || err == nil {
|
if err == sql.ErrNoRows || err == nil {
|
||||||
return total, 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.
|
// sum call sum some column. bean's non-empty fields are conditions.
|
||||||
func (session *Session) sum(res interface{}, bean interface{}, columnNames ...string) error {
|
func (session *Session) sum(res interface{}, bean interface{}, columnNames ...string) error {
|
||||||
defer session.resetStatement()
|
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
|
@ -73,22 +64,11 @@ func (session *Session) sum(res interface{}, bean interface{}, columnNames ...st
|
||||||
args = session.statement.RawParams
|
args = session.statement.RawParams
|
||||||
}
|
}
|
||||||
|
|
||||||
session.queryPreprocess(&sqlStr, args...)
|
|
||||||
|
|
||||||
if isSlice {
|
if isSlice {
|
||||||
if session.isAutoCommit {
|
err = session.queryRow(sqlStr, args...).ScanSlice(res)
|
||||||
err = session.DB().QueryRow(sqlStr, args...).ScanSlice(res)
|
|
||||||
} else {
|
|
||||||
err = session.tx.QueryRow(sqlStr, args...).ScanSlice(res)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if session.isAutoCommit {
|
err = session.queryRow(sqlStr, args...).Scan(res)
|
||||||
err = session.DB().QueryRow(sqlStr, args...).Scan(res)
|
|
||||||
} else {
|
|
||||||
err = session.tx.QueryRow(sqlStr, args...).Scan(res)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == sql.ErrNoRows || err == nil {
|
if err == sql.ErrNoRows || err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@ import (
|
||||||
"github.com/go-xorm/core"
|
"github.com/go-xorm/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error {
|
func (session *Session) cacheUpdate(table *core.Table, tableName, sqlStr string, args ...interface{}) error {
|
||||||
if session.statement.RefTable == nil ||
|
if table == nil ||
|
||||||
session.tx != nil {
|
session.tx != nil {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
for _, filter := range session.engine.dialect.Filters() {
|
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)
|
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, "$")
|
nStart = strings.Count(oldhead, "$")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
table := session.statement.RefTable
|
|
||||||
cacher := session.engine.getCacher2(table)
|
cacher := session.engine.getCacher2(table)
|
||||||
tableName := session.statement.TableName()
|
|
||||||
session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:])
|
session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:])
|
||||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args[nStart:])
|
ids, err := core.GetCacheSql(cacher, tableName, newsql, args[nStart:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rows, err := session.DB().Query(newsql, args[nStart:]...)
|
rows, err := session.NoCache().queryRows(newsql, args[nStart:]...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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.
|
// You should call UseBool if you have bool to use.
|
||||||
// 2.float32 & float64 may be not inexact as conditions
|
// 2.float32 & float64 may be not inexact as conditions
|
||||||
func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int64, error) {
|
func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int64, error) {
|
||||||
defer session.resetStatement()
|
|
||||||
if session.isAutoClose {
|
if session.isAutoClose {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
}
|
}
|
||||||
|
@ -249,8 +247,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
st := session.statement
|
st := &session.statement
|
||||||
defer session.resetStatement()
|
|
||||||
|
|
||||||
var sqlStr string
|
var sqlStr string
|
||||||
var condArgs []interface{}
|
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)
|
condSQL = condSQL + fmt.Sprintf(" ORDER BY %v", st.OrderStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tableName = session.statement.TableName()
|
||||||
// TODO: Oracle support needed
|
// TODO: Oracle support needed
|
||||||
var top string
|
var top string
|
||||||
if st.LimitN > 0 {
|
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 {
|
} else if st.Engine.dialect.DBType() == core.SQLITE {
|
||||||
tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
|
tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
|
||||||
cond = cond.And(builder.Expr(fmt.Sprintf("rowid IN (SELECT rowid FROM %v %v)",
|
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)
|
condSQL, condArgs, err = builder.ToSQL(cond)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -301,7 +299,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
} else if st.Engine.dialect.DBType() == core.POSTGRES {
|
} else if st.Engine.dialect.DBType() == core.POSTGRES {
|
||||||
tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
|
tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
|
||||||
cond = cond.And(builder.Expr(fmt.Sprintf("CTID IN (SELECT CTID FROM %v %v)",
|
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)
|
condSQL, condArgs, err = builder.ToSQL(cond)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -315,7 +313,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
table != nil && len(table.PrimaryKeys) == 1 {
|
table != nil && len(table.PrimaryKeys) == 1 {
|
||||||
cond = builder.Expr(fmt.Sprintf("%s IN (SELECT TOP (%d) %s FROM %v%v)",
|
cond = builder.Expr(fmt.Sprintf("%s IN (SELECT TOP (%d) %s FROM %v%v)",
|
||||||
table.PrimaryKeys[0], st.LimitN, table.PrimaryKeys[0],
|
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)
|
condSQL, condArgs, err = builder.ToSQL(cond)
|
||||||
if err != nil {
|
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",
|
sqlStr = fmt.Sprintf("UPDATE %v%v SET %v %v",
|
||||||
top,
|
top,
|
||||||
session.engine.Quote(session.statement.TableName()),
|
session.engine.Quote(tableName),
|
||||||
strings.Join(colNames, ", "),
|
strings.Join(colNames, ", "),
|
||||||
condSQL)
|
condSQL)
|
||||||
|
|
||||||
|
@ -351,8 +349,9 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
|
|
||||||
if table != nil {
|
if table != nil {
|
||||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||||
cacher.ClearIds(session.statement.TableName())
|
//session.cacheUpdate(table, tableName, sqlStr, args...)
|
||||||
cacher.ClearBeans(session.statement.TableName())
|
cacher.ClearIds(tableName)
|
||||||
|
cacher.ClearBeans(tableName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +361,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
closure(bean)
|
closure(bean)
|
||||||
}
|
}
|
||||||
if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok {
|
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()
|
processor.AfterUpdate()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1205,7 +1205,8 @@ func (statement *Statement) convertIDSQL(sqlStr string) string {
|
||||||
top = fmt.Sprintf("TOP %d ", statement.LimitN)
|
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 ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
go test -db=mssql -conn_str="server=192.168.1.58;user id=sa;password=123456;database=xorm_test" -cache=true
|
|
@ -0,0 +1 @@
|
||||||
|
go test -db=mymysql -conn_str="xorm_test/root/" -cache=true
|
|
@ -0,0 +1 @@
|
||||||
|
go test -db=mysql -conn_str="root:@/xorm_test" -cache=true
|
|
@ -0,0 +1 @@
|
||||||
|
go test -db=postgres -conn_str="dbname=xorm_test sslmode=disable" -cache=true
|
|
@ -0,0 +1 @@
|
||||||
|
go test -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" -cache=true
|
|
@ -17,7 +17,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Version show the xorm's version
|
// Version show the xorm's version
|
||||||
Version string = "0.6.3.0713"
|
Version string = "0.6.4.0910"
|
||||||
)
|
)
|
||||||
|
|
||||||
func regDrvsNDialects() bool {
|
func regDrvsNDialects() bool {
|
||||||
|
|
|
@ -456,10 +456,10 @@
|
||||||
"revisionTime": "2017-05-19T03:21:30Z"
|
"revisionTime": "2017-05-19T03:21:30Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "KOHXTLwpgTMxBB9aGF2aIxkWdm8=",
|
"checksumSHA1": "HMavuxvDhKOwmbbFnYt9hfT6jE0=",
|
||||||
"path": "github.com/go-xorm/core",
|
"path": "github.com/go-xorm/core",
|
||||||
"revision": "71c1070a861118827352b1394eb86cbfeef5c513",
|
"revision": "da1adaf7a28ca792961721a34e6e04945200c890",
|
||||||
"revisionTime": "2017-08-22T05:50:40Z"
|
"revisionTime": "2017-09-09T08:56:53Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "k52lEKLp8j5M+jFpe+3u+bIFpxQ=",
|
"checksumSHA1": "k52lEKLp8j5M+jFpe+3u+bIFpxQ=",
|
||||||
|
@ -468,10 +468,10 @@
|
||||||
"revisionTime": "2016-08-11T02:11:45Z"
|
"revisionTime": "2016-08-11T02:11:45Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "0F65zfDi1ys3KD/wMKtxC2k13DA=",
|
"checksumSHA1": "SoZDnkd5NdwE0g4MY1nTAl8ZtPo=",
|
||||||
"path": "github.com/go-xorm/xorm",
|
"path": "github.com/go-xorm/xorm",
|
||||||
"revision": "a10b5aba4bb97b30daa74e7c0363d3084ede0514",
|
"revision": "c29485f954ed6495861c0098f9a1642a467299c8",
|
||||||
"revisionTime": "2017-08-20T09:05:42Z"
|
"revisionTime": "2017-09-10T12:58:18Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "1ft/4j5MFa7C9dPI9whL03HSUzk=",
|
"checksumSHA1": "1ft/4j5MFa7C9dPI9whL03HSUzk=",
|
||||||
|
|
Loading…
Reference in New Issue