mirror of
https://github.com/standardnotes/server
synced 2026-07-14 00:01:54 -04:00
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:
@@ -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
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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
-6
@@ -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
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -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
|
||||
Reference in New Issue
Block a user