Crear, Leer, Actualizar, Eliminar (CRUD)

Cuando ya has definido tus colecciones, aprende cómo manipularlas!

Abriendo Isar

Antes de hacer nada, necesitamos una instancia Isar. Cada instancia requiere un directorio con permisos de escritura donde el archivo de la base de datos pueda ser almacenado. Si no defines un directorio, Isar encontrará un directorio por defecto apropiado para la plataforma en uso.

Provee todos los esquemas que quieras usar con la instancia Isar. Si abres múltiples instancias, aún tienes que proveer todos los esquemas a cada instancia.

final dir = await getApplicationDocumentsDirectory();
final isar = await Isar.openAsync(
  [ContactSchema],
  directory: dir.path,
);

Puedes usar la configuración por defecto o proveer algunos de los siguientes parámetros:

ConfiguraciónDescripción
nameAbre múltiples instancias con distinto nombre. "default" es el nomre usado por defecto.
directoryLa ubicación de almacenamiento para esta instancia. Puedes usar una ruta relativa o absoluta. NSDocumentDirectory para iOS y getDataDirectory para Android son los usados por defecto. No se requiere para web.
relaxedDurabilityRelaja la garantía de durabilidad para incrementar el rendimiento de escritura. En caso de falla del sistema (no de la aplicación), es posible perder la última transacción ejecutada. La corrupción de los datos no es posible
compactOnLaunchCondiciones a verificar cuando la base de datos deba ser compactada cuando se abra la instancia.
inspectorHabilita el inspector para las compilaciones de depuración. Esta opción se ignora para las compilaciones de perfil y entrega.

Si existiera una instancia ya abierta al momento de llamar a Isar.open(), ésta retornará la instancia existente independientemente de los parámetros especificados. Ésto es útil para usar Isar en un isolate.

Consejo

Considera usar el paquete path_provideropen in new window para obtener una ruta válida en todas las plataformas.

La ubicación de almacenamiento del archivo de la base de datos Isar es directory/name.isar

Leyendo la base de datos

Usa instancias IsarCollection para buscar, consultar y crear nuevos objetos de un tipo dado en Isar.

Para los ejemplos siguientes, asumimos que tenemos una colección Recipe definida como sigue:

@collection
class Recipe {
  late int id;

  String? name;

  DateTime? lastCooked;

  bool? isFavorite;
}

Obtener una colección

Todas tus colecciones viven en la instancia Isar. Puedes obtener tu colección Recipes con:

final recipes = isar.recipes;

Obtener un objeto (por su id)

Todavía no tenemos datos en la colección, pero pretendamos que tenemos así podemos obtener un objeto imaginario dado su id 123

final recipe = await isar.recipes.getAsync(123);

getAsync() retorna un Future con el objeto o null si éste no existe. Por defecto todas las operaciones Isar son asíncronas, y la mayoría de ellas tienen su versión síncrona:

final recipe = recipes.get(123);

Advertencia

En tus isolate de UI, por defecto deberías usar los métodos en su versión asíncrona. Debido a que Isar es súper rápido, a menudo es aceptable usar la versión síncrona.

Si quieres obtener múltiples objetos de una vez, utiliza getAll() o getAllSync():

final recipe = await isar.recipes.getAll([1, 2]);

Consulta de objectos

En lugar de obtener objetos por su id, puedes también consultar una lista objetos que coincidan con ciertas condiciones usando .where() y .filter():

final allRecipes = await isar.recipes.where().findAll();

final favouires = await isar.recipes.filter()
  .isFavoriteEqualTo(true)
  .findAll();

➡️ Ver más en: Consultas

Modificando los datos

Finalmente es momento de modificar los datos en nuestra colección! Para crear, actualizar o eliminar objectos, usa las respectivas operaciones juntas en una transacción de escritura:

await isar.writeAsync((isar) async {
  final recipe = await isar.recipes.getAsync(123)

  recipe.isFavorite = false;
  await isar.recipes.put(recipe); // perform update operations

  await isar.recipes.delete(123); // or delete operations
});

➡️ Ver más en: Transacciones

Insertar objectos

Para almacenar un objeto en Isar, insértalo en una colección. El método put() de Isar insertará o actualizará el objecto dependiendo si el mismo ya existe o no en la colección.

Si el campo id es null o Isar.autoIncrement, Isar usará un id auto incrementable.

final pancakes = Recipe()
  ..id = isar.recipes.autoIncrement()
  ..name = 'Pancakes'
  ..lastCooked = DateTime.now()
  ..isFavorite = true;

await isar.writeAsync((isar) async {
  await isar.recipes.put(pancakes);
})

Isar asignará automáticamente el id al objeto si el campo id es no-final.

Insertar múltiples objetos de una sola vez es muy fácil:

await isar.writeAsync((isar) async {
  await isar.recipes.putAll([pancakes, pizza]);
})

Actualizar objectos

Crear y actualizar objetos funcionan ambos con collection.put(object). Si el id es null (o no existe), el object se crea; de otra manera será actualizado.

Entonces si queremos quitar los pancakes de los favoritos, podemos hacer los siguiente:

await isar.writeAsync((isar) async {
  pancakes.isFavorite = false;
  await isar.recipes.put(recipe);
});

Eliminar objetos

Quieres eliminar un objeto en Isar? Usa collection.delete(id). El método delete retorna verdadero si el objeto con el id especificado fue encontrado y eliminado. Por ejemplo, si quieres eliminar el objeto con el id 123, puedes hacer:

await isar.writeAsync((isar) async {
  final success = await isar.recipes.delete(123);
  print('Recipe deleted: $success');
});

De manera similar a get y put, también existe una operación para eliminar múltiples objetos de una vez que retorna la cantidad de objetos eliminados:

await isar.writeAsync((isar) async {
  final count = await isar.recipes.deleteAll([1, 2, 3]);
  print('We deleted $count recipes');
});

Si no conoces los ids de los objetos que quieres eliminar, puedes utilizar una consulta:

await isar.writeAsync((isar) async {
  final count = await isar.recipes.filter()
    .isFavoriteEqualTo(false)
    .deleteAll();
  print('We deleted $count recipes');
});