Implement database versioning and migration. It could not possibly be any simpler or easier to break, but it works. And it can be used to automatically migrate to a better system for migration later.

For now, the way it works is by creating a new migration script with the name of the version (increment by one, whole numbers) in the src/db folder
On start up, it will compare version numbers and run new scripts. The user can also manually check for migrations and skip the automatic checking.
Added a bit of additional logging to see what's happening in the startup process as well.
merge-requests/24/head
knotteye 2020-10-10 15:55:32 -05:00
parent a36a49b70e
commit ee3527f292
8 changed files with 62 additions and 4 deletions

View File

@ -13,7 +13,13 @@ Follow the instructions after setup runs.
### Run the server ### Run the server
```bash ```bash
npm start npm run start
```
You can also run this to skip checking the database version on startup.
```bash
npm run start -- --skip-migrate
# don't forget to migrate manually when you update
npm run migrate
``` ```
## Contributing ## Contributing

View File

@ -7,7 +7,8 @@
"scripts": { "scripts": {
"start": "ts-node src/index.ts", "start": "ts-node src/index.ts",
"user": "ts-node src/cli.ts", "user": "ts-node src/cli.ts",
"setup": "sh install/setup.sh" "setup": "sh install/setup.sh",
"migrate": "ts-node src/migrate.ts"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -1,10 +1,42 @@
import * as db from "./database"; import * as db from "./database";
import {readdirSync} from "fs";
async function init() { async function init(m?: boolean) {
if(!m){
console.log('Checking database version.');
var tmp: string[] = await db.query('show tables like \"db_meta\"');
if(tmp.length === 0){
console.log('No database version info, running initial migration.');
await require('./db/0').run();
await bringUpToDate();
}
else {
await bringUpToDate();
}
}
else {
console.log('Skipping database version check.');
}
//If satyr is restarted in the middle of a stream //If satyr is restarted in the middle of a stream
//it causes problems //it causes problems
//Live flags in the database stay live //Live flags in the database stay live
await db.query('update user_meta set live=false'); await db.query('update user_meta set live=false');
} }
async function bringUpToDate(): Promise<void>{
var versions: Object[] = await db.query('select * from db_meta');
var scripts: Buffer[] | string[] = readdirSync('./src/db/', {withFileTypes: false});
var diff: number = scripts.length - versions.length
if(diff === 0){
console.log('No migration needed.');
} else {
console.log('Versions differ, migrating now.');
for(let i=0;i<diff;i++){
console.log('Migration to version '+Math.floor(scripts.length-(diff-i)));
await require('./db/'+scripts[Math.floor(scripts.length-(diff-i))]).run();
}
console.log('Done migrating database.');
}
}
export { init }; export { init };

View File

@ -2,6 +2,7 @@ import {parseAsYaml as parse} from "parse-yaml";
import {readFileSync as read} from "fs"; import {readFileSync as read} from "fs";
try { try {
var localconfig: Object = parse(read('config/config.yml')); var localconfig: Object = parse(read('config/config.yml'));
console.log('Config file found.');
} catch (e) { } catch (e) {
console.log('No config file found. Exiting.'); console.log('No config file found. Exiting.');
process.exit(); process.exit();

View File

@ -9,6 +9,7 @@ var cryptoconfig: Object;
function init (){ function init (){
raw = mysql.createPool(config['database']); raw = mysql.createPool(config['database']);
cryptoconfig = config['crypto']; cryptoconfig = config['crypto'];
console.log('Connected to database.');
} }
async function addUser(name: string, password: string){ async function addUser(name: string, password: string){

8
src/db/0.ts Normal file
View File

@ -0,0 +1,8 @@
import * as db from "../database";
async function run () {
await db.query('CREATE TABLE IF NOT EXISTS db_meta(version SMALLINT)');
await db.query('INSERT INTO db_meta (version) VALUES (0)');
}
export { run }

View File

@ -7,7 +7,7 @@ import { config } from "./config";
async function run() { async function run() {
await initDB(); await initDB();
await clean(); await clean(process.argv.indexOf('--skip-migrate') !== -1);
await initHTTP(); await initHTTP();
await initRTMP(); await initRTMP();
await initChat(); await initChat();

9
src/migrate.ts Normal file
View File

@ -0,0 +1,9 @@
import {init as initDB} from "./database";
import {init as clean} from "./cleanup";
import { config } from "./config";
async function run() {
await initDB();
await clean(false);
}
run().then(() => {process.exit()});