HuaHsin Lu edited this page Jan 26, 2016 · 44 revisions

Thanks to g40

1. How do I know what values are on the row object?

The row object has properties which align to the column names returned from the query.

Given a table users with columns 'name' and 'age' doing select * from users would return you a result object with an array of row objects. Each row object would have the properties name and age. Example:

client.query('SELECT * FROM users',function(err,result){console.log('name: %s and age: %d',result.rows[0].name,result.rows[0].age);//since the row object is just a hash, it can be accessed also as followsconsole.log('name: %s and age: %d',result.rows[0]['name'],result.rows[0]['age']);});

2. Can I iterate across the columns in the recordset to dynamically display column names?

Why, yes. Yes you can.

client.query(...,function(err,result){varfirstRow=result.rows[0];for(varcolumnNameinfirstRow){console.log('column "%s" has a value of "%j"',columnName,firstRow[columnName]);}});

3. Assuming a recordset is enumerated using the array accessor style used in 1, can we get the column names in the same fashion, i.e. is there a result.rows[i].columnName property?

This is possible using the result.fields array:

client.query(...,function(err,result){console.log("Returned columns:",result.fields.map(function(f){returnf.name;}).join(', '));});

4. How do you get the count of columns in the result set ?

client.query(...,function(err,result){varcolumnCount=Object.keys(result.rows[0]).length;});

This may also be accomplished using the result.fields array:

client.query(...,function(err,result){varcolumnCount=result.fields.length;});

5. If pg returns query data in JSON format, for web service applications, it would make sense to return that directly to the client. If this assumption is correct what is the most efficient method?

http.createServer(function(req,res){//NOTE: pg connection boilerplate not presentpg.query(...,function(err,result){//NOTE: error handling not presentvarjson=JSON.stringify(result.rows);res.writeHead(200,{'content-type':'application/json','content-length':Buffer.byteLength(json)});res.end(json);});})

6. How do I use the Client instance directly?

Example code:

varclient=newClient(connectionString);client.connect();// now enumerate ...enumerate(client,path,callback);//client.end();

This fails with:

varclient=newClient(connectionString);^
ReferenceError: Clientisnotdefined

When you import the postgres library you commonly do require('pg'). This works and requires the 'root' of the library with various properties hanging off of it. To directly instantiate a specific client instance instead of using the pool you can access the client constructor off the the imported pg object.

  1. var Client = require('pg').Client;

or for the native client

  1. var Client = require('pg').native.Client;

Thank you Brian. pg is excellent.

7. I just have a question and maybe a feature request that i am not able to think about how to implement or do it: i need to retrieve the inserted row or someway to reach it after the insert is done.

Yeah, you can do this as so:

//let's pretend we have a user table with the 'id' as the auto-incrementing primary keyvarqueryText='INSERT INTO users(password_hash, email) VALUES($1, $2) RETURNING id'client.query(queryText,['841l14yah','test@te.st'],function(err,result){if(err)//handle errorelse{varnewlyCreatedUserId=result.rows[0].id;}});

8. Does node-postgres handle SQL injection?

Absolutely! The parameterized query support in node-postgres is first class. All escaping is done by the postgresql server ensuring proper behavior across dialects, encodings, etc... For example, this will not inject sql:

client.query("INSERT INTO user(name) VALUES($1)",["'; DROP TABLE user;"],function(err,result){// ...});

9. Can I create a named prepared statement for use later on without performing a query? If not, does passing the same text again to a named statement get ignored and the cached version used? I don't want to have two codepaths in a function, one for first-use and one for every other.

If a prepared statement has a name, it is only parsed once. After that, name will re-use the prepared statement regardless of what text is.

10. Can we override the built in data converters between javascript and postgres data types?

Yes, here is a test that shows how it can be done. And for some examples of already registered converters, take a look at the node-pg-types project.

11. How do I build a WHERE foo IN (...) query to find rows matching an array of values?

node-postgres supports mapping simple JavaScript arrays to PostgreSQL arrays, so in most cases you can just pass it like any other parameter.

client.query("SELECT * FROM stooges WHERE name = ANY ($1)",[['larry','curly','moe']], ...);

Note that = ANY is another way to write IN (...), but unlike IN (...) it will work how you'd expect when you pass an array as a query parameter.

If you know the length of the array in advance you can flatten it to an IN list:

// passing a flat array of values will work:
client.query("SELECT * FROM stooges WHERE name IN ($1, $2, $3)", ['larry', 'curly', 'moe'], ...);

... but there's little benefit when = ANY works with a JavaScript array.

If you're on an old version of node-postgres or you need to create more complex PostgreSQL arrays (arrays of composite types, etc) that node-postgres isn't coping with, you can generate an array literal with dynamic SQL, but be extremely careful of SQL injection when doing this. The following approach is safe because it generates a query string with query parameters and a flattened parameter list, so you're still using the driver's support for parameterised queries ("prepared statements") to protect against SQL injection:

varstooge_names=['larry','curly','moe'];varoffset=1;varplaceholders=stooge_names.map(function(name,i){return'$'+(i+offset);}).join(',');client.query("SELECT * FROM stooges WHERE name IN ("+placeholders+")",stooge_names, ...);

If you have other values and placeholders in your query you'll need to use a different offset value for the array placeholders. See #129 and #82 for extra discussion.

12. Why does node-postgres come with two bindings? One in Javascript and one "native" that uses libpq? Which one is fastest and why isn't a single binding enough?

node-postgres comes with two bindings because I wrote it back before the idea of "do one tiny thing in each module" was a popular idea. I initially wrote the pure-javascript bindings. People were complaining about adopting them because it wasn't a C binding so it wasn't fast. To answer their critique I wrote libpq bindings. I placed them in the same module because I could reuse 70% of the tests (all of the integration tests) so I could quickly know when the APIs diverged.

note: sometime after v1.0 I plan on splitting the javascript, native, and integration tests into their own modules. the node-postgres module itself will be a sort of 'meta package' for the other modules

Last time I checked the native bindings were faster than the pure JavaScript bindings; however, there are performance gains still available to both through code refactors and this can/will change. Either binding you use is fast enough to not end up being a significant factor in your application. As for why isn't a single binding enough? A single binding is enough - either one 😉.

Personally, I like the pure JavaScript bindings because it's JavaScript all the way down, but they both work equally and have full feature parity due to the extensive overlapping test suite.

13. What happens to open transactions when pg.connect's done is called?

Nothing. You are responsible for calling either client.query('COMMIT') or client.query('ROLLBACK') If you call neither and call the done() callback the client will be returned to the pool with an open transaction, and I assume bad things will happen in your application.

14. How do I install pg on Windows?

Problem: npm install pg fails with error message Call to 'pg_config --libdir' returned exit status 1. while trying to load binding.gyp

You need PostgreSQL installed on your system. The path to PostgreSQL bin directory must be included in the environment PATH variable. pg_config is stored in that bin directory.

Quick fix for PowerShell:

$env:PATH+=";C:\Program Files\PostgreSQL\9.2\bin"

npm install pg

15. (New Question) How can a quickly get a Client from Client pool?

pg.connect(): It takes time to reconnect ?

16. (New Question) Are queries asynchronous, or do they block? Can this behavior be overridden if desired?

17. What happens if I ask for a connection and the pool is already empty? will it throw an error or wait until a connection becomes available?

It will wait, and call your callback with a connection after one becomes available. This package uses the generic-pool package to provide this behavior.

18. (New Question) Is there a way to check if I have an active connection?


◄ Back (Transactions)Next (Example App) ►

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content
HuaHsin Lu edited this page Jan 26, 2016 · 44 revisions

Thanks to g40

1. How do I know what values are on the row object?

The row object has properties which align to the column names returned from the query.

Given a table users with columns 'name' and 'age' doing select * from users would return you a result object with an array of row objects. Each row object would have the properties name and age. Example:

client.query('SELECT * FROM users',function(err,result){console.log('name: %s and age: %d',result.rows[0].name,result.rows[0].age);//since the row object is just a hash, it can be accessed also as followsconsole.log('name: %s and age: %d',result.rows[0]['name'],result.rows[0]['age']);});

2. Can I iterate across the columns in the recordset to dynamically display column names?

Why, yes. Yes you can.

client.query(...,function(err,result){varfirstRow=result.rows[0];for(varcolumnNameinfirstRow){console.log('column "%s" has a value of "%j"',columnName,firstRow[columnName]);}});

3. Assuming a recordset is enumerated using the array accessor style used in 1, can we get the column names in the same fashion, i.e. is there a result.rows[i].columnName property?

This is possible using the result.fields array:

client.query(...,function(err,result){console.log("Returned columns:",result.fields.map(function(f){returnf.name;}).join(', '));});

4. How do you get the count of columns in the result set ?

client.query(...,function(err,result){varcolumnCount=Object.keys(result.rows[0]).length;});

This may also be accomplished using the result.fields array:

client.query(...,function(err,result){varcolumnCount=result.fields.length;});

5. If pg returns query data in JSON format, for web service applications, it would make sense to return that directly to the client. If this assumption is correct what is the most efficient method?

http.createServer(function(req,res){//NOTE: pg connection boilerplate not presentpg.query(...,function(err,result){//NOTE: error handling not presentvarjson=JSON.stringify(result.rows);res.writeHead(200,{'content-type':'application/json','content-length':Buffer.byteLength(json)});res.end(json);});})

6. How do I use the Client instance directly?

Example code:

varclient=newClient(connectionString);client.connect();// now enumerate ...enumerate(client,path,callback);//client.end();

This fails with:

varclient=newClient(connectionString);^
ReferenceError: Clientisnotdefined

When you import the postgres library you commonly do require('pg'). This works and requires the 'root' of the library with various properties hanging off of it. To directly instantiate a specific client instance instead of using the pool you can access the client constructor off the the imported pg object.

  1. var Client = require('pg').Client;

or for the native client

  1. var Client = require('pg').native.Client;

Thank you Brian. pg is excellent.

7. I just have a question and maybe a feature request that i am not able to think about how to implement or do it: i need to retrieve the inserted row or someway to reach it after the insert is done.

Yeah, you can do this as so:

//let's pretend we have a user table with the 'id' as the auto-incrementing primary keyvarqueryText='INSERT INTO users(password_hash, email) VALUES($1, $2) RETURNING id'client.query(queryText,['841l14yah','test@te.st'],function(err,result){if(err)//handle errorelse{varnewlyCreatedUserId=result.rows[0].id;}});

8. Does node-postgres handle SQL injection?

Absolutely! The parameterized query support in node-postgres is first class. All escaping is done by the postgresql server ensuring proper behavior across dialects, encodings, etc... For example, this will not inject sql:

client.query("INSERT INTO user(name) VALUES($1)",["'; DROP TABLE user;"],function(err,result){// ...});

9. Can I create a named prepared statement for use later on without performing a query? If not, does passing the same text again to a named statement get ignored and the cached version used? I don't want to have two codepaths in a function, one for first-use and one for every other.

If a prepared statement has a name, it is only parsed once. After that, name will re-use the prepared statement regardless of what text is.

10. Can we override the built in data converters between javascript and postgres data types?

Yes, here is a test that shows how it can be done. And for some examples of already registered converters, take a look at the node-pg-types project.

11. How do I build a WHERE foo IN (...) query to find rows matching an array of values?

node-postgres supports mapping simple JavaScript arrays to PostgreSQL arrays, so in most cases you can just pass it like any other parameter.

client.query("SELECT * FROM stooges WHERE name = ANY ($1)",[['larry','curly','moe']], ...);

Note that = ANY is another way to write IN (...), but unlike IN (...) it will work how you'd expect when you pass an array as a query parameter.

If you know the length of the array in advance you can flatten it to an IN list:

// passing a flat array of values will work:
client.query("SELECT * FROM stooges WHERE name IN ($1, $2, $3)", ['larry', 'curly', 'moe'], ...);

... but there's little benefit when = ANY works with a JavaScript array.

If you're on an old version of node-postgres or you need to create more complex PostgreSQL arrays (arrays of composite types, etc) that node-postgres isn't coping with, you can generate an array literal with dynamic SQL, but be extremely careful of SQL injection when doing this. The following approach is safe because it generates a query string with query parameters and a flattened parameter list, so you're still using the driver's support for parameterised queries ("prepared statements") to protect against SQL injection:

varstooge_names=['larry','curly','moe'];varoffset=1;varplaceholders=stooge_names.map(function(name,i){return'$'+(i+offset);}).join(',');client.query("SELECT * FROM stooges WHERE name IN ("+placeholders+")",stooge_names, ...);

If you have other values and placeholders in your query you'll need to use a different offset value for the array placeholders. See #129 and #82 for extra discussion.

12. Why does node-postgres come with two bindings? One in Javascript and one "native" that uses libpq? Which one is fastest and why isn't a single binding enough?

node-postgres comes with two bindings because I wrote it back before the idea of "do one tiny thing in each module" was a popular idea. I initially wrote the pure-javascript bindings. People were complaining about adopting them because it wasn't a C binding so it wasn't fast. To answer their critique I wrote libpq bindings. I placed them in the same module because I could reuse 70% of the tests (all of the integration tests) so I could quickly know when the APIs diverged.

note: sometime after v1.0 I plan on splitting the javascript, native, and integration tests into their own modules. the node-postgres module itself will be a sort of 'meta package' for the other modules

Last time I checked the native bindings were faster than the pure JavaScript bindings; however, there are performance gains still available to both through code refactors and this can/will change. Either binding you use is fast enough to not end up being a significant factor in your application. As for why isn't a single binding enough? A single binding is enough - either one 😉.

Personally, I like the pure JavaScript bindings because it's JavaScript all the way down, but they both work equally and have full feature parity due to the extensive overlapping test suite.

13. What happens to open transactions when pg.connect's done is called?

Nothing. You are responsible for calling either client.query('COMMIT') or client.query('ROLLBACK') If you call neither and call the done() callback the client will be returned to the pool with an open transaction, and I assume bad things will happen in your application.

14. How do I install pg on Windows?

Problem: npm install pg fails with error message Call to 'pg_config --libdir' returned exit status 1. while trying to load binding.gyp

You need PostgreSQL installed on your system. The path to PostgreSQL bin directory must be included in the environment PATH variable. pg_config is stored in that bin directory.

Quick fix for PowerShell:

$env:PATH+=";C:\Program Files\PostgreSQL\9.2\bin"

npm install pg

15. (New Question) How can a quickly get a Client from Client pool?

pg.connect(): It takes time to reconnect ?

16. (New Question) Are queries asynchronous, or do they block? Can this behavior be overridden if desired?

17. What happens if I ask for a connection and the pool is already empty? will it throw an error or wait until a connection becomes available?

It will wait, and call your callback with a connection after one becomes available. This package uses the generic-pool package to provide this behavior.

18. (New Question) Is there a way to check if I have an active connection?


◄ Back (Transactions)Next (Example App) ►

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
HuaHsin Lu edited this page Jan 26, 2016 · 44 revisions

Thanks to g40

1. How do I know what values are on the row object?

The row object has properties which align to the column names returned from the query.

Given a table users with columns 'name' and 'age' doing select * from users would return you a result object with an array of row objects. Each row object would have the properties name and age. Example:

client.query('SELECT * FROM users',function(err,result){console.log('name: %s and age: %d',result.rows[0].name,result.rows[0].age);//since the row object is just a hash, it can be accessed also as followsconsole.log('name: %s and age: %d',result.rows[0]['name'],result.rows[0]['age']);});

2. Can I iterate across the columns in the recordset to dynamically display column names?

Why, yes. Yes you can.

client.query(...,function(err,result){varfirstRow=result.rows[0];for(varcolumnNameinfirstRow){console.log('column "%s" has a value of "%j"',columnName,firstRow[columnName]);}});

3. Assuming a recordset is enumerated using the array accessor style used in 1, can we get the column names in the same fashion, i.e. is there a result.rows[i].columnName property?

This is possible using the result.fields array:

client.query(...,function(err,result){console.log("Returned columns:",result.fields.map(function(f){returnf.name;}).join(', '));});

4. How do you get the count of columns in the result set ?

client.query(...,function(err,result){varcolumnCount=Object.keys(result.rows[0]).length;});

This may also be accomplished using the result.fields array:

client.query(...,function(err,result){varcolumnCount=result.fields.length;});

5. If pg returns query data in JSON format, for web service applications, it would make sense to return that directly to the client. If this assumption is correct what is the most efficient method?

http.createServer(function(req,res){//NOTE: pg connection boilerplate not presentpg.query(...,function(err,result){//NOTE: error handling not presentvarjson=JSON.stringify(result.rows);res.writeHead(200,{'content-type':'application/json','content-length':Buffer.byteLength(json)});res.end(json);});})

6. How do I use the Client instance directly?

Example code:

varclient=newClient(connectionString);client.connect();// now enumerate ...enumerate(client,path,callback);//client.end();

This fails with:

varclient=newClient(connectionString);^
ReferenceError: Clientisnotdefined

When you import the postgres library you commonly do require('pg'). This works and requires the 'root' of the library with various properties hanging off of it. To directly instantiate a specific client instance instead of using the pool you can access the client constructor off the the imported pg object.

  1. var Client = require('pg').Client;

or for the native client

  1. var Client = require('pg').native.Client;

Thank you Brian. pg is excellent.

7. I just have a question and maybe a feature request that i am not able to think about how to implement or do it: i need to retrieve the inserted row or someway to reach it after the insert is done.

Yeah, you can do this as so:

//let's pretend we have a user table with the 'id' as the auto-incrementing primary keyvarqueryText='INSERT INTO users(password_hash, email) VALUES($1, $2) RETURNING id'client.query(queryText,['841l14yah','test@te.st'],function(err,result){if(err)//handle errorelse{varnewlyCreatedUserId=result.rows[0].id;}});

8. Does node-postgres handle SQL injection?

Absolutely! The parameterized query support in node-postgres is first class. All escaping is done by the postgresql server ensuring proper behavior across dialects, encodings, etc... For example, this will not inject sql:

client.query("INSERT INTO user(name) VALUES($1)",["'; DROP TABLE user;"],function(err,result){// ...});

9. Can I create a named prepared statement for use later on without performing a query? If not, does passing the same text again to a named statement get ignored and the cached version used? I don't want to have two codepaths in a function, one for first-use and one for every other.

If a prepared statement has a name, it is only parsed once. After that, name will re-use the prepared statement regardless of what text is.

10. Can we override the built in data converters between javascript and postgres data types?

Yes, here is a test that shows how it can be done. And for some examples of already registered converters, take a look at the node-pg-types project.

11. How do I build a WHERE foo IN (...) query to find rows matching an array of values?

node-postgres supports mapping simple JavaScript arrays to PostgreSQL arrays, so in most cases you can just pass it like any other parameter.

client.query("SELECT * FROM stooges WHERE name = ANY ($1)",[['larry','curly','moe']], ...);

Note that = ANY is another way to write IN (...), but unlike IN (...) it will work how you'd expect when you pass an array as a query parameter.

If you know the length of the array in advance you can flatten it to an IN list:

// passing a flat array of values will work:
client.query("SELECT * FROM stooges WHERE name IN ($1, $2, $3)", ['larry', 'curly', 'moe'], ...);

... but there's little benefit when = ANY works with a JavaScript array.

If you're on an old version of node-postgres or you need to create more complex PostgreSQL arrays (arrays of composite types, etc) that node-postgres isn't coping with, you can generate an array literal with dynamic SQL, but be extremely careful of SQL injection when doing this. The following approach is safe because it generates a query string with query parameters and a flattened parameter list, so you're still using the driver's support for parameterised queries ("prepared statements") to protect against SQL injection:

varstooge_names=['larry','curly','moe'];varoffset=1;varplaceholders=stooge_names.map(function(name,i){return'$'+(i+offset);}).join(',');client.query("SELECT * FROM stooges WHERE name IN ("+placeholders+")",stooge_names, ...);

If you have other values and placeholders in your query you'll need to use a different offset value for the array placeholders. See #129 and #82 for extra discussion.

12. Why does node-postgres come with two bindings? One in Javascript and one "native" that uses libpq? Which one is fastest and why isn't a single binding enough?

node-postgres comes with two bindings because I wrote it back before the idea of "do one tiny thing in each module" was a popular idea. I initially wrote the pure-javascript bindings. People were complaining about adopting them because it wasn't a C binding so it wasn't fast. To answer their critique I wrote libpq bindings. I placed them in the same module because I could reuse 70% of the tests (all of the integration tests) so I could quickly know when the APIs diverged.

note: sometime after v1.0 I plan on splitting the javascript, native, and integration tests into their own modules. the node-postgres module itself will be a sort of 'meta package' for the other modules

Last time I checked the native bindings were faster than the pure JavaScript bindings; however, there are performance gains still available to both through code refactors and this can/will change. Either binding you use is fast enough to not end up being a significant factor in your application. As for why isn't a single binding enough? A single binding is enough - either one 😉.

Personally, I like the pure JavaScript bindings because it's JavaScript all the way down, but they both work equally and have full feature parity due to the extensive overlapping test suite.

13. What happens to open transactions when pg.connect's done is called?

Nothing. You are responsible for calling either client.query('COMMIT') or client.query('ROLLBACK') If you call neither and call the done() callback the client will be returned to the pool with an open transaction, and I assume bad things will happen in your application.

14. How do I install pg on Windows?

Problem: npm install pg fails with error message Call to 'pg_config --libdir' returned exit status 1. while trying to load binding.gyp

You need PostgreSQL installed on your system. The path to PostgreSQL bin directory must be included in the environment PATH variable. pg_config is stored in that bin directory.

Quick fix for PowerShell:

$env:PATH+=";C:\Program Files\PostgreSQL\9.2\bin"

npm install pg

15. (New Question) How can a quickly get a Client from Client pool?

pg.connect(): It takes time to reconnect ?

16. (New Question) Are queries asynchronous, or do they block? Can this behavior be overridden if desired?

17. What happens if I ask for a connection and the pool is already empty? will it throw an error or wait until a connection becomes available?

It will wait, and call your callback with a connection after one becomes available. This package uses the generic-pool package to provide this behavior.

18. (New Question) Is there a way to check if I have an active connection?


◄ Back (Transactions)Next (Example App) ►

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
HuaHsin Lu edited this page Jan 26, 2016 · 44 revisions

Thanks to g40

1. How do I know what values are on the row object?

The row object has properties which align to the column names returned from the query.

Given a table users with columns 'name' and 'age' doing select * from users would return you a result object with an array of row objects. Each row object would have the properties name and age. Example:

client.query('SELECT * FROM users',function(err,result){console.log('name: %s and age: %d',result.rows[0].name,result.rows[0].age);//since the row object is just a hash, it can be accessed also as followsconsole.log('name: %s and age: %d',result.rows[0]['name'],result.rows[0]['age']);});

2. Can I iterate across the columns in the recordset to dynamically display column names?

Why, yes. Yes you can.

client.query(...,function(err,result){varfirstRow=result.rows[0];for(varcolumnNameinfirstRow){console.log('column "%s" has a value of "%j"',columnName,firstRow[columnName]);}});

3. Assuming a recordset is enumerated using the array accessor style used in 1, can we get the column names in the same fashion, i.e. is there a result.rows[i].columnName property?

This is possible using the result.fields array:

client.query(...,function(err,result){console.log("Returned columns:",result.fields.map(function(f){returnf.name;}).join(', '));});

4. How do you get the count of columns in the result set ?

client.query(...,function(err,result){varcolumnCount=Object.keys(result.rows[0]).length;});

This may also be accomplished using the result.fields array:

client.query(...,function(err,result){varcolumnCount=result.fields.length;});

5. If pg returns query data in JSON format, for web service applications, it would make sense to return that directly to the client. If this assumption is correct what is the most efficient method?

http.createServer(function(req,res){//NOTE: pg connection boilerplate not presentpg.query(...,function(err,result){//NOTE: error handling not presentvarjson=JSON.stringify(result.rows);res.writeHead(200,{'content-type':'application/json','content-length':Buffer.byteLength(json)});res.end(json);});})

6. How do I use the Client instance directly?

Example code:

varclient=newClient(connectionString);client.connect();// now enumerate ...enumerate(client,path,callback);//client.end();

This fails with:

varclient=newClient(connectionString);^
ReferenceError: Clientisnotdefined

When you import the postgres library you commonly do require('pg'). This works and requires the 'root' of the library with various properties hanging off of it. To directly instantiate a specific client instance instead of using the pool you can access the client constructor off the the imported pg object.

  1. var Client = require('pg').Client;

or for the native client

  1. var Client = require('pg').native.Client;

Thank you Brian. pg is excellent.

7. I just have a question and maybe a feature request that i am not able to think about how to implement or do it: i need to retrieve the inserted row or someway to reach it after the insert is done.

Yeah, you can do this as so:

//let's pretend we have a user table with the 'id' as the auto-incrementing primary keyvarqueryText='INSERT INTO users(password_hash, email) VALUES($1, $2) RETURNING id'client.query(queryText,['841l14yah','test@te.st'],function(err,result){if(err)//handle errorelse{varnewlyCreatedUserId=result.rows[0].id;}});

8. Does node-postgres handle SQL injection?

Absolutely! The parameterized query support in node-postgres is first class. All escaping is done by the postgresql server ensuring proper behavior across dialects, encodings, etc... For example, this will not inject sql:

client.query("INSERT INTO user(name) VALUES($1)",["'; DROP TABLE user;"],function(err,result){// ...});

9. Can I create a named prepared statement for use later on without performing a query? If not, does passing the same text again to a named statement get ignored and the cached version used? I don't want to have two codepaths in a function, one for first-use and one for every other.

If a prepared statement has a name, it is only parsed once. After that, name will re-use the prepared statement regardless of what text is.

10. Can we override the built in data converters between javascript and postgres data types?

Yes, here is a test that shows how it can be done. And for some examples of already registered converters, take a look at the node-pg-types project.

11. How do I build a WHERE foo IN (...) query to find rows matching an array of values?

node-postgres supports mapping simple JavaScript arrays to PostgreSQL arrays, so in most cases you can just pass it like any other parameter.

client.query("SELECT * FROM stooges WHERE name = ANY ($1)",[['larry','curly','moe']], ...);

Note that = ANY is another way to write IN (...), but unlike IN (...) it will work how you'd expect when you pass an array as a query parameter.

If you know the length of the array in advance you can flatten it to an IN list:

// passing a flat array of values will work:
client.query("SELECT * FROM stooges WHERE name IN ($1, $2, $3)", ['larry', 'curly', 'moe'], ...);

... but there's little benefit when = ANY works with a JavaScript array.

If you're on an old version of node-postgres or you need to create more complex PostgreSQL arrays (arrays of composite types, etc) that node-postgres isn't coping with, you can generate an array literal with dynamic SQL, but be extremely careful of SQL injection when doing this. The following approach is safe because it generates a query string with query parameters and a flattened parameter list, so you're still using the driver's support for parameterised queries ("prepared statements") to protect against SQL injection:

varstooge_names=['larry','curly','moe'];varoffset=1;varplaceholders=stooge_names.map(function(name,i){return'$'+(i+offset);}).join(',');client.query("SELECT * FROM stooges WHERE name IN ("+placeholders+")",stooge_names, ...);

If you have other values and placeholders in your query you'll need to use a different offset value for the array placeholders. See #129 and #82 for extra discussion.

12. Why does node-postgres come with two bindings? One in Javascript and one "native" that uses libpq? Which one is fastest and why isn't a single binding enough?

node-postgres comes with two bindings because I wrote it back before the idea of "do one tiny thing in each module" was a popular idea. I initially wrote the pure-javascript bindings. People were complaining about adopting them because it wasn't a C binding so it wasn't fast. To answer their critique I wrote libpq bindings. I placed them in the same module because I could reuse 70% of the tests (all of the integration tests) so I could quickly know when the APIs diverged.

note: sometime after v1.0 I plan on splitting the javascript, native, and integration tests into their own modules. the node-postgres module itself will be a sort of 'meta package' for the other modules

Last time I checked the native bindings were faster than the pure JavaScript bindings; however, there are performance gains still available to both through code refactors and this can/will change. Either binding you use is fast enough to not end up being a significant factor in your application. As for why isn't a single binding enough? A single binding is enough - either one 😉.

Personally, I like the pure JavaScript bindings because it's JavaScript all the way down, but they both work equally and have full feature parity due to the extensive overlapping test suite.

13. What happens to open transactions when pg.connect's done is called?

Nothing. You are responsible for calling either client.query('COMMIT') or client.query('ROLLBACK') If you call neither and call the done() callback the client will be returned to the pool with an open transaction, and I assume bad things will happen in your application.

14. How do I install pg on Windows?

Problem: npm install pg fails with error message Call to 'pg_config --libdir' returned exit status 1. while trying to load binding.gyp

You need PostgreSQL installed on your system. The path to PostgreSQL bin directory must be included in the environment PATH variable. pg_config is stored in that bin directory.

Quick fix for PowerShell:

$env:PATH+=";C:\Program Files\PostgreSQL\9.2\bin"

npm install pg

15. (New Question) How can a quickly get a Client from Client pool?

pg.connect(): It takes time to reconnect ?

16. (New Question) Are queries asynchronous, or do they block? Can this behavior be overridden if desired?

17. What happens if I ask for a connection and the pool is already empty? will it throw an error or wait until a connection becomes available?

It will wait, and call your callback with a connection after one becomes available. This package uses the generic-pool package to provide this behavior.

18. (New Question) Is there a way to check if I have an active connection?


◄ Back (Transactions)Next (Example App) ►

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
HuaHsin Lu edited this page Jan 26, 2016 · 44 revisions

Thanks to g40

1. How do I know what values are on the row object?

The row object has properties which align to the column names returned from the query.

Given a table users with columns 'name' and 'age' doing select * from users would return you a result object with an array of row objects. Each row object would have the properties name and age. Example:

client.query('SELECT * FROM users',function(err,result){console.log('name: %s and age: %d',result.rows[0].name,result.rows[0].age);//since the row object is just a hash, it can be accessed also as followsconsole.log('name: %s and age: %d',result.rows[0]['name'],result.rows[0]['age']);});

2. Can I iterate across the columns in the recordset to dynamically display column names?

Why, yes. Yes you can.

client.query(...,function(err,result){varfirstRow=result.rows[0];for(varcolumnNameinfirstRow){console.log('column "%s" has a value of "%j"',columnName,firstRow[columnName]);}});

3. Assuming a recordset is enumerated using the array accessor style used in 1, can we get the column names in the same fashion, i.e. is there a result.rows[i].columnName property?

This is possible using the result.fields array:

client.query(...,function(err,result){console.log("Returned columns:",result.fields.map(function(f){returnf.name;}).join(', '));});

4. How do you get the count of columns in the result set ?

client.query(...,function(err,result){varcolumnCount=Object.keys(result.rows[0]).length;});

This may also be accomplished using the result.fields array:

client.query(...,function(err,result){varcolumnCount=result.fields.length;});

5. If pg returns query data in JSON format, for web service applications, it would make sense to return that directly to the client. If this assumption is correct what is the most efficient method?

http.createServer(function(req,res){//NOTE: pg connection boilerplate not presentpg.query(...,function(err,result){//NOTE: error handling not presentvarjson=JSON.stringify(result.rows);res.writeHead(200,{'content-type':'application/json','content-length':Buffer.byteLength(json)});res.end(json);});})

6. How do I use the Client instance directly?

Example code:

varclient=newClient(connectionString);client.connect();// now enumerate ...enumerate(client,path,callback);//client.end();

This fails with:

varclient=newClient(connectionString);^
ReferenceError: Clientisnotdefined

When you import the postgres library you commonly do require('pg'). This works and requires the 'root' of the library with various properties hanging off of it. To directly instantiate a specific client instance instead of using the pool you can access the client constructor off the the imported pg object.

  1. var Client = require('pg').Client;

or for the native client

  1. var Client = require('pg').native.Client;

Thank you Brian. pg is excellent.

7. I just have a question and maybe a feature request that i am not able to think about how to implement or do it: i need to retrieve the inserted row or someway to reach it after the insert is done.

Yeah, you can do this as so:

//let's pretend we have a user table with the 'id' as the auto-incrementing primary keyvarqueryText='INSERT INTO users(password_hash, email) VALUES($1, $2) RETURNING id'client.query(queryText,['841l14yah','test@te.st'],function(err,result){if(err)//handle errorelse{varnewlyCreatedUserId=result.rows[0].id;}});

8. Does node-postgres handle SQL injection?

Absolutely! The parameterized query support in node-postgres is first class. All escaping is done by the postgresql server ensuring proper behavior across dialects, encodings, etc... For example, this will not inject sql:

client.query("INSERT INTO user(name) VALUES($1)",["'; DROP TABLE user;"],function(err,result){// ...});

9. Can I create a named prepared statement for use later on without performing a query? If not, does passing the same text again to a named statement get ignored and the cached version used? I don't want to have two codepaths in a function, one for first-use and one for every other.

If a prepared statement has a name, it is only parsed once. After that, name will re-use the prepared statement regardless of what text is.

10. Can we override the built in data converters between javascript and postgres data types?

Yes, here is a test that shows how it can be done. And for some examples of already registered converters, take a look at the node-pg-types project.

11. How do I build a WHERE foo IN (...) query to find rows matching an array of values?

node-postgres supports mapping simple JavaScript arrays to PostgreSQL arrays, so in most cases you can just pass it like any other parameter.

client.query("SELECT * FROM stooges WHERE name = ANY ($1)",[['larry','curly','moe']], ...);

Note that = ANY is another way to write IN (...), but unlike IN (...) it will work how you'd expect when you pass an array as a query parameter.

If you know the length of the array in advance you can flatten it to an IN list:

// passing a flat array of values will work:
client.query("SELECT * FROM stooges WHERE name IN ($1, $2, $3)", ['larry', 'curly', 'moe'], ...);

... but there's little benefit when = ANY works with a JavaScript array.

If you're on an old version of node-postgres or you need to create more complex PostgreSQL arrays (arrays of composite types, etc) that node-postgres isn't coping with, you can generate an array literal with dynamic SQL, but be extremely careful of SQL injection when doing this. The following approach is safe because it generates a query string with query parameters and a flattened parameter list, so you're still using the driver's support for parameterised queries ("prepared statements") to protect against SQL injection:

varstooge_names=['larry','curly','moe'];varoffset=1;varplaceholders=stooge_names.map(function(name,i){return'$'+(i+offset);}).join(',');client.query("SELECT * FROM stooges WHERE name IN ("+placeholders+")",stooge_names, ...);

If you have other values and placeholders in your query you'll need to use a different offset value for the array placeholders. See #129 and #82 for extra discussion.

12. Why does node-postgres come with two bindings? One in Javascript and one "native" that uses libpq? Which one is fastest and why isn't a single binding enough?

node-postgres comes with two bindings because I wrote it back before the idea of "do one tiny thing in each module" was a popular idea. I initially wrote the pure-javascript bindings. People were complaining about adopting them because it wasn't a C binding so it wasn't fast. To answer their critique I wrote libpq bindings. I placed them in the same module because I could reuse 70% of the tests (all of the integration tests) so I could quickly know when the APIs diverged.

note: sometime after v1.0 I plan on splitting the javascript, native, and integration tests into their own modules. the node-postgres module itself will be a sort of 'meta package' for the other modules

Last time I checked the native bindings were faster than the pure JavaScript bindings; however, there are performance gains still available to both through code refactors and this can/will change. Either binding you use is fast enough to not end up being a significant factor in your application. As for why isn't a single binding enough? A single binding is enough - either one 😉.

Personally, I like the pure JavaScript bindings because it's JavaScript all the way down, but they both work equally and have full feature parity due to the extensive overlapping test suite.

13. What happens to open transactions when pg.connect's done is called?

Nothing. You are responsible for calling either client.query('COMMIT') or client.query('ROLLBACK') If you call neither and call the done() callback the client will be returned to the pool with an open transaction, and I assume bad things will happen in your application.

14. How do I install pg on Windows?

Problem: npm install pg fails with error message Call to 'pg_config --libdir' returned exit status 1. while trying to load binding.gyp

You need PostgreSQL installed on your system. The path to PostgreSQL bin directory must be included in the environment PATH variable. pg_config is stored in that bin directory.

Quick fix for PowerShell:

$env:PATH+=";C:\Program Files\PostgreSQL\9.2\bin"

npm install pg

15. (New Question) How can a quickly get a Client from Client pool?

pg.connect(): It takes time to reconnect ?

16. (New Question) Are queries asynchronous, or do they block? Can this behavior be overridden if desired?

17. What happens if I ask for a connection and the pool is already empty? will it throw an error or wait until a connection becomes available?

It will wait, and call your callback with a connection after one becomes available. This package uses the generic-pool package to provide this behavior.

18. (New Question) Is there a way to check if I have an active connection?


◄ Back (Transactions)Next (Example App) ►

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
HuaHsin Lu edited this page Jan 26, 2016 · 44 revisions

Thanks to g40

1. How do I know what values are on the row object?

The row object has properties which align to the column names returned from the query.

Given a table users with columns 'name' and 'age' doing select * from users would return you a result object with an array of row objects. Each row object would have the properties name and age. Example:

client.query('SELECT * FROM users',function(err,result){console.log('name: %s and age: %d',result.rows[0].name,result.rows[0].age);//since the row object is just a hash, it can be accessed also as followsconsole.log('name: %s and age: %d',result.rows[0]['name'],result.rows[0]['age']);});

2. Can I iterate across the columns in the recordset to dynamically display column names?

Why, yes. Yes you can.

client.query(...,function(err,result){varfirstRow=result.rows[0];for(varcolumnNameinfirstRow){console.log('column "%s" has a value of "%j"',columnName,firstRow[columnName]);}});

3. Assuming a recordset is enumerated using the array accessor style used in 1, can we get the column names in the same fashion, i.e. is there a result.rows[i].columnName property?

This is possible using the result.fields array:

client.query(...,function(err,result){console.log("Returned columns:",result.fields.map(function(f){returnf.name;}).join(', '));});

4. How do you get the count of columns in the result set ?

client.query(...,function(err,result){varcolumnCount=Object.keys(result.rows[0]).length;});

This may also be accomplished using the result.fields array:

client.query(...,function(err,result){varcolumnCount=result.fields.length;});

5. If pg returns query data in JSON format, for web service applications, it would make sense to return that directly to the client. If this assumption is correct what is the most efficient method?

http.createServer(function(req,res){//NOTE: pg connection boilerplate not presentpg.query(...,function(err,result){//NOTE: error handling not presentvarjson=JSON.stringify(result.rows);res.writeHead(200,{'content-type':'application/json','content-length':Buffer.byteLength(json)});res.end(json);});})

6. How do I use the Client instance directly?

Example code:

varclient=newClient(connectionString);client.connect();// now enumerate ...enumerate(client,path,callback);//client.end();

This fails with:

varclient=newClient(connectionString);^
ReferenceError: Clientisnotdefined

When you import the postgres library you commonly do require('pg'). This works and requires the 'root' of the library with various properties hanging off of it. To directly instantiate a specific client instance instead of using the pool you can access the client constructor off the the imported pg object.

  1. var Client = require('pg').Client;

or for the native client

  1. var Client = require('pg').native.Client;

Thank you Brian. pg is excellent.

7. I just have a question and maybe a feature request that i am not able to think about how to implement or do it: i need to retrieve the inserted row or someway to reach it after the insert is done.

Yeah, you can do this as so:

//let's pretend we have a user table with the 'id' as the auto-incrementing primary keyvarqueryText='INSERT INTO users(password_hash, email) VALUES($1, $2) RETURNING id'client.query(queryText,['841l14yah','test@te.st'],function(err,result){if(err)//handle errorelse{varnewlyCreatedUserId=result.rows[0].id;}});

8. Does node-postgres handle SQL injection?

Absolutely! The parameterized query support in node-postgres is first class. All escaping is done by the postgresql server ensuring proper behavior across dialects, encodings, etc... For example, this will not inject sql:

client.query("INSERT INTO user(name) VALUES($1)",["'; DROP TABLE user;"],function(err,result){// ...});

9. Can I create a named prepared statement for use later on without performing a query? If not, does passing the same text again to a named statement get ignored and the cached version used? I don't want to have two codepaths in a function, one for first-use and one for every other.

If a prepared statement has a name, it is only parsed once. After that, name will re-use the prepared statement regardless of what text is.

10. Can we override the built in data converters between javascript and postgres data types?

Yes, here is a test that shows how it can be done. And for some examples of already registered converters, take a look at the node-pg-types project.

11. How do I build a WHERE foo IN (...) query to find rows matching an array of values?

node-postgres supports mapping simple JavaScript arrays to PostgreSQL arrays, so in most cases you can just pass it like any other parameter.

client.query("SELECT * FROM stooges WHERE name = ANY ($1)",[['larry','curly','moe']], ...);

Note that = ANY is another way to write IN (...), but unlike IN (...) it will work how you'd expect when you pass an array as a query parameter.

If you know the length of the array in advance you can flatten it to an IN list:

// passing a flat array of values will work:
client.query("SELECT * FROM stooges WHERE name IN ($1, $2, $3)", ['larry', 'curly', 'moe'], ...);

... but there's little benefit when = ANY works with a JavaScript array.

If you're on an old version of node-postgres or you need to create more complex PostgreSQL arrays (arrays of composite types, etc) that node-postgres isn't coping with, you can generate an array literal with dynamic SQL, but be extremely careful of SQL injection when doing this. The following approach is safe because it generates a query string with query parameters and a flattened parameter list, so you're still using the driver's support for parameterised queries ("prepared statements") to protect against SQL injection:

varstooge_names=['larry','curly','moe'];varoffset=1;varplaceholders=stooge_names.map(function(name,i){return'$'+(i+offset);}).join(',');client.query("SELECT * FROM stooges WHERE name IN ("+placeholders+")",stooge_names, ...);

If you have other values and placeholders in your query you'll need to use a different offset value for the array placeholders. See #129 and #82 for extra discussion.

12. Why does node-postgres come with two bindings? One in Javascript and one "native" that uses libpq? Which one is fastest and why isn't a single binding enough?

node-postgres comes with two bindings because I wrote it back before the idea of "do one tiny thing in each module" was a popular idea. I initially wrote the pure-javascript bindings. People were complaining about adopting them because it wasn't a C binding so it wasn't fast. To answer their critique I wrote libpq bindings. I placed them in the same module because I could reuse 70% of the tests (all of the integration tests) so I could quickly know when the APIs diverged.

note: sometime after v1.0 I plan on splitting the javascript, native, and integration tests into their own modules. the node-postgres module itself will be a sort of 'meta package' for the other modules

Last time I checked the native bindings were faster than the pure JavaScript bindings; however, there are performance gains still available to both through code refactors and this can/will change. Either binding you use is fast enough to not end up being a significant factor in your application. As for why isn't a single binding enough? A single binding is enough - either one 😉.

Personally, I like the pure JavaScript bindings because it's JavaScript all the way down, but they both work equally and have full feature parity due to the extensive overlapping test suite.

13. What happens to open transactions when pg.connect's done is called?

Nothing. You are responsible for calling either client.query('COMMIT') or client.query('ROLLBACK') If you call neither and call the done() callback the client will be returned to the pool with an open transaction, and I assume bad things will happen in your application.

14. How do I install pg on Windows?

Problem: npm install pg fails with error message Call to 'pg_config --libdir' returned exit status 1. while trying to load binding.gyp

You need PostgreSQL installed on your system. The path to PostgreSQL bin directory must be included in the environment PATH variable. pg_config is stored in that bin directory.

Quick fix for PowerShell:

$env:PATH+=";C:\Program Files\PostgreSQL\9.2\bin"

npm install pg

15. (New Question) How can a quickly get a Client from Client pool?

pg.connect(): It takes time to reconnect ?

16. (New Question) Are queries asynchronous, or do they block? Can this behavior be overridden if desired?

17. What happens if I ask for a connection and the pool is already empty? will it throw an error or wait until a connection becomes available?

It will wait, and call your callback with a connection after one becomes available. This package uses the generic-pool package to provide this behavior.

18. (New Question) Is there a way to check if I have an active connection?


◄ Back (Transactions)Next (Example App) ►

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
HuaHsin Lu edited this page Jan 26, 2016 · 44 revisions

Thanks to g40

1. How do I know what values are on the row object?

The row object has properties which align to the column names returned from the query.

Given a table users with columns 'name' and 'age' doing select * from users would return you a result object with an array of row objects. Each row object would have the properties name and age. Example:

client.query('SELECT * FROM users',function(err,result){console.log('name: %s and age: %d',result.rows[0].name,result.rows[0].age);//since the row object is just a hash, it can be accessed also as followsconsole.log('name: %s and age: %d',result.rows[0]['name'],result.rows[0]['age']);});

2. Can I iterate across the columns in the recordset to dynamically display column names?

Why, yes. Yes you can.

client.query(...,function(err,result){varfirstRow=result.rows[0];for(varcolumnNameinfirstRow){console.log('column "%s" has a value of "%j"',columnName,firstRow[columnName]);}});

3. Assuming a recordset is enumerated using the array accessor style used in 1, can we get the column names in the same fashion, i.e. is there a result.rows[i].columnName property?

This is possible using the result.fields array:

client.query(...,function(err,result){console.log("Returned columns:",result.fields.map(function(f){returnf.name;}).join(', '));});

4. How do you get the count of columns in the result set ?

client.query(...,function(err,result){varcolumnCount=Object.keys(result.rows[0]).length;});

This may also be accomplished using the result.fields array:

client.query(...,function(err,result){varcolumnCount=result.fields.length;});

5. If pg returns query data in JSON format, for web service applications, it would make sense to return that directly to the client. If this assumption is correct what is the most efficient method?

http.createServer(function(req,res){//NOTE: pg connection boilerplate not presentpg.query(...,function(err,result){//NOTE: error handling not presentvarjson=JSON.stringify(result.rows);res.writeHead(200,{'content-type':'application/json','content-length':Buffer.byteLength(json)});res.end(json);});})

6. How do I use the Client instance directly?

Example code:

varclient=newClient(connectionString);client.connect();// now enumerate ...enumerate(client,path,callback);//client.end();

This fails with:

varclient=newClient(connectionString);^
ReferenceError: Clientisnotdefined

When you import the postgres library you commonly do require('pg'). This works and requires the 'root' of the library with various properties hanging off of it. To directly instantiate a specific client instance instead of using the pool you can access the client constructor off the the imported pg object.

  1. var Client = require('pg').Client;

or for the native client

  1. var Client = require('pg').native.Client;

Thank you Brian. pg is excellent.

7. I just have a question and maybe a feature request that i am not able to think about how to implement or do it: i need to retrieve the inserted row or someway to reach it after the insert is done.

Yeah, you can do this as so:

//let's pretend we have a user table with the 'id' as the auto-incrementing primary keyvarqueryText='INSERT INTO users(password_hash, email) VALUES($1, $2) RETURNING id'client.query(queryText,['841l14yah','test@te.st'],function(err,result){if(err)//handle errorelse{varnewlyCreatedUserId=result.rows[0].id;}});

8. Does node-postgres handle SQL injection?

Absolutely! The parameterized query support in node-postgres is first class. All escaping is done by the postgresql server ensuring proper behavior across dialects, encodings, etc... For example, this will not inject sql:

client.query("INSERT INTO user(name) VALUES($1)",["'; DROP TABLE user;"],function(err,result){// ...});

9. Can I create a named prepared statement for use later on without performing a query? If not, does passing the same text again to a named statement get ignored and the cached version used? I don't want to have two codepaths in a function, one for first-use and one for every other.

If a prepared statement has a name, it is only parsed once. After that, name will re-use the prepared statement regardless of what text is.

10. Can we override the built in data converters between javascript and postgres data types?

Yes, here is a test that shows how it can be done. And for some examples of already registered converters, take a look at the node-pg-types project.

11. How do I build a WHERE foo IN (...) query to find rows matching an array of values?

node-postgres supports mapping simple JavaScript arrays to PostgreSQL arrays, so in most cases you can just pass it like any other parameter.

client.query("SELECT * FROM stooges WHERE name = ANY ($1)",[['larry','curly','moe']], ...);

Note that = ANY is another way to write IN (...), but unlike IN (...) it will work how you'd expect when you pass an array as a query parameter.

If you know the length of the array in advance you can flatten it to an IN list:

// passing a flat array of values will work:
client.query("SELECT * FROM stooges WHERE name IN ($1, $2, $3)", ['larry', 'curly', 'moe'], ...);

... but there's little benefit when = ANY works with a JavaScript array.

If you're on an old version of node-postgres or you need to create more complex PostgreSQL arrays (arrays of composite types, etc) that node-postgres isn't coping with, you can generate an array literal with dynamic SQL, but be extremely careful of SQL injection when doing this. The following approach is safe because it generates a query string with query parameters and a flattened parameter list, so you're still using the driver's support for parameterised queries ("prepared statements") to protect against SQL injection:

varstooge_names=['larry','curly','moe'];varoffset=1;varplaceholders=stooge_names.map(function(name,i){return'$'+(i+offset);}).join(',');client.query("SELECT * FROM stooges WHERE name IN ("+placeholders+")",stooge_names, ...);

If you have other values and placeholders in your query you'll need to use a different offset value for the array placeholders. See #129 and #82 for extra discussion.

12. Why does node-postgres come with two bindings? One in Javascript and one "native" that uses libpq? Which one is fastest and why isn't a single binding enough?

node-postgres comes with two bindings because I wrote it back before the idea of "do one tiny thing in each module" was a popular idea. I initially wrote the pure-javascript bindings. People were complaining about adopting them because it wasn't a C binding so it wasn't fast. To answer their critique I wrote libpq bindings. I placed them in the same module because I could reuse 70% of the tests (all of the integration tests) so I could quickly know when the APIs diverged.

note: sometime after v1.0 I plan on splitting the javascript, native, and integration tests into their own modules. the node-postgres module itself will be a sort of 'meta package' for the other modules

Last time I checked the native bindings were faster than the pure JavaScript bindings; however, there are performance gains still available to both through code refactors and this can/will change. Either binding you use is fast enough to not end up being a significant factor in your application. As for why isn't a single binding enough? A single binding is enough - either one 😉.

Personally, I like the pure JavaScript bindings because it's JavaScript all the way down, but they both work equally and have full feature parity due to the extensive overlapping test suite.

13. What happens to open transactions when pg.connect's done is called?

Nothing. You are responsible for calling either client.query('COMMIT') or client.query('ROLLBACK') If you call neither and call the done() callback the client will be returned to the pool with an open transaction, and I assume bad things will happen in your application.

14. How do I install pg on Windows?

Problem: npm install pg fails with error message Call to 'pg_config --libdir' returned exit status 1. while trying to load binding.gyp

You need PostgreSQL installed on your system. The path to PostgreSQL bin directory must be included in the environment PATH variable. pg_config is stored in that bin directory.

Quick fix for PowerShell:

$env:PATH+=";C:\Program Files\PostgreSQL\9.2\bin"

npm install pg

15. (New Question) How can a quickly get a Client from Client pool?

pg.connect(): It takes time to reconnect ?

16. (New Question) Are queries asynchronous, or do they block? Can this behavior be overridden if desired?

17. What happens if I ask for a connection and the pool is already empty? will it throw an error or wait until a connection becomes available?

It will wait, and call your callback with a connection after one becomes available. This package uses the generic-pool package to provide this behavior.

18. (New Question) Is there a way to check if I have an active connection?


◄ Back (Transactions)Next (Example App) ►

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
HuaHsin Lu edited this page Jan 26, 2016 · 44 revisions

Thanks to g40

1. How do I know what values are on the row object?

The row object has properties which align to the column names returned from the query.

Given a table users with columns 'name' and 'age' doing select * from users would return you a result object with an array of row objects. Each row object would have the properties name and age. Example:

client.query('SELECT * FROM users',function(err,result){console.log('name: %s and age: %d',result.rows[0].name,result.rows[0].age);//since the row object is just a hash, it can be accessed also as followsconsole.log('name: %s and age: %d',result.rows[0]['name'],result.rows[0]['age']);});

2. Can I iterate across the columns in the recordset to dynamically display column names?

Why, yes. Yes you can.

client.query(...,function(err,result){varfirstRow=result.rows[0];for(varcolumnNameinfirstRow){console.log('column "%s" has a value of "%j"',columnName,firstRow[columnName]);}});

3. Assuming a recordset is enumerated using the array accessor style used in 1, can we get the column names in the same fashion, i.e. is there a result.rows[i].columnName property?

This is possible using the result.fields array:

client.query(...,function(err,result){console.log("Returned columns:",result.fields.map(function(f){returnf.name;}).join(', '));});

4. How do you get the count of columns in the result set ?

client.query(...,function(err,result){varcolumnCount=Object.keys(result.rows[0]).length;});

This may also be accomplished using the result.fields array:

client.query(...,function(err,result){varcolumnCount=result.fields.length;});

5. If pg returns query data in JSON format, for web service applications, it would make sense to return that directly to the client. If this assumption is correct what is the most efficient method?

http.createServer(function(req,res){//NOTE: pg connection boilerplate not presentpg.query(...,function(err,result){//NOTE: error handling not presentvarjson=JSON.stringify(result.rows);res.writeHead(200,{'content-type':'application/json','content-length':Buffer.byteLength(json)});res.end(json);});})

6. How do I use the Client instance directly?

Example code:

varclient=newClient(connectionString);client.connect();// now enumerate ...enumerate(client,path,callback);//client.end();

This fails with:

varclient=newClient(connectionString);^
ReferenceError: Clientisnotdefined

When you import the postgres library you commonly do require('pg'). This works and requires the 'root' of the library with various properties hanging off of it. To directly instantiate a specific client instance instead of using the pool you can access the client constructor off the the imported pg object.

  1. var Client = require('pg').Client;

or for the native client

  1. var Client = require('pg').native.Client;

Thank you Brian. pg is excellent.

7. I just have a question and maybe a feature request that i am not able to think about how to implement or do it: i need to retrieve the inserted row or someway to reach it after the insert is done.

Yeah, you can do this as so:

//let's pretend we have a user table with the 'id' as the auto-incrementing primary keyvarqueryText='INSERT INTO users(password_hash, email) VALUES($1, $2) RETURNING id'client.query(queryText,['841l14yah','test@te.st'],function(err,result){if(err)//handle errorelse{varnewlyCreatedUserId=result.rows[0].id;}});

8. Does node-postgres handle SQL injection?

Absolutely! The parameterized query support in node-postgres is first class. All escaping is done by the postgresql server ensuring proper behavior across dialects, encodings, etc... For example, this will not inject sql:

client.query("INSERT INTO user(name) VALUES($1)",["'; DROP TABLE user;"],function(err,result){// ...});

9. Can I create a named prepared statement for use later on without performing a query? If not, does passing the same text again to a named statement get ignored and the cached version used? I don't want to have two codepaths in a function, one for first-use and one for every other.

If a prepared statement has a name, it is only parsed once. After that, name will re-use the prepared statement regardless of what text is.

10. Can we override the built in data converters between javascript and postgres data types?

Yes, here is a test that shows how it can be done. And for some examples of already registered converters, take a look at the node-pg-types project.

11. How do I build a WHERE foo IN (...) query to find rows matching an array of values?

node-postgres supports mapping simple JavaScript arrays to PostgreSQL arrays, so in most cases you can just pass it like any other parameter.

client.query("SELECT * FROM stooges WHERE name = ANY ($1)",[['larry','curly','moe']], ...);

Note that = ANY is another way to write IN (...), but unlike IN (...) it will work how you'd expect when you pass an array as a query parameter.

If you know the length of the array in advance you can flatten it to an IN list:

// passing a flat array of values will work:
client.query("SELECT * FROM stooges WHERE name IN ($1, $2, $3)", ['larry', 'curly', 'moe'], ...);

... but there's little benefit when = ANY works with a JavaScript array.

If you're on an old version of node-postgres or you need to create more complex PostgreSQL arrays (arrays of composite types, etc) that node-postgres isn't coping with, you can generate an array literal with dynamic SQL, but be extremely careful of SQL injection when doing this. The following approach is safe because it generates a query string with query parameters and a flattened parameter list, so you're still using the driver's support for parameterised queries ("prepared statements") to protect against SQL injection:

varstooge_names=['larry','curly','moe'];varoffset=1;varplaceholders=stooge_names.map(function(name,i){return'$'+(i+offset);}).join(',');client.query("SELECT * FROM stooges WHERE name IN ("+placeholders+")",stooge_names, ...);

If you have other values and placeholders in your query you'll need to use a different offset value for the array placeholders. See #129 and #82 for extra discussion.

12. Why does node-postgres come with two bindings? One in Javascript and one "native" that uses libpq? Which one is fastest and why isn't a single binding enough?

node-postgres comes with two bindings because I wrote it back before the idea of "do one tiny thing in each module" was a popular idea. I initially wrote the pure-javascript bindings. People were complaining about adopting them because it wasn't a C binding so it wasn't fast. To answer their critique I wrote libpq bindings. I placed them in the same module because I could reuse 70% of the tests (all of the integration tests) so I could quickly know when the APIs diverged.

note: sometime after v1.0 I plan on splitting the javascript, native, and integration tests into their own modules. the node-postgres module itself will be a sort of 'meta package' for the other modules

Last time I checked the native bindings were faster than the pure JavaScript bindings; however, there are performance gains still available to both through code refactors and this can/will change. Either binding you use is fast enough to not end up being a significant factor in your application. As for why isn't a single binding enough? A single binding is enough - either one 😉.

Personally, I like the pure JavaScript bindings because it's JavaScript all the way down, but they both work equally and have full feature parity due to the extensive overlapping test suite.

13. What happens to open transactions when pg.connect's done is called?

Nothing. You are responsible for calling either client.query('COMMIT') or client.query('ROLLBACK') If you call neither and call the done() callback the client will be returned to the pool with an open transaction, and I assume bad things will happen in your application.

14. How do I install pg on Windows?

Problem: npm install pg fails with error message Call to 'pg_config --libdir' returned exit status 1. while trying to load binding.gyp

You need PostgreSQL installed on your system. The path to PostgreSQL bin directory must be included in the environment PATH variable. pg_config is stored in that bin directory.

Quick fix for PowerShell:

$env:PATH+=";C:\Program Files\PostgreSQL\9.2\bin"

npm install pg

15. (New Question) How can a quickly get a Client from Client pool?

pg.connect(): It takes time to reconnect ?

16. (New Question) Are queries asynchronous, or do they block? Can this behavior be overridden if desired?

17. What happens if I ask for a connection and the pool is already empty? will it throw an error or wait until a connection becomes available?

It will wait, and call your callback with a connection after one becomes available. This package uses the generic-pool package to provide this behavior.

18. (New Question) Is there a way to check if I have an active connection?


◄ Back (Transactions)Next (Example App) ►

Clone this wiki locally