database.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. const {defaultSettings} = require('./util/default.json');
  2. const sqlite3 = require('sqlite3').verbose();
  3. const mode = ( process.env.READONLY ? sqlite3.OPEN_READONLY : sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE );
  4. const schema = [`
  5. BEGIN TRANSACTION;
  6. CREATE TABLE patreons (
  7. patreon TEXT PRIMARY KEY
  8. UNIQUE
  9. NOT NULL,
  10. count INTEGER NOT NULL
  11. );
  12. CREATE INDEX idx_patreons_patreon ON patreons (
  13. patreon
  14. );
  15. CREATE TABLE discord (
  16. main TEXT UNIQUE
  17. CHECK (main = guild),
  18. guild TEXT NOT NULL
  19. REFERENCES discord (main) ON DELETE CASCADE,
  20. channel TEXT,
  21. wiki TEXT NOT NULL
  22. DEFAULT [${defaultSettings.wiki}],
  23. lang TEXT NOT NULL
  24. DEFAULT [${defaultSettings.lang}],
  25. role TEXT,
  26. inline INTEGER,
  27. prefix TEXT NOT NULL
  28. DEFAULT [${process.env.prefix}],
  29. patreon TEXT REFERENCES patreons (patreon) ON DELETE SET NULL,
  30. voice INTEGER,
  31. UNIQUE (
  32. guild,
  33. channel
  34. )
  35. );
  36. CREATE INDEX idx_discord_channel ON discord (
  37. guild,
  38. channel DESC
  39. );
  40. CREATE INDEX idx_discord_patreon ON discord (
  41. patreon
  42. )
  43. WHERE patreon IS NOT NULL;
  44. CREATE INDEX idx_discord_voice ON discord (
  45. voice
  46. )
  47. WHERE voice IS NOT NULL;
  48. CREATE TABLE verification (
  49. guild TEXT NOT NULL
  50. REFERENCES discord (main) ON DELETE CASCADE,
  51. configid INTEGER NOT NULL,
  52. channel TEXT NOT NULL,
  53. role TEXT NOT NULL,
  54. editcount INTEGER NOT NULL
  55. DEFAULT [0],
  56. usergroup TEXT NOT NULL
  57. DEFAULT [user],
  58. accountage INTEGER NOT NULL
  59. DEFAULT [0],
  60. rename INTEGER NOT NULL
  61. DEFAULT [0],
  62. UNIQUE (
  63. guild,
  64. configid
  65. )
  66. );
  67. CREATE INDEX idx_verification_config ON verification (
  68. guild,
  69. configid ASC,
  70. channel
  71. );
  72. CREATE TABLE rcgcdw (
  73. guild TEXT NOT NULL
  74. REFERENCES discord (main) ON DELETE CASCADE,
  75. configid INTEGER NOT NULL,
  76. webhook TEXT NOT NULL
  77. UNIQUE,
  78. wiki TEXT NOT NULL,
  79. lang TEXT NOT NULL
  80. DEFAULT [${defaultSettings.lang}],
  81. display INTEGER NOT NULL
  82. DEFAULT [1],
  83. wikiid INTEGER,
  84. rcid INTEGER,
  85. postid TEXT,
  86. UNIQUE (
  87. guild,
  88. configid
  89. )
  90. );
  91. CREATE INDEX idx_rcgcdw_wiki ON rcgcdw (
  92. wiki
  93. );
  94. CREATE INDEX idx_rcgcdw_webhook ON rcgcdw (
  95. webhook
  96. );
  97. CREATE INDEX idx_rcgcdw_config ON rcgcdw (
  98. guild,
  99. configid ASC
  100. );
  101. CREATE TABLE blocklist (
  102. wiki TEXT UNIQUE
  103. NOT NULL,
  104. reason TEXT
  105. );
  106. CREATE INDEX idx_blocklist_wiki ON blocklist (
  107. wiki
  108. );
  109. COMMIT TRANSACTION;
  110. PRAGMA user_version = 1;
  111. `];
  112. module.exports = new Promise( (resolve, reject) => {
  113. const db = new sqlite3.Database( './wikibot.db', mode, dberror => {
  114. if ( dberror ) {
  115. console.log( '- Error while connecting to the database: ' + dberror );
  116. return reject();
  117. }
  118. db.get( 'PRAGMA user_version;', (error, row) => {
  119. if ( error ) {
  120. console.log( '- Error while getting the database version: ' + error );
  121. return reject();
  122. }
  123. if ( row.user_version > schema.length ) {
  124. console.log( '- Invalid database version: ' + row.user_version );
  125. return reject();
  126. }
  127. if ( row.user_version === schema.length ) {
  128. console.log( '- The database is up to date: ' + row.user_version );
  129. db.close( cerror => {
  130. if ( cerror ) {
  131. console.log( '- Error while closing the database connection: ' + cerror );
  132. return cerror;
  133. }
  134. } );
  135. return resolve();
  136. }
  137. console.log( '- The database outdated: ' + row.user_version );
  138. if ( process.env.READONLY ) return reject();
  139. db.exec( schema.filter( (sql, version) => {
  140. return ( row.user_version > version );
  141. } ).join('\n'), exerror => {
  142. if ( exerror ) {
  143. console.log( '- Error while updating the database: ' + exerror );
  144. return reject();
  145. }
  146. console.log( '- The database has been updated to: ' + schema.length );
  147. db.close( cerror => {
  148. if ( cerror ) {
  149. console.log( '- Error while closing the database connection: ' + cerror );
  150. return cerror;
  151. }
  152. } );
  153. return resolve();
  154. } );
  155. } );
  156. } );
  157. } );