UNPKG

rxdb

Version:

A local-first realtime NoSQL Database for JavaScript applications - https://rxdb.info/

160 lines (152 loc) 5.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dexieCount = dexieCount; exports.dexieQuery = dexieQuery; exports.getKeyRangeByQueryPlan = getKeyRangeByQueryPlan; exports.mapKeyForKeyRange = mapKeyForKeyRange; var _queryPlanner = require("../../query-planner.js"); var _rxQueryHelper = require("../../rx-query-helper.js"); var _dexieHelper = require("./dexie-helper.js"); function mapKeyForKeyRange(k) { if (k === _queryPlanner.INDEX_MIN) { return -Infinity; } else { return k; } } function rangeFieldToBooleanSubstitute(booleanIndexes, fieldName, value) { if (booleanIndexes.includes(fieldName)) { var newValue = value === _queryPlanner.INDEX_MAX || value === true ? '1' : '0'; return newValue; } else { return value; } } function getKeyRangeByQueryPlan(booleanIndexes, queryPlan, IDBKeyRange) { if (!IDBKeyRange) { if (typeof window === 'undefined') { throw new Error('IDBKeyRange missing'); } else { IDBKeyRange = window.IDBKeyRange; } } var startKeys = queryPlan.startKeys.map((v, i) => { var fieldName = queryPlan.index[i]; return rangeFieldToBooleanSubstitute(booleanIndexes, fieldName, v); }).map(mapKeyForKeyRange); var endKeys = queryPlan.endKeys.map((v, i) => { var fieldName = queryPlan.index[i]; return rangeFieldToBooleanSubstitute(booleanIndexes, fieldName, v); }).map(mapKeyForKeyRange); var keyRange = IDBKeyRange.bound(startKeys, endKeys, !queryPlan.inclusiveStart, !queryPlan.inclusiveEnd); return keyRange; } /** * Runs mango queries over the Dexie.js database. */ async function dexieQuery(instance, preparedQuery) { var state = await instance.internals; var query = preparedQuery.query; var skip = query.skip ? query.skip : 0; var limit = query.limit ? query.limit : Infinity; var skipPlusLimit = skip + limit; var queryPlan = preparedQuery.queryPlan; var queryMatcher = false; if (!queryPlan.selectorSatisfiedByIndex) { queryMatcher = (0, _rxQueryHelper.getQueryMatcher)(instance.schema, preparedQuery.query); } var keyRange = getKeyRangeByQueryPlan(state.booleanIndexes, queryPlan, state.dexieDb._options.IDBKeyRange); var queryPlanFields = queryPlan.index; var rows = []; await state.dexieDb.transaction('r', state.dexieTable, async dexieTx => { /** * Here we use the native IndexedDB transaction * to get the cursor. * Maybe we should not leave Dexie.js API and find * a way to create the cursor with Dexie.js. */ var tx = dexieTx.idbtrans; // const nativeIndexedDB = state.dexieDb.backendDB(); // const trans = nativeIndexedDB.transaction([DEXIE_DOCS_TABLE_NAME], 'readonly'); var store = tx.objectStore(_dexieHelper.DEXIE_DOCS_TABLE_NAME); var index; var indexName; indexName = '[' + queryPlanFields.map(field => (0, _dexieHelper.dexieReplaceIfStartsWithPipe)(field)).join('+') + ']'; index = store.index(indexName); var cursorReq = index.openCursor(keyRange); await new Promise(res => { cursorReq.onsuccess = function (e) { var cursor = e.target.result; if (cursor) { // We have a record in cursor.value var docData = (0, _dexieHelper.fromDexieToStorage)(state.booleanIndexes, cursor.value); if (!queryMatcher || queryMatcher(docData)) { rows.push(docData); } /** * If we do not have to manually sort * and have enough documents, * we can abort iterating over the cursor * because we already have every relevant document. */ if (queryPlan.sortSatisfiedByIndex && rows.length === skipPlusLimit) { res(); } else { cursor.continue(); } } else { // Iteration complete res(); } }; }); }); if (!queryPlan.sortSatisfiedByIndex) { var sortComparator = (0, _rxQueryHelper.getSortComparator)(instance.schema, preparedQuery.query); rows = rows.sort(sortComparator); } // apply skip and limit boundaries. rows = rows.slice(skip, skipPlusLimit); /** * Comment this in for debugging to check all fields in the database. */ // const docsInDb = await state.dexieTable.filter(queryMatcher).toArray(); // let documents = docsInDb // .map(docData => stripDexieKey(docData)) // .sort(sortComparator); // if (preparedQuery.skip) { // documents = documents.slice(preparedQuery.skip); // } // if (preparedQuery.limit && documents.length > preparedQuery.limit) { // documents = documents.slice(0, preparedQuery.limit); // } return { documents: rows }; } async function dexieCount(instance, preparedQuery) { var state = await instance.internals; var queryPlan = preparedQuery.queryPlan; var queryPlanFields = queryPlan.index; var keyRange = getKeyRangeByQueryPlan(state.booleanIndexes, queryPlan, state.dexieDb._options.IDBKeyRange); var count = -1; await state.dexieDb.transaction('r', state.dexieTable, async dexieTx => { var tx = dexieTx.idbtrans; var store = tx.objectStore(_dexieHelper.DEXIE_DOCS_TABLE_NAME); var index; var indexName; indexName = '[' + queryPlanFields.map(field => (0, _dexieHelper.dexieReplaceIfStartsWithPipe)(field)).join('+') + ']'; index = store.index(indexName); var request = index.count(keyRange); count = await new Promise((res, rej) => { request.onsuccess = function () { res(request.result); }; request.onerror = err => rej(err); }); }); return count; } //# sourceMappingURL=dexie-query.js.map