Skip to content

Commit a4428de

Browse files
committed
Update QlBuiltins::NewEntity for db upgrades
1 parent 2a29eaf commit a4428de

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

‎docs/prepare-db-upgrade-downgrade.md‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,59 @@ relation1.rel: run upgrade.qlo predicate1
101101
relation2.rel: run upgrade.qlo predicate2
102102
```
103103

104+
### Creating new database entities
105+
106+
An upgrade or downgrade query can create database entities that do not exist in
107+
the source database by using the compiler-provided `QlBuiltins::NewEntity`
108+
module. Define a `newtype` whose values uniquely identify the entities to
109+
create, and instantiate `NewEntity` with that type:
110+
111+
```ql
112+
class Element extends @element {
113+
string toString() { none() }
114+
}
115+
116+
// Create one wrapper for each existing element.
117+
newtype TAddedElement = TWrapper(Element element)
118+
119+
module Fresh = QlBuiltins::NewEntity<TAddedElement>;
120+
```
121+
122+
`Fresh::map` maps each value of `TAddedElement` to a distinct new entity ID.
123+
Using an algebraic data type with multiple constructors allows several distinct
124+
entities to be created for the same source entity.
125+
126+
The query is compiled against the source schema, so a fresh ID cannot belong to
127+
an entity type that exists only in the target schema. Define a union of the
128+
appropriate source-schema type and `Fresh::EntityId`, then use a class extending
129+
that union in the output predicates:
130+
131+
```ql
132+
class TNewElement = @element or Fresh::EntityId;
133+
134+
class NewElement extends TNewElement {
135+
string toString() { none() }
136+
}
137+
138+
query predicate new_wrappers(NewElement wrapper, Element element) {
139+
wrapper = Fresh::map(TWrapper(element))
140+
}
141+
```
142+
143+
Run the predicate to populate a relation in the target schema:
144+
145+
```properties
146+
wrappers.rel: run upgrade.qlo new_wrappers
147+
```
148+
149+
The target relation's column type determines the database type of each fresh
150+
ID. Emit every target relation needed to describe the new entity, including
151+
relationships such as its parent, location, or type. When rewriting an existing
152+
relation, its output predicate will usually need to preserve all existing rows
153+
as well as add rows containing the fresh IDs. Reuse the same
154+
`Fresh::map(...)` expression in each predicate that refers to a particular new
155+
entity.
156+
104157
### Testing your scripts
105158

106159
Although we have some automated testing of the scripts (e.g. to test that you can upgrade databases all the way from an initial dbscheme to the newest, and back), it's essential that you apply some more rigorous testing for any non-trivial upgrade or downgrade. You might do so as follows:

0 commit comments

Comments
 (0)