Fix sqlite multiline query parse (#2367)
The app "DB Browser for SQLite" produces multiline queries in the `sqlite_master` table which xorm can't parse. Examples: ``` CREATE TABLE "push_mirror" ( id INTEGER not null primary key autoincrement, repo_id INTEGER, remote_name TEXT, interval INTEGER, created_unix INTEGER, last_update INTEGER, last_error TEXT, sync_on_commit INTEGER default 0 not null , `remote_address` TEXT NULL) ``` ``` CREATE INDEX "IDX_audit_event_action" ON "audit_event" ( "action" ) ``` Reviewed-on: https://gitea.com/xorm/xorm/pulls/2367 Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: KN4CK3R <admin@oldschoolhack.me> Co-committed-by: KN4CK3R <admin@oldschoolhack.me>
This commit is contained in:
parent
c855ca4e59
commit
529a264d8e
|
@ -11,6 +11,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"xorm.io/xorm/core"
|
"xorm.io/xorm/core"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
|
@ -320,7 +321,7 @@ func splitColStr(colStr string) []string {
|
||||||
var lastIdx int
|
var lastIdx int
|
||||||
var hasC, hasQuote bool
|
var hasC, hasQuote bool
|
||||||
for i, c := range colStr {
|
for i, c := range colStr {
|
||||||
if c == ' ' && !hasQuote {
|
if unicode.IsSpace(c) && !hasQuote {
|
||||||
if hasC {
|
if hasC {
|
||||||
results = append(results, colStr[lastIdx:i])
|
results = append(results, colStr[lastIdx:i])
|
||||||
hasC = false
|
hasC = false
|
||||||
|
@ -350,7 +351,7 @@ func parseString(colStr string) (*schemas.Column, error) {
|
||||||
|
|
||||||
for idx, field := range fields {
|
for idx, field := range fields {
|
||||||
if idx == 0 {
|
if idx == 0 {
|
||||||
col.Name = strings.Trim(strings.Trim(field, "`[] "), `"`)
|
col.Name = strings.Trim(strings.TrimSpace(field), "`[]'\"")
|
||||||
continue
|
continue
|
||||||
} else if idx == 1 {
|
} else if idx == 1 {
|
||||||
col.SQLType = schemas.SQLType{Name: field, DefaultLength: 0, DefaultLength2: 0}
|
col.SQLType = schemas.SQLType{Name: field, DefaultLength: 0, DefaultLength2: 0}
|
||||||
|
@ -400,6 +401,8 @@ func (db *sqlite3) GetColumns(queryer core.Queryer, ctx context.Context, tableNa
|
||||||
return nil, nil, errors.New("no table named " + tableName)
|
return nil, nil, errors.New("no table named " + tableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = strings.ReplaceAll(name, "\n", " ")
|
||||||
|
|
||||||
nStart := strings.Index(name, "(")
|
nStart := strings.Index(name, "(")
|
||||||
nEnd := strings.LastIndex(name, ")")
|
nEnd := strings.LastIndex(name, ")")
|
||||||
reg := regexp.MustCompile(`[^\(,\)]*(\([^\(]*\))?`)
|
reg := regexp.MustCompile(`[^\(,\)]*(\([^\(]*\))?`)
|
||||||
|
@ -483,7 +486,7 @@ func (db *sqlite3) GetIndexes(queryer core.Queryer, ctx context.Context, tableNa
|
||||||
if !tmpSQL.Valid {
|
if !tmpSQL.Valid {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
sql := tmpSQL.String
|
sql := strings.ReplaceAll(tmpSQL.String, "\n", " ")
|
||||||
|
|
||||||
index := new(schemas.Index)
|
index := new(schemas.Index)
|
||||||
nNStart := strings.Index(sql, "INDEX")
|
nNStart := strings.Index(sql, "INDEX")
|
||||||
|
|
|
@ -27,6 +27,13 @@ func TestSplitColStr(t *testing.T) {
|
||||||
"`created`", "DATETIME", "DEFAULT", "'2006-01-02 15:04:05'", "NULL",
|
"`created`", "DATETIME", "DEFAULT", "'2006-01-02 15:04:05'", "NULL",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
colStr: ` id INTEGER not null
|
||||||
|
primary key autoincrement`,
|
||||||
|
fields: []string{
|
||||||
|
"id", "INTEGER", "not null", "primary", "key", "autoincrement",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, kase := range kases {
|
for _, kase := range kases {
|
||||||
|
|
Loading…
Reference in New Issue