修复 schema 同步中的转义解析
This commit is contained in:
parent
056cbb38e7
commit
9891797591
38
Schema.go
38
Schema.go
@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"apigo.cc/go/cast"
|
"apigo.cc/go/cast"
|
||||||
@ -19,6 +20,39 @@ type SchemaGroup struct {
|
|||||||
var fieldSpliter = regexp.MustCompile(`\s+`)
|
var fieldSpliter = regexp.MustCompile(`\s+`)
|
||||||
var wnMatcher = regexp.MustCompile(`^([a-zA-Z]+)([0-9]+)$`)
|
var wnMatcher = regexp.MustCompile(`^([a-zA-Z]+)([0-9]+)$`)
|
||||||
|
|
||||||
|
func splitSchemaField(line string) []string {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if line == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if line[0] != '"' {
|
||||||
|
return fieldSpliter.Split(line, 10)
|
||||||
|
}
|
||||||
|
for i, escaped := 1, false; i < len(line); i++ {
|
||||||
|
if escaped {
|
||||||
|
escaped = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if line[i] == '\\' {
|
||||||
|
escaped = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if line[i] == '"' {
|
||||||
|
name, err := strconv.Unquote(line[:i+1])
|
||||||
|
if err != nil {
|
||||||
|
return fieldSpliter.Split(line, 10)
|
||||||
|
}
|
||||||
|
rest := strings.TrimSpace(line[i+1:])
|
||||||
|
parts := []string{name}
|
||||||
|
if rest != "" {
|
||||||
|
parts = append(parts, fieldSpliter.Split(rest, 9)...)
|
||||||
|
}
|
||||||
|
return parts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fieldSpliter.Split(line, 10)
|
||||||
|
}
|
||||||
|
|
||||||
// ParseField 解析单行字段描述
|
// ParseField 解析单行字段描述
|
||||||
func ParseField(line string) TableField {
|
func ParseField(line string) TableField {
|
||||||
lc := strings.SplitN(line, "//", 2)
|
lc := strings.SplitN(line, "//", 2)
|
||||||
@ -28,7 +62,7 @@ func ParseField(line string) TableField {
|
|||||||
comment = strings.TrimSpace(lc[1])
|
comment = strings.TrimSpace(lc[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
a := fieldSpliter.Split(line, 10)
|
a := splitSchemaField(line)
|
||||||
field := TableField{
|
field := TableField{
|
||||||
Name: a[0],
|
Name: a[0],
|
||||||
Type: "",
|
Type: "",
|
||||||
@ -309,8 +343,6 @@ func (db *DB) Sync(desc string) error {
|
|||||||
return outErr
|
return outErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// CheckTable 检查并同步单个表结构
|
// CheckTable 检查并同步单个表结构
|
||||||
func (db *DB) CheckTable(table *TableStruct) error {
|
func (db *DB) CheckTable(table *TableStruct) error {
|
||||||
fieldSets := make([]string, 0)
|
fieldSets := make([]string, 0)
|
||||||
|
|||||||
@ -8,6 +8,13 @@ import (
|
|||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestParseFieldQuotedName(t *testing.T) {
|
||||||
|
field := db.ParseField(`"Display Name 中文" v255 I // label`)
|
||||||
|
if field.Name != "Display Name 中文" || field.Type != "varchar(255)" || field.Index != "index" || field.Comment != "label" {
|
||||||
|
t.Fatalf("unexpected quoted field: %#v", field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSchemaSync(t *testing.T) {
|
func TestSchemaSync(t *testing.T) {
|
||||||
dbPath := "test_schema.db"
|
dbPath := "test_schema.db"
|
||||||
dbInst := db.GetDB("sqlite://"+dbPath, nil)
|
dbInst := db.GetDB("sqlite://"+dbPath, nil)
|
||||||
@ -57,4 +64,3 @@ func TestAutoDetectShadow(t *testing.T) {
|
|||||||
t.Fatal("Auto-detect shadow delete failed")
|
t.Fatal("Auto-detect shadow delete failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user