Create, Read, Update, Delete

When you have your Collections defined, learn how to manipulate them!

Opening Isar

Before you can do anything, you have to open an Isar instance. Each instance needs a directory with write permission. If you don't specify a directory, Isar will find a suitable default directory for the current platform.

final isar = await Isar.open([ContactSchema]);

You can use the default config or provide some of the following parameters.

ConfigDescription
nameYou can open multiple instances with distinct names. By default, "default" is used.
schemasA list of all collection schemas you want to use. All instances need to use the same schemas.
directoryThe storage location for this instance. You can pass a relative or absolute path. By default, NSDocumentDirectory is used for iOS and getDataDirectory for Android. The final location is path/name.isar. Not required for web.
relaxedDurabilityRelaxes the durability guarantee to increase write performance. In case of a system crash (not app crash), it is possible to lose the last committed transaction. Corruption is not possible
compactOnLaunchConditions to check whether the database should be compacted when the instance is opened.
inspectorEnabled the Inspector for debug builds. For profile and release builds this option is ignored.

You can either store the Isar instance in a global variable or use your favorite dependency injection package to manage it.

If an instance is already open, calling Isar.open() will yield the existing instance regardless of the specified parameters. That's useful for using Isar in an isolate.

TIP

Consider using the path_provideropen in new window package to get a valid path on all platforms.

Collections

The Collection object is how you find, query, and create new records of a given type.

Get a collection

All your collections live in the Isar instance. Remember the Contact class we annotated before with @collection. You can get the contacts collection with:

final contacts = isar.contacts;

That was easy!

Get a record (by id)

final contact = await contacts.get(someId);

get() returns a Future. All Isar operations are asynchronous by default. Most operations have a synchronous counterpart:

final contact = contacts.getSync(someId);

TIP

It is recommended to use the asynchronous version of the method in your UI isolate. Since Isar is very fast, it is often fine however to use the synchronous version.

Query records

Find a list of records matching given conditions using .where() and .filter():

final allContacts = await contacts.where().findAll();

final starredContacts = await contacts.filter()
  .isStarredEqualTo(true)
  .findAll();

➡️ Learn more: Queries

Modifying the database

To create, update, or delete records, use the respective operations wrapped in a write transaction:

await isar.writeTxn(() async {
  final contact = await contacts.get(someId)

  contact.isStarred = false;
  await contacts.put(contact); // perform update operations

  await contacts.delete(contact.id); // or delete operations
});

➡️ Learn more: Transactions

Create a new record

When an object is not yet managed by Isar, you need to .put() it into a collection. If the id field is null or Isar.autoIncrement, Isar will use an auto-increment id.

final newContact = Contact()
  ..firstName = "Albert"
  ..lastName = "Einstein"
  ..isStarred = true;
await isar.writeTxn(() async {
  await contacts.put(newContact);
})

Isar will automatically assign the new id to the object if the id field is non-final.

Update a record

Both creating and updating works with yourCollection.put(yourObject). If the id is null (or does not exist), the object is inserted, otherwise, it is updated.

Delete records

await isar.writeTxn(() async {
  contacts.delete(contact.id);
});

or:

await isar.writeTxn(() async {
  final idsOfUnstarredContacts = await contacts.filter()
    .isStarredEqualTo(false)
    .idProperty()
    .findAll();

  contacts.deleteAll(idsOfUnstarredContacts);
});