ORM-style database access
Each Sealious collection has simple Promise-based accessor methods.
Getting a single item
const item = await app.collections.tasks.getByID(context, some_id);
If you want to skip any access policy checks, you can pass SuperContext as the first argument:
await app.collections.tasks.getByID(new app.SuperContext(), some_id);
A shorthand for that, as with many other collection methods, is to add a su prefix to the method name, and skip the context:
await app.collections.tasks.suGetByID(some_id);
If you want to use .attach or .filter or any other list-based methods on a single item, you can use
const { items: [item], } = await app.collectionst.tasks .list(context) .ids([some_id]) .attach({ author: true }) .fetch();
Listing items
To query a collection, first create an ItemList:
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:
const { items: matching_animals } = await app.collections.animals .list(context) .filter({ name: "Reksio" }) .fetch();
You can specify multiple field names and values:
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.
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.
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.
const { items: logs } = await app.collections.logs .list(context) .paginate({ page: 2, items: 10 }) .fetch(); // returns items 11-20
Turning on attachments
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:
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
const { items: users } = await app.collections.users .list(context) .sort({ price: "asc" }) // "asc" or "desc" .fetch();
Listing many items by a list of IDs
If you have a list of IDs, you can get all of the items for that ids with a single query like this:
const { items } = await app.collections.tasks .list(context) .ids([id1, id2, id3, ...]) .fetch();
Combining the chain methods
You can combine the filter, paginate, format, sort, ids 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.
Creating an item in a database
const new_task = app.collections.tasks.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:
const new_task = app.collections.tasks.make(); new_task.setMultiple({ title: "Write sealious docs", done: false }); await item.save(context);
Editing an item
const item = await app.collections.tasks.getByID(context, "Xi3am-29"); item.set("done", true); await item.save(context);
Removing an item from database
const item = await app.collections.tasks.getByID(context, "Xi3am-29"); item.set("done", true); await item.remove(context);
Upserting
You can use the upsert method to add or update an existing item in the
database based on some identifying field:
await app.collections.patrons.upsert( new app.SuperContext(), "email", [ { email: "adam@example.com", end_date: "2024-12-24", }, ] );
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.
File Metadata
- Mime Type
- text/plain
- Expires
- Mon, Dec 23, 07:11 (21 h, 8 m)
- Storage Engine
- blob
- Storage Format
- Raw Data
- Storage Handle
- 552918
- Default Alt Text
- orm.remarkup (6 KB)