Skip to content

Commit

Permalink
ADD .info call (#5045)
Browse files Browse the repository at this point in the history
* ADD .info call

* FIX types
  • Loading branch information
pubkey authored Sep 28, 2023
1 parent f93c2c1 commit c8011b2
Show file tree
Hide file tree
Showing 15 changed files with 171 additions and 11 deletions.
7 changes: 5 additions & 2 deletions orga/before-next-major.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,12 @@ Most "normal" users do not need premium access so we should name it "RxDB Enterp



## RxStorage: Add RxStorage.info() which also calls parents
## RxStorage: Add RxStorage.info() [DONE]

Having an .info() method helps in debugging stuff and sending reports on problems etc.
Also used to count total documents etc for the state of the migration/replication.
Can be augmented in the future.

HAving an .info() method helps in debugging stuff and sending reports on problems etc.

## Skip responding full document data on bulkWrites (only in all happy case)

Expand Down
1 change: 1 addition & 0 deletions src/plugin-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ export function wrapRxStorageInstance<RxDocType>(
schema: instance.schema,
collectionName: instance.collectionName,
count: instance.count.bind(instance),
info: instance.info.bind(instance),
remove: instance.remove.bind(instance),
originalStorageInstance: instance,
bulkWrite: async (
Expand Down
24 changes: 23 additions & 1 deletion src/plugins/storage-dexie/rx-storage-instance-dexie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import type {
RxStorageDefaultCheckpoint,
CategorizeBulkWriteRowsOutput,
RxStorageCountResult,
DefaultPreparedQuery
DefaultPreparedQuery,
RxStorageInfoResult
} from '../../types';
import {
DexieSettings,
Expand Down Expand Up @@ -248,6 +249,27 @@ export class RxStorageInstanceDexie<RxDocType> implements RxStorageInstance<
}
}

async info(): Promise<RxStorageInfoResult> {
const state = await this.internals;
const ret: RxStorageInfoResult = {
totalCount: -1
};
await state.dexieDb.transaction(
'r',
state.dexieTable,
state.dexieDeletedTable,
async (_dexieTx) => {
const [nonDeleted, deleted] = await Promise.all([
state.dexieTable.count(),
state.dexieDeletedTable.count()
]);
ret.totalCount = nonDeleted + deleted;
}
);

return ret;
}

async getChangedDocumentsSince(
limit: number,
checkpoint?: RxStorageDefaultCheckpoint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
RxStorageChangeEvent,
RxStorageCountResult,
RxStorageDefaultCheckpoint,
RxStorageInfoResult,
RxStorageInstance,
RxStorageInstanceCreationParams,
RxStorageQueryResult,
Expand Down Expand Up @@ -118,8 +119,6 @@ export class RxStorageInstanceFoundationDB<RxDocType> implements RxStorageInstan
docsInDB.set(id, doc);
})
);


categorized = categorizeBulkWriteRows<RxDocType>(
this,
this.primaryPath as any,
Expand Down Expand Up @@ -243,6 +242,22 @@ export class RxStorageInstanceFoundationDB<RxDocType> implements RxStorageInstan
mode: 'fast'
};
}
async info(): Promise<RxStorageInfoResult> {
const dbs = await this.internals.dbsPromise;
const ret: RxStorageInfoResult = {
totalCount: -1
};
await dbs.root.doTransaction(async (tx: any) => {
const mainTx = tx.at(dbs.main.subspace);
const range = await mainTx.getRangeAll(
'',
INDEX_MAX
);
ret.totalCount = range.length;
});
return ret;
}

async getAttachmentData(documentId: string, attachmentId: string, _digest: string): Promise<string> {
const dbs = await this.internals.dbsPromise;
const attachment = await dbs.attachments.get(attachmentMapKey(documentId, attachmentId));
Expand Down
15 changes: 14 additions & 1 deletion src/plugins/storage-lokijs/rx-storage-instance-loki.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ import type {
RxConflictResultionTask,
RxConflictResultionTaskSolution,
RxStorageDefaultCheckpoint,
RxStorageCountResult
RxStorageCountResult,
RxStorageInfoResult
} from '../../types';
import {
closeLokiCollections,
Expand Down Expand Up @@ -100,6 +101,7 @@ export class RxStorageInstanceLoki<RxDocType> implements RxStorageInstance<
close: this.close.bind(this),
query: this.query.bind(this),
count: this.count.bind(this),
info: this.info.bind(this),
findDocumentsById: this.findDocumentsById.bind(this),
collectionName: this.collectionName,
databaseName: this.databaseName,
Expand Down Expand Up @@ -263,6 +265,17 @@ export class RxStorageInstanceLoki<RxDocType> implements RxStorageInstance<
}


async info(): Promise<RxStorageInfoResult> {
const localState = await mustUseLocalState(this);
if (!localState) {
return requestRemoteInstance(this, 'info', []);
}
return {
totalCount: localState.collection.count()
};
}


async getChangedDocumentsSince(
limit: number,
checkpoint?: RxStorageDefaultCheckpoint | null
Expand Down
8 changes: 8 additions & 0 deletions src/plugins/storage-memory/rx-storage-instance-memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type {
RxStorageChangeEvent,
RxStorageCountResult,
RxStorageDefaultCheckpoint,
RxStorageInfoResult,
RxStorageInstance,
RxStorageInstanceCreationParams,
RxStorageQueryResult,
Expand Down Expand Up @@ -362,6 +363,13 @@ export class RxStorageInstanceMemory<RxDocType> implements RxStorageInstance<
};
}

info(): Promise<RxStorageInfoResult> {
this.ensurePersistence();
return Promise.resolve({
totalCount: this.internals.documents.size
});
}

getChangedDocumentsSince(
limit: number,
checkpoint?: RxStorageDefaultCheckpoint
Expand Down
12 changes: 12 additions & 0 deletions src/plugins/storage-mongodb/rx-storage-instance-mongodb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type {
RxStorageChangeEvent,
RxStorageCountResult,
RxStorageDefaultCheckpoint,
RxStorageInfoResult,
RxStorageInstance,
RxStorageInstanceCreationParams,
RxStorageQueryResult,
Expand Down Expand Up @@ -385,6 +386,17 @@ export class RxStorageInstanceMongoDB<RxDocType> implements RxStorageInstance<
};
}

async info(): Promise<RxStorageInfoResult> {
this.runningOperations.next(this.runningOperations.getValue() + 1);
await this.writeQueue;
const mongoCollection = await this.mongoCollectionPromise;
const totalCount = await mongoCollection.countDocuments();
this.runningOperations.next(this.runningOperations.getValue() - 1);
return {
totalCount
};
}

async getChangedDocumentsSince(
limit: number,
checkpoint?: RxStorageDefaultCheckpoint
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/storage-remote/rx-storage-remote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
RxStorageBulkWriteResponse,
RxStorageChangeEvent,
RxStorageCountResult,
RxStorageInfoResult,
RxStorageInstance,
RxStorageInstanceCreationParams,
RxStorageQueryResult,
Expand Down Expand Up @@ -240,6 +241,9 @@ export class RxStorageInstanceRemote<RxDocType> implements RxStorageInstance<RxD
count(preparedQuery: any): Promise<RxStorageCountResult> {
return this.requestRemote('count', [preparedQuery]);
}
info(): Promise<RxStorageInfoResult> {
return this.requestRemote('info', []);
}
getAttachmentData(documentId: string, attachmentId: string, digest: string): Promise<string> {
return this.requestRemote('getAttachmentData', [documentId, attachmentId, digest]);
}
Expand Down
5 changes: 5 additions & 0 deletions src/rx-storage-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,11 @@ export function getWrappedStorageInstance<
() => storageInstance.count(preparedQuery)
);
},
info() {
return database.lockedRun(
() => storageInstance.info()
);
},
findDocumentsById(ids, deleted) {
return database.lockedRun(
() => storageInstance.findDocumentsById(ids, deleted)
Expand Down
4 changes: 2 additions & 2 deletions src/types/plugins/lokijs.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { LeaderElector } from 'broadcast-channel';
import type {
Collection
Collection as LokiCollection
} from 'lokijs';
import { AddReturn } from 'unload';
import { LokiSaveQueue } from '../../plugins/storage-lokijs/loki-save-queue';
Expand Down Expand Up @@ -47,7 +47,7 @@ export type LokiDatabaseState = {

// all known collections of the database
collections: {
[collectionName: string]: Collection;
[collectionName: string]: LokiCollection;
};

/**
Expand Down
11 changes: 11 additions & 0 deletions src/types/rx-storage.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,16 @@ export type RxStorageCountResult = {
mode: 'fast' | 'slow';
};

export type RxStorageInfoResult = {
/**
* Contains the total amount of stored documents.
* This contains the _deleted and non-_deleted documents.
* This is used by RxDB to give the option to show
* loading percentage in replication and migration.
*/
totalCount: number;
};

export type RxStorageInstanceCreationParams<RxDocType, InstanceCreationOptions> = {

/**
Expand Down Expand Up @@ -305,6 +315,7 @@ export type RxStorageDefaultCheckpoint = {




export type CategorizeBulkWriteRowsOutput<RxDocType> = {

// TODO only needs the document, not the row.
Expand Down
11 changes: 11 additions & 0 deletions src/types/rx-storage.interface.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
RxStorageBulkWriteResponse,
RxStorageChangeEvent,
RxStorageCountResult,
RxStorageInfoResult,
RxStorageInstanceCreationParams,
RxStorageQueryResult
} from './rx-storage';
Expand Down Expand Up @@ -248,6 +249,16 @@ export interface RxStorageInstance<
preparedQuery: PreparedQuery<RxDocType>
): Promise<RxStorageCountResult>;



/**
* Returns some info about the storage.
* Used in various places. This method is expected to
* not really care about performance, so do not
* use it in hot paths.
*/
info(): Promise<RxStorageInfoResult>;

/**
* Returns the plain data of a single attachment.
*/
Expand Down
4 changes: 2 additions & 2 deletions test/unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ import './unit/rx-storage-lokijs.test';
import './unit/rx-storage-dexie.test';
import './unit/rx-storage-remote.test';

import './unit/replication.test';
import './unit/replication-protocol.test'; // TODO move down

import './unit/instance-of-check.test';
import './unit/rx-schema.test';
Expand Down Expand Up @@ -55,6 +53,8 @@ import './unit/reactive-document.test';
import './unit/cleanup.test';
import './unit/hooks.test';
import './unit/orm.test';
import './unit/replication.test';
import './unit/replication-protocol.test';
import './unit/replication-graphql.test';
import './unit/replication-couchdb.test';
import './unit/replication-websocket.test';
Expand Down
4 changes: 3 additions & 1 deletion test/unit/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import parallel from 'mocha.parallel';
import { getRxStorageLoki } from '../../plugins/storage-lokijs';
import {
randomCouchString,
RxStorage, RxStorageDefaultStatics, RxTestStorage
RxStorage,
RxStorageDefaultStatics,
RxTestStorage
} from '../../plugins/core';
import {
getRxStorageDexie
Expand Down
53 changes: 53 additions & 0 deletions test/unit/rx-storage-implementations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1802,6 +1802,59 @@ config.parallel('rx-storage-implementations.test.ts (implementation: ' + config.
storageInstance.close();
});
});
describe('.info()', () => {
it('should have the correct total count', async () => {
const schema = getTestDataSchema();
const storageInstance = await config.storage
.getStorage()
.createStorageInstance<TestDocType>({
databaseInstanceToken: randomCouchString(10),
databaseName: randomCouchString(12),
collectionName: randomCouchString(12),
schema,
options: {},
multiInstance: false,
devMode: true
});
async function ensureCountIs(nr: number) {
const result = await storageInstance.info();
assert.strictEqual(result.totalCount, nr);
}

await ensureCountIs(0);
await storageInstance.bulkWrite([{ document: getWriteData() }], testContext);
await ensureCountIs(1);

const writeData = getWriteData();
const insertResult = await storageInstance.bulkWrite([{ document: writeData }], testContext);
await ensureCountIs(2);

// DELETE
const previous = insertResult.success[0];
await storageInstance.bulkWrite(
[{
previous,
document: Object.assign({}, writeData, {
_rev: EXAMPLE_REVISION_2,
_deleted: true,
_meta: {
lwt: now()
}
})
}],
testContext
);

/**
* Must still count 2 because totalCount includes _deleted documents
* as long as they did not have been purged by the .cleanup()
*/
await ensureCountIs(2);

storageInstance.close();
});

});
describe('.findDocumentsById()', () => {
it('should find the documents', async () => {
const storageInstance = await config.storage.getStorage().createStorageInstance<TestDocType>({
Expand Down

0 comments on commit c8011b2

Please sign in to comment.