diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..b512c09
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1 @@
+node_modules
\ No newline at end of file
diff --git a/Dockerfile.db-create b/Dockerfile.db-create
new file mode 100644
index 0000000..0239417
--- /dev/null
+++ b/Dockerfile.db-create
@@ -0,0 +1,10 @@
+FROM node:16
+WORKDIR /opt/app/
+COPY package.json ./
+RUN npm install
+RUN npm prune
+COPY . /opt/app
+ARG NODE_ENV
+ENV NODE_ENV $NODE_ENV
+
+CMD [ "npm", "run", "upgrade-db" ]
\ No newline at end of file
diff --git a/db/jambones-sql.sql b/db/jambones-sql.sql
index 16fd530..b157f3a 100644
--- a/db/jambones-sql.sql
+++ b/db/jambones-sql.sql
@@ -28,6 +28,8 @@ DROP TABLE IF EXISTS account_offers;
DROP TABLE IF EXISTS products;
+DROP TABLE IF EXISTS schema_version;
+
DROP TABLE IF EXISTS api_keys;
DROP TABLE IF EXISTS sbc_addresses;
@@ -190,6 +192,11 @@ stripe_product_id VARCHAR(56) NOT NULL,
PRIMARY KEY (account_offer_sid)
);
+CREATE TABLE schema_version
+(
+version VARCHAR(16)
+);
+
CREATE TABLE api_keys
(
api_key_sid CHAR(36) NOT NULL UNIQUE ,
@@ -565,4 +572,4 @@ ALTER TABLE accounts ADD FOREIGN KEY queue_event_hook_sid_idxfk (queue_event_hoo
ALTER TABLE accounts ADD FOREIGN KEY device_calling_application_sid_idxfk (device_calling_application_sid) REFERENCES applications (application_sid);
-SET FOREIGN_KEY_CHECKS=1;
+SET FOREIGN_KEY_CHECKS=0;
diff --git a/db/jambones.sqs b/db/jambones.sqs
index b8c40db..a6087ac 100644
--- a/db/jambones.sqs
+++ b/db/jambones.sqs
@@ -87,7 +87,7 @@
-
+
@@ -148,7 +148,7 @@
-
+
@@ -225,7 +225,7 @@
-
+
@@ -279,7 +279,7 @@
-
+
@@ -426,7 +426,7 @@
-
+
@@ -492,7 +492,7 @@
-
+
@@ -670,7 +670,7 @@
-
+
@@ -752,7 +752,7 @@
-
+
@@ -880,10 +880,29 @@
-
+
+
+
+
+
+ 2131.00
+ 136.00
+
+
+ 159.00
+ 40.00
+
+ 28
+
+
+
+
+
+
+
@@ -941,7 +960,7 @@
-
+
@@ -991,7 +1010,7 @@
-
+
@@ -1091,7 +1110,7 @@
-
+
@@ -1160,7 +1179,7 @@
-
+
@@ -1197,7 +1216,7 @@
-
+
@@ -1306,7 +1325,7 @@
-
+
@@ -1376,7 +1395,7 @@
-
+
@@ -1536,7 +1555,7 @@
-
+
@@ -1575,7 +1594,7 @@
-
+
@@ -1667,7 +1686,7 @@
-
+
@@ -1718,7 +1737,7 @@
-
+
@@ -1814,7 +1833,7 @@
-
+
@@ -1914,7 +1933,7 @@
-
+
@@ -2083,7 +2102,7 @@
-
+
@@ -2191,7 +2210,7 @@
-
+
@@ -2261,7 +2280,7 @@
-
+
@@ -2306,7 +2325,7 @@
-
+
@@ -2373,7 +2392,7 @@
-
+
@@ -2381,7 +2400,7 @@
-
+
@@ -2392,17 +2411,17 @@
-
+
-
-
-
-
-
+
+
+
+
+
diff --git a/db/upgrade-jambonz-db.js b/db/upgrade-jambonz-db.js
new file mode 100644
index 0000000..17297cb
--- /dev/null
+++ b/db/upgrade-jambonz-db.js
@@ -0,0 +1,71 @@
+#!/usr/bin/env node
+const assert = require('assert');
+const mysql = require('mysql2/promise');
+const {readFile} = require('fs/promises');
+const {execSync} = require('child_process');
+const {version:desiredVersion} = require('../package.json');
+const logger = require('pino')();
+
+logger.info(`upgrade-jambonz-db: desired version ${desiredVersion}`);
+
+assert.ok(process.env.JAMBONES_MYSQL_HOST, 'missing env JAMBONES_MYSQL_HOST');
+assert.ok(process.env.JAMBONES_MYSQL_DATABASE, 'missing env JAMBONES_MYSQL_DATABASE');
+assert.ok(process.env.JAMBONES_MYSQL_PASSWORD, 'missing env JAMBONES_MYSQL_PASSWORD');
+assert.ok(process.env.JAMBONES_MYSQL_USER, 'missing env JAMBONES_MYSQL_USER');
+
+const doIt = async () => {
+ let connection;
+ try {
+ connection = await mysql.createConnection({
+ host: process.env.JAMBONES_MYSQL_HOST,
+ user: process.env.JAMBONES_MYSQL_USER,
+ password: process.env.JAMBONES_MYSQL_PASSWORD,
+ database: process.env.JAMBONES_MYSQL_DATABASE,
+ port: process.env.JAMBONES_MYSQL_PORT || 3306,
+ multipleStatements: true
+ });
+ } catch (err) {
+ logger.error({err}, 'Error connecting to database with provided env vars');
+ return;
+ }
+
+ try {
+ /* does the schema exist at all ? */
+ const [r] = await connection.execute('SELECT version from schema_version');
+ if (r.length) {
+ //TODO: check against desired version and perform upgrades
+ logger.info(`current version is ${r[0].version}, no upgrade will be performed`);
+ await connection.end();
+ return;
+ }
+ } catch (err) {
+ }
+ try {
+ await createSchema(connection);
+ await seedDatabase(connection);
+ logger.info('reset admin password..');
+ execSync(`${__dirname}/../db/reset_admin_password.js`);
+ await connection.query(`INSERT into schema_version (version) values('${desiredVersion}')`);
+ logger.info('database install/upgrade complete.');
+ await connection.end();
+ } catch (err) {
+ logger.error({err}, 'Error seeding database');
+ process.exit(1);
+ }
+};
+
+const createSchema = async(connection) => {
+ logger.info('reading schema..');
+ const sql = await readFile(`${__dirname}/../db/jambones-sql.sql`, {encoding: 'utf8'});
+ logger.info('creating schema..');
+ await connection.query(sql);
+};
+
+const seedDatabase = async(connection) => {
+ const sql = await readFile(`${__dirname}/../db/seed-production-database-open-source.sql`, {encoding: 'utf8'});
+ logger.info('seeding data..');
+ await connection.query(sql);
+};
+
+doIt();
+
diff --git a/package.json b/package.json
index 393ace4..f7c9af9 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
"start": "node app.js",
"test": "NODE_ENV=test APPLY_JAMBONZ_DB_LIMITS=1 JWT_SECRET=foobarbazzle JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_TIME_SERIES_HOST=127.0.0.1 JAMBONES_LOGLEVEL=error JAMBONES_CREATE_CALL_URL=http://localhost/v1/createCall node test/ ",
"integration-test": "NODE_ENV=test JAMBONES_TIME_SERIES_HOST=127.0.0.1 AWS_REGION='us-east-1' JAMBONES_CURRENCY=USD JWT_SECRET=foobarbazzle JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=debug JAMBONES_CREATE_CALL_URL=http://localhost/v1/createCall node test/serve-integration.js",
+ "upgrade-db": "node ./db/upgrade-jambonz-db.js",
"coverage": "./node_modules/.bin/nyc --reporter html --report-dir ./coverage npm run test",
"jslint": "eslint app.js lib"
},