From a33f417457651471d99be6d8c4bfa816d1dd6ed8 Mon Sep 17 00:00:00 2001 From: Hugo Manrique Date: Wed, 21 Apr 2021 22:29:57 +0200 Subject: [PATCH] Handle SQLite errors Should indicate the error occurring on #245. --- lib/app.js | 8 ++++---- lib/database.js | 52 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/lib/app.js b/lib/app.js index c4419b3..2bd7466 100644 --- a/lib/app.js +++ b/lib/app.js @@ -22,10 +22,10 @@ class App { this.database = new Database(this) // Setup database instance - this.database.ensureIndexes() - - this.database.loadGraphPoints(config.graphDuration, () => { - this.database.loadRecords(callback) + this.database.ensureIndexes(() => { + this.database.loadGraphPoints(config.graphDuration, () => { + this.database.loadRecords(callback) + }) }) } diff --git a/lib/database.js b/lib/database.js index c0bfe7c..bd7c603 100644 --- a/lib/database.js +++ b/lib/database.js @@ -1,5 +1,7 @@ const sqlite = require('sqlite3') +const logger = require('./logger') + const config = require('../config') const { TimeTracker } = require('./time') @@ -28,18 +30,36 @@ class Database { // Ensure the initial tables are created // This does not created indexes since it is only inserted to this._currentDatabaseCopyInstance.serialize(() => { - this._currentDatabaseCopyInstance.run('CREATE TABLE IF NOT EXISTS pings (timestamp BIGINT NOT NULL, ip TINYTEXT, playerCount MEDIUMINT)') + this._currentDatabaseCopyInstance.run('CREATE TABLE IF NOT EXISTS pings (timestamp BIGINT NOT NULL, ip TINYTEXT, playerCount MEDIUMINT)', err => { + if (err) { + logger.log('error', 'Cannot create initial table for daily database') + throw err + } + }) }) } return this._currentDatabaseCopyInstance } - ensureIndexes () { + ensureIndexes (callback) { + const handleError = err => { + if (err) { + logger.log('error', 'Cannot create table or table index') + throw err + } + } + this._sql.serialize(() => { - this._sql.run('CREATE TABLE IF NOT EXISTS pings (timestamp BIGINT NOT NULL, ip TINYTEXT, playerCount MEDIUMINT)') - this._sql.run('CREATE INDEX IF NOT EXISTS ip_index ON pings (ip, playerCount)') - this._sql.run('CREATE INDEX IF NOT EXISTS timestamp_index on PINGS (timestamp)') + this._sql.run('CREATE TABLE IF NOT EXISTS pings (timestamp BIGINT NOT NULL, ip TINYTEXT, playerCount MEDIUMINT)', handleError) + this._sql.run('CREATE INDEX IF NOT EXISTS ip_index ON pings (ip, playerCount)', handleError) + this._sql.run('CREATE INDEX IF NOT EXISTS timestamp_index on PINGS (timestamp)', [], err => { + handleError(err) + // Queries are executed one at a time; this is the last one. + // Note that queries not scheduled directly in the callback function of + // #serialize are not necessarily serialized. + callback() + }) }) } @@ -125,13 +145,24 @@ class Database { this._sql.all('SELECT * FROM pings WHERE timestamp >= ? AND timestamp <= ?', [ startTime, endTime - ], (_, data) => callback(data)) + ], (err, data) => { + if (err) { + logger.log('error', 'Cannot get recent pings') + throw err + } + callback(data) + }) } getRecord (ip, callback) { this._sql.all('SELECT MAX(playerCount), timestamp FROM pings WHERE ip = ?', [ ip - ], (_, data) => { + ], (err, data) => { + if (err) { + logger.log('error', `Cannot get ping record for ${ip}`) + throw err + } + // For empty results, data will be length 1 with [null, null] const playerCount = data[0]['MAX(playerCount)'] const timestamp = data[0].timestamp @@ -161,7 +192,12 @@ class Database { _insertPingTo (ip, timestamp, unsafePlayerCount, db) { const statement = db.prepare('INSERT INTO pings (timestamp, ip, playerCount) VALUES (?, ?, ?)') - statement.run(timestamp, ip, unsafePlayerCount) + statement.run(timestamp, ip, unsafePlayerCount, err => { + if (err) { + logger.error(`Cannot insert ping record of ${ip} at ${timestamp}`) + throw err + } + }) statement.finalize() } }