feat: use userData electron path for database (subfolder with version)
This has the side effect of no more ormconfig.yml file, and the database connections are now only loaded on demand (as well as running the migrations). BREAKING CHANGE: there is no migration for the old database
This commit is contained in:
parent
41fc16c1c8
commit
e02e0d97e0
|
@ -15,10 +15,9 @@ node_modules
|
|||
|
||||
# created by testing
|
||||
/store-backup
|
||||
/database-backup
|
||||
/test-paths
|
||||
|
||||
# managed by application
|
||||
/database
|
||||
/store
|
||||
|
||||
# built app
|
||||
|
|
|
@ -3,13 +3,12 @@ const ignoreList = [
|
|||
/^\/\.vscode($|\/)/,
|
||||
|
||||
/^\/\.nyc_output($|\/)/,
|
||||
/^\/database($|\/)/,
|
||||
/^\/database-backup($|\/)/,
|
||||
/^\/declarations($|\/)/,
|
||||
/^\/mocks($|\/)/,
|
||||
/^\/store($|\/)/,
|
||||
/^\/store-backup($|\/)/,
|
||||
/^\/templates($|\/)/,
|
||||
/^\/test-paths($|\/)/,
|
||||
/^\/tests($|\/)/,
|
||||
/^\/workspace($|\/)/,
|
||||
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
import { rewiremock } from './rewiremock';
|
||||
import WebContents = Electron.WebContents;
|
||||
import path from 'path';
|
||||
import { rewiremock } from './rewiremock';
|
||||
|
||||
const electronMock: DeepPartial<typeof Electron> = {
|
||||
app: {
|
||||
on() {},
|
||||
on(): void {},
|
||||
getPath(name: string): string {
|
||||
return path.resolve('test-paths', name);
|
||||
},
|
||||
quit(): void {},
|
||||
},
|
||||
BrowserWindow: class {
|
||||
public webContents: DeepPartial<WebContents> = {
|
||||
openDevTools() {},
|
||||
openDevTools(): void {},
|
||||
};
|
||||
public loadFile() {}
|
||||
public on() {}
|
||||
public loadFile(): void {}
|
||||
public on(): void {}
|
||||
},
|
||||
ipcMain: {
|
||||
on() {},
|
||||
on(): void {},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"extends": ["../tslint.json"],
|
||||
"rules": {
|
||||
"typedef": false
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
library:
|
||||
type: sqlite
|
||||
database: ./database/library.db
|
||||
entities:
|
||||
- ./src/main/entities/library/*.js
|
||||
migrations:
|
||||
- ./src/main/migrations/library/*.js
|
||||
cli:
|
||||
migrationsDir: ./src/main/migrations/library
|
|
@ -11,7 +11,7 @@
|
|||
"main": "src/main.js",
|
||||
"scripts": {
|
||||
"postinstall": "npm run rebuild",
|
||||
"start": "electron . --enable-logging",
|
||||
"start": "electron . --enable-logging --dev",
|
||||
"rebuild": "electron-rebuild -f -b -t prod,dev,optional",
|
||||
"typeorm:migrate": "npm run typeorm:migrate:library",
|
||||
"typeorm:migrate:library": "typeorm migration:run -c library",
|
||||
|
@ -41,7 +41,6 @@
|
|||
"prettier": "prettier --ignore-path .gitignore -c **/*.{html,handlebars,json,{c,sc,sa,le}ss,yml,svelte,md,ts,js}",
|
||||
"prettier:fix": "prettier --ignore-path .gitignore --write **/*.{html,handlebars,json,{c,sc,sa,le}ss,yml,svelte,md,ts,js}",
|
||||
"fix": "npm run lint:check && npm run lint:fix && npm run prettier:fix",
|
||||
"forge:start": "electron-forge start",
|
||||
"forge:make": "electron-forge --platform win32 --arch x64 make",
|
||||
"forge": "npm run build && npm run forge:make",
|
||||
"precommit": "npm run build && npm run prettier && npm run lint:check && npm run lint && npm run coverage:fast",
|
||||
|
@ -50,6 +49,7 @@
|
|||
"dependencies": {
|
||||
"fs-extra": "^8.1.0",
|
||||
"jsdom": "^15.2.1",
|
||||
"minimist": "^1.2.0",
|
||||
"node-fetch": "^2.6.0",
|
||||
"sqlite3": "^4.1.1",
|
||||
"typeorm": "^0.2.21",
|
||||
|
@ -79,7 +79,6 @@
|
|||
"handlebars": "^4.5.3",
|
||||
"husky": "^3.1.0",
|
||||
"lodash": "^4.17.15",
|
||||
"minimist": "^1.2.0",
|
||||
"mocha": "^6.2.2",
|
||||
"nock": "^11.7.0",
|
||||
"nyc": "^14.1.1",
|
||||
|
|
16
src/main.ts
16
src/main.ts
|
@ -1,13 +1,19 @@
|
|||
import { app, BrowserWindow } from 'electron';
|
||||
import os from 'os';
|
||||
|
||||
import './main/controllers/api';
|
||||
import './main/services/database';
|
||||
import * as session from './main/services/session';
|
||||
import BrowserWindowConstructorOptions = Electron.BrowserWindowConstructorOptions;
|
||||
import minimist from 'minimist';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import packageJson from '../package.json';
|
||||
import './main/controllers/api';
|
||||
import * as session from './main/services/session';
|
||||
|
||||
export let mainWindow: Electron.BrowserWindow;
|
||||
|
||||
export let appPath = path.resolve(
|
||||
app.getPath('userData'),
|
||||
`${packageJson.version}${minimist(process.argv).dev ? '-dev' : ''}`
|
||||
);
|
||||
|
||||
async function createWindow(): Promise<void> {
|
||||
session.setHeaders();
|
||||
|
||||
|
|
|
@ -1,30 +1,50 @@
|
|||
import path from 'path';
|
||||
import 'reflect-metadata';
|
||||
import { Connection, createConnection } from 'typeorm';
|
||||
import { throwError } from './error';
|
||||
import { Connection, createConnection as ormCreateConnection } from 'typeorm';
|
||||
import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions';
|
||||
import { appPath } from '../../main';
|
||||
|
||||
export enum Databases {
|
||||
LIBRARY = 'library',
|
||||
}
|
||||
|
||||
type MyConnectionOptions = { [key in Databases]?: SqliteConnectionOptions };
|
||||
|
||||
const databasePath = path.resolve(appPath, 'database');
|
||||
const connectionOptions: MyConnectionOptions = Object.values(Databases).reduce(
|
||||
(prev: MyConnectionOptions, database: Databases) => {
|
||||
prev[database] = {
|
||||
type: 'sqlite',
|
||||
database: path.resolve(databasePath, `${database}.db`),
|
||||
entities: [`./src/main/entities/${database}/*.js`],
|
||||
migrations: [`./src/main/migrations/${database}/*.js`],
|
||||
cli: {
|
||||
migrationsDir: `./src/main/migrations/${database}`,
|
||||
},
|
||||
};
|
||||
return prev;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
const connections: {
|
||||
[key in Databases]?: Connection;
|
||||
} = {};
|
||||
|
||||
Object.values(Databases).forEach((database: Databases) => {
|
||||
createConnection(database)
|
||||
function createConnection(database: Databases): Promise<Connection> {
|
||||
return ormCreateConnection(connectionOptions[database])
|
||||
.then((connection: Connection) => {
|
||||
connections[database] = connection;
|
||||
return connection.runMigrations();
|
||||
})
|
||||
.catch((reason: any) => {
|
||||
throwError(reason, true);
|
||||
.then(() => {
|
||||
return connections[database];
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function getConnection(database: Databases): Promise<Connection> {
|
||||
if (connections[database] === undefined) {
|
||||
return createConnection(database).then((connection: Connection) => {
|
||||
connections[database] = connection;
|
||||
return connection;
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import rewiremock from 'rewiremock';
|
||||
import '../../../mocks/electron';
|
||||
|
||||
import { expect } from 'chai';
|
||||
import 'mocha';
|
||||
import { Databases, getConnection } from '../../../src/main/services/database';
|
||||
|
||||
describe('Database Service', () => {
|
||||
before(() => {
|
||||
rewiremock.enable();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
rewiremock.disable();
|
||||
});
|
||||
|
||||
it('returns a connection', async () => {
|
||||
const libraryConnection = await getConnection(Databases.LIBRARY);
|
||||
expect(libraryConnection).to.not.equal(undefined);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue