database.js 4.3 KB

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