2020-08-30 13:54:59 +00:00
const pj = require ( "path" ) . join
const db = require ( "./db" )
const deltas = [
// 0: from empty file, +DatabaseVersion, +Subscriptions
function ( ) {
db . prepare ( "CREATE TABLE DatabaseVersion (version INTEGER NOT NULL, PRIMARY KEY (version))" )
. run ( )
db . prepare ( "CREATE TABLE Subscriptions (token TEXT NOT NULL, ucid TEXT NOT NULL, PRIMARY KEY (token, ucid))" )
. run ( )
db . prepare ( "CREATE TABLE Channels (ucid TEXT NOT NULL, name TEXT NOT NULL, icon_url TEXT, PRIMARY KEY (ucid))" )
. run ( )
2020-08-31 13:22:16 +00:00
db . prepare ( "CREATE TABLE Videos (videoId TEXT NOT NULL, title TEXT NOT NULL, author TEXT, authorId TEXT NOT NULL, published INTEGER, publishedText TEXT, lengthText TEXT, viewCountText TEXT, descriptionHtml TEXT, PRIMARY KEY (videoId))" )
. run ( )
2020-08-30 13:54:59 +00:00
db . prepare ( "CREATE TABLE CSRFTokens (token TEXT NOT NULL, expires INTEGER NOT NULL, PRIMARY KEY (token))" )
. run ( )
2020-08-31 13:22:16 +00:00
db . prepare ( "CREATE TABLE SeenTokens (token TEXT NOT NULL, seen INTEGER NOT NULL, PRIMARY KEY (token))" )
. run ( )
db . prepare ( "CREATE TABLE Settings (token TEXT NOT NULL, instance TEXT, save_history INTEGER, PRIMARY KEY (token))" )
. run ( )
2020-09-23 12:48:32 +00:00
} ,
// 1: Channels +refreshed
function ( ) {
db . prepare ( "ALTER TABLE Channels ADD COLUMN refreshed INTEGER" )
. run ( )
2020-10-26 07:29:05 +00:00
} ,
// 2: Settings +local
function ( ) {
db . prepare ( "ALTER TABLE Settings ADD COLUMN local INTEGER DEFAULT 0" )
. run ( )
2020-12-28 12:42:25 +00:00
} ,
// 3: +WatchedVideos
function ( ) {
db . prepare ( "CREATE TABLE WatchedVideos (token TEXT NOT NULL, videoID TEXT NOT NULL, PRIMARY KEY (token, videoID))" )
. run ( )
2021-02-06 07:06:55 +00:00
} ,
// 4: Fixup stored instance settings
function ( ) {
db . prepare ( "UPDATE Settings SET instance = REPLACE(REPLACE(instance, '/', ''), ':', '://') WHERE instance LIKE '%/'" )
. run ( )
2021-04-04 04:51:39 +00:00
} ,
// 5: Settings +quality
function ( ) {
db . prepare ( "ALTER TABLE Settings ADD COLUMN quality INTEGER DEFAULT 0" )
. run ( )
2021-05-11 12:29:44 +00:00
} ,
// 6: +Filters
function ( ) {
db . prepare ( "CREATE TABLE Filters (id INTEGER, token TEXT NOT NULL, type TEXT NOT NULL, data TEXT NOT NULL, label TEXT, PRIMARY KEY (id))" )
. run ( )
2021-08-16 10:37:12 +00:00
} ,
// 7: Settings +recommended_mode
function ( ) {
db . prepare ( "ALTER TABLE Settings ADD COLUMN recommended_mode INTEGER DEFAULT 0" )
. run ( )
2021-08-23 11:43:23 +00:00
} ,
// 8: Subscriptions +channel_missing
function ( ) {
db . prepare ( "ALTER TABLE Subscriptions ADD COLUMN channel_missing INTEGER DEFAULT 0" )
. run ( )
2021-08-26 11:47:53 +00:00
} ,
// 9: add index Videos (authorID)
function ( ) {
db . prepare ( "CREATE INDEX Videos_authorID ON Videos (authorID)" )
. run ( )
2021-11-20 06:42:34 +00:00
} ,
// 10: +TakedownVideos, +TakedownChannels
function ( ) {
db . prepare ( "CREATE TABLE TakedownVideos (id TEXT NOT NULL, org TEXT, url TEXT, PRIMARY KEY (id))" )
. run ( )
db . prepare ( "CREATE TABLE TakedownChannels (ucid TEXT NOT NULL, org TEXT, url TEXT, PRIMARY KEY (ucid))" )
. run ( )
2021-12-28 03:32:11 +00:00
} ,
// 11: Settings +theme
function ( ) {
db . prepare ( "ALTER TABLE Settings ADD COLUMN theme INTEGER DEFAULT 0" )
. run ( )
2022-01-10 01:18:45 +00:00
} ,
// 12: Channels +missing +missing_reason, Subscriptions -
// Better management for missing channels
// We totally discard the existing Subscriptions.channel_missing since it is unreliable.
function ( ) {
db . prepare ( "ALTER TABLE Channels ADD COLUMN missing INTEGER NOT NULL DEFAULT 0" )
. run ( )
db . prepare ( "ALTER TABLE Channels ADD COLUMN missing_reason TEXT" )
. run ( )
// https://www.sqlite.org/lang_altertable.html#making_other_kinds_of_table_schema_changes
db . transaction ( ( ) => {
db . prepare ( "CREATE TABLE NEW_Subscriptions (token TEXT NOT NULL, ucid TEXT NOT NULL, PRIMARY KEY (token, ucid))" )
. run ( )
db . prepare ( "INSERT INTO NEW_Subscriptions (token, ucid) SELECT token, ucid FROM Subscriptions" )
. run ( )
db . prepare ( "DROP TABLE Subscriptions" )
. run ( )
db . prepare ( "ALTER TABLE NEW_Subscriptions RENAME TO Subscriptions" )
. run ( )
} ) ( )
2020-08-30 13:54:59 +00:00
}
]
async function createBackup ( entry ) {
const filename = ` db/backups/cloudtube.db.bak-v ${ entry - 1 } `
process . stdout . write ( ` Backing up current to ${ filename } ... ` )
2020-09-23 12:48:32 +00:00
await db . backup ( pj ( _ _dirname , "../" , filename ) )
2020-08-30 13:54:59 +00:00
process . stdout . write ( "done.\n" )
}
/ * *
* @ param { number } entry
2021-12-28 03:32:11 +00:00
* @ param { boolean } [ log ]
2020-08-30 13:54:59 +00:00
* /
function runDelta ( entry , log ) {
process . stdout . write ( ` Upgrading database to version ${ entry } ... ` )
deltas [ entry ] ( )
db . prepare ( "DELETE FROM DatabaseVersion" ) . run ( )
db . prepare ( "INSERT INTO DatabaseVersion (version) VALUES (?)" ) . run ( entry )
process . stdout . write ( "done.\n" )
}
module . exports = async function ( ) {
let currentVersion = - 1
const newVersion = deltas . length - 1
try {
currentVersion = db . prepare ( "SELECT version FROM DatabaseVersion" ) . pluck ( ) . get ( )
} catch ( e ) { } // if the table doesn't exist yet then we don't care
if ( currentVersion !== newVersion ) {
// go through the entire upgrade sequence
for ( let entry = currentVersion + 1 ; entry <= newVersion ; entry ++ ) {
// Back up current version
if ( entry > 0 ) await createBackup ( entry )
// Run delta
runDelta ( entry )
}
}
}