bug fixed and performance improved for table name

This commit is contained in:
Lunny Xiao 2016-07-09 08:15:53 +08:00
parent 86701ad07e
commit 5612916fea
6 changed files with 159 additions and 190 deletions

View File

@ -1 +1 @@
xorm v0.5.5.0707
xorm v0.5.5.0709

126
engine.go
View File

@ -286,46 +286,6 @@ func (engine *Engine) logSQLExecutionTime(sqlStr string, args []interface{}, exe
}
}
// LogError logging error
/*func (engine *Engine) LogError(contents ...interface{}) {
engine.logger.Err(contents...)
}
// LogErrorf logging errorf
func (engine *Engine) LogErrorf(format string, contents ...interface{}) {
engine.logger.Errf(format, contents...)
}
// LogInfo logging info
func (engine *Engine) LogInfo(contents ...interface{}) {
engine.logger.Info(contents...)
}
// LogInfof logging infof
func (engine *Engine) LogInfof(format string, contents ...interface{}) {
engine.logger.Infof(format, contents...)
}
// LogDebug logging debug
func (engine *Engine) LogDebug(contents ...interface{}) {
engine.logger.Debug(contents...)
}
// LogDebugf logging debugf
func (engine *Engine) LogDebugf(format string, contents ...interface{}) {
engine.logger.Debugf(format, contents...)
}
// LogWarn logging warn
func (engine *Engine) LogWarn(contents ...interface{}) {
engine.logger.Warning(contents...)
}
// LogWarnf logging warnf
func (engine *Engine) LogWarnf(format string, contents ...interface{}) {
engine.logger.Warningf(format, contents...)
}*/
// Sql method let's you manualy write raw sql and operate
// For example:
//
@ -421,8 +381,26 @@ func (engine *Engine) DumpTables(tables []*core.Table, w io.Writer, tp ...core.D
return engine.dumpTables(tables, w, tp...)
}
func (engine *Engine) tbName(tb *core.Table) string {
return tb.Name
func (engine *Engine) tableName(beanOrTableName interface{}) (string, error) {
v := rValue(beanOrTableName)
if v.Type().Kind() == reflect.String {
return beanOrTableName.(string), nil
} else if v.Type().Kind() == reflect.Struct {
return engine.tbName(v), nil
}
return "", errors.New("bean should be a struct or struct's point")
}
func (engine *Engine) tbName(v reflect.Value) string {
if tb, ok := v.Interface().(TableName); ok {
return tb.TableName()
}
if v.CanAddr() {
if tb, ok := v.Addr().Interface().(TableName); ok {
return tb.TableName()
}
}
return engine.TableMapper.Obj2Table(v.Type().Name())
}
// DumpAll dump database all table structs and data to w with specify db type
@ -461,16 +439,17 @@ func (engine *Engine) dumpAll(w io.Writer, tp ...core.DbType) error {
return err
}
for _, index := range table.Indexes {
_, err = io.WriteString(w, dialect.CreateIndexSql(engine.tbName(table), index)+";\n")
_, err = io.WriteString(w, dialect.CreateIndexSql(table.Name, index)+";\n")
if err != nil {
return err
}
}
rows, err := engine.DB().Query("SELECT * FROM " + engine.Quote(engine.tbName(table)))
rows, err := engine.DB().Query("SELECT * FROM " + engine.Quote(table.Name))
if err != nil {
return err
}
defer rows.Close()
cols, err := rows.Columns()
if err != nil {
@ -486,7 +465,7 @@ func (engine *Engine) dumpAll(w io.Writer, tp ...core.DbType) error {
return err
}
_, err = io.WriteString(w, "INSERT INTO "+dialect.Quote(engine.tbName(table))+" ("+dialect.Quote(strings.Join(cols, dialect.Quote(", ")))+") VALUES (")
_, err = io.WriteString(w, "INSERT INTO "+dialect.Quote(table.Name)+" ("+dialect.Quote(strings.Join(cols, dialect.Quote(", ")))+") VALUES (")
if err != nil {
return err
}
@ -561,16 +540,17 @@ func (engine *Engine) dumpTables(tables []*core.Table, w io.Writer, tp ...core.D
return err
}
for _, index := range table.Indexes {
_, err = io.WriteString(w, dialect.CreateIndexSql(engine.tbName(table), index)+";\n")
_, err = io.WriteString(w, dialect.CreateIndexSql(table.Name, index)+";\n")
if err != nil {
return err
}
}
rows, err := engine.DB().Query("SELECT * FROM " + engine.Quote(engine.tbName(table)))
rows, err := engine.DB().Query("SELECT * FROM " + engine.Quote(table.Name))
if err != nil {
return err
}
defer rows.Close()
cols, err := rows.Columns()
if err != nil {
@ -586,7 +566,7 @@ func (engine *Engine) dumpTables(tables []*core.Table, w io.Writer, tp ...core.D
return err
}
_, err = io.WriteString(w, "INSERT INTO "+dialect.Quote(engine.tbName(table))+" ("+dialect.Quote(strings.Join(cols, dialect.Quote(", ")))+") VALUES (")
_, err = io.WriteString(w, "INSERT INTO "+dialect.Quote(table.Name)+" ("+dialect.Quote(strings.Join(cols, dialect.Quote(", ")))+") VALUES (")
if err != nil {
return err
}
@ -868,9 +848,14 @@ func (engine *Engine) GobRegister(v interface{}) *Engine {
return engine
}
func (engine *Engine) TableInfo(bean interface{}) *core.Table {
type Table struct {
*core.Table
Name string
}
func (engine *Engine) TableInfo(bean interface{}) *Table {
v := rValue(bean)
return engine.autoMapType(v)
return &Table{engine.autoMapType(v), engine.tbName(v)}
}
func addIndex(indexName string, table *core.Table, col *core.Column, indexType int) {
@ -1247,18 +1232,20 @@ func (engine *Engine) getCacher(v reflect.Value) core.Cacher {
// If enabled cache, clear the cache bean
func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
t := rType(bean)
v := rValue(bean)
t := v.Type()
if t.Kind() != reflect.Struct {
return errors.New("error params")
}
table := engine.TableInfo(bean)
tableName := engine.tbName(v)
table := engine.autoMapType(v)
cacher := table.Cacher
if cacher == nil {
cacher = engine.Cacher
}
if cacher != nil {
cacher.ClearIds(table.Name)
cacher.DelBean(table.Name, id)
cacher.ClearIds(tableName)
cacher.DelBean(tableName, id)
}
return nil
}
@ -1266,18 +1253,20 @@ func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
// If enabled cache, clear some tables' cache
func (engine *Engine) ClearCache(beans ...interface{}) error {
for _, bean := range beans {
t := rType(bean)
v := rValue(bean)
t := v.Type()
if t.Kind() != reflect.Struct {
return errors.New("error params")
}
table := engine.TableInfo(bean)
tableName := engine.tbName(v)
table := engine.autoMapType(v)
cacher := table.Cacher
if cacher == nil {
cacher = engine.Cacher
}
if cacher != nil {
cacher.ClearIds(table.Name)
cacher.ClearBeans(table.Name)
cacher.ClearIds(tableName)
cacher.ClearBeans(tableName)
}
}
return nil
@ -1288,11 +1277,13 @@ func (engine *Engine) ClearCache(beans ...interface{}) error {
// If you change some field, you should change the database manually.
func (engine *Engine) Sync(beans ...interface{}) error {
for _, bean := range beans {
table := engine.TableInfo(bean)
v := rValue(bean)
tableName := engine.tbName(v)
table := engine.autoMapType(v)
s := engine.NewSession()
defer s.Close()
isExist, err := s.Table(bean).isTableExist(table.Name)
isExist, err := s.Table(bean).isTableExist(tableName)
if err != nil {
return err
}
@ -1306,7 +1297,7 @@ func (engine *Engine) Sync(beans ...interface{}) error {
if err != nil {
return err
}*/
var isEmpty bool = false
var isEmpty bool
if isEmpty {
err = engine.DropTables(bean)
if err != nil {
@ -1321,7 +1312,7 @@ func (engine *Engine) Sync(beans ...interface{}) error {
session := engine.NewSession()
session.Statement.RefTable = table
defer session.Close()
isExist, err := session.Engine.dialect.IsColumnExist(table.Name, col.Name)
isExist, err := session.Engine.dialect.IsColumnExist(tableName, col.Name)
if err != nil {
return err
}
@ -1342,7 +1333,7 @@ func (engine *Engine) Sync(beans ...interface{}) error {
defer session.Close()
if index.Type == core.UniqueType {
//isExist, err := session.isIndexExist(table.Name, name, true)
isExist, err := session.isIndexExist2(table.Name, index.Cols, true)
isExist, err := session.isIndexExist2(tableName, index.Cols, true)
if err != nil {
return err
}
@ -1350,13 +1341,13 @@ func (engine *Engine) Sync(beans ...interface{}) error {
session := engine.NewSession()
session.Statement.RefTable = table
defer session.Close()
err = session.addUnique(engine.tbName(table), name)
err = session.addUnique(tableName, name)
if err != nil {
return err
}
}
} else if index.Type == core.IndexType {
isExist, err := session.isIndexExist2(table.Name, index.Cols, false)
isExist, err := session.isIndexExist2(tableName, index.Cols, false)
if err != nil {
return err
}
@ -1364,7 +1355,7 @@ func (engine *Engine) Sync(beans ...interface{}) error {
session := engine.NewSession()
session.Statement.RefTable = table
defer session.Close()
err = session.addIndex(engine.tbName(table), name)
err = session.addIndex(tableName, name)
if err != nil {
return err
}
@ -1416,8 +1407,9 @@ func (engine *Engine) dropAll() error {
// CreateTables create tabls according bean
func (engine *Engine) CreateTables(beans ...interface{}) error {
session := engine.NewSession()
err := session.Begin()
defer session.Close()
err := session.Begin()
if err != nil {
return err
}

View File

@ -29,11 +29,13 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
rows.session = session
rows.beanType = reflect.Indirect(reflect.ValueOf(bean)).Type()
defer rows.session.Statement.Init()
defer rows.session.resetStatement()
var sqlStr string
var args []interface{}
rows.session.Statement.RefTable = rows.session.Engine.TableInfo(bean)
rows.session.Statement.setRefValue(rValue(bean))
if rows.session.Statement.RawSQL == "" {
sqlStr, args = rows.session.Statement.genGetSql(bean)
} else {

View File

@ -444,7 +444,9 @@ func (session *Session) scanMapIntoStruct(obj interface{}, objMap map[string][]b
}
var col *core.Column
table := session.Engine.autoMapType(dataStruct)
session.Statement.setRefValue(dataStruct)
table := session.Statement.RefTable
tableName := session.Statement.tableName
for key, data := range objMap {
if col = table.GetColumn(key); col == nil {
@ -468,7 +470,7 @@ func (session *Session) scanMapIntoStruct(obj interface{}, objMap map[string][]b
fieldValue = dataStruct.FieldByName(fieldName)
}
if !fieldValue.IsValid() || !fieldValue.CanSet() {
session.Engine.logger.Warnf("table %v's column %v is not valid or cannot set", table.Name, key)
session.Engine.logger.Warnf("table %v's column %v is not valid or cannot set", tableName, key)
continue
}
@ -534,7 +536,7 @@ func (session *Session) Exec(sqlStr string, args ...interface{}) (sql.Result, er
// CreateTable create a table according a bean
func (session *Session) CreateTable(bean interface{}) error {
v := rValue(bean)
session.Statement.RefTable = session.Engine.mapType(v)
session.Statement.setRefValue(v)
defer session.resetStatement()
if session.IsAutoClose {
@ -547,7 +549,7 @@ func (session *Session) CreateTable(bean interface{}) error {
// CreateIndexes create indexes
func (session *Session) CreateIndexes(bean interface{}) error {
v := rValue(bean)
session.Statement.RefTable = session.Engine.mapType(v)
session.Statement.setRefValue(v)
defer session.resetStatement()
if session.IsAutoClose {
@ -567,7 +569,7 @@ func (session *Session) CreateIndexes(bean interface{}) error {
// CreateUniques create uniques
func (session *Session) CreateUniques(bean interface{}) error {
v := rValue(bean)
session.Statement.RefTable = session.Engine.mapType(v)
session.Statement.setRefValue(v)
defer session.resetStatement()
if session.IsAutoClose {
@ -592,14 +594,15 @@ func (session *Session) createOneTable() error {
// to be deleted
func (session *Session) createAll() error {
defer session.resetStatement()
if session.IsAutoClose {
defer session.Close()
}
for _, table := range session.Engine.Tables {
session.Statement.RefTable = table
session.Statement.tableName = table.Name
err := session.createOneTable()
session.resetStatement()
if err != nil {
return err
}
@ -609,6 +612,9 @@ func (session *Session) createAll() error {
// drop indexes
func (session *Session) DropIndexes(bean interface{}) error {
v := rValue(bean)
session.Statement.setRefValue(v)
defer session.resetStatement()
if session.IsAutoClose {
defer session.Close()
@ -775,9 +781,11 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
return ErrCacheFailed
}
tableName := session.Statement.TableName()
table := session.Statement.RefTable
cacher := session.Engine.getCacher2(table)
ids, err := core.GetCacheSql(cacher, session.Statement.TableName(), newsql, args)
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
if err != nil {
rows, err := session.DB().Query(newsql, args...)
if err != nil {
@ -817,8 +825,6 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
ids = append(ids, pk)
}
tableName := session.Statement.TableName()
session.Engine.logger.Debug("[cacheFind] cache sql:", ids, tableName, newsql, args)
err = core.PutCacheSql(cacher, ids, tableName, newsql, args)
if err != nil {
@ -833,7 +839,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
ididxes := make(map[string]int)
var ides []core.PK = make([]core.PK, 0)
var temps []interface{} = make([]interface{}, len(ids))
tableName := session.Statement.TableName()
for idx, id := range ids {
sid, err := id.ToString()
if err != nil {
@ -1007,14 +1013,12 @@ func (session *Session) Get(bean interface{}) (bool, error) {
defer session.Close()
}
session.Statement.setRefValue(rValue(bean))
session.Statement.Limit(1)
var sqlStr string
var args []interface{}
if session.Statement.RefTable == nil {
session.Statement.RefTable = session.Engine.TableInfo(bean)
}
if session.Statement.RawSQL == "" {
sqlStr, args = session.Statement.genGetSql(bean)
} else {
@ -1199,26 +1203,25 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
}
sliceElementType := sliceValue.Type().Elem()
var table *core.Table
if session.Statement.RefTable == nil {
if sliceElementType.Kind() == reflect.Ptr {
if sliceElementType.Elem().Kind() == reflect.Struct {
pv := reflect.New(sliceElementType.Elem())
table = session.Engine.autoMapType(pv.Elem())
session.Statement.setRefValue(pv.Elem())
} else {
return errors.New("slice type")
}
} else if sliceElementType.Kind() == reflect.Struct {
pv := reflect.New(sliceElementType)
table = session.Engine.autoMapType(pv.Elem())
session.Statement.setRefValue(pv.Elem())
} else {
return errors.New("slice type")
}
session.Statement.RefTable = table
} else {
table = session.Statement.RefTable
}
var table = session.Statement.RefTable
var addedTableName = (len(session.Statement.JoinStr) > 0)
if !session.Statement.noAutoCondition && len(condiBean) > 0 {
colNames, args := session.Statement.buildConditions(table, condiBean[0], true, true, false, true, addedTableName)
@ -1412,17 +1415,6 @@ func (session *Session) Ping() error {
return session.DB().Ping()
}
func (engine *Engine) tableName(beanOrTableName interface{}) (string, error) {
v := rValue(beanOrTableName)
if v.Type().Kind() == reflect.String {
return beanOrTableName.(string), nil
} else if v.Type().Kind() == reflect.Struct {
table := engine.autoMapType(v)
return table.Name, nil
}
return "", errors.New("bean should be a struct or struct's point")
}
// IsTableExist if a table is exist
func (session *Session) IsTableExist(beanOrTableName interface{}) (bool, error) {
tableName, err := session.Engine.tableName(beanOrTableName)
@ -1451,7 +1443,6 @@ func (session *Session) IsTableEmpty(bean interface{}) (bool, error) {
if t.Kind() == reflect.String {
return session.isTableEmpty(bean.(string))
} else if t.Kind() == reflect.Struct {
session.Engine.autoMapType(v)
rows, err := session.Count(bean)
return rows == 0, err
}
@ -1614,8 +1605,9 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i
return errors.New("Expected a pointer to a struct")
}
table := session.Engine.autoMapType(dataStruct)
return session._row2Bean(rows, fields, fieldsCount, bean, &dataStruct, table)
session.Statement.setRefValue(dataStruct)
return session._row2Bean(rows, fields, fieldsCount, bean, &dataStruct, session.Statement.RefTable)
}
func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}, dataStruct *reflect.Value, table *core.Table) error {
@ -2177,7 +2169,7 @@ func (session *Session) query2(sqlStr string, paramStr ...interface{}) (resultsS
func (session *Session) Insert(beans ...interface{}) (int64, error) {
var affected int64
var err error
defer session.resetStatement()
if session.IsAutoClose {
defer session.Close()
}
@ -2189,6 +2181,7 @@ func (session *Session) Insert(beans ...interface{}) (int64, error) {
if size > 0 {
if session.Engine.SupportInsertMany() {
cnt, err := session.innerInsertMulti(bean)
session.resetStatement()
if err != nil {
return affected, err
}
@ -2196,6 +2189,7 @@ func (session *Session) Insert(beans ...interface{}) (int64, error) {
} else {
for i := 0; i < size; i++ {
cnt, err := session.innerInsert(sliceValue.Index(i).Interface())
session.resetStatement()
if err != nil {
return affected, err
}
@ -2205,6 +2199,7 @@ func (session *Session) Insert(beans ...interface{}) (int64, error) {
}
} else {
cnt, err := session.innerInsert(bean)
session.resetStatement()
if err != nil {
return affected, err
}
@ -2223,23 +2218,20 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
bean := sliceValue.Index(0).Interface()
elementValue := rValue(bean)
//sliceElementType := elementValue.Type()
table := session.Engine.autoMapType(elementValue)
session.Statement.RefTable = table
session.Statement.setRefValue(elementValue)
table := session.Statement.RefTable
size := sliceValue.Len()
colNames := make([]string, 0)
colMultiPlaces := make([]string, 0)
var args = make([]interface{}, 0)
cols := make([]*core.Column, 0)
var colNames []string
var colMultiPlaces []string
var args []interface{}
var cols []*core.Column
for i := 0; i < size; i++ {
v := sliceValue.Index(i)
vv := reflect.Indirect(v)
elemValue := v.Interface()
colPlaces := make([]string, 0)
var colPlaces []string
// handle BeforeInsertProcessor
// !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi??
@ -3063,8 +3055,8 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
}
func (session *Session) innerInsert(bean interface{}) (int64, error) {
table := session.Engine.TableInfo(bean)
session.Statement.RefTable = table
session.Statement.setRefValue(rValue(bean))
table := session.Statement.RefTable
// handle BeforeInsertProcessor
for _, closure := range session.beforeClosures {
@ -3076,7 +3068,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
processor.BeforeInsert()
}
// --
colNames, args, err := genCols(table, session, bean, false, false)
colNames, args, err := genCols(session.Statement.RefTable, session, bean, false, false)
if err != nil {
return 0, err
}
@ -3439,11 +3431,11 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
defer session.Close()
}
t := rType(bean)
v := rValue(bean)
t := v.Type()
var colNames []string
var args []interface{}
var table *core.Table
// handle before update processors
for _, closure := range session.beforeClosures {
@ -3459,25 +3451,25 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
var isMap = t.Kind() == reflect.Map
var isStruct = t.Kind() == reflect.Struct
if isStruct {
table = session.Engine.TableInfo(bean)
session.Statement.RefTable = table
session.Statement.setRefValue(v)
if session.Statement.ColumnStr == "" {
colNames, args = buildUpdates(session.Engine, table, bean, false, false,
colNames, args = buildUpdates(session.Engine, session.Statement.RefTable, bean, false, false,
false, false, session.Statement.allUseBool, session.Statement.useAllCols,
session.Statement.mustColumnMap, session.Statement.nullableMap,
session.Statement.columnMap, true, session.Statement.unscoped)
} else {
colNames, args, err = genCols(table, session, bean, true, true)
colNames, args, err = genCols(session.Statement.RefTable, session, bean, true, true)
if err != nil {
return 0, err
}
}
} else if isMap {
// TODO: So why Table("table_name") could not be used with update map?
if session.Statement.RefTable == nil {
return 0, ErrTableNotFound
}
table = session.Statement.RefTable
colNames = make([]string, 0)
args = make([]interface{}, 0)
bValue := reflect.Indirect(reflect.ValueOf(bean))
@ -3490,6 +3482,8 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
return 0, ErrParamsType
}
table := session.Statement.RefTable
if session.Statement.UseAutoTime && table.Updated != "" {
colNames = append(colNames, session.Engine.Quote(table.Updated)+" = ?")
col := table.UpdatedColumn()
@ -3691,18 +3685,16 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
for _, col := range session.Statement.RefTable.PKColumns() {
if v, ok := data[col.Name]; !ok {
return errors.New("no id")
} else {
if col.SQLType.IsText() {
pk = append(pk, string(v))
} else if col.SQLType.IsNumeric() {
id, err = strconv.ParseInt(string(v), 10, 64)
if err != nil {
return err
}
pk = append(pk, id)
} else {
return errors.New("not supported primary key type")
} else if col.SQLType.IsText() {
pk = append(pk, string(v))
} else if col.SQLType.IsNumeric() {
id, err = strconv.ParseInt(string(v), 10, 64)
if err != nil {
return err
}
pk = append(pk, id)
} else {
return errors.New("not supported primary key type")
}
}
ids = append(ids, pk)
@ -3733,6 +3725,9 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
defer session.Close()
}
session.Statement.setRefValue(rValue(bean))
var table = session.Statement.RefTable
// handle before delete processors
for _, closure := range session.beforeClosures {
closure(bean)
@ -3744,8 +3739,6 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
}
// --
table := session.Engine.TableInfo(bean)
session.Statement.RefTable = table
var colNames []string
var args []interface{}
@ -3925,19 +3918,6 @@ func (session *Session) LastSQL() (string, []interface{}) {
return session.lastSQL, session.lastSQLArgs
}
// tbName get some table's table name
func (session *Session) tbName(table *core.Table) string {
var tbName = table.Name
if len(session.Statement.AltTableName) > 0 {
tbName = session.Statement.AltTableName
}
/*if len(session.Engine.dialect.URI().Schema) > 0 {
return session.Engine.dialect.URI().Schema + "." + tbName
}*/
return tbName
}
// tbName get some table's table name
func (session *Session) tbNameNoSchema(table *core.Table) string {
if len(session.Statement.AltTableName) > 0 {
@ -4008,7 +3988,7 @@ func (s *Session) Sync2(beans ...interface{}) error {
engine.dialect.DBType() == core.POSTGRES {
engine.logger.Infof("Table %s column %s change type from %s to %s\n",
tbName, col.Name, curType, expectedType)
_, err = engine.Exec(engine.dialect.ModifyColumnSql(engine.tbName(table), col))
_, err = engine.Exec(engine.dialect.ModifyColumnSql(table.Name, col))
} else {
engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s\n",
tbName, col.Name, curType, expectedType)
@ -4018,7 +3998,7 @@ func (s *Session) Sync2(beans ...interface{}) error {
if oriCol.Length < col.Length {
engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n",
tbName, col.Name, oriCol.Length, col.Length)
_, err = engine.Exec(engine.dialect.ModifyColumnSql(engine.tbName(table), col))
_, err = engine.Exec(engine.dialect.ModifyColumnSql(table.Name, col))
}
}
} else {
@ -4032,7 +4012,7 @@ func (s *Session) Sync2(beans ...interface{}) error {
if oriCol.Length < col.Length {
engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n",
tbName, col.Name, oriCol.Length, col.Length)
_, err = engine.Exec(engine.dialect.ModifyColumnSql(engine.tbName(table), col))
_, err = engine.Exec(engine.dialect.ModifyColumnSql(table.Name, col))
}
}
}

View File

@ -58,6 +58,7 @@ type Statement struct {
OmitStr string
ConditionStr string
AltTableName string
tableName string
RawSQL string
RawParams []interface{}
UseCascade bool
@ -100,6 +101,7 @@ func (statement *Statement) Init() {
statement.columnMap = make(map[string]bool)
statement.ConditionStr = ""
statement.AltTableName = ""
statement.tableName = ""
statement.IdParam = nil
statement.RawSQL = ""
statement.RawParams = make([]interface{}, 0)
@ -188,6 +190,11 @@ func (statement *Statement) Or(querystring string, args ...interface{}) *Stateme
return statement
}
func (statement *Statement) setRefValue(v reflect.Value) {
statement.RefTable = statement.Engine.autoMapType(v)
statement.tableName = statement.Engine.tbName(v)
}
// Table tempororily set table name, the parameter could be a string or a pointer of struct
func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
v := rValue(tableNameOrBean)
@ -196,6 +203,7 @@ func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
statement.AltTableName = tableNameOrBean.(string)
} else if t.Kind() == reflect.Struct {
statement.RefTable = statement.Engine.autoMapType(v)
statement.AltTableName = statement.Engine.tbName(v)
}
return statement
}
@ -678,14 +686,7 @@ func (statement *Statement) TableName() string {
return statement.AltTableName
}
if statement.RefTable != nil {
/*schema := statement.Engine.dialect.URI().Schema
if len(schema) > 0 {
return schema + "." + statement.RefTable.Name
}*/
return statement.RefTable.Name
}
return ""
return statement.tableName
}
// Id generate "where id = ? " statment or for composite key "where key1 = ? and key2 = ?"
@ -998,8 +999,7 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
if t.Kind() == reflect.String {
table = f.(string)
} else if t.Kind() == reflect.Struct {
r := statement.Engine.autoMapType(v)
table = r.Name
table = statement.Engine.tbName(v)
}
}
if l > 1 {
@ -1038,7 +1038,7 @@ func (statement *Statement) Unscoped() *Statement {
func (statement *Statement) genColumnStr() string {
table := statement.RefTable
colNames := make([]string, 0)
var colNames []string
for _, col := range table.Columns() {
if statement.OmitStr != "" {
if _, ok := statement.columnMap[strings.ToLower(col.Name)]; ok {
@ -1075,17 +1075,17 @@ func (statement *Statement) genColumnStr() string {
}
func (statement *Statement) genCreateTableSQL() string {
return statement.Engine.dialect.CreateTableSql(statement.RefTable, statement.AltTableName,
return statement.Engine.dialect.CreateTableSql(statement.RefTable, statement.TableName(),
statement.StoreEngine, statement.Charset)
}
func (s *Statement) genIndexSQL() []string {
var sqls []string = make([]string, 0)
var sqls []string
tbName := s.TableName()
quote := s.Engine.Quote
for idxName, index := range s.RefTable.Indexes {
if index.Type == core.IndexType {
sql := fmt.Sprintf("CREATE INDEX %v ON %v (%v);", quote(indexName(s.RefTable.Name, idxName)),
sql := fmt.Sprintf("CREATE INDEX %v ON %v (%v);", quote(indexName(tbName, idxName)),
quote(tbName), quote(strings.Join(index.Cols, quote(","))))
sqls = append(sqls, sql)
}
@ -1098,10 +1098,11 @@ func uniqueName(tableName, uqeName string) string {
}
func (s *Statement) genUniqueSQL() []string {
var sqls []string = make([]string, 0)
var sqls []string
tbName := s.TableName()
for _, index := range s.RefTable.Indexes {
if index.Type == core.UniqueType {
sql := s.Engine.dialect.CreateIndexSql(s.RefTable.Name, index)
sql := s.Engine.dialect.CreateIndexSql(tbName, index)
sqls = append(sqls, sql)
}
}
@ -1109,13 +1110,14 @@ func (s *Statement) genUniqueSQL() []string {
}
func (s *Statement) genDelIndexSQL() []string {
var sqls []string = make([]string, 0)
var sqls []string
tbName := s.TableName()
for idxName, index := range s.RefTable.Indexes {
var rIdxName string
if index.Type == core.UniqueType {
rIdxName = uniqueName(s.RefTable.Name, idxName)
rIdxName = uniqueName(tbName, idxName)
} else if index.Type == core.IndexType {
rIdxName = indexName(s.RefTable.Name, idxName)
rIdxName = indexName(tbName, idxName)
}
sql := fmt.Sprintf("DROP INDEX %v", s.Engine.Quote(rIdxName))
if s.Engine.dialect.IndexOnTable() {
@ -1127,14 +1129,9 @@ func (s *Statement) genDelIndexSQL() []string {
}
func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) {
var table *core.Table
if statement.RefTable == nil {
table = statement.Engine.TableInfo(bean)
statement.RefTable = table
} else {
table = statement.RefTable
}
statement.setRefValue(rValue(bean))
var table = statement.RefTable
var addedTableName = (len(statement.JoinStr) > 0)
if !statement.noAutoCondition {
@ -1144,7 +1141,7 @@ func (statement *Statement) genGetSql(bean interface{}) (string, []interface{})
statement.BeanArgs = args
}
var columnStr string = statement.ColumnStr
var columnStr = statement.ColumnStr
if len(statement.selectStr) > 0 {
columnStr = statement.selectStr
} else {
@ -1199,13 +1196,12 @@ func (statement *Statement) buildConditions(table *core.Table, bean interface{},
}
func (statement *Statement) genCountSql(bean interface{}) (string, []interface{}) {
table := statement.Engine.TableInfo(bean)
statement.RefTable = table
statement.setRefValue(rValue(bean))
var addedTableName = (len(statement.JoinStr) > 0)
if !statement.noAutoCondition {
colNames, args := statement.buildConditions(table, bean, true, true, false, true, addedTableName)
colNames, args := statement.buildConditions(statement.RefTable, bean, true, true, false, true, addedTableName)
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.Dialect().AndStr()+" ")
statement.BeanArgs = args
@ -1221,13 +1217,12 @@ func (statement *Statement) genCountSql(bean interface{}) (string, []interface{}
}
func (statement *Statement) genSumSql(bean interface{}, columns ...string) (string, []interface{}) {
table := statement.Engine.TableInfo(bean)
statement.RefTable = table
statement.setRefValue(rValue(bean))
var addedTableName = (len(statement.JoinStr) > 0)
if !statement.noAutoCondition {
colNames, args := statement.buildConditions(table, bean, true, true, false, true, addedTableName)
colNames, args := statement.buildConditions(statement.RefTable, bean, true, true, false, true, addedTableName)
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.Dialect().AndStr()+" ")
statement.BeanArgs = args
@ -1269,7 +1264,7 @@ func (statement *Statement) genSelectSQL(columnStr string) (a string) {
}
var whereStr = buf.String()
var fromStr string = " FROM " + quote(statement.TableName())
var fromStr = " FROM " + quote(statement.TableName())
if statement.TableAlias != "" {
if dialect.DBType() == core.ORACLE {
fromStr += " " + quote(statement.TableAlias)
@ -1286,7 +1281,7 @@ func (statement *Statement) genSelectSQL(columnStr string) (a string) {
top = fmt.Sprintf(" TOP %d ", statement.LimitN)
}
if statement.Start > 0 {
var column string = "(id)"
var column = "(id)"
if len(statement.RefTable.PKColumns()) == 0 {
for _, index := range statement.RefTable.Indexes {
if len(index.Cols) == 1 {

View File

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