mirror of
https://github.com/NuSkooler/enigma-bbs.git
synced 2025-06-10 14:44:40 +02:00
ENiGMA 1/2 WILL USE SPACES FROM THIS POINT ON VS TABS
* Really just to make GitHub formatting happy. Arg.
This commit is contained in:
parent
5ddf04c882
commit
e9787cee3e
135 changed files with 27397 additions and 27397 deletions
330
core/database.js
330
core/database.js
|
@ -25,98 +25,98 @@ exports.initializeDatabases = initializeDatabases;
|
|||
exports.dbs = dbs;
|
||||
|
||||
function getTransactionDatabase(db) {
|
||||
return sqlite3Trans.wrap(db);
|
||||
return sqlite3Trans.wrap(db);
|
||||
}
|
||||
|
||||
function getDatabasePath(name) {
|
||||
return paths.join(conf.config.paths.db, `${name}.sqlite3`);
|
||||
return paths.join(conf.config.paths.db, `${name}.sqlite3`);
|
||||
}
|
||||
|
||||
function getModDatabasePath(moduleInfo, suffix) {
|
||||
//
|
||||
// Mods that use a database are stored in Config.paths.modsDb (e.g. enigma-bbs/db/mods)
|
||||
// We expect that moduleInfo defines packageName which will be the base of the modules
|
||||
// filename. An optional suffix may be supplied as well.
|
||||
//
|
||||
const HOST_RE = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/;
|
||||
//
|
||||
// Mods that use a database are stored in Config.paths.modsDb (e.g. enigma-bbs/db/mods)
|
||||
// We expect that moduleInfo defines packageName which will be the base of the modules
|
||||
// filename. An optional suffix may be supplied as well.
|
||||
//
|
||||
const HOST_RE = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/;
|
||||
|
||||
assert(_.isObject(moduleInfo));
|
||||
assert(_.isString(moduleInfo.packageName), 'moduleInfo must define "packageName"!');
|
||||
assert(_.isObject(moduleInfo));
|
||||
assert(_.isString(moduleInfo.packageName), 'moduleInfo must define "packageName"!');
|
||||
|
||||
let full = moduleInfo.packageName;
|
||||
if(suffix) {
|
||||
full += `.${suffix}`;
|
||||
}
|
||||
let full = moduleInfo.packageName;
|
||||
if(suffix) {
|
||||
full += `.${suffix}`;
|
||||
}
|
||||
|
||||
assert(
|
||||
(full.split('.').length > 1 && HOST_RE.test(full)),
|
||||
'packageName must follow Reverse Domain Name Notation - https://en.wikipedia.org/wiki/Reverse_domain_name_notation');
|
||||
assert(
|
||||
(full.split('.').length > 1 && HOST_RE.test(full)),
|
||||
'packageName must follow Reverse Domain Name Notation - https://en.wikipedia.org/wiki/Reverse_domain_name_notation');
|
||||
|
||||
return paths.join(conf.config.paths.modsDb, `${full}.sqlite3`);
|
||||
return paths.join(conf.config.paths.modsDb, `${full}.sqlite3`);
|
||||
}
|
||||
|
||||
function getISOTimestampString(ts) {
|
||||
ts = ts || moment();
|
||||
return ts.format('YYYY-MM-DDTHH:mm:ss.SSSZ');
|
||||
ts = ts || moment();
|
||||
return ts.format('YYYY-MM-DDTHH:mm:ss.SSSZ');
|
||||
}
|
||||
|
||||
function sanatizeString(s) {
|
||||
return s.replace(/[\0\x08\x09\x1a\n\r"'\\%]/g, c => { // eslint-disable-line no-control-regex
|
||||
switch (c) {
|
||||
case '\0' : return '\\0';
|
||||
case '\x08' : return '\\b';
|
||||
case '\x09' : return '\\t';
|
||||
case '\x1a' : return '\\z';
|
||||
case '\n' : return '\\n';
|
||||
case '\r' : return '\\r';
|
||||
return s.replace(/[\0\x08\x09\x1a\n\r"'\\%]/g, c => { // eslint-disable-line no-control-regex
|
||||
switch (c) {
|
||||
case '\0' : return '\\0';
|
||||
case '\x08' : return '\\b';
|
||||
case '\x09' : return '\\t';
|
||||
case '\x1a' : return '\\z';
|
||||
case '\n' : return '\\n';
|
||||
case '\r' : return '\\r';
|
||||
|
||||
case '"' :
|
||||
case '\'' :
|
||||
return `${c}${c}`;
|
||||
case '"' :
|
||||
case '\'' :
|
||||
return `${c}${c}`;
|
||||
|
||||
case '\\' :
|
||||
case '%' :
|
||||
return `\\${c}`;
|
||||
}
|
||||
});
|
||||
case '\\' :
|
||||
case '%' :
|
||||
return `\\${c}`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initializeDatabases(cb) {
|
||||
async.eachSeries( [ 'system', 'user', 'message', 'file' ], (dbName, next) => {
|
||||
dbs[dbName] = sqlite3Trans.wrap(new sqlite3.Database(getDatabasePath(dbName), err => {
|
||||
if(err) {
|
||||
return cb(err);
|
||||
}
|
||||
async.eachSeries( [ 'system', 'user', 'message', 'file' ], (dbName, next) => {
|
||||
dbs[dbName] = sqlite3Trans.wrap(new sqlite3.Database(getDatabasePath(dbName), err => {
|
||||
if(err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
dbs[dbName].serialize( () => {
|
||||
DB_INIT_TABLE[dbName]( () => {
|
||||
return next(null);
|
||||
});
|
||||
});
|
||||
}));
|
||||
}, err => {
|
||||
return cb(err);
|
||||
});
|
||||
dbs[dbName].serialize( () => {
|
||||
DB_INIT_TABLE[dbName]( () => {
|
||||
return next(null);
|
||||
});
|
||||
});
|
||||
}));
|
||||
}, err => {
|
||||
return cb(err);
|
||||
});
|
||||
}
|
||||
|
||||
function enableForeignKeys(db) {
|
||||
db.run('PRAGMA foreign_keys = ON;');
|
||||
db.run('PRAGMA foreign_keys = ON;');
|
||||
}
|
||||
|
||||
const DB_INIT_TABLE = {
|
||||
system : (cb) => {
|
||||
enableForeignKeys(dbs.system);
|
||||
system : (cb) => {
|
||||
enableForeignKeys(dbs.system);
|
||||
|
||||
// Various stat/event logging - see stat_log.js
|
||||
dbs.system.run(
|
||||
`CREATE TABLE IF NOT EXISTS system_stat (
|
||||
// Various stat/event logging - see stat_log.js
|
||||
dbs.system.run(
|
||||
`CREATE TABLE IF NOT EXISTS system_stat (
|
||||
stat_name VARCHAR PRIMARY KEY NOT NULL,
|
||||
stat_value VARCHAR NOT NULL
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.system.run(
|
||||
`CREATE TABLE IF NOT EXISTS system_event_log (
|
||||
dbs.system.run(
|
||||
`CREATE TABLE IF NOT EXISTS system_event_log (
|
||||
id INTEGER PRIMARY KEY,
|
||||
timestamp DATETIME NOT NULL,
|
||||
log_name VARCHAR NOT NULL,
|
||||
|
@ -124,10 +124,10 @@ const DB_INIT_TABLE = {
|
|||
|
||||
UNIQUE(timestamp, log_name)
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.system.run(
|
||||
`CREATE TABLE IF NOT EXISTS user_event_log (
|
||||
dbs.system.run(
|
||||
`CREATE TABLE IF NOT EXISTS user_event_log (
|
||||
id INTEGER PRIMARY KEY,
|
||||
timestamp DATETIME NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
|
@ -136,58 +136,58 @@ const DB_INIT_TABLE = {
|
|||
|
||||
UNIQUE(timestamp, user_id, log_name)
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
return cb(null);
|
||||
},
|
||||
return cb(null);
|
||||
},
|
||||
|
||||
user : (cb) => {
|
||||
enableForeignKeys(dbs.user);
|
||||
user : (cb) => {
|
||||
enableForeignKeys(dbs.user);
|
||||
|
||||
dbs.user.run(
|
||||
`CREATE TABLE IF NOT EXISTS user (
|
||||
dbs.user.run(
|
||||
`CREATE TABLE IF NOT EXISTS user (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_name VARCHAR NOT NULL,
|
||||
UNIQUE(user_name)
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
// :TODO: create FK on delete/etc.
|
||||
// :TODO: create FK on delete/etc.
|
||||
|
||||
dbs.user.run(
|
||||
`CREATE TABLE IF NOT EXISTS user_property (
|
||||
dbs.user.run(
|
||||
`CREATE TABLE IF NOT EXISTS user_property (
|
||||
user_id INTEGER NOT NULL,
|
||||
prop_name VARCHAR NOT NULL,
|
||||
prop_value VARCHAR,
|
||||
UNIQUE(user_id, prop_name),
|
||||
FOREIGN KEY(user_id) REFERENCES user(id) ON DELETE CASCADE
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.user.run(
|
||||
`CREATE TABLE IF NOT EXISTS user_group_member (
|
||||
dbs.user.run(
|
||||
`CREATE TABLE IF NOT EXISTS user_group_member (
|
||||
group_name VARCHAR NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
UNIQUE(group_name, user_id)
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.user.run(
|
||||
`CREATE TABLE IF NOT EXISTS user_login_history (
|
||||
dbs.user.run(
|
||||
`CREATE TABLE IF NOT EXISTS user_login_history (
|
||||
user_id INTEGER NOT NULL,
|
||||
user_name VARCHAR NOT NULL,
|
||||
timestamp DATETIME NOT NULL
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
return cb(null);
|
||||
},
|
||||
return cb(null);
|
||||
},
|
||||
|
||||
message : (cb) => {
|
||||
enableForeignKeys(dbs.message);
|
||||
message : (cb) => {
|
||||
enableForeignKeys(dbs.message);
|
||||
|
||||
dbs.message.run(
|
||||
`CREATE TABLE IF NOT EXISTS message (
|
||||
dbs.message.run(
|
||||
`CREATE TABLE IF NOT EXISTS message (
|
||||
message_id INTEGER PRIMARY KEY,
|
||||
area_tag VARCHAR NOT NULL,
|
||||
message_uuid VARCHAR(36) NOT NULL,
|
||||
|
@ -200,47 +200,47 @@ const DB_INIT_TABLE = {
|
|||
view_count INTEGER NOT NULL DEFAULT 0,
|
||||
UNIQUE(message_uuid)
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.message.run(
|
||||
`CREATE INDEX IF NOT EXISTS message_by_area_tag_index
|
||||
dbs.message.run(
|
||||
`CREATE INDEX IF NOT EXISTS message_by_area_tag_index
|
||||
ON message (area_tag);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.message.run(
|
||||
`CREATE VIRTUAL TABLE IF NOT EXISTS message_fts USING fts4 (
|
||||
dbs.message.run(
|
||||
`CREATE VIRTUAL TABLE IF NOT EXISTS message_fts USING fts4 (
|
||||
content="message",
|
||||
subject,
|
||||
message
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.message.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS message_before_update BEFORE UPDATE ON message BEGIN
|
||||
dbs.message.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS message_before_update BEFORE UPDATE ON message BEGIN
|
||||
DELETE FROM message_fts WHERE docid=old.rowid;
|
||||
END;`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.message.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS message_before_delete BEFORE DELETE ON message BEGIN
|
||||
dbs.message.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS message_before_delete BEFORE DELETE ON message BEGIN
|
||||
DELETE FROM message_fts WHERE docid=old.rowid;
|
||||
END;`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.message.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS message_after_update AFTER UPDATE ON message BEGIN
|
||||
dbs.message.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS message_after_update AFTER UPDATE ON message BEGIN
|
||||
INSERT INTO message_fts(docid, subject, message) VALUES(new.rowid, new.subject, new.message);
|
||||
END;`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.message.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS message_after_insert AFTER INSERT ON message BEGIN
|
||||
dbs.message.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS message_after_insert AFTER INSERT ON message BEGIN
|
||||
INSERT INTO message_fts(docid, subject, message) VALUES(new.rowid, new.subject, new.message);
|
||||
END;`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.message.run(
|
||||
`CREATE TABLE IF NOT EXISTS message_meta (
|
||||
dbs.message.run(
|
||||
`CREATE TABLE IF NOT EXISTS message_meta (
|
||||
message_id INTEGER NOT NULL,
|
||||
meta_category INTEGER NOT NULL,
|
||||
meta_name VARCHAR NOT NULL,
|
||||
|
@ -248,11 +248,11 @@ const DB_INIT_TABLE = {
|
|||
UNIQUE(message_id, meta_category, meta_name, meta_value),
|
||||
FOREIGN KEY(message_id) REFERENCES message(message_id) ON DELETE CASCADE
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
// :TODO: need SQL to ensure cleaned up if delete from message?
|
||||
/*
|
||||
// :TODO: need SQL to ensure cleaned up if delete from message?
|
||||
/*
|
||||
dbs.message.run(
|
||||
`CREATE TABLE IF NOT EXISTS hash_tag (
|
||||
hash_tag_id INTEGER PRIMARY KEY,
|
||||
|
@ -270,33 +270,33 @@ const DB_INIT_TABLE = {
|
|||
);
|
||||
*/
|
||||
|
||||
dbs.message.run(
|
||||
`CREATE TABLE IF NOT EXISTS user_message_area_last_read (
|
||||
dbs.message.run(
|
||||
`CREATE TABLE IF NOT EXISTS user_message_area_last_read (
|
||||
user_id INTEGER NOT NULL,
|
||||
area_tag VARCHAR NOT NULL,
|
||||
message_id INTEGER NOT NULL,
|
||||
UNIQUE(user_id, area_tag)
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.message.run(
|
||||
`CREATE TABLE IF NOT EXISTS message_area_last_scan (
|
||||
dbs.message.run(
|
||||
`CREATE TABLE IF NOT EXISTS message_area_last_scan (
|
||||
scan_toss VARCHAR NOT NULL,
|
||||
area_tag VARCHAR NOT NULL,
|
||||
message_id INTEGER NOT NULL,
|
||||
UNIQUE(scan_toss, area_tag)
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
return cb(null);
|
||||
},
|
||||
return cb(null);
|
||||
},
|
||||
|
||||
file : (cb) => {
|
||||
enableForeignKeys(dbs.file);
|
||||
file : (cb) => {
|
||||
enableForeignKeys(dbs.file);
|
||||
|
||||
dbs.file.run(
|
||||
// :TODO: should any of this be unique -- file_sha256 unless dupes are allowed on the system
|
||||
`CREATE TABLE IF NOT EXISTS file (
|
||||
dbs.file.run(
|
||||
// :TODO: should any of this be unique -- file_sha256 unless dupes are allowed on the system
|
||||
`CREATE TABLE IF NOT EXISTS file (
|
||||
file_id INTEGER PRIMARY KEY,
|
||||
area_tag VARCHAR NOT NULL,
|
||||
file_sha256 VARCHAR NOT NULL,
|
||||
|
@ -306,105 +306,105 @@ const DB_INIT_TABLE = {
|
|||
desc_long, /* FTS @ file_fts */
|
||||
upload_timestamp DATETIME NOT NULL
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE INDEX IF NOT EXISTS file_by_area_tag_index
|
||||
dbs.file.run(
|
||||
`CREATE INDEX IF NOT EXISTS file_by_area_tag_index
|
||||
ON file (area_tag);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE INDEX IF NOT EXISTS file_by_sha256_index
|
||||
dbs.file.run(
|
||||
`CREATE INDEX IF NOT EXISTS file_by_sha256_index
|
||||
ON file (file_sha256);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE VIRTUAL TABLE IF NOT EXISTS file_fts USING fts4 (
|
||||
dbs.file.run(
|
||||
`CREATE VIRTUAL TABLE IF NOT EXISTS file_fts USING fts4 (
|
||||
content="file",
|
||||
file_name,
|
||||
desc,
|
||||
desc_long
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS file_before_update BEFORE UPDATE ON file BEGIN
|
||||
dbs.file.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS file_before_update BEFORE UPDATE ON file BEGIN
|
||||
DELETE FROM file_fts WHERE docid=old.rowid;
|
||||
END;`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS file_before_delete BEFORE DELETE ON file BEGIN
|
||||
dbs.file.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS file_before_delete BEFORE DELETE ON file BEGIN
|
||||
DELETE FROM file_fts WHERE docid=old.rowid;
|
||||
END;`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS file_after_update AFTER UPDATE ON file BEGIN
|
||||
dbs.file.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS file_after_update AFTER UPDATE ON file BEGIN
|
||||
INSERT INTO file_fts(docid, file_name, desc, desc_long) VALUES(new.rowid, new.file_name, new.desc, new.desc_long);
|
||||
END;`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS file_after_insert AFTER INSERT ON file BEGIN
|
||||
dbs.file.run(
|
||||
`CREATE TRIGGER IF NOT EXISTS file_after_insert AFTER INSERT ON file BEGIN
|
||||
INSERT INTO file_fts(docid, file_name, desc, desc_long) VALUES(new.rowid, new.file_name, new.desc, new.desc_long);
|
||||
END;`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS file_meta (
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS file_meta (
|
||||
file_id INTEGER NOT NULL,
|
||||
meta_name VARCHAR NOT NULL,
|
||||
meta_value VARCHAR NOT NULL,
|
||||
UNIQUE(file_id, meta_name, meta_value),
|
||||
FOREIGN KEY(file_id) REFERENCES file(file_id) ON DELETE CASCADE
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS hash_tag (
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS hash_tag (
|
||||
hash_tag_id INTEGER PRIMARY KEY,
|
||||
hash_tag VARCHAR NOT NULL,
|
||||
|
||||
UNIQUE(hash_tag)
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS file_hash_tag (
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS file_hash_tag (
|
||||
hash_tag_id INTEGER NOT NULL,
|
||||
file_id INTEGER NOT NULL,
|
||||
|
||||
UNIQUE(hash_tag_id, file_id)
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS file_user_rating (
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS file_user_rating (
|
||||
file_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
rating INTEGER NOT NULL,
|
||||
|
||||
UNIQUE(file_id, user_id)
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS file_web_serve (
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS file_web_serve (
|
||||
hash_id VARCHAR NOT NULL PRIMARY KEY,
|
||||
expire_timestamp DATETIME NOT NULL
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS file_web_serve_batch (
|
||||
dbs.file.run(
|
||||
`CREATE TABLE IF NOT EXISTS file_web_serve_batch (
|
||||
hash_id VARCHAR NOT NULL,
|
||||
file_id INTEGER NOT NULL,
|
||||
|
||||
UNIQUE(hash_id, file_id)
|
||||
);`
|
||||
);
|
||||
);
|
||||
|
||||
return cb(null);
|
||||
}
|
||||
return cb(null);
|
||||
}
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue