src/app/core/database/database.ts
Based upon PouchDb changes feed format.
Properties |
[key: string]:
|
|
Defined in src/app/core/database/database.ts:200
|
| _deleted |
_deleted:
|
Type : boolean
|
| Optional |
|
Defined in src/app/core/database/database.ts:200
|
| _id |
_id:
|
Type : string
|
|
Defined in src/app/core/database/database.ts:198
|
| _rev |
_rev:
|
Type : string
|
|
Defined in src/app/core/database/database.ts:199
|
import { Observable } from "rxjs";
/**
* An implementation of this abstract class provides functions for direct database access.
* This interface is an extension of the [PouchDB API](https://pouchdb.com/api.html).
*
* PLEASE NOTE:
* Direct access to the Database layer is rarely necessary, and you should probably use EntityMapperService instead.
* Database is not an Angular Service and has to be accessed through the DatabaseResolverService.
*/
export abstract class Database {
constructor(protected dbName: string) {}
/**
* Initialize the database fully after its initial creation,
* e.g. once user details are available.
* @param dbName A special database name, if different from the default name passed in the constructor
*/
abstract init(dbName?: string);
/**
* Whether the database is already initialized and ready for use.
*/
abstract isInitialized(): boolean;
/**
* Load a single document by id from the database.
* @param id The primary key of the document to be loaded
* @param options Optional options for the database engine (PouchDB)
*/
abstract get(id: string, options?: GetOptions): Promise<any>;
/**
* Load all documents (matching the given PouchDB options) from the database.
*
* Normally you should rather use "getAll()" or another well typed method of this class
* instead of passing PouchDB specific options here
* because that will make your code tightly coupled with PouchDB rather than any other database provider.
*
* @param options PouchDB options object as in the normal PouchDB library
*/
abstract allDocs(options?: GetAllOptions): Promise<any>;
/**
* Save a document to the database.
* @param object The document to be saved
* @param forceUpdate (Optional) Whether conflicts should be ignored and an existing conflicting document forcefully overwritten.
*/
abstract put(object: any, forceUpdate?: boolean): Promise<any>;
/**
* Save a bunch of documents at once to the database
* @param objects The documents to be saved
* @param forceUpdate (Optional) Whether conflicts should be ignored and existing conflicting documents forcefully overwritten.
* @returns array holding success responses or errors depending on the success of the operation
*/
abstract putAll(objects: any[], forceUpdate?: boolean): Promise<any[]>;
/**
* Delete a document from the database
* @param object The document to be deleted (usually this object must at least contain the _id and _rev)
*/
abstract remove(object: any): Promise<any>;
/**
* Permanently remove a document from the local database without syncing the deletion to the server.
*
* Unlike {@link remove}, purge leaves no tombstone and does not affect the remote database.
* Throws if not supported by the current implementation.
*
* @param id The document ID to purge
*/
purge(_id: string): Promise<boolean> {
throw new Error("purge() is not supported by this database implementation");
}
/**
* Uses the PouchDB-find plugin {@link https://github.com/apache/pouchdb/tree/master/packages/node_modules/pouchdb-find}
* This supports querying using the Mango Query Language {@link https://pouchdb.com/guides/mango-queries.html#query-language}
* There might be differences in queries between a local PouchDB and the CouchDB.
*
* Pagination uses an opaque `bookmark` cursor rather than `skip`: passing the
* `bookmark` returned by a previous call continues right after those
* results. Unlike `skip`, this also works correctly when the remote CouchDB
* applies permission filtering to the query (see
* {@link https://github.com/Aam-Digital/replication-backend/pull/330}).
* A bookmark is forward-only - it cannot be used to jump backwards - so
* callers that need to revisit earlier pages must cache them themselves.
*
* @param prefix of the entity to be queried
* @param query the Mango Query Language query
* @param page additional pagination options
* @param sort additional sorting options
*/
abstract find(
prefix: string,
query: any,
page?: { limit?: number; bookmark?: string },
sort?: { prop?: string; dir?: "asc" | "desc" },
): Promise<{ docs: any[]; bookmark?: string }>;
/**
* Query data from the database based on a more complex, indexed request.
*
* This is directly calling the PouchDB implementation of this function.
* Also see the documentation there: {@link https://pouchdb.com/api.html#query_database}
*
* @param fun The name of a previously saved database index
* @param options Additional options for the query, like a `key`. See the PouchDB docs for details.
*/
abstract query(fun: any, options?: QueryOptions): Promise<any>;
/**
* Create a database index to `query()` certain data more efficiently in the future.
*
* Also see the PouchDB documentation regarding indices and queries: {@link https://pouchdb.com/api.html#query_database}
*
* @param designDoc The PouchDB style design document for the map/reduce query
*/
abstract saveDatabaseIndex(designDoc: any): Promise<any>;
/**
* Load all documents (with the given prefix) from the database.
* @param prefix The string prefix of document ids that should be retrieved
*/
getAll(prefix = ""): Promise<Array<any>> {
return this.allDocs({
include_docs: true,
startkey: prefix,
endkey: prefix + "\ufff0",
});
}
/**
* Delete all documents of the database matching the given filter.
*
* Note that `getAll()` also returns the database's own "_design/..." index
* documents, so a filter that does not exclude them deletes the indices as well.
* They are only recreated when the app starts up again
* (see {@link DatabaseIndexingService}), so only delete them if the calling code
* reloads the app or restores the documents immediately afterwards.
*
* @param shouldDelete filter deciding for each document whether it is deleted.
* Pass a specialized document type if the filter reads fields other than `_id`.
* @returns the number of deleted documents
*/
async removeAll<T extends { _id: string }>(
shouldDelete: (doc: T) => boolean,
): Promise<number> {
const allDocs: T[] = await this.getAll();
const docsToDelete = allDocs.filter(shouldDelete);
for (const doc of docsToDelete) {
await this.remove(doc);
}
return docsToDelete.length;
}
/**
* @returns true if there are no documents in the database
*/
abstract isEmpty(): Promise<boolean>;
/**
* Closes open connections and un-initializes the database
* (without deleting persisted data, see destroy() for that)
*/
abstract reset(): Promise<any>;
/**
* Closes all open connections to the database base and destroys it (clearing all data)
*/
abstract destroy(): Promise<any>;
abstract changes(): Observable<DatabaseDocChange>;
}
/**
* Based upon PouchDb changes feed format.
*/
export interface DatabaseDocChange {
_id: string;
_rev: string;
_deleted?: boolean;
[key: string]: any;
}
/**
* Basic query options supported by {@link Database}.
*
* also see https://pouchdb.com/guides/queries.html
*/
export type QueryOptions = PouchDB.Query.Options<any, any>;
/**
* Basic database read options supported by {@link Database}.
*
* also see https://pouchdb.com/api.html#fetch_document
*/
export type GetAllOptions =
| PouchDB.Core.AllDocsWithKeyOptions
| PouchDB.Core.AllDocsWithKeysOptions
| PouchDB.Core.AllDocsWithinRangeOptions
| PouchDB.Core.AllDocsOptions;
/**
* Basic database read options supported by {@link Database}.
*
* also see https://pouchdb.com/api.html#fetch_document
*/
export type GetOptions = PouchDB.Core.GetOptions;