Merge branch 'master' of github.com:go-xorm/xorm

This commit is contained in:
Nash Tsai 2014-09-09 09:50:11 +08:00
commit e19faeb670
11 changed files with 1470 additions and 64 deletions

48
doc.go
View File

@ -19,17 +19,17 @@ Firstly, we should new an engine for a database
Method NewEngine's parameters is the same as sql.Open. It depends Method NewEngine's parameters is the same as sql.Open. It depends
drivers' implementation. drivers' implementation.
Generally, one engine is enough. You can set it as package variable. Generally, one engine for an application is enough. You can set it as package variable.
Raw Methods Raw Methods
Xorm also support raw sql execution: Xorm also support raw sql execution:
1. query sql, the returned results is []map[string][]byte 1. query a SQL string, the returned results is []map[string][]byte
results, err := engine.Query("select * from user") results, err := engine.Query("select * from user")
2. exec sql, the returned results 2. execute a SQL string, the returned results
affected, err := engine.Exec("update user set .... where ...") affected, err := engine.Exec("update user set .... where ...")
@ -57,29 +57,31 @@ There are 7 major ORM methods and many helpful methods to use to operate databas
3. Query multiple records from database 3. Query multiple records from database
err := engine.Find(...) sliceOfStructs := new(Struct)
err := engine.Find(sliceOfStructs)
// SELECT * FROM user // SELECT * FROM user
4. Query multiple records and record by record handle, there two methods, one is Iterate, 4. Query multiple records and record by record handle, there two methods, one is Iterate,
another is Raws another is Raws
raws, err := engine.Raws(...)
// SELECT * FROM user
for raws.Next() {
raws.Scan(bean)
}
err := engine.Iterate(...) err := engine.Iterate(...)
// SELECT * FROM user // SELECT * FROM user
raws, err := engine.Raws(...)
// SELECT * FROM user
bean := new(Struct)
for raws.Next() {
err = raws.Scan(bean)
}
5. Update one or more records 5. Update one or more records
affected, err := engine.Update(&user) affected, err := engine.Update(&user)
// UPDATE user SET // UPDATE user SET ...
6. Delete one or more records 6. Delete one or more records, Delete MUST has conditon
affected, err := engine.Delete(&user) affected, err := engine.Where(...).Delete(&user)
// DELETE FROM user Where ... // DELETE FROM user Where ...
7. Count records 7. Count records
@ -89,14 +91,19 @@ another is Raws
Conditions Conditions
The above 7 methods could use with condition methods. The above 7 methods could use with condition methods chainable.
Attention: the above 7 methods should be the last chainable method.
1. Id, In 1. Id, In
engine.Id(1).Get(&user) engine.Id(1).Get(&user) // for single primary key
// SELECT * FROM user WHERE id = 1 // SELECT * FROM user WHERE id = 1
engine.Id(core.PK{1, 2}).Get(&user) // for composite primary keys
// SELECT * FROM user WHERE id1 = 1 AND id2 = 2
engine.In("id", 1, 2, 3).Find(&users) engine.In("id", 1, 2, 3).Find(&users)
// SELECT * FROM user WHERE id IN (1, 2, 3) // SELECT * FROM user WHERE id IN (1, 2, 3)
engine.In("id", []int{1, 2, 3})
// SELECT * FROM user WHERE id IN (1, 2, 3)
2. Where, And, Or 2. Where, And, Or
@ -114,10 +121,11 @@ The above 7 methods could use with condition methods.
engine.Limit().Find() engine.Limit().Find()
// SELECT * FROM user LIMIT .. OFFSET .. // SELECT * FROM user LIMIT .. OFFSET ..
engine.Top().Find() engine.Top(5).Find()
// SELECT * FROM user LIMIT .. // SELECT TOP 5 * FROM user // for mssql
// SELECT * FROM user LIMIT .. OFFSET 0 //for other databases
5. Sql 5. Sql, let you custom SQL
engine.Sql("select * from user").Find() engine.Sql("select * from user").Find()
@ -125,8 +133,12 @@ The above 7 methods could use with condition methods.
engine.Cols("col1, col2").Find() engine.Cols("col1, col2").Find()
// SELECT col1, col2 FROM user // SELECT col1, col2 FROM user
engine.Cols("col1", "col2").Where().Update(user)
// UPDATE user set col1 = ?, col2 = ? Where ...
engine.Omit("col1").Find() engine.Omit("col1").Find()
// SELECT col2, col3 FROM user // SELECT col2, col3 FROM user
engine.Omit("col1").Insert()
// INSERT INTO table (non-col1) VALUES ()
engine.Distinct("col1").Find() engine.Distinct("col1").Find()
// SELECT DISTINCT col1 FROM user // SELECT DISTINCT col1 FROM user

View File

@ -346,7 +346,6 @@ Notice: If you want to use transaction on inserting, you should use session.Begi
### 5.1. Chainable APIs for Queries, Execusions and Aggregations ### 5.1. Chainable APIs for Queries, Execusions and Aggregations
Queries and Aggregations is basically formed by using `Get`, `Find`, `Count` methods, with conjunction of following chainable APIs to form conditions, grouping and ordering: Queries and Aggregations is basically formed by using `Get`, `Find`, `Count` methods, with conjunction of following chainable APIs to form conditions, grouping and ordering:
查询和统计主要使用`Get`, `Find`, `Count`三个方法。在进行查询时可以使用多个方法来形成查询条件,条件函数如下:
* Id([]interface{}) * Id([]interface{})
Primary Key lookup Primary Key lookup
@ -535,16 +534,16 @@ affected, err := engine.Table(new(User)).Id(id).Update(map[string]interface{}{"a
``` ```
### 6.1.乐观锁 ### 6.1.Optimistic Lock
要使用乐观锁需要使用version标记 To enable object optimistic lock, add 'version' tag value:
type User struct { type User struct {
Id int64 Id int64
Name string Name string
Version int `xorm:"version"` Version int `xorm:"version"`
} }
在Insert时version标记的字段将会被设置为1在Update时Update的内容必须包含version原来的值。 The version starts with 1 when inserted to DB. For updating make sure originated version value is used for optimistic lock check.
```Go ```Go
var user User var user User

View File

@ -42,6 +42,14 @@ type Engine struct {
Logger core.ILogger Logger core.ILogger
TZLocation *time.Location TZLocation *time.Location
disableGlobalCache bool
}
func (engine *Engine) SetDisableGlobalCache(disable bool) {
if engine.disableGlobalCache != disable {
engine.disableGlobalCache = disable
}
} }
func (engine *Engine) DriverName() string { func (engine *Engine) DriverName() string {
@ -186,6 +194,30 @@ func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) {
} }
} }
func (engine *Engine) LogSQLQueryTime(sqlStr string, args interface{}, executionBlock func() (*core.Stmt, *core.Rows, error)) (*core.Stmt, *core.Rows, error) {
if engine.ShowDebug {
b4ExecTime := time.Now()
stmt, res, err := executionBlock()
execDuration := time.Since(b4ExecTime)
engine.LogDebugf("sql [%s] - args [%v] - query took: %vns", sqlStr, args, execDuration.Nanoseconds())
return stmt, res, err
} else {
return executionBlock()
}
}
func (engine *Engine) LogSQLExecutionTime(sqlStr string, args interface{}, executionBlock func() (sql.Result, error)) (sql.Result, error) {
if engine.ShowDebug {
b4ExecTime := time.Now()
res, err := executionBlock()
execDuration := time.Since(b4ExecTime)
engine.LogDebugf("sql [%s] - args [%v] - execution took: %vns", sqlStr, args, execDuration.Nanoseconds())
return res, err
} else {
return executionBlock()
}
}
// logging error // logging error
func (engine *Engine) overrideLogLevel(overrideLevel core.LogLevel) { func (engine *Engine) overrideLogLevel(overrideLevel core.LogLevel) {
logLevel := engine.Logger.Level() logLevel := engine.Logger.Level()
@ -380,7 +412,12 @@ func (engine *Engine) DumpAll(w io.Writer) error {
temp += fmt.Sprintf(", '%s'", d.(string)) temp += fmt.Sprintf(", '%s'", d.(string))
} }
} else if col.SQLType.IsNumeric() { } else if col.SQLType.IsNumeric() {
switch reflect.TypeOf(d).Kind() {
case reflect.Slice:
temp += fmt.Sprintf(", %s", string(d.([]byte))) temp += fmt.Sprintf(", %s", string(d.([]byte)))
default:
temp += fmt.Sprintf(", %v", d)
}
} else { } else {
s := fmt.Sprintf("%v", d) s := fmt.Sprintf("%v", d)
if strings.Contains(s, ":") || strings.Contains(s, "-") { if strings.Contains(s, ":") || strings.Contains(s, "-") {
@ -591,7 +628,7 @@ func (engine *Engine) autoMapType(v reflect.Value) *core.Table {
return table return table
} }
func (engine *Engine) autoMap(bean interface{}) *core.Table { func (engine *Engine) TableInfo(bean interface{}) *core.Table {
v := rValue(bean) v := rValue(bean)
return engine.autoMapType(v) return engine.autoMapType(v)
} }
@ -610,7 +647,10 @@ func addIndex(indexName string, table *core.Table, col *core.Column, indexType i
func (engine *Engine) newTable() *core.Table { func (engine *Engine) newTable() *core.Table {
table := core.NewEmptyTable() table := core.NewEmptyTable()
if !engine.disableGlobalCache {
table.Cacher = engine.Cacher table.Cacher = engine.Cacher
}
return table return table
} }
@ -639,6 +679,9 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
var idFieldColName string var idFieldColName string
var err error var err error
hasCacheTag := false
hasNoCacheTag := false
for i := 0; i < t.NumField(); i++ { for i := 0; i < t.NumField(); i++ {
tag := t.Field(i).Tag tag := t.Field(i).Tag
@ -733,6 +776,14 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
isUnique = true isUnique = true
case k == "NOTNULL": case k == "NOTNULL":
col.Nullable = false col.Nullable = false
case k == "CACHE":
if !hasCacheTag {
hasCacheTag = true
}
case k == "NOCACHE":
if !hasNoCacheTag {
hasNoCacheTag = true
}
case k == "NOT": case k == "NOT":
default: default:
if strings.HasPrefix(k, "'") && strings.HasSuffix(k, "'") { if strings.HasPrefix(k, "'") && strings.HasSuffix(k, "'") {
@ -841,7 +892,7 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
if fieldType.Kind() == reflect.Int64 && (col.FieldName == "Id" || strings.HasSuffix(col.FieldName, ".Id")) { if fieldType.Kind() == reflect.Int64 && (col.FieldName == "Id" || strings.HasSuffix(col.FieldName, ".Id")) {
idFieldColName = col.Name idFieldColName = col.Name
} }
} } // end for
if idFieldColName != "" && len(table.PrimaryKeys) == 0 { if idFieldColName != "" && len(table.PrimaryKeys) == 0 {
col := table.GetColumn(idFieldColName) col := table.GetColumn(idFieldColName)
@ -852,6 +903,20 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
table.AutoIncrement = col.Name table.AutoIncrement = col.Name
} }
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
} 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
}
}
if hasNoCacheTag {
engine.Logger.Info("no cache on table:", table.Name)
table.Cacher = nil
}
return table return table
} }
@ -900,7 +965,7 @@ func (engine *Engine) IsTableExist(bean interface{}) (bool, error) {
} }
func (engine *Engine) IdOf(bean interface{}) core.PK { func (engine *Engine) IdOf(bean interface{}) core.PK {
table := engine.autoMap(bean) table := engine.TableInfo(bean)
v := reflect.Indirect(reflect.ValueOf(bean)) v := reflect.Indirect(reflect.ValueOf(bean))
pk := make([]interface{}, len(table.PrimaryKeys)) pk := make([]interface{}, len(table.PrimaryKeys))
for i, col := range table.PKColumns() { for i, col := range table.PKColumns() {
@ -948,7 +1013,7 @@ func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
if t.Kind() != reflect.Struct { if t.Kind() != reflect.Struct {
return errors.New("error params") return errors.New("error params")
} }
table := engine.autoMap(bean) table := engine.TableInfo(bean)
cacher := table.Cacher cacher := table.Cacher
if cacher == nil { if cacher == nil {
cacher = engine.Cacher cacher = engine.Cacher
@ -967,7 +1032,7 @@ func (engine *Engine) ClearCache(beans ...interface{}) error {
if t.Kind() != reflect.Struct { if t.Kind() != reflect.Struct {
return errors.New("error params") return errors.New("error params")
} }
table := engine.autoMap(bean) table := engine.TableInfo(bean)
cacher := table.Cacher cacher := table.Cacher
if cacher == nil { if cacher == nil {
cacher = engine.Cacher cacher = engine.Cacher
@ -985,7 +1050,7 @@ func (engine *Engine) ClearCache(beans ...interface{}) error {
// If you change some field, you should change the database manually. // If you change some field, you should change the database manually.
func (engine *Engine) Sync(beans ...interface{}) error { func (engine *Engine) Sync(beans ...interface{}) error {
for _, bean := range beans { for _, bean := range beans {
table := engine.autoMap(bean) table := engine.TableInfo(bean)
s := engine.NewSession() s := engine.NewSession()
defer s.Close() defer s.Close()
@ -1084,7 +1149,7 @@ func (engine *Engine) Sync2(beans ...interface{}) error {
structTables := make([]*core.Table, 0) structTables := make([]*core.Table, 0)
for _, bean := range beans { for _, bean := range beans {
table := engine.autoMap(bean) table := engine.TableInfo(bean)
structTables = append(structTables, table) structTables = append(structTables, table)
var oriTable *core.Table var oriTable *core.Table
@ -1126,16 +1191,19 @@ func (engine *Engine) Sync2(beans ...interface{}) error {
curType := engine.dialect.SqlType(oriCol) curType := engine.dialect.SqlType(oriCol)
if expectedType != curType { if expectedType != curType {
if expectedType == core.Text && if expectedType == core.Text &&
curType == core.Varchar { strings.HasPrefix(curType, core.Varchar) {
// currently only support mysql // currently only support mysql
if engine.dialect.DBType() == core.MYSQL { if engine.dialect.DBType() == core.MYSQL ||
engine.dialect.DBType() == core.POSTGRES {
engine.LogInfof("Table %s column %s change type from %s to %s\n",
table.Name, col.Name, curType, expectedType)
_, err = engine.Exec(engine.dialect.ModifyColumnSql(table.Name, col)) _, err = engine.Exec(engine.dialect.ModifyColumnSql(table.Name, col))
} else { } else {
engine.LogWarnf("Table %s Column %s db type is %s, struct type is %s\n", engine.LogWarnf("Table %s column %s db type is %s, struct type is %s\n",
table.Name, col.Name, curType, expectedType) table.Name, col.Name, curType, expectedType)
} }
} else { } else {
engine.LogWarnf("Table %s Column %s db type is %s, struct type is %s", engine.LogWarnf("Table %s column %s db type is %s, struct type is %s",
table.Name, col.Name, curType, expectedType) table.Name, col.Name, curType, expectedType)
} }
} }

View File

@ -13,6 +13,196 @@ import (
// RegisterDialect("mssql", &mssql{}) // RegisterDialect("mssql", &mssql{})
// } // }
var (
mssqlReservedWords = map[string]bool{
"ADD": true,
"EXTERNAL": true,
"PROCEDURE": true,
"ALL": true,
"FETCH": true,
"PUBLIC": true,
"ALTER": true,
"FILE": true,
"RAISERROR": true,
"AND": true,
"FILLFACTOR": true,
"READ": true,
"ANY": true,
"FOR": true,
"READTEXT": true,
"AS": true,
"FOREIGN": true,
"RECONFIGURE": true,
"ASC": true,
"FREETEXT": true,
"REFERENCES": true,
"AUTHORIZATION": true,
"FREETEXTTABLE": true,
"REPLICATION": true,
"BACKUP": true,
"FROM": true,
"RESTORE": true,
"BEGIN": true,
"FULL": true,
"RESTRICT": true,
"BETWEEN": true,
"FUNCTION": true,
"RETURN": true,
"BREAK": true,
"GOTO": true,
"REVERT": true,
"BROWSE": true,
"GRANT": true,
"REVOKE": true,
"BULK": true,
"GROUP": true,
"RIGHT": true,
"BY": true,
"HAVING": true,
"ROLLBACK": true,
"CASCADE": true,
"HOLDLOCK": true,
"ROWCOUNT": true,
"CASE": true,
"IDENTITY": true,
"ROWGUIDCOL": true,
"CHECK": true,
"IDENTITY_INSERT": true,
"RULE": true,
"CHECKPOINT": true,
"IDENTITYCOL": true,
"SAVE": true,
"CLOSE": true,
"IF": true,
"SCHEMA": true,
"CLUSTERED": true,
"IN": true,
"SECURITYAUDIT": true,
"COALESCE": true,
"INDEX": true,
"SELECT": true,
"COLLATE": true,
"INNER": true,
"SEMANTICKEYPHRASETABLE": true,
"COLUMN": true,
"INSERT": true,
"SEMANTICSIMILARITYDETAILSTABLE": true,
"COMMIT": true,
"INTERSECT": true,
"SEMANTICSIMILARITYTABLE": true,
"COMPUTE": true,
"INTO": true,
"SESSION_USER": true,
"CONSTRAINT": true,
"IS": true,
"SET": true,
"CONTAINS": true,
"JOIN": true,
"SETUSER": true,
"CONTAINSTABLE": true,
"KEY": true,
"SHUTDOWN": true,
"CONTINUE": true,
"KILL": true,
"SOME": true,
"CONVERT": true,
"LEFT": true,
"STATISTICS": true,
"CREATE": true,
"LIKE": true,
"SYSTEM_USER": true,
"CROSS": true,
"LINENO": true,
"TABLE": true,
"CURRENT": true,
"LOAD": true,
"TABLESAMPLE": true,
"CURRENT_DATE": true,
"MERGE": true,
"TEXTSIZE": true,
"CURRENT_TIME": true,
"NATIONAL": true,
"THEN": true,
"CURRENT_TIMESTAMP": true,
"NOCHECK": true,
"TO": true,
"CURRENT_USER": true,
"NONCLUSTERED": true,
"TOP": true,
"CURSOR": true,
"NOT": true,
"TRAN": true,
"DATABASE": true,
"NULL": true,
"TRANSACTION": true,
"DBCC": true,
"NULLIF": true,
"TRIGGER": true,
"DEALLOCATE": true,
"OF": true,
"TRUNCATE": true,
"DECLARE": true,
"OFF": true,
"TRY_CONVERT": true,
"DEFAULT": true,
"OFFSETS": true,
"TSEQUAL": true,
"DELETE": true,
"ON": true,
"UNION": true,
"DENY": true,
"OPEN": true,
"UNIQUE": true,
"DESC": true,
"OPENDATASOURCE": true,
"UNPIVOT": true,
"DISK": true,
"OPENQUERY": true,
"UPDATE": true,
"DISTINCT": true,
"OPENROWSET": true,
"UPDATETEXT": true,
"DISTRIBUTED": true,
"OPENXML": true,
"USE": true,
"DOUBLE": true,
"OPTION": true,
"USER": true,
"DROP": true,
"OR": true,
"VALUES": true,
"DUMP": true,
"ORDER": true,
"VARYING": true,
"ELSE": true,
"OUTER": true,
"VIEW": true,
"END": true,
"OVER": true,
"WAITFOR": true,
"ERRLVL": true,
"PERCENT": true,
"WHEN": true,
"ESCAPE": true,
"PIVOT": true,
"WHERE": true,
"EXCEPT": true,
"PLAN": true,
"WHILE": true,
"EXEC": true,
"PRECISION": true,
"WITH": true,
"EXECUTE": true,
"PRIMARY": true,
"WITHIN": true,
"EXISTS": true,
"PRINT": true,
"WRITETEXT": true,
"EXIT": true,
"PROC": true,
}
)
type mssql struct { type mssql struct {
core.Base core.Base
} }
@ -74,6 +264,15 @@ func (db *mssql) SupportInsertMany() bool {
return true return true
} }
func (db *mssql) IsReserved(name string) bool {
_, ok := mssqlReservedWords[name]
return ok
}
func (db *mssql) Quote(name string) string {
return "[" + name + "]"
}
func (db *mssql) QuoteStr() string { func (db *mssql) QuoteStr() string {
return "\"" return "\""
} }

View File

@ -15,6 +15,151 @@ import (
// RegisterDialect("mysql", &mysql{}) // RegisterDialect("mysql", &mysql{})
// } // }
var (
mysqlReservedWords = map[string]bool{
"ADD": true,
"ALL": true,
"ALTER": true,
"ANALYZE": true,
"AND": true,
"AS": true,
"ASC": true,
"ASENSITIVE": true,
"BEFORE": true,
"BETWEEN": true,
"BIGINT": true,
"BINARY": true,
"BLOB": true,
"BOTH": true,
"BY": true,
"CALL": true,
"CASCADE": true,
"CASE": true,
"CHANGE": true,
"CHAR": true,
"CHARACTER": true,
"CHECK": true,
"COLLATE": true,
"COLUMN": true,
"CONDITION": true,
"CONNECTION": true,
"CONSTRAINT": true,
"CONTINUE": true,
"CONVERT": true,
"CREATE": true,
"CROSS": true,
"CURRENT_DATE": true,
"CURRENT_TIME": true,
"CURRENT_TIMESTAMP": true,
"CURRENT_USER": true,
"CURSOR": true,
"DATABASE": true,
"DATABASES": true,
"DAY_HOUR": true,
"DAY_MICROSECOND": true,
"DAY_MINUTE": true,
"DAY_SECOND": true,
"DEC": true,
"DECIMAL": true,
"DECLARE": true,
"DEFAULT": true,
"DELAYED": true,
"DELETE": true,
"DESC": true,
"DESCRIBE": true,
"DETERMINISTIC": true,
"DISTINCT": true,
"DISTINCTROW": true,
"DIV": true,
"DOUBLE": true,
"DROP": true,
"DUAL": true,
"EACH": true,
"ELSE": true,
"ELSEIF": true,
"ENCLOSED": true,
"ESCAPED": true,
"EXISTS": true,
"EXIT": true,
"EXPLAIN": true,
"FALSE": true,
"FETCH": true,
"FLOAT": true,
"FLOAT4": true,
"FLOAT8": true,
"FOR": true,
"FORCE": true,
"FOREIGN": true,
"FROM": true,
"FULLTEXT": true,
"GOTO": true,
"GRANT": true,
"GROUP": true,
"HAVING": true,
"HIGH_PRIORITY": true,
"HOUR_MICROSECOND": true,
"HOUR_MINUTE": true,
"HOUR_SECOND": true,
"IF": true,
"IGNORE": true,
"IN": true, "INDEX": true,
"INFILE": true, "INNER": true, "INOUT": true,
"INSENSITIVE": true, "INSERT": true, "INT": true,
"INT1": true, "INT2": true, "INT3": true,
"INT4": true, "INT8": true, "INTEGER": true,
"INTERVAL": true, "INTO": true, "IS": true,
"ITERATE": true, "JOIN": true, "KEY": true,
"KEYS": true, "KILL": true, "LABEL": true,
"LEADING": true, "LEAVE": true, "LEFT": true,
"LIKE": true, "LIMIT": true, "LINEAR": true,
"LINES": true, "LOAD": true, "LOCALTIME": true,
"LOCALTIMESTAMP": true, "LOCK": true, "LONG": true,
"LONGBLOB": true, "LONGTEXT": true, "LOOP": true,
"LOW_PRIORITY": true, "MATCH": true, "MEDIUMBLOB": true,
"MEDIUMINT": true, "MEDIUMTEXT": true, "MIDDLEINT": true,
"MINUTE_MICROSECOND": true, "MINUTE_SECOND": true, "MOD": true,
"MODIFIES": true, "NATURAL": true, "NOT": true,
"NO_WRITE_TO_BINLOG": true, "NULL": true, "NUMERIC": true,
"ON OPTIMIZE": true, "OPTION": true,
"OPTIONALLY": true, "OR": true, "ORDER": true,
"OUT": true, "OUTER": true, "OUTFILE": true,
"PRECISION": true, "PRIMARY": true, "PROCEDURE": true,
"PURGE": true, "RAID0": true, "RANGE": true,
"READ": true, "READS": true, "REAL": true,
"REFERENCES": true, "REGEXP": true, "RELEASE": true,
"RENAME": true, "REPEAT": true, "REPLACE": true,
"REQUIRE": true, "RESTRICT": true, "RETURN": true,
"REVOKE": true, "RIGHT": true, "RLIKE": true,
"SCHEMA": true, "SCHEMAS": true, "SECOND_MICROSECOND": true,
"SELECT": true, "SENSITIVE": true, "SEPARATOR": true,
"SET": true, "SHOW": true, "SMALLINT": true,
"SPATIAL": true, "SPECIFIC": true, "SQL": true,
"SQLEXCEPTION": true, "SQLSTATE": true, "SQLWARNING": true,
"SQL_BIG_RESULT": true, "SQL_CALC_FOUND_ROWS": true, "SQL_SMALL_RESULT": true,
"SSL": true, "STARTING": true, "STRAIGHT_JOIN": true,
"TABLE": true, "TERMINATED": true, "THEN": true,
"TINYBLOB": true, "TINYINT": true, "TINYTEXT": true,
"TO": true, "TRAILING": true, "TRIGGER": true,
"TRUE": true, "UNDO": true, "UNION": true,
"UNIQUE": true, "UNLOCK": true, "UNSIGNED": true,
"UPDATE": true, "USAGE": true, "USE": true,
"USING": true, "UTC_DATE": true, "UTC_TIME": true,
"UTC_TIMESTAMP": true, "VALUES": true, "VARBINARY": true,
"VARCHAR": true,
"VARCHARACTER": true,
"VARYING": true,
"WHEN": true,
"WHERE": true,
"WHILE": true,
"WITH": true,
"WRITE": true,
"X509": true,
"XOR": true,
"YEAR_MONTH": true,
"ZEROFILL": true,
}
)
type mysql struct { type mysql struct {
core.Base core.Base
net string net string
@ -95,6 +240,15 @@ func (db *mysql) SupportInsertMany() bool {
return true return true
} }
func (db *mysql) IsReserved(name string) bool {
_, ok := mysqlReservedWords[name]
return ok
}
func (db *mysql) Quote(name string) string {
return "`" + name + "`"
}
func (db *mysql) QuoteStr() string { func (db *mysql) QuoteStr() string {
return "`" return "`"
} }

View File

@ -13,6 +13,490 @@ import (
// RegisterDialect("oracle", &oracle{}) // RegisterDialect("oracle", &oracle{})
// } // }
var (
oracleReservedWords = map[string]bool{
"ACCESS": true,
"ACCOUNT": true,
"ACTIVATE": true,
"ADD": true,
"ADMIN": true,
"ADVISE": true,
"AFTER": true,
"ALL": true,
"ALL_ROWS": true,
"ALLOCATE": true,
"ALTER": true,
"ANALYZE": true,
"AND": true,
"ANY": true,
"ARCHIVE": true,
"ARCHIVELOG": true,
"ARRAY": true,
"AS": true,
"ASC": true,
"AT": true,
"AUDIT": true,
"AUTHENTICATED": true,
"AUTHORIZATION": true,
"AUTOEXTEND": true,
"AUTOMATIC": true,
"BACKUP": true,
"BECOME": true,
"BEFORE": true,
"BEGIN": true,
"BETWEEN": true,
"BFILE": true,
"BITMAP": true,
"BLOB": true,
"BLOCK": true,
"BODY": true,
"BY": true,
"CACHE": true,
"CACHE_INSTANCES": true,
"CANCEL": true,
"CASCADE": true,
"CAST": true,
"CFILE": true,
"CHAINED": true,
"CHANGE": true,
"CHAR": true,
"CHAR_CS": true,
"CHARACTER": true,
"CHECK": true,
"CHECKPOINT": true,
"CHOOSE": true,
"CHUNK": true,
"CLEAR": true,
"CLOB": true,
"CLONE": true,
"CLOSE": true,
"CLOSE_CACHED_OPEN_CURSORS": true,
"CLUSTER": true,
"COALESCE": true,
"COLUMN": true,
"COLUMNS": true,
"COMMENT": true,
"COMMIT": true,
"COMMITTED": true,
"COMPATIBILITY": true,
"COMPILE": true,
"COMPLETE": true,
"COMPOSITE_LIMIT": true,
"COMPRESS": true,
"COMPUTE": true,
"CONNECT": true,
"CONNECT_TIME": true,
"CONSTRAINT": true,
"CONSTRAINTS": true,
"CONTENTS": true,
"CONTINUE": true,
"CONTROLFILE": true,
"CONVERT": true,
"COST": true,
"CPU_PER_CALL": true,
"CPU_PER_SESSION": true,
"CREATE": true,
"CURRENT": true,
"CURRENT_SCHEMA": true,
"CURREN_USER": true,
"CURSOR": true,
"CYCLE": true,
"DANGLING": true,
"DATABASE": true,
"DATAFILE": true,
"DATAFILES": true,
"DATAOBJNO": true,
"DATE": true,
"DBA": true,
"DBHIGH": true,
"DBLOW": true,
"DBMAC": true,
"DEALLOCATE": true,
"DEBUG": true,
"DEC": true,
"DECIMAL": true,
"DECLARE": true,
"DEFAULT": true,
"DEFERRABLE": true,
"DEFERRED": true,
"DEGREE": true,
"DELETE": true,
"DEREF": true,
"DESC": true,
"DIRECTORY": true,
"DISABLE": true,
"DISCONNECT": true,
"DISMOUNT": true,
"DISTINCT": true,
"DISTRIBUTED": true,
"DML": true,
"DOUBLE": true,
"DROP": true,
"DUMP": true,
"EACH": true,
"ELSE": true,
"ENABLE": true,
"END": true,
"ENFORCE": true,
"ENTRY": true,
"ESCAPE": true,
"EXCEPT": true,
"EXCEPTIONS": true,
"EXCHANGE": true,
"EXCLUDING": true,
"EXCLUSIVE": true,
"EXECUTE": true,
"EXISTS": true,
"EXPIRE": true,
"EXPLAIN": true,
"EXTENT": true,
"EXTENTS": true,
"EXTERNALLY": true,
"FAILED_LOGIN_ATTEMPTS": true,
"FALSE": true,
"FAST": true,
"FILE": true,
"FIRST_ROWS": true,
"FLAGGER": true,
"FLOAT": true,
"FLOB": true,
"FLUSH": true,
"FOR": true,
"FORCE": true,
"FOREIGN": true,
"FREELIST": true,
"FREELISTS": true,
"FROM": true,
"FULL": true,
"FUNCTION": true,
"GLOBAL": true,
"GLOBALLY": true,
"GLOBAL_NAME": true,
"GRANT": true,
"GROUP": true,
"GROUPS": true,
"HASH": true,
"HASHKEYS": true,
"HAVING": true,
"HEADER": true,
"HEAP": true,
"IDENTIFIED": true,
"IDGENERATORS": true,
"IDLE_TIME": true,
"IF": true,
"IMMEDIATE": true,
"IN": true,
"INCLUDING": true,
"INCREMENT": true,
"INDEX": true,
"INDEXED": true,
"INDEXES": true,
"INDICATOR": true,
"IND_PARTITION": true,
"INITIAL": true,
"INITIALLY": true,
"INITRANS": true,
"INSERT": true,
"INSTANCE": true,
"INSTANCES": true,
"INSTEAD": true,
"INT": true,
"INTEGER": true,
"INTERMEDIATE": true,
"INTERSECT": true,
"INTO": true,
"IS": true,
"ISOLATION": true,
"ISOLATION_LEVEL": true,
"KEEP": true,
"KEY": true,
"KILL": true,
"LABEL": true,
"LAYER": true,
"LESS": true,
"LEVEL": true,
"LIBRARY": true,
"LIKE": true,
"LIMIT": true,
"LINK": true,
"LIST": true,
"LOB": true,
"LOCAL": true,
"LOCK": true,
"LOCKED": true,
"LOG": true,
"LOGFILE": true,
"LOGGING": true,
"LOGICAL_READS_PER_CALL": true,
"LOGICAL_READS_PER_SESSION": true,
"LONG": true,
"MANAGE": true,
"MASTER": true,
"MAX": true,
"MAXARCHLOGS": true,
"MAXDATAFILES": true,
"MAXEXTENTS": true,
"MAXINSTANCES": true,
"MAXLOGFILES": true,
"MAXLOGHISTORY": true,
"MAXLOGMEMBERS": true,
"MAXSIZE": true,
"MAXTRANS": true,
"MAXVALUE": true,
"MIN": true,
"MEMBER": true,
"MINIMUM": true,
"MINEXTENTS": true,
"MINUS": true,
"MINVALUE": true,
"MLSLABEL": true,
"MLS_LABEL_FORMAT": true,
"MODE": true,
"MODIFY": true,
"MOUNT": true,
"MOVE": true,
"MTS_DISPATCHERS": true,
"MULTISET": true,
"NATIONAL": true,
"NCHAR": true,
"NCHAR_CS": true,
"NCLOB": true,
"NEEDED": true,
"NESTED": true,
"NETWORK": true,
"NEW": true,
"NEXT": true,
"NOARCHIVELOG": true,
"NOAUDIT": true,
"NOCACHE": true,
"NOCOMPRESS": true,
"NOCYCLE": true,
"NOFORCE": true,
"NOLOGGING": true,
"NOMAXVALUE": true,
"NOMINVALUE": true,
"NONE": true,
"NOORDER": true,
"NOOVERRIDE": true,
"NOPARALLEL": true,
"NOREVERSE": true,
"NORMAL": true,
"NOSORT": true,
"NOT": true,
"NOTHING": true,
"NOWAIT": true,
"NULL": true,
"NUMBER": true,
"NUMERIC": true,
"NVARCHAR2": true,
"OBJECT": true,
"OBJNO": true,
"OBJNO_REUSE": true,
"OF": true,
"OFF": true,
"OFFLINE": true,
"OID": true,
"OIDINDEX": true,
"OLD": true,
"ON": true,
"ONLINE": true,
"ONLY": true,
"OPCODE": true,
"OPEN": true,
"OPTIMAL": true,
"OPTIMIZER_GOAL": true,
"OPTION": true,
"OR": true,
"ORDER": true,
"ORGANIZATION": true,
"OSLABEL": true,
"OVERFLOW": true,
"OWN": true,
"PACKAGE": true,
"PARALLEL": true,
"PARTITION": true,
"PASSWORD": true,
"PASSWORD_GRACE_TIME": true,
"PASSWORD_LIFE_TIME": true,
"PASSWORD_LOCK_TIME": true,
"PASSWORD_REUSE_MAX": true,
"PASSWORD_REUSE_TIME": true,
"PASSWORD_VERIFY_FUNCTION": true,
"PCTFREE": true,
"PCTINCREASE": true,
"PCTTHRESHOLD": true,
"PCTUSED": true,
"PCTVERSION": true,
"PERCENT": true,
"PERMANENT": true,
"PLAN": true,
"PLSQL_DEBUG": true,
"POST_TRANSACTION": true,
"PRECISION": true,
"PRESERVE": true,
"PRIMARY": true,
"PRIOR": true,
"PRIVATE": true,
"PRIVATE_SGA": true,
"PRIVILEGE": true,
"PRIVILEGES": true,
"PROCEDURE": true,
"PROFILE": true,
"PUBLIC": true,
"PURGE": true,
"QUEUE": true,
"QUOTA": true,
"RANGE": true,
"RAW": true,
"RBA": true,
"READ": true,
"READUP": true,
"REAL": true,
"REBUILD": true,
"RECOVER": true,
"RECOVERABLE": true,
"RECOVERY": true,
"REF": true,
"REFERENCES": true,
"REFERENCING": true,
"REFRESH": true,
"RENAME": true,
"REPLACE": true,
"RESET": true,
"RESETLOGS": true,
"RESIZE": true,
"RESOURCE": true,
"RESTRICTED": true,
"RETURN": true,
"RETURNING": true,
"REUSE": true,
"REVERSE": true,
"REVOKE": true,
"ROLE": true,
"ROLES": true,
"ROLLBACK": true,
"ROW": true,
"ROWID": true,
"ROWNUM": true,
"ROWS": true,
"RULE": true,
"SAMPLE": true,
"SAVEPOINT": true,
"SB4": true,
"SCAN_INSTANCES": true,
"SCHEMA": true,
"SCN": true,
"SCOPE": true,
"SD_ALL": true,
"SD_INHIBIT": true,
"SD_SHOW": true,
"SEGMENT": true,
"SEG_BLOCK": true,
"SEG_FILE": true,
"SELECT": true,
"SEQUENCE": true,
"SERIALIZABLE": true,
"SESSION": true,
"SESSION_CACHED_CURSORS": true,
"SESSIONS_PER_USER": true,
"SET": true,
"SHARE": true,
"SHARED": true,
"SHARED_POOL": true,
"SHRINK": true,
"SIZE": true,
"SKIP": true,
"SKIP_UNUSABLE_INDEXES": true,
"SMALLINT": true,
"SNAPSHOT": true,
"SOME": true,
"SORT": true,
"SPECIFICATION": true,
"SPLIT": true,
"SQL_TRACE": true,
"STANDBY": true,
"START": true,
"STATEMENT_ID": true,
"STATISTICS": true,
"STOP": true,
"STORAGE": true,
"STORE": true,
"STRUCTURE": true,
"SUCCESSFUL": true,
"SWITCH": true,
"SYS_OP_ENFORCE_NOT_NULL$": true,
"SYS_OP_NTCIMG$": true,
"SYNONYM": true,
"SYSDATE": true,
"SYSDBA": true,
"SYSOPER": true,
"SYSTEM": true,
"TABLE": true,
"TABLES": true,
"TABLESPACE": true,
"TABLESPACE_NO": true,
"TABNO": true,
"TEMPORARY": true,
"THAN": true,
"THE": true,
"THEN": true,
"THREAD": true,
"TIMESTAMP": true,
"TIME": true,
"TO": true,
"TOPLEVEL": true,
"TRACE": true,
"TRACING": true,
"TRANSACTION": true,
"TRANSITIONAL": true,
"TRIGGER": true,
"TRIGGERS": true,
"TRUE": true,
"TRUNCATE": true,
"TX": true,
"TYPE": true,
"UB2": true,
"UBA": true,
"UID": true,
"UNARCHIVED": true,
"UNDO": true,
"UNION": true,
"UNIQUE": true,
"UNLIMITED": true,
"UNLOCK": true,
"UNRECOVERABLE": true,
"UNTIL": true,
"UNUSABLE": true,
"UNUSED": true,
"UPDATABLE": true,
"UPDATE": true,
"USAGE": true,
"USE": true,
"USER": true,
"USING": true,
"VALIDATE": true,
"VALIDATION": true,
"VALUE": true,
"VALUES": true,
"VARCHAR": true,
"VARCHAR2": true,
"VARYING": true,
"VIEW": true,
"WHEN": true,
"WHENEVER": true,
"WHERE": true,
"WITH": true,
"WITHOUT": true,
"WORK": true,
"WRITE": true,
"WRITEDOWN": true,
"WRITEUP": true,
"XID": true,
"YEAR": true,
"ZONE": true,
}
)
type oracle struct { type oracle struct {
core.Base core.Base
} }
@ -56,6 +540,15 @@ func (db *oracle) SupportInsertMany() bool {
return true return true
} }
func (db *oracle) IsReserved(name string) bool {
_, ok := oracleReservedWords[name]
return ok
}
func (db *oracle) Quote(name string) string {
return "\"" + name + "\""
}
func (db *oracle) QuoteStr() string { func (db *oracle) QuoteStr() string {
return "\"" return "\""
} }

View File

@ -12,6 +12,325 @@ import (
// func init() { // func init() {
// RegisterDialect("postgres", &postgres{}) // RegisterDialect("postgres", &postgres{})
// } // }
var (
postgresReservedWords = map[string]bool{
"A": true,
"ABORT": true,
"ABS": true,
"ABSENT": true,
"ABSOLUTE": true,
"ACCESS": true,
"ACCORDING": true,
"ACTION": true,
"ADA": true,
"ADD": true,
"ADMIN": true,
"AFTER": true,
"AGGREGATE": true,
"ALL": true,
"ALLOCATE": true,
"ALSO": true,
"ALTER": true,
"ALWAYS": true,
"ANALYSE": true,
"ANALYZE": true,
"AND": true,
"ANY": true,
"ARE": true,
"ARRAY": true,
"ARRAY_AGG": true,
"ARRAY_MAX_CARDINALITY": true,
"AS": true,
"ASC": true,
"ASENSITIVE": true,
"ASSERTION": true,
"ASSIGNMENT": true,
"ASYMMETRIC": true,
"AT": true,
"ATOMIC": true,
"ATTRIBUTE": true,
"ATTRIBUTES": true,
"AUTHORIZATION": true,
"AVG": true,
"BACKWARD": true,
"BASE64": true,
"BEFORE": true,
"BEGIN": true,
"BEGIN_FRAME": true,
"BEGIN_PARTITION": true,
"BERNOULLI": true,
"BETWEEN": true,
"BIGINT": true,
"BINARY": true,
"BIT": true,
"BIT_LENGTH": true,
"BLOB": true,
"BLOCKED": true,
"BOM": true,
"BOOLEAN": true,
"BOTH": true,
"BREADTH": true,
"BY": true,
"C": true,
"CACHE": true,
"CALL": true,
"CALLED": true,
"CARDINALITY": true,
"CASCADE": true,
"CASCADED": true,
"CASE": true,
"CAST": true,
"CATALOG": true,
"CATALOG_NAME": true,
"CEIL": true,
"CEILING": true,
"CHAIN": true,
"CHAR": true,
"CHARACTER": true,
"CHARACTERISTICS": true,
"CHARACTERS": true,
"CHARACTER_LENGTH": true,
"CHARACTER_SET_CATALOG": true,
"CHARACTER_SET_NAME": true,
"CHARACTER_SET_SCHEMA": true,
"CHAR_LENGTH": true,
"CHECK": true,
"CHECKPOINT": true,
"CLASS": true,
"CLASS_ORIGIN": true,
"CLOB": true,
"CLOSE": true,
"CLUSTER": true,
"COALESCE": true,
"COBOL": true,
"COLLATE": true,
"COLLATION": true,
"COLLATION_CATALOG": true,
"COLLATION_NAME": true,
"COLLATION_SCHEMA": true,
"COLLECT": true,
"COLUMN": true,
"COLUMNS": true,
"COLUMN_NAME": true,
"COMMAND_FUNCTION": true,
"COMMAND_FUNCTION_CODE": true,
"COMMENT": true,
"COMMENTS": true,
"COMMIT": true,
"COMMITTED": true,
"CONCURRENTLY": true,
"CONDITION": true,
"CONDITION_NUMBER": true,
"CONFIGURATION": true,
"CONNECT": true,
"CONNECTION": true,
"CONNECTION_NAME": true,
"CONSTRAINT": true,
"CONSTRAINTS": true,
"CONSTRAINT_CATALOG": true,
"CONSTRAINT_NAME": true,
"CONSTRAINT_SCHEMA": true,
"CONSTRUCTOR": true,
"CONTAINS": true,
"CONTENT": true,
"CONTINUE": true,
"CONTROL": true,
"CONVERSION": true,
"CONVERT": true,
"COPY": true,
"CORR": true,
"CORRESPONDING": true,
"COST": true,
"COUNT": true,
"COVAR_POP": true,
"COVAR_SAMP": true,
"CREATE": true,
"CROSS": true,
"CSV": true,
"CUBE": true,
"CUME_DIST": true,
"CURRENT": true,
"CURRENT_CATALOG": true,
"CURRENT_DATE": true,
"CURRENT_DEFAULT_TRANSFORM_GROUP": true,
"CURRENT_PATH": true,
"CURRENT_ROLE": true,
"CURRENT_ROW": true,
"CURRENT_SCHEMA": true,
"CURRENT_TIME": true,
"CURRENT_TIMESTAMP": true,
"CURRENT_TRANSFORM_GROUP_FOR_TYPE": true,
"CURRENT_USER": true,
"CURSOR": true,
"CURSOR_NAME": true,
"CYCLE": true,
"DATA": true,
"DATABASE": true,
"DATALINK": true,
"DATE": true,
"DATETIME_INTERVAL_CODE": true,
"DATETIME_INTERVAL_PRECISION": true,
"DAY": true,
"DB": true,
"DEALLOCATE": true,
"DEC": true,
"DECIMAL": true,
"DECLARE": true,
"DEFAULT": true,
"DEFAULTS": true,
"DEFERRABLE": true,
"DEFERRED": true,
"DEFINED": true,
"DEFINER": true,
"DEGREE": true,
"DELETE": true,
"DELIMITER": true,
"DELIMITERS": true,
"DENSE_RANK": true,
"DEPTH": true,
"DEREF": true,
"DERIVED": true,
"DESC": true,
"DESCRIBE": true,
"DESCRIPTOR": true,
"DETERMINISTIC": true,
"DIAGNOSTICS": true,
"DICTIONARY": true,
"DISABLE": true,
"DISCARD": true,
"DISCONNECT": true,
"DISPATCH": true,
"DISTINCT": true,
"DLNEWCOPY": true,
"DLPREVIOUSCOPY": true,
"DLURLCOMPLETE": true,
"DLURLCOMPLETEONLY": true,
"DLURLCOMPLETEWRITE": true,
"DLURLPATH": true,
"DLURLPATHONLY": true,
"DLURLPATHWRITE": true,
"DLURLSCHEME": true,
"DLURLSERVER": true,
"DLVALUE": true,
"DO": true,
"DOCUMENT": true,
"DOMAIN": true,
"DOUBLE": true,
"DROP": true,
"DYNAMIC": true,
"DYNAMIC_FUNCTION": true,
"DYNAMIC_FUNCTION_CODE": true,
"EACH": true,
"ELEMENT": true,
"ELSE": true,
"EMPTY": true,
"ENABLE": true,
"ENCODING": true,
"ENCRYPTED": true,
"END": true,
"END-EXEC": true,
"END_FRAME": true,
"END_PARTITION": true,
"ENFORCED": true,
"ENUM": true,
"EQUALS": true,
"ESCAPE": true,
"EVENT": true,
"EVERY": true,
"EXCEPT": true,
"EXCEPTION": true,
"EXCLUDE": true,
"EXCLUDING": true,
"EXCLUSIVE": true,
"EXEC": true,
"EXECUTE": true,
"EXISTS": true,
"EXP": true,
"EXPLAIN": true,
"EXPRESSION": true,
"EXTENSION": true,
"EXTERNAL": true,
"EXTRACT": true,
"FALSE": true,
"FAMILY": true,
"FETCH": true,
"FILE": true,
"FILTER": true,
"FINAL": true,
"FIRST": true,
"FIRST_VALUE": true,
"FLAG": true,
"FLOAT": true,
"FLOOR": true,
"FOLLOWING": true,
"FOR": true,
"FORCE": true,
"FOREIGN": true,
"FORTRAN": true,
"FORWARD": true,
"FOUND": true,
"FRAME_ROW": true,
"FREE": true,
"FREEZE": true,
"FROM": true,
"FS": true,
"FULL": true,
"FUNCTION": true,
"FUNCTIONS": true,
"FUSION": true,
"G": true,
"GENERAL": true,
"GENERATED": true,
"GET": true,
"GLOBAL": true,
"GO": true,
"GOTO": true,
"GRANT": true,
"GRANTED": true,
"GREATEST": true,
"GROUP": true,
"GROUPING": true,
"GROUPS": true,
"HANDLER": true,
"HAVING": true,
"HEADER": true,
"HEX": true,
"HIERARCHY": true,
"HOLD": true,
"HOUR": true,
"ID": true,
"IDENTITY": true,
"IF": true,
"IGNORE": true,
"ILIKE": true,
"IMMEDIATE": true,
"IMMEDIATELY": true,
"IMMUTABLE": true,
"IMPLEMENTATION": true,
"IMPLICIT": true,
"IMPORT": true,
"IN": true,
"INCLUDING": true,
"INCREMENT": true,
"INDENT": true,
"INDEX": true,
"INDEXES": true,
"INDICATOR": true,
"INHERIT": true,
"INHERITS": true,
"INITIALLY": true,
"INLINE": true,
"INNER": true,
"INOUT": true,
"INPUT": true,
"INSENSITIVE": true,
"INSERT": true,
"INSTANCE": true,
"INSTANTIABLE": true,
"INSTEAD": true,
"INT": true,
}
)
type postgres struct { type postgres struct {
core.Base core.Base
@ -73,6 +392,15 @@ func (db *postgres) SupportInsertMany() bool {
return true return true
} }
func (db *postgres) IsReserved(name string) bool {
_, ok := postgresReservedWords[name]
return ok
}
func (db *postgres) Quote(name string) string {
return "\"" + name + "\""
}
func (db *postgres) QuoteStr() string { func (db *postgres) QuoteStr() string {
return "\"" return "\""
} }

View File

@ -34,7 +34,7 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
var sqlStr string var sqlStr string
var args []interface{} var args []interface{}
rows.session.Statement.RefTable = rows.session.Engine.autoMap(bean) rows.session.Statement.RefTable = rows.session.Engine.TableInfo(bean)
if rows.session.Statement.RawSQL == "" { if rows.session.Statement.RawSQL == "" {
sqlStr, args = rows.session.Statement.genGetSql(bean) sqlStr, args = rows.session.Statement.genGetSql(bean)
} else { } else {

View File

@ -447,10 +447,12 @@ func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, er
session.Engine.logSQL(sqlStr, args...) session.Engine.logSQL(sqlStr, args...)
return session.Engine.LogSQLExecutionTime(sqlStr, args, func() (sql.Result, error) {
if session.IsAutoCommit { if session.IsAutoCommit {
return session.innerExec(sqlStr, args...) return session.innerExec(sqlStr, args...)
} }
return session.Tx.Exec(sqlStr, args...) return session.Tx.Exec(sqlStr, args...)
})
} }
// Exec raw sql // Exec raw sql
@ -469,7 +471,7 @@ func (session *Session) Exec(sqlStr string, args ...interface{}) (sql.Result, er
// this function create a table according a bean // this function create a table according a bean
func (session *Session) CreateTable(bean interface{}) error { func (session *Session) CreateTable(bean interface{}) error {
session.Statement.RefTable = session.Engine.autoMap(bean) session.Statement.RefTable = session.Engine.TableInfo(bean)
err := session.newDb() err := session.newDb()
if err != nil { if err != nil {
@ -485,7 +487,7 @@ func (session *Session) CreateTable(bean interface{}) error {
// create indexes // create indexes
func (session *Session) CreateIndexes(bean interface{}) error { func (session *Session) CreateIndexes(bean interface{}) error {
session.Statement.RefTable = session.Engine.autoMap(bean) session.Statement.RefTable = session.Engine.TableInfo(bean)
err := session.newDb() err := session.newDb()
if err != nil { if err != nil {
@ -508,7 +510,7 @@ func (session *Session) CreateIndexes(bean interface{}) error {
// create uniques // create uniques
func (session *Session) CreateUniques(bean interface{}) error { func (session *Session) CreateUniques(bean interface{}) error {
session.Statement.RefTable = session.Engine.autoMap(bean) session.Statement.RefTable = session.Engine.TableInfo(bean)
err := session.newDb() err := session.newDb()
if err != nil { if err != nil {
@ -595,7 +597,7 @@ func (session *Session) DropTable(bean interface{}) error {
if t.Kind() == reflect.String { if t.Kind() == reflect.String {
session.Statement.AltTableName = bean.(string) session.Statement.AltTableName = bean.(string)
} else if t.Kind() == reflect.Struct { } else if t.Kind() == reflect.Struct {
session.Statement.RefTable = session.Engine.autoMap(bean) session.Statement.RefTable = session.Engine.TableInfo(bean)
} else { } else {
return errors.New("Unsupported type") return errors.New("Unsupported type")
} }
@ -952,7 +954,7 @@ func (session *Session) Get(bean interface{}) (bool, error) {
var args []interface{} var args []interface{}
if session.Statement.RefTable == nil { if session.Statement.RefTable == nil {
session.Statement.RefTable = session.Engine.autoMap(bean) session.Statement.RefTable = session.Engine.TableInfo(bean)
} }
if session.Statement.RawSQL == "" { if session.Statement.RawSQL == "" {
@ -1814,15 +1816,16 @@ func (session *Session) queryPreprocess(sqlStr *string, paramStr ...interface{})
} }
func (session *Session) query(sqlStr string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) { func (session *Session) query(sqlStr string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) {
session.queryPreprocess(&sqlStr, paramStr...) session.queryPreprocess(&sqlStr, paramStr...)
if session.IsAutoCommit { if session.IsAutoCommit {
return query(session.Db, sqlStr, paramStr...) return session.innerQuery(session.Db, sqlStr, paramStr...)
} }
return txQuery(session.Tx, sqlStr, paramStr...) return session.txQuery(session.Tx, sqlStr, paramStr...)
} }
func txQuery(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string][]byte, err error) { func (session *Session) txQuery(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string][]byte, err error) {
rows, err := tx.Query(sqlStr, params...) rows, err := tx.Query(sqlStr, params...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -1832,17 +1835,26 @@ func txQuery(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []
return rows2maps(rows) return rows2maps(rows)
} }
func query(db *core.DB, sqlStr string, params ...interface{}) (resultsSlice []map[string][]byte, err error) { func (session *Session) innerQuery(db *core.DB, sqlStr string, params ...interface{}) (resultsSlice []map[string][]byte, err error) {
s, err := db.Prepare(sqlStr)
stmt, rows, err := session.Engine.LogSQLQueryTime(sqlStr, params, func() (*core.Stmt, *core.Rows, error) {
stmt, err := db.Prepare(sqlStr)
if err != nil { if err != nil {
return nil, err return stmt, nil, err
}
defer s.Close()
rows, err := s.Query(params...)
if err != nil {
return nil, err
} }
rows, err := stmt.Query(params...)
return stmt, rows, err
})
if rows != nil {
defer rows.Close() defer rows.Close()
}
if stmt != nil {
defer stmt.Close()
}
if err != nil {
return nil, err
}
return rows2maps(rows) return rows2maps(rows)
} }
@ -2064,6 +2076,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
strings.Join(colMultiPlaces, "),(")) strings.Join(colMultiPlaces, "),("))
res, err := session.exec(statement, args...) res, err := session.exec(statement, args...)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -2720,7 +2733,7 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
} }
func (session *Session) innerInsert(bean interface{}) (int64, error) { func (session *Session) innerInsert(bean interface{}) (int64, error) {
table := session.Engine.autoMap(bean) table := session.Engine.TableInfo(bean)
session.Statement.RefTable = table session.Statement.RefTable = table
// handle BeforeInsertProcessor // handle BeforeInsertProcessor
@ -3117,7 +3130,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
// -- // --
if t.Kind() == reflect.Struct { if t.Kind() == reflect.Struct {
table = session.Engine.autoMap(bean) table = session.Engine.TableInfo(bean)
session.Statement.RefTable = table session.Statement.RefTable = table
if session.Statement.ColumnStr == "" { if session.Statement.ColumnStr == "" {
@ -3371,7 +3384,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
} }
// -- // --
table := session.Engine.autoMap(bean) table := session.Engine.TableInfo(bean)
session.Statement.RefTable = table session.Statement.RefTable = table
colNames, args := buildConditions(session.Engine, table, bean, true, true, colNames, args := buildConditions(session.Engine, table, bean, true, true,
false, true, session.Statement.allUseBool, session.Statement.useAllCols, false, true, session.Statement.allUseBool, session.Statement.useAllCols,

View File

@ -12,6 +12,135 @@ import (
// RegisterDialect("sqlite3", &sqlite3{}) // RegisterDialect("sqlite3", &sqlite3{})
// } // }
var (
sqlite3ReservedWords = map[string]bool{
"ABORT": true,
"ACTION": true,
"ADD": true,
"AFTER": true,
"ALL": true,
"ALTER": true,
"ANALYZE": true,
"AND": true,
"AS": true,
"ASC": true,
"ATTACH": true,
"AUTOINCREMENT": true,
"BEFORE": true,
"BEGIN": true,
"BETWEEN": true,
"BY": true,
"CASCADE": true,
"CASE": true,
"CAST": true,
"CHECK": true,
"COLLATE": true,
"COLUMN": true,
"COMMIT": true,
"CONFLICT": true,
"CONSTRAINT": true,
"CREATE": true,
"CROSS": true,
"CURRENT_DATE": true,
"CURRENT_TIME": true,
"CURRENT_TIMESTAMP": true,
"DATABASE": true,
"DEFAULT": true,
"DEFERRABLE": true,
"DEFERRED": true,
"DELETE": true,
"DESC": true,
"DETACH": true,
"DISTINCT": true,
"DROP": true,
"EACH": true,
"ELSE": true,
"END": true,
"ESCAPE": true,
"EXCEPT": true,
"EXCLUSIVE": true,
"EXISTS": true,
"EXPLAIN": true,
"FAIL": true,
"FOR": true,
"FOREIGN": true,
"FROM": true,
"FULL": true,
"GLOB": true,
"GROUP": true,
"HAVING": true,
"IF": true,
"IGNORE": true,
"IMMEDIATE": true,
"IN": true,
"INDEX": true,
"INDEXED": true,
"INITIALLY": true,
"INNER": true,
"INSERT": true,
"INSTEAD": true,
"INTERSECT": true,
"INTO": true,
"IS": true,
"ISNULL": true,
"JOIN": true,
"KEY": true,
"LEFT": true,
"LIKE": true,
"LIMIT": true,
"MATCH": true,
"NATURAL": true,
"NO": true,
"NOT": true,
"NOTNULL": true,
"NULL": true,
"OF": true,
"OFFSET": true,
"ON": true,
"OR": true,
"ORDER": true,
"OUTER": true,
"PLAN": true,
"PRAGMA": true,
"PRIMARY": true,
"QUERY": true,
"RAISE": true,
"RECURSIVE": true,
"REFERENCES": true,
"REGEXP": true,
"REINDEX": true,
"RELEASE": true,
"RENAME": true,
"REPLACE": true,
"RESTRICT": true,
"RIGHT": true,
"ROLLBACK": true,
"ROW": true,
"SAVEPOINT": true,
"SELECT": true,
"SET": true,
"TABLE": true,
"TEMP": true,
"TEMPORARY": true,
"THEN": true,
"TO": true,
"TRANSACTI": true,
"TRIGGER": true,
"UNION": true,
"UNIQUE": true,
"UPDATE": true,
"USING": true,
"VACUUM": true,
"VALUES": true,
"VIEW": true,
"VIRTUAL": true,
"WHEN": true,
"WHERE": true,
"WITH": true,
"WITHOUT": true,
}
)
type sqlite3 struct { type sqlite3 struct {
core.Base core.Base
} }
@ -54,6 +183,15 @@ func (db *sqlite3) SupportInsertMany() bool {
return true return true
} }
func (db *sqlite3) IsReserved(name string) bool {
_, ok := sqlite3ReservedWords[name]
return ok
}
func (db *sqlite3) Quote(name string) string {
return "`" + name + "`"
}
func (db *sqlite3) QuoteStr() string { func (db *sqlite3) QuoteStr() string {
return "`" return "`"
} }

View File

@ -151,7 +151,7 @@ func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
/*func (statement *Statement) genFields(bean interface{}) map[string]interface{} { /*func (statement *Statement) genFields(bean interface{}) map[string]interface{} {
results := make(map[string]interface{}) results := make(map[string]interface{})
table := statement.Engine.autoMap(bean) table := statement.Engine.TableInfo(bean)
for _, col := range table.Columns { for _, col := range table.Columns {
fieldValue := col.ValueOf(bean) fieldValue := col.ValueOf(bean)
fieldType := reflect.TypeOf(fieldValue.Interface()) fieldType := reflect.TypeOf(fieldValue.Interface())
@ -905,9 +905,11 @@ func (statement *Statement) Asc(colNames ...string) *Statement {
//The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN //The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN
func (statement *Statement) Join(join_operator, tablename, condition string) *Statement { func (statement *Statement) Join(join_operator, tablename, condition string) *Statement {
if statement.JoinStr != "" { if statement.JoinStr != "" {
statement.JoinStr = statement.JoinStr + fmt.Sprintf(" %v JOIN %v ON %v", join_operator, tablename, condition) statement.JoinStr = statement.JoinStr + fmt.Sprintf(" %v JOIN %v ON %v", join_operator,
statement.Engine.Quote(tablename), condition)
} else { } else {
statement.JoinStr = fmt.Sprintf("%v JOIN %v ON %v", join_operator, tablename, condition) statement.JoinStr = fmt.Sprintf("%v JOIN %v ON %v", join_operator,
statement.Engine.Quote(tablename), condition)
} }
return statement return statement
} }
@ -1020,7 +1022,7 @@ func (s *Statement) genDropSQL() string {
func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) { func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) {
var table *core.Table var table *core.Table
if statement.RefTable == nil { if statement.RefTable == nil {
table = statement.Engine.autoMap(bean) table = statement.Engine.TableInfo(bean)
statement.RefTable = table statement.RefTable = table
} else { } else {
table = statement.RefTable table = statement.RefTable
@ -1070,7 +1072,7 @@ func (s *Statement) genAddUniqueStr(uqeName string, cols []string) (string, []in
}*/ }*/
func (statement *Statement) genCountSql(bean interface{}) (string, []interface{}) { func (statement *Statement) genCountSql(bean interface{}) (string, []interface{}) {
table := statement.Engine.autoMap(bean) table := statement.Engine.TableInfo(bean)
statement.RefTable = table statement.RefTable = table
colNames, args := buildConditions(statement.Engine, table, bean, true, true, false, colNames, args := buildConditions(statement.Engine, table, bean, true, true, false,