Skip to content

Commit 23e33fd

Browse files
committedMay 30, 2024
Add pg-native to monorepo
1 parent e25428c commit 23e33fd

35 files changed

+3318
-57
lines changed
 

Diff for: ‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"docs:start": "cd docs && yarn start",
1818
"pretest": "yarn build",
1919
"prepublish": "yarn build",
20-
"lint": "eslint --cache '*/**/*.{js,ts,tsx}'"
20+
"lint": "eslint --cache 'packages/**/*.{js,ts,tsx}'"
2121
},
2222
"devDependencies": {
2323
"@typescript-eslint/eslint-plugin": "^7.0.0",

Diff for: ‎packages/pg-native/Makefile

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.PHONY: publish-patch test
2+
3+
test:
4+
npm test
5+
6+
patch: test
7+
npm version patch -m "Bump version"
8+
git push origin master --tags
9+
npm publish
10+
11+
minor: test
12+
npm version minor -m "Bump version"
13+
git push origin master --tags
14+
npm publish

Diff for: ‎packages/pg-native/README.md

+306
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
# node-pg-native
2+
3+
[![Build Status](https://travis-ci.org/brianc/node-pg-native.svg?branch=master)](https://travis-ci.org/brianc/node-pg-native)
4+
5+
High performance native bindings between node.js and PostgreSQL via [libpq](https://github.com/brianc/node-libpq) with a simple API.
6+
7+
## install
8+
9+
You need PostgreSQL client libraries & tools installed. An easy way to check is to type `pg_config`. If `pg_config` is in your path, you should be good to go. If it's not in your path you'll need to consult operating specific instructions on how to go about getting it there.
10+
11+
Some ways I've done it in the past:
12+
13+
- On macOS: `brew install libpq`
14+
- On Ubuntu/Debian: `apt-get install libpq-dev g++ make`
15+
- On RHEL/CentOS: `yum install postgresql-devel`
16+
- On Windows:
17+
1. Install Visual Studio C++ (successfully built with Express 2010). Express is free.
18+
2. Install PostgreSQL (`http://www.postgresql.org/download/windows/`)
19+
3. Add your Postgre Installation's `bin` folder to the system path (i.e. `C:\Program Files\PostgreSQL\9.3\bin`).
20+
4. Make sure that both `libpq.dll` and `pg_config.exe` are in that folder.
21+
22+
Afterwards `pg_config` should be in your path. Then...
23+
24+
```sh
25+
$ npm i pg-native
26+
```
27+
28+
## use
29+
30+
### async
31+
32+
```js
33+
var Client = require('pg-native')
34+
35+
var client = new Client();
36+
client.connect(function(err) {
37+
if(err) throw err
38+
39+
//text queries
40+
client.query('SELECT NOW() AS the_date', function(err, rows) {
41+
if(err) throw err
42+
43+
console.log(rows[0].the_date) //Tue Sep 16 2014 23:42:39 GMT-0400 (EDT)
44+
45+
//parameterized statements
46+
client.query('SELECT $1::text as twitter_handle', ['@briancarlson'], function(err, rows) {
47+
if(err) throw err
48+
49+
console.log(rows[0].twitter_handle) //@briancarlson
50+
})
51+
52+
//prepared statements
53+
client.prepare('get_twitter', 'SELECT $1::text as twitter_handle', 1, function(err) {
54+
if(err) throw err
55+
56+
//execute the prepared, named statement
57+
client.execute('get_twitter', ['@briancarlson'], function(err, rows) {
58+
if(err) throw err
59+
60+
console.log(rows[0].twitter_handle) //@briancarlson
61+
62+
//execute the prepared, named statement again
63+
client.execute('get_twitter', ['@realcarrotfacts'], function(err, rows) {
64+
if(err) throw err
65+
66+
console.log(rows[0].twitter_handle) //@realcarrotfacts
67+
68+
client.end(function() {
69+
console.log('ended')
70+
})
71+
})
72+
})
73+
})
74+
})
75+
})
76+
77+
```
78+
79+
### sync
80+
81+
Because `pg-native` is bound to [libpq](https://github.com/brianc/node-libpq) it is able to provide _sync_ operations for both connecting and queries. This is a bad idea in _non-blocking systems_ like web servers, but is exteremly convienent in scripts and bootstrapping applications - much the same way `fs.readFileSync` comes in handy.
82+
83+
```js
84+
var Client = require('pg-native')
85+
86+
var client = new Client()
87+
client.connectSync()
88+
89+
//text queries
90+
var rows = client.querySync('SELECT NOW() AS the_date')
91+
console.log(rows[0].the_date) //Tue Sep 16 2014 23:42:39 GMT-0400 (EDT)
92+
93+
//parameterized queries
94+
var rows = client.querySync('SELECT $1::text as twitter_handle', ['@briancarlson'])
95+
console.log(rows[0].twitter_handle) //@briancarlson
96+
97+
//prepared statements
98+
client.prepareSync('get_twitter', 'SELECT $1::text as twitter_handle', 1)
99+
100+
var rows = client.executeSync('get_twitter', ['@briancarlson'])
101+
console.log(rows[0].twitter_handle) //@briancarlson
102+
103+
var rows = client.executeSync('get_twitter', ['@realcarrotfacts'])
104+
console.log(rows[0].twitter_handle) //@realcarrotfacts
105+
```
106+
107+
## api
108+
109+
### constructor
110+
111+
- __`constructor Client()`__
112+
113+
Constructs and returns a new `Client` instance
114+
115+
### async functions
116+
117+
- __`client.connect(<params:string>, callback:function(err:Error))`__
118+
119+
Connect to a PostgreSQL backend server.
120+
121+
__params__ is _optional_ and is in any format accepted by [libpq](http://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-CONNSTRING). The connection string is passed _as is_ to libpq, so any format supported by libpq will be supported here. Likewise, any format _unsupported_ by libpq will not work. If no parameters are supplied libpq will use [environment variables](http://www.postgresql.org/docs/9.3/static/libpq-envars.html) to connect.
122+
123+
Returns an `Error` to the `callback` if the connection was unsuccessful. `callback` is _required_.
124+
125+
##### example
126+
127+
```js
128+
var client = new Client()
129+
client.connect(function(err) {
130+
if(err) throw err
131+
132+
console.log('connected!')
133+
})
134+
135+
var client2 = new Client()
136+
client2.connect('postgresql://user:password@host:5432/database?param=value', function(err) {
137+
if(err) throw err
138+
139+
console.log('connected with connection string!')
140+
})
141+
```
142+
143+
- __`client.query(queryText:string, <values:string[]>, callback:Function(err:Error, rows:Object[]))`__
144+
145+
Execute a query with the text of `queryText` and _optional_ parameters specified in the `values` array. All values are passed to the PostgreSQL backend server and executed as a parameterized statement. The callback is _required_ and is called with an `Error` object in the event of a query error, otherwise it is passed an array of result objects. Each element in this array is a dictionary of results with keys for column names and their values as the values for those columns.
146+
147+
##### example
148+
149+
```js
150+
var client = new Client()
151+
client.connect(function(err) {
152+
if (err) throw err
153+
154+
client.query('SELECT NOW()', function(err, rows) {
155+
if (err) throw err
156+
157+
console.log(rows) // [{ "now": "Tue Sep 16 2014 23:42:39 GMT-0400 (EDT)" }]
158+
159+
client.query('SELECT $1::text as name', ['Brian'], function(err, rows) {
160+
if (err) throw err
161+
162+
console.log(rows) // [{ "name": "Brian" }]
163+
164+
client.end()
165+
})
166+
})
167+
})
168+
```
169+
170+
171+
- __`client.prepare(statementName:string, queryText:string, nParams:int, callback:Function(err:Error))`__
172+
173+
Prepares a _named statement_ for later execution. You _must_ supply the name of the statement via `statementName`, the command to prepare via `queryText` and the number of parameters in `queryText` via `nParams`. Calls the callback with an `Error` if there was an error.
174+
175+
##### example
176+
177+
```js
178+
var client = new Client()
179+
client.connect(function(err) {
180+
if(err) throw err
181+
182+
client.prepare('prepared_statement', 'SELECT $1::text as name', 1, function(err) {
183+
if(err) throw err
184+
185+
console.log('statement prepared')
186+
client.end()
187+
})
188+
189+
})
190+
```
191+
192+
- __`client.execute(statementName:string, <values:string[]>, callback:Function(err:err, rows:Object[]))`__
193+
194+
Executes a previously prepared statement on this client with the name of `statementName`, passing it the optional array of query parameters as a `values` array. The `callback` is mandatory and is called with and `Error` if the execution failed, or with the same array of results as would be passed to the callback of a `client.query` result.
195+
196+
##### example
197+
198+
199+
```js
200+
var client = new Client()
201+
client.connect(function(err) {
202+
if(err) throw err
203+
204+
client.prepare('i_like_beans', 'SELECT $1::text as beans', 1, function(err) {
205+
if(err) throw err
206+
207+
client.execute('i_like_beans', ['Brak'], function(err, rows) {
208+
if(err) throw err
209+
210+
console.log(rows) // [{ "i_like_beans": "Brak" }]
211+
client.end()
212+
})
213+
})
214+
})
215+
```
216+
217+
- __`client.end(<callback:Function()>`__
218+
219+
Ends the connection. Calls the _optional_ callback when the connection is terminated.
220+
221+
##### example
222+
223+
```js
224+
var client = new Client()
225+
client.connect(function(err) {
226+
if(err) throw err
227+
client.end(function() {
228+
console.log('client ended') // client ended
229+
})
230+
})
231+
```
232+
233+
- __`client.cancel(callback:function(err))`__
234+
235+
Cancels the active query on the client. Callback receives an error if there was an error _sending_ the cancel request.
236+
237+
##### example
238+
```js
239+
var client = new Client()
240+
client.connectSync()
241+
//sleep for 100 seconds
242+
client.query('select pg_sleep(100)', function(err) {
243+
console.log(err) // [Error: ERROR: canceling statement due to user request]
244+
})
245+
client.cancel(function(err) {
246+
console.log('cancel dispatched')
247+
})
248+
249+
```
250+
251+
### sync functions
252+
253+
- __`client.connectSync(params:string)`__
254+
255+
Connect to a PostgreSQL backend server. Params is in any format accepted by [libpq](http://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-CONNSTRING). Throws an `Error` if the connection was unsuccessful.
256+
257+
- __`client.querySync(queryText:string, <values:string[]>) -> results:Object[]`__
258+
259+
Executes a query with a text of `queryText` and optional parameters as `values`. Uses a parameterized query if `values` are supplied. Throws an `Error` if the query fails, otherwise returns an array of results.
260+
261+
- __`client.prepareSync(statementName:string, queryText:string, nParams:int)`__
262+
263+
Prepares a name statement with name of `statementName` and a query text of `queryText`. You must specify the number of params in the query with the `nParams` argument. Throws an `Error` if the statement is un-preparable, otherwise returns an array of results.
264+
265+
- __`client.executeSync(statementName:string, <values:string[]>) -> results:Object[]`__
266+
267+
Executes a previously prepared statement on this client with the name of `statementName`, passing it the optional array of query paramters as a `values` array. Throws an `Error` if the execution fails, otherwas returns an array of results.
268+
269+
## testing
270+
271+
```sh
272+
$ npm test
273+
```
274+
275+
To run the tests you need a PostgreSQL backend reachable by typing `psql` with no connection parameters in your terminal. The tests use [environment variables](http://www.postgresql.org/docs/9.3/static/libpq-envars.html) to connect to the backend.
276+
277+
An example of supplying a specific host the tests:
278+
279+
```sh
280+
$ PGHOST=blabla.mydatabasehost.com npm test
281+
```
282+
283+
284+
## license
285+
286+
The MIT License (MIT)
287+
288+
Copyright (c) 2014 Brian M. Carlson
289+
290+
Permission is hereby granted, free of charge, to any person obtaining a copy
291+
of this software and associated documentation files (the "Software"), to deal
292+
in the Software without restriction, including without limitation the rights
293+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
294+
copies of the Software, and to permit persons to whom the Software is
295+
furnished to do so, subject to the following conditions:
296+
297+
The above copyright notice and this permission notice shall be included in
298+
all copies or substantial portions of the Software.
299+
300+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
301+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
302+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
303+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
304+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
305+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
306+
THE SOFTWARE.

Diff for: ‎packages/pg-native/bench/index.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
var pg = require("pg").native;
2+
var Native = require("../");
3+
4+
var warmup = function (fn, cb) {
5+
var count = 0;
6+
var max = 10;
7+
var run = function (err) {
8+
if (err) return cb(err);
9+
10+
if (max >= count++) {
11+
return fn(run);
12+
}
13+
14+
cb();
15+
};
16+
run();
17+
};
18+
19+
var native = Native();
20+
native.connectSync();
21+
22+
var queryText = "SELECT generate_series(0, 1000)";
23+
var client = new pg.Client();
24+
client.connect(function () {
25+
var pure = function (cb) {
26+
client.query(queryText, function (err) {
27+
if (err) throw err;
28+
cb(err);
29+
});
30+
};
31+
var nativeQuery = function (cb) {
32+
native.query(queryText, function (err) {
33+
if (err) throw err;
34+
cb(err);
35+
});
36+
};
37+
38+
var run = function () {
39+
var start = Date.now();
40+
warmup(pure, function () {
41+
console.log("pure done", Date.now() - start);
42+
start = Date.now();
43+
warmup(nativeQuery, function () {
44+
console.log("native done", Date.now() - start);
45+
});
46+
});
47+
};
48+
49+
setInterval(function () {
50+
run();
51+
}, 500);
52+
});

0 commit comments

Comments
 (0)
Please sign in to comment.