From 529a264d8e18fc972ab095aae394328919e83807 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Fri, 1 Dec 2023 07:07:35 +0000 Subject: [PATCH] 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 Co-authored-by: KN4CK3R Co-committed-by: KN4CK3R --- dialects/sqlite3.go | 9 ++++++--- dialects/sqlite3_test.go | 7 +++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/dialects/sqlite3.go b/dialects/sqlite3.go index 62519b6b..ece360e7 100644 --- a/dialects/sqlite3.go +++ b/dialects/sqlite3.go @@ -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") diff --git a/dialects/sqlite3_test.go b/dialects/sqlite3_test.go index aa6c3cea..ec973ae6 100644 --- a/dialects/sqlite3_test.go +++ b/dialects/sqlite3_test.go @@ -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 {