Skip to content

Commit

Permalink
fix: add foreign key constraint for network ID
Browse files Browse the repository at this point in the history
  • Loading branch information
zepatrik committed Feb 21, 2022
1 parent 6c0cf17 commit e815cb0
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 10 deletions.
8 changes: 0 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,6 @@ test-docs-samples:
&& \
npm test

.PHONY: migrations-render
migrations-render: .bin/ory
ory dev pop migration render internal/persistence/sql/migrations/templates internal/persistence/sql/migrations/sql

.PHONY: migrations-render-replace
migrations-render-replace: .bin/ory
ory dev pop migration render -r internal/persistence/sql/migrations/templates internal/persistence/sql/migrations/sql

.PHONY: cve-scan
cve-scan: docker .bin/grype
grype oryd/keto:latest
Expand Down
28 changes: 26 additions & 2 deletions cmd/migrate/migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ func TestMigrate(t *testing.T) {
t.Run("dsn=memory", func(t *testing.T) {
t.Run("case=auto migrates", func(t *testing.T) {
hook := &test.Hook{}
ctx := context.WithValue(context.Background(), driver.LogrusHookContextKey, hook)
ctx, cancel := context.WithCancel(context.WithValue(context.Background(), driver.LogrusHookContextKey, hook))
t.Cleanup(cancel)

cf := dbx.ConfigFile(t, map[string]interface{}{
config.KeyDSN: dsn.Conn,
Expand All @@ -78,7 +79,8 @@ func TestMigrate(t *testing.T) {
} else {
t.Run("dsn="+dsn.Name, func(t *testing.T) {
hook := &test.Hook{}
ctx := context.WithValue(context.Background(), driver.LogrusHookContextKey, hook)
ctx, cancel := context.WithCancel(context.WithValue(context.Background(), driver.LogrusHookContextKey, hook))
t.Cleanup(cancel)

cf := dbx.ConfigFile(t, map[string]interface{}{
config.KeyDSN: dsn.Conn,
Expand Down Expand Up @@ -131,3 +133,25 @@ func TestMigrate(t *testing.T) {
}
}
}

func TestUpAndDown(t *testing.T) {
const debugOnDisk = false

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

cmd := &cmdx.CommandExecuter{
New: func() *cobra.Command {
cmd := newMigrateCmd()
configx.RegisterFlags(cmd.PersistentFlags())
return cmd
},
Ctx: ctx,
}
for _, dsn := range dbx.GetDSNs(t, debugOnDisk) {
cf := dbx.ConfigFile(t, map[string]interface{}{config.KeyDSN: dsn.Conn})

t.Log(cmd.ExecNoErr(t, "up", "-c", cf, "--"+FlagYes))
t.Log(cmd.ExecNoErr(t, "down", "0", "-c", cf, "--"+FlagYes))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE keto_relation_tuples DROP CONSTRAINT keto_relation_tuples_nid_fk;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
CREATE TABLE keto_relation_tuples_no_fk
(
shard_id UUID NOT NULL,
nid UUID NOT NULL,
namespace_id INTEGER NOT NULL,
object VARCHAR(64) NOT NULL,
relation VARCHAR(64) NOT NULL,
subject_id VARCHAR(64) NULL,
subject_set_namespace_id INTEGER NULL,
subject_set_object VARCHAR(64) NULL,
subject_set_relation VARCHAR(64) NULL,
commit_time TIMESTAMP NOT NULL,

PRIMARY KEY (shard_id, nid),

-- enforce to have exactly one of subject_id or subject_set
CONSTRAINT chk_keto_rt_subject_type CHECK
((subject_id IS NULL AND
subject_set_namespace_id IS NOT NULL AND subject_set_object IS NOT NULL AND subject_set_relation IS NOT NULL)
OR
(subject_id IS NOT NULL AND
subject_set_namespace_id IS NULL AND subject_set_object IS NULL AND subject_set_relation IS NULL))
);

INSERT INTO keto_relation_tuples_no_fk (shard_id, nid, namespace_id, object, relation, subject_id, subject_set_namespace_id, subject_set_object, subject_set_relation, commit_time) SELECT * FROM keto_relation_tuples;

DROP TABLE keto_relation_tuples;

ALTER TABLE keto_relation_tuples_no_fk RENAME TO keto_relation_tuples;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
-- These tuples can't be retrieved over any API (and also not inserted by any API) because we always add a `WHERE nid = ?` clause to the queries.
-- This DELETE statement is here to ensure that we don't run into problems where the `nid` column is not properly set. Should not happen if only the official API is used.
DELETE FROM keto_relation_tuples WHERE nid NOT IN (SELECT nid FROM networks);

CREATE TABLE keto_relation_tuples_with_fk
(
shard_id UUID NOT NULL,
nid UUID NOT NULL,
namespace_id INTEGER NOT NULL,
object VARCHAR(64) NOT NULL,
relation VARCHAR(64) NOT NULL,
subject_id VARCHAR(64) NULL,
subject_set_namespace_id INTEGER NULL,
subject_set_object VARCHAR(64) NULL,
subject_set_relation VARCHAR(64) NULL,
commit_time TIMESTAMP NOT NULL,

PRIMARY KEY (shard_id, nid),

CONSTRAINT keto_relation_tuples_nid_fk FOREIGN KEY (nid) REFERENCES networks (nid),

-- enforce to have exactly one of subject_id or subject_set
CONSTRAINT chk_keto_rt_subject_type CHECK
((subject_id IS NULL AND
subject_set_namespace_id IS NOT NULL AND subject_set_object IS NOT NULL AND subject_set_relation IS NOT NULL)
OR
(subject_id IS NOT NULL AND
subject_set_namespace_id IS NULL AND subject_set_object IS NULL AND subject_set_relation IS NULL))
);

INSERT INTO keto_relation_tuples_with_fk (shard_id, nid, namespace_id, object, relation, subject_id, subject_set_namespace_id, subject_set_object, subject_set_relation, commit_time) SELECT * FROM keto_relation_tuples;

DROP TABLE keto_relation_tuples;

ALTER TABLE keto_relation_tuples_with_fk RENAME TO keto_relation_tuples;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- These tuples can't be retrieved over any API (and also not inserted by any API) because we always add a `WHERE nid = ?` clause to the queries.
-- This DELETE statement is here to ensure that we don't run into problems where the `nid` column is not properly set. Should not happen if only the official API is used.
DELETE FROM keto_relation_tuples WHERE nid NOT IN (SELECT nid FROM networks);

ALTER TABLE keto_relation_tuples
ADD CONSTRAINT keto_relation_tuples_nid_fk
FOREIGN KEY (nid) REFERENCES networks (id);
1 change: 1 addition & 0 deletions internal/persistence/sql/migrations/templates/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*
1 change: 1 addition & 0 deletions internal/persistence/sql/migrations/templates/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# The fizz templates are frozen at this point. Add SQL migrations right in `./sql`

0 comments on commit e815cb0

Please sign in to comment.