Issue #23593:correctly handle nulls in address
[xtuple] / scripts / lib / util / init_database.js
1 /*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
2 regexp:true, undef:true, strict:true, trailing:true, white:true */
3 /*global _:true */
4
5 (function () {
6   "use strict";
7
8   var async = require("async"),
9     exec = require('child_process').exec,
10     path = require('path'),
11     os = require('os'),
12     winston = require('winston'),
13     dataSource = require('../../../node-datasource/lib/ext/datasource').dataSource,
14     inspectDatabaseExtensions = require("./inspect_database").inspectDatabaseExtensions;
15
16   //
17   // Wipe out the database
18   // and load it from scratch using pg_restore something.backup unless
19   // we're building from source.
20   //
21   var initDatabase = function (spec, creds, callback) {
22     var databaseName = spec.database,
23       credsClone = JSON.parse(JSON.stringify(creds)),
24       dropDatabase = function (done) {
25         winston.info("Dropping database " + databaseName);
26         // the calls to drop and create the database need to be run against the database "postgres"
27         credsClone.database = "postgres";
28         dataSource.query("drop database if exists " + databaseName + ";", credsClone, done);
29       },
30       createDatabase = function (done) {
31         winston.info("Creating database " + databaseName);
32         dataSource.query("create database " + databaseName + " template template1;", credsClone, done);
33       },
34       buildSchema = function (done) {
35         var schemaPath = path.join(path.dirname(spec.source), "440_schema.sql");
36         winston.info("Building schema for database " + databaseName);
37
38         exec("psql -U " + creds.username + " -h " + creds.hostname + " --single-transaction -p " +
39           creds.port + " -d " + databaseName + " -f " + schemaPath,
40           {maxBuffer: 40000 * 1024 /* 200x default */}, done);
41       },
42       populateData = function (done) {
43         winston.info("Populating data for database " + databaseName + " from " + spec.source);
44         exec("psql -U " + creds.username + " -h " + creds.hostname + " --single-transaction -p " +
45           creds.port + " -d " + databaseName + " -f " + spec.source,
46           {maxBuffer: 40000 * 1024 /* 200x default */}, done);
47       },
48       // use exec to restore the backup. The alternative, reading the backup file into a string to query
49       // doesn't work because the backup file is binary.
50       restoreBackup = function (done) {
51         exec("pg_restore -U " + creds.username + " -h " + creds.hostname + " -p " +
52           creds.port + " -d " + databaseName + " -j " + os.cpus().length + " " + spec.backup, function (err, res) {
53           if (err) {
54             console.log("ignoring restore db error", err);
55           }
56           done(null, res);
57         });
58       },
59       finish = function (err, results) {
60         if (err) {
61           winston.error("init database error", err.message, err.stack, err);
62         }
63         callback(err, results);
64       };
65
66     if (spec.source) {
67       async.series([
68         dropDatabase,
69         createDatabase,
70         buildSchema,
71         populateData
72       ], finish);
73     } else {
74       async.series([
75         dropDatabase,
76         createDatabase,
77         restoreBackup,
78         function (done) {
79           credsClone.database = databaseName;
80           inspectDatabaseExtensions(credsClone, function (err, paths) {
81             // in the case of a build-from-backup, we ignore any user desires and dictate the extensions
82             spec.extensions = paths;
83             done();
84           });
85         }
86       ], finish);
87     }
88   };
89
90   exports.initDatabase = initDatabase;
91 }());