import type { HashFunction, InternalStoreDocType, RxDatabase, RxDocumentData, RxJsonSchema, RxStorage, RxStorageInstance, RxStorageInstanceCreationParams } from 'nxdb-old/src/types'; import { createRevision, flatClone, getDefaultRevision, getDefaultRxDocumentMeta, now } from 'nxdb-old/src/plugins/utils'; import { fillObjectWithDefaults, fillPrimaryKey } from 'nxdb-old/src/rx-schema-helper'; import type { RxSchema } from 'nxdb-old/src/rx-schema'; import { runAsyncPluginHooks } from 'nxdb-old/src/hooks'; import { getAllCollectionDocuments } from 'nxdb-old/src/rx-database-internal-store'; import { flatCloneDocWithMeta } from 'nxdb-old/src/rx-storage-helper'; import { overwritable } from 'nxdb-old/src/overwritable'; /** * fills in the default data. * This also clones the data. */ export function fillObjectDataBeforeInsert( schema: RxSchema, data: Partial> | any ): RxDocumentData { data = flatClone(data); data = fillObjectWithDefaults(schema, data); data = fillPrimaryKey( schema.primaryPath, schema.jsonSchema, data ); data._meta = getDefaultRxDocumentMeta(); if (!data.hasOwnProperty('_deleted')) { data._deleted = false; } if (!data.hasOwnProperty('_attachments')) { data._attachments = {}; } if (!data.hasOwnProperty('_rev')) { data._rev = getDefaultRevision(); } return data; } /** * Creates the storage instances that are used internally in the collection */ export async function createRxCollectionStorageInstance( rxDatabase: RxDatabase<{}, Internals, InstanceCreationOptions>, storageInstanceCreationParams: RxStorageInstanceCreationParams ): Promise> { storageInstanceCreationParams.multiInstance = rxDatabase.multiInstance; const storageInstance = await rxDatabase.storage.createStorageInstance( storageInstanceCreationParams ); return storageInstance; } /** * Removes the main storage of the collection * and all connected storages like the ones from the replication meta etc. */ export async function removeCollectionStorages( storage: RxStorage, databaseInternalStorage: RxStorageInstance, any, any>, databaseInstanceToken: string, databaseName: string, collectionName: string, /** * If no hash function is provided, * we assume that the whole internal store is removed anyway * so we do not have to delete the meta documents. */ hashFunction?: HashFunction, ) { const allCollectionMetaDocs = await getAllCollectionDocuments( storage.statics, databaseInternalStorage ); const relevantCollectionMetaDocs = allCollectionMetaDocs .filter(metaDoc => metaDoc.data.name === collectionName); let removeStorages: { collectionName: string; schema: RxJsonSchema; isCollection: boolean; }[] = []; relevantCollectionMetaDocs.forEach(metaDoc => { removeStorages.push({ collectionName: metaDoc.data.name, schema: metaDoc.data.schema, isCollection: true }); metaDoc.data.connectedStorages.forEach(row => removeStorages.push({ collectionName: row.collectionName, isCollection: false, schema: row.schema })); }); // ensure uniqueness const alreadyAdded = new Set(); removeStorages = removeStorages.filter(row => { const key = row.collectionName + '||' + row.schema.version; if (alreadyAdded.has(key)) { return false; } else { alreadyAdded.add(key); return true; } }); // remove all the storages await Promise.all( removeStorages .map(async (row) => { const storageInstance = await storage.createStorageInstance({ collectionName: row.collectionName, databaseInstanceToken, databaseName, multiInstance: false, options: {}, schema: row.schema, devMode: overwritable.isDevMode() }); await storageInstance.remove(); if (row.isCollection) { await runAsyncPluginHooks('postRemoveRxCollection', { storage, databaseName: databaseName, collectionName }); } }) ); // remove the meta documents if (hashFunction) { const writeRows = relevantCollectionMetaDocs.map(doc => { const writeDoc = flatCloneDocWithMeta(doc); writeDoc._deleted = true; writeDoc._meta.lwt = now(); writeDoc._rev = createRevision( databaseInstanceToken, doc ); return { previous: doc, document: writeDoc }; }); await databaseInternalStorage.bulkWrite( writeRows, 'rx-database-remove-collection-all' ); } }