Skip to content

Commit

Permalink
feat: add preferNativeBindings
Browse files Browse the repository at this point in the history
  • Loading branch information
gajus committed Oct 22, 2019
1 parent 9ecd58e commit c69a5c0
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 1 deletion.
13 changes: 13 additions & 0 deletions .README/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ createPool(
* @property interceptors An array of [Slonik interceptors](https://github.com/gajus/slonik#slonik-interceptors).
* @property maximumPoolSize Do not allow more than this many connections. Use 'DISABLE_TIMEOUT' constant to disable the timeout. (Default: 10)
* @property minimumPoolSize Add more server connections to pool if below this number. (Default: 1)
* @property preferNativeBindings Uses libpq bindings when `pg-native` module is installed. (Default: true)
* @property typeParsers An array of [Slonik type parsers](https://github.com/gajus/slonik#slonik-type-parsers).
*/
type ClientConfigurationType = {|
Expand All @@ -62,6 +63,7 @@ type ClientConfigurationType = {|
+interceptors?: $ReadOnlyArray<InterceptorType>,
+maximumPoolSize?: number,
+minimumPoolSize?: number,
+preferNativeBindings?: boolean,
+typeParsers?: $ReadOnlyArray<TypeParserType>
|};

Expand Down Expand Up @@ -123,6 +125,17 @@ createPool('postgres://', {

```

### Using native libpq bindings

In order to use native [libpq](https://www.npmjs.com/package/libpq) PostgreSQL bindings install `pg-native`.

```bash
$ npm install pg-native

```

By default, Slonik uses native bindings when `pg-native` is installed. To use JavaScript bindings when `pg-native` is installed, configure `preferNativeBindings: false`.

### Checking out a client from the connection pool

Slonik only allows to check out a connection for the duration of the promise routine supplied to the `pool#connect()` method.
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Note: Using this project does not require TypeScript or Flow. It is a regular ES
* [Create connection](#slonik-usage-create-connection)
* [API](#slonik-usage-api)
* [Default configuration](#slonik-usage-default-configuration)
* [Using native libpq bindings](#slonik-usage-using-native-libpq-bindings)
* [Checking out a client from the connection pool](#slonik-usage-checking-out-a-client-from-the-connection-pool)
* [How are they different?](#slonik-how-are-they-different)
* [`pg` vs `slonik`](#slonik-how-are-they-different-pg-vs-slonik)
Expand Down Expand Up @@ -457,6 +458,7 @@ createPool(
* @property interceptors An array of [Slonik interceptors](https://github.com/gajus/slonik#slonik-interceptors).
* @property maximumPoolSize Do not allow more than this many connections. Use 'DISABLE_TIMEOUT' constant to disable the timeout. (Default: 10)
* @property minimumPoolSize Add more server connections to pool if below this number. (Default: 1)
* @property preferNativeBindings Uses libpq bindings when `pg-native` module is installed. (Default: true)
* @property typeParsers An array of [Slonik type parsers](https://github.com/gajus/slonik#slonik-type-parsers).
*/
type ClientConfigurationType = {|
Expand All @@ -466,6 +468,7 @@ type ClientConfigurationType = {|
+interceptors?: $ReadOnlyArray<InterceptorType>,
+maximumPoolSize?: number,
+minimumPoolSize?: number,
+preferNativeBindings?: boolean,
+typeParsers?: $ReadOnlyArray<TypeParserType>
|};

Expand Down Expand Up @@ -530,6 +533,18 @@ createPool('postgres://', {

```

<a name="slonik-usage-using-native-libpq-bindings"></a>
### Using native libpq bindings

In order to use native [libpq](https://www.npmjs.com/package/libpq) PostgreSQL bindings install `pg-native`.

```bash
$ npm install pg-native

```

By default, Slonik uses native bindings when `pg-native` is installed. To use JavaScript bindings when `pg-native` is installed, configure `preferNativeBindings: false`.

<a name="slonik-usage-checking-out-a-client-from-the-connection-pool"></a>
### Checking out a client from the connection pool

Expand Down
2 changes: 2 additions & 0 deletions src/factories/createClientConfiguration.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export default (clientUserConfiguration?: ClientUserConfigurationType): ClientCo
maximumPoolSize: 10,
minimumPoolSize: 0,

preferNativeBindings: true,

typeParsers,

// $FlowFixMe
Expand Down
37 changes: 36 additions & 1 deletion src/factories/createPool.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// @flow

import pg from 'pg';
import {
serializeError,
} from 'serialize-error';
Expand Down Expand Up @@ -56,6 +55,40 @@ export default (
poolConfiguration.idleTimeout = 1;
}

let pgNativeBindingsAreAvailable = false;

try {
/* eslint-disable global-require, import/no-unassigned-import */
// $FlowFixMe
require('pg-native');
/* eslint-enable */

pgNativeBindingsAreAvailable = true;

poolLog.debug('found pg-native module');
} catch (error) {
poolLog.debug('pg-native module is not found');
}

let pg;

if (clientConfiguration.preferNativeBindings && pgNativeBindingsAreAvailable) {
poolLog.info('using native libpq bindings');

// eslint-disable-next-line global-require
pg = require('pg').native;
} else if (clientConfiguration.preferNativeBindings && !pgNativeBindingsAreAvailable) {
poolLog.info('using JavaScript bindings; pg-native not found');

// eslint-disable-next-line global-require
pg = require('pg');
} else {
poolLog.info('using JavaScript bindings');

// eslint-disable-next-line global-require
pg = require('pg');
}

const pool = new pg.Pool(poolConfiguration);

pool.slonik = {
Expand All @@ -74,6 +107,8 @@ export default (

// istanbul ignore next
pool.on('connect', (client) => {
client.connection = client.connection || {};

client.connection.slonik = {
connectionId: createUlid(),
transactionDepth: null,
Expand Down
3 changes: 3 additions & 0 deletions src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export type InternalDatabaseConnectionType = any;
* @property interceptors An array of [Slonik interceptors](https://github.com/gajus/slonik#slonik-interceptors).
* @property maximumPoolSize Do not allow more than this many connections. Use 'DISABLE_TIMEOUT' constant to disable the timeout. (Default: 10)
* @property minimumPoolSize Add more server connections to pool if below this number. (Default: 1)
* @property preferNativeBindings Uses libpq bindings when `pg-native` module is installed. (Default: true)
* @property typeParsers An array of [Slonik type parsers](https://github.com/gajus/slonik#slonik-type-parsers).
*/
export type ClientUserConfigurationType = {|
Expand All @@ -88,6 +89,7 @@ export type ClientUserConfigurationType = {|
+interceptors?: $ReadOnlyArray<InterceptorType>,
+maximumPoolSize?: number,
+minimumPoolSize?: number,
+preferNativeBindings?: boolean,
+typeParsers?: $ReadOnlyArray<TypeParserType>,
|};

Expand All @@ -98,6 +100,7 @@ export type ClientConfigurationType = {|
+interceptors: $ReadOnlyArray<InterceptorType>,
+maximumPoolSize: number,
+minimumPoolSize: number,
+preferNativeBindings: boolean,
+typeParsers: $ReadOnlyArray<TypeParserType>,
|};

Expand Down
1 change: 1 addition & 0 deletions test/helpers/createClientConfiguration.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default (): ClientConfigurationType => {
interceptors: [],
maximumPoolSize: 10,
minimumPoolSize: 0,
preferNativeBindings: true,
typeParsers: [],
};
};
1 change: 1 addition & 0 deletions test/slonik/factories/createClientConfiguration.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const defaultConfiguration = {
interceptors: [],
maximumPoolSize: 10,
minimumPoolSize: 0,
preferNativeBindings: true,
typeParsers: createTypeParserPreset(),
};

Expand Down

0 comments on commit c69a5c0

Please sign in to comment.