Compare commits

...

3 Commits

15 changed files with 156 additions and 27 deletions
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.15.15](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.14...@standardnotes/home-server@1.15.15) (2023-08-31)
**Note:** Version bump only for package @standardnotes/home-server
## [1.15.14](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.13...@standardnotes/home-server@1.15.14) (2023-08-31)
**Note:** Version bump only for package @standardnotes/home-server
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/home-server",
"version": "1.15.14",
"version": "1.15.15",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.30.5](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.30.4...@standardnotes/revisions-server@1.30.5) (2023-08-31)
### Bug Fixes
* **revisions:** indiciate if revision did not save ([a6039bd](https://github.com/standardnotes/server/commit/a6039bd99ac37cc5ee4487336fa42412722c7815))
## [1.30.4](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.30.3...@standardnotes/revisions-server@1.30.4) (2023-08-31)
### Bug Fixes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/revisions-server",
"version": "1.30.4",
"version": "1.30.5",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -1,4 +1,4 @@
import { ContentType, Dates, Uuid } from '@standardnotes/domain-core'
import { ContentType, Dates, UniqueEntityId, Uuid } from '@standardnotes/domain-core'
import { Revision } from './Revision'
@@ -19,4 +19,106 @@ describe('Revision', () => {
expect(entityOrError.isFailed()).toBeFalsy()
expect(entityOrError.getValue().id).not.toBeNull()
})
it('should tell if a revision is identical to another revision', () => {
const entity1 = Revision.create(
{
itemUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
userUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
content: 'test',
contentType: ContentType.create('Note').getValue(),
itemsKeyId: 'test',
encItemKey: 'test',
authHash: 'test',
creationDate: new Date(1),
dates: Dates.create(new Date(1), new Date(2)).getValue(),
},
new UniqueEntityId('00000000-0000-0000-0000-000000000000'),
).getValue()
const entity2 = Revision.create(
{
itemUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
userUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
content: 'test',
contentType: ContentType.create('Note').getValue(),
itemsKeyId: 'test',
encItemKey: 'test',
authHash: 'test',
creationDate: new Date(1),
dates: Dates.create(new Date(1), new Date(2)).getValue(),
},
new UniqueEntityId('00000000-0000-0000-0000-000000000000'),
).getValue()
expect(entity1.isIdenticalTo(entity2)).toBeTruthy()
})
it('should tell if a revision is not identical to another revision', () => {
const entity1 = Revision.create(
{
itemUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
userUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
content: 'test',
contentType: ContentType.create('Note').getValue(),
itemsKeyId: 'test',
encItemKey: 'test',
authHash: 'test',
creationDate: new Date(1),
dates: Dates.create(new Date(1), new Date(2)).getValue(),
},
new UniqueEntityId('00000000-0000-0000-0000-000000000000'),
).getValue()
const entity2 = Revision.create(
{
itemUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
userUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
content: 'test2',
contentType: ContentType.create('Note').getValue(),
itemsKeyId: 'test',
encItemKey: 'test',
authHash: 'test',
creationDate: new Date(1),
dates: Dates.create(new Date(1), new Date(2)).getValue(),
},
new UniqueEntityId('00000000-0000-0000-0000-000000000000'),
).getValue()
expect(entity1.isIdenticalTo(entity2)).toBeFalsy()
})
it('should tell if a revision is not identical to another revision id ids do not match', () => {
const entity1 = Revision.create(
{
itemUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
userUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
content: 'test',
contentType: ContentType.create('Note').getValue(),
itemsKeyId: 'test',
encItemKey: 'test',
authHash: 'test',
creationDate: new Date(1),
dates: Dates.create(new Date(1), new Date(2)).getValue(),
},
new UniqueEntityId('00000000-0000-0000-0000-000000000000'),
).getValue()
const entity2 = Revision.create(
{
itemUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
userUuid: Uuid.create('84c0f8e8-544a-4c7e-9adf-26209303bc1d').getValue(),
content: 'test',
contentType: ContentType.create('Note').getValue(),
itemsKeyId: 'test',
encItemKey: 'test',
authHash: 'test',
creationDate: new Date(1),
dates: Dates.create(new Date(1), new Date(2)).getValue(),
},
new UniqueEntityId('00000000-0000-0000-0000-000000000001'),
).getValue()
expect(entity1.isIdenticalTo(entity2)).toBeFalsy()
})
})
@@ -12,5 +12,5 @@ export interface RevisionRepositoryInterface {
findMetadataByItemId(itemUuid: Uuid, userUuid: Uuid): Promise<Array<RevisionMetadata>>
updateUserUuid(itemUuid: Uuid, userUuid: Uuid): Promise<void>
findByUserUuid(dto: { userUuid: Uuid; offset?: number; limit?: number }): Promise<Array<Revision>>
save(revision: Revision): Promise<Revision>
save(revision: Revision): Promise<boolean>
}
@@ -96,7 +96,7 @@ describe('TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser', () => {
primaryRevisionRepository.removeByUserUuid = jest.fn().mockResolvedValue(undefined)
secondaryRevisionRepository = {} as jest.Mocked<RevisionRepositoryInterface>
secondaryRevisionRepository.save = jest.fn().mockResolvedValue(undefined)
secondaryRevisionRepository.save = jest.fn().mockResolvedValue(true)
secondaryRevisionRepository.removeByUserUuid = jest.fn().mockResolvedValue(undefined)
secondaryRevisionRepository.countByUserUuid = jest.fn().mockResolvedValue(2)
secondaryRevisionRepository.findOneByUuid = jest
@@ -373,5 +373,23 @@ describe('TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser', () => {
expect(primaryRevisionRepository.removeByUserUuid).not.toHaveBeenCalled()
expect((secondaryRevisionRepository as RevisionRepositoryInterface).removeByUserUuid).toHaveBeenCalledTimes(1)
})
it('should fail if a revisions did not save in the secondary database', async () => {
;(secondaryRevisionRepository as RevisionRepositoryInterface).save = jest.fn().mockResolvedValue(false)
const useCase = createUseCase()
const result = await useCase.execute({
userUuid: '00000000-0000-0000-0000-000000000000',
})
expect(result.isFailed()).toBeTruthy()
expect(result.getError()).toEqual(
'Failed to save revision 00000000-0000-0000-0000-000000000000 to secondary database',
)
expect(primaryRevisionRepository.removeByUserUuid).not.toHaveBeenCalled()
expect((secondaryRevisionRepository as RevisionRepositoryInterface).removeByUserUuid).toHaveBeenCalledTimes(1)
})
})
})
@@ -74,15 +74,9 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
private async migrateRevisionsForUser(userUuid: Uuid): Promise<Result<void>> {
try {
const totalRevisionsCountForUser = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
this.logger.info(`Total revisions count for user ${userUuid.value} is ${totalRevisionsCountForUser}`)
const pageSize = 1
const totalPages = Math.ceil(totalRevisionsCountForUser / pageSize)
this.logger.info(`Total pages to migrate for user ${userUuid.value} is ${totalPages}`)
for (let currentPage = 1; currentPage <= totalPages; currentPage++) {
this.logger.info(`Migrating page ${currentPage} of ${totalPages} for user ${userUuid.value}`)
const query = {
userUuid: userUuid,
offset: (currentPage - 1) * pageSize,
@@ -91,10 +85,11 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
const revisions = await this.primaryRevisionsRepository.findByUserUuid(query)
this.logger.info(`Migrating ${revisions.length} revisions for user ${userUuid.value}`)
for (const revision of revisions) {
await (this.secondRevisionsRepository as RevisionRepositoryInterface).save(revision)
const didSave = await (this.secondRevisionsRepository as RevisionRepositoryInterface).save(revision)
if (!didSave) {
return Result.fail(`Failed to save revision ${revision.id.toString()} to secondary database`)
}
}
}
@@ -123,12 +123,12 @@ export class MongoDBRevisionRepository implements RevisionRepositoryInterface {
)
}
async save(revision: Revision): Promise<Revision> {
async save(revision: Revision): Promise<boolean> {
const persistence = this.revisionMapper.toProjection(revision)
const { _id, ...rest } = persistence
await this.mongoRepository.updateOne(
const updateResult = await this.mongoRepository.updateOne(
{ _id: { $eq: _id } },
{
$set: rest,
@@ -136,6 +136,6 @@ export class MongoDBRevisionRepository implements RevisionRepositoryInterface {
{ upsert: true },
)
return revision
return updateResult.acknowledged
}
}
@@ -106,12 +106,12 @@ export class SQLRevisionRepository implements RevisionRepositoryInterface {
return this.revisionMapper.toDomain(SQLRevision)
}
async save(revision: Revision): Promise<Revision> {
async save(revision: Revision): Promise<boolean> {
const SQLRevision = this.revisionMapper.toProjection(revision)
await this.ormRepository.save(SQLRevision)
return revision
return true
}
async findMetadataByItemId(itemUuid: Uuid, userUuid: Uuid): Promise<Array<RevisionMetadata>> {
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.88.3](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.88.2...@standardnotes/syncing-server@1.88.3) (2023-08-31)
### Bug Fixes
* **syncing-server:** persistence mapping for deleted field ([baf4b2c](https://github.com/standardnotes/syncing-server-js/commit/baf4b2c1d205929be8c330450dca16c18ad5cdd6))
## [1.88.2](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.88.1...@standardnotes/syncing-server@1.88.2) (2023-08-31)
### Bug Fixes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.88.2",
"version": "1.88.3",
"engines": {
"node": ">=18.0.0 <21.0.0"
},
@@ -189,9 +189,7 @@ export class MongoDBItemRepository implements ItemRepositoryInterface {
}
}
if (query.deleted !== undefined) {
const deletedMixedValues = query.deleted === true ? [true, 1] : [false, 0]
options.where = { ...options.where, deleted: { $in: deletedMixedValues } }
options.where = { ...options.where, deleted: { $eq: query.deleted } }
}
if (query.contentType) {
if (Array.isArray(query.contentType)) {
@@ -99,7 +99,7 @@ export class SQLItemPersistenceMapper implements MapperInterface<Item, SQLItem>
encItemKey: projection.encItemKey,
authHash: projection.authHash,
userUuid,
deleted: projection.deleted,
deleted: !!projection.deleted,
dates,
timestamps,
updatedWithSession,
@@ -127,7 +127,7 @@ export class SQLItemPersistenceMapper implements MapperInterface<Item, SQLItem>
typeorm.encItemKey = domain.props.encItemKey
typeorm.authHash = domain.props.authHash
typeorm.userUuid = domain.props.userUuid.value
typeorm.deleted = domain.props.deleted
typeorm.deleted = !!domain.props.deleted
typeorm.createdAt = domain.props.dates.createdAt
typeorm.updatedAt = domain.props.dates.updatedAt
typeorm.createdAtTimestamp = domain.props.timestamps.createdAt
@@ -64,7 +64,7 @@ export class SQLLegacyItemPersistenceMapper implements MapperInterface<Item, SQL
encItemKey: projection.encItemKey,
authHash: projection.authHash,
userUuid,
deleted: projection.deleted,
deleted: !!projection.deleted,
dates,
timestamps,
updatedWithSession,
@@ -90,7 +90,7 @@ export class SQLLegacyItemPersistenceMapper implements MapperInterface<Item, SQL
typeorm.encItemKey = domain.props.encItemKey
typeorm.authHash = domain.props.authHash
typeorm.userUuid = domain.props.userUuid.value
typeorm.deleted = domain.props.deleted
typeorm.deleted = !!domain.props.deleted
typeorm.createdAt = domain.props.dates.createdAt
typeorm.updatedAt = domain.props.dates.updatedAt
typeorm.createdAtTimestamp = domain.props.timestamps.createdAt