Skip to content

Commit

Permalink
Clean Arch file structure
Browse files Browse the repository at this point in the history
  • Loading branch information
p3rcypj committed Jun 2, 2024
1 parent ae4b039 commit 39235ae
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { D2Api } from "../types/d2-api";
import { Debug } from "../domain/entities/Migration";
import { MigrationsStorage } from "../domain/entities/MigrationsStorage";
import { MigrationsStorage } from "../domain/repositories/MigrationsStorage";

export class DataStoreStorage implements MigrationsStorage {
constructor(private api: D2Api, private namespace: string) {}
Expand Down
2 changes: 1 addition & 1 deletion src/d2-migrations/domain/entities/Migration.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MigrationsStorage } from "./MigrationsStorage";
import { MigrationsStorage } from "../repositories/MigrationsStorage";

export interface Config {
version: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Debug } from "./Migration";
import { Debug } from "../entities/Migration";

export interface MigrationsStorage {
get<T extends object>(key: string, defaultValue: T): Promise<T>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import _ from "lodash";
import { promiseMap, zeroPad } from "../../utils";
import { MigrationsStorage } from "./MigrationsStorage";
import { Config, Debug, MigrationWithVersion, RunnerOptions } from "./Migration";
import { MigrationsStorage } from "../repositories/MigrationsStorage";
import { Config, Debug, MigrationWithVersion, RunnerOptions } from "../entities/Migration";

const configKey = "migrations";

export class MigrationsRunner {
public migrations: MigrationWithVersion[];
public debug: Debug;
public lastMigrationVersion: number;
export class RunMigrations {
lastMigrationVersion: number;
private migrations: MigrationWithVersion[];
private debug: Debug;
private backupPrefix = "backup-";

constructor(private storage: MigrationsStorage, private config: Config, private options: RunnerOptions) {
Expand All @@ -19,39 +19,26 @@ export class MigrationsRunner {
this.storage = storage;
}

setDebug(debug: Debug) {
const newOptions = { ...this.options, debug };
return new MigrationsRunner(this.storage, this.config, newOptions);
}

static async init(options: RunnerOptions): Promise<MigrationsRunner> {
const { storage } = options;
const config = await storage.get<Config>(configKey, {
version: 0,
});
return new MigrationsRunner(storage, config, options);
}

public async execute(): Promise<void> {
// Re-load the runner to make sure we have the latest data as config.
const runner = await MigrationsRunner.init(this.options);
const runner = await RunMigrations.init(this.options);
return runner.migrateFromCurrent();
}

public async migrateFromCurrent(): Promise<void> {
const { config, migrations, debug } = this;

if (_.isEmpty(migrations)) {
debug(`No migrations pending to run (current version: ${config.version})`);
return;
}
public hasPendingMigrations(): boolean {
return this.config.version !== this.lastMigrationVersion;
}

debug(`Migrate: version ${this.currentStorageVersion} to version ${this.lastMigrationVersion}`);
public get currentStorageVersion(): number {
return this.config.version;
}

await this.runMigrations(migrations);
setDebug(debug: Debug) {
const newOptions = { ...this.options, debug };
return new RunMigrations(this.storage, this.config, newOptions);
}

async runMigrations(migrations: MigrationWithVersion[]): Promise<Config> {
public async runMigrations(migrations: MigrationWithVersion[]): Promise<Config> {
const { debug, config } = this;

const configWithCurrentMigration: Config = {
Expand All @@ -78,9 +65,30 @@ export class MigrationsRunner {
return newConfig;
}

static async init(options: RunnerOptions): Promise<RunMigrations> {
const { storage } = options;
const config = await storage.get<Config>(configKey, {
version: 0,
});
return new RunMigrations(storage, config, options);
}

private async migrateFromCurrent(): Promise<void> {
const { config, migrations, debug } = this;

if (_.isEmpty(migrations)) {
debug(`No migrations pending to run (current version: ${config.version})`);
return;
}

debug(`Migrate: version ${this.currentStorageVersion} to version ${this.lastMigrationVersion}`);

await this.runMigrations(migrations);
}

// dataStore backup methods are currently unused, call only if a migration needs it.

async deleteBackup() {
private async deleteBackup() {
try {
const { debug } = this;
const backupKeys = await this.getBackupKeys();
Expand All @@ -94,13 +102,13 @@ export class MigrationsRunner {
}
}

async rollBackExistingBackup() {
private async rollBackExistingBackup() {
if (this.config.migration) {
await this.rollbackDataStore(new Error("Rollback existing backup"));
}
}

async backupDataStore() {
private async backupDataStore() {
const { debug } = this;
debug(`Backup data store`);
const allKeys = await this.storage.getKeys();
Expand All @@ -117,12 +125,12 @@ export class MigrationsRunner {
});
}

async getBackupKeys() {
private async getBackupKeys() {
const allKeys = await this.storage.getKeys();
return allKeys.filter(key => key.startsWith(this.backupPrefix));
}

async rollbackDataStore(error: Error): Promise<Config> {
private async rollbackDataStore(error: Error): Promise<Config> {
const { debug, config } = this;
const errorMsg = error.message || error.toString();
const keysToRestore = await this.getBackupKeys();
Expand Down Expand Up @@ -152,18 +160,10 @@ export class MigrationsRunner {
return newConfig;
}

getMigrationToApply(allMigrations: MigrationWithVersion[], config: Config) {
private getMigrationToApply(allMigrations: MigrationWithVersion[], config: Config) {
return _(allMigrations)
.filter(info => info.version > config.version)
.sortBy(info => info.version)
.value();
}

hasPendingMigrations(): boolean {
return this.config.version !== this.lastMigrationVersion;
}

get currentStorageVersion(): number {
return this.config.version;
}
}
6 changes: 3 additions & 3 deletions src/d2-migrations/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export type { Migration } from "./domain/entities/Migration";
export type { MigrationTasks } from "./domain/entities/Migration";
export type { MigrationsStorage } from "./domain/entities/MigrationsStorage";
export type { MigrationsStorage } from "./domain/repositories/MigrationsStorage";
export type { Debug } from "./domain/entities/Migration";

export { DataStoreStorage } from "./storages/DataStoreStorage";
export { Migrations } from "./react/Migrations";
export { DataStoreStorage } from "./data/DataStoreStorage";
export { Migrations } from "./presentation/Migrations";
export { migration } from "./domain/entities/Migration";
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from "react";
import styled from "styled-components";
import i18n from "@eyeseetea/d2-ui-components/locales";
import { ConfirmationDialog } from "@eyeseetea/d2-ui-components";
import { MigrationsStorage } from "../domain/entities/MigrationsStorage";
import { MigrationsStorage } from "../domain/repositories/MigrationsStorage";
import { MigrationTasks } from "../domain/entities/Migration";
import { MigrationsRunner } from "../domain/entities/MigrationsRunner";
import { RunMigrations } from "../domain/usecases/RunMigrations";
import { useMigrations } from "./useMigrations";
import { CircularProgress } from "@material-ui/core";

Expand All @@ -25,7 +25,7 @@ export const Migrations: React.FC<MigrationsProps> = React.memo(props => {
});

export interface MigrationsRunnerProps {
runner: MigrationsRunner;
runner: RunMigrations;
onFinish: () => void;
}

Expand Down Expand Up @@ -88,7 +88,7 @@ const LoadingMigrations: React.FC = () => (
</ProgressContainer>
);

const MigrationsError: React.FC<{ runner: MigrationsRunner; onFinish: () => void }> = ({ runner, onFinish }) => (
const MigrationsError: React.FC<{ runner: RunMigrations; onFinish: () => void }> = ({ runner, onFinish }) => (
<ConfirmationDialog
isOpen={true}
title={i18n.t("Error")}
Expand All @@ -105,7 +105,7 @@ const MigrationsError: React.FC<{ runner: MigrationsRunner; onFinish: () => void
);

function runMigrations(
runner: MigrationsRunner,
runner: RunMigrations,
debug: (message: string) => void,
setState: React.Dispatch<React.SetStateAction<DialogState>>
): Promise<DialogState> {
Expand Down Expand Up @@ -146,7 +146,7 @@ function getActionText(state: DialogState): string | undefined {
}
}

function getInitialState(runner: MigrationsRunner): DialogState {
function getInitialState(runner: RunMigrations): DialogState {
if (runner.currentStorageVersion === runner.lastMigrationVersion) {
return { type: "success" };
} else if (runner.currentStorageVersion > runner.lastMigrationVersion) {
Expand All @@ -156,7 +156,7 @@ function getInitialState(runner: MigrationsRunner): DialogState {
}
}

function getPendingMigrationsText(runner: MigrationsRunner): string {
function getPendingMigrationsText(runner: RunMigrations): string {
return i18n.t(
"The app needs to run pending migrations (from version {{currentStorageVersion}} to version {{lastMigrationVersion}}) in order to continue. This may take a long time, make sure the process is not interrupted.",
runner
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import React from "react";
import { MigrationsRunner } from "../domain/entities/MigrationsRunner";
import { MigrationsStorage } from "../domain/entities/MigrationsStorage";
import { RunMigrations } from "../domain/usecases/RunMigrations";
import { MigrationsStorage } from "../domain/repositories/MigrationsStorage";
import { MigrationTasks } from "../domain/entities/Migration";

export type MigrationsState =
| { type: "checking" }
| { type: "pending"; runner: MigrationsRunner }
| { type: "checked" };
export type MigrationsState = { type: "checking" } | { type: "pending"; runner: RunMigrations } | { type: "checked" };

export interface UseMigrationsResult {
state: MigrationsState;
Expand All @@ -27,7 +24,7 @@ export function useMigrations(storage: MigrationsStorage, tasks: MigrationTasks)
}

async function runMigrations(storage: MigrationsStorage, tasks: MigrationTasks): Promise<MigrationsState> {
const runner = await MigrationsRunner.init({
const runner = await RunMigrations.init({
storage: storage,
debug: console.debug,
migrations: tasks,
Expand Down

0 comments on commit 39235ae

Please sign in to comment.