diff --git a/config/config.go b/config/config.go index a639c736..afcfb7aa 100644 --- a/config/config.go +++ b/config/config.go @@ -206,7 +206,7 @@ func Exclude(e []string) Option { } } -// IncludeLabels return Option set Config.IncludeLabels +// IncludeLabels return Option set Config.includeLabels func IncludeLabels(l []string) Option { return func(c *Config) error { if len(l) > 0 { @@ -226,7 +226,7 @@ func New() (*Config, error) { return &c, nil } -// Load load config with all method +// Load config with all method func (c *Config) Load(configPath string, options ...Option) error { if err := c.LoadConfigFile(configPath); err != nil { return err diff --git a/config/config_test.go b/config/config_test.go index e049dd2e..0efa8e16 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/k1LoW/tbls/schema" + "github.com/tenntenn/golden" ) func TestLoadDefault(t *testing.T) { @@ -179,10 +180,6 @@ func TestFilterTables(t *testing.T) { if err != nil { t.Error(err) } - err = c.LoadConfigFile(filepath.Join(testdataDir(), "config_test_tbls.yml")) - if err != nil { - t.Error(err) - } tests := []struct { include []string exclude []string @@ -222,8 +219,8 @@ func TestFilterTables(t *testing.T) { {[]string{"users"}, []string{}, []string{"private"}, 0, 2, 1}, } for i, tt := range tests { - t.Run(fmt.Sprintf("%d.%v%v", i, tt.include, tt.exclude), func(t *testing.T) { - s := newSchemaForTestFilterTables(t) + t.Run(fmt.Sprintf("%d.%v%v%v", i, tt.include, tt.exclude, tt.labels), func(t *testing.T) { + s := newTestSchemaViaJSON(t) c.Include = tt.include c.Exclude = tt.exclude c.includeLabels = tt.labels @@ -243,100 +240,46 @@ func TestFilterTables(t *testing.T) { } func TestModifySchema(t *testing.T) { - s := schema.Schema{ - Name: "testschema", - Tables: []*schema.Table{ - &schema.Table{ - Name: "users", - Comment: "users comment", - Columns: []*schema.Column{ - &schema.Column{ - Name: "id", - Type: "serial", - }, - &schema.Column{ - Name: "username", - Type: "text", - }, - }, - Indexes: []*schema.Index{ - &schema.Index{ - Name: "user_index", - }, - }, - Constraints: []*schema.Constraint{ - &schema.Constraint{ - Name: "PRIMARY", - }, - }, - }, - &schema.Table{ - Name: "posts", - Comment: "posts comment", - Columns: []*schema.Column{ - &schema.Column{ - Name: "id", - Type: "serial", - }, - &schema.Column{ - Name: "user_id", - Type: "int", - }, - &schema.Column{ - Name: "title", - Type: "text", - }, - }, - Triggers: []*schema.Trigger{ - &schema.Trigger{ - Name: "update_posts_title", - }, - }, - }, - &schema.Table{ - Name: "migrations", - Columns: []*schema.Column{ - &schema.Column{ - Name: "id", - Type: "serial", - }, - &schema.Column{ - Name: "name", - Type: "text", - }, - }, - }, - }, - } c, err := New() if err != nil { t.Error(err) } - err = c.LoadConfigFile(filepath.Join(testdataDir(), "config_test_tbls.yml")) - if err != nil { - t.Error(err) - } - err = c.ModifySchema(&s) - if err != nil { - t.Error(err) + tests := []struct { + name string + desc string + labels []string + comments []AdditionalComment + relations []AdditionalRelation + }{ + {"", "", []string{}, nil, nil}, + {"mod_name_and_desc", "this is test schema", []string{}, nil, nil}, } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c.Name = tt.name + c.Desc = tt.desc + c.Labels = tt.labels + c.Comments = tt.comments + c.Relations = tt.relations + s := newTestSchemaViaJSON(t) + err = c.ModifySchema(s) + if err != nil { + t.Error(err) + } - if want := 1; len(s.Relations) != want { - t.Errorf("got %v\nwant %v", len(s.Relations), want) - } - posts, _ := s.FindTableByName("posts") - title, _ := posts.FindColumnByName("title") - if want := "post title"; title.Comment != want { - t.Errorf("got %v\nwant %v", title.Comment, want) - } - if want := 2; len(title.Labels) != want { - t.Errorf("got %v\nwant %v", len(title.Labels), want) - } - if want := 2; len(s.Tables) != want { - t.Errorf("got %v\nwant %v", len(s.Tables), want) - } - if want := "mydatabase"; s.Name != want { - t.Errorf("got %v\nwant %v", s.Name, want) + got, err := json.MarshalIndent(s, "", " ") + if err != nil { + t.Error(err) + } + f := fmt.Sprintf("modify_schema_%s", tt.name) + if os.Getenv("UPDATE_GOLDEN") != "" { + golden.Update(t, testdataDir(), f, got) + return + } + if diff := golden.Diff(t, testdataDir(), f, got); diff != "" { + t.Error(diff) + } + }) } } @@ -559,10 +502,10 @@ func TestCheckVersion(t *testing.T) { } } -func newSchemaForTestFilterTables(t *testing.T) *schema.Schema { +func newTestSchemaViaJSON(t *testing.T) *schema.Schema { t.Helper() s := &schema.Schema{} - file, err := os.Open(filepath.Join(testdataDir(), "filter_tables.json")) + file, err := os.Open(filepath.Join(testdataDir(), "test_schema.json")) if err != nil { t.Fatal(err) } diff --git a/docker-compose.yml b/docker-compose.yml index 0689ad20..cb8af728 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -67,6 +67,6 @@ services: - MONGO_INITDB_ROOT_PASSWORD=secret - MONGO_INITDB_DATABASE=test volumes: - - ./testdata/ddl/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro + - ./testdata/ddl/mongo:/docker-entrypoint-initdb.d ports: - "27017:27017" diff --git a/go.mod b/go.mod index 7295bd1b..8424382e 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 github.com/snowflakedb/gosnowflake v1.6.16 github.com/spf13/cobra v1.6.1 + github.com/tenntenn/golden v0.4.0 github.com/xo/dburl v0.13.0 gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84 go.mongodb.org/mongo-driver v1.11.1 @@ -86,6 +87,8 @@ require ( github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/josharian/mapfs v0.0.0-20210615234106-095c008854e6 // indirect + github.com/josharian/txtarfs v0.0.0-20210615234325-77aca6df5bca // indirect github.com/k1LoW/fontdir v0.1.0 // indirect github.com/klauspost/compress v1.15.11 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -110,6 +113,7 @@ require ( golang.org/x/sys v0.4.0 // indirect golang.org/x/term v0.4.0 // indirect golang.org/x/text v0.6.0 // indirect + golang.org/x/tools v0.1.12 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect diff --git a/go.sum b/go.sum index b7cfaf8d..9e9f3ab5 100644 --- a/go.sum +++ b/go.sum @@ -248,6 +248,10 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/josharian/mapfs v0.0.0-20210615234106-095c008854e6 h1:c+ctPFdISggaSNCfU1IueNBAsqetJSvMcpQlT+0OVdY= +github.com/josharian/mapfs v0.0.0-20210615234106-095c008854e6/go.mod h1:Rv/momJI8DgrWnBZip+SgagpcgORIZQE5SERlxNb8LY= +github.com/josharian/txtarfs v0.0.0-20210615234325-77aca6df5bca h1:a8xeK4GsWLE4LYo5VI4u1Cn7ZvT1NtXouXR3DdKLB8Q= +github.com/josharian/txtarfs v0.0.0-20210615234325-77aca6df5bca/go.mod h1:UbC32ft9G/jG+sZI8wLbIBNIrYr7vp/yqMDa9SxVBNA= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/k1LoW/duration v1.2.0 h1:qq1gWtPh7YROFyerBufVP+ATR11mOOHDInrcC/Xe/6A= @@ -361,6 +365,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tenntenn/golden v0.4.0 h1:ghZvhG1A3zp3JKBBywTt4GRJ4ieCtZi6Xw20kt8fpy0= +github.com/tenntenn/golden v0.4.0/go.mod h1:0xI/4lpoHR65AUTmd1RKR9S1Uv0JR3yR2Q1Ob2bKqQA= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= @@ -376,6 +382,7 @@ github.com/xo/dburl v0.13.0 h1:kq+oD1j/m8DnJ/p6G/LQXRosVchs8q5/AszEUKkvYfo= github.com/xo/dburl v0.13.0/go.mod h1:K6rSPgbVqP3ZFT0RHkdg/M3M5KhLeV2MaS/ZqaLd1kA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84 h1:qqjvoVXdWIcZCLPMlzgA7P9FZWdPGPvP/l3ef8GzV6o= @@ -424,6 +431,7 @@ golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -459,6 +467,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= @@ -521,7 +530,9 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/schema/schema.go b/schema/schema.go index 698b3c71..b6d56501 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -167,7 +167,7 @@ func (s *Schema) FindTableByName(name string) (*Table, error) { return nil, errors.Errorf("not found table '%s'", name) } -// FindRelation ... +// FindRelation find relation by columns and parent colums func (s *Schema) FindRelation(cs, pcs []*Column) (*Relation, error) { L: for _, r := range s.Relations { diff --git a/testdata/ddl/mongo-init.js b/testdata/ddl/mongo/init.js similarity index 100% rename from testdata/ddl/mongo-init.js rename to testdata/ddl/mongo/init.js diff --git a/testdata/ddl/filter_tables.sql b/testdata/ddl/test_schema.sql similarity index 82% rename from testdata/ddl/filter_tables.sql rename to testdata/ddl/test_schema.sql index b53e2ad2..3f7a178a 100644 --- a/testdata/ddl/filter_tables.sql +++ b/testdata/ddl/test_schema.sql @@ -1,3 +1,4 @@ +DROP TRIGGER IF EXISTS update_posts_updated; DROP TABLE IF EXISTS schema_migrations; DROP TABLE IF EXISTS user_options; DROP TABLE IF EXISTS posts; @@ -22,6 +23,7 @@ CREATE TABLE posts ( CONSTRAINT posts_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT posts_category_id_fk FOREIGN KEY(category_id) REFERENCES categories(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE ); +CREATE INDEX posts_user_id_idx ON posts(user_id); CREATE TABLE user_options ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -34,3 +36,8 @@ CREATE TABLE schema_migrations ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL ); + +CREATE TRIGGER update_posts_updated AFTER UPDATE ON posts FOR EACH ROW +BEGIN + UPDATE posts SET updated = current_timestamp WHERE id = OLD.id; +END; diff --git a/testdata/modify_schema_.golden b/testdata/modify_schema_.golden new file mode 100644 index 00000000..d1af918c --- /dev/null +++ b/testdata/modify_schema_.golden @@ -0,0 +1,407 @@ +{ + "name": "testdb.sqlite3", + "desc": "", + "tables": [ + { + "name": "users", + "type": "table", + "comment": "users comment", + "columns": [ + { + "name": "id", + "type": "INTEGER", + "nullable": true, + "default": null, + "comment": "" + }, + { + "name": "username", + "type": "TEXT", + "nullable": false, + "default": null, + "comment": "" + } + ], + "indexes": [ + { + "name": "sqlite_autoindex_users_1", + "def": "UNIQUE (username)", + "table": "users", + "columns": [ + "username" + ], + "comment": "" + } + ], + "constraints": [ + { + "name": "id", + "type": "PRIMARY KEY", + "def": "PRIMARY KEY (id)", + "table": "users", + "referenced_table": null, + "columns": [ + "id" + ], + "referenced_columns": null, + "comment": "" + }, + { + "name": "sqlite_autoindex_users_1", + "type": "UNIQUE", + "def": "UNIQUE (username)", + "table": "users", + "referenced_table": null, + "columns": [ + "username" + ], + "referenced_columns": null, + "comment": "" + }, + { + "name": "-", + "type": "CHECK", + "def": "CHECK(length(username) \u003e 4)", + "table": "users", + "referenced_table": null, + "columns": [ + "username" + ], + "referenced_columns": null, + "comment": "" + } + ], + "triggers": [], + "def": "CREATE TABLE users (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n username TEXT UNIQUE NOT NULL CHECK(length(username) \u003e 4)\n)", + "labels": [ + { + "Name": "private", + "Virtual": true + } + ] + }, + { + "name": "categories", + "type": "table", + "comment": "", + "columns": [ + { + "name": "id", + "type": "INTEGER", + "nullable": true, + "default": null, + "comment": "" + }, + { + "name": "name", + "type": "TEXT", + "nullable": false, + "default": null, + "comment": "" + } + ], + "indexes": [ + { + "name": "sqlite_autoindex_categories_1", + "def": "UNIQUE (name)", + "table": "categories", + "columns": [ + "name" + ], + "comment": "" + } + ], + "constraints": [ + { + "name": "id", + "type": "PRIMARY KEY", + "def": "PRIMARY KEY (id)", + "table": "categories", + "referenced_table": null, + "columns": [ + "id" + ], + "referenced_columns": null, + "comment": "" + }, + { + "name": "sqlite_autoindex_categories_1", + "type": "UNIQUE", + "def": "UNIQUE (name)", + "table": "categories", + "referenced_table": null, + "columns": [ + "name" + ], + "referenced_columns": null, + "comment": "" + } + ], + "triggers": [], + "def": "CREATE TABLE categories (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT UNIQUE NOT NULL\n)", + "labels": [ + { + "Name": "public", + "Virtual": true + }, + { + "Name": "option", + "Virtual": true + } + ] + }, + { + "name": "posts", + "type": "table", + "comment": "", + "columns": [ + { + "name": "id", + "type": "INTEGER", + "nullable": true, + "default": null, + "comment": "" + }, + { + "name": "user_id", + "type": "INTEGER", + "nullable": false, + "default": null, + "comment": "" + }, + { + "name": "category_id", + "type": "INTEGER", + "nullable": false, + "default": null, + "comment": "" + }, + { + "name": "title", + "type": "TEXT", + "nullable": false, + "default": null, + "comment": "" + } + ], + "indexes": [ + { + "name": "posts_user_id_idx", + "def": "CREATE INDEX posts_user_id_idx ON posts(user_id)", + "table": "posts", + "columns": [ + "user_id" + ], + "comment": "" + } + ], + "constraints": [ + { + "name": "id", + "type": "PRIMARY KEY", + "def": "PRIMARY KEY (id)", + "table": "posts", + "referenced_table": null, + "columns": [ + "id" + ], + "referenced_columns": null, + "comment": "" + }, + { + "name": "- (Foreign key ID: 0)", + "type": "FOREIGN KEY", + "def": "FOREIGN KEY (category_id) REFERENCES categories (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "table": "posts", + "referenced_table": "categories", + "columns": [ + "category_id" + ], + "referenced_columns": [ + "id" + ], + "comment": "" + }, + { + "name": "- (Foreign key ID: 1)", + "type": "FOREIGN KEY", + "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "table": "posts", + "referenced_table": "users", + "columns": [ + "user_id" + ], + "referenced_columns": [ + "id" + ], + "comment": "" + } + ], + "triggers": [ + { + "name": "update_posts_updated", + "def": "CREATE TRIGGER update_posts_updated AFTER UPDATE ON posts FOR EACH ROW\nBEGIN\n UPDATE posts SET updated = current_timestamp WHERE id = OLD.id;\nEND", + "comment": "" + } + ], + "def": "CREATE TABLE posts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n user_id INTEGER NOT NULL,\n category_id INTEGER NOT NULL,\n title TEXT NOT NULL,\n CONSTRAINT posts_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE,\n CONSTRAINT posts_category_id_fk FOREIGN KEY(category_id) REFERENCES categories(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE\n)", + "labels": [ + { + "Name": "public", + "Virtual": true + } + ] + }, + { + "name": "user_options", + "type": "table", + "comment": "", + "columns": [ + { + "name": "id", + "type": "INTEGER", + "nullable": true, + "default": null, + "comment": "" + }, + { + "name": "user_id", + "type": "INTEGER", + "nullable": false, + "default": null, + "comment": "" + }, + { + "name": "email", + "type": "TEXT", + "nullable": false, + "default": null, + "comment": "" + } + ], + "indexes": [], + "constraints": [ + { + "name": "id", + "type": "PRIMARY KEY", + "def": "PRIMARY KEY (id)", + "table": "user_options", + "referenced_table": null, + "columns": [ + "id" + ], + "referenced_columns": null, + "comment": "" + }, + { + "name": "- (Foreign key ID: 0)", + "type": "FOREIGN KEY", + "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "table": "user_options", + "referenced_table": "users", + "columns": [ + "user_id" + ], + "referenced_columns": [ + "id" + ], + "comment": "" + } + ], + "triggers": [], + "def": "CREATE TABLE user_options (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n user_id INTEGER NOT NULL,\n email TEXT NOT NULL,\n CONSTRAINT user_options_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE\n)", + "labels": [ + { + "Name": "private", + "Virtual": true + }, + { + "Name": "option", + "Virtual": true + } + ] + }, + { + "name": "schema_migrations", + "type": "table", + "comment": "", + "columns": [ + { + "name": "id", + "type": "INTEGER", + "nullable": true, + "default": null, + "comment": "" + }, + { + "name": "name", + "type": "TEXT", + "nullable": false, + "default": null, + "comment": "" + } + ], + "indexes": [], + "constraints": [ + { + "name": "id", + "type": "PRIMARY KEY", + "def": "PRIMARY KEY (id)", + "table": "schema_migrations", + "referenced_table": null, + "columns": [ + "id" + ], + "referenced_columns": null, + "comment": "" + } + ], + "triggers": [], + "def": "CREATE TABLE schema_migrations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL\n)" + } + ], + "relations": [ + { + "table": "posts", + "columns": [ + "category_id" + ], + "parent_table": "categories", + "parent_columns": [ + "id" + ], + "def": "FOREIGN KEY (category_id) REFERENCES categories (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "virtual": false + }, + { + "table": "posts", + "columns": [ + "user_id" + ], + "parent_table": "users", + "parent_columns": [ + "id" + ], + "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "virtual": false + }, + { + "table": "user_options", + "columns": [ + "user_id" + ], + "parent_table": "users", + "parent_columns": [ + "id" + ], + "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "virtual": false + } + ], + "functions": null, + "driver": { + "name": "sqlite", + "database_version": "3.39.4", + "meta": {} + } +} \ No newline at end of file diff --git a/testdata/modify_schema_mod_name_and_desc.golden b/testdata/modify_schema_mod_name_and_desc.golden new file mode 100644 index 00000000..c103e020 --- /dev/null +++ b/testdata/modify_schema_mod_name_and_desc.golden @@ -0,0 +1,407 @@ +{ + "name": "mod_name_and_desc", + "desc": "this is test schema", + "tables": [ + { + "name": "users", + "type": "table", + "comment": "users comment", + "columns": [ + { + "name": "id", + "type": "INTEGER", + "nullable": true, + "default": null, + "comment": "" + }, + { + "name": "username", + "type": "TEXT", + "nullable": false, + "default": null, + "comment": "" + } + ], + "indexes": [ + { + "name": "sqlite_autoindex_users_1", + "def": "UNIQUE (username)", + "table": "users", + "columns": [ + "username" + ], + "comment": "" + } + ], + "constraints": [ + { + "name": "id", + "type": "PRIMARY KEY", + "def": "PRIMARY KEY (id)", + "table": "users", + "referenced_table": null, + "columns": [ + "id" + ], + "referenced_columns": null, + "comment": "" + }, + { + "name": "sqlite_autoindex_users_1", + "type": "UNIQUE", + "def": "UNIQUE (username)", + "table": "users", + "referenced_table": null, + "columns": [ + "username" + ], + "referenced_columns": null, + "comment": "" + }, + { + "name": "-", + "type": "CHECK", + "def": "CHECK(length(username) \u003e 4)", + "table": "users", + "referenced_table": null, + "columns": [ + "username" + ], + "referenced_columns": null, + "comment": "" + } + ], + "triggers": [], + "def": "CREATE TABLE users (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n username TEXT UNIQUE NOT NULL CHECK(length(username) \u003e 4)\n)", + "labels": [ + { + "Name": "private", + "Virtual": true + } + ] + }, + { + "name": "categories", + "type": "table", + "comment": "", + "columns": [ + { + "name": "id", + "type": "INTEGER", + "nullable": true, + "default": null, + "comment": "" + }, + { + "name": "name", + "type": "TEXT", + "nullable": false, + "default": null, + "comment": "" + } + ], + "indexes": [ + { + "name": "sqlite_autoindex_categories_1", + "def": "UNIQUE (name)", + "table": "categories", + "columns": [ + "name" + ], + "comment": "" + } + ], + "constraints": [ + { + "name": "id", + "type": "PRIMARY KEY", + "def": "PRIMARY KEY (id)", + "table": "categories", + "referenced_table": null, + "columns": [ + "id" + ], + "referenced_columns": null, + "comment": "" + }, + { + "name": "sqlite_autoindex_categories_1", + "type": "UNIQUE", + "def": "UNIQUE (name)", + "table": "categories", + "referenced_table": null, + "columns": [ + "name" + ], + "referenced_columns": null, + "comment": "" + } + ], + "triggers": [], + "def": "CREATE TABLE categories (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT UNIQUE NOT NULL\n)", + "labels": [ + { + "Name": "public", + "Virtual": true + }, + { + "Name": "option", + "Virtual": true + } + ] + }, + { + "name": "posts", + "type": "table", + "comment": "", + "columns": [ + { + "name": "id", + "type": "INTEGER", + "nullable": true, + "default": null, + "comment": "" + }, + { + "name": "user_id", + "type": "INTEGER", + "nullable": false, + "default": null, + "comment": "" + }, + { + "name": "category_id", + "type": "INTEGER", + "nullable": false, + "default": null, + "comment": "" + }, + { + "name": "title", + "type": "TEXT", + "nullable": false, + "default": null, + "comment": "" + } + ], + "indexes": [ + { + "name": "posts_user_id_idx", + "def": "CREATE INDEX posts_user_id_idx ON posts(user_id)", + "table": "posts", + "columns": [ + "user_id" + ], + "comment": "" + } + ], + "constraints": [ + { + "name": "id", + "type": "PRIMARY KEY", + "def": "PRIMARY KEY (id)", + "table": "posts", + "referenced_table": null, + "columns": [ + "id" + ], + "referenced_columns": null, + "comment": "" + }, + { + "name": "- (Foreign key ID: 0)", + "type": "FOREIGN KEY", + "def": "FOREIGN KEY (category_id) REFERENCES categories (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "table": "posts", + "referenced_table": "categories", + "columns": [ + "category_id" + ], + "referenced_columns": [ + "id" + ], + "comment": "" + }, + { + "name": "- (Foreign key ID: 1)", + "type": "FOREIGN KEY", + "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "table": "posts", + "referenced_table": "users", + "columns": [ + "user_id" + ], + "referenced_columns": [ + "id" + ], + "comment": "" + } + ], + "triggers": [ + { + "name": "update_posts_updated", + "def": "CREATE TRIGGER update_posts_updated AFTER UPDATE ON posts FOR EACH ROW\nBEGIN\n UPDATE posts SET updated = current_timestamp WHERE id = OLD.id;\nEND", + "comment": "" + } + ], + "def": "CREATE TABLE posts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n user_id INTEGER NOT NULL,\n category_id INTEGER NOT NULL,\n title TEXT NOT NULL,\n CONSTRAINT posts_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE,\n CONSTRAINT posts_category_id_fk FOREIGN KEY(category_id) REFERENCES categories(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE\n)", + "labels": [ + { + "Name": "public", + "Virtual": true + } + ] + }, + { + "name": "user_options", + "type": "table", + "comment": "", + "columns": [ + { + "name": "id", + "type": "INTEGER", + "nullable": true, + "default": null, + "comment": "" + }, + { + "name": "user_id", + "type": "INTEGER", + "nullable": false, + "default": null, + "comment": "" + }, + { + "name": "email", + "type": "TEXT", + "nullable": false, + "default": null, + "comment": "" + } + ], + "indexes": [], + "constraints": [ + { + "name": "id", + "type": "PRIMARY KEY", + "def": "PRIMARY KEY (id)", + "table": "user_options", + "referenced_table": null, + "columns": [ + "id" + ], + "referenced_columns": null, + "comment": "" + }, + { + "name": "- (Foreign key ID: 0)", + "type": "FOREIGN KEY", + "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "table": "user_options", + "referenced_table": "users", + "columns": [ + "user_id" + ], + "referenced_columns": [ + "id" + ], + "comment": "" + } + ], + "triggers": [], + "def": "CREATE TABLE user_options (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n user_id INTEGER NOT NULL,\n email TEXT NOT NULL,\n CONSTRAINT user_options_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE\n)", + "labels": [ + { + "Name": "private", + "Virtual": true + }, + { + "Name": "option", + "Virtual": true + } + ] + }, + { + "name": "schema_migrations", + "type": "table", + "comment": "", + "columns": [ + { + "name": "id", + "type": "INTEGER", + "nullable": true, + "default": null, + "comment": "" + }, + { + "name": "name", + "type": "TEXT", + "nullable": false, + "default": null, + "comment": "" + } + ], + "indexes": [], + "constraints": [ + { + "name": "id", + "type": "PRIMARY KEY", + "def": "PRIMARY KEY (id)", + "table": "schema_migrations", + "referenced_table": null, + "columns": [ + "id" + ], + "referenced_columns": null, + "comment": "" + } + ], + "triggers": [], + "def": "CREATE TABLE schema_migrations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL\n)" + } + ], + "relations": [ + { + "table": "posts", + "columns": [ + "category_id" + ], + "parent_table": "categories", + "parent_columns": [ + "id" + ], + "def": "FOREIGN KEY (category_id) REFERENCES categories (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "virtual": false + }, + { + "table": "posts", + "columns": [ + "user_id" + ], + "parent_table": "users", + "parent_columns": [ + "id" + ], + "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "virtual": false + }, + { + "table": "user_options", + "columns": [ + "user_id" + ], + "parent_table": "users", + "parent_columns": [ + "id" + ], + "def": "FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE", + "virtual": false + } + ], + "functions": null, + "driver": { + "name": "sqlite", + "database_version": "3.39.4", + "meta": {} + } +} \ No newline at end of file diff --git a/testdata/filter_tables.json b/testdata/test_schema.json similarity index 93% rename from testdata/filter_tables.json rename to testdata/test_schema.json index 92f54a5f..dffd8831 100644 --- a/testdata/filter_tables.json +++ b/testdata/test_schema.json @@ -1,11 +1,11 @@ { - "name": "filter_tables.sqlite3", + "name": "testdb.sqlite3", "desc": "", "tables": [ { "name": "users", "type": "table", - "comment": "", + "comment": "users comment", "columns": [ { "name": "id", @@ -170,7 +170,17 @@ "comment": "" } ], - "indexes": [], + "indexes": [ + { + "name": "posts_user_id_idx", + "def": "CREATE INDEX posts_user_id_idx ON posts(user_id)", + "table": "posts", + "columns": [ + "user_id" + ], + "comment": "" + } + ], "constraints": [ { "name": "id", @@ -213,7 +223,13 @@ "comment": "" } ], - "triggers": [], + "triggers": [ + { + "name": "update_posts_updated", + "def": "CREATE TRIGGER update_posts_updated AFTER UPDATE ON posts FOR EACH ROW\nBEGIN\n UPDATE posts SET updated = current_timestamp WHERE id = OLD.id;\nEND", + "comment": "" + } + ], "def": "CREATE TABLE posts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n user_id INTEGER NOT NULL,\n category_id INTEGER NOT NULL,\n title TEXT NOT NULL,\n CONSTRAINT posts_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE,\n CONSTRAINT posts_category_id_fk FOREIGN KEY(category_id) REFERENCES categories(id) MATCH NONE ON UPDATE NO ACTION ON DELETE CASCADE\n)", "labels": [{"name":"public", "virtual": true}] },