1
0
mirror of https://github.com/matt-fidd/stratos.git synced 2026-01-01 22:19:26 +00:00

Added database initialisation script and mysql2 npm package

This commit is contained in:
2022-01-11 22:10:05 +00:00
parent a79c19a791
commit 55d68df2c5
5 changed files with 573 additions and 1 deletions

6
.gitignore vendored
View File

@@ -1,2 +1,8 @@
static/assets/diagrams/ static/assets/diagrams/
node_modules/ node_modules/
config/*.json
!config/*_sample*
*.swp

7
config/db_sample.json Normal file
View File

@@ -0,0 +1,7 @@
{
"host": "hostname",
"port": 1111,
"user": "username",
"password": "password",
"database": "dbname"
}

229
package-lock.json generated
View File

@@ -7,7 +7,234 @@
"": { "": {
"name": "stratos", "name": "stratos",
"version": "1.0.0", "version": "1.0.0",
"license": "MIT" "license": "MIT",
"dependencies": {
"mysql2": "^2.3.3"
}
},
"node_modules/denque": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
"integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==",
"engines": {
"node": ">=0.10"
}
},
"node_modules/generate-function": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
"integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
"dependencies": {
"is-property": "^1.0.2"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-property": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
},
"node_modules/long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/mysql2": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz",
"integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==",
"dependencies": {
"denque": "^2.0.1",
"generate-function": "^2.3.1",
"iconv-lite": "^0.6.3",
"long": "^4.0.0",
"lru-cache": "^6.0.0",
"named-placeholders": "^1.1.2",
"seq-queue": "^0.0.5",
"sqlstring": "^2.3.2"
},
"engines": {
"node": ">= 8.0"
}
},
"node_modules/named-placeholders": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz",
"integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==",
"dependencies": {
"lru-cache": "^4.1.3"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/named-placeholders/node_modules/lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"dependencies": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
}
},
"node_modules/named-placeholders/node_modules/yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
},
"node_modules/pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/seq-queue": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
"integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4="
},
"node_modules/sqlstring": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz",
"integrity": "sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
},
"dependencies": {
"denque": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
"integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ=="
},
"generate-function": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
"integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
"requires": {
"is-property": "^1.0.2"
}
},
"iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
}
},
"is-property": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
},
"long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"requires": {
"yallist": "^4.0.0"
}
},
"mysql2": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz",
"integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==",
"requires": {
"denque": "^2.0.1",
"generate-function": "^2.3.1",
"iconv-lite": "^0.6.3",
"long": "^4.0.0",
"lru-cache": "^6.0.0",
"named-placeholders": "^1.1.2",
"seq-queue": "^0.0.5",
"sqlstring": "^2.3.2"
}
},
"named-placeholders": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz",
"integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==",
"requires": {
"lru-cache": "^4.1.3"
},
"dependencies": {
"lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"requires": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
}
},
"yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
}
}
},
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"seq-queue": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
"integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4="
},
"sqlstring": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz",
"integrity": "sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg=="
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
} }
} }
} }

View File

@@ -17,5 +17,6 @@
}, },
"homepage": "https://github.com/matt-fidd/stratos#readme", "homepage": "https://github.com/matt-fidd/stratos#readme",
"dependencies": { "dependencies": {
"mysql2": "^2.3.3"
} }
} }

331
utility/db/dbInit.js Normal file
View File

@@ -0,0 +1,331 @@
'use strict';
// Import required modules
const mysql = require('mysql2/promise');
const path = require('path');
// Initialise maps for table creation and constraint queries
const tableCreate = new Map();
const tableConstraints = new Map();
// For each table, set tableCreate.tableName equal to the creation statment
// for that table
tableCreate.set('account', `
CREATE TABLE IF NOT EXISTS account (
accountId varchar(36) NOT NULL PRIMARY KEY,
email varchar(255) NOT NULL ,
firstName varchar(50) NOT NULL ,
otherNames varchar(255) NOT NULL ,
lastName varchar(50) NOT NULL ,
password varchar(60) NOT NULL ,
CONSTRAINT Unq_account_email UNIQUE ( email )
);
`);
tableCreate.set('parent', `
CREATE TABLE IF NOT EXISTS parent (
parentId varchar(36) NOT NULL PRIMARY KEY,
email varchar(255) NOT NULL ,
firstName varchar(50) NOT NULL ,
otherNames varchar(50) NOT NULL ,
lastName varchar(50) NOT NULL ,
password varchar(60) NOT NULL ,
CONSTRAINT Unq_parent UNIQUE ( email )
);
`);
tableCreate.set('student', `
CREATE TABLE IF NOT EXISTS student (
studentId varchar(36) NOT NULL PRIMARY KEY,
email varchar(255) NOT NULL ,
firstName varchar(50) NOT NULL ,
otherNames varchar(50) NOT NULL ,
lastName varchar(50) NOT NULL ,
password varchar(60) NOT NULL ,
CONSTRAINT Unq_student UNIQUE ( email )
);
`);
tableCreate.set('studentParentLink', `
CREATE TABLE IF NOT EXISTS studentParentLink (
studentid varchar(36) NOT NULL ,
parentId varchar(36) NOT NULL ,
CONSTRAINT pk_studentparentlink_studentid
PRIMARY KEY ( studentid, parentId )
);
`);
tableCreate.set('subject', `
CREATE TABLE IF NOT EXISTS subject (
subjectId int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(100) NOT NULL
);
`);
tableCreate.set('testTemplate', `
CREATE TABLE IF NOT EXISTS testTemplate (
testTemplateId varchar(36) NOT NULL PRIMARY KEY,
accountId varchar(36) NOT NULL ,
name varchar(100) NOT NULL ,
maxMark int NOT NULL
);
`);
tableCreate.set('class', `
CREATE TABLE IF NOT EXISTS class (
classId varchar(36) NOT NULL PRIMARY KEY,
name varchar(50) NOT NULL ,
subjectId int NOT NULL
);
`);
tableCreate.set('passwordReset', `
CREATE TABLE IF NOT EXISTS passwordReset (
accountId varchar(36) NOT NULL PRIMARY KEY,
token varchar(60) NOT NULL ,
nonce varchar(16) NOT NULL ,
expires datetime NOT NULL
);
`);
tableCreate.set('studentClassLink', `
CREATE TABLE IF NOT EXISTS studentClassLink (
studentId varchar(36) NOT NULL ,
classId varchar(36) NOT NULL ,
CONSTRAINT Pk_studentClassLink_studentId
PRIMARY KEY ( studentId, classId )
);
`);
tableCreate.set('test', `
CREATE TABLE IF NOT EXISTS test (
testId varchar(36) NOT NULL PRIMARY KEY,
testTemplateId varchar(36) NOT NULL ,
classId varchar(36) NOT NULL ,
testDate date NOT NULL ,
CONSTRAINT Unq_test UNIQUE ( testTemplateId, classId, testDate )
);
`);
tableCreate.set('testResult', `
CREATE TABLE IF NOT EXISTS testResult (
studentId varchar(36) NOT NULL ,
testId varchar(36) NOT NULL ,
accountId varchar(36) NOT NULL ,
mark int NOT NULL ,
CONSTRAINT primarykey PRIMARY KEY ( studentId, testId )
);
`);
tableCreate.set('accountClassLink', `
CREATE TABLE IF NOT EXISTS accountClassLink (
accountId varchar(36) NOT NULL ,
classId varchar(36) NOT NULL ,
CONSTRAINT primarykey PRIMARY KEY ( accountId, classId )
);
`);
// For each table constraint, set tableConstraints.constraitName equal to the
// creation statment for that constraint
tableConstraints.set('accountClassLink_fk0', `
ALTER TABLE accountClassLink
ADD CONSTRAINT accountClassLink_fk0
FOREIGN KEY IF NOT EXISTS ( accountId )
REFERENCES account( accountId )
ON DELETE CASCADE
ON UPDATE NO ACTION;
`);
tableConstraints.set('accountClassLink_fk1', `
ALTER TABLE accountClassLink
ADD CONSTRAINT accountClassLink_fk1
FOREIGN KEY IF NOT EXISTS ( classId )
REFERENCES class( classId )
ON DELETE CASCADE
ON UPDATE NO ACTION;
`);
tableConstraints.set('class_fk0', `
ALTER TABLE class
ADD CONSTRAINT class_fk0
FOREIGN KEY IF NOT EXISTS ( subjectId )
REFERENCES subject( subjectId )
ON DELETE RESTRICT
ON UPDATE NO ACTION;
`);
tableConstraints.set('fk_passwordreset_account', `
ALTER TABLE passwordReset
ADD CONSTRAINT fk_passwordreset_account
FOREIGN KEY IF NOT EXISTS ( accountId )
REFERENCES account( accountId )
ON DELETE CASCADE
ON UPDATE NO ACTION;
`);
tableConstraints.set('fk_passwordreset_parent', `
ALTER TABLE passwordReset
ADD CONSTRAINT fk_passwordreset_parent
FOREIGN KEY IF NOT EXISTS ( accountId )
REFERENCES parent( parentId )
ON DELETE CASCADE
ON UPDATE NO ACTION;
`);
tableConstraints.set('fk_passwordreset_student', `
ALTER TABLE passwordReset
ADD CONSTRAINT fk_passwordreset_student
FOREIGN KEY IF NOT EXISTS ( accountId )
REFERENCES student( studentId )
ON DELETE CASCADE
ON UPDATE NO ACTION;
`);
tableConstraints.set('fk_studentclasslink_student', `
ALTER TABLE studentClassLink
ADD CONSTRAINT fk_studentclasslink_student
FOREIGN KEY IF NOT EXISTS ( studentId )
REFERENCES student( studentId )
ON DELETE CASCADE
ON UPDATE NO ACTION;
`);
tableConstraints.set('fk_studentclasslink_class', `
ALTER TABLE studentClassLink
ADD CONSTRAINT fk_studentclasslink_class
FOREIGN KEY IF NOT EXISTS ( classId )
REFERENCES class( classId )
ON DELETE CASCADE
ON UPDATE NO ACTION;
`);
tableConstraints.set('fk_studentclasslink_class', `
ALTER TABLE studentParentLink
ADD CONSTRAINT studentParentLink_fk0
FOREIGN KEY IF NOT EXISTS ( studentid )
REFERENCES student( studentId )
ON DELETE CASCADE
ON UPDATE NO ACTION;
`);
tableConstraints.set('studentParentLink_fk1', `
ALTER TABLE studentParentLink
ADD CONSTRAINT studentParentLink_fk1
FOREIGN KEY IF NOT EXISTS ( parentId )
REFERENCES parent( parentId )
ON DELETE CASCADE
ON UPDATE NO ACTION;
`);
tableConstraints.set('fk_test_account', `
ALTER TABLE test
ADD CONSTRAINT fk_test_account
FOREIGN KEY IF NOT EXISTS ( classId )
REFERENCES class( classId )
ON DELETE RESTRICT
ON UPDATE NO ACTION;
`);
tableConstraints.set('fk_test_testtemplate', `
ALTER TABLE test
ADD CONSTRAINT fk_test_testtemplate
FOREIGN KEY IF NOT EXISTS ( testTemplateId )
REFERENCES testTemplate( testTemplateId )
ON DELETE NO ACTION
ON UPDATE NO ACTION;
`);
tableConstraints.set('testResult_fk0', `
ALTER TABLE testResult
ADD CONSTRAINT testResult_fk0
FOREIGN KEY IF NOT EXISTS ( studentId )
REFERENCES student( studentId )
ON DELETE CASCADE
ON UPDATE NO ACTION;
`);
tableConstraints.set('fk_testresult_test', `
ALTER TABLE testResult
ADD CONSTRAINT fk_testresult_test
FOREIGN KEY IF NOT EXISTS ( testId )
REFERENCES test( testId )
ON DELETE CASCADE
ON UPDATE NO ACTION;
`);
tableConstraints.set('fk_testresult_account', `
ALTER TABLE testResult
ADD CONSTRAINT fk_testresult_account
FOREIGN KEY IF NOT EXISTS ( accountId )
REFERENCES account( accountId )
ON DELETE NO ACTION
ON UPDATE NO ACTION;
`);
tableConstraints.set('test_fk0', `
ALTER TABLE testTemplate
ADD CONSTRAINT test_fk0
FOREIGN KEY IF NOT EXISTS ( accountId )
REFERENCES account( accountId )
ON DELETE NO ACTION
ON UPDATE NO ACTION;
`);
async function initialise(dbOptions) {
/*
Initialises a database using the options object provided
and applies schema to it
Arguments:
- database options object loaded in from
config/db.json
*/
// Connect to the database
const c = await mysql.createConnection(dbOptions);
// Run the creation statment for each table
for (const [ tableName, sql ] of tableCreate) {
console.log(`Creating table ${tableName}`);
try {
await c.execute(sql);
} catch (e) {
console.error(e);
throw new Error(`Unable to create table ${tableName}`);
}
}
console.log('\n');
// Run the creation statment for each constraint
for (const [ fkName, sql ] of tableConstraints) {
console.log(`Creating constraint ${fkName}`);
try {
await c.execute(sql);
} catch (e) {
console.error(e);
throw new Error('Unable to create constraint ' +
`${fkName}`);
}
}
// Drop the database connection
c.end();
console.log('\nFinished initialising database');
}
// Import data from config/db.json
let dbOptions;
try {
dbOptions = require(path.join(__dirname, '../../config/db.json'));
console.log('DB config loaded\n');
} catch {
return console.error('Missing or malformed config ' +
'(config/db.json)');
}
initialise(dbOptions);