2021-11-22 16:55:27 -08:00
package persistence
import (
"fmt"
"database/sql"
2021-12-12 20:10:08 -08:00
"offline_twitter/terminal_utils"
2021-11-22 16:55:27 -08:00
)
2022-02-26 15:58:30 -08:00
const ENGINE_DATABASE_VERSION = 9
2021-11-22 16:55:27 -08:00
type VersionMismatchError struct {
EngineVersion int
DatabaseVersion int
}
func ( e VersionMismatchError ) Error ( ) string {
return fmt . Sprintf (
` This profile was created with database schema version % d , which is newer than this application ' s database schema version , % d .
Please upgrade this application to a newer version to use this profile . Or downgrade the profile ' s schema version , somehow . ` ,
e . DatabaseVersion , e . EngineVersion ,
)
}
/ * *
2021-12-21 16:05:51 -05:00
* The Nth entry is the migration that moves you from version N to version N + 1.
* ` len(MIGRATIONS) ` should always equal ` ENGINE_DATABASE_VERSION ` .
2021-11-22 16:55:27 -08:00
* /
var MIGRATIONS = [ ] string {
2021-12-12 19:38:28 -08:00
` create table polls ( rowid integer primary key ,
id integer unique not null check ( typeof ( id ) = ' integer ' ) ,
tweet_id integer not null ,
num_choices integer not null ,
2021-11-22 16:55:27 -08:00
2021-12-12 19:38:28 -08:00
choice1 text ,
choice1_votes integer ,
choice2 text ,
choice2_votes integer ,
choice3 text ,
choice3_votes integer ,
choice4 text ,
choice4_votes integer ,
voting_duration integer not null , -- in seconds
voting_ends_at integer not null ,
last_scraped_at integer not null ,
foreign key ( tweet_id ) references tweets ( id )
2021-12-20 14:07:20 -05:00
) ; ` ,
` alter table tweets add column is_conversation_scraped boolean default 0 ;
alter table tweets add column last_scraped_at integer not null default 0 ` ,
2021-12-21 16:05:51 -05:00
` update tombstone_types set tombstone_text = ' This Tweet is from a suspended account ' where rowid = 2 ;
2021-12-21 20:31:33 -05:00
insert into tombstone_types ( rowid , short_name , tombstone_text ) values ( 5 , ' violated ' , ' This Tweet violated the Twitter Rules ' ) , ( 6 , ' no longer exists ' , ' This Tweet is from an account that no longer exists ' ) ` ,
2021-12-23 15:36:14 -05:00
` alter table videos add column thumbnail_remote_url text not null default "missing" ;
alter table videos add column thumbnail_local_filename text not null default "missing" ` ,
2021-12-24 16:26:34 -05:00
` alter table videos add column duration integer not null default 0 ;
alter table videos add column view_count integer not null default 0 ` ,
2022-01-07 12:38:56 -05:00
` alter table users add column is_banned boolean default 0 ` ,
2022-02-01 15:48:43 -08:00
` alter table urls add column short_text text not null default "" ` ,
2022-02-14 17:15:01 -08:00
` insert into tombstone_types (rowid, short_name, tombstone_text) values (7, 'age-restricted', 'Age-restricted adult content. This content might not be appropriate for people under 18 years old. To view this media, you’ ll need to log in to Twitter') ` ,
2022-02-26 15:58:30 -08:00
` alter table users add column is_followed boolean default 0 ` ,
2021-11-22 16:55:27 -08:00
}
/ * *
* This should only get called on a newly created Profile .
* Subsequent updates should change the number , not insert a new row .
* /
func InitializeDatabaseVersion ( db * sql . DB ) {
_ , err := db . Exec ( "insert into database_version (version_number) values (?)" , ENGINE_DATABASE_VERSION )
if err != nil {
panic ( err )
}
}
func ( p Profile ) GetDatabaseVersion ( ) ( int , error ) {
row := p . DB . QueryRow ( "select version_number from database_version" )
var version int
err := row . Scan ( & version )
if err != nil {
return 0 , err
}
return version , nil
}
func ( p Profile ) check_and_update_version ( ) error {
version , err := p . GetDatabaseVersion ( )
if err != nil {
return err
}
if version > ENGINE_DATABASE_VERSION {
return VersionMismatchError { ENGINE_DATABASE_VERSION , version }
}
if ENGINE_DATABASE_VERSION > version {
2021-12-12 20:10:08 -08:00
fmt . Printf ( terminal_utils . COLOR_YELLOW )
fmt . Printf ( "================================================\n" )
2021-12-12 20:17:05 -08:00
fmt . Printf ( "Database version is out of date. Upgrading database from version %d to version %d!\n" , version , ENGINE_DATABASE_VERSION )
2021-12-12 20:10:08 -08:00
fmt . Printf ( terminal_utils . COLOR_RESET )
2021-11-22 17:03:57 -08:00
return p . UpgradeFromXToY ( version , ENGINE_DATABASE_VERSION )
2021-11-22 16:55:27 -08:00
}
return nil
}
/ * *
* Run all the migrations from version X to version Y , and update the ` database_version ` table ' s ` version_number `
* /
func ( p Profile ) UpgradeFromXToY ( x int , y int ) error {
for i := x ; i < y ; i ++ {
2021-12-12 20:10:08 -08:00
fmt . Printf ( terminal_utils . COLOR_CYAN )
2021-11-22 16:55:27 -08:00
fmt . Println ( MIGRATIONS [ i ] )
2021-12-12 20:10:08 -08:00
fmt . Printf ( terminal_utils . COLOR_RESET )
2021-11-22 16:55:27 -08:00
_ , err := p . DB . Exec ( MIGRATIONS [ i ] )
if err != nil {
return err
}
_ , err = p . DB . Exec ( "update database_version set version_number = ?" , i + 1 )
if err != nil {
return err
}
2021-12-12 20:10:08 -08:00
fmt . Printf ( terminal_utils . COLOR_YELLOW )
2021-11-22 16:55:27 -08:00
fmt . Printf ( "Now at database schema version %d.\n" , i + 1 )
2021-12-12 20:10:08 -08:00
fmt . Printf ( terminal_utils . COLOR_RESET )
2021-11-22 16:55:27 -08:00
}
2021-12-12 20:10:08 -08:00
fmt . Printf ( terminal_utils . COLOR_GREEN )
fmt . Printf ( "================================================\n" )
fmt . Printf ( "Database version has been upgraded to version %d.\n" , y )
fmt . Printf ( terminal_utils . COLOR_RESET )
2021-11-22 16:55:27 -08:00
return nil
}