Skip to content
This repository was archived by the owner on Dec 26, 2022. It is now read-only.

Commit a9af012

Browse files
committed
Migrations WIP
1 parent 34e19b2 commit a9af012

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+381
-51
lines changed

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,5 @@
3636
"*.{css,sass,scss}.d.ts": true
3737
},
3838

39-
"cSpell.words": ["Popconfirm", "Sider", "Yadro"]
39+
"cSpell.words": ["autorun", "Popconfirm", "Sider", "Yadro"]
4040
}

src/base/AbstractFactory.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
// ConstructorParameters<typeof SomeClass>
2+
13
export default abstract class AbstractFactory {
24
create<T>(Model: any, data: any): T {
35
return new Model(data);
46
}
57

6-
createList<T>(Model: any, data: any): T[] {
8+
createList<M, T>(Model: M, data: any): T[] {
79
let items: T[] = [];
810

911
data.forEach((json: any) => {

src/base/MigrationRunner.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function migrationAssertShowValidationErrors(
2929
);
3030
}
3131

32-
export default class MigrationRunner {
32+
export default class MigrationRunner<TRes extends SchemaType> {
3333
private schemaMigrations: SchemaMigration[] = [];
3434
private ajv: Ajv;
3535

@@ -63,7 +63,7 @@ export default class MigrationRunner {
6363
this.ajv = new Ajv({ allErrors: true });
6464
}
6565

66-
runMigration<T extends SchemaType>(data: T) {
66+
runMigration<T extends SchemaType>(data: T): TRes {
6767
let newData: T = data;
6868
let fromVersion = newData.__version || 0;
6969
let toVersion = fromVersion !== undefined ? fromVersion + 1 : 1;
@@ -92,7 +92,7 @@ export default class MigrationRunner {
9292

9393
while (true) {
9494
if (toVersion > latestVersion) {
95-
return newData;
95+
return newData as TRes;
9696
}
9797

9898
const migration = this.schemaMigrations.find(

src/base/repositories/AbstractFileRepository.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ipcRenderer } from 'electron';
77
import FsHelper from '../../helpers/FsHelper';
88
import PromiseQueue from '../../helpers/PromiseQueueHelper';
99
import { SchemaMigration } from '../../types/SchemaMigration';
10+
import MigrationRunner from '../MigrationRunner';
1011

1112
const APP_DIR =
1213
process.env.NODE_ENV === 'development'
@@ -15,19 +16,24 @@ const APP_DIR =
1516

1617
let _appDataPath: string = '';
1718

18-
export default abstract class AbstractFileRepository<T = any> {
19+
export default abstract class AbstractFileRepository<T = unknown> {
1920
dirWithProfileData: string = 'profile1';
2021
fileName: string = 'defaultFileName.json';
2122
saveInRoot: boolean = false;
2223
schemaMigrations: SchemaMigration[] = [];
2324

2425
private writeFileQueue = new PromiseQueue();
26+
private migrationRunner: MigrationRunner<T>;
2527

2628
private get logPrefix() {
2729
const filePath = !this.saveInRoot ? this.dirWithProfileData : '';
2830
return `FileRepository [${filePath}/${this.fileName}]:`;
2931
}
3032

33+
constructor() {
34+
this.migrationRunner = new MigrationRunner(this.schemaMigrations);
35+
}
36+
3137
static get appDataFolder() {
3238
if (_appDataPath) {
3339
return _appDataPath;
@@ -58,6 +64,7 @@ export default abstract class AbstractFileRepository<T = any> {
5864
const data = fs.readFileSync(this.filePath, { encoding: 'utf-8' });
5965
// TODO handle parse error. Backup file with issues and return defaultValue
6066
const parsedData = JSON.parse(data);
67+
return this.migrationRunner.runMigration(parsedData);
6168
}
6269
return defaultValue;
6370
}

src/modules/projects/ProjectFactory.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import AbstractFactory from '../../base/AbstractFactory';
22
import ProjectModel, {
33
DEFAULT_PROJECT_ID,
44
DEFAULT_PROJECTS,
5-
IJsonProjectItem,
65
} from './models/ProjectModel';
76
import { Features } from '../../config';
7+
import { ProjectTypeV1 } from './types/ProjectTypeV1';
88

99
export default class ProjectFactory extends AbstractFactory {
10-
createProjects(projectItems: IJsonProjectItem[]): ProjectModel[] {
10+
createProjects(projectItems: ProjectTypeV1[]): ProjectModel[] {
1111
if (Features.myDay) {
1212
const hasMyDay = projectItems.find(
1313
(p) => p.key === DEFAULT_PROJECT_ID.MyDay
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import AbstractFileRepository from '../../base/repositories/AbstractFileRepository';
2-
import { IJsonProjectItem } from './models/ProjectModel';
2+
import { schemaMigrations } from './migrations';
3+
import { ProjectDataV1 } from './types';
34

45
export default class ProjectRepository extends AbstractFileRepository<
5-
IJsonProjectItem[]
6+
ProjectDataV1
67
> {
78
fileName = 'projects.json';
9+
schemaMigrations = schemaMigrations;
810
}

src/modules/projects/ProjectService.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
1-
import ProjectModel, {
2-
DEFAULT_PROJECTS,
3-
IJsonProjectItem,
4-
} from './models/ProjectModel';
1+
import { toJS } from 'mobx';
2+
import ProjectModel, { IJsonProjectItem } from './models/ProjectModel';
53
import ProjectFactory from './ProjectFactory';
64
import ProjectRepository from './ProjectRepository';
75
import AbstractServiceWithProfile from '../../base/AbstractServiceWithProfile';
86
import TreeModelHelper from '../../helpers/TreeModelHelper';
9-
import { toJS } from 'mobx';
7+
import DEFAULT_PROJECTS from './models/DefaultProjects';
8+
import { ProjectDataV0, ProjectDataV1 } from './types';
109

1110
export default class ProjectService extends AbstractServiceWithProfile<
12-
ProjectModel[]
11+
ProjectDataV0
1312
> {
1413
private factory = new ProjectFactory();
1514
protected repository = new ProjectRepository();
1615

1716
getAll(): ProjectModel[] {
1817
const data = this.repository.restore(DEFAULT_PROJECTS);
1918
ProjectService.fillParent(data);
20-
return this.factory.createProjects(data);
19+
return this.factory.createProjects(data.data);
2120
}
2221

2322
save(data: ProjectModel[]): void {
@@ -26,8 +25,8 @@ export default class ProjectService extends AbstractServiceWithProfile<
2625
this.repository.save(copyData);
2726
}
2827

29-
private static fillParent(data: IJsonProjectItem[]) {
30-
TreeModelHelper.fillParent(data);
28+
private static fillParent(data: ProjectDataV1) {
29+
TreeModelHelper.fillParent(data.data);
3130
}
3231

3332
private static clearParent(data: ProjectModel[]) {

src/modules/projects/ProjectStore.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ export default class ProjectStore {
3030

3131
set(projects: ProjectModel[]) {
3232
this.projects = projects;
33-
this.projectService.save(this.projects);
33+
this.projectService.save({
34+
__version: 1,
35+
data: this.projects,
36+
});
3437
}
3538

3639
setEditableProject(project?: ProjectModel) {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export enum DEFAULT_PROJECT_ID {
2+
MyDay = '0',
3+
Inbox = '1',
4+
}

src/modules/projects/ProjectValidator.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)