Handshaking with a database using Node.js PgSQL client

Before doing some more fancy stuff, we should learn how to talk to our PostgreSQL database. In order to do so, once an appropriate project is created, we need to install a DB client. I used node-PostgreSQL:

    npm install pg --save
npm is the Node.js package manager, a utility that helps managing node packages: creating them, installing remote package, and so on. You will find more information at https://docs.npmjs.com/.

The code should be created in an index.js file:

const pg = require('pg'); 

//init client with the appropriate conn details
const client = new pg.Client({
host: 'localhost',
port: 5434,
user: 'postgres',
password: 'postgres',
database: 'mastering_postgis'
});

//connect to the db
client.connect(function(err){
if(err){
console.warn('Error connecting to the database: ', err.message);
throw err;
}

//once connected we can now interact with a db
client.query('SELECT PostGIS_full_version() as postgis_version;',
function(err, result){
if(err){
console.warn('Error obtaining PostGIS version: ', err.message);
throw err;
}

//there should be one row present provided PostGIS is installed. If
not, executing query would throw.
console.warn(result.rows[0].postgis_version);

//close the connection when done
client.end(function(err){
if(err){
console.warn('Error disconnecting: ', err.message);
throw err;
}
});
});
});

In short, the preceding code brings in a node-postgres package, creates a DB client with the appropriate connection details, and, once connected, it retrieves PostGIS version information and prints it to the console.

When you run this code via node index.js, you should see a similar output to the following:

POSTGIS="2.2.1 r14555" GEOS="3.5.0-CAPI-1.9.0 r4090" SFCGAL="1.2.2" PROJ="Rel. 4.9.1, 04 March 2015" GDAL="GDAL 2.0.1, released 2015/09/15" LIBXML="2.7.8" LIBJSON="0.12" TOPOLOGY RASTER  
The source code for this example is available in the chapter's resources in the code/03_db_handshake directory.

As you may have noticed, the asynchronous nature of Node.js requires us to await callbacks or subscribe to events in order to process the results of the functions called. This quickly becomes callback hell if we need to perform some more logic, and because of that, since we will now wrap our functions into promises, we can execute the code and avoid overnesting callbacks. Consider the following code:

var f1 = function(p1, p2){ 
return new Promise((resolve, reject)=>{
setTimeout(()=>{
if(!p1){
reject('whoaaa, f1 err - no params dude!');
}
else {
console.warn(`f1 processig following params: ${p1},
${p2}`);
resolve({p1: 'P3', p2: 'P4'});
}
}, 500);
});
}

var f2 = function(input){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
try {
console.warn(`f2 params are: ${input.p1}, ${input.p2}`);
}
catch(err){
reject(err.message);
}
}, 500);
});
}

//f1 & f2 executed one by one
f1('p1', 'p2').then(f2);

//f1 throws, execution goes to the next catch and since the chain ends there, execution stops
f1().then(f2).catch(err => {
console.warn(`Uups an error occured: ${err}`);
});

//f1 throws, err is processed in the next catch, and the execution continues to throw in f2 that is caught by the last catch
f1().catch(err => console.warn(`Uups an error occured: ${err}`)).then(f2).catch(err => console.warn(`Uups an error occured: ${err}`));

In the preceding code, we define two functions that do not return a potentially expected value, but a Promise object instead. Because of that, we can chain them together so that once one is resolved another one is called. In a scenario where a Promise object does not resolve, the very next catch function in the chain is called. Unless a catch function throws, the remaining <then> after catch is executed.

The source code for this example is available in the chapter's resources in the code/04_promises directory.

While some further reading on promises may be beneficial, the basic ideas behind promises are as follows:

  • A promise represents a value that can be handled at any time in the future. The consumer is guaranteed to receive that value regardless of the time a handler has been registered.
  • A promise value is immutable.

As we go forward, promises will be used to simplify our code and make it more readable.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset