Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modlog: Support logging to a SQLite database #7513

Merged
merged 38 commits into from
Oct 30, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
c6d0097
Modlog: Support logging to a SQLite database
Aug 19, 2020
ac00a28
small fixes
Oct 12, 2020
566ae3a
Add id tokenizer extension
monsanto Oct 14, 2020
e5398b4
Support FTS with chaos' extension
Oct 15, 2020
0a1b76c
code review
Oct 15, 2020
1289778
Default to FTS
Oct 15, 2020
8e80dd4
Fixes so I can run converter
monsanto Oct 15, 2020
2ebe051
Converter: Support FTS
Oct 15, 2020
bd4e291
Fix converter
Oct 16, 2020
96b55c0
Buffer by 25000 instead of 100
monsanto Oct 16, 2020
7d36831
dont insert nulls to FTS
Oct 16, 2020
222c8b9
Merge branch 'modlog-sql-new' of https://github.com/AnnikaCodes/pokem…
Oct 16, 2020
cb93fc9
Converter: Make some fixes
Oct 17, 2020
1a26693
Use FTS more
Oct 17, 2020
d649ef3
Merge remote-tracking branch 'upstream/master' into modlog-sql-new
Oct 17, 2020
236d949
alts_fts stuff
Oct 17, 2020
224ad43
right
Oct 17, 2020
57beee7
simplify
Oct 17, 2020
1f39120
fts changes
Oct 18, 2020
92f714e
simplify
Oct 20, 2020
e7f1b7b
Add Config setting to disable SQLite logging
Oct 22, 2020
4ff626d
Merge remote-tracking branch 'upstream/master' into modlog-sql-new
Oct 22, 2020
12ea945
Support Iterables in the modlog API
Oct 23, 2020
006fd20
More fixes
Oct 23, 2020
6c7b981
Merge branch 'modlog-sql-new' of https://github.com/AnnikaCodes/pokem…
Oct 23, 2020
50f0929
Fix transaction
Oct 23, 2020
6357b18
Fix query
Oct 23, 2020
cdf4444
Rename config setting
Oct 26, 2020
8028535
Don't automatically create a Modlog instance
Oct 26, 2020
3a2fe7d
Merge remote-tracking branch 'upstream/master' into modlog-sql-new
Oct 26, 2020
4de0bf7
Only run schema if database doesn't exist
monsanto Oct 28, 2020
484412d
Fix relative path on native extension
monsanto Oct 28, 2020
5695aec
Remove redundant transaction
monsanto Oct 30, 2020
145e788
Remove unused query functionality
monsanto Oct 30, 2020
bfadd1b
Skip prepareSQLSearch test
monsanto Oct 30, 2020
1f278dd
Remove FTS
monsanto Oct 30, 2020
e9effcb
Slightly optimize schema
monsanto Oct 30, 2020
9961d28
Fix /hotpatch modlog
Oct 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 33 additions & 0 deletions databases/schemas/modlog-fts.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
SELECT load_extension("native/fts_id_tokenizer.o");

CREATE TABLE IF NOT EXISTS modlog (
AnnikaCodes marked this conversation as resolved.
Show resolved Hide resolved
modlog_id INTEGER NOT NULL PRIMARY KEY,
-- UNIX timestamp
timestamp INTEGER NOT NULL,
--- roomid OR global-roomid
roomid TEXT NOT NULL,
action TEXT NOT NULL,
visual_roomid TEXT,
action_taker_userid TEXT,
userid TEXT,
autoconfirmed_userid TEXT,
ip TEXT,
note TEXT
);

CREATE TABLE IF NOT EXISTS alts (
modlog_id INTEGER NOT NULL,
userid TEXT NOT NULL,
PRIMARY KEY (modlog_id, userid),
FOREIGN KEY (modlog_id) REFERENCES modlog(modlog_id)
);

CREATE VIRTUAL TABLE modlog_fts USING fts5(note, content=modlog, content_rowid=modlog_id, tokenize='id_tokenizer')

CREATE INDEX IF NOT EXISTS ml_index_1 ON modlog(timestamp);
CREATE INDEX IF NOT EXISTS ml_index_2 ON modlog(roomid, userid, autoconfirmed_userid, timestamp);
CREATE INDEX IF NOT EXISTS ml_index_3 ON modlog(roomid, ip, timestamp);
CREATE INDEX IF NOT EXISTS ml_index_4 ON modlog(roomid, note, timestamp);
CREATE INDEX IF NOT EXISTS ml_index_5 ON modlog(roomid, action_taker_userid, timestamp);

PRAGMA journal_mode=WAL;
38 changes: 28 additions & 10 deletions server/modlog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ const MAX_PROCESSES = 1;
const LONG_QUERY_DURATION = 2000;
const MODLOG_PATH = 'logs/modlog';
const MODLOG_DB_PATH = `${__dirname}/../databases/modlog.db`;

const MODLOG_SCHEMA_PATH = 'databases/schemas/modlog.sql';
const MODLOG_SCHEMA_WITH_FTS_PATH = 'databases/schemas/modlog-fts.sql';

const GLOBAL_PUNISHMENTS = [
'WEEKLOCK', 'LOCK', 'BAN', 'RANGEBAN', 'RANGELOCK', 'FORCERENAME',
Expand Down Expand Up @@ -153,21 +155,32 @@ export class Modlog {
readonly globalPunishmentsSearchQuery: Database.Statement<[string, string, string, number, ...string[]]>;
readonly insertionTransaction: Database.Transaction;

readonly useFTS: boolean;

constructor(flatFilePath: string, databasePath: string) {
this.logPath = flatFilePath;
this.useFTS = Config.modlogfts;

this.database = new Database(databasePath);
this.database.exec("PRAGMA foreign_keys = ON;");
this.database.exec(FS(MODLOG_SCHEMA_PATH).readIfExistsSync()); // Set up tables, etc.

// Set up tables, etc
this.database.exec(
FS(this.useFTS ? MODLOG_SCHEMA_WITH_FTS_PATH : MODLOG_SCHEMA_PATH).readIfExistsSync()
);
this.database.function('regex', {deterministic: true}, (regexString, toMatch) => {
return Number(RegExp(regexString, 'i').test(toMatch));
});


this.modlogInsertionQuery = this.database.prepare(
`INSERT INTO modlog (timestamp, roomid, visual_roomid, action, userid, autoconfirmed_userid, ip, action_taker_userid, note)` +
` VALUES ($time, $roomID, $visualRoomID, $action, $userid, $autoconfirmedID, $ip, $loggedBy, $note)`
);
let insertionQuerySource = `INSERT INTO modlog (timestamp, roomid, visual_roomid, action, userid, autoconfirmed_userid, ip, action_taker_userid, note)`;
insertionQuerySource += ` VALUES ($time, $roomID, $visualRoomID, $action, $userid, $autoconfirmedID, $ip, $loggedBy, $note)`;
if (this.useFTS) {
insertionQuerySource += `INSERT INTO modlog_fts (timestamp, roomid, visual_roomid, action, userid, autoconfirmed_userid, ip, action_taker_userid, note)`;
AnnikaCodes marked this conversation as resolved.
Show resolved Hide resolved
insertionQuerySource += ` VALUES ($time, $roomID, $visualRoomID, $action, $userid, $autoconfirmedID, $ip, $loggedBy, $note)`;
}

this.modlogInsertionQuery = this.database.prepare(insertionQuerySource);
this.altsInsertionQuery = this.database.prepare(`INSERT INTO alts (modlog_id, userid) VALUES (?, ?)`);
this.renameQuery = this.database.prepare(`UPDATE modlog SET roomid = ? WHERE roomid = ?`);
this.globalPunishmentsSearchQuery = this.database.prepare(
Expand Down Expand Up @@ -498,8 +511,13 @@ export class Modlog {

args.push(...Array(6).fill(search.anyField));

query += ` OR regex(?, note)`;
args.push(this.generateIDRegex(toID(search.anyField)));
if (this.useFTS) {
query += ` OR note MATCH ?`;
AnnikaCodes marked this conversation as resolved.
Show resolved Hide resolved
args.push(toID(search.anyField));
} else {
query += ` OR note LIKE '%' || ? || '%'`;
args.push(search.anyField);
}
}

if (search.action) {
Expand Down Expand Up @@ -527,9 +545,9 @@ export class Modlog {
if (search.note) {
const parts = [];
for (const noteSearch of search.note.searches) {
if (!search.note.isExact) {
parts.push(`regex(?, note)`);
args.push(this.generateIDRegex(noteSearch));
if (this.useFTS && !search.note.isExact) {
parts.push(`note MATCH ?`);
args.push(toID(noteSearch));
} else {
parts.push(`note LIKE '%' || ? || '%'`);
args.push(noteSearch);
Expand Down