Gathering detailed insights and metrics for pg-iterator
Gathering detailed insights and metrics for pg-iterator
Gathering detailed insights and metrics for pg-iterator
Gathering detailed insights and metrics for pg-iterator
es-iterator-helpers
An ESnext spec-compliant iterator helpers shim/polyfill/replacement that works as far down as ES3.
es-get-iterator
Get an iterator for any JS language value. Works robustly across all environments, all versions.
stop-iteration-iterator
Firefox 17-26 iterators throw a StopIteration object to indicate "done". This normalizes it.
es6-iterator
Iterator abstraction based on ES6 specification
npm install pg-iterator
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
7 Stars
70 Commits
1 Forks
2 Watching
1 Branches
1 Contributors
Updated on 13 Aug 2024
TypeScript (100%)
Cumulative downloads
Total Downloads
Last day
-60.6%
117
Compared to previous day
Last week
-7.3%
968
Compared to previous week
Last month
15%
3,681
Compared to previous month
Last year
270.8%
30,813
Compared to previous year
2
3
TypeScript wrapper for pg-query-stream, which adds the following:
AsyncIterable
, for row-by-row processing, with for await
or a library (like RxJs).$ npm i pg-iterator
You have the flexibility of using this module with Pool or Client, or a dynamically-determined type, via createQueryIterable function.
Each of the interfaces - QueryIterablePool, QueryIterableClient or createQueryIterable supports strong-type parametrization, for typed row iteration.
See complete examples.
Pool
When using an existing Pool object, this library will automatically acquire the connection,
create AsyncIterable
from a query
and release the connection, once the stream has finished.
Class QueryIterablePool implements such functionality:
1import {Pool} from 'pg'; 2import {QueryIterablePool} from 'pg-iterator'; 3 4const pool = new Pool(/* connection config */); 5 6const q = new QueryIterablePool(pool); // creating our Pool container 7 8const i = q.query('SELECT * FROM users WHERE id = $1', [123]); 9 10for await(const u of i) { 11 console.log(u); // output each row 12}
Client
This library can use a connected Client object directly, via QueryIterableClient class:
1import {Pool, Client} from 'pg'; 2import {QueryIterableClient} from 'pg-iterator'; 3 4const pool = new Pool(/* connection config */); 5const client: Client = await pool.connect(); 6 7const q = new QueryIterableClient(client); // creating our Client container 8 9const i = q.query('SELECT * FROM users WHERE id = $1', [123]); 10 11for await(const u of i) { 12 console.log(u); // output each row 13} 14 15// the onus is on you when to release the client and the pool when done: 16// client.release(), pool.end()
When you do not know whether the source is a Pool or Client, you can use function createQueryIterable instead, which will check the type at run-time, and return either QueryIterablePool or QueryIterableClient, which share generic QueryIterable protocol.
In every usage scenario, you end up with QueryIterable base interface, which exposes information about columns.
1const q = new QueryIterablePool(pool); 2 3const i = q.query('SELECT * FROM users WHERE id = $1', [123]); 4 5// q.fields is empty at this point 6 7for await(const u of i) { 8 const {fields} = q; // fields details are available at this point 9 10 console.log(u); // output each row 11}
fields
instead:1const q = new QueryIterablePool(pool); 2 3q.on('fields', fields => { 4 // sent with complete list of fields here, 5 // before the first row in the loop below 6}); 7 8const i = q.query('SELECT * FROM users WHERE id = $1', [123]); 9 10for await(const u of i) { 11 console.log(u); // output each row 12}
Base interface QueryIterable can emit the following events:
fields
- fields details, as explained above;stream
- notification of a new stream created;complete
- notification of completing the current query.This library manages connection and runs queries inside the same row iteration, the only thing that can throw errors:
1const q = new QueryIterablePool(pool); 2 3const i = q.query('SELECT * FROM users WHERE id = $1', [123]); 4 5try { 6 for await(const u of i) { 7 console.log(u); // output each row 8 } 9} catch (err) { 10 // all connection and query errors arrive here 11}
Most libraries that are based on node-postgres expose Pool and Client interfaces.
For example, pg-promise exposes Pool via Database.$pool, so you can do:
1const q = new QueryIterablePool(db.$pool); // creating Pool container from Database object
And in terms of data consumption, since the data here is AsyncIterable
, there are many libraries
that can consume and process it.
1import {from, take} from 'rxjs'; 2 3const i = q.query('SELECT * FROM users WHERE id = $1', [123]); 4 5from(i).pipe(take(10)).subscribe(row => { 6 console.log(row); // up to 10 rows 7});
1import {pipe, take} from 'iter-ops'; 2 3const i = q.query('SELECT * FROM users WHERE id = $1', [123]); 4 5const r = pipe(i, take(10)); 6 7for await (const a of r) { 8 console.log(a); // up to 10 rows 9}
Note that if iteration is incomplete because you interrupted the iteration loop,
or used some limiting operators (like take
above), the connection will remain
open indefinitely. In such cases you may want to force-release the connection,
by calling method release
of QueryIterable manually:
1import {from, take} from 'rxjs'; 2 3const q = new QueryIterablePool(pool); 4 5const i = q.query('SELECT * FROM users WHERE id = $1', [123]); 6 7from(i).pipe(take(10)).subscribe({ 8 next(row) { 9 console.log(row); 10 }, 11 complete() { 12 // since we use "take(10)" above, the iteration may be incomplete, 13 // and the connection will be stuck, so we have to force-release it: 14 q.release(); 15 } 16});
Alternatively, you can wrap QueryIterable + query into a safe Observable
creator:
1function fromQuery<T>(qi: QueryIterable<T>, text: string, params?: any[]): Observable<T> { 2 return from(qi.query(text, params)).pipe(finalize(() => { 3 qi.release(); 4 })); 5}
See also: complete examples.
No vulnerabilities found.
No security vulnerabilities found.