Page MenuHomeSealhub

orm.remarkup
No OneTemporary

orm.remarkup

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 &amp; 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.

Custom methods in Users class

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 24, 08:18 (1 d, 4 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
552918
Default Alt Text
orm.remarkup (6 KB)

Event Timeline