Skip to content

Commit

Permalink
feat: Created migrations and refactored the database layer
Browse files Browse the repository at this point in the history
  • Loading branch information
zoemaas committed Feb 19, 2024
1 parent f8571cb commit 8672b82
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import {BaseEntity, Column, Entity, PrimaryColumn} from "typeorm";

@Entity('state')
export class State extends BaseEntity {
@PrimaryColumn()
// @ts-ignore
@Entity('XstateEntity')
export class XStateEntity extends BaseEntity {
@PrimaryColumn({ name: 'id', type: 'varchar' })
id: string
@Column()
// @ts-ignore
state: string
@Column()
// @ts-ignore
type: string
@Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
// @ts-ignore
createdAt: Date
@Column({ type: 'timestamp', onUpdate: 'CURRENT_TIMESTAMP', nullable: true })
// @ts-ignore
updatedAt: Date
@Column({ type: 'timestamp', nullable: true })
// @ts-ignore
completedAt: Date
@Column()
// @ts-ignore
tenantId?: string
@Column({ default: 0 })
// @ts-ignore
ttl: number
}
9 changes: 9 additions & 0 deletions packages/data-store/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { IssuerBrandingEntity, issuerBrandingEntityFrom } from './entities/issua
import { TextAttributesEntity, textAttributesEntityFrom } from './entities/issuanceBranding/TextAttributesEntity'
import { StatusListEntity } from './entities/statusList2021/StatusList2021Entity'
import { StatusListEntryEntity } from './entities/statusList2021/StatusList2021EntryEntity'
import {XStateEntity} from "./entities/xstatePersistence/XStateEntity";
import { IStatusListEntity, IStatusListEntryEntity } from './types'
import { PartyRelationshipEntity } from './entities/contact/PartyRelationshipEntity'
import { PartyTypeEntity } from './entities/contact/PartyTypeEntity'
Expand All @@ -32,12 +33,16 @@ export { StatusListStore } from './statusList/StatusListStore'
import { AuditEventEntity, auditEventEntityFrom } from './entities/eventLogger/AuditEventEntity'
export { AbstractEventLoggerStore } from './eventLogger/AbstractEventLoggerStore'
export { EventLoggerStore } from './eventLogger/EventLoggerStore'
export { IAbstractStateStore } from './xstatePersistence/IAbstractStateStore'
export { XStateStore } from './xstatePersistence/XStateStore'

export {
DataStoreMigrations,
DataStoreEventLoggerMigrations,
DataStoreContactMigrations,
DataStoreIssuanceBrandingMigrations,
DataStoreStatusListMigrations,
DataStoreXStatePersistenceMigration,
} from './migrations'
export * from './types'
export * from './utils/contact/MappingUtils'
Expand Down Expand Up @@ -75,12 +80,15 @@ export const DataStoreStatusListEntities = [StatusListEntity, StatusListEntryEnt

export const DataStoreEventLoggerEntities = [AuditEventEntity]

export const DataStoreXStateStoreEntities = [XStateEntity]

// All entities combined if a party wants to enable them all at once
export const DataStoreEntities = [
...DataStoreContactEntities,
...DataStoreIssuanceBrandingEntities,
...DataStoreStatusListEntities,
...DataStoreEventLoggerEntities,
...DataStoreXStateStoreEntities
]

export {
Expand Down Expand Up @@ -116,4 +124,5 @@ export {
StatusListEntryEntity,
AuditEventEntity,
auditEventEntityFrom,
XStateEntity
}
66 changes: 66 additions & 0 deletions packages/data-store/src/migrations/generic/6-CreateXStateStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { DatabaseType, MigrationInterface, QueryRunner } from 'typeorm'
import Debug from 'debug'
import { CreateXStateStore1708097018115 } from '../postgres/1708097018115-CreateXStateStore'
import { CreateXStateStore1708096002272 } from '../sqlite/1708096002272-CreateXStateStore'

const debug: Debug.Debugger = Debug('sphereon:ssi-sdk:migrations')

export class CreateXStateStore1708098041262 implements MigrationInterface {
name = 'CreateXStateStore1708098041262'

public async up(queryRunner: QueryRunner): Promise<void> {
debug('migration: creating contacts tables')
const dbType: DatabaseType = queryRunner.connection.driver.options.type

switch (dbType) {
case 'postgres': {
debug('using postgres migration file')
const mig: CreateXStateStore1708097018115 = new CreateXStateStore1708097018115()
await mig.up(queryRunner)
debug('Migration statements executed')
return
}
case 'sqlite':
case 'expo':
case 'react-native': {
debug('using sqlite/react-native migration file')
const mig: CreateXStateStore1708096002272 = new CreateXStateStore1708096002272()
await mig.up(queryRunner)
debug('Migration statements executed')
return
}
default:
return Promise.reject(
`Migrations are currently only supported for sqlite, react-native, expo and postgres. Was ${dbType}. Please run your database without migrations and with 'migrationsRun: false' and 'synchronize: true' for now`
)
}
}

public async down(queryRunner: QueryRunner): Promise<void> {
debug('migration: reverting contacts tables')
const dbType: DatabaseType = queryRunner.connection.driver.options.type

switch (dbType) {
case 'postgres': {
debug('using postgres migration file')
const mig: CreateXStateStore1708097018115 = new CreateXStateStore1708097018115()
await mig.down(queryRunner)
debug('Migration statements executed')
return
}
case 'sqlite':
case 'expo':
case 'react-native': {
debug('using sqlite/react-native migration file')
const mig: CreateXStateStore1708096002272 = new CreateXStateStore1708096002272()
await mig.down(queryRunner)
debug('Migration statements executed')
return
}
default:
return Promise.reject(
`Migrations are currently only supported for sqlite, react-native, expo and postgres. Was ${dbType}. Please run your database without migrations and with 'migrationsRun: false' and 'synchronize: true' for now`
)
}
}
}
3 changes: 3 additions & 0 deletions packages/data-store/src/migrations/generic/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CreateIssuanceBranding1659463079429 } from './2-CreateIssuanceBranding'
import { CreateContacts1690925872318 } from './3-CreateContacts'
import { CreateStatusList1693866470000 } from './4-CreateStatusList'
import { CreateAuditEvents1701635835330 } from './5-CreateAuditEvents'
import {CreateXStateStore1708098041262} from "./6-CreateXStateStore";

/**
* The migrations array that SHOULD be used when initializing a TypeORM database connection.
Expand All @@ -17,11 +18,13 @@ export const DataStoreContactMigrations = [CreateContacts1659463079429, CreateCo
export const DataStoreIssuanceBrandingMigrations = [CreateIssuanceBranding1659463079429]
export const DataStoreStatusListMigrations = [CreateStatusList1693866470000]
export const DataStoreEventLoggerMigrations = [CreateAuditEvents1701635835330]
export const DataStoreXStatePersistenceMigration = [CreateXStateStore1708098041262]

// All migrations together
export const DataStoreMigrations = [
...DataStoreContactMigrations,
...DataStoreIssuanceBrandingMigrations,
...DataStoreStatusListMigrations,
...DataStoreEventLoggerMigrations,
...DataStoreXStatePersistenceMigration
]
1 change: 1 addition & 0 deletions packages/data-store/src/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export {
DataStoreContactMigrations,
DataStoreIssuanceBrandingMigrations,
DataStoreStatusListMigrations,
DataStoreXStatePersistenceMigration
} from './generic'
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {enablePostgresUuidExtension} from "@sphereon/ssi-sdk.core";
import {MigrationInterface, QueryRunner} from "typeorm";

export class CreateXStateStore1708097018115 implements MigrationInterface {
name = 'CreateXStateStore1708097018115'

public async up(queryRunner: QueryRunner): Promise<any> {
await enablePostgresUuidExtension(queryRunner)
await queryRunner.query(
`CREATE TABLE "XStateStore" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "state" varchar(255) NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP, CONSTRAINT PK_XStateStore_id PRIMARY KEY ("id")`
)
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "XStateStore" DROP CONSTRAINT "PK_XStateStore_id"`)
await queryRunner.query(`DROP TABLE "XStateStore"`)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {MigrationInterface, QueryRunner} from "typeorm";

export class CreateXStateStore1708096002272 implements MigrationInterface {
name = 'CreateXStateStore1708096002272'

public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(
`CREATE TABLE "XStateStore" ("id" varchar PRIMARY KEY NOT NULL, "state" varchar(255) NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP, CONSTRAINT "PK_XStateStore_id"`
)
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "XStateStore" DROP CONSTRAINT "PK_XStateStore_id"`)
await queryRunner.query(`DROP TABLE "XStateStore"`)
}
}
1 change: 1 addition & 0 deletions packages/data-store/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from './statusList/statusList'
export * from './statusList/IAbstractStatusListStore'
export * from './eventLogger/IAbstractEventLoggerStore'
export * from './eventLogger/eventLogger'
export * from './xstatePersistence/types'
19 changes: 19 additions & 0 deletions packages/data-store/src/types/xstatePersistence/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {XStateEntity} from "../../entities/xstatePersistence/XStateEntity";

export type PersistStateArgs = {
state: string
type: string
createdAt: Date
updatedAt: Date
completedAt: Date
tenantId?: string
ttl: number
}

export type LoadStateArgs = Pick<PersistStateArgs, 'type'>

export type DeleteStateArgs = Pick<PersistStateArgs, 'type'>

export type VoidResult = void

export type LoadStateResult = XStateEntity | null
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {LoadStateArgs, LoadStateResult, PersistStateArgs, VoidResult} from "../types";

export abstract class IAbstractStateStore {
abstract persistState(state: PersistStateArgs): Promise<VoidResult>
abstract loadState(args: LoadStateArgs): Promise<LoadStateResult>
abstract deleteState(args: LoadStateArgs): Promise<VoidResult>
}
40 changes: 40 additions & 0 deletions packages/data-store/src/xstatePersistence/XStateStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {OrPromise} from "@sphereon/ssi-types";
import Debug from 'debug'
import {DataSource} from "typeorm";

import {XStateEntity} from "../entities/xstatePersistence/XStateEntity";
import {DeleteStateArgs, LoadStateArgs, LoadStateResult, PersistStateArgs, VoidResult,} from "../types";
import {IAbstractStateStore} from "./IAbstractStateStore";

const debug = Debug('sphereon:ssi-sdk:xstatePersistence')

export class XStateStore extends IAbstractStateStore {
private readonly dbConnection: OrPromise<DataSource>

constructor(dbConnection: OrPromise<DataSource>) {
super()
this.dbConnection = dbConnection
}

async persistState(state: PersistStateArgs): Promise<VoidResult> {
const connection: DataSource = await this.dbConnection
debug.log(`Executing persistState with state: ${JSON.stringify(state)}`)
await connection.getRepository(XStateEntity).save(state)
}

async loadState(args: LoadStateArgs): Promise<LoadStateResult> {
const connection: DataSource = await this.dbConnection
debug.log(`Executing loadState query with type: ${args.type}`)
return await connection.getRepository(XStateEntity)
.findOne({
where: { type: args.type }
})
}

async deleteState(args: DeleteStateArgs): Promise<VoidResult> {
const connection: DataSource = await this.dbConnection
debug.log(`Executing loadState query with type: ${args.type}`)
await connection.getRepository(XStateEntity)
.delete({ type: args.type })
}
}

0 comments on commit 8672b82

Please sign in to comment.