2014-04-11 13:06:11 +00:00
|
|
|
package xorm
|
2013-06-04 08:56:59 +00:00
|
|
|
|
2013-10-13 15:57:57 +00:00
|
|
|
import (
|
2014-05-24 08:05:48 +00:00
|
|
|
"errors"
|
2014-05-04 05:53:38 +00:00
|
|
|
"fmt"
|
2013-12-18 03:31:32 +00:00
|
|
|
"strings"
|
2013-10-13 15:57:57 +00:00
|
|
|
|
2014-04-11 13:06:11 +00:00
|
|
|
"github.com/go-xorm/core"
|
2014-01-07 09:33:27 +00:00
|
|
|
)
|
2013-12-17 09:30:05 +00:00
|
|
|
|
2014-04-11 13:06:11 +00:00
|
|
|
// func init() {
|
|
|
|
// RegisterDialect("sqlite3", &sqlite3{})
|
|
|
|
// }
|
2013-12-17 09:30:05 +00:00
|
|
|
|
2014-01-07 09:33:27 +00:00
|
|
|
type sqlite3 struct {
|
2014-04-11 13:06:11 +00:00
|
|
|
core.Base
|
2013-06-04 08:56:59 +00:00
|
|
|
}
|
|
|
|
|
2014-04-18 10:39:07 +00:00
|
|
|
func (db *sqlite3) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error {
|
|
|
|
return db.Base.Init(d, db, uri, drivername, dataSourceName)
|
2013-09-28 15:14:42 +00:00
|
|
|
}
|
|
|
|
|
2014-04-11 13:06:11 +00:00
|
|
|
func (db *sqlite3) SqlType(c *core.Column) string {
|
2013-12-18 03:31:32 +00:00
|
|
|
switch t := c.SQLType.Name; t {
|
2014-04-11 13:06:11 +00:00
|
|
|
case core.Date, core.DateTime, core.TimeStamp, core.Time:
|
|
|
|
return core.Numeric
|
|
|
|
case core.TimeStampz:
|
|
|
|
return core.Text
|
|
|
|
case core.Char, core.Varchar, core.TinyText, core.Text, core.MediumText, core.LongText:
|
|
|
|
return core.Text
|
|
|
|
case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt, core.Bool:
|
|
|
|
return core.Integer
|
|
|
|
case core.Float, core.Double, core.Real:
|
|
|
|
return core.Real
|
|
|
|
case core.Decimal, core.Numeric:
|
|
|
|
return core.Numeric
|
|
|
|
case core.TinyBlob, core.Blob, core.MediumBlob, core.LongBlob, core.Bytea, core.Binary, core.VarBinary:
|
|
|
|
return core.Blob
|
|
|
|
case core.Serial, core.BigSerial:
|
2013-12-18 03:31:32 +00:00
|
|
|
c.IsPrimaryKey = true
|
|
|
|
c.IsAutoIncrement = true
|
|
|
|
c.Nullable = false
|
2014-04-11 13:06:11 +00:00
|
|
|
return core.Integer
|
2013-12-18 03:31:32 +00:00
|
|
|
default:
|
|
|
|
return t
|
|
|
|
}
|
2013-06-04 08:56:59 +00:00
|
|
|
}
|
2013-07-03 03:49:29 +00:00
|
|
|
|
2014-05-04 05:53:38 +00:00
|
|
|
func (db *sqlite3) FormatBytes(bs []byte) string {
|
|
|
|
return fmt.Sprintf("X'%x'", bs)
|
|
|
|
}
|
|
|
|
|
2013-07-03 03:49:29 +00:00
|
|
|
func (db *sqlite3) SupportInsertMany() bool {
|
2013-12-18 03:31:32 +00:00
|
|
|
return true
|
2013-07-03 03:49:29 +00:00
|
|
|
}
|
|
|
|
|
2013-08-08 05:24:38 +00:00
|
|
|
func (db *sqlite3) QuoteStr() string {
|
2013-12-18 03:31:32 +00:00
|
|
|
return "`"
|
2013-07-03 03:49:29 +00:00
|
|
|
}
|
|
|
|
|
2013-08-08 05:24:38 +00:00
|
|
|
func (db *sqlite3) AutoIncrStr() string {
|
2013-12-18 03:31:32 +00:00
|
|
|
return "AUTOINCREMENT"
|
2013-07-03 03:49:29 +00:00
|
|
|
}
|
2013-08-08 05:24:38 +00:00
|
|
|
|
|
|
|
func (db *sqlite3) SupportEngine() bool {
|
2013-12-18 03:31:32 +00:00
|
|
|
return false
|
2013-08-08 05:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (db *sqlite3) SupportCharset() bool {
|
2013-12-18 03:31:32 +00:00
|
|
|
return false
|
2013-08-08 05:24:38 +00:00
|
|
|
}
|
2013-09-26 07:19:39 +00:00
|
|
|
|
|
|
|
func (db *sqlite3) IndexOnTable() bool {
|
2013-12-18 03:31:32 +00:00
|
|
|
return false
|
2013-09-26 07:19:39 +00:00
|
|
|
}
|
2013-09-28 15:14:42 +00:00
|
|
|
|
|
|
|
func (db *sqlite3) IndexCheckSql(tableName, idxName string) (string, []interface{}) {
|
2013-12-18 03:31:32 +00:00
|
|
|
args := []interface{}{idxName}
|
|
|
|
return "SELECT name FROM sqlite_master WHERE type='index' and name = ?", args
|
2013-09-28 15:14:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (db *sqlite3) TableCheckSql(tableName string) (string, []interface{}) {
|
2013-12-18 03:31:32 +00:00
|
|
|
args := []interface{}{tableName}
|
|
|
|
return "SELECT name FROM sqlite_master WHERE type='table' and name = ?", args
|
2013-09-28 15:14:42 +00:00
|
|
|
}
|
|
|
|
|
2014-04-23 06:01:04 +00:00
|
|
|
/*func (db *sqlite3) ColumnCheckSql(tableName, colName string) (string, []interface{}) {
|
2013-12-18 03:31:32 +00:00
|
|
|
args := []interface{}{tableName}
|
|
|
|
sql := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + colName + "`%') or (sql like '%[" + colName + "]%'))"
|
|
|
|
return sql, args
|
2014-04-23 06:01:04 +00:00
|
|
|
}*/
|
|
|
|
|
|
|
|
func (db *sqlite3) IsColumnExist(tableName string, col *core.Column) (bool, error) {
|
|
|
|
args := []interface{}{tableName}
|
|
|
|
query := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + col.Name + "`%') or (sql like '%[" + col.Name + "]%'))"
|
|
|
|
rows, err := db.DB().Query(query, args...)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
if rows.Next() {
|
|
|
|
return true, nil
|
|
|
|
}
|
2014-05-14 12:26:42 +00:00
|
|
|
return false, nil
|
2013-09-28 15:14:42 +00:00
|
|
|
}
|
2013-10-12 15:16:51 +00:00
|
|
|
|
2014-04-11 13:06:11 +00:00
|
|
|
func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
|
2013-12-18 03:31:32 +00:00
|
|
|
args := []interface{}{tableName}
|
|
|
|
s := "SELECT sql FROM sqlite_master WHERE type='table' and name = ?"
|
2014-01-07 09:33:27 +00:00
|
|
|
|
2014-04-18 10:39:07 +00:00
|
|
|
rows, err := db.DB().Query(s, args...)
|
2013-12-18 03:31:32 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2014-01-07 09:33:27 +00:00
|
|
|
defer rows.Close()
|
2013-12-18 03:31:32 +00:00
|
|
|
|
2014-01-07 09:33:27 +00:00
|
|
|
var name string
|
|
|
|
for rows.Next() {
|
|
|
|
err = rows.Scan(&name)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
2013-12-18 03:31:32 +00:00
|
|
|
}
|
2014-05-24 08:05:48 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
if name == "" {
|
|
|
|
return nil, nil, errors.New("no table named " + tableName)
|
2013-12-18 03:31:32 +00:00
|
|
|
}
|
|
|
|
|
2014-01-07 09:33:27 +00:00
|
|
|
nStart := strings.Index(name, "(")
|
2014-07-03 15:35:31 +00:00
|
|
|
nEnd := strings.LastIndex(name, ")")
|
2014-01-07 09:33:27 +00:00
|
|
|
colCreates := strings.Split(name[nStart+1:nEnd], ",")
|
2014-04-11 13:06:11 +00:00
|
|
|
cols := make(map[string]*core.Column)
|
2013-12-18 03:31:32 +00:00
|
|
|
colSeq := make([]string, 0)
|
|
|
|
for _, colStr := range colCreates {
|
|
|
|
fields := strings.Fields(strings.TrimSpace(colStr))
|
2014-04-11 13:06:11 +00:00
|
|
|
col := new(core.Column)
|
2013-12-18 03:31:32 +00:00
|
|
|
col.Indexes = make(map[string]bool)
|
|
|
|
col.Nullable = true
|
|
|
|
for idx, field := range fields {
|
|
|
|
if idx == 0 {
|
|
|
|
col.Name = strings.Trim(field, "`[] ")
|
|
|
|
continue
|
|
|
|
} else if idx == 1 {
|
2014-04-11 13:06:11 +00:00
|
|
|
col.SQLType = core.SQLType{field, 0, 0}
|
2013-12-18 03:31:32 +00:00
|
|
|
}
|
|
|
|
switch field {
|
|
|
|
case "PRIMARY":
|
|
|
|
col.IsPrimaryKey = true
|
|
|
|
case "AUTOINCREMENT":
|
|
|
|
col.IsAutoIncrement = true
|
|
|
|
case "NULL":
|
|
|
|
if fields[idx-1] == "NOT" {
|
|
|
|
col.Nullable = false
|
|
|
|
} else {
|
|
|
|
col.Nullable = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cols[col.Name] = col
|
|
|
|
colSeq = append(colSeq, col.Name)
|
|
|
|
}
|
|
|
|
return colSeq, cols, nil
|
2013-10-12 15:16:51 +00:00
|
|
|
}
|
|
|
|
|
2014-04-11 13:06:11 +00:00
|
|
|
func (db *sqlite3) GetTables() ([]*core.Table, error) {
|
2013-12-18 03:31:32 +00:00
|
|
|
args := []interface{}{}
|
|
|
|
s := "SELECT name FROM sqlite_master WHERE type='table'"
|
|
|
|
|
2014-04-18 10:39:07 +00:00
|
|
|
rows, err := db.DB().Query(s, args...)
|
2013-12-18 03:31:32 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2014-01-07 09:33:27 +00:00
|
|
|
defer rows.Close()
|
2013-12-18 03:31:32 +00:00
|
|
|
|
2014-04-11 13:06:11 +00:00
|
|
|
tables := make([]*core.Table, 0)
|
2014-01-07 09:33:27 +00:00
|
|
|
for rows.Next() {
|
2014-04-11 13:06:11 +00:00
|
|
|
table := core.NewEmptyTable()
|
2014-01-07 09:33:27 +00:00
|
|
|
err = rows.Scan(&table.Name)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-12-18 03:31:32 +00:00
|
|
|
}
|
|
|
|
if table.Name == "sqlite_sequence" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
tables = append(tables, table)
|
|
|
|
}
|
|
|
|
return tables, nil
|
2013-10-12 15:16:51 +00:00
|
|
|
}
|
|
|
|
|
2014-04-11 13:06:11 +00:00
|
|
|
func (db *sqlite3) GetIndexes(tableName string) (map[string]*core.Index, error) {
|
2013-12-18 03:31:32 +00:00
|
|
|
args := []interface{}{tableName}
|
|
|
|
s := "SELECT sql FROM sqlite_master WHERE type='index' and tbl_name = ?"
|
2014-04-18 10:39:07 +00:00
|
|
|
|
|
|
|
rows, err := db.DB().Query(s, args...)
|
2013-12-18 03:31:32 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2014-01-07 09:33:27 +00:00
|
|
|
defer rows.Close()
|
2013-12-18 03:31:32 +00:00
|
|
|
|
2014-04-11 13:06:11 +00:00
|
|
|
indexes := make(map[string]*core.Index, 0)
|
2014-01-07 09:33:27 +00:00
|
|
|
for rows.Next() {
|
|
|
|
var sql string
|
|
|
|
err = rows.Scan(&sql)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2013-12-24 10:18:48 +00:00
|
|
|
|
|
|
|
if sql == "" {
|
|
|
|
continue
|
2013-12-18 03:31:32 +00:00
|
|
|
}
|
|
|
|
|
2014-04-11 13:06:11 +00:00
|
|
|
index := new(core.Index)
|
2013-12-18 03:31:32 +00:00
|
|
|
nNStart := strings.Index(sql, "INDEX")
|
|
|
|
nNEnd := strings.Index(sql, "ON")
|
2013-12-24 10:18:48 +00:00
|
|
|
if nNStart == -1 || nNEnd == -1 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2013-12-18 03:31:32 +00:00
|
|
|
indexName := strings.Trim(sql[nNStart+6:nNEnd], "` []")
|
|
|
|
//fmt.Println(indexName)
|
|
|
|
if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) {
|
|
|
|
index.Name = indexName[5+len(tableName) : len(indexName)]
|
|
|
|
} else {
|
|
|
|
index.Name = indexName
|
|
|
|
}
|
|
|
|
|
|
|
|
if strings.HasPrefix(sql, "CREATE UNIQUE INDEX") {
|
2014-04-11 13:06:11 +00:00
|
|
|
index.Type = core.UniqueType
|
2013-12-18 03:31:32 +00:00
|
|
|
} else {
|
2014-04-11 13:06:11 +00:00
|
|
|
index.Type = core.IndexType
|
2013-12-18 03:31:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nStart := strings.Index(sql, "(")
|
|
|
|
nEnd := strings.Index(sql, ")")
|
|
|
|
colIndexes := strings.Split(sql[nStart+1:nEnd], ",")
|
|
|
|
|
|
|
|
index.Cols = make([]string, 0)
|
|
|
|
for _, col := range colIndexes {
|
|
|
|
index.Cols = append(index.Cols, strings.Trim(col, "` []"))
|
|
|
|
}
|
|
|
|
indexes[index.Name] = index
|
|
|
|
}
|
|
|
|
|
|
|
|
return indexes, nil
|
2013-10-12 15:16:51 +00:00
|
|
|
}
|
2014-01-07 09:33:27 +00:00
|
|
|
|
2014-04-11 13:06:11 +00:00
|
|
|
func (db *sqlite3) Filters() []core.Filter {
|
|
|
|
return []core.Filter{&core.IdFilter{}}
|
2014-01-07 09:33:27 +00:00
|
|
|
}
|