github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/go-xorm/xorm/sqlite3_dialect.go (about) 1 // Copyright 2015 The Xorm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package xorm 6 7 import ( 8 "database/sql" 9 "errors" 10 "fmt" 11 "regexp" 12 "strings" 13 14 "github.com/insionng/yougam/libraries/go-xorm/core" 15 ) 16 17 // func init() { 18 // RegisterDialect("sqlite3", &sqlite3{}) 19 // } 20 21 var ( 22 sqlite3ReservedWords = map[string]bool{ 23 "ABORT": true, 24 "ACTION": true, 25 "ADD": true, 26 "AFTER": true, 27 "ALL": true, 28 "ALTER": true, 29 "ANALYZE": true, 30 "AND": true, 31 "AS": true, 32 "ASC": true, 33 "ATTACH": true, 34 "AUTOINCREMENT": true, 35 "BEFORE": true, 36 "BEGIN": true, 37 "BETWEEN": true, 38 "BY": true, 39 "CASCADE": true, 40 "CASE": true, 41 "CAST": true, 42 "CHECK": true, 43 "COLLATE": true, 44 "COLUMN": true, 45 "COMMIT": true, 46 "CONFLICT": true, 47 "CONSTRAINT": true, 48 "CREATE": true, 49 "CROSS": true, 50 "CURRENT_DATE": true, 51 "CURRENT_TIME": true, 52 "CURRENT_TIMESTAMP": true, 53 "DATABASE": true, 54 "DEFAULT": true, 55 "DEFERRABLE": true, 56 "DEFERRED": true, 57 "DELETE": true, 58 "DESC": true, 59 "DETACH": true, 60 "DISTINCT": true, 61 "DROP": true, 62 "EACH": true, 63 "ELSE": true, 64 "END": true, 65 "ESCAPE": true, 66 "EXCEPT": true, 67 "EXCLUSIVE": true, 68 "EXISTS": true, 69 "EXPLAIN": true, 70 "FAIL": true, 71 "FOR": true, 72 "FOREIGN": true, 73 "FROM": true, 74 "FULL": true, 75 "GLOB": true, 76 "GROUP": true, 77 "HAVING": true, 78 "IF": true, 79 "IGNORE": true, 80 "IMMEDIATE": true, 81 "IN": true, 82 "INDEX": true, 83 "INDEXED": true, 84 "INITIALLY": true, 85 "INNER": true, 86 "INSERT": true, 87 "INSTEAD": true, 88 "INTERSECT": true, 89 "INTO": true, 90 "IS": true, 91 "ISNULL": true, 92 "JOIN": true, 93 "KEY": true, 94 "LEFT": true, 95 "LIKE": true, 96 "LIMIT": true, 97 "MATCH": true, 98 "NATURAL": true, 99 "NO": true, 100 "NOT": true, 101 "NOTNULL": true, 102 "NULL": true, 103 "OF": true, 104 "OFFSET": true, 105 "ON": true, 106 "OR": true, 107 "ORDER": true, 108 "OUTER": true, 109 "PLAN": true, 110 "PRAGMA": true, 111 "PRIMARY": true, 112 "QUERY": true, 113 "RAISE": true, 114 "RECURSIVE": true, 115 "REFERENCES": true, 116 "REGEXP": true, 117 "REINDEX": true, 118 "RELEASE": true, 119 "RENAME": true, 120 "REPLACE": true, 121 "RESTRICT": true, 122 "RIGHT": true, 123 "ROLLBACK": true, 124 "ROW": true, 125 "SAVEPOINT": true, 126 "SELECT": true, 127 "SET": true, 128 "TABLE": true, 129 "TEMP": true, 130 "TEMPORARY": true, 131 "THEN": true, 132 "TO": true, 133 "TRANSACTI": true, 134 "TRIGGER": true, 135 "UNION": true, 136 "UNIQUE": true, 137 "UPDATE": true, 138 "USING": true, 139 "VACUUM": true, 140 "VALUES": true, 141 "VIEW": true, 142 "VIRTUAL": true, 143 "WHEN": true, 144 "WHERE": true, 145 "WITH": true, 146 "WITHOUT": true, 147 } 148 ) 149 150 type sqlite3 struct { 151 core.Base 152 } 153 154 func (db *sqlite3) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { 155 return db.Base.Init(d, db, uri, drivername, dataSourceName) 156 } 157 158 func (db *sqlite3) SqlType(c *core.Column) string { 159 switch t := c.SQLType.Name; t { 160 case core.Bool: 161 if c.Default == "true" { 162 c.Default = "1" 163 } else if c.Default == "false" { 164 c.Default = "0" 165 } 166 return core.Integer 167 case core.Date, core.DateTime, core.TimeStamp, core.Time: 168 return core.DateTime 169 case core.TimeStampz: 170 return core.Text 171 case core.Char, core.Varchar, core.NVarchar, core.TinyText, 172 core.Text, core.MediumText, core.LongText, core.Json: 173 return core.Text 174 case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt: 175 return core.Integer 176 case core.Float, core.Double, core.Real: 177 return core.Real 178 case core.Decimal, core.Numeric: 179 return core.Numeric 180 case core.TinyBlob, core.Blob, core.MediumBlob, core.LongBlob, core.Bytea, core.Binary, core.VarBinary: 181 return core.Blob 182 case core.Serial, core.BigSerial: 183 c.IsPrimaryKey = true 184 c.IsAutoIncrement = true 185 c.Nullable = false 186 return core.Integer 187 default: 188 return t 189 } 190 } 191 192 func (db *sqlite3) FormatBytes(bs []byte) string { 193 return fmt.Sprintf("X'%x'", bs) 194 } 195 196 func (db *sqlite3) SupportInsertMany() bool { 197 return true 198 } 199 200 func (db *sqlite3) IsReserved(name string) bool { 201 _, ok := sqlite3ReservedWords[name] 202 return ok 203 } 204 205 func (db *sqlite3) Quote(name string) string { 206 return "`" + name + "`" 207 } 208 209 func (db *sqlite3) QuoteStr() string { 210 return "`" 211 } 212 213 func (db *sqlite3) AutoIncrStr() string { 214 return "AUTOINCREMENT" 215 } 216 217 func (db *sqlite3) SupportEngine() bool { 218 return false 219 } 220 221 func (db *sqlite3) SupportCharset() bool { 222 return false 223 } 224 225 func (db *sqlite3) IndexOnTable() bool { 226 return false 227 } 228 229 func (db *sqlite3) IndexCheckSql(tableName, idxName string) (string, []interface{}) { 230 args := []interface{}{idxName} 231 return "SELECT name FROM sqlite_master WHERE type='index' and name = ?", args 232 } 233 234 func (db *sqlite3) TableCheckSql(tableName string) (string, []interface{}) { 235 args := []interface{}{tableName} 236 return "SELECT name FROM sqlite_master WHERE type='table' and name = ?", args 237 } 238 239 func (db *sqlite3) DropIndexSql(tableName string, index *core.Index) string { 240 //var unique string 241 quote := db.Quote 242 idxName := index.Name 243 244 if !strings.HasPrefix(idxName, "UQE_") && 245 !strings.HasPrefix(idxName, "IDX_") { 246 if index.Type == core.UniqueType { 247 idxName = fmt.Sprintf("UQE_%v_%v", tableName, index.Name) 248 } else { 249 idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name) 250 } 251 } 252 return fmt.Sprintf("DROP INDEX %v", quote(idxName)) 253 } 254 255 func (db *sqlite3) ForUpdateSql(query string) string { 256 return query 257 } 258 259 /*func (db *sqlite3) ColumnCheckSql(tableName, colName string) (string, []interface{}) { 260 args := []interface{}{tableName} 261 sql := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + colName + "`%') or (sql like '%[" + colName + "]%'))" 262 return sql, args 263 }*/ 264 265 func (db *sqlite3) IsColumnExist(tableName, colName string) (bool, error) { 266 args := []interface{}{tableName} 267 query := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + colName + "`%') or (sql like '%[" + colName + "]%'))" 268 db.LogSQL(query, args) 269 rows, err := db.DB().Query(query, args...) 270 if err != nil { 271 return false, err 272 } 273 defer rows.Close() 274 275 if rows.Next() { 276 return true, nil 277 } 278 return false, nil 279 } 280 281 func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { 282 args := []interface{}{tableName} 283 s := "SELECT sql FROM sqlite_master WHERE type='table' and name = ?" 284 db.LogSQL(s, args) 285 rows, err := db.DB().Query(s, args...) 286 if err != nil { 287 return nil, nil, err 288 } 289 defer rows.Close() 290 291 var name string 292 for rows.Next() { 293 err = rows.Scan(&name) 294 if err != nil { 295 return nil, nil, err 296 } 297 break 298 } 299 300 if name == "" { 301 return nil, nil, errors.New("no table named " + tableName) 302 } 303 304 nStart := strings.Index(name, "(") 305 nEnd := strings.LastIndex(name, ")") 306 reg := regexp.MustCompile(`[^\(,\)]*(\([^\(]*\))?`) 307 colCreates := reg.FindAllString(name[nStart+1:nEnd], -1) 308 cols := make(map[string]*core.Column) 309 colSeq := make([]string, 0) 310 for _, colStr := range colCreates { 311 reg = regexp.MustCompile(`,\s`) 312 colStr = reg.ReplaceAllString(colStr, ",") 313 fields := strings.Fields(strings.TrimSpace(colStr)) 314 col := new(core.Column) 315 col.Indexes = make(map[string]int) 316 col.Nullable = true 317 col.DefaultIsEmpty = true 318 for idx, field := range fields { 319 if idx == 0 { 320 col.Name = strings.Trim(field, "`[] ") 321 continue 322 } else if idx == 1 { 323 col.SQLType = core.SQLType{Name: field, DefaultLength: 0, DefaultLength2: 0} 324 } 325 switch field { 326 case "PRIMARY": 327 col.IsPrimaryKey = true 328 case "AUTOINCREMENT": 329 col.IsAutoIncrement = true 330 case "NULL": 331 if fields[idx-1] == "NOT" { 332 col.Nullable = false 333 } else { 334 col.Nullable = true 335 } 336 case "DEFAULT": 337 col.Default = fields[idx+1] 338 col.DefaultIsEmpty = false 339 } 340 } 341 if !col.SQLType.IsNumeric() && !col.DefaultIsEmpty { 342 col.Default = "'" + col.Default + "'" 343 } 344 cols[col.Name] = col 345 colSeq = append(colSeq, col.Name) 346 } 347 return colSeq, cols, nil 348 } 349 350 func (db *sqlite3) GetTables() ([]*core.Table, error) { 351 args := []interface{}{} 352 s := "SELECT name FROM sqlite_master WHERE type='table'" 353 db.LogSQL(s, args) 354 355 rows, err := db.DB().Query(s, args...) 356 if err != nil { 357 return nil, err 358 } 359 defer rows.Close() 360 361 tables := make([]*core.Table, 0) 362 for rows.Next() { 363 table := core.NewEmptyTable() 364 err = rows.Scan(&table.Name) 365 if err != nil { 366 return nil, err 367 } 368 if table.Name == "sqlite_sequence" { 369 continue 370 } 371 tables = append(tables, table) 372 } 373 return tables, nil 374 } 375 376 func (db *sqlite3) GetIndexes(tableName string) (map[string]*core.Index, error) { 377 args := []interface{}{tableName} 378 s := "SELECT sql FROM sqlite_master WHERE type='index' and tbl_name = ?" 379 db.LogSQL(s, args) 380 381 rows, err := db.DB().Query(s, args...) 382 if err != nil { 383 return nil, err 384 } 385 defer rows.Close() 386 387 indexes := make(map[string]*core.Index, 0) 388 for rows.Next() { 389 var tmpSql sql.NullString 390 err = rows.Scan(&tmpSql) 391 if err != nil { 392 return nil, err 393 } 394 395 if !tmpSql.Valid { 396 continue 397 } 398 sql := tmpSql.String 399 400 index := new(core.Index) 401 nNStart := strings.Index(sql, "INDEX") 402 nNEnd := strings.Index(sql, "ON") 403 if nNStart == -1 || nNEnd == -1 { 404 continue 405 } 406 407 indexName := strings.Trim(sql[nNStart+6:nNEnd], "` []") 408 if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { 409 index.Name = indexName[5+len(tableName) : len(indexName)] 410 } else { 411 index.Name = indexName 412 } 413 414 if strings.HasPrefix(sql, "CREATE UNIQUE INDEX") { 415 index.Type = core.UniqueType 416 } else { 417 index.Type = core.IndexType 418 } 419 420 nStart := strings.Index(sql, "(") 421 nEnd := strings.Index(sql, ")") 422 colIndexes := strings.Split(sql[nStart+1:nEnd], ",") 423 424 index.Cols = make([]string, 0) 425 for _, col := range colIndexes { 426 index.Cols = append(index.Cols, strings.Trim(col, "` []")) 427 } 428 indexes[index.Name] = index 429 } 430 431 return indexes, nil 432 } 433 434 func (db *sqlite3) Filters() []core.Filter { 435 return []core.Filter{&core.IdFilter{}} 436 }