mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Update xorm to latest version and fix correct user table referencing in sql (#4473)
				
					
				
			This commit is contained in:
		
							
								
								
									
										74
									
								
								vendor/github.com/go-xorm/xorm/dialect_mysql.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										74
									
								
								vendor/github.com/go-xorm/xorm/dialect_mysql.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -172,12 +172,33 @@ type mysql struct { | ||||
| 	allowAllFiles     bool | ||||
| 	allowOldPasswords bool | ||||
| 	clientFoundRows   bool | ||||
| 	rowFormat         string | ||||
| } | ||||
|  | ||||
| func (db *mysql) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { | ||||
| 	return db.Base.Init(d, db, uri, drivername, dataSourceName) | ||||
| } | ||||
|  | ||||
| func (db *mysql) SetParams(params map[string]string) { | ||||
| 	rowFormat, ok := params["rowFormat"] | ||||
| 	if ok { | ||||
| 		var t = strings.ToUpper(rowFormat) | ||||
| 		switch t { | ||||
| 		case "COMPACT": | ||||
| 			fallthrough | ||||
| 		case "REDUNDANT": | ||||
| 			fallthrough | ||||
| 		case "DYNAMIC": | ||||
| 			fallthrough | ||||
| 		case "COMPRESSED": | ||||
| 			db.rowFormat = t | ||||
| 			break | ||||
| 		default: | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (db *mysql) SqlType(c *core.Column) string { | ||||
| 	var res string | ||||
| 	switch t := c.SQLType.Name; t { | ||||
| @@ -487,6 +508,59 @@ func (db *mysql) GetIndexes(tableName string) (map[string]*core.Index, error) { | ||||
| 	return indexes, nil | ||||
| } | ||||
|  | ||||
| func (db *mysql) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string { | ||||
| 	var sql string | ||||
| 	sql = "CREATE TABLE IF NOT EXISTS " | ||||
| 	if tableName == "" { | ||||
| 		tableName = table.Name | ||||
| 	} | ||||
|  | ||||
| 	sql += db.Quote(tableName) | ||||
| 	sql += " (" | ||||
|  | ||||
| 	if len(table.ColumnsSeq()) > 0 { | ||||
| 		pkList := table.PrimaryKeys | ||||
|  | ||||
| 		for _, colName := range table.ColumnsSeq() { | ||||
| 			col := table.GetColumn(colName) | ||||
| 			if col.IsPrimaryKey && len(pkList) == 1 { | ||||
| 				sql += col.String(db) | ||||
| 			} else { | ||||
| 				sql += col.StringNoPk(db) | ||||
| 			} | ||||
| 			sql = strings.TrimSpace(sql) | ||||
| 			if len(col.Comment) > 0 { | ||||
| 				sql += " COMMENT '" + col.Comment + "'" | ||||
| 			} | ||||
| 			sql += ", " | ||||
| 		} | ||||
|  | ||||
| 		if len(pkList) > 1 { | ||||
| 			sql += "PRIMARY KEY ( " | ||||
| 			sql += db.Quote(strings.Join(pkList, db.Quote(","))) | ||||
| 			sql += " ), " | ||||
| 		} | ||||
|  | ||||
| 		sql = sql[:len(sql)-2] | ||||
| 	} | ||||
| 	sql += ")" | ||||
|  | ||||
| 	if storeEngine != "" { | ||||
| 		sql += " ENGINE=" + storeEngine | ||||
| 	} | ||||
|  | ||||
| 	if len(charset) == 0 { | ||||
| 		charset = db.URI().Charset | ||||
| 	} else if len(charset) > 0 { | ||||
| 		sql += " DEFAULT CHARSET " + charset | ||||
| 	} | ||||
|  | ||||
| 	if db.rowFormat != "" { | ||||
| 		sql += " ROW_FORMAT=" + db.rowFormat | ||||
| 	} | ||||
| 	return sql | ||||
| } | ||||
|  | ||||
| func (db *mysql) Filters() []core.Filter { | ||||
| 	return []core.Filter{&core.IdFilter{}} | ||||
| } | ||||
|   | ||||
							
								
								
									
										105
									
								
								vendor/github.com/go-xorm/xorm/dialect_postgres.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/go-xorm/xorm/dialect_postgres.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -769,14 +769,21 @@ var ( | ||||
| 	DefaultPostgresSchema = "public" | ||||
| ) | ||||
|  | ||||
| const postgresPublicSchema = "public" | ||||
|  | ||||
| type postgres struct { | ||||
| 	core.Base | ||||
| 	schema string | ||||
| } | ||||
|  | ||||
| func (db *postgres) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { | ||||
| 	db.schema = DefaultPostgresSchema | ||||
| 	return db.Base.Init(d, db, uri, drivername, dataSourceName) | ||||
| 	err := db.Base.Init(d, db, uri, drivername, dataSourceName) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if db.Schema == "" { | ||||
| 		db.Schema = DefaultPostgresSchema | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (db *postgres) SqlType(c *core.Column) string { | ||||
| @@ -873,32 +880,42 @@ func (db *postgres) IndexOnTable() bool { | ||||
| } | ||||
|  | ||||
| func (db *postgres) IndexCheckSql(tableName, idxName string) (string, []interface{}) { | ||||
| 	args := []interface{}{tableName, idxName} | ||||
| 	if len(db.Schema) == 0 { | ||||
| 		args := []interface{}{tableName, idxName} | ||||
| 		return `SELECT indexname FROM pg_indexes WHERE tablename = ? AND indexname = ?`, args | ||||
| 	} | ||||
|  | ||||
| 	args := []interface{}{db.Schema, tableName, idxName} | ||||
| 	return `SELECT indexname FROM pg_indexes ` + | ||||
| 		`WHERE tablename = ? AND indexname = ?`, args | ||||
| 		`WHERE schemaname = ? AND tablename = ? AND indexname = ?`, args | ||||
| } | ||||
|  | ||||
| func (db *postgres) TableCheckSql(tableName string) (string, []interface{}) { | ||||
| 	args := []interface{}{tableName} | ||||
| 	return `SELECT tablename FROM pg_tables WHERE tablename = ?`, args | ||||
| 	if len(db.Schema) == 0 { | ||||
| 		args := []interface{}{tableName} | ||||
| 		return `SELECT tablename FROM pg_tables WHERE tablename = ?`, args | ||||
| 	} | ||||
|  | ||||
| 	args := []interface{}{db.Schema, tableName} | ||||
| 	return `SELECT tablename FROM pg_tables WHERE schemaname = ? AND tablename = ?`, args | ||||
| } | ||||
|  | ||||
| /*func (db *postgres) ColumnCheckSql(tableName, colName string) (string, []interface{}) { | ||||
| 	args := []interface{}{tableName, colName} | ||||
| 	return "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = ?" + | ||||
| 		" AND column_name = ?", args | ||||
| }*/ | ||||
|  | ||||
| func (db *postgres) ModifyColumnSql(tableName string, col *core.Column) string { | ||||
| 	return fmt.Sprintf("alter table %s ALTER COLUMN %s TYPE %s", | ||||
| 		tableName, col.Name, db.SqlType(col)) | ||||
| 	if len(db.Schema) == 0 { | ||||
| 		return fmt.Sprintf("alter table %s ALTER COLUMN %s TYPE %s", | ||||
| 			tableName, col.Name, db.SqlType(col)) | ||||
| 	} | ||||
| 	return fmt.Sprintf("alter table %s.%s ALTER COLUMN %s TYPE %s", | ||||
| 		db.Schema, tableName, col.Name, db.SqlType(col)) | ||||
| } | ||||
|  | ||||
| func (db *postgres) DropIndexSql(tableName string, index *core.Index) string { | ||||
| 	//var unique string | ||||
| 	quote := db.Quote | ||||
| 	idxName := index.Name | ||||
|  | ||||
| 	tableName = strings.Replace(tableName, `"`, "", -1) | ||||
| 	tableName = strings.Replace(tableName, `.`, "_", -1) | ||||
|  | ||||
| 	if !strings.HasPrefix(idxName, "UQE_") && | ||||
| 		!strings.HasPrefix(idxName, "IDX_") { | ||||
| 		if index.Type == core.UniqueType { | ||||
| @@ -907,13 +924,21 @@ func (db *postgres) DropIndexSql(tableName string, index *core.Index) string { | ||||
| 			idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name) | ||||
| 		} | ||||
| 	} | ||||
| 	if db.Uri.Schema != "" { | ||||
| 		idxName = db.Uri.Schema + "." + idxName | ||||
| 	} | ||||
| 	return fmt.Sprintf("DROP INDEX %v", quote(idxName)) | ||||
| } | ||||
|  | ||||
| func (db *postgres) IsColumnExist(tableName, colName string) (bool, error) { | ||||
| 	args := []interface{}{tableName, colName} | ||||
| 	query := "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = $1" + | ||||
| 		" AND column_name = $2" | ||||
| 	args := []interface{}{db.Schema, tableName, colName} | ||||
| 	query := "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = $1 AND table_name = $2" + | ||||
| 		" AND column_name = $3" | ||||
| 	if len(db.Schema) == 0 { | ||||
| 		args = []interface{}{tableName, colName} | ||||
| 		query = "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = $1" + | ||||
| 			" AND column_name = $2" | ||||
| 	} | ||||
| 	db.LogSQL(query, args) | ||||
|  | ||||
| 	rows, err := db.DB().Query(query, args...) | ||||
| @@ -926,8 +951,7 @@ func (db *postgres) IsColumnExist(tableName, colName string) (bool, error) { | ||||
| } | ||||
|  | ||||
| func (db *postgres) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { | ||||
| 	// FIXME: the schema should be replaced by user custom's | ||||
| 	args := []interface{}{tableName, db.schema} | ||||
| 	args := []interface{}{tableName} | ||||
| 	s := `SELECT column_name, column_default, is_nullable, data_type, character_maximum_length, numeric_precision, numeric_precision_radix , | ||||
|     CASE WHEN p.contype = 'p' THEN true ELSE false END AS primarykey, | ||||
|     CASE WHEN p.contype = 'u' THEN true ELSE false END AS uniquekey | ||||
| @@ -938,7 +962,15 @@ FROM pg_attribute f | ||||
|     LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey) | ||||
|     LEFT JOIN pg_class AS g ON p.confrelid = g.oid | ||||
|     LEFT JOIN INFORMATION_SCHEMA.COLUMNS s ON s.column_name=f.attname AND c.relname=s.table_name | ||||
| WHERE c.relkind = 'r'::char AND c.relname = $1 AND s.table_schema = $2 AND f.attnum > 0 ORDER BY f.attnum;` | ||||
| WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.attnum;` | ||||
|  | ||||
| 	var f string | ||||
| 	if len(db.Schema) != 0 { | ||||
| 		args = append(args, db.Schema) | ||||
| 		f = " AND s.table_schema = $2" | ||||
| 	} | ||||
| 	s = fmt.Sprintf(s, f) | ||||
|  | ||||
| 	db.LogSQL(s, args) | ||||
|  | ||||
| 	rows, err := db.DB().Query(s, args...) | ||||
| @@ -1028,8 +1060,13 @@ WHERE c.relkind = 'r'::char AND c.relname = $1 AND s.table_schema = $2 AND f.att | ||||
| } | ||||
|  | ||||
| func (db *postgres) GetTables() ([]*core.Table, error) { | ||||
| 	args := []interface{}{db.schema} | ||||
| 	s := fmt.Sprintf("SELECT tablename FROM pg_tables WHERE schemaname = $1") | ||||
| 	args := []interface{}{} | ||||
| 	s := "SELECT tablename FROM pg_tables" | ||||
| 	if len(db.Schema) != 0 { | ||||
| 		args = append(args, db.Schema) | ||||
| 		s = s + " WHERE schemaname = $1" | ||||
| 	} | ||||
|  | ||||
| 	db.LogSQL(s, args) | ||||
|  | ||||
| 	rows, err := db.DB().Query(s, args...) | ||||
| @@ -1053,8 +1090,12 @@ func (db *postgres) GetTables() ([]*core.Table, error) { | ||||
| } | ||||
|  | ||||
| func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) { | ||||
| 	args := []interface{}{db.schema, tableName} | ||||
| 	s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE schemaname=$1 AND tablename=$2") | ||||
| 	args := []interface{}{tableName} | ||||
| 	s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE tablename=$1") | ||||
| 	if len(db.Schema) != 0 { | ||||
| 		args = append(args, db.Schema) | ||||
| 		s = s + " AND schemaname=$2" | ||||
| 	} | ||||
| 	db.LogSQL(s, args) | ||||
|  | ||||
| 	rows, err := db.DB().Query(s, args...) | ||||
| @@ -1182,3 +1223,15 @@ func (p *pqDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { | ||||
|  | ||||
| 	return db, nil | ||||
| } | ||||
|  | ||||
| type pqDriverPgx struct { | ||||
| 	pqDriver | ||||
| } | ||||
|  | ||||
| func (pgx *pqDriverPgx) Parse(driverName, dataSourceName string) (*core.Uri, error) { | ||||
| 	// Remove the leading characters for driver to work | ||||
| 	if len(dataSourceName) >= 9 && dataSourceName[0] == 0 { | ||||
| 		dataSourceName = dataSourceName[9:] | ||||
| 	} | ||||
| 	return pgx.pqDriver.Parse(driverName, dataSourceName) | ||||
| } | ||||
|   | ||||
							
								
								
									
										192
									
								
								vendor/github.com/go-xorm/xorm/engine.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										192
									
								
								vendor/github.com/go-xorm/xorm/engine.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -49,6 +49,35 @@ type Engine struct { | ||||
| 	tagHandlers map[string]tagHandler | ||||
|  | ||||
| 	engineGroup *EngineGroup | ||||
|  | ||||
| 	cachers    map[string]core.Cacher | ||||
| 	cacherLock sync.RWMutex | ||||
| } | ||||
|  | ||||
| func (engine *Engine) setCacher(tableName string, cacher core.Cacher) { | ||||
| 	engine.cacherLock.Lock() | ||||
| 	engine.cachers[tableName] = cacher | ||||
| 	engine.cacherLock.Unlock() | ||||
| } | ||||
|  | ||||
| func (engine *Engine) SetCacher(tableName string, cacher core.Cacher) { | ||||
| 	engine.setCacher(tableName, cacher) | ||||
| } | ||||
|  | ||||
| func (engine *Engine) getCacher(tableName string) core.Cacher { | ||||
| 	var cacher core.Cacher | ||||
| 	var ok bool | ||||
| 	engine.cacherLock.RLock() | ||||
| 	cacher, ok = engine.cachers[tableName] | ||||
| 	engine.cacherLock.RUnlock() | ||||
| 	if !ok && !engine.disableGlobalCache { | ||||
| 		cacher = engine.Cacher | ||||
| 	} | ||||
| 	return cacher | ||||
| } | ||||
|  | ||||
| func (engine *Engine) GetCacher(tableName string) core.Cacher { | ||||
| 	return engine.getCacher(tableName) | ||||
| } | ||||
|  | ||||
| // BufferSize sets buffer size for iterate | ||||
| @@ -165,7 +194,7 @@ func (engine *Engine) Quote(value string) string { | ||||
| } | ||||
|  | ||||
| // QuoteTo quotes string and writes into the buffer | ||||
| func (engine *Engine) QuoteTo(buf *bytes.Buffer, value string) { | ||||
| func (engine *Engine) QuoteTo(buf *builder.StringBuilder, value string) { | ||||
| 	if buf == nil { | ||||
| 		return | ||||
| 	} | ||||
| @@ -245,13 +274,7 @@ func (engine *Engine) NoCascade() *Session { | ||||
|  | ||||
| // MapCacher Set a table use a special cacher | ||||
| func (engine *Engine) MapCacher(bean interface{}, cacher core.Cacher) error { | ||||
| 	v := rValue(bean) | ||||
| 	tb, err := engine.autoMapType(v) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	tb.Cacher = cacher | ||||
| 	engine.setCacher(engine.TableName(bean, true), cacher) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -536,33 +559,6 @@ func (engine *Engine) dumpTables(tables []*core.Table, w io.Writer, tp ...core.D | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| 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.Type().Kind() == reflect.Ptr { | ||||
| 		if tb, ok := reflect.Indirect(v).Interface().(TableName); ok { | ||||
| 			return tb.TableName() | ||||
| 		} | ||||
| 	} else if v.CanAddr() { | ||||
| 		if tb, ok := v.Addr().Interface().(TableName); ok { | ||||
| 			return tb.TableName() | ||||
| 		} | ||||
| 	} | ||||
| 	return engine.TableMapper.Obj2Table(reflect.Indirect(v).Type().Name()) | ||||
| } | ||||
|  | ||||
| // Cascade use cascade or not | ||||
| func (engine *Engine) Cascade(trueOrFalse ...bool) *Session { | ||||
| 	session := engine.NewSession() | ||||
| @@ -846,7 +842,7 @@ func (engine *Engine) TableInfo(bean interface{}) *Table { | ||||
| 	if err != nil { | ||||
| 		engine.logger.Error(err) | ||||
| 	} | ||||
| 	return &Table{tb, engine.tbName(v)} | ||||
| 	return &Table{tb, engine.TableName(bean)} | ||||
| } | ||||
|  | ||||
| func addIndex(indexName string, table *core.Table, col *core.Column, indexType int) { | ||||
| @@ -861,15 +857,6 @@ func addIndex(indexName string, table *core.Table, col *core.Column, indexType i | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (engine *Engine) newTable() *core.Table { | ||||
| 	table := core.NewEmptyTable() | ||||
|  | ||||
| 	if !engine.disableGlobalCache { | ||||
| 		table.Cacher = engine.Cacher | ||||
| 	} | ||||
| 	return table | ||||
| } | ||||
|  | ||||
| // TableName table name interface to define customerize table name | ||||
| type TableName interface { | ||||
| 	TableName() string | ||||
| @@ -881,21 +868,9 @@ var ( | ||||
|  | ||||
| func (engine *Engine) mapType(v reflect.Value) (*core.Table, error) { | ||||
| 	t := v.Type() | ||||
| 	table := engine.newTable() | ||||
| 	if tb, ok := v.Interface().(TableName); ok { | ||||
| 		table.Name = tb.TableName() | ||||
| 	} else { | ||||
| 		if v.CanAddr() { | ||||
| 			if tb, ok = v.Addr().Interface().(TableName); ok { | ||||
| 				table.Name = tb.TableName() | ||||
| 			} | ||||
| 		} | ||||
| 		if table.Name == "" { | ||||
| 			table.Name = engine.TableMapper.Obj2Table(t.Name()) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	table := core.NewEmptyTable() | ||||
| 	table.Type = t | ||||
| 	table.Name = engine.tbNameForMap(v) | ||||
|  | ||||
| 	var idFieldColName string | ||||
| 	var hasCacheTag, hasNoCacheTag bool | ||||
| @@ -1049,15 +1024,15 @@ func (engine *Engine) mapType(v reflect.Value) (*core.Table, error) { | ||||
| 	if hasCacheTag { | ||||
| 		if engine.Cacher != nil { // !nash! use engine's cacher if provided | ||||
| 			engine.logger.Info("enable cache on table:", table.Name) | ||||
| 			table.Cacher = engine.Cacher | ||||
| 			engine.setCacher(table.Name, engine.Cacher) | ||||
| 		} else { | ||||
| 			engine.logger.Info("enable LRU cache on table:", table.Name) | ||||
| 			table.Cacher = NewLRUCacher2(NewMemoryStore(), time.Hour, 10000) // !nashtsai! HACK use LRU cacher for now | ||||
| 			engine.setCacher(table.Name, NewLRUCacher2(NewMemoryStore(), time.Hour, 10000)) | ||||
| 		} | ||||
| 	} | ||||
| 	if hasNoCacheTag { | ||||
| 		engine.logger.Info("no cache on table:", table.Name) | ||||
| 		table.Cacher = nil | ||||
| 		engine.logger.Info("disable cache on table:", table.Name) | ||||
| 		engine.setCacher(table.Name, nil) | ||||
| 	} | ||||
|  | ||||
| 	return table, nil | ||||
| @@ -1116,7 +1091,25 @@ func (engine *Engine) idOfV(rv reflect.Value) (core.PK, error) { | ||||
| 	pk := make([]interface{}, len(table.PrimaryKeys)) | ||||
| 	for i, col := range table.PKColumns() { | ||||
| 		var err error | ||||
| 		pkField := v.FieldByName(col.FieldName) | ||||
|  | ||||
| 		fieldName := col.FieldName | ||||
| 		for { | ||||
| 			parts := strings.SplitN(fieldName, ".", 2) | ||||
| 			if len(parts) == 1 { | ||||
| 				break | ||||
| 			} | ||||
|  | ||||
| 			v = v.FieldByName(parts[0]) | ||||
| 			if v.Kind() == reflect.Ptr { | ||||
| 				v = v.Elem() | ||||
| 			} | ||||
| 			if v.Kind() != reflect.Struct { | ||||
| 				return nil, ErrUnSupportedType | ||||
| 			} | ||||
| 			fieldName = parts[1] | ||||
| 		} | ||||
|  | ||||
| 		pkField := v.FieldByName(fieldName) | ||||
| 		switch pkField.Kind() { | ||||
| 		case reflect.String: | ||||
| 			pk[i], err = engine.idTypeAssertion(col, pkField.String()) | ||||
| @@ -1162,26 +1155,10 @@ func (engine *Engine) CreateUniques(bean interface{}) error { | ||||
| 	return session.CreateUniques(bean) | ||||
| } | ||||
|  | ||||
| func (engine *Engine) getCacher2(table *core.Table) core.Cacher { | ||||
| 	return table.Cacher | ||||
| } | ||||
|  | ||||
| // ClearCacheBean if enabled cache, clear the cache bean | ||||
| func (engine *Engine) ClearCacheBean(bean interface{}, id string) error { | ||||
| 	v := rValue(bean) | ||||
| 	t := v.Type() | ||||
| 	if t.Kind() != reflect.Struct { | ||||
| 		return errors.New("error params") | ||||
| 	} | ||||
| 	tableName := engine.tbName(v) | ||||
| 	table, err := engine.autoMapType(v) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	cacher := table.Cacher | ||||
| 	if cacher == nil { | ||||
| 		cacher = engine.Cacher | ||||
| 	} | ||||
| 	tableName := engine.TableName(bean) | ||||
| 	cacher := engine.getCacher(tableName) | ||||
| 	if cacher != nil { | ||||
| 		cacher.ClearIds(tableName) | ||||
| 		cacher.DelBean(tableName, id) | ||||
| @@ -1192,21 +1169,8 @@ func (engine *Engine) ClearCacheBean(bean interface{}, id string) error { | ||||
| // ClearCache if enabled cache, clear some tables' cache | ||||
| func (engine *Engine) ClearCache(beans ...interface{}) error { | ||||
| 	for _, bean := range beans { | ||||
| 		v := rValue(bean) | ||||
| 		t := v.Type() | ||||
| 		if t.Kind() != reflect.Struct { | ||||
| 			return errors.New("error params") | ||||
| 		} | ||||
| 		tableName := engine.tbName(v) | ||||
| 		table, err := engine.autoMapType(v) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		cacher := table.Cacher | ||||
| 		if cacher == nil { | ||||
| 			cacher = engine.Cacher | ||||
| 		} | ||||
| 		tableName := engine.TableName(bean) | ||||
| 		cacher := engine.getCacher(tableName) | ||||
| 		if cacher != nil { | ||||
| 			cacher.ClearIds(tableName) | ||||
| 			cacher.ClearBeans(tableName) | ||||
| @@ -1224,13 +1188,13 @@ func (engine *Engine) Sync(beans ...interface{}) error { | ||||
|  | ||||
| 	for _, bean := range beans { | ||||
| 		v := rValue(bean) | ||||
| 		tableName := engine.tbName(v) | ||||
| 		tableNameNoSchema := engine.TableName(bean) | ||||
| 		table, err := engine.autoMapType(v) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		isExist, err := session.Table(bean).isTableExist(tableName) | ||||
| 		isExist, err := session.Table(bean).isTableExist(tableNameNoSchema) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -1256,12 +1220,12 @@ func (engine *Engine) Sync(beans ...interface{}) error { | ||||
| 			} | ||||
| 		} else { | ||||
| 			for _, col := range table.Columns() { | ||||
| 				isExist, err := engine.dialect.IsColumnExist(tableName, col.Name) | ||||
| 				isExist, err := engine.dialect.IsColumnExist(tableNameNoSchema, col.Name) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				if !isExist { | ||||
| 					if err := session.statement.setRefValue(v); err != nil { | ||||
| 					if err := session.statement.setRefBean(bean); err != nil { | ||||
| 						return err | ||||
| 					} | ||||
| 					err = session.addColumn(col.Name) | ||||
| @@ -1272,35 +1236,35 @@ func (engine *Engine) Sync(beans ...interface{}) error { | ||||
| 			} | ||||
|  | ||||
| 			for name, index := range table.Indexes { | ||||
| 				if err := session.statement.setRefValue(v); err != nil { | ||||
| 				if err := session.statement.setRefBean(bean); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				if index.Type == core.UniqueType { | ||||
| 					isExist, err := session.isIndexExist2(tableName, index.Cols, true) | ||||
| 					isExist, err := session.isIndexExist2(tableNameNoSchema, index.Cols, true) | ||||
| 					if err != nil { | ||||
| 						return err | ||||
| 					} | ||||
| 					if !isExist { | ||||
| 						if err := session.statement.setRefValue(v); err != nil { | ||||
| 						if err := session.statement.setRefBean(bean); err != nil { | ||||
| 							return err | ||||
| 						} | ||||
|  | ||||
| 						err = session.addUnique(tableName, name) | ||||
| 						err = session.addUnique(tableNameNoSchema, name) | ||||
| 						if err != nil { | ||||
| 							return err | ||||
| 						} | ||||
| 					} | ||||
| 				} else if index.Type == core.IndexType { | ||||
| 					isExist, err := session.isIndexExist2(tableName, index.Cols, false) | ||||
| 					isExist, err := session.isIndexExist2(tableNameNoSchema, index.Cols, false) | ||||
| 					if err != nil { | ||||
| 						return err | ||||
| 					} | ||||
| 					if !isExist { | ||||
| 						if err := session.statement.setRefValue(v); err != nil { | ||||
| 						if err := session.statement.setRefBean(bean); err != nil { | ||||
| 							return err | ||||
| 						} | ||||
|  | ||||
| 						err = session.addIndex(tableName, name) | ||||
| 						err = session.addIndex(tableNameNoSchema, name) | ||||
| 						if err != nil { | ||||
| 							return err | ||||
| 						} | ||||
| @@ -1453,6 +1417,13 @@ func (engine *Engine) Find(beans interface{}, condiBeans ...interface{}) error { | ||||
| 	return session.Find(beans, condiBeans...) | ||||
| } | ||||
|  | ||||
| // FindAndCount find the results and also return the counts | ||||
| func (engine *Engine) FindAndCount(rowsSlicePtr interface{}, condiBean ...interface{}) (int64, error) { | ||||
| 	session := engine.NewSession() | ||||
| 	defer session.Close() | ||||
| 	return session.FindAndCount(rowsSlicePtr, condiBean...) | ||||
| } | ||||
|  | ||||
| // Iterate record by record handle records from table, bean's non-empty fields | ||||
| // are conditions. | ||||
| func (engine *Engine) Iterate(bean interface{}, fun IterFunc) error { | ||||
| @@ -1629,6 +1600,11 @@ func (engine *Engine) SetTZDatabase(tz *time.Location) { | ||||
| 	engine.DatabaseTZ = tz | ||||
| } | ||||
|  | ||||
| // SetSchema sets the schema of database | ||||
| func (engine *Engine) SetSchema(schema string) { | ||||
| 	engine.dialect.URI().Schema = schema | ||||
| } | ||||
|  | ||||
| // Unscoped always disable struct tag "deleted" | ||||
| func (engine *Engine) Unscoped() *Session { | ||||
| 	session := engine.NewSession() | ||||
|   | ||||
							
								
								
									
										5
									
								
								vendor/github.com/go-xorm/xorm/engine_cond.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/go-xorm/xorm/engine_cond.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -9,6 +9,7 @@ import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/go-xorm/builder" | ||||
| @@ -51,7 +52,9 @@ func (engine *Engine) buildConds(table *core.Table, bean interface{}, | ||||
|  | ||||
| 		fieldValuePtr, err := col.ValueOf(bean) | ||||
| 		if err != nil { | ||||
| 			engine.logger.Error(err) | ||||
| 			if !strings.Contains(err.Error(), "is not valid") { | ||||
| 				engine.logger.Warn(err) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
|   | ||||
							
								
								
									
										113
									
								
								vendor/github.com/go-xorm/xorm/engine_table.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								vendor/github.com/go-xorm/xorm/engine_table.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| // Copyright 2018 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" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/go-xorm/core" | ||||
| ) | ||||
|  | ||||
| // TableNameWithSchema will automatically add schema prefix on table name | ||||
| func (engine *Engine) tbNameWithSchema(v string) string { | ||||
| 	// Add schema name as prefix of table name. | ||||
| 	// Only for postgres database. | ||||
| 	if engine.dialect.DBType() == core.POSTGRES && | ||||
| 		engine.dialect.URI().Schema != "" && | ||||
| 		engine.dialect.URI().Schema != postgresPublicSchema && | ||||
| 		strings.Index(v, ".") == -1 { | ||||
| 		return engine.dialect.URI().Schema + "." + v | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| // TableName returns table name with schema prefix if has | ||||
| func (engine *Engine) TableName(bean interface{}, includeSchema ...bool) string { | ||||
| 	tbName := engine.tbNameNoSchema(bean) | ||||
| 	if len(includeSchema) > 0 && includeSchema[0] { | ||||
| 		tbName = engine.tbNameWithSchema(tbName) | ||||
| 	} | ||||
|  | ||||
| 	return tbName | ||||
| } | ||||
|  | ||||
| // tbName get some table's table name | ||||
| func (session *Session) tbNameNoSchema(table *core.Table) string { | ||||
| 	if len(session.statement.AltTableName) > 0 { | ||||
| 		return session.statement.AltTableName | ||||
| 	} | ||||
|  | ||||
| 	return table.Name | ||||
| } | ||||
|  | ||||
| func (engine *Engine) tbNameForMap(v reflect.Value) string { | ||||
| 	if v.Type().Implements(tpTableName) { | ||||
| 		return v.Interface().(TableName).TableName() | ||||
| 	} | ||||
| 	if v.Kind() == reflect.Ptr { | ||||
| 		v = v.Elem() | ||||
| 		if v.Type().Implements(tpTableName) { | ||||
| 			return v.Interface().(TableName).TableName() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return engine.TableMapper.Obj2Table(v.Type().Name()) | ||||
| } | ||||
|  | ||||
| func (engine *Engine) tbNameNoSchema(tablename interface{}) string { | ||||
| 	switch tablename.(type) { | ||||
| 	case []string: | ||||
| 		t := tablename.([]string) | ||||
| 		if len(t) > 1 { | ||||
| 			return fmt.Sprintf("%v AS %v", engine.Quote(t[0]), engine.Quote(t[1])) | ||||
| 		} else if len(t) == 1 { | ||||
| 			return engine.Quote(t[0]) | ||||
| 		} | ||||
| 	case []interface{}: | ||||
| 		t := tablename.([]interface{}) | ||||
| 		l := len(t) | ||||
| 		var table string | ||||
| 		if l > 0 { | ||||
| 			f := t[0] | ||||
| 			switch f.(type) { | ||||
| 			case string: | ||||
| 				table = f.(string) | ||||
| 			case TableName: | ||||
| 				table = f.(TableName).TableName() | ||||
| 			default: | ||||
| 				v := rValue(f) | ||||
| 				t := v.Type() | ||||
| 				if t.Kind() == reflect.Struct { | ||||
| 					table = engine.tbNameForMap(v) | ||||
| 				} else { | ||||
| 					table = engine.Quote(fmt.Sprintf("%v", f)) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if l > 1 { | ||||
| 			return fmt.Sprintf("%v AS %v", engine.Quote(table), | ||||
| 				engine.Quote(fmt.Sprintf("%v", t[1]))) | ||||
| 		} else if l == 1 { | ||||
| 			return engine.Quote(table) | ||||
| 		} | ||||
| 	case TableName: | ||||
| 		return tablename.(TableName).TableName() | ||||
| 	case string: | ||||
| 		return tablename.(string) | ||||
| 	case reflect.Value: | ||||
| 		v := tablename.(reflect.Value) | ||||
| 		return engine.tbNameForMap(v) | ||||
| 	default: | ||||
| 		v := rValue(tablename) | ||||
| 		t := v.Type() | ||||
| 		if t.Kind() == reflect.Struct { | ||||
| 			return engine.tbNameForMap(v) | ||||
| 		} | ||||
| 		return engine.Quote(fmt.Sprintf("%v", tablename)) | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
							
								
								
									
										31
									
								
								vendor/github.com/go-xorm/xorm/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/go-xorm/xorm/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -6,23 +6,44 @@ package xorm | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// ErrParamsType params error | ||||
| 	ErrParamsType = errors.New("Params type error") | ||||
| 	// ErrTableNotFound table not found error | ||||
| 	ErrTableNotFound = errors.New("Not found table") | ||||
| 	ErrTableNotFound = errors.New("Table not found") | ||||
| 	// ErrUnSupportedType unsupported error | ||||
| 	ErrUnSupportedType = errors.New("Unsupported type error") | ||||
| 	// ErrNotExist record is not exist error | ||||
| 	ErrNotExist = errors.New("Not exist error") | ||||
| 	// ErrNotExist record does not exist error | ||||
| 	ErrNotExist = errors.New("Record does not exist") | ||||
| 	// ErrCacheFailed cache failed error | ||||
| 	ErrCacheFailed = errors.New("Cache failed") | ||||
| 	// ErrNeedDeletedCond delete needs less one condition error | ||||
| 	ErrNeedDeletedCond = errors.New("Delete need at least one condition") | ||||
| 	ErrNeedDeletedCond = errors.New("Delete action needs at least one condition") | ||||
| 	// ErrNotImplemented not implemented | ||||
| 	ErrNotImplemented = errors.New("Not implemented") | ||||
| 	// ErrConditionType condition type unsupported | ||||
| 	ErrConditionType = errors.New("Unsupported conditon type") | ||||
| 	ErrConditionType = errors.New("Unsupported condition type") | ||||
| ) | ||||
|  | ||||
| // ErrFieldIsNotExist columns does not exist | ||||
| type ErrFieldIsNotExist struct { | ||||
| 	FieldName string | ||||
| 	TableName string | ||||
| } | ||||
|  | ||||
| func (e ErrFieldIsNotExist) Error() string { | ||||
| 	return fmt.Sprintf("field %s is not valid on table %s", e.FieldName, e.TableName) | ||||
| } | ||||
|  | ||||
| // ErrFieldIsNotValid is not valid | ||||
| type ErrFieldIsNotValid struct { | ||||
| 	FieldName string | ||||
| 	TableName string | ||||
| } | ||||
|  | ||||
| func (e ErrFieldIsNotValid) Error() string { | ||||
| 	return fmt.Sprintf("field %s is not valid on table %s", e.FieldName, e.TableName) | ||||
| } | ||||
|   | ||||
							
								
								
									
										162
									
								
								vendor/github.com/go-xorm/xorm/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										162
									
								
								vendor/github.com/go-xorm/xorm/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -11,7 +11,6 @@ import ( | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/go-xorm/core" | ||||
| ) | ||||
| @@ -293,19 +292,6 @@ func structName(v reflect.Type) string { | ||||
| 	return v.Name() | ||||
| } | ||||
|  | ||||
| func col2NewCols(columns ...string) []string { | ||||
| 	newColumns := make([]string, 0, len(columns)) | ||||
| 	for _, col := range columns { | ||||
| 		col = strings.Replace(col, "`", "", -1) | ||||
| 		col = strings.Replace(col, `"`, "", -1) | ||||
| 		ccols := strings.Split(col, ",") | ||||
| 		for _, c := range ccols { | ||||
| 			newColumns = append(newColumns, strings.TrimSpace(c)) | ||||
| 		} | ||||
| 	} | ||||
| 	return newColumns | ||||
| } | ||||
|  | ||||
| func sliceEq(left, right []string) bool { | ||||
| 	if len(left) != len(right) { | ||||
| 		return false | ||||
| @@ -320,154 +306,6 @@ func sliceEq(left, right []string) bool { | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func setColumnInt(bean interface{}, col *core.Column, t int64) { | ||||
| 	v, err := col.ValueOf(bean) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if v.CanSet() { | ||||
| 		switch v.Type().Kind() { | ||||
| 		case reflect.Int, reflect.Int64, reflect.Int32: | ||||
| 			v.SetInt(t) | ||||
| 		case reflect.Uint, reflect.Uint64, reflect.Uint32: | ||||
| 			v.SetUint(uint64(t)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func setColumnTime(bean interface{}, col *core.Column, t time.Time) { | ||||
| 	v, err := col.ValueOf(bean) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if v.CanSet() { | ||||
| 		switch v.Type().Kind() { | ||||
| 		case reflect.Struct: | ||||
| 			v.Set(reflect.ValueOf(t).Convert(v.Type())) | ||||
| 		case reflect.Int, reflect.Int64, reflect.Int32: | ||||
| 			v.SetInt(t.Unix()) | ||||
| 		case reflect.Uint, reflect.Uint64, reflect.Uint32: | ||||
| 			v.SetUint(uint64(t.Unix())) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, includeQuote bool) ([]string, []interface{}, error) { | ||||
| 	colNames := make([]string, 0, len(table.ColumnsSeq())) | ||||
| 	args := make([]interface{}, 0, len(table.ColumnsSeq())) | ||||
|  | ||||
| 	for _, col := range table.Columns() { | ||||
| 		if useCol && !col.IsVersion && !col.IsCreated && !col.IsUpdated { | ||||
| 			if _, ok := getFlagForColumn(session.statement.columnMap, col); !ok { | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
| 		if col.MapType == core.ONLYFROMDB { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		fieldValuePtr, err := col.ValueOf(bean) | ||||
| 		if err != nil { | ||||
| 			return nil, nil, err | ||||
| 		} | ||||
| 		fieldValue := *fieldValuePtr | ||||
|  | ||||
| 		if col.IsAutoIncrement { | ||||
| 			switch fieldValue.Type().Kind() { | ||||
| 			case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64: | ||||
| 				if fieldValue.Int() == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64: | ||||
| 				if fieldValue.Uint() == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			case reflect.String: | ||||
| 				if len(fieldValue.String()) == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			case reflect.Ptr: | ||||
| 				if fieldValue.Pointer() == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if col.IsDeleted { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if session.statement.ColumnStr != "" { | ||||
| 			if _, ok := getFlagForColumn(session.statement.columnMap, col); !ok { | ||||
| 				continue | ||||
| 			} else if _, ok := session.statement.incrColumns[col.Name]; ok { | ||||
| 				continue | ||||
| 			} else if _, ok := session.statement.decrColumns[col.Name]; ok { | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
| 		if session.statement.OmitStr != "" { | ||||
| 			if _, ok := getFlagForColumn(session.statement.columnMap, col); ok { | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// !evalphobia! set fieldValue as nil when column is nullable and zero-value | ||||
| 		if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok { | ||||
| 			if col.Nullable && isZero(fieldValue.Interface()) { | ||||
| 				var nilValue *int | ||||
| 				fieldValue = reflect.ValueOf(nilValue) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ { | ||||
| 			// if time is non-empty, then set to auto time | ||||
| 			val, t := session.engine.nowTime(col) | ||||
| 			args = append(args, val) | ||||
|  | ||||
| 			var colName = col.Name | ||||
| 			session.afterClosures = append(session.afterClosures, func(bean interface{}) { | ||||
| 				col := table.GetColumn(colName) | ||||
| 				setColumnTime(bean, col, t) | ||||
| 			}) | ||||
| 		} else if col.IsVersion && session.statement.checkVersion { | ||||
| 			args = append(args, 1) | ||||
| 		} else { | ||||
| 			arg, err := session.value2Interface(col, fieldValue) | ||||
| 			if err != nil { | ||||
| 				return colNames, args, err | ||||
| 			} | ||||
| 			args = append(args, arg) | ||||
| 		} | ||||
|  | ||||
| 		if includeQuote { | ||||
| 			colNames = append(colNames, session.engine.Quote(col.Name)+" = ?") | ||||
| 		} else { | ||||
| 			colNames = append(colNames, col.Name) | ||||
| 		} | ||||
| 	} | ||||
| 	return colNames, args, nil | ||||
| } | ||||
|  | ||||
| func indexName(tableName, idxName string) string { | ||||
| 	return fmt.Sprintf("IDX_%v_%v", tableName, idxName) | ||||
| } | ||||
|  | ||||
| func getFlagForColumn(m map[string]bool, col *core.Column) (val bool, has bool) { | ||||
| 	if len(m) == 0 { | ||||
| 		return false, false | ||||
| 	} | ||||
|  | ||||
| 	n := len(col.Name) | ||||
|  | ||||
| 	for mk := range m { | ||||
| 		if len(mk) != n { | ||||
| 			continue | ||||
| 		} | ||||
| 		if strings.EqualFold(mk, col.Name) { | ||||
| 			return m[mk], true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return false, false | ||||
| } | ||||
|   | ||||
							
								
								
									
										6
									
								
								vendor/github.com/go-xorm/xorm/interface.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/go-xorm/xorm/interface.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -30,6 +30,7 @@ type Interface interface { | ||||
| 	Exec(string, ...interface{}) (sql.Result, error) | ||||
| 	Exist(bean ...interface{}) (bool, error) | ||||
| 	Find(interface{}, ...interface{}) error | ||||
| 	FindAndCount(interface{}, ...interface{}) (int64, error) | ||||
| 	Get(interface{}) (bool, error) | ||||
| 	GroupBy(keys string) *Session | ||||
| 	ID(interface{}) *Session | ||||
| @@ -41,6 +42,7 @@ type Interface interface { | ||||
| 	IsTableExist(beanOrTableName interface{}) (bool, error) | ||||
| 	Iterate(interface{}, IterFunc) error | ||||
| 	Limit(int, ...int) *Session | ||||
| 	MustCols(columns ...string) *Session | ||||
| 	NoAutoCondition(...bool) *Session | ||||
| 	NotIn(string, ...interface{}) *Session | ||||
| 	Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session | ||||
| @@ -75,6 +77,7 @@ type EngineInterface interface { | ||||
| 	Dialect() core.Dialect | ||||
| 	DropTables(...interface{}) error | ||||
| 	DumpAllToFile(fp string, tp ...core.DbType) error | ||||
| 	GetCacher(string) core.Cacher | ||||
| 	GetColumnMapper() core.IMapper | ||||
| 	GetDefaultCacher() core.Cacher | ||||
| 	GetTableMapper() core.IMapper | ||||
| @@ -83,9 +86,11 @@ type EngineInterface interface { | ||||
| 	NewSession() *Session | ||||
| 	NoAutoTime() *Session | ||||
| 	Quote(string) string | ||||
| 	SetCacher(string, core.Cacher) | ||||
| 	SetDefaultCacher(core.Cacher) | ||||
| 	SetLogLevel(core.LogLevel) | ||||
| 	SetMapper(core.IMapper) | ||||
| 	SetSchema(string) | ||||
| 	SetTZDatabase(tz *time.Location) | ||||
| 	SetTZLocation(tz *time.Location) | ||||
| 	ShowSQL(show ...bool) | ||||
| @@ -93,6 +98,7 @@ type EngineInterface interface { | ||||
| 	Sync2(...interface{}) error | ||||
| 	StoreEngine(storeEngine string) *Session | ||||
| 	TableInfo(bean interface{}) *Table | ||||
| 	TableName(interface{}, ...bool) string | ||||
| 	UnMapType(reflect.Type) | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										6
									
								
								vendor/github.com/go-xorm/xorm/rows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/go-xorm/xorm/rows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -32,7 +32,7 @@ func newRows(session *Session, bean interface{}) (*Rows, error) { | ||||
| 	var args []interface{} | ||||
| 	var err error | ||||
|  | ||||
| 	if err = rows.session.statement.setRefValue(rValue(bean)); err != nil { | ||||
| 	if err = rows.session.statement.setRefBean(bean); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| @@ -94,8 +94,7 @@ func (rows *Rows) Scan(bean interface{}) error { | ||||
| 		return fmt.Errorf("scan arg is incompatible type to [%v]", rows.beanType) | ||||
| 	} | ||||
|  | ||||
| 	dataStruct := rValue(bean) | ||||
| 	if err := rows.session.statement.setRefValue(dataStruct); err != nil { | ||||
| 	if err := rows.session.statement.setRefBean(bean); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @@ -104,6 +103,7 @@ func (rows *Rows) Scan(bean interface{}) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	dataStruct := rValue(bean) | ||||
| 	_, err = rows.session.slice2Bean(scanResults, rows.fields, bean, &dataStruct, rows.session.statement.RefTable) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|   | ||||
							
								
								
									
										761
									
								
								vendor/github.com/go-xorm/xorm/session.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										761
									
								
								vendor/github.com/go-xorm/xorm/session.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -278,24 +278,22 @@ func (session *Session) doPrepare(db *core.DB, sqlStr string) (stmt *core.Stmt, | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (session *Session) getField(dataStruct *reflect.Value, key string, table *core.Table, idx int) *reflect.Value { | ||||
| func (session *Session) getField(dataStruct *reflect.Value, key string, table *core.Table, idx int) (*reflect.Value, error) { | ||||
| 	var col *core.Column | ||||
| 	if col = table.GetColumnIdx(key, idx); col == nil { | ||||
| 		//session.engine.logger.Warnf("table %v has no column %v. %v", table.Name, key, table.ColumnsSeq()) | ||||
| 		return nil | ||||
| 		return nil, ErrFieldIsNotExist{key, table.Name} | ||||
| 	} | ||||
|  | ||||
| 	fieldValue, err := col.ValueOfV(dataStruct) | ||||
| 	if err != nil { | ||||
| 		session.engine.logger.Error(err) | ||||
| 		return nil | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if !fieldValue.IsValid() || !fieldValue.CanSet() { | ||||
| 		session.engine.logger.Warnf("table %v's column %v is not valid or cannot set", table.Name, key) | ||||
| 		return nil | ||||
| 		return nil, ErrFieldIsNotValid{key, table.Name} | ||||
| 	} | ||||
| 	return fieldValue | ||||
|  | ||||
| 	return fieldValue, nil | ||||
| } | ||||
|  | ||||
| // Cell cell is a result of one column field | ||||
| @@ -407,409 +405,417 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b | ||||
| 		} | ||||
| 		tempMap[lKey] = idx | ||||
|  | ||||
| 		if fieldValue := session.getField(dataStruct, key, table, idx); fieldValue != nil { | ||||
| 			rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii])) | ||||
|  | ||||
| 			// if row is null then ignore | ||||
| 			if rawValue.Interface() == nil { | ||||
| 				continue | ||||
| 		fieldValue, err := session.getField(dataStruct, key, table, idx) | ||||
| 		if err != nil { | ||||
| 			if !strings.Contains(err.Error(), "is not valid") { | ||||
| 				session.engine.logger.Warn(err) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
| 		if fieldValue == nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii])) | ||||
|  | ||||
| 			if fieldValue.CanAddr() { | ||||
| 				if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok { | ||||
| 					if data, err := value2Bytes(&rawValue); err == nil { | ||||
| 						if err := structConvert.FromDB(data); err != nil { | ||||
| 							return nil, err | ||||
| 						} | ||||
| 					} else { | ||||
| 		// if row is null then ignore | ||||
| 		if rawValue.Interface() == nil { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if fieldValue.CanAddr() { | ||||
| 			if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok { | ||||
| 				if data, err := value2Bytes(&rawValue); err == nil { | ||||
| 					if err := structConvert.FromDB(data); err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					continue | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			if _, ok := fieldValue.Interface().(core.Conversion); ok { | ||||
| 				if data, err := value2Bytes(&rawValue); err == nil { | ||||
| 					if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() { | ||||
| 						fieldValue.Set(reflect.New(fieldValue.Type().Elem())) | ||||
| 					} | ||||
| 					fieldValue.Interface().(core.Conversion).FromDB(data) | ||||
| 				} else { | ||||
| 					return nil, err | ||||
| 				} | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 			rawValueType := reflect.TypeOf(rawValue.Interface()) | ||||
| 			vv := reflect.ValueOf(rawValue.Interface()) | ||||
| 			col := table.GetColumnIdx(key, idx) | ||||
| 			if col.IsPrimaryKey { | ||||
| 				pk = append(pk, rawValue.Interface()) | ||||
| 		if _, ok := fieldValue.Interface().(core.Conversion); ok { | ||||
| 			if data, err := value2Bytes(&rawValue); err == nil { | ||||
| 				if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() { | ||||
| 					fieldValue.Set(reflect.New(fieldValue.Type().Elem())) | ||||
| 				} | ||||
| 				fieldValue.Interface().(core.Conversion).FromDB(data) | ||||
| 			} else { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			fieldType := fieldValue.Type() | ||||
| 			hasAssigned := false | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 			if col.SQLType.IsJson() { | ||||
| 				var bs []byte | ||||
| 				if rawValueType.Kind() == reflect.String { | ||||
| 					bs = []byte(vv.String()) | ||||
| 				} else if rawValueType.ConvertibleTo(core.BytesType) { | ||||
| 					bs = vv.Bytes() | ||||
| 		rawValueType := reflect.TypeOf(rawValue.Interface()) | ||||
| 		vv := reflect.ValueOf(rawValue.Interface()) | ||||
| 		col := table.GetColumnIdx(key, idx) | ||||
| 		if col.IsPrimaryKey { | ||||
| 			pk = append(pk, rawValue.Interface()) | ||||
| 		} | ||||
| 		fieldType := fieldValue.Type() | ||||
| 		hasAssigned := false | ||||
|  | ||||
| 		if col.SQLType.IsJson() { | ||||
| 			var bs []byte | ||||
| 			if rawValueType.Kind() == reflect.String { | ||||
| 				bs = []byte(vv.String()) | ||||
| 			} else if rawValueType.ConvertibleTo(core.BytesType) { | ||||
| 				bs = vv.Bytes() | ||||
| 			} else { | ||||
| 				return nil, fmt.Errorf("unsupported database data type: %s %v", key, rawValueType.Kind()) | ||||
| 			} | ||||
|  | ||||
| 			hasAssigned = true | ||||
|  | ||||
| 			if len(bs) > 0 { | ||||
| 				if fieldType.Kind() == reflect.String { | ||||
| 					fieldValue.SetString(string(bs)) | ||||
| 					continue | ||||
| 				} | ||||
| 				if fieldValue.CanAddr() { | ||||
| 					err := json.Unmarshal(bs, fieldValue.Addr().Interface()) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 				} else { | ||||
| 					return nil, fmt.Errorf("unsupported database data type: %s %v", key, rawValueType.Kind()) | ||||
| 				} | ||||
|  | ||||
| 				hasAssigned = true | ||||
|  | ||||
| 				if len(bs) > 0 { | ||||
| 					if fieldType.Kind() == reflect.String { | ||||
| 						fieldValue.SetString(string(bs)) | ||||
| 						continue | ||||
| 					} | ||||
| 					if fieldValue.CanAddr() { | ||||
| 						err := json.Unmarshal(bs, fieldValue.Addr().Interface()) | ||||
| 						if err != nil { | ||||
| 							return nil, err | ||||
| 						} | ||||
| 					} else { | ||||
| 						x := reflect.New(fieldType) | ||||
| 						err := json.Unmarshal(bs, x.Interface()) | ||||
| 						if err != nil { | ||||
| 							return nil, err | ||||
| 						} | ||||
| 						fieldValue.Set(x.Elem()) | ||||
| 					x := reflect.New(fieldType) | ||||
| 					err := json.Unmarshal(bs, x.Interface()) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					fieldValue.Set(x.Elem()) | ||||
| 				} | ||||
|  | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			switch fieldType.Kind() { | ||||
| 			case reflect.Complex64, reflect.Complex128: | ||||
| 				// TODO: reimplement this | ||||
| 				var bs []byte | ||||
| 				if rawValueType.Kind() == reflect.String { | ||||
| 					bs = []byte(vv.String()) | ||||
| 				} else if rawValueType.ConvertibleTo(core.BytesType) { | ||||
| 					bs = vv.Bytes() | ||||
| 				} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 				hasAssigned = true | ||||
| 				if len(bs) > 0 { | ||||
| 					if fieldValue.CanAddr() { | ||||
| 						err := json.Unmarshal(bs, fieldValue.Addr().Interface()) | ||||
| 						if err != nil { | ||||
| 							return nil, err | ||||
| 						} | ||||
| 					} else { | ||||
| 						x := reflect.New(fieldType) | ||||
| 						err := json.Unmarshal(bs, x.Interface()) | ||||
| 						if err != nil { | ||||
| 							return nil, err | ||||
| 						} | ||||
| 						fieldValue.Set(x.Elem()) | ||||
| 		switch fieldType.Kind() { | ||||
| 		case reflect.Complex64, reflect.Complex128: | ||||
| 			// TODO: reimplement this | ||||
| 			var bs []byte | ||||
| 			if rawValueType.Kind() == reflect.String { | ||||
| 				bs = []byte(vv.String()) | ||||
| 			} else if rawValueType.ConvertibleTo(core.BytesType) { | ||||
| 				bs = vv.Bytes() | ||||
| 			} | ||||
|  | ||||
| 			hasAssigned = true | ||||
| 			if len(bs) > 0 { | ||||
| 				if fieldValue.CanAddr() { | ||||
| 					err := json.Unmarshal(bs, fieldValue.Addr().Interface()) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 				} else { | ||||
| 					x := reflect.New(fieldType) | ||||
| 					err := json.Unmarshal(bs, x.Interface()) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					fieldValue.Set(x.Elem()) | ||||
| 				} | ||||
| 			} | ||||
| 		case reflect.Slice, reflect.Array: | ||||
| 			switch rawValueType.Kind() { | ||||
| 			case reflect.Slice, reflect.Array: | ||||
| 				switch rawValueType.Kind() { | ||||
| 				case reflect.Slice, reflect.Array: | ||||
| 					switch rawValueType.Elem().Kind() { | ||||
| 					case reflect.Uint8: | ||||
| 						if fieldType.Elem().Kind() == reflect.Uint8 { | ||||
| 							hasAssigned = true | ||||
| 							if col.SQLType.IsText() { | ||||
| 								x := reflect.New(fieldType) | ||||
| 								err := json.Unmarshal(vv.Bytes(), x.Interface()) | ||||
| 								if err != nil { | ||||
| 									return nil, err | ||||
| 								} | ||||
| 								fieldValue.Set(x.Elem()) | ||||
| 							} else { | ||||
| 								if fieldValue.Len() > 0 { | ||||
| 									for i := 0; i < fieldValue.Len(); i++ { | ||||
| 										if i < vv.Len() { | ||||
| 											fieldValue.Index(i).Set(vv.Index(i)) | ||||
| 										} | ||||
| 									} | ||||
| 								} else { | ||||
| 									for i := 0; i < vv.Len(); i++ { | ||||
| 										fieldValue.Set(reflect.Append(*fieldValue, vv.Index(i))) | ||||
| 									} | ||||
| 								} | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			case reflect.String: | ||||
| 				if rawValueType.Kind() == reflect.String { | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.SetString(vv.String()) | ||||
| 				} | ||||
| 			case reflect.Bool: | ||||
| 				if rawValueType.Kind() == reflect.Bool { | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.SetBool(vv.Bool()) | ||||
| 				} | ||||
| 			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 				switch rawValueType.Kind() { | ||||
| 				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.SetInt(vv.Int()) | ||||
| 				} | ||||
| 			case reflect.Float32, reflect.Float64: | ||||
| 				switch rawValueType.Kind() { | ||||
| 				case reflect.Float32, reflect.Float64: | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.SetFloat(vv.Float()) | ||||
| 				} | ||||
| 			case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: | ||||
| 				switch rawValueType.Kind() { | ||||
| 				case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.SetUint(vv.Uint()) | ||||
| 				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.SetUint(uint64(vv.Int())) | ||||
| 				} | ||||
| 			case reflect.Struct: | ||||
| 				if fieldType.ConvertibleTo(core.TimeType) { | ||||
| 					dbTZ := session.engine.DatabaseTZ | ||||
| 					if col.TimeZone != nil { | ||||
| 						dbTZ = col.TimeZone | ||||
| 					} | ||||
|  | ||||
| 					if rawValueType == core.TimeType { | ||||
| 				switch rawValueType.Elem().Kind() { | ||||
| 				case reflect.Uint8: | ||||
| 					if fieldType.Elem().Kind() == reflect.Uint8 { | ||||
| 						hasAssigned = true | ||||
|  | ||||
| 						t := vv.Convert(core.TimeType).Interface().(time.Time) | ||||
|  | ||||
| 						z, _ := t.Zone() | ||||
| 						// set new location if database don't save timezone or give an incorrect timezone | ||||
| 						if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbTZ.String() { // !nashtsai! HACK tmp work around for lib/pq doesn't properly time with location | ||||
| 							session.engine.logger.Debugf("empty zone key[%v] : %v | zone: %v | location: %+v\n", key, t, z, *t.Location()) | ||||
| 							t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), | ||||
| 								t.Minute(), t.Second(), t.Nanosecond(), dbTZ) | ||||
| 						} | ||||
|  | ||||
| 						t = t.In(session.engine.TZLocation) | ||||
| 						fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) | ||||
| 					} else if rawValueType == core.IntType || rawValueType == core.Int64Type || | ||||
| 						rawValueType == core.Int32Type { | ||||
| 						hasAssigned = true | ||||
|  | ||||
| 						t := time.Unix(vv.Int(), 0).In(session.engine.TZLocation) | ||||
| 						fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) | ||||
| 					} else { | ||||
| 						if d, ok := vv.Interface().([]uint8); ok { | ||||
| 							hasAssigned = true | ||||
| 							t, err := session.byte2Time(col, d) | ||||
| 							if err != nil { | ||||
| 								session.engine.logger.Error("byte2Time error:", err.Error()) | ||||
| 								hasAssigned = false | ||||
| 							} else { | ||||
| 								fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) | ||||
| 							} | ||||
| 						} else if d, ok := vv.Interface().(string); ok { | ||||
| 							hasAssigned = true | ||||
| 							t, err := session.str2Time(col, d) | ||||
| 							if err != nil { | ||||
| 								session.engine.logger.Error("byte2Time error:", err.Error()) | ||||
| 								hasAssigned = false | ||||
| 							} else { | ||||
| 								fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) | ||||
| 							} | ||||
| 						} else { | ||||
| 							return nil, fmt.Errorf("rawValueType is %v, value is %v", rawValueType, vv.Interface()) | ||||
| 						} | ||||
| 					} | ||||
| 				} else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok { | ||||
| 					// !<winxxp>! 增加支持sql.Scanner接口的结构,如sql.NullString | ||||
| 					hasAssigned = true | ||||
| 					if err := nulVal.Scan(vv.Interface()); err != nil { | ||||
| 						session.engine.logger.Error("sql.Sanner error:", err.Error()) | ||||
| 						hasAssigned = false | ||||
| 					} | ||||
| 				} else if col.SQLType.IsJson() { | ||||
| 					if rawValueType.Kind() == reflect.String { | ||||
| 						hasAssigned = true | ||||
| 						x := reflect.New(fieldType) | ||||
| 						if len([]byte(vv.String())) > 0 { | ||||
| 							err := json.Unmarshal([]byte(vv.String()), x.Interface()) | ||||
| 							if err != nil { | ||||
| 								return nil, err | ||||
| 							} | ||||
| 							fieldValue.Set(x.Elem()) | ||||
| 						} | ||||
| 					} else if rawValueType.Kind() == reflect.Slice { | ||||
| 						hasAssigned = true | ||||
| 						x := reflect.New(fieldType) | ||||
| 						if len(vv.Bytes()) > 0 { | ||||
| 						if col.SQLType.IsText() { | ||||
| 							x := reflect.New(fieldType) | ||||
| 							err := json.Unmarshal(vv.Bytes(), x.Interface()) | ||||
| 							if err != nil { | ||||
| 								return nil, err | ||||
| 							} | ||||
| 							fieldValue.Set(x.Elem()) | ||||
| 						} | ||||
| 					} | ||||
| 				} else if session.statement.UseCascade { | ||||
| 					table, err := session.engine.autoMapType(*fieldValue) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
|  | ||||
| 					hasAssigned = true | ||||
| 					if len(table.PrimaryKeys) != 1 { | ||||
| 						return nil, errors.New("unsupported non or composited primary key cascade") | ||||
| 					} | ||||
| 					var pk = make(core.PK, len(table.PrimaryKeys)) | ||||
| 					pk[0], err = asKind(vv, rawValueType) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
|  | ||||
| 					if !isPKZero(pk) { | ||||
| 						// !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch | ||||
| 						// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne | ||||
| 						// property to be fetched lazily | ||||
| 						structInter := reflect.New(fieldValue.Type()) | ||||
| 						has, err := session.ID(pk).NoCascade().get(structInter.Interface()) | ||||
| 						if err != nil { | ||||
| 							return nil, err | ||||
| 						} | ||||
| 						if has { | ||||
| 							fieldValue.Set(structInter.Elem()) | ||||
| 						} else { | ||||
| 							return nil, errors.New("cascade obj is not exist") | ||||
| 							if fieldValue.Len() > 0 { | ||||
| 								for i := 0; i < fieldValue.Len(); i++ { | ||||
| 									if i < vv.Len() { | ||||
| 										fieldValue.Index(i).Set(vv.Index(i)) | ||||
| 									} | ||||
| 								} | ||||
| 							} else { | ||||
| 								for i := 0; i < vv.Len(); i++ { | ||||
| 									fieldValue.Set(reflect.Append(*fieldValue, vv.Index(i))) | ||||
| 								} | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			case reflect.Ptr: | ||||
| 				// !nashtsai! TODO merge duplicated codes above | ||||
| 				switch fieldType { | ||||
| 				// following types case matching ptr's native type, therefore assign ptr directly | ||||
| 				case core.PtrStringType: | ||||
| 					if rawValueType.Kind() == reflect.String { | ||||
| 						x := vv.String() | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrBoolType: | ||||
| 					if rawValueType.Kind() == reflect.Bool { | ||||
| 						x := vv.Bool() | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrTimeType: | ||||
| 					if rawValueType == core.PtrTimeType { | ||||
| 						hasAssigned = true | ||||
| 						var x = rawValue.Interface().(time.Time) | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrFloat64Type: | ||||
| 					if rawValueType.Kind() == reflect.Float64 { | ||||
| 						x := vv.Float() | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrUint64Type: | ||||
| 					if rawValueType.Kind() == reflect.Int64 { | ||||
| 						var x = uint64(vv.Int()) | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrInt64Type: | ||||
| 					if rawValueType.Kind() == reflect.Int64 { | ||||
| 						x := vv.Int() | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrFloat32Type: | ||||
| 					if rawValueType.Kind() == reflect.Float64 { | ||||
| 						var x = float32(vv.Float()) | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrIntType: | ||||
| 					if rawValueType.Kind() == reflect.Int64 { | ||||
| 						var x = int(vv.Int()) | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrInt32Type: | ||||
| 					if rawValueType.Kind() == reflect.Int64 { | ||||
| 						var x = int32(vv.Int()) | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrInt8Type: | ||||
| 					if rawValueType.Kind() == reflect.Int64 { | ||||
| 						var x = int8(vv.Int()) | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrInt16Type: | ||||
| 					if rawValueType.Kind() == reflect.Int64 { | ||||
| 						var x = int16(vv.Int()) | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrUintType: | ||||
| 					if rawValueType.Kind() == reflect.Int64 { | ||||
| 						var x = uint(vv.Int()) | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.PtrUint32Type: | ||||
| 					if rawValueType.Kind() == reflect.Int64 { | ||||
| 						var x = uint32(vv.Int()) | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.Uint8Type: | ||||
| 					if rawValueType.Kind() == reflect.Int64 { | ||||
| 						var x = uint8(vv.Int()) | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.Uint16Type: | ||||
| 					if rawValueType.Kind() == reflect.Int64 { | ||||
| 						var x = uint16(vv.Int()) | ||||
| 						hasAssigned = true | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 				case core.Complex64Type: | ||||
| 					var x complex64 | ||||
| 					if len([]byte(vv.String())) > 0 { | ||||
| 						err := json.Unmarshal([]byte(vv.String()), &x) | ||||
| 						if err != nil { | ||||
| 							return nil, err | ||||
| 						} | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 					hasAssigned = true | ||||
| 				case core.Complex128Type: | ||||
| 					var x complex128 | ||||
| 					if len([]byte(vv.String())) > 0 { | ||||
| 						err := json.Unmarshal([]byte(vv.String()), &x) | ||||
| 						if err != nil { | ||||
| 							return nil, err | ||||
| 						} | ||||
| 						fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 					} | ||||
| 					hasAssigned = true | ||||
| 				} // switch fieldType | ||||
| 			} // switch fieldType.Kind() | ||||
| 			} | ||||
| 		case reflect.String: | ||||
| 			if rawValueType.Kind() == reflect.String { | ||||
| 				hasAssigned = true | ||||
| 				fieldValue.SetString(vv.String()) | ||||
| 			} | ||||
| 		case reflect.Bool: | ||||
| 			if rawValueType.Kind() == reflect.Bool { | ||||
| 				hasAssigned = true | ||||
| 				fieldValue.SetBool(vv.Bool()) | ||||
| 			} | ||||
| 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 			switch rawValueType.Kind() { | ||||
| 			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 				hasAssigned = true | ||||
| 				fieldValue.SetInt(vv.Int()) | ||||
| 			} | ||||
| 		case reflect.Float32, reflect.Float64: | ||||
| 			switch rawValueType.Kind() { | ||||
| 			case reflect.Float32, reflect.Float64: | ||||
| 				hasAssigned = true | ||||
| 				fieldValue.SetFloat(vv.Float()) | ||||
| 			} | ||||
| 		case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: | ||||
| 			switch rawValueType.Kind() { | ||||
| 			case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: | ||||
| 				hasAssigned = true | ||||
| 				fieldValue.SetUint(vv.Uint()) | ||||
| 			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 				hasAssigned = true | ||||
| 				fieldValue.SetUint(uint64(vv.Int())) | ||||
| 			} | ||||
| 		case reflect.Struct: | ||||
| 			if fieldType.ConvertibleTo(core.TimeType) { | ||||
| 				dbTZ := session.engine.DatabaseTZ | ||||
| 				if col.TimeZone != nil { | ||||
| 					dbTZ = col.TimeZone | ||||
| 				} | ||||
|  | ||||
| 			// !nashtsai! for value can't be assigned directly fallback to convert to []byte then back to value | ||||
| 			if !hasAssigned { | ||||
| 				data, err := value2Bytes(&rawValue) | ||||
| 				if rawValueType == core.TimeType { | ||||
| 					hasAssigned = true | ||||
|  | ||||
| 					t := vv.Convert(core.TimeType).Interface().(time.Time) | ||||
|  | ||||
| 					z, _ := t.Zone() | ||||
| 					// set new location if database don't save timezone or give an incorrect timezone | ||||
| 					if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbTZ.String() { // !nashtsai! HACK tmp work around for lib/pq doesn't properly time with location | ||||
| 						session.engine.logger.Debugf("empty zone key[%v] : %v | zone: %v | location: %+v\n", key, t, z, *t.Location()) | ||||
| 						t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), | ||||
| 							t.Minute(), t.Second(), t.Nanosecond(), dbTZ) | ||||
| 					} | ||||
|  | ||||
| 					t = t.In(session.engine.TZLocation) | ||||
| 					fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) | ||||
| 				} else if rawValueType == core.IntType || rawValueType == core.Int64Type || | ||||
| 					rawValueType == core.Int32Type { | ||||
| 					hasAssigned = true | ||||
|  | ||||
| 					t := time.Unix(vv.Int(), 0).In(session.engine.TZLocation) | ||||
| 					fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) | ||||
| 				} else { | ||||
| 					if d, ok := vv.Interface().([]uint8); ok { | ||||
| 						hasAssigned = true | ||||
| 						t, err := session.byte2Time(col, d) | ||||
| 						if err != nil { | ||||
| 							session.engine.logger.Error("byte2Time error:", err.Error()) | ||||
| 							hasAssigned = false | ||||
| 						} else { | ||||
| 							fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) | ||||
| 						} | ||||
| 					} else if d, ok := vv.Interface().(string); ok { | ||||
| 						hasAssigned = true | ||||
| 						t, err := session.str2Time(col, d) | ||||
| 						if err != nil { | ||||
| 							session.engine.logger.Error("byte2Time error:", err.Error()) | ||||
| 							hasAssigned = false | ||||
| 						} else { | ||||
| 							fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) | ||||
| 						} | ||||
| 					} else { | ||||
| 						return nil, fmt.Errorf("rawValueType is %v, value is %v", rawValueType, vv.Interface()) | ||||
| 					} | ||||
| 				} | ||||
| 			} else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok { | ||||
| 				// !<winxxp>! 增加支持sql.Scanner接口的结构,如sql.NullString | ||||
| 				hasAssigned = true | ||||
| 				if err := nulVal.Scan(vv.Interface()); err != nil { | ||||
| 					session.engine.logger.Error("sql.Sanner error:", err.Error()) | ||||
| 					hasAssigned = false | ||||
| 				} | ||||
| 			} else if col.SQLType.IsJson() { | ||||
| 				if rawValueType.Kind() == reflect.String { | ||||
| 					hasAssigned = true | ||||
| 					x := reflect.New(fieldType) | ||||
| 					if len([]byte(vv.String())) > 0 { | ||||
| 						err := json.Unmarshal([]byte(vv.String()), x.Interface()) | ||||
| 						if err != nil { | ||||
| 							return nil, err | ||||
| 						} | ||||
| 						fieldValue.Set(x.Elem()) | ||||
| 					} | ||||
| 				} else if rawValueType.Kind() == reflect.Slice { | ||||
| 					hasAssigned = true | ||||
| 					x := reflect.New(fieldType) | ||||
| 					if len(vv.Bytes()) > 0 { | ||||
| 						err := json.Unmarshal(vv.Bytes(), x.Interface()) | ||||
| 						if err != nil { | ||||
| 							return nil, err | ||||
| 						} | ||||
| 						fieldValue.Set(x.Elem()) | ||||
| 					} | ||||
| 				} | ||||
| 			} else if session.statement.UseCascade { | ||||
| 				table, err := session.engine.autoMapType(*fieldValue) | ||||
| 				if err != nil { | ||||
| 					return nil, err | ||||
| 				} | ||||
|  | ||||
| 				if err = session.bytes2Value(col, fieldValue, data); err != nil { | ||||
| 				hasAssigned = true | ||||
| 				if len(table.PrimaryKeys) != 1 { | ||||
| 					return nil, errors.New("unsupported non or composited primary key cascade") | ||||
| 				} | ||||
| 				var pk = make(core.PK, len(table.PrimaryKeys)) | ||||
| 				pk[0], err = asKind(vv, rawValueType) | ||||
| 				if err != nil { | ||||
| 					return nil, err | ||||
| 				} | ||||
|  | ||||
| 				if !isPKZero(pk) { | ||||
| 					// !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch | ||||
| 					// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne | ||||
| 					// property to be fetched lazily | ||||
| 					structInter := reflect.New(fieldValue.Type()) | ||||
| 					has, err := session.ID(pk).NoCascade().get(structInter.Interface()) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					if has { | ||||
| 						fieldValue.Set(structInter.Elem()) | ||||
| 					} else { | ||||
| 						return nil, errors.New("cascade obj is not exist") | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		case reflect.Ptr: | ||||
| 			// !nashtsai! TODO merge duplicated codes above | ||||
| 			switch fieldType { | ||||
| 			// following types case matching ptr's native type, therefore assign ptr directly | ||||
| 			case core.PtrStringType: | ||||
| 				if rawValueType.Kind() == reflect.String { | ||||
| 					x := vv.String() | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrBoolType: | ||||
| 				if rawValueType.Kind() == reflect.Bool { | ||||
| 					x := vv.Bool() | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrTimeType: | ||||
| 				if rawValueType == core.PtrTimeType { | ||||
| 					hasAssigned = true | ||||
| 					var x = rawValue.Interface().(time.Time) | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrFloat64Type: | ||||
| 				if rawValueType.Kind() == reflect.Float64 { | ||||
| 					x := vv.Float() | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrUint64Type: | ||||
| 				if rawValueType.Kind() == reflect.Int64 { | ||||
| 					var x = uint64(vv.Int()) | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrInt64Type: | ||||
| 				if rawValueType.Kind() == reflect.Int64 { | ||||
| 					x := vv.Int() | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrFloat32Type: | ||||
| 				if rawValueType.Kind() == reflect.Float64 { | ||||
| 					var x = float32(vv.Float()) | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrIntType: | ||||
| 				if rawValueType.Kind() == reflect.Int64 { | ||||
| 					var x = int(vv.Int()) | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrInt32Type: | ||||
| 				if rawValueType.Kind() == reflect.Int64 { | ||||
| 					var x = int32(vv.Int()) | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrInt8Type: | ||||
| 				if rawValueType.Kind() == reflect.Int64 { | ||||
| 					var x = int8(vv.Int()) | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrInt16Type: | ||||
| 				if rawValueType.Kind() == reflect.Int64 { | ||||
| 					var x = int16(vv.Int()) | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrUintType: | ||||
| 				if rawValueType.Kind() == reflect.Int64 { | ||||
| 					var x = uint(vv.Int()) | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.PtrUint32Type: | ||||
| 				if rawValueType.Kind() == reflect.Int64 { | ||||
| 					var x = uint32(vv.Int()) | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.Uint8Type: | ||||
| 				if rawValueType.Kind() == reflect.Int64 { | ||||
| 					var x = uint8(vv.Int()) | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.Uint16Type: | ||||
| 				if rawValueType.Kind() == reflect.Int64 { | ||||
| 					var x = uint16(vv.Int()) | ||||
| 					hasAssigned = true | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 			case core.Complex64Type: | ||||
| 				var x complex64 | ||||
| 				if len([]byte(vv.String())) > 0 { | ||||
| 					err := json.Unmarshal([]byte(vv.String()), &x) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 				hasAssigned = true | ||||
| 			case core.Complex128Type: | ||||
| 				var x complex128 | ||||
| 				if len([]byte(vv.String())) > 0 { | ||||
| 					err := json.Unmarshal([]byte(vv.String()), &x) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					fieldValue.Set(reflect.ValueOf(&x)) | ||||
| 				} | ||||
| 				hasAssigned = true | ||||
| 			} // switch fieldType | ||||
| 		} // switch fieldType.Kind() | ||||
|  | ||||
| 		// !nashtsai! for value can't be assigned directly fallback to convert to []byte then back to value | ||||
| 		if !hasAssigned { | ||||
| 			data, err := value2Bytes(&rawValue) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
|  | ||||
| 			if err = session.bytes2Value(col, fieldValue, data); err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -828,15 +834,6 @@ func (session *Session) LastSQL() (string, []interface{}) { | ||||
| 	return session.lastSQL, session.lastSQLArgs | ||||
| } | ||||
|  | ||||
| // tbName get some table's table name | ||||
| func (session *Session) tbNameNoSchema(table *core.Table) string { | ||||
| 	if len(session.statement.AltTableName) > 0 { | ||||
| 		return session.statement.AltTableName | ||||
| 	} | ||||
|  | ||||
| 	return table.Name | ||||
| } | ||||
|  | ||||
| // Unscoped always disable struct tag "deleted" | ||||
| func (session *Session) Unscoped() *Session { | ||||
| 	session.statement.Unscoped() | ||||
|   | ||||
							
								
								
									
										115
									
								
								vendor/github.com/go-xorm/xorm/session_cols.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										115
									
								
								vendor/github.com/go-xorm/xorm/session_cols.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,6 +4,121 @@ | ||||
|  | ||||
| package xorm | ||||
|  | ||||
| import ( | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/go-xorm/core" | ||||
| ) | ||||
|  | ||||
| type incrParam struct { | ||||
| 	colName string | ||||
| 	arg     interface{} | ||||
| } | ||||
|  | ||||
| type decrParam struct { | ||||
| 	colName string | ||||
| 	arg     interface{} | ||||
| } | ||||
|  | ||||
| type exprParam struct { | ||||
| 	colName string | ||||
| 	expr    string | ||||
| } | ||||
|  | ||||
| type columnMap []string | ||||
|  | ||||
| func (m columnMap) contain(colName string) bool { | ||||
| 	if len(m) == 0 { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	n := len(colName) | ||||
| 	for _, mk := range m { | ||||
| 		if len(mk) != n { | ||||
| 			continue | ||||
| 		} | ||||
| 		if strings.EqualFold(mk, colName) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (m *columnMap) add(colName string) bool { | ||||
| 	if m.contain(colName) { | ||||
| 		return false | ||||
| 	} | ||||
| 	*m = append(*m, colName) | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func setColumnInt(bean interface{}, col *core.Column, t int64) { | ||||
| 	v, err := col.ValueOf(bean) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if v.CanSet() { | ||||
| 		switch v.Type().Kind() { | ||||
| 		case reflect.Int, reflect.Int64, reflect.Int32: | ||||
| 			v.SetInt(t) | ||||
| 		case reflect.Uint, reflect.Uint64, reflect.Uint32: | ||||
| 			v.SetUint(uint64(t)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func setColumnTime(bean interface{}, col *core.Column, t time.Time) { | ||||
| 	v, err := col.ValueOf(bean) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if v.CanSet() { | ||||
| 		switch v.Type().Kind() { | ||||
| 		case reflect.Struct: | ||||
| 			v.Set(reflect.ValueOf(t).Convert(v.Type())) | ||||
| 		case reflect.Int, reflect.Int64, reflect.Int32: | ||||
| 			v.SetInt(t.Unix()) | ||||
| 		case reflect.Uint, reflect.Uint64, reflect.Uint32: | ||||
| 			v.SetUint(uint64(t.Unix())) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func getFlagForColumn(m map[string]bool, col *core.Column) (val bool, has bool) { | ||||
| 	if len(m) == 0 { | ||||
| 		return false, false | ||||
| 	} | ||||
|  | ||||
| 	n := len(col.Name) | ||||
|  | ||||
| 	for mk := range m { | ||||
| 		if len(mk) != n { | ||||
| 			continue | ||||
| 		} | ||||
| 		if strings.EqualFold(mk, col.Name) { | ||||
| 			return m[mk], true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return false, false | ||||
| } | ||||
|  | ||||
| func col2NewCols(columns ...string) []string { | ||||
| 	newColumns := make([]string, 0, len(columns)) | ||||
| 	for _, col := range columns { | ||||
| 		col = strings.Replace(col, "`", "", -1) | ||||
| 		col = strings.Replace(col, `"`, "", -1) | ||||
| 		ccols := strings.Split(col, ",") | ||||
| 		for _, c := range ccols { | ||||
| 			newColumns = append(newColumns, strings.TrimSpace(c)) | ||||
| 		} | ||||
| 	} | ||||
| 	return newColumns | ||||
| } | ||||
|  | ||||
| // Incr provides a query string like "count = count + 1" | ||||
| func (session *Session) Incr(column string, arg ...interface{}) *Session { | ||||
| 	session.statement.Incr(column, arg...) | ||||
|   | ||||
							
								
								
									
										6
									
								
								vendor/github.com/go-xorm/xorm/session_delete.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/go-xorm/xorm/session_delete.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -27,7 +27,7 @@ func (session *Session) cacheDelete(table *core.Table, tableName, sqlStr string, | ||||
| 		return ErrCacheFailed | ||||
| 	} | ||||
|  | ||||
| 	cacher := session.engine.getCacher2(table) | ||||
| 	cacher := session.engine.getCacher(tableName) | ||||
| 	pkColumns := table.PKColumns() | ||||
| 	ids, err := core.GetCacheSql(cacher, tableName, newsql, args) | ||||
| 	if err != nil { | ||||
| @@ -79,7 +79,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) { | ||||
| 		defer session.Close() | ||||
| 	} | ||||
|  | ||||
| 	if err := session.statement.setRefValue(rValue(bean)); err != nil { | ||||
| 	if err := session.statement.setRefBean(bean); err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
|  | ||||
| @@ -199,7 +199,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) { | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache { | ||||
| 	if cacher := session.engine.getCacher(tableName); cacher != nil && session.statement.UseCache { | ||||
| 		session.cacheDelete(table, tableNameNoQuote, deleteSQL, argsForCache...) | ||||
| 	} | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/go-xorm/xorm/session_exist.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/go-xorm/xorm/session_exist.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -57,7 +57,7 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) { | ||||
| 			} | ||||
|  | ||||
| 			if beanValue.Elem().Kind() == reflect.Struct { | ||||
| 				if err := session.statement.setRefValue(beanValue.Elem()); err != nil { | ||||
| 				if err := session.statement.setRefBean(bean[0]); err != nil { | ||||
| 					return false, err | ||||
| 				} | ||||
| 			} | ||||
|   | ||||
							
								
								
									
										49
									
								
								vendor/github.com/go-xorm/xorm/session_find.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										49
									
								
								vendor/github.com/go-xorm/xorm/session_find.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -29,6 +29,39 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) | ||||
| 	return session.find(rowsSlicePtr, condiBean...) | ||||
| } | ||||
|  | ||||
| // FindAndCount find the results and also return the counts | ||||
| func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...interface{}) (int64, error) { | ||||
| 	if session.isAutoClose { | ||||
| 		defer session.Close() | ||||
| 	} | ||||
|  | ||||
| 	session.autoResetStatement = false | ||||
| 	err := session.find(rowsSlicePtr, condiBean...) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
|  | ||||
| 	sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) | ||||
| 	if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map { | ||||
| 		return 0, errors.New("needs a pointer to a slice or a map") | ||||
| 	} | ||||
|  | ||||
| 	sliceElementType := sliceValue.Type().Elem() | ||||
| 	if sliceElementType.Kind() == reflect.Ptr { | ||||
| 		sliceElementType = sliceElementType.Elem() | ||||
| 	} | ||||
| 	session.autoResetStatement = true | ||||
|  | ||||
| 	if session.statement.selectStr != "" { | ||||
| 		session.statement.selectStr = "" | ||||
| 	} | ||||
| 	if session.statement.OrderStr != "" { | ||||
| 		session.statement.OrderStr = "" | ||||
| 	} | ||||
|  | ||||
| 	return session.Count(reflect.New(sliceElementType).Interface()) | ||||
| } | ||||
|  | ||||
| func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error { | ||||
| 	sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) | ||||
| 	if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map { | ||||
| @@ -42,7 +75,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) | ||||
| 		if sliceElementType.Kind() == reflect.Ptr { | ||||
| 			if sliceElementType.Elem().Kind() == reflect.Struct { | ||||
| 				pv := reflect.New(sliceElementType.Elem()) | ||||
| 				if err := session.statement.setRefValue(pv.Elem()); err != nil { | ||||
| 				if err := session.statement.setRefValue(pv); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} else { | ||||
| @@ -50,7 +83,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) | ||||
| 			} | ||||
| 		} else if sliceElementType.Kind() == reflect.Struct { | ||||
| 			pv := reflect.New(sliceElementType) | ||||
| 			if err := session.statement.setRefValue(pv.Elem()); err != nil { | ||||
| 			if err := session.statement.setRefValue(pv); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} else { | ||||
| @@ -128,7 +161,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) | ||||
| 		} | ||||
|  | ||||
| 		args = append(session.statement.joinArgs, condArgs...) | ||||
| 		sqlStr, err = session.statement.genSelectSQL(columnStr, condSQL) | ||||
| 		sqlStr, err = session.statement.genSelectSQL(columnStr, condSQL, true, true) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -143,7 +176,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) | ||||
| 	} | ||||
|  | ||||
| 	if session.canCache() { | ||||
| 		if cacher := session.engine.getCacher2(table); cacher != nil && | ||||
| 		if cacher := session.engine.getCacher(table.Name); cacher != nil && | ||||
| 			!session.statement.IsDistinct && | ||||
| 			!session.statement.unscoped { | ||||
| 			err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...) | ||||
| @@ -288,6 +321,12 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in | ||||
| 		return ErrCacheFailed | ||||
| 	} | ||||
|  | ||||
| 	tableName := session.statement.TableName() | ||||
| 	cacher := session.engine.getCacher(tableName) | ||||
| 	if cacher == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	for _, filter := range session.engine.dialect.Filters() { | ||||
| 		sqlStr = filter.Do(sqlStr, session.engine.dialect, session.statement.RefTable) | ||||
| 	} | ||||
| @@ -297,9 +336,7 @@ 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, tableName, newsql, args) | ||||
| 	if err != nil { | ||||
| 		rows, err := session.queryRows(newsql, args...) | ||||
|   | ||||
							
								
								
									
										7
									
								
								vendor/github.com/go-xorm/xorm/session_get.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/go-xorm/xorm/session_get.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -31,7 +31,7 @@ func (session *Session) get(bean interface{}) (bool, error) { | ||||
| 	} | ||||
|  | ||||
| 	if beanValue.Elem().Kind() == reflect.Struct { | ||||
| 		if err := session.statement.setRefValue(beanValue.Elem()); err != nil { | ||||
| 		if err := session.statement.setRefBean(bean); err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
| 	} | ||||
| @@ -57,7 +57,7 @@ func (session *Session) get(bean interface{}) (bool, error) { | ||||
| 	table := session.statement.RefTable | ||||
|  | ||||
| 	if session.canCache() && beanValue.Elem().Kind() == reflect.Struct { | ||||
| 		if cacher := session.engine.getCacher2(table); cacher != nil && | ||||
| 		if cacher := session.engine.getCacher(table.Name); cacher != nil && | ||||
| 			!session.statement.unscoped { | ||||
| 			has, err := session.cacheGet(bean, sqlStr, args...) | ||||
| 			if err != ErrCacheFailed { | ||||
| @@ -134,8 +134,9 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf | ||||
| 		return false, ErrCacheFailed | ||||
| 	} | ||||
|  | ||||
| 	cacher := session.engine.getCacher2(session.statement.RefTable) | ||||
| 	tableName := session.statement.TableName() | ||||
| 	cacher := session.engine.getCacher(tableName) | ||||
|  | ||||
| 	session.engine.logger.Debug("[cacheGet] find sql:", newsql, args) | ||||
| 	table := session.statement.RefTable | ||||
| 	ids, err := core.GetCacheSql(cacher, tableName, newsql, args) | ||||
|   | ||||
							
								
								
									
										168
									
								
								vendor/github.com/go-xorm/xorm/session_insert.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										168
									
								
								vendor/github.com/go-xorm/xorm/session_insert.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -66,11 +66,12 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error | ||||
| 		return 0, errors.New("could not insert a empty slice") | ||||
| 	} | ||||
|  | ||||
| 	if err := session.statement.setRefValue(reflect.ValueOf(sliceValue.Index(0).Interface())); err != nil { | ||||
| 	if err := session.statement.setRefBean(sliceValue.Index(0).Interface()); err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
|  | ||||
| 	if len(session.statement.TableName()) <= 0 { | ||||
| 	tableName := session.statement.TableName() | ||||
| 	if len(tableName) <= 0 { | ||||
| 		return 0, ErrTableNotFound | ||||
| 	} | ||||
|  | ||||
| @@ -115,15 +116,11 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error | ||||
| 				if col.IsDeleted { | ||||
| 					continue | ||||
| 				} | ||||
| 				if session.statement.ColumnStr != "" { | ||||
| 					if _, ok := getFlagForColumn(session.statement.columnMap, col); !ok { | ||||
| 						continue | ||||
| 					} | ||||
| 				if session.statement.omitColumnMap.contain(col.Name) { | ||||
| 					continue | ||||
| 				} | ||||
| 				if session.statement.OmitStr != "" { | ||||
| 					if _, ok := getFlagForColumn(session.statement.columnMap, col); ok { | ||||
| 						continue | ||||
| 					} | ||||
| 				if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) { | ||||
| 					continue | ||||
| 				} | ||||
| 				if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime { | ||||
| 					val, t := session.engine.nowTime(col) | ||||
| @@ -170,15 +167,11 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error | ||||
| 				if col.IsDeleted { | ||||
| 					continue | ||||
| 				} | ||||
| 				if session.statement.ColumnStr != "" { | ||||
| 					if _, ok := getFlagForColumn(session.statement.columnMap, col); !ok { | ||||
| 						continue | ||||
| 					} | ||||
| 				if session.statement.omitColumnMap.contain(col.Name) { | ||||
| 					continue | ||||
| 				} | ||||
| 				if session.statement.OmitStr != "" { | ||||
| 					if _, ok := getFlagForColumn(session.statement.columnMap, col); ok { | ||||
| 						continue | ||||
| 					} | ||||
| 				if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) { | ||||
| 					continue | ||||
| 				} | ||||
| 				if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime { | ||||
| 					val, t := session.engine.nowTime(col) | ||||
| @@ -211,38 +204,33 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error | ||||
| 	} | ||||
| 	cleanupProcessorsClosures(&session.beforeClosures) | ||||
|  | ||||
| 	var sql = "INSERT INTO %s (%v%v%v) VALUES (%v)" | ||||
| 	var statement string | ||||
| 	var tableName = session.statement.TableName() | ||||
| 	var sql string | ||||
| 	if session.engine.dialect.DBType() == core.ORACLE { | ||||
| 		sql = "INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL" | ||||
| 		temp := fmt.Sprintf(") INTO %s (%v%v%v) VALUES (", | ||||
| 			session.engine.Quote(tableName), | ||||
| 			session.engine.QuoteStr(), | ||||
| 			strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()), | ||||
| 			session.engine.QuoteStr()) | ||||
| 		statement = fmt.Sprintf(sql, | ||||
| 		sql = fmt.Sprintf("INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL", | ||||
| 			session.engine.Quote(tableName), | ||||
| 			session.engine.QuoteStr(), | ||||
| 			strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()), | ||||
| 			session.engine.QuoteStr(), | ||||
| 			strings.Join(colMultiPlaces, temp)) | ||||
| 	} else { | ||||
| 		statement = fmt.Sprintf(sql, | ||||
| 		sql = fmt.Sprintf("INSERT INTO %s (%v%v%v) VALUES (%v)", | ||||
| 			session.engine.Quote(tableName), | ||||
| 			session.engine.QuoteStr(), | ||||
| 			strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()), | ||||
| 			session.engine.QuoteStr(), | ||||
| 			strings.Join(colMultiPlaces, "),(")) | ||||
| 	} | ||||
| 	res, err := session.exec(statement, args...) | ||||
| 	res, err := session.exec(sql, args...) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
|  | ||||
| 	if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache { | ||||
| 		session.cacheInsert(table, tableName) | ||||
| 	} | ||||
| 	session.cacheInsert(tableName) | ||||
|  | ||||
| 	lenAfterClosures := len(session.afterClosures) | ||||
| 	for i := 0; i < size; i++ { | ||||
| @@ -298,7 +286,7 @@ func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) { | ||||
| } | ||||
|  | ||||
| func (session *Session) innerInsert(bean interface{}) (int64, error) { | ||||
| 	if err := session.statement.setRefValue(rValue(bean)); err != nil { | ||||
| 	if err := session.statement.setRefBean(bean); err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	if len(session.statement.TableName()) <= 0 { | ||||
| @@ -316,8 +304,8 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) { | ||||
| 	if processor, ok := interface{}(bean).(BeforeInsertProcessor); ok { | ||||
| 		processor.BeforeInsert() | ||||
| 	} | ||||
| 	// -- | ||||
| 	colNames, args, err := genCols(session.statement.RefTable, session, bean, false, false) | ||||
|  | ||||
| 	colNames, args, err := session.genInsertColumns(bean) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| @@ -402,9 +390,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) { | ||||
|  | ||||
| 		defer handleAfterInsertProcessorFunc(bean) | ||||
|  | ||||
| 		if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache { | ||||
| 			session.cacheInsert(table, tableName) | ||||
| 		} | ||||
| 		session.cacheInsert(tableName) | ||||
|  | ||||
| 		if table.Version != "" && session.statement.checkVersion { | ||||
| 			verValue, err := table.VersionColumn().ValueOf(bean) | ||||
| @@ -447,9 +433,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) { | ||||
| 		} | ||||
| 		defer handleAfterInsertProcessorFunc(bean) | ||||
|  | ||||
| 		if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache { | ||||
| 			session.cacheInsert(table, tableName) | ||||
| 		} | ||||
| 		session.cacheInsert(tableName) | ||||
|  | ||||
| 		if table.Version != "" && session.statement.checkVersion { | ||||
| 			verValue, err := table.VersionColumn().ValueOf(bean) | ||||
| @@ -490,9 +474,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) { | ||||
|  | ||||
| 		defer handleAfterInsertProcessorFunc(bean) | ||||
|  | ||||
| 		if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache { | ||||
| 			session.cacheInsert(table, tableName) | ||||
| 		} | ||||
| 		session.cacheInsert(tableName) | ||||
|  | ||||
| 		if table.Version != "" && session.statement.checkVersion { | ||||
| 			verValue, err := table.VersionColumn().ValueOf(bean) | ||||
| @@ -539,16 +521,104 @@ func (session *Session) InsertOne(bean interface{}) (int64, error) { | ||||
| 	return session.innerInsert(bean) | ||||
| } | ||||
|  | ||||
| func (session *Session) cacheInsert(table *core.Table, tables ...string) error { | ||||
| 	if table == nil { | ||||
| 		return ErrCacheFailed | ||||
| func (session *Session) cacheInsert(table string) error { | ||||
| 	if !session.statement.UseCache { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	cacher := session.engine.getCacher2(table) | ||||
| 	for _, t := range tables { | ||||
| 		session.engine.logger.Debug("[cache] clear sql:", t) | ||||
| 		cacher.ClearIds(t) | ||||
| 	cacher := session.engine.getCacher(table) | ||||
| 	if cacher == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	session.engine.logger.Debug("[cache] clear sql:", table) | ||||
| 	cacher.ClearIds(table) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // genInsertColumns generates insert needed columns | ||||
| func (session *Session) genInsertColumns(bean interface{}) ([]string, []interface{}, error) { | ||||
| 	table := session.statement.RefTable | ||||
| 	colNames := make([]string, 0, len(table.ColumnsSeq())) | ||||
| 	args := make([]interface{}, 0, len(table.ColumnsSeq())) | ||||
|  | ||||
| 	for _, col := range table.Columns() { | ||||
| 		if col.MapType == core.ONLYFROMDB { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if col.IsDeleted { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if session.statement.omitColumnMap.contain(col.Name) { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if _, ok := session.statement.incrColumns[col.Name]; ok { | ||||
| 			continue | ||||
| 		} else if _, ok := session.statement.decrColumns[col.Name]; ok { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		fieldValuePtr, err := col.ValueOf(bean) | ||||
| 		if err != nil { | ||||
| 			return nil, nil, err | ||||
| 		} | ||||
| 		fieldValue := *fieldValuePtr | ||||
|  | ||||
| 		if col.IsAutoIncrement { | ||||
| 			switch fieldValue.Type().Kind() { | ||||
| 			case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64: | ||||
| 				if fieldValue.Int() == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64: | ||||
| 				if fieldValue.Uint() == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			case reflect.String: | ||||
| 				if len(fieldValue.String()) == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			case reflect.Ptr: | ||||
| 				if fieldValue.Pointer() == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// !evalphobia! set fieldValue as nil when column is nullable and zero-value | ||||
| 		if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok { | ||||
| 			if col.Nullable && isZero(fieldValue.Interface()) { | ||||
| 				var nilValue *int | ||||
| 				fieldValue = reflect.ValueOf(nilValue) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ { | ||||
| 			// if time is non-empty, then set to auto time | ||||
| 			val, t := session.engine.nowTime(col) | ||||
| 			args = append(args, val) | ||||
|  | ||||
| 			var colName = col.Name | ||||
| 			session.afterClosures = append(session.afterClosures, func(bean interface{}) { | ||||
| 				col := table.GetColumn(colName) | ||||
| 				setColumnTime(bean, col, t) | ||||
| 			}) | ||||
| 		} else if col.IsVersion && session.statement.checkVersion { | ||||
| 			args = append(args, 1) | ||||
| 		} else { | ||||
| 			arg, err := session.value2Interface(col, fieldValue) | ||||
| 			if err != nil { | ||||
| 				return colNames, args, err | ||||
| 			} | ||||
| 			args = append(args, arg) | ||||
| 		} | ||||
|  | ||||
| 		colNames = append(colNames, col.Name) | ||||
| 	} | ||||
| 	return colNames, args, nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										6
									
								
								vendor/github.com/go-xorm/xorm/session_query.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/go-xorm/xorm/session_query.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -64,13 +64,17 @@ func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interfa | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if err := session.statement.processIDParam(); err != nil { | ||||
| 		return "", nil, err | ||||
| 	} | ||||
|  | ||||
| 	condSQL, condArgs, err := builder.ToSQL(session.statement.cond) | ||||
| 	if err != nil { | ||||
| 		return "", nil, err | ||||
| 	} | ||||
|  | ||||
| 	args := append(session.statement.joinArgs, condArgs...) | ||||
| 	sqlStr, err := session.statement.genSelectSQL(columnStr, condSQL) | ||||
| 	sqlStr, err := session.statement.genSelectSQL(columnStr, condSQL, true, true) | ||||
| 	if err != nil { | ||||
| 		return "", nil, err | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										87
									
								
								vendor/github.com/go-xorm/xorm/session_schema.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										87
									
								
								vendor/github.com/go-xorm/xorm/session_schema.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -6,9 +6,7 @@ package xorm | ||||
|  | ||||
| import ( | ||||
| 	"database/sql" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/go-xorm/core" | ||||
| @@ -34,8 +32,7 @@ func (session *Session) CreateTable(bean interface{}) error { | ||||
| } | ||||
|  | ||||
| func (session *Session) createTable(bean interface{}) error { | ||||
| 	v := rValue(bean) | ||||
| 	if err := session.statement.setRefValue(v); err != nil { | ||||
| 	if err := session.statement.setRefBean(bean); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @@ -54,8 +51,7 @@ func (session *Session) CreateIndexes(bean interface{}) error { | ||||
| } | ||||
|  | ||||
| func (session *Session) createIndexes(bean interface{}) error { | ||||
| 	v := rValue(bean) | ||||
| 	if err := session.statement.setRefValue(v); err != nil { | ||||
| 	if err := session.statement.setRefBean(bean); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @@ -78,8 +74,7 @@ func (session *Session) CreateUniques(bean interface{}) error { | ||||
| } | ||||
|  | ||||
| func (session *Session) createUniques(bean interface{}) error { | ||||
| 	v := rValue(bean) | ||||
| 	if err := session.statement.setRefValue(v); err != nil { | ||||
| 	if err := session.statement.setRefBean(bean); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @@ -103,8 +98,7 @@ func (session *Session) DropIndexes(bean interface{}) error { | ||||
| } | ||||
|  | ||||
| func (session *Session) dropIndexes(bean interface{}) error { | ||||
| 	v := rValue(bean) | ||||
| 	if err := session.statement.setRefValue(v); err != nil { | ||||
| 	if err := session.statement.setRefBean(bean); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @@ -128,11 +122,7 @@ func (session *Session) DropTable(beanOrTableName interface{}) error { | ||||
| } | ||||
|  | ||||
| func (session *Session) dropTable(beanOrTableName interface{}) error { | ||||
| 	tableName, err := session.engine.tableName(beanOrTableName) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	tableName := session.engine.TableName(beanOrTableName) | ||||
| 	var needDrop = true | ||||
| 	if !session.engine.dialect.SupportDropIfExists() { | ||||
| 		sqlStr, args := session.engine.dialect.TableCheckSql(tableName) | ||||
| @@ -144,8 +134,8 @@ func (session *Session) dropTable(beanOrTableName interface{}) error { | ||||
| 	} | ||||
|  | ||||
| 	if needDrop { | ||||
| 		sqlStr := session.engine.Dialect().DropTableSql(tableName) | ||||
| 		_, err = session.exec(sqlStr) | ||||
| 		sqlStr := session.engine.Dialect().DropTableSql(session.engine.TableName(tableName, true)) | ||||
| 		_, err := session.exec(sqlStr) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| @@ -157,10 +147,7 @@ func (session *Session) IsTableExist(beanOrTableName interface{}) (bool, error) | ||||
| 		defer session.Close() | ||||
| 	} | ||||
|  | ||||
| 	tableName, err := session.engine.tableName(beanOrTableName) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| 	tableName := session.engine.TableName(beanOrTableName) | ||||
|  | ||||
| 	return session.isTableExist(tableName) | ||||
| } | ||||
| @@ -173,24 +160,15 @@ func (session *Session) isTableExist(tableName string) (bool, error) { | ||||
|  | ||||
| // IsTableEmpty if table have any records | ||||
| func (session *Session) IsTableEmpty(bean interface{}) (bool, error) { | ||||
| 	v := rValue(bean) | ||||
| 	t := v.Type() | ||||
|  | ||||
| 	if t.Kind() == reflect.String { | ||||
| 		if session.isAutoClose { | ||||
| 			defer session.Close() | ||||
| 		} | ||||
| 		return session.isTableEmpty(bean.(string)) | ||||
| 	} else if t.Kind() == reflect.Struct { | ||||
| 		rows, err := session.Count(bean) | ||||
| 		return rows == 0, err | ||||
| 	if session.isAutoClose { | ||||
| 		defer session.Close() | ||||
| 	} | ||||
| 	return false, errors.New("bean should be a struct or struct's point") | ||||
| 	return session.isTableEmpty(session.engine.TableName(bean)) | ||||
| } | ||||
|  | ||||
| func (session *Session) isTableEmpty(tableName string) (bool, error) { | ||||
| 	var total int64 | ||||
| 	sqlStr := fmt.Sprintf("select count(*) from %s", session.engine.Quote(tableName)) | ||||
| 	sqlStr := fmt.Sprintf("select count(*) from %s", session.engine.Quote(session.engine.TableName(tableName, true))) | ||||
| 	err := session.queryRow(sqlStr).Scan(&total) | ||||
| 	if err != nil { | ||||
| 		if err == sql.ErrNoRows { | ||||
| @@ -255,6 +233,12 @@ func (session *Session) Sync2(beans ...interface{}) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	session.autoResetStatement = false | ||||
| 	defer func() { | ||||
| 		session.autoResetStatement = true | ||||
| 		session.resetStatement() | ||||
| 	}() | ||||
|  | ||||
| 	var structTables []*core.Table | ||||
|  | ||||
| 	for _, bean := range beans { | ||||
| @@ -264,7 +248,8 @@ func (session *Session) Sync2(beans ...interface{}) error { | ||||
| 			return err | ||||
| 		} | ||||
| 		structTables = append(structTables, table) | ||||
| 		var tbName = session.tbNameNoSchema(table) | ||||
| 		tbName := engine.TableName(bean) | ||||
| 		tbNameWithSchema := engine.TableName(tbName, true) | ||||
|  | ||||
| 		var oriTable *core.Table | ||||
| 		for _, tb := range tables { | ||||
| @@ -309,32 +294,32 @@ func (session *Session) Sync2(beans ...interface{}) error { | ||||
| 							if engine.dialect.DBType() == core.MYSQL || | ||||
| 								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 = session.exec(engine.dialect.ModifyColumnSql(table.Name, col)) | ||||
| 									tbNameWithSchema, col.Name, curType, expectedType) | ||||
| 								_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) | ||||
| 							} else { | ||||
| 								engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s\n", | ||||
| 									tbName, col.Name, curType, expectedType) | ||||
| 									tbNameWithSchema, col.Name, curType, expectedType) | ||||
| 							} | ||||
| 						} else if strings.HasPrefix(curType, core.Varchar) && strings.HasPrefix(expectedType, core.Varchar) { | ||||
| 							if engine.dialect.DBType() == core.MYSQL { | ||||
| 								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 = session.exec(engine.dialect.ModifyColumnSql(table.Name, col)) | ||||
| 										tbNameWithSchema, col.Name, oriCol.Length, col.Length) | ||||
| 									_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) | ||||
| 								} | ||||
| 							} | ||||
| 						} else { | ||||
| 							if !(strings.HasPrefix(curType, expectedType) && curType[len(expectedType)] == '(') { | ||||
| 								engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s", | ||||
| 									tbName, col.Name, curType, expectedType) | ||||
| 									tbNameWithSchema, col.Name, curType, expectedType) | ||||
| 							} | ||||
| 						} | ||||
| 					} else if expectedType == core.Varchar { | ||||
| 						if engine.dialect.DBType() == core.MYSQL { | ||||
| 							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 = session.exec(engine.dialect.ModifyColumnSql(table.Name, col)) | ||||
| 									tbNameWithSchema, col.Name, oriCol.Length, col.Length) | ||||
| 								_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| @@ -348,7 +333,7 @@ func (session *Session) Sync2(beans ...interface{}) error { | ||||
| 					} | ||||
| 				} else { | ||||
| 					session.statement.RefTable = table | ||||
| 					session.statement.tableName = tbName | ||||
| 					session.statement.tableName = tbNameWithSchema | ||||
| 					err = session.addColumn(col.Name) | ||||
| 				} | ||||
| 				if err != nil { | ||||
| @@ -371,7 +356,7 @@ func (session *Session) Sync2(beans ...interface{}) error { | ||||
|  | ||||
| 				if oriIndex != nil { | ||||
| 					if oriIndex.Type != index.Type { | ||||
| 						sql := engine.dialect.DropIndexSql(tbName, oriIndex) | ||||
| 						sql := engine.dialect.DropIndexSql(tbNameWithSchema, oriIndex) | ||||
| 						_, err = session.exec(sql) | ||||
| 						if err != nil { | ||||
| 							return err | ||||
| @@ -387,7 +372,7 @@ func (session *Session) Sync2(beans ...interface{}) error { | ||||
|  | ||||
| 			for name2, index2 := range oriTable.Indexes { | ||||
| 				if _, ok := foundIndexNames[name2]; !ok { | ||||
| 					sql := engine.dialect.DropIndexSql(tbName, index2) | ||||
| 					sql := engine.dialect.DropIndexSql(tbNameWithSchema, index2) | ||||
| 					_, err = session.exec(sql) | ||||
| 					if err != nil { | ||||
| 						return err | ||||
| @@ -398,12 +383,12 @@ func (session *Session) Sync2(beans ...interface{}) error { | ||||
| 			for name, index := range addedNames { | ||||
| 				if index.Type == core.UniqueType { | ||||
| 					session.statement.RefTable = table | ||||
| 					session.statement.tableName = tbName | ||||
| 					err = session.addUnique(tbName, name) | ||||
| 					session.statement.tableName = tbNameWithSchema | ||||
| 					err = session.addUnique(tbNameWithSchema, name) | ||||
| 				} else if index.Type == core.IndexType { | ||||
| 					session.statement.RefTable = table | ||||
| 					session.statement.tableName = tbName | ||||
| 					err = session.addIndex(tbName, name) | ||||
| 					session.statement.tableName = tbNameWithSchema | ||||
| 					err = session.addIndex(tbNameWithSchema, name) | ||||
| 				} | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| @@ -428,7 +413,7 @@ func (session *Session) Sync2(beans ...interface{}) error { | ||||
|  | ||||
| 		for _, colName := range table.ColumnsSeq() { | ||||
| 			if oriTable.GetColumn(colName) == nil { | ||||
| 				engine.logger.Warnf("Table %s has column %s but struct has not related field", table.Name, colName) | ||||
| 				engine.logger.Warnf("Table %s has column %s but struct has not related field", engine.TableName(table.Name, true), colName) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/go-xorm/xorm/session_tx.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/go-xorm/xorm/session_tx.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -24,6 +24,7 @@ func (session *Session) Rollback() error { | ||||
| 	if !session.isAutoCommit && !session.isCommitedOrRollbacked { | ||||
| 		session.saveLastSQL(session.engine.dialect.RollBackStr()) | ||||
| 		session.isCommitedOrRollbacked = true | ||||
| 		session.isAutoCommit = true | ||||
| 		return session.tx.Rollback() | ||||
| 	} | ||||
| 	return nil | ||||
| @@ -34,6 +35,7 @@ func (session *Session) Commit() error { | ||||
| 	if !session.isAutoCommit && !session.isCommitedOrRollbacked { | ||||
| 		session.saveLastSQL("COMMIT") | ||||
| 		session.isCommitedOrRollbacked = true | ||||
| 		session.isAutoCommit = true | ||||
| 		var err error | ||||
| 		if err = session.tx.Commit(); err == nil { | ||||
| 			// handle processors after tx committed | ||||
|   | ||||
							
								
								
									
										115
									
								
								vendor/github.com/go-xorm/xorm/session_update.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										115
									
								
								vendor/github.com/go-xorm/xorm/session_update.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -40,7 +40,7 @@ func (session *Session) cacheUpdate(table *core.Table, tableName, sqlStr string, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	cacher := session.engine.getCacher2(table) | ||||
| 	cacher := session.engine.getCacher(tableName) | ||||
| 	session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:]) | ||||
| 	ids, err := core.GetCacheSql(cacher, tableName, newsql, args[nStart:]) | ||||
| 	if err != nil { | ||||
| @@ -167,7 +167,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 | ||||
| 	var isMap = t.Kind() == reflect.Map | ||||
| 	var isStruct = t.Kind() == reflect.Struct | ||||
| 	if isStruct { | ||||
| 		if err := session.statement.setRefValue(v); err != nil { | ||||
| 		if err := session.statement.setRefBean(bean); err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
|  | ||||
| @@ -176,12 +176,10 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 | ||||
| 		} | ||||
|  | ||||
| 		if session.statement.ColumnStr == "" { | ||||
| 			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) | ||||
| 			colNames, args = session.statement.buildUpdates(bean, false, false, | ||||
| 				false, false, true) | ||||
| 		} else { | ||||
| 			colNames, args, err = genCols(session.statement.RefTable, session, bean, true, true) | ||||
| 			colNames, args, err = session.genUpdateColumns(bean) | ||||
| 			if err != nil { | ||||
| 				return 0, err | ||||
| 			} | ||||
| @@ -202,7 +200,8 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 | ||||
| 	table := session.statement.RefTable | ||||
|  | ||||
| 	if session.statement.UseAutoTime && table != nil && table.Updated != "" { | ||||
| 		if _, ok := session.statement.columnMap[strings.ToLower(table.Updated)]; !ok { | ||||
| 		if !session.statement.columnMap.contain(table.Updated) && | ||||
| 			!session.statement.omitColumnMap.contain(table.Updated) { | ||||
| 			colNames = append(colNames, session.engine.Quote(table.Updated)+" = ?") | ||||
| 			col := table.UpdatedColumn() | ||||
| 			val, t := session.engine.nowTime(col) | ||||
| @@ -362,12 +361,11 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if table != nil { | ||||
| 		if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache { | ||||
| 			//session.cacheUpdate(table, tableName, sqlStr, args...) | ||||
| 			cacher.ClearIds(tableName) | ||||
| 			cacher.ClearBeans(tableName) | ||||
| 		} | ||||
| 	if cacher := session.engine.getCacher(tableName); cacher != nil && session.statement.UseCache { | ||||
| 		//session.cacheUpdate(table, tableName, sqlStr, args...) | ||||
| 		session.engine.logger.Debug("[cacheUpdate] clear table ", tableName) | ||||
| 		cacher.ClearIds(tableName) | ||||
| 		cacher.ClearBeans(tableName) | ||||
| 	} | ||||
|  | ||||
| 	// handle after update processors | ||||
| @@ -402,3 +400,92 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 | ||||
|  | ||||
| 	return res.RowsAffected() | ||||
| } | ||||
|  | ||||
| func (session *Session) genUpdateColumns(bean interface{}) ([]string, []interface{}, error) { | ||||
| 	table := session.statement.RefTable | ||||
| 	colNames := make([]string, 0, len(table.ColumnsSeq())) | ||||
| 	args := make([]interface{}, 0, len(table.ColumnsSeq())) | ||||
|  | ||||
| 	for _, col := range table.Columns() { | ||||
| 		if !col.IsVersion && !col.IsCreated && !col.IsUpdated { | ||||
| 			if session.statement.omitColumnMap.contain(col.Name) { | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
| 		if col.MapType == core.ONLYFROMDB { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		fieldValuePtr, err := col.ValueOf(bean) | ||||
| 		if err != nil { | ||||
| 			return nil, nil, err | ||||
| 		} | ||||
| 		fieldValue := *fieldValuePtr | ||||
|  | ||||
| 		if col.IsAutoIncrement { | ||||
| 			switch fieldValue.Type().Kind() { | ||||
| 			case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64: | ||||
| 				if fieldValue.Int() == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64: | ||||
| 				if fieldValue.Uint() == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			case reflect.String: | ||||
| 				if len(fieldValue.String()) == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			case reflect.Ptr: | ||||
| 				if fieldValue.Pointer() == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if col.IsDeleted || col.IsCreated { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if len(session.statement.columnMap) > 0 { | ||||
| 			if !session.statement.columnMap.contain(col.Name) { | ||||
| 				continue | ||||
| 			} else if _, ok := session.statement.incrColumns[col.Name]; ok { | ||||
| 				continue | ||||
| 			} else if _, ok := session.statement.decrColumns[col.Name]; ok { | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// !evalphobia! set fieldValue as nil when column is nullable and zero-value | ||||
| 		if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok { | ||||
| 			if col.Nullable && isZero(fieldValue.Interface()) { | ||||
| 				var nilValue *int | ||||
| 				fieldValue = reflect.ValueOf(nilValue) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if col.IsUpdated && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ { | ||||
| 			// if time is non-empty, then set to auto time | ||||
| 			val, t := session.engine.nowTime(col) | ||||
| 			args = append(args, val) | ||||
|  | ||||
| 			var colName = col.Name | ||||
| 			session.afterClosures = append(session.afterClosures, func(bean interface{}) { | ||||
| 				col := table.GetColumn(colName) | ||||
| 				setColumnTime(bean, col, t) | ||||
| 			}) | ||||
| 		} else if col.IsVersion && session.statement.checkVersion { | ||||
| 			args = append(args, 1) | ||||
| 		} else { | ||||
| 			arg, err := session.value2Interface(col, fieldValue) | ||||
| 			if err != nil { | ||||
| 				return colNames, args, err | ||||
| 			} | ||||
| 			args = append(args, arg) | ||||
| 		} | ||||
|  | ||||
| 		colNames = append(colNames, session.engine.Quote(col.Name)+" = ?") | ||||
| 	} | ||||
| 	return colNames, args, nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										280
									
								
								vendor/github.com/go-xorm/xorm/statement.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										280
									
								
								vendor/github.com/go-xorm/xorm/statement.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -5,7 +5,6 @@ | ||||
| package xorm | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"database/sql/driver" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| @@ -18,21 +17,6 @@ import ( | ||||
| 	"github.com/go-xorm/core" | ||||
| ) | ||||
|  | ||||
| type incrParam struct { | ||||
| 	colName string | ||||
| 	arg     interface{} | ||||
| } | ||||
|  | ||||
| type decrParam struct { | ||||
| 	colName string | ||||
| 	arg     interface{} | ||||
| } | ||||
|  | ||||
| type exprParam struct { | ||||
| 	colName string | ||||
| 	expr    string | ||||
| } | ||||
|  | ||||
| // Statement save all the sql info for executing SQL | ||||
| type Statement struct { | ||||
| 	RefTable        *core.Table | ||||
| @@ -47,7 +31,6 @@ type Statement struct { | ||||
| 	HavingStr       string | ||||
| 	ColumnStr       string | ||||
| 	selectStr       string | ||||
| 	columnMap       map[string]bool | ||||
| 	useAllCols      bool | ||||
| 	OmitStr         string | ||||
| 	AltTableName    string | ||||
| @@ -67,6 +50,8 @@ type Statement struct { | ||||
| 	allUseBool      bool | ||||
| 	checkVersion    bool | ||||
| 	unscoped        bool | ||||
| 	columnMap       columnMap | ||||
| 	omitColumnMap   columnMap | ||||
| 	mustColumnMap   map[string]bool | ||||
| 	nullableMap     map[string]bool | ||||
| 	incrColumns     map[string]incrParam | ||||
| @@ -89,7 +74,8 @@ func (statement *Statement) Init() { | ||||
| 	statement.HavingStr = "" | ||||
| 	statement.ColumnStr = "" | ||||
| 	statement.OmitStr = "" | ||||
| 	statement.columnMap = make(map[string]bool) | ||||
| 	statement.columnMap = columnMap{} | ||||
| 	statement.omitColumnMap = columnMap{} | ||||
| 	statement.AltTableName = "" | ||||
| 	statement.tableName = "" | ||||
| 	statement.idParam = nil | ||||
| @@ -221,34 +207,33 @@ func (statement *Statement) setRefValue(v reflect.Value) error { | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	statement.tableName = statement.Engine.tbName(v) | ||||
| 	statement.tableName = statement.Engine.TableName(v, true) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // 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) | ||||
| 	t := v.Type() | ||||
| 	if t.Kind() == reflect.String { | ||||
| 		statement.AltTableName = tableNameOrBean.(string) | ||||
| 	} else if t.Kind() == reflect.Struct { | ||||
| 		var err error | ||||
| 		statement.RefTable, err = statement.Engine.autoMapType(v) | ||||
| 		if err != nil { | ||||
| 			statement.Engine.logger.Error(err) | ||||
| 			return statement | ||||
| 		} | ||||
| 		statement.AltTableName = statement.Engine.tbName(v) | ||||
| func (statement *Statement) setRefBean(bean interface{}) error { | ||||
| 	var err error | ||||
| 	statement.RefTable, err = statement.Engine.autoMapType(rValue(bean)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return statement | ||||
| 	statement.tableName = statement.Engine.TableName(bean, true) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Auto generating update columnes and values according a struct | ||||
| func buildUpdates(engine *Engine, table *core.Table, bean interface{}, | ||||
| 	includeVersion bool, includeUpdated bool, includeNil bool, | ||||
| 	includeAutoIncr bool, allUseBool bool, useAllCols bool, | ||||
| 	mustColumnMap map[string]bool, nullableMap map[string]bool, | ||||
| 	columnMap map[string]bool, update, unscoped bool) ([]string, []interface{}) { | ||||
| func (statement *Statement) buildUpdates(bean interface{}, | ||||
| 	includeVersion, includeUpdated, includeNil, | ||||
| 	includeAutoIncr, update bool) ([]string, []interface{}) { | ||||
| 	engine := statement.Engine | ||||
| 	table := statement.RefTable | ||||
| 	allUseBool := statement.allUseBool | ||||
| 	useAllCols := statement.useAllCols | ||||
| 	mustColumnMap := statement.mustColumnMap | ||||
| 	nullableMap := statement.nullableMap | ||||
| 	columnMap := statement.columnMap | ||||
| 	omitColumnMap := statement.omitColumnMap | ||||
| 	unscoped := statement.unscoped | ||||
|  | ||||
| 	var colNames = make([]string, 0) | ||||
| 	var args = make([]interface{}, 0) | ||||
| @@ -268,7 +253,14 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, | ||||
| 		if col.IsDeleted && !unscoped { | ||||
| 			continue | ||||
| 		} | ||||
| 		if use, ok := columnMap[strings.ToLower(col.Name)]; ok && !use { | ||||
| 		if omitColumnMap.contain(col.Name) { | ||||
| 			continue | ||||
| 		} | ||||
| 		if len(columnMap) > 0 && !columnMap.contain(col.Name) { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if col.MapType == core.ONLYFROMDB { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| @@ -604,17 +596,10 @@ func (statement *Statement) col2NewColsWithQuote(columns ...string) []string { | ||||
| } | ||||
|  | ||||
| func (statement *Statement) colmap2NewColsWithQuote() []string { | ||||
| 	newColumns := make([]string, 0, len(statement.columnMap)) | ||||
| 	for col := range statement.columnMap { | ||||
| 		fields := strings.Split(strings.TrimSpace(col), ".") | ||||
| 		if len(fields) == 1 { | ||||
| 			newColumns = append(newColumns, statement.Engine.quote(fields[0])) | ||||
| 		} else if len(fields) == 2 { | ||||
| 			newColumns = append(newColumns, statement.Engine.quote(fields[0])+"."+ | ||||
| 				statement.Engine.quote(fields[1])) | ||||
| 		} else { | ||||
| 			panic(errors.New("unwanted colnames")) | ||||
| 		} | ||||
| 	newColumns := make([]string, len(statement.columnMap), len(statement.columnMap)) | ||||
| 	copy(newColumns, statement.columnMap) | ||||
| 	for i := 0; i < len(statement.columnMap); i++ { | ||||
| 		newColumns[i] = statement.Engine.Quote(newColumns[i]) | ||||
| 	} | ||||
| 	return newColumns | ||||
| } | ||||
| @@ -642,10 +627,11 @@ func (statement *Statement) Select(str string) *Statement { | ||||
| func (statement *Statement) Cols(columns ...string) *Statement { | ||||
| 	cols := col2NewCols(columns...) | ||||
| 	for _, nc := range cols { | ||||
| 		statement.columnMap[strings.ToLower(nc)] = true | ||||
| 		statement.columnMap.add(nc) | ||||
| 	} | ||||
|  | ||||
| 	newColumns := statement.colmap2NewColsWithQuote() | ||||
|  | ||||
| 	statement.ColumnStr = strings.Join(newColumns, ", ") | ||||
| 	statement.ColumnStr = strings.Replace(statement.ColumnStr, statement.Engine.quote("*"), "*", -1) | ||||
| 	return statement | ||||
| @@ -680,7 +666,7 @@ func (statement *Statement) UseBool(columns ...string) *Statement { | ||||
| func (statement *Statement) Omit(columns ...string) { | ||||
| 	newColumns := col2NewCols(columns...) | ||||
| 	for _, nc := range newColumns { | ||||
| 		statement.columnMap[strings.ToLower(nc)] = false | ||||
| 		statement.omitColumnMap = append(statement.omitColumnMap, nc) | ||||
| 	} | ||||
| 	statement.OmitStr = statement.Engine.Quote(strings.Join(newColumns, statement.Engine.Quote(", "))) | ||||
| } | ||||
| @@ -719,10 +705,9 @@ func (statement *Statement) OrderBy(order string) *Statement { | ||||
|  | ||||
| // Desc generate `ORDER BY xx DESC` | ||||
| func (statement *Statement) Desc(colNames ...string) *Statement { | ||||
| 	var buf bytes.Buffer | ||||
| 	fmt.Fprintf(&buf, statement.OrderStr) | ||||
| 	var buf builder.StringBuilder | ||||
| 	if len(statement.OrderStr) > 0 { | ||||
| 		fmt.Fprint(&buf, ", ") | ||||
| 		fmt.Fprint(&buf, statement.OrderStr, ", ") | ||||
| 	} | ||||
| 	newColNames := statement.col2NewColsWithQuote(colNames...) | ||||
| 	fmt.Fprintf(&buf, "%v DESC", strings.Join(newColNames, " DESC, ")) | ||||
| @@ -732,10 +717,9 @@ func (statement *Statement) Desc(colNames ...string) *Statement { | ||||
|  | ||||
| // Asc provide asc order by query condition, the input parameters are columns. | ||||
| func (statement *Statement) Asc(colNames ...string) *Statement { | ||||
| 	var buf bytes.Buffer | ||||
| 	fmt.Fprintf(&buf, statement.OrderStr) | ||||
| 	var buf builder.StringBuilder | ||||
| 	if len(statement.OrderStr) > 0 { | ||||
| 		fmt.Fprint(&buf, ", ") | ||||
| 		fmt.Fprint(&buf, statement.OrderStr, ", ") | ||||
| 	} | ||||
| 	newColNames := statement.col2NewColsWithQuote(colNames...) | ||||
| 	fmt.Fprintf(&buf, "%v ASC", strings.Join(newColNames, " ASC, ")) | ||||
| @@ -743,48 +727,35 @@ func (statement *Statement) Asc(colNames ...string) *Statement { | ||||
| 	return statement | ||||
| } | ||||
|  | ||||
| // 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) | ||||
| 	t := v.Type() | ||||
| 	if t.Kind() == reflect.Struct { | ||||
| 		var err error | ||||
| 		statement.RefTable, err = statement.Engine.autoMapType(v) | ||||
| 		if err != nil { | ||||
| 			statement.Engine.logger.Error(err) | ||||
| 			return statement | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	statement.AltTableName = statement.Engine.TableName(tableNameOrBean, true) | ||||
| 	return statement | ||||
| } | ||||
|  | ||||
| // Join The joinOP should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN | ||||
| func (statement *Statement) Join(joinOP string, tablename interface{}, condition string, args ...interface{}) *Statement { | ||||
| 	var buf bytes.Buffer | ||||
| 	var buf builder.StringBuilder | ||||
| 	if len(statement.JoinStr) > 0 { | ||||
| 		fmt.Fprintf(&buf, "%v %v JOIN ", statement.JoinStr, joinOP) | ||||
| 	} else { | ||||
| 		fmt.Fprintf(&buf, "%v JOIN ", joinOP) | ||||
| 	} | ||||
|  | ||||
| 	switch tablename.(type) { | ||||
| 	case []string: | ||||
| 		t := tablename.([]string) | ||||
| 		if len(t) > 1 { | ||||
| 			fmt.Fprintf(&buf, "%v AS %v", statement.Engine.Quote(t[0]), statement.Engine.Quote(t[1])) | ||||
| 		} else if len(t) == 1 { | ||||
| 			fmt.Fprintf(&buf, statement.Engine.Quote(t[0])) | ||||
| 		} | ||||
| 	case []interface{}: | ||||
| 		t := tablename.([]interface{}) | ||||
| 		l := len(t) | ||||
| 		var table string | ||||
| 		if l > 0 { | ||||
| 			f := t[0] | ||||
| 			v := rValue(f) | ||||
| 			t := v.Type() | ||||
| 			if t.Kind() == reflect.String { | ||||
| 				table = f.(string) | ||||
| 			} else if t.Kind() == reflect.Struct { | ||||
| 				table = statement.Engine.tbName(v) | ||||
| 			} | ||||
| 		} | ||||
| 		if l > 1 { | ||||
| 			fmt.Fprintf(&buf, "%v AS %v", statement.Engine.Quote(table), | ||||
| 				statement.Engine.Quote(fmt.Sprintf("%v", t[1]))) | ||||
| 		} else if l == 1 { | ||||
| 			fmt.Fprintf(&buf, statement.Engine.Quote(table)) | ||||
| 		} | ||||
| 	default: | ||||
| 		fmt.Fprintf(&buf, statement.Engine.Quote(fmt.Sprintf("%v", tablename))) | ||||
| 	} | ||||
| 	tbName := statement.Engine.TableName(tablename, true) | ||||
|  | ||||
| 	fmt.Fprintf(&buf, " ON %v", condition) | ||||
| 	fmt.Fprintf(&buf, "%s ON %v", tbName, condition) | ||||
| 	statement.JoinStr = buf.String() | ||||
| 	statement.joinArgs = append(statement.joinArgs, args...) | ||||
| 	return statement | ||||
| @@ -809,18 +780,20 @@ func (statement *Statement) Unscoped() *Statement { | ||||
| } | ||||
|  | ||||
| func (statement *Statement) genColumnStr() string { | ||||
| 	var buf bytes.Buffer | ||||
| 	if statement.RefTable == nil { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	var buf builder.StringBuilder | ||||
| 	columns := statement.RefTable.Columns() | ||||
|  | ||||
| 	for _, col := range columns { | ||||
| 		if statement.OmitStr != "" { | ||||
| 			if _, ok := getFlagForColumn(statement.columnMap, col); ok { | ||||
| 				continue | ||||
| 			} | ||||
| 		if statement.omitColumnMap.contain(col.Name) { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if len(statement.columnMap) > 0 && !statement.columnMap.contain(col.Name) { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if col.MapType == core.ONLYTODB { | ||||
| @@ -831,10 +804,6 @@ func (statement *Statement) genColumnStr() string { | ||||
| 			buf.WriteString(", ") | ||||
| 		} | ||||
|  | ||||
| 		if col.IsPrimaryKey && statement.Engine.Dialect().DBType() == "ql" { | ||||
| 			buf.WriteString("id() AS ") | ||||
| 		} | ||||
|  | ||||
| 		if statement.JoinStr != "" { | ||||
| 			if statement.TableAlias != "" { | ||||
| 				buf.WriteString(statement.TableAlias) | ||||
| @@ -859,11 +828,13 @@ func (statement *Statement) genCreateTableSQL() string { | ||||
| func (statement *Statement) genIndexSQL() []string { | ||||
| 	var sqls []string | ||||
| 	tbName := statement.TableName() | ||||
| 	quote := statement.Engine.Quote | ||||
| 	for idxName, index := range statement.RefTable.Indexes { | ||||
| 	for _, index := range statement.RefTable.Indexes { | ||||
| 		if index.Type == core.IndexType { | ||||
| 			sql := fmt.Sprintf("CREATE INDEX %v ON %v (%v);", quote(indexName(tbName, idxName)), | ||||
| 				quote(tbName), quote(strings.Join(index.Cols, quote(",")))) | ||||
| 			sql := statement.Engine.dialect.CreateIndexSql(tbName, index) | ||||
| 			/*idxTBName := strings.Replace(tbName, ".", "_", -1) | ||||
| 			idxTBName = strings.Replace(idxTBName, `"`, "", -1) | ||||
| 			sql := fmt.Sprintf("CREATE INDEX %v ON %v (%v);", quote(indexName(idxTBName, idxName)), | ||||
| 				quote(tbName), quote(strings.Join(index.Cols, quote(","))))*/ | ||||
| 			sqls = append(sqls, sql) | ||||
| 		} | ||||
| 	} | ||||
| @@ -889,16 +860,18 @@ func (statement *Statement) genUniqueSQL() []string { | ||||
| func (statement *Statement) genDelIndexSQL() []string { | ||||
| 	var sqls []string | ||||
| 	tbName := statement.TableName() | ||||
| 	idxPrefixName := strings.Replace(tbName, `"`, "", -1) | ||||
| 	idxPrefixName = strings.Replace(idxPrefixName, `.`, "_", -1) | ||||
| 	for idxName, index := range statement.RefTable.Indexes { | ||||
| 		var rIdxName string | ||||
| 		if index.Type == core.UniqueType { | ||||
| 			rIdxName = uniqueName(tbName, idxName) | ||||
| 			rIdxName = uniqueName(idxPrefixName, idxName) | ||||
| 		} else if index.Type == core.IndexType { | ||||
| 			rIdxName = indexName(tbName, idxName) | ||||
| 			rIdxName = indexName(idxPrefixName, idxName) | ||||
| 		} | ||||
| 		sql := fmt.Sprintf("DROP INDEX %v", statement.Engine.Quote(rIdxName)) | ||||
| 		sql := fmt.Sprintf("DROP INDEX %v", statement.Engine.Quote(statement.Engine.TableName(rIdxName, true))) | ||||
| 		if statement.Engine.dialect.IndexOnTable() { | ||||
| 			sql += fmt.Sprintf(" ON %v", statement.Engine.Quote(statement.TableName())) | ||||
| 			sql += fmt.Sprintf(" ON %v", statement.Engine.Quote(tbName)) | ||||
| 		} | ||||
| 		sqls = append(sqls, sql) | ||||
| 	} | ||||
| @@ -949,7 +922,7 @@ func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{}, | ||||
| 	v := rValue(bean) | ||||
| 	isStruct := v.Kind() == reflect.Struct | ||||
| 	if isStruct { | ||||
| 		statement.setRefValue(v) | ||||
| 		statement.setRefBean(bean) | ||||
| 	} | ||||
|  | ||||
| 	var columnStr = statement.ColumnStr | ||||
| @@ -982,13 +955,17 @@ func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{}, | ||||
| 		if err := statement.mergeConds(bean); err != nil { | ||||
| 			return "", nil, err | ||||
| 		} | ||||
| 	} else { | ||||
| 		if err := statement.processIDParam(); err != nil { | ||||
| 			return "", nil, err | ||||
| 		} | ||||
| 	} | ||||
| 	condSQL, condArgs, err := builder.ToSQL(statement.cond) | ||||
| 	if err != nil { | ||||
| 		return "", nil, err | ||||
| 	} | ||||
|  | ||||
| 	sqlStr, err := statement.genSelectSQL(columnStr, condSQL) | ||||
| 	sqlStr, err := statement.genSelectSQL(columnStr, condSQL, true, true) | ||||
| 	if err != nil { | ||||
| 		return "", nil, err | ||||
| 	} | ||||
| @@ -1001,7 +978,7 @@ func (statement *Statement) genCountSQL(beans ...interface{}) (string, []interfa | ||||
| 	var condArgs []interface{} | ||||
| 	var err error | ||||
| 	if len(beans) > 0 { | ||||
| 		statement.setRefValue(rValue(beans[0])) | ||||
| 		statement.setRefBean(beans[0]) | ||||
| 		condSQL, condArgs, err = statement.genConds(beans[0]) | ||||
| 	} else { | ||||
| 		condSQL, condArgs, err = builder.ToSQL(statement.cond) | ||||
| @@ -1018,7 +995,7 @@ func (statement *Statement) genCountSQL(beans ...interface{}) (string, []interfa | ||||
| 			selectSQL = "count(*)" | ||||
| 		} | ||||
| 	} | ||||
| 	sqlStr, err := statement.genSelectSQL(selectSQL, condSQL) | ||||
| 	sqlStr, err := statement.genSelectSQL(selectSQL, condSQL, false, false) | ||||
| 	if err != nil { | ||||
| 		return "", nil, err | ||||
| 	} | ||||
| @@ -1027,7 +1004,7 @@ func (statement *Statement) genCountSQL(beans ...interface{}) (string, []interfa | ||||
| } | ||||
|  | ||||
| func (statement *Statement) genSumSQL(bean interface{}, columns ...string) (string, []interface{}, error) { | ||||
| 	statement.setRefValue(rValue(bean)) | ||||
| 	statement.setRefBean(bean) | ||||
|  | ||||
| 	var sumStrs = make([]string, 0, len(columns)) | ||||
| 	for _, colName := range columns { | ||||
| @@ -1043,7 +1020,7 @@ func (statement *Statement) genSumSQL(bean interface{}, columns ...string) (stri | ||||
| 		return "", nil, err | ||||
| 	} | ||||
|  | ||||
| 	sqlStr, err := statement.genSelectSQL(sumSelect, condSQL) | ||||
| 	sqlStr, err := statement.genSelectSQL(sumSelect, condSQL, true, true) | ||||
| 	if err != nil { | ||||
| 		return "", nil, err | ||||
| 	} | ||||
| @@ -1051,27 +1028,20 @@ func (statement *Statement) genSumSQL(bean interface{}, columns ...string) (stri | ||||
| 	return sqlStr, append(statement.joinArgs, condArgs...), nil | ||||
| } | ||||
|  | ||||
| func (statement *Statement) genSelectSQL(columnStr, condSQL string) (a string, err error) { | ||||
| 	var distinct string | ||||
| func (statement *Statement) genSelectSQL(columnStr, condSQL string, needLimit, needOrderBy bool) (string, error) { | ||||
| 	var ( | ||||
| 		distinct                  string | ||||
| 		dialect                   = statement.Engine.Dialect() | ||||
| 		quote                     = statement.Engine.Quote | ||||
| 		fromStr                   = " FROM " | ||||
| 		top, mssqlCondi, whereStr string | ||||
| 	) | ||||
| 	if statement.IsDistinct && !strings.HasPrefix(columnStr, "count") { | ||||
| 		distinct = "DISTINCT " | ||||
| 	} | ||||
|  | ||||
| 	var dialect = statement.Engine.Dialect() | ||||
| 	var quote = statement.Engine.Quote | ||||
| 	var top string | ||||
| 	var mssqlCondi string | ||||
|  | ||||
| 	if err := statement.processIDParam(); err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	var buf bytes.Buffer | ||||
| 	if len(condSQL) > 0 { | ||||
| 		fmt.Fprintf(&buf, " WHERE %v", condSQL) | ||||
| 		whereStr = " WHERE " + condSQL | ||||
| 	} | ||||
| 	var whereStr = buf.String() | ||||
| 	var fromStr = " FROM " | ||||
|  | ||||
| 	if dialect.DBType() == core.MSSQL && strings.Contains(statement.TableName(), "..") { | ||||
| 		fromStr += statement.TableName() | ||||
| @@ -1118,9 +1088,10 @@ func (statement *Statement) genSelectSQL(columnStr, condSQL string) (a string, e | ||||
| 			} | ||||
|  | ||||
| 			var orderStr string | ||||
| 			if len(statement.OrderStr) > 0 { | ||||
| 			if needOrderBy && len(statement.OrderStr) > 0 { | ||||
| 				orderStr = " ORDER BY " + statement.OrderStr | ||||
| 			} | ||||
|  | ||||
| 			var groupStr string | ||||
| 			if len(statement.GroupByStr) > 0 { | ||||
| 				groupStr = " GROUP BY " + statement.GroupByStr | ||||
| @@ -1130,45 +1101,50 @@ func (statement *Statement) genSelectSQL(columnStr, condSQL string) (a string, e | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// !nashtsai! REVIEW Sprintf is considered slowest mean of string concatnation, better to work with builder pattern | ||||
| 	a = fmt.Sprintf("SELECT %v%v%v%v%v", distinct, top, columnStr, fromStr, whereStr) | ||||
| 	var buf builder.StringBuilder | ||||
| 	fmt.Fprintf(&buf, "SELECT %v%v%v%v%v", distinct, top, columnStr, fromStr, whereStr) | ||||
| 	if len(mssqlCondi) > 0 { | ||||
| 		if len(whereStr) > 0 { | ||||
| 			a += " AND " + mssqlCondi | ||||
| 			fmt.Fprint(&buf, " AND ", mssqlCondi) | ||||
| 		} else { | ||||
| 			a += " WHERE " + mssqlCondi | ||||
| 			fmt.Fprint(&buf, " WHERE ", mssqlCondi) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if statement.GroupByStr != "" { | ||||
| 		a = fmt.Sprintf("%v GROUP BY %v", a, statement.GroupByStr) | ||||
| 		fmt.Fprint(&buf, " GROUP BY ", statement.GroupByStr) | ||||
| 	} | ||||
| 	if statement.HavingStr != "" { | ||||
| 		a = fmt.Sprintf("%v %v", a, statement.HavingStr) | ||||
| 		fmt.Fprint(&buf, " ", statement.HavingStr) | ||||
| 	} | ||||
| 	if statement.OrderStr != "" { | ||||
| 		a = fmt.Sprintf("%v ORDER BY %v", a, statement.OrderStr) | ||||
| 	if needOrderBy && statement.OrderStr != "" { | ||||
| 		fmt.Fprint(&buf, " ORDER BY ", statement.OrderStr) | ||||
| 	} | ||||
| 	if dialect.DBType() != core.MSSQL && dialect.DBType() != core.ORACLE { | ||||
| 		if statement.Start > 0 { | ||||
| 			a = fmt.Sprintf("%v LIMIT %v OFFSET %v", a, statement.LimitN, statement.Start) | ||||
| 		} else if statement.LimitN > 0 { | ||||
| 			a = fmt.Sprintf("%v LIMIT %v", a, statement.LimitN) | ||||
| 		} | ||||
| 	} else if dialect.DBType() == core.ORACLE { | ||||
| 		if statement.Start != 0 || statement.LimitN != 0 { | ||||
| 			a = fmt.Sprintf("SELECT %v FROM (SELECT %v,ROWNUM RN FROM (%v) at WHERE ROWNUM <= %d) aat WHERE RN > %d", columnStr, columnStr, a, statement.Start+statement.LimitN, statement.Start) | ||||
| 	if needLimit { | ||||
| 		if dialect.DBType() != core.MSSQL && dialect.DBType() != core.ORACLE { | ||||
| 			if statement.Start > 0 { | ||||
| 				fmt.Fprintf(&buf, " LIMIT %v OFFSET %v", statement.LimitN, statement.Start) | ||||
| 			} else if statement.LimitN > 0 { | ||||
| 				fmt.Fprint(&buf, " LIMIT ", statement.LimitN) | ||||
| 			} | ||||
| 		} else if dialect.DBType() == core.ORACLE { | ||||
| 			if statement.Start != 0 || statement.LimitN != 0 { | ||||
| 				oldString := buf.String() | ||||
| 				buf.Reset() | ||||
| 				fmt.Fprintf(&buf, "SELECT %v FROM (SELECT %v,ROWNUM RN FROM (%v) at WHERE ROWNUM <= %d) aat WHERE RN > %d", | ||||
| 					columnStr, columnStr, oldString, statement.Start+statement.LimitN, statement.Start) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if statement.IsForUpdate { | ||||
| 		a = dialect.ForUpdateSql(a) | ||||
| 		return dialect.ForUpdateSql(buf.String()), nil | ||||
| 	} | ||||
|  | ||||
| 	return | ||||
| 	return buf.String(), nil | ||||
| } | ||||
|  | ||||
| func (statement *Statement) processIDParam() error { | ||||
| 	if statement.idParam == nil { | ||||
| 	if statement.idParam == nil || statement.RefTable == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
|   | ||||
							
								
								
									
										12
									
								
								vendor/github.com/go-xorm/xorm/xorm.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/go-xorm/xorm/xorm.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -17,7 +17,7 @@ import ( | ||||
|  | ||||
| const ( | ||||
| 	// Version show the xorm's version | ||||
| 	Version string = "0.6.4.0910" | ||||
| 	Version string = "0.7.0.0504" | ||||
| ) | ||||
|  | ||||
| func regDrvsNDialects() bool { | ||||
| @@ -31,7 +31,7 @@ func regDrvsNDialects() bool { | ||||
| 		"mysql":    {"mysql", func() core.Driver { return &mysqlDriver{} }, func() core.Dialect { return &mysql{} }}, | ||||
| 		"mymysql":  {"mysql", func() core.Driver { return &mymysqlDriver{} }, func() core.Dialect { return &mysql{} }}, | ||||
| 		"postgres": {"postgres", func() core.Driver { return &pqDriver{} }, func() core.Dialect { return &postgres{} }}, | ||||
| 		"pgx":      {"postgres", func() core.Driver { return &pqDriver{} }, func() core.Dialect { return &postgres{} }}, | ||||
| 		"pgx":      {"postgres", func() core.Driver { return &pqDriverPgx{} }, func() core.Dialect { return &postgres{} }}, | ||||
| 		"sqlite3":  {"sqlite3", func() core.Driver { return &sqlite3Driver{} }, func() core.Dialect { return &sqlite3{} }}, | ||||
| 		"oci8":     {"oracle", func() core.Driver { return &oci8Driver{} }, func() core.Dialect { return &oracle{} }}, | ||||
| 		"goracle":  {"oracle", func() core.Driver { return &goracleDriver{} }, func() core.Dialect { return &oracle{} }}, | ||||
| @@ -90,6 +90,7 @@ func NewEngine(driverName string, dataSourceName string) (*Engine, error) { | ||||
| 		TagIdentifier: "xorm", | ||||
| 		TZLocation:    time.Local, | ||||
| 		tagHandlers:   defaultTagHandlers, | ||||
| 		cachers:       make(map[string]core.Cacher), | ||||
| 	} | ||||
|  | ||||
| 	if uri.DbType == core.SQLITE { | ||||
| @@ -108,6 +109,13 @@ func NewEngine(driverName string, dataSourceName string) (*Engine, error) { | ||||
| 	return engine, nil | ||||
| } | ||||
|  | ||||
| // NewEngineWithParams new a db manager with params. The params will be passed to dialect. | ||||
| func NewEngineWithParams(driverName string, dataSourceName string, params map[string]string) (*Engine, error) { | ||||
| 	engine, err := NewEngine(driverName, dataSourceName) | ||||
| 	engine.dialect.SetParams(params) | ||||
| 	return engine, err | ||||
| } | ||||
|  | ||||
| // Clone clone an engine | ||||
| func (engine *Engine) Clone() (*Engine, error) { | ||||
| 	return NewEngine(engine.DriverName(), engine.DataSourceName()) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user