Skip to content

Commit a82534f

Browse files
authored
[EdgeDB] Build out scripture collection schema, for easier querying & inspection (#3039)
1 parent b54a0c0 commit a82534f

File tree

3 files changed

+135
-1
lines changed

3 files changed

+135
-1
lines changed

dbschema/migrations/00037.edgeql

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
CREATE MIGRATION m1xzy4deu3w7kduilieoiydxysopymo7skj4sftggjen4vi3og6kaq
2+
ONTO m1ydhle3dwjru34saeiidf5dyepbesugdwttrvnsyxhezpme5bfqga
3+
{
4+
CREATE MODULE Scripture IF NOT EXISTS;
5+
CREATE TYPE Scripture::Collection {
6+
CREATE REQUIRED PROPERTY label: std::str {
7+
SET readonly := true;
8+
};
9+
};
10+
CREATE TYPE Scripture::VerseRange {
11+
CREATE REQUIRED PROPERTY label: std::str {
12+
SET readonly := true;
13+
};
14+
};
15+
ALTER TYPE Scripture::Collection {
16+
CREATE MULTI LINK verses: Scripture::VerseRange {
17+
ON SOURCE DELETE DELETE TARGET IF ORPHAN;
18+
SET readonly := true;
19+
};
20+
};
21+
CREATE TYPE Scripture::Verse {
22+
CREATE REQUIRED PROPERTY verseId: std::int16 {
23+
SET readonly := true;
24+
CREATE CONSTRAINT std::max_value(31101);
25+
CREATE CONSTRAINT std::min_value(0);
26+
};
27+
CREATE REQUIRED PROPERTY book: std::str {
28+
SET readonly := true;
29+
};
30+
CREATE REQUIRED PROPERTY chapter: std::int16 {
31+
SET readonly := true;
32+
CREATE CONSTRAINT std::max_value(150);
33+
CREATE CONSTRAINT std::min_value(1);
34+
};
35+
CREATE REQUIRED PROPERTY verse: std::int16 {
36+
SET readonly := true;
37+
CREATE CONSTRAINT std::max_value(176);
38+
CREATE CONSTRAINT std::min_value(1);
39+
};
40+
CREATE PROPERTY label := (((((.book ++ ' ') ++ <std::str>.chapter) ++ ':') ++ <std::str>.verse));
41+
};
42+
ALTER TYPE Scripture::VerseRange {
43+
CREATE REQUIRED LINK `end`: Scripture::Verse {
44+
ON SOURCE DELETE DELETE TARGET IF ORPHAN;
45+
SET readonly := true;
46+
};
47+
CREATE REQUIRED LINK `start`: Scripture::Verse {
48+
ON SOURCE DELETE DELETE TARGET IF ORPHAN;
49+
SET readonly := true;
50+
};
51+
CREATE PROPERTY ids := (std::range(<std::int32>.`start`.verseId, <std::int32>.`end`.verseId, inc_upper := true));
52+
};
53+
ALTER TYPE Scripture::Collection {
54+
CREATE PROPERTY ids := (std::multirange(std::array_agg(.verses.ids)));
55+
};
56+
ALTER TYPE default::Producible {
57+
CREATE LINK scripture: Scripture::Collection {
58+
ON SOURCE DELETE DELETE TARGET IF ORPHAN;
59+
};
60+
CREATE TRIGGER denyEmptyScriptureCollection
61+
AFTER UPDATE, INSERT
62+
FOR EACH DO (std::assert(EXISTS (__new__.scripture.verses), message := '`Producible.scripture` should have a `Scripture::Collection` with verses or be null/empty-set'));
63+
};
64+
ALTER TYPE default::Producible {
65+
DROP PROPERTY scriptureReferences;
66+
};
67+
};

dbschema/producible.esdl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,20 @@ module default {
44
delegated constraint exclusive;
55
};
66

7-
scriptureReferences: multirange<int32>;
7+
scripture: Scripture::Collection {
8+
on source delete delete target if orphan;
9+
# https://github.com/edgedb/edgedb/issues/5827
10+
# rewrite insert, update using (
11+
# if exists .scripture.verses then .scripture else <Scripture::Collection>{}
12+
# );
13+
}
14+
# Enforce no empty collections for this type's use-case. Use null/empty-set instead.
15+
trigger denyEmptyScriptureCollection after insert, update for each do (
16+
assert(
17+
exists __new__.scripture.verses,
18+
message := "`Producible.scripture` should have a `Scripture::Collection` with verses or be null/empty-set"
19+
)
20+
);
821
}
922

1023
type EthnoArt extending Producible;

dbschema/scripture.esdl

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
module Scripture {
2+
type Collection {
3+
required label: str {
4+
readonly := true;
5+
}
6+
# Want to allow optional for now for DerivativeScriptureProduct's scripture override use-case
7+
multi verses: VerseRange {
8+
readonly := true;
9+
on source delete delete target if orphan;
10+
}
11+
ids := multirange(array_agg(.verses.ids));
12+
}
13+
14+
type VerseRange {
15+
required label: str {
16+
readonly := true;
17+
}
18+
required `start`: Verse {
19+
readonly := true;
20+
on source delete delete target if orphan;
21+
}
22+
required `end`: Verse {
23+
readonly := true;
24+
on source delete delete target if orphan;
25+
}
26+
ids := range(
27+
<int32>.`start`.verseId,
28+
<int32>.`end`.verseId,
29+
inc_upper := true
30+
);
31+
}
32+
33+
type Verse {
34+
label := .book ++ " " ++ <str>.chapter ++ ":" ++ <str>.verse;
35+
required book: str {
36+
readonly := true;
37+
}
38+
required chapter: int16 {
39+
readonly := true;
40+
constraint min_value(1);
41+
constraint max_value(150); # Psalms
42+
}
43+
required verse: int16 {
44+
readonly := true;
45+
constraint min_value(1);
46+
constraint max_value(176); # Psalms 119
47+
}
48+
required verseId: int16 {
49+
readonly := true;
50+
constraint min_value(0);
51+
constraint max_value(31101);
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)