bslocombe:pg

v1.0.6Published 11 months ago

numtel:pg Build Status

Reactive PostgreSQL for Meteor, Credits to original package by numtel, updated to get newer PG libraries.

Provides Meteor integration of the pg-live-select NPM module, bringing reactive SELECT statement result sets from PostgreSQL >= 9.3.

If you do not have PostgreSQL server already installed, you may use the numtel:pg-server Meteor Package to bundle the PostgreSQL server directly to your Meteor application.

Server Implements

This package provides the LivePg class as defined in the pg-live-select NPM package.

Also exposed on the server is the pg object as defined in the node-postgres NPM package (useful for other operations like INSERT and UPDATE).

LivePg.prototype.select()

In this Meteor package, the SelectHandle object returned by the select() method is modified to act as a cursor that can be published.

1var liveDb = new LivePg(CONNECTION_STRING, CHANNEL);
2
3Meteor.publish('allPlayers', function(){
4  return liveDb.select('SELECT * FROM players ORDER BY score DESC');
5});

Client/Server Implements

PgSubscription([connection,] name, [args...])

Constructor for subscribing to a published select statement. No extra call to Meteor.subscribe() is required. Specify the name of the subscription along with any arguments.

The first argument, connection, is optional. If connecting to a different Meteor server, pass the DDP connection object in this first argument. If not specified, the first argument becomes the name of the subscription (string) and the default Meteor server connection will be used.

The prototype inherits from Array and is extended with the following methods:

NameDescription
change([args...])Change the subscription's arguments. Publication name and connection are preserved.
addEventListener(eventName, listener)Bind a listener function to this subscription
removeEventListener(eventName)Remove listener functions from an event queue
dispatchEvent(eventName, [args...])Call the listeners for a given event, returns boolean
depend()Call from inside of a Template helper function to ensure reactive updates
reactive()Same as depend() except returns self
changed()Signal new data in the subscription
ready()Return boolean value corresponding to subscription fully loaded
stop()Stop updates for this subscription

Notes:

  • changed() is automatically called when the query updates and is most likely to only be called manually from a method stub on the client.
  • Event listener methods are similar to native methods. For example, if an event listener returns false exactly, it will halt listeners of the same event that have been added previously. A few differences do exist though to make usage easier in this context:
    • The event name may also contain an identifier suffix using dot namespacing (e.g. update.myEvent) to allow removing/dispatching only a subset of listeners.
    • removeEventListener() and dispatchEvent() both refer to listeners by name only. Regular expessions allowed.
    • useCapture argument is not available.

Event Types

NameListener ArgumentsDescription
updatediff, dataNew change, before data update
updateddiff, dataNew change, after data update
resetmsgSubscription reset (most likely due to code-push), before update

Closing connections between hot code-pushes

With Meteor's hot code-push feature, new triggers and functions on database server are created with each restart. In order to remove old items, a handler to your application process's SIGTERM signal event must be added that calls the cleanup() method on each LivePg instance in your application. Also, a handler for SIGINT can be used to close connections on exit.

On the server-side of your application, add event handlers like this:

1
2var liveDb = new LivePg(CONNECTION_STRING, CHANNEL);
3
4var closeAndExit = function() {
5  // Call process.exit() as callback
6  liveDb.cleanup(process.exit);
7};
8
9// Close connections on hot code push
10process.on('SIGTERM', closeAndExit);
11// Close connections on exit (ctrl + c)
12process.on('SIGINT', closeAndExit);

Tests / Benchmarks

The test suite does not require a separate Postgres server installation as it uses the numtel:pg-server package to run the tests.

The database connection settings must be configured in test/settings/local.json.

The database specified should be an empty database with no tables because the tests will create and delete tables as needed.

# Install Meteor
$ curl -L https://install.meteor.com/ | /bin/sh

# Clone Repository
$ git clone https://github.com/numtel/meteor-pg.git
$ cd meteor-pg

# Optionally, configure port and data dir in test/settings/test.pg.json.
# If changing port, keep port value updated in test/index.es6 as well.

# Test database will be created in dbtest directory.

# Run test server
$ meteor test-packages ./

Example Usage Publication

1var liveDb = new LivePg(Meteor.settings.private.postgres, 'test');
2
3// uses the name of the publication as the name of the collection by default.
4// option to override so you can have more than one publication for the same "collection" 
5// this is the publication context.. 
6
7// this._collection_name = "entities"
8
9Meteor.publish('test', function(){
10  let res = liveDb.select(
11    `SELECT * from entity`,
12    [],
13    LivePgKeySelector.Columns(['id']),
14    [{table:'entity'}]
15  );
16  return res;
17})
18
19var closeAndExit = function() {
20  // Call process.exit() as callback
21  liveDb.cleanup(process.exit);
22};
23
24// Close connections on hot code push
25process.on('SIGTERM', closeAndExit);
26// Close connections on exit (ctrl + c)
27process.on('SIGINT', closeAndExit);

License

MIT