forked from Markus-Rost/discord-wiki-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
database.js
260 lines (231 loc) · 6.6 KB
/
database.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
import { createRequire } from 'module';
import pg from 'pg';
const require = createRequire(import.meta.url);
const {defaultSettings} = require('./util/default.json');
const db = new pg.Client();
db.on( 'error', dberror => {
console.log( '- Error while connecting to the database: ' + dberror );
} );
const schema = [`
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS patreons (
patreon TEXT PRIMARY KEY
UNIQUE
NOT NULL,
count INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_patreons_patreon ON patreons (
patreon
);
CREATE TABLE IF NOT EXISTS discord (
main TEXT UNIQUE
CHECK (main = guild),
guild TEXT NOT NULL
REFERENCES discord (main) ON DELETE CASCADE,
channel TEXT,
wiki TEXT NOT NULL
DEFAULT '${defaultSettings.wiki}',
lang TEXT NOT NULL
DEFAULT '${defaultSettings.lang}',
role TEXT,
inline INTEGER,
prefix TEXT NOT NULL
DEFAULT '${process.env.prefix}',
patreon TEXT REFERENCES patreons (patreon) ON DELETE SET NULL,
voice INTEGER,
UNIQUE (
guild,
channel
)
);
CREATE INDEX IF NOT EXISTS idx_discord_channel ON discord (
guild,
channel DESC
NULLS LAST
);
CREATE INDEX IF NOT EXISTS idx_discord_patreon ON discord (
patreon
)
WHERE patreon IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_discord_voice ON discord (
voice
)
WHERE voice IS NOT NULL;
CREATE TABLE IF NOT EXISTS verification (
guild TEXT NOT NULL
REFERENCES discord (main) ON DELETE CASCADE,
configid INTEGER NOT NULL,
channel TEXT NOT NULL,
role TEXT NOT NULL,
editcount INTEGER NOT NULL
DEFAULT 0,
postcount INTEGER DEFAULT 0,
usergroup TEXT NOT NULL
DEFAULT 'user',
accountage INTEGER NOT NULL
DEFAULT 0,
rename INTEGER NOT NULL
DEFAULT 0,
UNIQUE (
guild,
configid
)
);
CREATE INDEX IF NOT EXISTS idx_verification_config ON verification (
guild,
configid ASC,
channel
);
CREATE TABLE IF NOT EXISTS verifynotice (
guild TEXT UNIQUE
NOT NULL
REFERENCES discord (main) ON DELETE CASCADE,
logchannel TEXT,
onsuccess TEXT,
onmatch TEXT,
flags INTEGER NOT NULL
DEFAULT 0
);
CREATE INDEX IF NOT EXISTS idx_verifynotice_guild ON verifynotice (
guild
);
CREATE TABLE IF NOT EXISTS oauthusers (
userid TEXT NOT NULL,
site TEXT NOT NULL,
token TEXT,
UNIQUE (
userid,
site
)
);
CREATE INDEX IF NOT EXISTS idx_oauthusers_userid ON oauthusers (
userid,
site
);
CREATE TABLE IF NOT EXISTS rcgcdw (
guild TEXT NOT NULL
REFERENCES discord (main) ON DELETE CASCADE,
configid INTEGER NOT NULL,
webhook TEXT NOT NULL
UNIQUE,
wiki TEXT NOT NULL,
lang TEXT NOT NULL
DEFAULT '${defaultSettings.lang}',
display INTEGER NOT NULL
DEFAULT 1,
rcid INTEGER,
postid TEXT DEFAULT '-1',
UNIQUE (
guild,
configid
)
);
CREATE INDEX IF NOT EXISTS idx_rcgcdw_wiki ON rcgcdw (
wiki
);
CREATE INDEX IF NOT EXISTS idx_rcgcdw_webhook ON rcgcdw (
webhook
);
CREATE INDEX IF NOT EXISTS idx_rcgcdw_config ON rcgcdw (
guild,
configid ASC
);
CREATE TABLE IF NOT EXISTS blocklist (
wiki TEXT UNIQUE
NOT NULL,
reason TEXT
);
CREATE INDEX IF NOT EXISTS idx_blocklist_wiki ON blocklist (
wiki
);
COMMIT TRANSACTION;
ALTER DATABASE "${process.env.PGDATABASE}" SET my.version TO 4;
`,`
BEGIN TRANSACTION;
guild TEXT UNIQUE
NOT NULL
REFERENCES discord (main) ON DELETE CASCADE,
CREATE TABLE IF NOT EXISTS verifynotice (
logchannel TEXT,
onsuccess TEXT,
onmatch TEXT
);
CREATE INDEX IF NOT EXISTS idx_verifynotice_guild ON verifynotice (
guild
);
COMMIT TRANSACTION;
ALTER DATABASE "${process.env.PGDATABASE}" SET my.version TO 2;
`,`
BEGIN TRANSACTION;
ALTER TABLE verifynotice
ADD COLUMN IF NOT EXISTS flags INTEGER NOT NULL DEFAULT 0;
COMMIT TRANSACTION;
ALTER DATABASE "${process.env.PGDATABASE}" SET my.version TO 3;
`,`
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS oauthusers (
userid TEXT NOT NULL,
site TEXT NOT NULL,
token TEXT,
UNIQUE (
userid,
site
)
);
CREATE INDEX IF NOT EXISTS idx_oauthusers_userid ON oauthusers (
userid,
site
);
COMMIT TRANSACTION;
ALTER DATABASE "${process.env.PGDATABASE}" SET my.version TO 4;
`];
export default await db.connect().then( () => {
return db.query( 'SELECT CURRENT_SETTING($1, $2) AS version', ['my.version', true] ).then( ({rows:[row]}) => {
if ( row.version === null ) {
return db.query( schema[0] ).then( () => {
console.log( '- The database has been updated to: v' + schema.length );
}, dberror => {
console.log( '- Error while updating the database: ' + dberror );
return Promise.reject();
} );
}
row.version = parseInt(row.version, 10);
if ( isNaN(row.version) || row.version > schema.length ) {
console.log( '- Invalid database version: v' + row.version );
return Promise.reject();
}
if ( row.version === schema.length ) {
console.log( '- The database is up to date: v' + row.version );
return;
}
console.log( '- The database is outdated: v' + row.version );
if ( process.env.READONLY ) return Promise.reject();
return db.query( schema.filter( (sql, version) => {
if ( row.version === 0 ) return ( version === 0 );
return ( row.version <= version );
} ).join('\n') ).then( () => {
console.log( '- The database has been updated to: v' + schema.length );
}, dberror => {
console.log( '- Error while updating the database: ' + dberror );
return Promise.reject();
} );
}, dberror => {
console.log( '- Error while getting the database version: ' + dberror );
return Promise.reject();
} );
}, dberror => {
console.log( '- Error while connecting to the database: ' + dberror );
return Promise.reject();
} ).then( () => {
db.end().catch( dberror => {
console.log( '- Error while closing the database connection: ' + dberror );
} );
}, () => {
return db.end().then( () => {
console.log( '- Closed the database connection.' );
}, dberror => {
console.log( '- Error while closing the database connection: ' + dberror );
} ).then( () => {
process.exit(1);
} );
} );