CRUD

Just like any other database, BlinkDB gives you the ability to Create, Read, Update and Delete items in a table.

Creating entities

The first step you want to do will probably be inserting entities inside the table. You can do so with insert():

import { createDB, createTable, insert } from 'blinkdb';

const db = createDB();
const userTable = createTable<User>(db, "users")();
const aliceId = await insert(userTable, { id: 'some-uuid', name: 'Alice', age: 24 });

Generating an UUID

If your entities are using strings as primary keys, you’re probably hoping to use UUIDs - universally unique identifiers. BlinkDB automatically supplies you with uuid(), a blazing fast method for generating them.

const bobId = await insert(userTable, { id: uuid(), name: 'Bob', age: 21 });

Creating many entities at once

If you are inserting many items in bulk, use the more performant insertMany() instead.

const [aliceId, bobId, charlieId] = await insertMany(userTable, [
  { id: uuid(), name: "Alice", age: 23 },
  { id: uuid(), name: "Bob", age: 45 },
  { id: uuid(), name: "Charlie", age: 34 }
]);

Querying entities

Now that you have items in your table, it’s time to retrieve them! Of course, you can always retrieve all items from a table with many():

const users = await many(userTable);

But where BlinkDB really starts to shine is when you’re using filters. Most of the time, you won’t need all entities in your app, just a specific subset - and BlinkDB allows you to filter your results, optimizing for speed along the way.

For example, you can retrieve the first ten users older than 26 like this:

const usersOlderThan26 = await many(userTable, {
  where: {
    age: { gt: 26 }
  },
  limit: { take: 10 }
});

BlinkDB allows you to filter, sort, and limit items - see more on Filters.

Retrieving one entity

In case you only need the first item of a query result, you can use first().

const youngestUser = await first(userTable, {
  sort: {
    key: 'age',
    order: 'asc'
  }
});

On the other hand, if you want to make sure that the query you’re using will only ever return one item, you can use one() - It will throw an exception if there isn’t exactly one entity matching the filter.

const alice = await one(userTable, {
  where: {
    id: 'alice-uuid'
  }
});

Updating entities

To update entities, simply call update(), and provide the primary key of the entity. While you can provide the entire object to the update() method, you don’t have to - you can only update selected properties as well.

const userTable = createTable<User>(db, "users")();
const userId = await insert(userTable, { id: uuid(), name: 'Alice', age: 15 });
// Increase the age of Alice
await update(userTable, { id: userId, age: 16 });

Updating many entities at once

Updating many items at once can also be done with updateMany().

const userTable = createTable<User>(db, "users")();
const [aliceId, bobId, charlieId] = await insertMany(userTable, [
  { id: uuid(), name: "Alice", age: 23 },
  { id: uuid(), name: "Bob", age: 45 },
  { id: uuid(), name: "Charlie", age: 34 }
]);
// Set the age of those three users above to 10
await updateMany(userTable, [
  { id: aliceId, name: "Alice", age: 10 },
  { id: bobId, name: "Bob", age: 10 },
  { id: charlieId, name: "Charlie", age: 10 }
]);

Updating items that match a given filter

What if you want to dynamically update entities that match a given filter? Of course, you could do this:

const someFilter: Query<User> = { ... };
const users = await many(userTable, someFilter);

// Modify the items somehow
const newUsers = users.map(user => {
  return doSomethingWithItem(user);
};

await updateMany(userTable, newUsers);

But there is a superior option that is also slightly more performant. Enter updateWhere():

const someFilter: Query<User> = { ... };
// Update all items in userTable that match someFilter
await updateWhere(userTable, someFilter, user => {
  return doSomethingWithItem(user);
});

The provided callback will then be called with every item that matches someFilter.

Updating nonexistent entities

update() & updateMany() will throw if you provide a primary key which does not yet exist in the database.

If you like to update an entity, but are not sure if it even exists in the database yet, you can use upsert() & upsertMany(). These methods will update the entities if they exist within the database, or insert them if they don’t.

// Create Alice & Charlie, and update Bob
const [aliceId, bobId, charlieId] = await upsertMany(userTable, [
  { id: uuid(), name: "Alice", age: 23 },
  { id: "existing-bob-uuid", name: "Bob", age: 45 },
  { id: uuid(), name: "Charlie", age: 34 }
]);

Deleting entities

You can delete entities by calling remove() with the primary key of the entity that should be deleted.

const userTable = createTable<User>(db, "users")();
const userId = await insert(userTable, { id: uuid(), name: 'Alice', age: 15 });
// Remove Alice from the table
await remove(userTable, { id: userId });

Deleting many entities at once

Similar to bulk inserting and updating, you can also remove items in bulk with removeMany().

const userTable = createTable<User>(db, "users")();
const [aliceId, bobId, charlieId] = await insertMany(userTable, [
  { id: uuid(), name: "Alice", age: 23 },
  { id: uuid(), name: "Bob", age: 45 },
  { id: uuid(), name: "Charlie", age: 34 }
]);
// Remove Alice, Bob & Charlie from the table
await removeMany(userTable, [
  { id: aliceId },
  { id: bobId },
  { id: charlieId }
]);

Deleting items that match a given filter

And removing all items that match a given filter can be done with removeWhere().

// Remove all users named "Charlie"
await removeWhere(userTable, {
  where: {
    name: "Charlie"
  }
});

Deleting all items

Finally, if you want to remove ALL items from a table, use clear().

// Remove ALL users
await clear(userTable);
blinkDB © 2023