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
maxRowsandrowModeoptions; - 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
sqlandparamsby calling normalizeSQL; - schedules calling
finish ()for anyerrorreceived; - emits the
startevent; - performs the actual query to the database with
db.call (this)and- upon intercepting an error:
- sets
this.errorand throws it.
- sets
- upon receiving a result:
- emits
'result', - for a non-zero
maxRows:- calls either
processArray ()orprocessStream ()based onthis.rowstype; - calls
fetchStreamif needed (maxRowsis finite butthis.rowsare stream);
- calls either
- returns
result- checks for
minRows, may throw an Error.
- checks for
- emits
- upon intercepting 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 atoptions.maxRows;options.checkOverflow: the stream is presumed to have no more thanoptions.maxRowsrecords, 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
endandclose, to callthis.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
rowModeisscalar, callsflattenArray - calls
finish - returns
this.result
processStream
Provided that this.rows is an stream.Readable, performs all necessary actions to complete the call:
- if
rowModeisscalar, callsflattenStream; - sets necessary event handlers by calling
observeStream