-
Notifications
You must be signed in to change notification settings - Fork 2
/
orm.remarkup
200 lines (153 loc) · 4.92 KB
/
orm.remarkup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# ORM-style database access
Each Sealious collection has simple Promise-based accessor methods.
## Creating an item in a database
```
lang=typescript
const new_task = app.collections.task.make();
new_task.set("title", "Write sealious docs");
new_task.set("done", false);
await item.save(context);
```
Alternatively, you can use `setMultiple` to set multiple fields with one call:
```
lang=typescript
const new_task = app.collections.task.make();
new_task.setMultiple({ title: "Write sealious docs", done: false });
await item.save(context);
```
## Editing an item
```
lang=typescript
const item = await this.getByID(context, "Xi3am-29");
item.set("done", true);
await item.save(context);
```
## Removing an item from database
```
lang=typescript
const item = await this.getByID(context, "Xi3am-29");
item.set("done", true);
await item.remove(context);
```
## Listing items
To query a collection, first create an `ItemList`:
```
lang=typescript
app.collections.tasks.list(context)
```
The above code returns an instance of `ItemList`. It supports chainable methods
that allow you to specify which items you want to fetch before any database
query is ran. Those methods are described below.
Remember that in order to actually run the database query and get the items you
want, you have to call the `.fetch()` method of the ItemList object.
### Filtering the list
You can narrow down the items that will be returned by field values. For that,
use the `.filter` chain method:
```
lang=typescript
const { items: matching_animals } = await app.collections.animals
.list(context)
.filter({ name: "Reksio" })
.fetch();
```
You can specify multiple field names and values:
```
lang=typescript
const { items: matching_animals } = await app.collections.animals
.list(context)
.filter({ name: "Reksio", species: "dog" })
.fetch();
```
Some field types support more complex filter values. Refer to each of the field
type's specification for details.
```
lang=typescript
const { items: matching_animals } = await app.collections.animals
.list(context)
.filter({ name: "Reksio", species: "dog", age: { ">": 3, "<": 5 } })
.fetch();
```
### Setting field format
Some fields' output varies depending on the specified format. While querying the
database usint `ItemList`, you can specify different formats for each field.
Refer to each of the field types' specification for details.
```
lang=typescript
const { items: messages } = await app.collections.messages.list().fetch();
console.log(messages[0].get("content")); // foo & bar
const original_messages = await app.collections.messages
.list(context)
.format({ content: "original" })
.fetch();
console.log(messages[0].get("content")); // foo & bar
```
### Pagination
You can use pagination to limit the amount of returned entries. Think of it as
LIMIT/SKIP from SQL, but within Sealious' context.
```
lang=typescript
const { items: logs } = await app.collections.logs
.list(context)
.paginate({ page: 2, items: 10 })
.fetch(); // returns items 11-20
```
### Turning on attachments
```
lang=typescript
const { items: users } = await app.collections.users
.list(context)
.attach({ field1: true })
.fetch();
```
After turning on attachments for certain field/fields, you can access their full
values (e.g. `CollectionItem` instances) with `getAttachments`:
```
lang=typescript
items[0].getAttachments("field1");
```
`.attach` is very useful, because you can load all resources related
to a given item in one command chain. If you want to for example load
all Images linked to a Gallery item, make sure that the Gallery
collection has an `images` field that is a `ReverseSingleReference`
and do:
```
const { items: users } = await app.collections.galleries
.list(context)
.attach({ images: true })
.fetch();
```
You can nest the attachments, as well:
```
const { items: users } = await app.collections.galleries
.list(context)
.attach({ images: {author: true} })
.fetch();
```
### Sorting
```
lang=typescript
const { items: users } = await app.collections.users
.list(context)
.sort({ price: "asc" }) // "asc" or "desc"
.fetch();
```
### Combining the chain methods
You can combine the `filter`, `paginate`, `format`, `sort` and `attach` methods into one elegant chain, like so:
```
const { items } = await app.collections.items
.list(context)
.filter({ name: "Reksio" })
.format({content: "original"})
.attach({ field1: true })
.sort({name: "asc"})
.paginate({ page: 2, items: 10 })
.fetch();
```
The order of the methods in chain is not significant, aside from the fact that
`fetch` has to be at the end of the chain.
## Custom methods
Some collections have custom methods attached to them, so it's easier
to perform certain repetitive tasks. Developers are encouraged to add
all custom logic related to a given collection to the class
representing that collection.
[Custom methods in Users class](https://hub.sealcode.org/source/sealious/browse/dev/src/app/collections/users.remarkup)