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:
KN4CK3R 2023-12-01 07:07:35 +00:00 committed by Lunny Xiao
parent c855ca4e59
commit 529a264d8e
2 changed files with 13 additions and 3 deletions

View File

@ -11,6 +11,7 @@ import (
"fmt"
"regexp"
"strings"
"unicode"
"xorm.io/xorm/core"
"xorm.io/xorm/schemas"
@ -320,7 +321,7 @@ func splitColStr(colStr string) []string {
var lastIdx int
var hasC, hasQuote bool
for i, c := range colStr {
if c == ' ' && !hasQuote {
if unicode.IsSpace(c) && !hasQuote {
if hasC {
results = append(results, colStr[lastIdx:i])
hasC = false
@ -350,7 +351,7 @@ func parseString(colStr string) (*schemas.Column, error) {
for idx, field := range fields {
if idx == 0 {
col.Name = strings.Trim(strings.Trim(field, "`[] "), `"`)
col.Name = strings.Trim(strings.TrimSpace(field), "`[]'\"")
continue
} else if idx == 1 {
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)
}
name = strings.ReplaceAll(name, "\n", " ")
nStart := strings.Index(name, "(")
nEnd := strings.LastIndex(name, ")")
reg := regexp.MustCompile(`[^\(,\)]*(\([^\(]*\))?`)
@ -483,7 +486,7 @@ func (db *sqlite3) GetIndexes(queryer core.Queryer, ctx context.Context, tableNa
if !tmpSQL.Valid {
continue
}
sql := tmpSQL.String
sql := strings.ReplaceAll(tmpSQL.String, "\n", " ")
index := new(schemas.Index)
nNStart := strings.Index(sql, "INDEX")

View File

@ -27,6 +27,13 @@ func TestSplitColStr(t *testing.T) {
"`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 {