Newer
Older
import { Client, Q, QueryResult } from 'cozy-client'
import { SCHEMAS_DOCTYPE } from 'doctypes'
import { InitStepsErrors, ReleaseNotes, Schema } from 'models'
import logApp from 'utils/logger'
import { migrate, migrationLog } from './migration'

Hugo NOUTS
committed
import {
MIGRATION_RESULT_COMPLETE,
MIGRATION_RESULT_FAILED,
} from './migration.data'
import { Migration } from './migration.type'
export class MigrationService {
private readonly _client: Client
private readonly _setInitStepError: React.Dispatch<
React.SetStateAction<InitStepsErrors | null>
>
constructor(
_client: Client,
React.SetStateAction<InitStepsErrors | null>
>
) {
/**
* Return schema version
* @param _client cozyClient
* @returns Promise<number> Version number of schema
*/
public async currentSchemaVersion(_client: Client): Promise<number> {
const data: QueryResult<Schema[]> = await _client.query(query.limitBy(1))
return data?.data[0]?.version || 0
}
public async runMigrations(migrations: Migration[]): Promise<ReleaseNotes> {

Hugo NOUTS
committed
let releaseStatus = false
const releaseNotes: ReleaseNotes = {
show: releaseStatus,
notes: [
{
title: '',
description: '',
},
],
redirectLink: '',

Hugo NOUTS
committed
}
const currentVersion = await this.currentSchemaVersion(this._client)
const targetVersion = migrations[migrations.length - 1].targetSchemaVersion
// Prevent Migration service to run every migration if not needed
if (currentVersion != targetVersion) {
const startMigrationIndex =
migrations.length - (targetVersion - currentVersion)
const migrationsToRun = migrations.splice(startMigrationIndex)
for (const migration of migrationsToRun) {
// First attempt
const migrationResult = await migrate(migration, this._client)
if (migrationResult.type === MIGRATION_RESULT_FAILED) {
// Retry in case of failure
const result = await migrate(migration, this._client)
if (result.type === MIGRATION_RESULT_FAILED) {
// Error in case of second failure
this._setInitStepError(InitStepsErrors.MIGRATION_ERROR)
logApp.error(migrationLog(migration, result))
Sentry.captureException(migrationLog(migration, result))

Hugo NOUTS
committed
if (
migration.releaseNotes !== null &&
migrationResult.type === MIGRATION_RESULT_COMPLETE
) {
releaseNotes.notes.push(migration.releaseNotes)
releaseStatus = true
if (migration.redirectLink) {
releaseNotes.redirectLink = migration.redirectLink
}

Hugo NOUTS
committed
}
releaseNotes.show = releaseStatus
// In case of first instance, don't show release notes
if (startMigrationIndex === 0) releaseNotes.show = false
logApp.info('[Migration] Skipped Migration Process, already up-to-date')
logDuration('[Migration] Finished in', startTime)
return releaseNotes