- Created view for journal query so we can use the calculated fields in a where clause - Changed journal ordering from newest-first to oldest-first; that way, clicking "prayed" at the top, one right after the other, will let the user pray through their list with minimal distraction - Answered requests now drop off the active journal (still need to write the ability to review answered requests) - All the activities now send messages to the user, so they have confirmation that their action has completed
98 lines
2.9 KiB
JavaScript
98 lines
2.9 KiB
JavaScript
'use strict'
|
|
|
|
import { Pool } from 'pg'
|
|
|
|
/**
|
|
* SQL to check the existence of a table in the mpj schema
|
|
* @param {string} table The name of the table whose existence should be checked
|
|
*/
|
|
const tableSql = table => `SELECT 1 FROM pg_tables WHERE schemaname='mpj' AND tablename='${table}'`
|
|
|
|
/**
|
|
* SQL to determine if an index exists
|
|
* @param {string} table The name of the table which the given index indexes
|
|
* @param {string} index The name of the index
|
|
*/
|
|
const indexSql = (table, index) =>
|
|
`SELECT 1 FROM pg_indexes WHERE schemaname='mpj' AND tablename='${table}' AND indexname='${index}'`
|
|
|
|
const ddl = [
|
|
{
|
|
name: 'myPrayerJournal Schema',
|
|
check: `SELECT 1 FROM pg_namespace WHERE nspname='mpj'`,
|
|
fix: `
|
|
CREATE SCHEMA mpj;
|
|
COMMENT ON SCHEMA mpj IS 'myPrayerJournal data'`
|
|
},
|
|
{
|
|
name: 'request Table',
|
|
check: tableSql('request'),
|
|
fix: `
|
|
CREATE TABLE mpj.request (
|
|
"requestId" varchar(25) PRIMARY KEY,
|
|
"enteredOn" bigint NOT NULL,
|
|
"userId" varchar(100) NOT NULL);
|
|
COMMENT ON TABLE mpj.request IS 'Requests'`
|
|
},
|
|
{
|
|
name: 'history Table',
|
|
check: tableSql('history'),
|
|
fix: `
|
|
CREATE TABLE mpj.history (
|
|
"requestId" varchar(25) NOT NULL REFERENCES mpj.request,
|
|
"asOf" bigint NOT NULL,
|
|
"status" varchar(25),
|
|
"text" text,
|
|
PRIMARY KEY ("requestId", "asOf"));
|
|
COMMENT ON TABLE mpj.history IS 'Request update history'`
|
|
},
|
|
{
|
|
name: 'request.userId Index',
|
|
check: indexSql('request', 'idx_request_userId'),
|
|
fix: `
|
|
CREATE INDEX "idx_request_userId" ON mpj.request ("userId");
|
|
COMMENT ON INDEX "idx_request_userId" IS 'Requests are retrieved by user'`
|
|
},
|
|
{
|
|
name: 'journal View',
|
|
check: `SELECT 1 FROM pg_views WHERE schemaname='mpj' AND viewname='journal'`,
|
|
fix: `
|
|
CREATE VIEW mpj.journal AS
|
|
SELECT
|
|
request."requestId",
|
|
request."userId",
|
|
(SELECT "text"
|
|
FROM mpj.history
|
|
WHERE history."requestId" = request."requestId"
|
|
AND "text" IS NOT NULL
|
|
ORDER BY "asOf" DESC
|
|
LIMIT 1) AS "text",
|
|
(SELECT "asOf"
|
|
FROM mpj.history
|
|
WHERE history."requestId" = request."requestId"
|
|
ORDER BY "asOf" DESC
|
|
LIMIT 1) AS "asOf",
|
|
(SELECT "status"
|
|
FROM mpj.history
|
|
WHERE history."requestId" = request."requestId"
|
|
ORDER BY "asOf" DESC
|
|
LIMIT 1) AS "lastStatus"
|
|
FROM mpj.request;
|
|
COMMENT ON VIEW mpj.journal IS 'Requests with latest text'`
|
|
}
|
|
]
|
|
|
|
export default function (query) {
|
|
return {
|
|
/**
|
|
* Ensure that the database schema, tables, and indexes exist
|
|
*/
|
|
ensureDatabase: async () => {
|
|
for (let item of ddl) {
|
|
const result = await query(item.check, [])
|
|
if (1 > result.rowCount) await query(item.fix, [])
|
|
}
|
|
}
|
|
}
|
|
}
|