Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sqlite3 - promise for asynchronous calls

I want to select asynchronous some data of a sqlite3 database. But since db.each is a asynchron function my following select function doesn't work properly. How to add a Promise to wait for the result?

const sqlite3 = require('sqlite3').verbose();

export default function select(database, table) {
  return new Promise((resolve, reject) => {
    const db = new sqlite3.Database(database);
    const queries = [];
    db.each(`SELECT rowid as key, * FROM ${table}`, (err, row) => {
      if (err) {
        reject(err);
      }
      console.log(`Push row ${row.key} from database.`);
      queries.push(row);
    });
    console.log(queries);
    console.log(JSON.stringify(queries));
  });
}

result of codesnippet

like image 614
tomole Avatar asked Oct 28 '17 20:10

tomole


People also ask

Is SQLite asynchronous?

SQLite doesn't support asynchronous I/O. Async ADO.NET methods will execute synchronously in Microsoft.

How many concurrent connections can SQLite handle?

SQLite supports an unlimited number of simultaneous readers, but it will only allow one writer at any instant in time. For many situations, this is not a problem. Writers queue up. Each application does its database work quickly and moves on, and no lock lasts for more than a few dozen milliseconds.

What is DB serialize?

Serialization is the process of converting a data object—a combination of code and data represented within a region of data storage—into a series of bytes that saves the state of the object in an easily transmittable form.

What is SQLite used for?

SQLite is used to develop embedded software for devices like televisions, cell phones, cameras, etc. It can manage low to medium-traffic HTTP requests. SQLite can change files into smaller size archives with lesser metadata. SQLite is used as a temporary dataset to get processed with some data within an application.


1 Answers

db.each() requires a slightly cumbersome, non-standard promisification due to the nature of its callbacks, through which it :

  • delivers rows, one at a time, to a first callback,
  • signals completion to a second callback.

Compare that with the standard pattern exhibited in db.all(), which takes a single callback with the signature (err, rows).

Sticking with db.each(), what you have written is correct as far as it goes but stops short of resolving the Promise on completion of db.each().

Fortunately the solution, despite being cumbersome, is fairly simple. resolve(queries) can be called from a second, callback.

export default function select(database, table) {
    return new Promise((resolve, reject) => {
        const db = new sqlite3.Database(database);
        const queries = [];
        db.each(`SELECT rowid as key, * FROM ${table}`, (err, row) => {
            if (err) {
                reject(err); // optional: you might choose to swallow errors.
            } else {
                queries.push(row); // accumulate the data
            }
        }, (err, n) => {
            if (err) {
                reject(err); // optional: again, you might choose to swallow this error.
            } else {
                resolve(queries); // resolve the promise
            }
        });
    });
}

If the expected number of rows is "very limited" (as it says in the SQLite documentation), then use db.all() instead.

like image 121
Roamer-1888 Avatar answered Nov 02 '22 13:11

Roamer-1888