From 2575ccbb68b60dfe3da86e425db60a3956e5abaf Mon Sep 17 00:00:00 2001 From: k1LoW Date: Mon, 6 Aug 2018 22:45:55 +0900 Subject: [PATCH] Support CHECK constraints --- drivers/sqlite/sqlite.go | 46 +++++++++++++++++++++++++++++- drivers/sqlite/sqlite_test.go | 2 +- output/md/templates.go | 12 ++++---- sample/sqlite/check_constraints.md | 5 ++++ sample/sqlite/users.md | 1 + 5 files changed, 58 insertions(+), 8 deletions(-) diff --git a/drivers/sqlite/sqlite.go b/drivers/sqlite/sqlite.go index da73c94c..8f35b145 100644 --- a/drivers/sqlite/sqlite.go +++ b/drivers/sqlite/sqlite.go @@ -8,6 +8,7 @@ import ( "github.com/k1LoW/tbls/schema" "github.com/pkg/errors" + "regexp" ) // Sqlite struct @@ -311,7 +312,50 @@ func convertColumnNullable(str string) bool { } func parseCheckConstraints(sql string) []*schema.Constraint { - // TODO + // tokenize + re := regexp.MustCompile(`\s+`) + separator := "__SEP__" + space := "__SP__" + r1 := strings.NewReplacer("(", fmt.Sprintf("%s(%s", separator, separator), ")", fmt.Sprintf("%s)%s", separator, separator), ",", fmt.Sprintf("%s,%s", separator, separator)) + r2 := strings.NewReplacer(" ", fmt.Sprintf("%s%s%s", separator, space, separator)) + tokens := strings.Split(r1.Replace(r2.Replace(re.ReplaceAllString(sql, " "))), separator) + + r3 := strings.NewReplacer(space, " ") constraints := []*schema.Constraint{} + def := "" + counter := 0 + for _, v := range tokens { + if counter == 0 && (v == "CHECK" || v == "check") { + def = v + continue + } + if def != "" && v == space { + def = def + v + continue + } + if def != "" && v == "(" { + def = def + v + counter = counter + 1 + continue + } + if def != "" && v == ")" { + def = def + v + counter = counter - 1 + if counter == 0 { + constraint := &schema.Constraint{ + Name: "-", + Type: "CHECK", + Def: r3.Replace(def), + } + constraints = append(constraints, constraint) + def = "" + } + continue + } + if def != "" && counter > 0 { + def = def + v + } + } + return constraints } diff --git a/drivers/sqlite/sqlite_test.go b/drivers/sqlite/sqlite_test.go index 1120da8b..09b6bc0d 100644 --- a/drivers/sqlite/sqlite_test.go +++ b/drivers/sqlite/sqlite_test.go @@ -84,6 +84,6 @@ func TestParseCheckConstraints(t *testing.T) { } actual := parseCheckConstraints(sql) if !reflect.DeepEqual(actual, expected) { - t.Errorf("got: %v\nwant: %v", actual, expected) + t.Errorf("got: %#v\nwant: %#v", actual, expected) } } diff --git a/output/md/templates.go b/output/md/templates.go index afcf1d99..02a20cae 100644 --- a/output/md/templates.go +++ b/output/md/templates.go @@ -11,7 +11,12 @@ var _Assetsac44302fb6150a621aa9d04a0350aac972bf7e18 = "# {{ .Table.Name }}\n\n## // Assets returns go-assets FileSystem var Assets = assets.NewFileSystem(map[string][]string{"/": []string{"index.md.tmpl", "table.md.tmpl"}}, map[string]*assets.File{ - "/index.md.tmpl": &assets.File{ + "/": &assets.File{ + Path: "/", + FileMode: 0x800001ed, + Mtime: time.Unix(1532785399, 1532785399000000000), + Data: nil, + }, "/index.md.tmpl": &assets.File{ Path: "/index.md.tmpl", FileMode: 0x1a4, Mtime: time.Unix(1532239511, 1532239511000000000), @@ -21,9 +26,4 @@ var Assets = assets.NewFileSystem(map[string][]string{"/": []string{"index.md.tm FileMode: 0x1a4, Mtime: time.Unix(1532785399, 1532785399000000000), Data: []byte(_Assetsac44302fb6150a621aa9d04a0350aac972bf7e18), - }, "/": &assets.File{ - Path: "/", - FileMode: 0x800001ed, - Mtime: time.Unix(1532785399, 1532785399000000000), - Data: nil, }}, "") diff --git a/sample/sqlite/check_constraints.md b/sample/sqlite/check_constraints.md index e6cb5459..00a2c481 100644 --- a/sample/sqlite/check_constraints.md +++ b/sample/sqlite/check_constraints.md @@ -42,6 +42,11 @@ CREATE TABLE check_constraints ( | sqlite_autoindex_check_constraints_3 | UNIQUE | UNIQUE (downcase) | | sqlite_autoindex_check_constraints_2 | UNIQUE | UNIQUE (checkcheck) | | sqlite_autoindex_check_constraints_1 | UNIQUE | UNIQUE (brackets) | +| - | CHECK | CHECK(length(col) > 4) | +| - | CHECK | CHECK(((length(brackets) > 4))) | +| - | CHECK | CHECK(length(checkcheck) > 4) | +| - | CHECK | check(length(downcase) > 4) | +| - | CHECK | check(length(nl) > 4 OR nl != 'ln') | ## Indexes diff --git a/sample/sqlite/users.md b/sample/sqlite/users.md index d24ba3d3..41ac3ada 100644 --- a/sample/sqlite/users.md +++ b/sample/sqlite/users.md @@ -38,6 +38,7 @@ CREATE TABLE users ( | id | PRIMARY KEY | PRIMARY KEY (id) | | sqlite_autoindex_users_2 | UNIQUE | UNIQUE (email) | | sqlite_autoindex_users_1 | UNIQUE | UNIQUE (username) | +| - | CHECK | CHECK(length(username) > 4) | ## Indexes