DbCall - do-/node-doix-db GitHub Wiki

DbCall is a class representing a single call to a database.

From the application perspective, each DbCall instance is basically a sql string with a params list plus some options.

The asynchronous exec () method sends the request to the parent DB server and returns when some kind of result is available. Here, we have three major cases:

  • no result data at all;
  • an Array or records;
  • or an object mode readable stream.

DbCall is a general purpose class not intended to be inherited. Everything it does is:

  • verifying options;
  • guaranteeing proper events to be fired at proper moments, once per lifecycle;
  • do some general result transformations (including safely fetching a stream into an array) based on maxRows and rowMode options;
  • routing errors.

The actual interaction with DB servers is done via DbClient's exec method.

Constructor

Not to be called directly. Instances of this class are created by DbClients:

const cl = db.call (
  'SELECT ts FROM log',  // SQL
// [],                   // params
// {                     // other options
//   maxRows: Infinity,
//   rowMode: 'scalar',
//   ...                 // vendor dependent
// }
})

Options

Name Type Default Description
sql String The SQL source of the statement to execute
params Array [] List of parameters for this call
options.maxRows Number 0 Maximal number of records to be fetched
options.minRows Number Minimal number of records to be fetched (requires 1 < maxRows < Infinity)
options.checkOverflow Boolean false Is options.maxRows overrun an error
options.notFound any The value to return as result instead of throwing an Error in case when the minRows check fails
options.rowMode see below 'object' Expected record format

Properties

Name Type Description
db DbClient The client this call belongs to
ord Number The serial number of this call in the db context
objectMode Boolean true iif options.rowMode === 'object'
rows see below The records fetched
columns [{name, type}] result column definitions
result see below The calculated exec ()'s return value.
error Error The error occurred during the call
raw any The driver dependent internal result of the call

maxRows

Value rows type result Description
0 undefined undefined No records are fetched (e. g. for DML, DDL statements)
1 Array rows [0]
1 < maxRows < Infinity Array rows
Infinity stream.Readable rows object mode, chunks are records

rowMode

Name Description
'object' Each result column is represented by an object property
'array' Flat array of field values corresponding to columns
'scalar' Only 1st field is fetched, others are discarded

Events

Name Defined properties Description
start sql, params The call is about to be executed
result result, columns, rows The result is obtained (but may be not yet completely fetched)
error error An error is occurred during the statement execution or the stream reading
finish The ultimate ending of the call's lifecycle

Methods

exec

This asynchronous method

  • adjusts sql and params by calling normalizeSQL;
  • schedules calling finish () for any error received;
  • emits the start event;
  • performs the actual query to the database with db.call (this) and
    • upon intercepting an error:
      • sets this.error and throws it.
    • upon receiving a result:
      • emits 'result',
      • for a non-zero maxRows:
        • calls either processArray () or processStream () based on this.rows type;
        • calls fetchStream if needed (maxRows is finite but this.rows are stream);
      • returns result
        • checks for minRows, may throw an Error.

Note that the exec actually emits the start event but takes care about finish only when maxRows != 0 (via either processArray or processStream). With maxRows == 0, it'up to the caller to invoke finish (), as it does DbClient.do

finish

Emits finish and removes all listeners registered for that event. Thus, it's safe to call this method multiple times: handlers will be invoked only for the first one.

The number of records to fetch is limited by options.maxRows. This works in to modes:

  • !options.checkOverflow: the stream can have any size, the fetching just stops at options.maxRows;
  • options.checkOverflow: the stream is presumed to have no more than options.maxRows records, an Error is thrown on the first extra record.

flattenArray

Provided that this.rows is an Array of Arrays, replaces each element by its 1st entry.

flattenStream

Provided that this.rows is an Readable stream of Arrays, replaces it by the stream of 1st elements.

observeStream

Provided that this.rows is an Readable stream, sets necessary event handlers:

  • on error, to echo it
  • on end and close, to call this.finish ()

fetchStream

This asynchronous method fetches the stream.Readable this.rows into an Array stored as the same property.

processArray

Provided that this.rows is an Array, performs all necessary actions to complete the call:

  • if rowMode is scalar, calls flattenArray
  • calls finish
  • returns this.result

processStream

Provided that this.rows is an stream.Readable, performs all necessary actions to complete the call:

  • if rowMode is scalar, calls flattenStream;
  • sets necessary event handlers by calling observeStream