feat(syncing-server): turn mysql items model into legacy (#711)

* feat(syncing-server): turn mysql items model into legacy

* fix: rename MySQL model to SQL model to include SQLite option

* fix: rename mysqlitem to sqlitem
This commit is contained in:
Karol Sójko
2023-08-28 12:28:48 +02:00
committed by GitHub
parent f4816e6c9a
commit effdfebc19
10 changed files with 293 additions and 38 deletions
@@ -6,7 +6,7 @@ import TYPES from './Types'
import { AppDataSource } from './DataSource'
import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns'
import { ItemRepositoryInterface } from '../Domain/Item/ItemRepositoryInterface'
import { TypeORMItemRepository } from '../Infra/TypeORM/TypeORMItemRepository'
import { SQLLegacyItemRepository } from '../Infra/TypeORM/SQLLegacyItemRepository'
import { MongoRepository, Repository } from 'typeorm'
import { Item } from '../Domain/Item/Item'
import {
@@ -61,8 +61,8 @@ import { S3ItemBackupService } from '../Infra/S3/S3ItemBackupService'
import { ControllerContainer, ControllerContainerInterface, MapperInterface } from '@standardnotes/domain-core'
import { BaseItemsController } from '../Infra/InversifyExpressUtils/Base/BaseItemsController'
import { Transform } from 'stream'
import { TypeORMItem } from '../Infra/TypeORM/TypeORMItem'
import { ItemPersistenceMapper } from '../Mapping/Persistence/ItemPersistenceMapper'
import { SQLLegacyItem } from '../Infra/TypeORM/SQLLegacyItem'
import { SQLLegacyItemPersistenceMapper } from '../Mapping/Persistence/SQLLegacyItemPersistenceMapper'
import { ItemHttpRepresentation } from '../Mapping/Http/ItemHttpRepresentation'
import { ItemHttpMapper } from '../Mapping/Http/ItemHttpMapper'
import { SavedItemHttpRepresentation } from '../Mapping/Http/SavedItemHttpRepresentation'
@@ -303,8 +303,8 @@ export class ContainerConfigLoader {
// Mapping
container
.bind<MapperInterface<Item, TypeORMItem>>(TYPES.Sync_ItemPersistenceMapper)
.toConstantValue(new ItemPersistenceMapper())
.bind<MapperInterface<Item, SQLLegacyItem>>(TYPES.Sync_SQLLegacyItemPersistenceMapper)
.toConstantValue(new SQLLegacyItemPersistenceMapper())
container
.bind<MapperInterface<ItemHash, ItemHashHttpRepresentation>>(TYPES.Sync_ItemHashHttpMapper)
.toConstantValue(new ItemHashHttpMapper())
@@ -360,8 +360,8 @@ export class ContainerConfigLoader {
// ORM
container
.bind<Repository<TypeORMItem>>(TYPES.Sync_ORMItemRepository)
.toDynamicValue(() => appDataSource.getRepository(TypeORMItem))
.bind<Repository<SQLLegacyItem>>(TYPES.Sync_ORMLegacyItemRepository)
.toDynamicValue(() => appDataSource.getRepository(SQLLegacyItem))
container
.bind<Repository<TypeORMSharedVault>>(TYPES.Sync_ORMSharedVaultRepository)
.toConstantValue(appDataSource.getRepository(TypeORMSharedVault))
@@ -401,11 +401,11 @@ export class ContainerConfigLoader {
// Repositories
container
.bind<ItemRepositoryInterface>(TYPES.Sync_MySQLItemRepository)
.bind<ItemRepositoryInterface>(TYPES.Sync_SQLLegacyItemRepository)
.toConstantValue(
new TypeORMItemRepository(
container.get<Repository<TypeORMItem>>(TYPES.Sync_ORMItemRepository),
container.get<MapperInterface<Item, TypeORMItem>>(TYPES.Sync_ItemPersistenceMapper),
new SQLLegacyItemRepository(
container.get<Repository<SQLLegacyItem>>(TYPES.Sync_ORMLegacyItemRepository),
container.get<MapperInterface<Item, SQLLegacyItem>>(TYPES.Sync_SQLLegacyItemPersistenceMapper),
container.get<Logger>(TYPES.Sync_Logger),
),
)
@@ -413,7 +413,7 @@ export class ContainerConfigLoader {
.bind<ItemRepositoryResolverInterface>(TYPES.Sync_ItemRepositoryResolver)
.toConstantValue(
new TypeORMItemRepositoryResolver(
container.get<ItemRepositoryInterface>(TYPES.Sync_MySQLItemRepository),
container.get<ItemRepositoryInterface>(TYPES.Sync_SQLLegacyItemRepository),
isSecondaryDatabaseEnabled ? container.get<ItemRepositoryInterface>(TYPES.Sync_MongoDBItemRepository) : null,
),
)
@@ -777,7 +777,7 @@ export class ContainerConfigLoader {
)
.toConstantValue(
new TransitionItemsFromPrimaryToSecondaryDatabaseForUser(
container.get<ItemRepositoryInterface>(TYPES.Sync_MySQLItemRepository),
container.get<ItemRepositoryInterface>(TYPES.Sync_SQLLegacyItemRepository),
isSecondaryDatabaseEnabled ? container.get<ItemRepositoryInterface>(TYPES.Sync_MongoDBItemRepository) : null,
container.get<TimerInterface>(TYPES.Sync_Timer),
container.get<Logger>(TYPES.Sync_Logger),
@@ -843,7 +843,7 @@ export class ContainerConfigLoader {
.bind<DuplicateItemSyncedEventHandler>(TYPES.Sync_DuplicateItemSyncedEventHandler)
.toConstantValue(
new DuplicateItemSyncedEventHandler(
container.get<ItemRepositoryInterface>(TYPES.Sync_MySQLItemRepository),
container.get<ItemRepositoryInterface>(TYPES.Sync_SQLLegacyItemRepository),
isSecondaryDatabaseEnabled ? container.get<ItemRepositoryInterface>(TYPES.Sync_MongoDBItemRepository) : null,
container.get<DomainEventFactoryInterface>(TYPES.Sync_DomainEventFactory),
container.get<DomainEventPublisherInterface>(TYPES.Sync_DomainEventPublisher),
@@ -854,7 +854,7 @@ export class ContainerConfigLoader {
.bind<AccountDeletionRequestedEventHandler>(TYPES.Sync_AccountDeletionRequestedEventHandler)
.toConstantValue(
new AccountDeletionRequestedEventHandler(
container.get<ItemRepositoryInterface>(TYPES.Sync_MySQLItemRepository),
container.get<ItemRepositoryInterface>(TYPES.Sync_SQLLegacyItemRepository),
isSecondaryDatabaseEnabled ? container.get<ItemRepositoryInterface>(TYPES.Sync_MongoDBItemRepository) : null,
container.get<Logger>(TYPES.Sync_Logger),
),
@@ -863,7 +863,7 @@ export class ContainerConfigLoader {
.bind<ItemRevisionCreationRequestedEventHandler>(TYPES.Sync_ItemRevisionCreationRequestedEventHandler)
.toConstantValue(
new ItemRevisionCreationRequestedEventHandler(
container.get<ItemRepositoryInterface>(TYPES.Sync_MySQLItemRepository),
container.get<ItemRepositoryInterface>(TYPES.Sync_SQLLegacyItemRepository),
isSecondaryDatabaseEnabled ? container.get<ItemRepositoryInterface>(TYPES.Sync_MongoDBItemRepository) : null,
container.get<ItemBackupServiceInterface>(TYPES.Sync_ItemBackupService),
container.get<DomainEventFactoryInterface>(TYPES.Sync_DomainEventFactory),
@@ -918,7 +918,7 @@ export class ContainerConfigLoader {
.toConstantValue(
new ExtensionsHttpService(
container.get<AxiosInstance>(TYPES.Sync_HTTPClient),
container.get<ItemRepositoryInterface>(TYPES.Sync_MySQLItemRepository),
container.get<ItemRepositoryInterface>(TYPES.Sync_SQLLegacyItemRepository),
isSecondaryDatabaseEnabled ? container.get<ItemRepositoryInterface>(TYPES.Sync_MongoDBItemRepository) : null,
container.get<ContentDecoderInterface>(TYPES.Sync_ContentDecoder),
container.get<DomainEventPublisherInterface>(TYPES.Sync_DomainEventPublisher),
@@ -964,7 +964,7 @@ export class ContainerConfigLoader {
.bind<EmailBackupRequestedEventHandler>(TYPES.Sync_EmailBackupRequestedEventHandler)
.toConstantValue(
new EmailBackupRequestedEventHandler(
container.get<ItemRepositoryInterface>(TYPES.Sync_MySQLItemRepository),
container.get<ItemRepositoryInterface>(TYPES.Sync_SQLLegacyItemRepository),
isSecondaryDatabaseEnabled
? container.get<ItemRepositoryInterface>(TYPES.Sync_MongoDBItemRepository)
: null,
@@ -2,7 +2,7 @@ import { DataSource, EntityTarget, LoggerOptions, MongoRepository, ObjectLiteral
import { MysqlConnectionOptions } from 'typeorm/driver/mysql/MysqlConnectionOptions'
import { Env } from './Env'
import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions'
import { TypeORMItem } from '../Infra/TypeORM/TypeORMItem'
import { SQLLegacyItem } from '../Infra/TypeORM/SQLLegacyItem'
import { TypeORMNotification } from '../Infra/TypeORM/TypeORMNotification'
import { TypeORMSharedVault } from '../Infra/TypeORM/TypeORMSharedVault'
import { TypeORMSharedVaultUser } from '../Infra/TypeORM/TypeORMSharedVaultUser'
@@ -75,7 +75,7 @@ export class AppDataSource {
const commonDataSourceOptions = {
maxQueryExecutionTime,
entities: [
TypeORMItem,
SQLLegacyItem,
TypeORMNotification,
TypeORMSharedVault,
TypeORMSharedVaultUser,
@@ -8,7 +8,7 @@ const TYPES = {
Sync_Env: Symbol.for('Sync_Env'),
// Repositories
Sync_ItemRepositoryResolver: Symbol.for('Sync_ItemRepositoryResolver'),
Sync_MySQLItemRepository: Symbol.for('Sync_MySQLItemRepository'),
Sync_SQLLegacyItemRepository: Symbol.for('Sync_SQLLegacyItemRepository'),
Sync_MongoDBItemRepository: Symbol.for('Sync_MongoDBItemRepository'),
Sync_SharedVaultRepository: Symbol.for('Sync_SharedVaultRepository'),
Sync_SharedVaultInviteRepository: Symbol.for('Sync_SharedVaultInviteRepository'),
@@ -16,7 +16,7 @@ const TYPES = {
Sync_NotificationRepository: Symbol.for('Sync_NotificationRepository'),
Sync_MessageRepository: Symbol.for('Sync_MessageRepository'),
// ORM
Sync_ORMItemRepository: Symbol.for('Sync_ORMItemRepository'),
Sync_ORMLegacyItemRepository: Symbol.for('Sync_ORMLegacyItemRepository'),
Sync_ORMSharedVaultRepository: Symbol.for('Sync_ORMSharedVaultRepository'),
Sync_ORMSharedVaultInviteRepository: Symbol.for('Sync_ORMSharedVaultInviteRepository'),
Sync_ORMSharedVaultUserRepository: Symbol.for('Sync_ORMSharedVaultUserRepository'),
@@ -131,7 +131,7 @@ const TYPES = {
Sync_MessagePersistenceMapper: Symbol.for('Sync_MessagePersistenceMapper'),
Sync_MessageHttpMapper: Symbol.for('Sync_MessageHttpMapper'),
Sync_NotificationHttpMapper: Symbol.for('Sync_NotificationHttpMapper'),
Sync_ItemPersistenceMapper: Symbol.for('Sync_ItemPersistenceMapper'),
Sync_SQLLegacyItemPersistenceMapper: Symbol.for('Sync_SQLLegacyItemPersistenceMapper'),
Sync_MongoDBItemPersistenceMapper: Symbol.for('Sync_MongoDBItemPersistenceMapper'),
Sync_ItemHttpMapper: Symbol.for('Sync_ItemHttpMapper'),
Sync_ItemHashHttpMapper: Symbol.for('Sync_ItemHashHttpMapper'),
@@ -0,0 +1,29 @@
import { Column, Entity } from 'typeorm'
import { SQLLegacyItem } from './SQLLegacyItem'
@Entity({ name: 'items' })
export class SQLItem extends SQLLegacyItem {
@Column({
type: 'varchar',
name: 'last_edited_by',
length: 36,
nullable: true,
})
declare lastEditedBy: string | null
@Column({
type: 'varchar',
name: 'shared_vault_uuid',
length: 36,
nullable: true,
})
declare sharedVaultUuid: string | null
@Column({
type: 'varchar',
name: 'key_system_identifier',
length: 36,
nullable: true,
})
declare keySystemIdentifier: string | null
}
@@ -0,0 +1,78 @@
import { Repository, SelectQueryBuilder } from 'typeorm'
import { MapperInterface } from '@standardnotes/domain-core'
import { Logger } from 'winston'
import { Item } from '../../Domain/Item/Item'
import { SQLLegacyItem } from './SQLLegacyItem'
import { SQLLegacyItemRepository } from './SQLLegacyItemRepository'
import { ItemQuery } from '../../Domain/Item/ItemQuery'
export class SQLItemRepository extends SQLLegacyItemRepository {
constructor(
protected override ormRepository: Repository<SQLLegacyItem>,
protected override mapper: MapperInterface<Item, SQLLegacyItem>,
protected override logger: Logger,
) {
super(ormRepository, mapper, logger)
}
protected override createFindAllQueryBuilder(query: ItemQuery): SelectQueryBuilder<SQLLegacyItem> {
const queryBuilder = this.ormRepository.createQueryBuilder('item')
if (query.sortBy !== undefined && query.sortOrder !== undefined) {
queryBuilder.orderBy(`item.${query.sortBy}`, query.sortOrder)
}
if (query.includeSharedVaultUuids !== undefined && query.includeSharedVaultUuids.length > 0) {
if (query.userUuid) {
queryBuilder.where('(item.user_uuid = :userUuid OR item.shared_vault_uuid IN (:...includeSharedVaultUuids))', {
userUuid: query.userUuid,
includeSharedVaultUuids: query.includeSharedVaultUuids,
})
} else {
queryBuilder.where('item.shared_vault_uuid IN (:...includeSharedVaultUuids)', {
includeSharedVaultUuids: query.includeSharedVaultUuids,
})
}
} else if (query.exclusiveSharedVaultUuids !== undefined && query.exclusiveSharedVaultUuids.length > 0) {
queryBuilder.where('item.shared_vault_uuid IN (:...exclusiveSharedVaultUuids)', {
exclusiveSharedVaultUuids: query.exclusiveSharedVaultUuids,
})
} else if (query.userUuid !== undefined) {
queryBuilder.where('item.user_uuid = :userUuid', { userUuid: query.userUuid })
}
if (query.uuids && query.uuids.length > 0) {
queryBuilder.andWhere('item.uuid IN (:...uuids)', { uuids: query.uuids })
}
if (query.deleted !== undefined) {
queryBuilder.andWhere('item.deleted = :deleted', { deleted: query.deleted })
}
if (query.contentType) {
if (Array.isArray(query.contentType)) {
queryBuilder.andWhere('item.content_type IN (:...contentTypes)', { contentTypes: query.contentType })
} else {
queryBuilder.andWhere('item.content_type = :contentType', { contentType: query.contentType })
}
}
if (query.lastSyncTime && query.syncTimeComparison) {
queryBuilder.andWhere(`item.updated_at_timestamp ${query.syncTimeComparison} :lastSyncTime`, {
lastSyncTime: query.lastSyncTime,
})
}
if (query.createdBetween !== undefined) {
queryBuilder.andWhere('item.created_at >= :createdAfter AND item.created_at <= :createdBefore', {
createdAfter: query.createdBetween[0].toISOString(),
createdBefore: query.createdBetween[1].toISOString(),
})
}
if (query.offset !== undefined) {
queryBuilder.skip(query.offset)
}
if (query.limit !== undefined) {
queryBuilder.take(query.limit)
}
return queryBuilder
}
}
@@ -8,7 +8,7 @@ import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'
'createdAtTimestamp',
])
@Index('user_uuid_and_deleted', ['userUuid', 'deleted'])
export class TypeORMItem {
export class SQLLegacyItem {
@PrimaryGeneratedColumn('uuid')
declare uuid: string
@@ -6,14 +6,14 @@ import { Item } from '../../Domain/Item/Item'
import { ItemQuery } from '../../Domain/Item/ItemQuery'
import { ItemRepositoryInterface } from '../../Domain/Item/ItemRepositoryInterface'
import { ExtendedIntegrityPayload } from '../../Domain/Item/ExtendedIntegrityPayload'
import { TypeORMItem } from './TypeORMItem'
import { SQLLegacyItem } from './SQLLegacyItem'
import { ItemContentSizeDescriptor } from '../../Domain/Item/ItemContentSizeDescriptor'
export class TypeORMItemRepository implements ItemRepositoryInterface {
export class SQLLegacyItemRepository implements ItemRepositoryInterface {
constructor(
private ormRepository: Repository<TypeORMItem>,
private mapper: MapperInterface<Item, TypeORMItem>,
private logger: Logger,
protected ormRepository: Repository<SQLLegacyItem>,
protected mapper: MapperInterface<Item, SQLLegacyItem>,
protected logger: Logger,
) {}
async save(item: Item): Promise<void> {
@@ -179,7 +179,7 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
.execute()
}
private createFindAllQueryBuilder(query: ItemQuery): SelectQueryBuilder<TypeORMItem> {
protected createFindAllQueryBuilder(query: ItemQuery): SelectQueryBuilder<SQLLegacyItem> {
const queryBuilder = this.ormRepository.createQueryBuilder('item')
if (query.sortBy !== undefined && query.sortOrder !== undefined) {
@@ -5,13 +5,13 @@ import { ItemRepositoryResolverInterface } from '../../Domain/Item/ItemRepositor
export class TypeORMItemRepositoryResolver implements ItemRepositoryResolverInterface {
constructor(
private mysqlItemRepository: ItemRepositoryInterface,
private SQLItemRepository: ItemRepositoryInterface,
private mongoDbItemRepository: ItemRepositoryInterface | null,
) {}
resolve(roleNames: RoleNameCollection): ItemRepositoryInterface {
if (!this.mongoDbItemRepository) {
return this.mysqlItemRepository
return this.SQLItemRepository
}
const transitionRoleName = RoleName.create(RoleName.NAMES.TransitionUser).getValue()
@@ -20,6 +20,6 @@ export class TypeORMItemRepositoryResolver implements ItemRepositoryResolverInte
return this.mongoDbItemRepository
}
return this.mysqlItemRepository
return this.SQLItemRepository
}
}
@@ -0,0 +1,148 @@
import { Timestamps, MapperInterface, UniqueEntityId, Uuid, ContentType, Dates } from '@standardnotes/domain-core'
import { Item } from '../../Domain/Item/Item'
import { SQLItem } from '../../Infra/TypeORM/SQLItem'
import { KeySystemAssociation } from '../../Domain/KeySystem/KeySystemAssociation'
import { SharedVaultAssociation } from '../../Domain/SharedVault/SharedVaultAssociation'
export class SQLItemPersistenceMapper implements MapperInterface<Item, SQLItem> {
toDomain(projection: SQLItem): Item {
const uuidOrError = Uuid.create(projection.uuid)
if (uuidOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${uuidOrError.getError()}`)
}
const uuid = uuidOrError.getValue()
let duplicateOf = null
if (projection.duplicateOf) {
const duplicateOfOrError = Uuid.create(projection.duplicateOf)
if (duplicateOfOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${duplicateOfOrError.getError()}`)
}
duplicateOf = duplicateOfOrError.getValue()
}
const contentTypeOrError = ContentType.create(projection.contentType)
if (contentTypeOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${contentTypeOrError.getError()}`)
}
const contentType = contentTypeOrError.getValue()
const userUuidOrError = Uuid.create(projection.userUuid)
if (userUuidOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${userUuidOrError.getError()}`)
}
const userUuid = userUuidOrError.getValue()
const datesOrError = Dates.create(projection.createdAt, projection.updatedAt)
if (datesOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${datesOrError.getError()}`)
}
const dates = datesOrError.getValue()
const timestampsOrError = Timestamps.create(projection.createdAtTimestamp, projection.updatedAtTimestamp)
if (timestampsOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${timestampsOrError.getError()}`)
}
const timestamps = timestampsOrError.getValue()
let updatedWithSession = null
if (projection.updatedWithSession) {
const updatedWithSessionOrError = Uuid.create(projection.updatedWithSession)
if (updatedWithSessionOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${updatedWithSessionOrError.getError()}`)
}
updatedWithSession = updatedWithSessionOrError.getValue()
}
let sharedVaultAssociation: SharedVaultAssociation | undefined = undefined
if (projection.sharedVaultUuid && projection.lastEditedBy) {
const sharedVaultUuidOrError = Uuid.create(projection.sharedVaultUuid)
if (sharedVaultUuidOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${sharedVaultUuidOrError.getError()}`)
}
const sharedVaultUuid = sharedVaultUuidOrError.getValue()
const lastEditedByOrError = Uuid.create(projection.lastEditedBy)
if (lastEditedByOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${lastEditedByOrError.getError()}`)
}
const lastEditedBy = lastEditedByOrError.getValue()
const sharedVaultAssociationOrError = SharedVaultAssociation.create({
sharedVaultUuid,
lastEditedBy,
})
if (sharedVaultAssociationOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${sharedVaultAssociationOrError.getError()}`)
}
sharedVaultAssociation = sharedVaultAssociationOrError.getValue()
}
let keySystemAssociation: KeySystemAssociation | undefined = undefined
if (projection.keySystemIdentifier) {
const keySystemAssociationOrError = KeySystemAssociation.create(projection.keySystemIdentifier)
if (keySystemAssociationOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${keySystemAssociationOrError.getError()}`)
}
keySystemAssociation = keySystemAssociationOrError.getValue()
}
const itemOrError = Item.create(
{
duplicateOf,
itemsKeyId: projection.itemsKeyId,
content: projection.content,
contentType,
contentSize: projection.contentSize ?? undefined,
encItemKey: projection.encItemKey,
authHash: projection.authHash,
userUuid,
deleted: projection.deleted,
dates,
timestamps,
updatedWithSession,
sharedVaultAssociation,
keySystemAssociation,
},
new UniqueEntityId(uuid.value),
)
if (itemOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${itemOrError.getError()}`)
}
return itemOrError.getValue()
}
toProjection(domain: Item): SQLItem {
const typeorm = new SQLItem()
typeorm.uuid = domain.id.toString()
typeorm.duplicateOf = domain.props.duplicateOf ? domain.props.duplicateOf.value : null
typeorm.itemsKeyId = domain.props.itemsKeyId
typeorm.content = domain.props.content
typeorm.contentType = domain.props.contentType.value
typeorm.contentSize = domain.props.contentSize ?? null
typeorm.encItemKey = domain.props.encItemKey
typeorm.authHash = domain.props.authHash
typeorm.userUuid = domain.props.userUuid.value
typeorm.deleted = domain.props.deleted
typeorm.createdAt = domain.props.dates.createdAt
typeorm.updatedAt = domain.props.dates.updatedAt
typeorm.createdAtTimestamp = domain.props.timestamps.createdAt
typeorm.updatedAtTimestamp = domain.props.timestamps.updatedAt
typeorm.updatedWithSession = domain.props.updatedWithSession ? domain.props.updatedWithSession.value : null
typeorm.lastEditedBy = domain.props.sharedVaultAssociation
? domain.props.sharedVaultAssociation.props.lastEditedBy.value
: null
typeorm.sharedVaultUuid = domain.props.sharedVaultAssociation
? domain.props.sharedVaultAssociation.props.sharedVaultUuid.value
: null
typeorm.keySystemIdentifier = domain.props.keySystemAssociation
? domain.props.keySystemAssociation.props.keySystemIdentifier
: null
return typeorm
}
}
@@ -2,10 +2,10 @@ import { Timestamps, MapperInterface, UniqueEntityId, Uuid, ContentType, Dates }
import { Item } from '../../Domain/Item/Item'
import { TypeORMItem } from '../../Infra/TypeORM/TypeORMItem'
import { SQLLegacyItem } from '../../Infra/TypeORM/SQLLegacyItem'
export class ItemPersistenceMapper implements MapperInterface<Item, TypeORMItem> {
toDomain(projection: TypeORMItem): Item {
export class SQLLegacyItemPersistenceMapper implements MapperInterface<Item, SQLLegacyItem> {
toDomain(projection: SQLLegacyItem): Item {
const uuidOrError = Uuid.create(projection.uuid)
if (uuidOrError.isFailed()) {
throw new Error(`Failed to create item from projection: ${uuidOrError.getError()}`)
@@ -78,8 +78,8 @@ export class ItemPersistenceMapper implements MapperInterface<Item, TypeORMItem>
return itemOrError.getValue()
}
toProjection(domain: Item): TypeORMItem {
const typeorm = new TypeORMItem()
toProjection(domain: Item): SQLLegacyItem {
const typeorm = new SQLLegacyItem()
typeorm.uuid = domain.id.toString()
typeorm.duplicateOf = domain.props.duplicateOf ? domain.props.duplicateOf.value : null