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
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
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")
2. exec sql, the returned results
2. execute a SQL string, the returned results
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
err := engine.Find(...)
sliceOfStructs := new(Struct)
err := engine.Find(sliceOfStructs)
// SELECT * FROM user
4. Query multiple records and record by record handle, there two methods, one is Iterate,
another is Raws
raws, err := engine.Raws(...)
// SELECT * FROM user
for raws.Next() {
raws.Scan(bean)
}
err := engine.Iterate(...)
// 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
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 ...
7. Count records
@ -89,14 +91,19 @@ another is Raws
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
engine.Id(1).Get(&user)
engine.Id(1).Get(&user) // for single primary key
// 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)
// 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
@ -114,10 +121,11 @@ The above 7 methods could use with condition methods.
engine.Limit().Find()
// SELECT * FROM user LIMIT .. OFFSET ..
engine.Top().Find()
// SELECT * FROM user LIMIT ..
engine.Top(5).Find()
// 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()
@ -125,8 +133,12 @@ The above 7 methods could use with condition methods.
engine.Cols("col1, col2").Find()
// SELECT col1, col2 FROM user
engine.Cols("col1", "col2").Where().Update(user)
// UPDATE user set col1 = ?, col2 = ? Where ...
engine.Omit("col1").Find()
// SELECT col2, col3 FROM user
engine.Omit("col1").Insert()
// INSERT INTO table (non-col1) VALUES ()
engine.Distinct("col1").Find()
// 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
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{})
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 {
Id int64
Name string
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
var user User

View File

@ -42,6 +42,14 @@ type Engine struct {
Logger core.ILogger
TZLocation *time.Location
disableGlobalCache bool
}
func (engine *Engine) SetDisableGlobalCache(disable bool) {
if engine.disableGlobalCache != disable {
engine.disableGlobalCache = disable
}
}
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
func (engine *Engine) overrideLogLevel(overrideLevel core.LogLevel) {
logLevel := engine.Logger.Level()
@ -380,7 +412,12 @@ func (engine *Engine) DumpAll(w io.Writer) error {
temp += fmt.Sprintf(", '%s'", d.(string))
}
} else if col.SQLType.IsNumeric() {
temp += fmt.Sprintf(", %s", string(d.([]byte)))
switch reflect.TypeOf(d).Kind() {
case reflect.Slice:
temp += fmt.Sprintf(", %s", string(d.([]byte)))
default:
temp += fmt.Sprintf(", %v", d)
}
} else {
s := fmt.Sprintf("%v", d)
if strings.Contains(s, ":") || strings.Contains(s, "-") {
@ -591,7 +628,7 @@ func (engine *Engine) autoMapType(v reflect.Value) *core.Table {
return table
}
func (engine *Engine) autoMap(bean interface{}) *core.Table {
func (engine *Engine) TableInfo(bean interface{}) *core.Table {
v := rValue(bean)
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 {
table := core.NewEmptyTable()
table.Cacher = engine.Cacher
if !engine.disableGlobalCache {
table.Cacher = engine.Cacher
}
return table
}
@ -639,6 +679,9 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
var idFieldColName string
var err error
hasCacheTag := false
hasNoCacheTag := false
for i := 0; i < t.NumField(); i++ {
tag := t.Field(i).Tag
@ -733,6 +776,14 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
isUnique = true
case k == "NOTNULL":
col.Nullable = false
case k == "CACHE":
if !hasCacheTag {
hasCacheTag = true
}
case k == "NOCACHE":
if !hasNoCacheTag {
hasNoCacheTag = true
}
case k == "NOT":
default:
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")) {
idFieldColName = col.Name
}
}
} // end for
if idFieldColName != "" && len(table.PrimaryKeys) == 0 {
col := table.GetColumn(idFieldColName)
@ -852,6 +903,20 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
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
}
@ -900,7 +965,7 @@ func (engine *Engine) IsTableExist(bean interface{}) (bool, error) {
}
func (engine *Engine) IdOf(bean interface{}) core.PK {
table := engine.autoMap(bean)
table := engine.TableInfo(bean)
v := reflect.Indirect(reflect.ValueOf(bean))
pk := make([]interface{}, len(table.PrimaryKeys))
for i, col := range table.PKColumns() {
@ -948,7 +1013,7 @@ func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
if t.Kind() != reflect.Struct {
return errors.New("error params")
}
table := engine.autoMap(bean)
table := engine.TableInfo(bean)
cacher := table.Cacher
if cacher == nil {
cacher = engine.Cacher
@ -967,7 +1032,7 @@ func (engine *Engine) ClearCache(beans ...interface{}) error {
if t.Kind() != reflect.Struct {
return errors.New("error params")
}
table := engine.autoMap(bean)
table := engine.TableInfo(bean)
cacher := table.Cacher
if cacher == nil {
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.
func (engine *Engine) Sync(beans ...interface{}) error {
for _, bean := range beans {
table := engine.autoMap(bean)
table := engine.TableInfo(bean)
s := engine.NewSession()
defer s.Close()
@ -1084,7 +1149,7 @@ func (engine *Engine) Sync2(beans ...interface{}) error {
structTables := make([]*core.Table, 0)
for _, bean := range beans {
table := engine.autoMap(bean)
table := engine.TableInfo(bean)
structTables = append(structTables, table)
var oriTable *core.Table
@ -1126,16 +1191,19 @@ func (engine *Engine) Sync2(beans ...interface{}) error {
curType := engine.dialect.SqlType(oriCol)
if expectedType != curType {
if expectedType == core.Text &&
curType == core.Varchar {
strings.HasPrefix(curType, core.Varchar) {
// 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))
} 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)
}
} 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)
}
}

View File

@ -13,6 +13,196 @@ import (
// 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 {
core.Base
}
@ -74,6 +264,15 @@ func (db *mssql) SupportInsertMany() bool {
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 {
return "\""
}

View File

@ -15,6 +15,151 @@ import (
// 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 {
core.Base
net string
@ -95,6 +240,15 @@ func (db *mysql) SupportInsertMany() bool {
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 {
return "`"
}

View File

@ -13,6 +13,490 @@ import (
// 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 {
core.Base
}
@ -56,6 +540,15 @@ func (db *oracle) SupportInsertMany() bool {
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 {
return "\""
}

View File

@ -12,6 +12,325 @@ import (
// func init() {
// 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 {
core.Base
@ -73,6 +392,15 @@ func (db *postgres) SupportInsertMany() bool {
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 {
return "\""
}

View File

@ -34,7 +34,7 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
var sqlStr string
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 == "" {
sqlStr, args = rows.session.Statement.genGetSql(bean)
} else {

View File

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

View File

@ -12,6 +12,135 @@ import (
// 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 {
core.Base
}
@ -54,6 +183,15 @@ func (db *sqlite3) SupportInsertMany() bool {
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 {
return "`"
}

View File

@ -151,7 +151,7 @@ func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
/*func (statement *Statement) genFields(bean interface{}) map[string]interface{} {
results := make(map[string]interface{})
table := statement.Engine.autoMap(bean)
table := statement.Engine.TableInfo(bean)
for _, col := range table.Columns {
fieldValue := col.ValueOf(bean)
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
func (statement *Statement) Join(join_operator, tablename, condition string) *Statement {
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 {
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
}
@ -1020,7 +1022,7 @@ func (s *Statement) genDropSQL() string {
func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) {
var table *core.Table
if statement.RefTable == nil {
table = statement.Engine.autoMap(bean)
table = statement.Engine.TableInfo(bean)
statement.RefTable = table
} else {
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{}) {
table := statement.Engine.autoMap(bean)
table := statement.Engine.TableInfo(bean)
statement.RefTable = table
colNames, args := buildConditions(statement.Engine, table, bean, true, true, false,