Lovefield DB Example

Storing in lovefield db gives us some advantages compared to the browser's local storage: it prevents storing a value twice, it simplifies ordering the data, etc. This is an implementation of the lovefield db with nodejs.

PACKAGE JSON Configuration

The following is an example of how the library should look like in the package.json with a stable version:

{
  "dependencies": {
    "lovefield": "2.1.12",
  }
}

Creating a lovefield file

An example of a lovefieldDatabase.js file is shown below, which contains the schema creation, the connection instantiation and actions to perform, such as delete, insert or query rows:

import lf, { Type } from 'lovefield';

const tableSchema = {
  name: 'TableName',
  properties: {
    id: 'id',
    data: 'data',
    date: 'date'
  }
};

/* DB connection instantiation */

let db;

export const loadLovefieldDB = () => {
  if (db) return Promise.resolve(db);

  // Creates a schema
  const schemaBuilder = lf.schema.create('schema-name', 1);

  // Creates a table in the schema
  schemaBuilder.createTable(tableSchema.name)
    .addColumn(tableSchema.properties.id, Type.STRING)
    .addColumn(tableSchema.properties.data, Type.OBJECT)
    .addColumn(tableSchema.properties.date, Type.DATE_TIME)
    .addPrimaryKey([tableSchema.properties.id])
    .addIndex('idxDate', [tableSchema.properties.date], false, lf.Order.DESC);

  // Returns an instance to the db connection
  return schemaBuilder.connect().then(newDb => {
    db = newDb;
    return db;
  });
};

/* DB actions (insert/delete/query) */

export const saveTableData = async (dataList) => {
  const rows = dataList.map(data => _dataToRow(data));
  return _insertOrReplaceQuery(rows, _getTable()).exec();
};

export const deleteTableData = (id) => {
  const table = _getTable();
  db.delete()
    .from(table)
    .where(table[tableSchema.properties.id].eq(id))
    .exec();
};

export const getTableData = () => {
  const table = _getTable();
  return db.select()
    .from(table)
    .exec()
    .then(rows => rows.map(row => row[tableSchema.properties.data]));
};

/* Helper Functions */

const _getTable = (name) => db.getSchema().table(tableSchema.name);

const _dataToRow = (data) =>
  _getTable().createRow({
    id: data.id,
    data: data.data,
    date: data.date
  });

const _insertOrReplaceQuery = (rows, table) =>
  db.insertOrReplace().into(table).values(rows);

In application startup start Lovefield instance

In the application startup (for example in the index.js file), the lovefield connection instance should be created in order to use all the actions in the lovefieldDatabase.js file along the app:

import { loadLovefieldDB } from 'path/to/lovefieldDatabase';

Promise.all([loadLovefieldDB()])
  .then(async () => {
    return undefined;
  })
  .catch((error) => {
    console.log(error);
  });