diff --git a/pkg/schema/lint/checks.go b/pkg/schema/lint/checks.go index ca43f24..545a2cc 100644 --- a/pkg/schema/lint/checks.go +++ b/pkg/schema/lint/checks.go @@ -133,4 +133,63 @@ var Checks = []Check{ return }, }, + { + Name: "forbid_rowid_on_without_rowid_table", + Explanation: "Tables that are `without rowid` may not have a `rowid` column", + Execute: func(s schema.Schema) (ret []CheckResult) { + for tblName, tbl := range s.Tables { + if !tbl.IsWithoutRowid { + continue + } + for _, column := range tbl.Columns { + if column.Name == "rowid" { + ret = append(ret, CheckResult{ + ErrorMsg: "rowid on 'without rowid' table", + TableName: tblName, + ColumnName: column.Name, + }) + } + } + } + return + }, + }, + { + Name: "require_explicit_rowid", + Explanation: "All tables should have an explicit `rowid integer primary key` column, unless they\n" + + "are declared `without rowid`.", + Execute: func(s schema.Schema) (ret []CheckResult) { + tbl_loop: + for tblName, tbl := range s.Tables { + if tbl.IsWithoutRowid { + continue + } + for _, column := range tbl.Columns { + if column.Name == "rowid" { + if !column.IsPrimaryKey { + ret = append(ret, CheckResult{ + ErrorMsg: "`rowid` column not declared \"primary key\"", + TableName: tblName, + ColumnName: column.Name, + }) + } + if column.Type != "integer" { + ret = append(ret, CheckResult{ + ErrorMsg: "non-integer `rowid` column", + TableName: tblName, + ColumnName: column.Name, + }) + } + continue tbl_loop + } + } + ret = append(ret, CheckResult{ + ErrorMsg: "no `rowid` column", + TableName: tblName, + ColumnName: "", + }) + } + return + }, + }, } diff --git a/pkg/schema/lint/checks_test.go b/pkg/schema/lint/checks_test.go index 4323656..a989957 100644 --- a/pkg/schema/lint/checks_test.go +++ b/pkg/schema/lint/checks_test.go @@ -20,12 +20,17 @@ func TestFailureCases(t *testing.T) { {"test_schemas/failure-has-ints.sql", []string{"forbid_int_type"}}, {"test_schemas/failure-has-nulls.sql", []string{"require_not_null"}}, {"test_schemas/failure-no-strict.sql", []string{"require_strict"}}, + {"test_schemas/failure-rowid-on-without-rowid.sql", []string{"forbid_rowid_on_without_rowid_table"}}, + {"test_schemas/failure-missing-rowid.sql", []string{"require_explicit_rowid"}}, + {"test_schemas/failure-non-integer-rowid.sql", []string{"require_explicit_rowid"}}, + {"test_schemas/failure-non-primary-key-rowid.sql", []string{"require_explicit_rowid"}}, {"test_schemas/failure-total.sql", []string{ "require_not_null", "require_explicit_primary_key", "forbid_int_type", "require_strict", "require_indexes_for_foreign_keys", + "require_explicit_rowid", }}, } diff --git a/pkg/schema/lint/test_schemas/failure-has-foreign-key-no-index.sql b/pkg/schema/lint/test_schemas/failure-has-foreign-key-no-index.sql index 86a19b3..2e8ceca 100644 --- a/pkg/schema/lint/test_schemas/failure-has-foreign-key-no-index.sql +++ b/pkg/schema/lint/test_schemas/failure-has-foreign-key-no-index.sql @@ -5,7 +5,7 @@ create table stuff ( ) strict; create table stuff2 ( - weird_pk integer primary key, + rowid integer primary key, label text not null unique, stuff_id integer references stuff(rowid), alternative_stuff_id integer references stuff(amount) diff --git a/pkg/schema/lint/test_schemas/failure-has-ints.sql b/pkg/schema/lint/test_schemas/failure-has-ints.sql index 009dd24..0f5e32c 100644 --- a/pkg/schema/lint/test_schemas/failure-has-ints.sql +++ b/pkg/schema/lint/test_schemas/failure-has-ints.sql @@ -6,7 +6,7 @@ create table stuff ( create index index_stuff_amount on stuff (amount); create table stuff2 ( - weird_pk integer primary key, + rowid integer primary key, label text not null unique, stuff_id int references stuff(rowid), alternative_stuff_id integer references stuff(amount) diff --git a/pkg/schema/lint/test_schemas/failure-has-nulls.sql b/pkg/schema/lint/test_schemas/failure-has-nulls.sql index 6ab9e0a..b728acb 100644 --- a/pkg/schema/lint/test_schemas/failure-has-nulls.sql +++ b/pkg/schema/lint/test_schemas/failure-has-nulls.sql @@ -6,7 +6,7 @@ create table stuff ( create index index_stuff_amount on stuff (amount); create table stuff2 ( - weird_pk integer primary key, + rowid integer primary key, label text not null unique, stuff_id integer references stuff(rowid), alternative_stuff_id integer references stuff(amount) diff --git a/pkg/schema/lint/test_schemas/failure-no-strict.sql b/pkg/schema/lint/test_schemas/failure-no-strict.sql index c45a92f..9ca209f 100644 --- a/pkg/schema/lint/test_schemas/failure-no-strict.sql +++ b/pkg/schema/lint/test_schemas/failure-no-strict.sql @@ -6,7 +6,7 @@ create table stuff ( create index index_stuff_amount on stuff (amount); create table stuff2 ( - weird_pk integer primary key, + rowid integer primary key, label text not null unique, stuff_id integer references stuff(rowid), alternative_stuff_id integer references stuff(amount) diff --git a/pkg/schema/lint/test_schemas/success.sql b/pkg/schema/lint/test_schemas/success.sql index e41809b..c0bd17d 100644 --- a/pkg/schema/lint/test_schemas/success.sql +++ b/pkg/schema/lint/test_schemas/success.sql @@ -10,9 +10,9 @@ create table stuff2 ( label text not null unique, stuff_id integer references stuff(rowid), alternative_stuff_id integer references stuff(amount) -) strict; +) strict, without rowid; create table stuff3 ( - weird_pk3 integer primary key, + rowid integer primary key, stuff2_id integer not null references stuff2(weird_pk) ) strict;