Skip to content

Commit 5433bcb

Browse files
authored
Add a flag to NoSqlProvider to skip ordering results. This can make th… (#67)
* Add a flag to NoSqlProvider to skip odering results. This can make the sqlite provider faster on large datasets Keep backwards compatibility with the existing boolean * Add more tests & bump package.json
1 parent da5a95a commit 5433bcb

8 files changed

Lines changed: 105 additions & 56 deletions

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nosqlprovider",
3-
"version": "0.6.20",
3+
"version": "0.6.21",
44
"description": "A cross-browser/platform indexeddb-like client library",
55
"author": "David de Regt <David.de.Regt@microsoft.com>",
66
"scripts": {

src/FullTextSearchHelpers.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,12 @@ export abstract class DbIndexFTSFromRangeQueries implements NoSqlProvider.DbInde
9191
});
9292
}
9393

94-
abstract getAll(reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]>;
95-
abstract getOnly(key: KeyType, reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]>;
94+
abstract getAll(reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number)
95+
: SyncTasks.Promise<ItemType[]>;
96+
abstract getOnly(key: KeyType, reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number)
97+
: SyncTasks.Promise<ItemType[]>;
9698
abstract getRange(keyLowRange: KeyType, keyHighRange: KeyType, lowRangeExclusive?: boolean, highRangeExclusive?: boolean,
97-
reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]>;
99+
reverseOrSortOrder?: boolean|NoSqlProvider.QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]>;
98100
abstract countAll(): SyncTasks.Promise<number>;
99101
abstract countOnly(key: KeyType): SyncTasks.Promise<number>;
100102
abstract countRange(keyLowRange: KeyType, keyHighRange: KeyType, lowRangeExclusive?: boolean, highRangeExclusive?: boolean)

src/InMemoryProvider.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ class InMemoryIndex extends FullTextSearchHelpers.DbIndexFTSFromRangeQueries {
303303
return data;
304304
}
305305

306-
getAll(reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
306+
getAll(reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
307307
if (!this._trans.internal_isOpen()) {
308308
return SyncTasks.Rejected('InMemoryTransaction already closed');
309309
}
@@ -316,15 +316,16 @@ class InMemoryIndex extends FullTextSearchHelpers.DbIndexFTSFromRangeQueries {
316316
}
317317

318318
const sortedKeys = _.keys(data).sort();
319-
return this._returnResultsFromKeys(data, sortedKeys, reverse, limit, offset);
319+
return this._returnResultsFromKeys(data, sortedKeys, reverseOrSortOrder, limit, offset);
320320
}
321321

322-
getOnly(key: KeyType, reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
323-
return this.getRange(key, key, false, false, reverse, limit, offset);
322+
getOnly(key: KeyType, reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number)
323+
: SyncTasks.Promise<ItemType[]> {
324+
return this.getRange(key, key, false, false, reverseOrSortOrder, limit, offset);
324325
}
325326

326327
getRange(keyLowRange: KeyType, keyHighRange: KeyType, lowRangeExclusive?: boolean, highRangeExclusive?: boolean,
327-
reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
328+
reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
328329
if (!this._trans.internal_isOpen()) {
329330
return SyncTasks.Rejected('InMemoryTransaction already closed');
330331
}
@@ -339,7 +340,7 @@ class InMemoryIndex extends FullTextSearchHelpers.DbIndexFTSFromRangeQueries {
339340
return SyncTasks.Rejected(err);
340341
}
341342

342-
return this._returnResultsFromKeys(data!!!, sortedKeys!!!, reverse, limit, offset);
343+
return this._returnResultsFromKeys(data!!!, sortedKeys!!!, reverseOrSortOrder, limit, offset);
343344
}
344345

345346
// Warning: This function can throw, make sure to trap.
@@ -351,9 +352,9 @@ class InMemoryIndex extends FullTextSearchHelpers.DbIndexFTSFromRangeQueries {
351352
(key > keyLow || (key === keyLow && !lowRangeExclusive)) && (key < keyHigh || (key === keyHigh && !highRangeExclusive)));
352353
}
353354

354-
private _returnResultsFromKeys(data: _.Dictionary<ItemType[]>|_.Dictionary<ItemType>, sortedKeys: string[], reverse?: boolean,
355-
limit?: number, offset?: number) {
356-
if (reverse) {
355+
private _returnResultsFromKeys(data: _.Dictionary<ItemType[]> | _.Dictionary<ItemType>, sortedKeys: string[],
356+
reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number) {
357+
if (reverseOrSortOrder === true || reverseOrSortOrder === NoSqlProvider.QuerySortOrder.Reverse) {
357358
sortedKeys = _.reverse(sortedKeys);
358359
}
359360

src/IndexedDbProvider.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -720,22 +720,24 @@ class IndexedDbIndex extends FullTextSearchHelpers.DbIndexFTSFromRangeQueries {
720720
}
721721
}
722722

723-
getAll(reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
723+
getAll(reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
724+
const reverse = reverseOrSortOrder === true || reverseOrSortOrder === NoSqlProvider.QuerySortOrder.Reverse;
724725
// ************************* Don't change this null to undefined, IE chokes on it... *****************************
725726
// ************************* Don't change this null to undefined, IE chokes on it... *****************************
726727
// ************************* Don't change this null to undefined, IE chokes on it... *****************************
727728
const req = this._store.openCursor(null!!!, reverse ? 'prev' : 'next');
728729
return this._resolveCursorResult(req, limit, offset);
729730
}
730731

731-
getOnly(key: KeyType, reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
732+
getOnly(key: KeyType, reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number)
733+
: SyncTasks.Promise<ItemType[]> {
732734
const keyRange = _.attempt(() => {
733735
return this._getKeyRangeForOnly(key);
734736
});
735737
if (_.isError(keyRange)) {
736738
return SyncTasks.Rejected(keyRange);
737739
}
738-
740+
const reverse = reverseOrSortOrder === true || reverseOrSortOrder === NoSqlProvider.QuerySortOrder.Reverse;
739741
const req = this._store.openCursor(keyRange, reverse ? 'prev' : 'next');
740742
return this._resolveCursorResult(req, limit, offset);
741743
}
@@ -749,14 +751,15 @@ class IndexedDbIndex extends FullTextSearchHelpers.DbIndexFTSFromRangeQueries {
749751
}
750752

751753
getRange(keyLowRange: KeyType, keyHighRange: KeyType, lowRangeExclusive?: boolean, highRangeExclusive?: boolean,
752-
reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
754+
reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
753755
const keyRange = _.attempt(() => {
754756
return this._getKeyRangeForRange(keyLowRange, keyHighRange, lowRangeExclusive, highRangeExclusive);
755757
});
756758
if (_.isError(keyRange)) {
757759
return SyncTasks.Rejected(keyRange);
758760
}
759761

762+
const reverse = reverseOrSortOrder === true || reverseOrSortOrder === NoSqlProvider.QuerySortOrder.Reverse;
760763
const req = this._store.openCursor(keyRange, reverse ? 'prev' : 'next');
761764
return this._resolveCursorResult(req, limit, offset);
762765
}

src/NoSqlProvider.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ import SyncTasks = require('synctasks');
1717
export type ItemType = object;
1818
export type KeyComponentType = string|number|Date;
1919
export type KeyType = KeyComponentType|KeyComponentType[];
20-
export type KeyPathType = string|string[];
20+
export type KeyPathType = string | string[];
21+
export enum QuerySortOrder {
22+
None,
23+
Forward,
24+
Reverse
25+
}
2126

2227
// Schema type describing an index for a store.
2328
export interface IndexSchema {
@@ -55,10 +60,10 @@ export enum FullTextTermResolution {
5560

5661
// Interface type describing an index being opened for querying.
5762
export interface DbIndex {
58-
getAll(reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]>;
59-
getOnly(key: KeyType, reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]>;
63+
getAll(reverseOrSortOrder?: boolean|QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]>;
64+
getOnly(key: KeyType, reverseOrSortOrder?: boolean|QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]>;
6065
getRange(keyLowRange: KeyType, keyHighRange: KeyType, lowRangeExclusive?: boolean, highRangeExclusive?: boolean,
61-
reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]>;
66+
reverseOrSortOrder?: boolean|QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]>;
6267
countAll(): SyncTasks.Promise<number>;
6368
countOnly(key: KeyType): SyncTasks.Promise<number>;
6469
countRange(keyLowRange: KeyType, keyHighRange: KeyType, lowRangeExclusive?: boolean, highRangeExclusive?: boolean)
@@ -189,25 +194,25 @@ export abstract class DbProvider {
189194
});
190195
}
191196

192-
getAll(storeName: string, indexName: string|undefined, reverse?: boolean, limit?: number, offset?: number)
197+
getAll(storeName: string, indexName: string|undefined, reverseOrSortOrder?: boolean|QuerySortOrder, limit?: number, offset?: number)
193198
: SyncTasks.Promise<ItemType[]> {
194199
return this._getStoreIndexTransaction(storeName, false, indexName).then(index => {
195-
return index.getAll(reverse, limit, offset);
200+
return index.getAll(reverseOrSortOrder, limit, offset);
196201
});
197202
}
198203

199-
getOnly(storeName: string, indexName: string|undefined, key: KeyType, reverse?: boolean, limit?: number, offset?: number)
200-
: SyncTasks.Promise<ItemType[]> {
204+
getOnly(storeName: string, indexName: string | undefined, key: KeyType, reverseOrSortOrder?: boolean | QuerySortOrder, limit?: number,
205+
offset?: number): SyncTasks.Promise<ItemType[]> {
201206
return this._getStoreIndexTransaction(storeName, false, indexName).then(index => {
202-
return index.getOnly(key, reverse, limit, offset);
207+
return index.getOnly(key, reverseOrSortOrder, limit, offset);
203208
});
204209
}
205210

206-
getRange(storeName: string, indexName: string|undefined, keyLowRange: KeyType, keyHighRange: KeyType,
207-
lowRangeExclusive?: boolean, highRangeExclusive?: boolean, reverse?: boolean, limit?: number, offset?: number)
211+
getRange(storeName: string, indexName: string | undefined, keyLowRange: KeyType, keyHighRange: KeyType, lowRangeExclusive?: boolean,
212+
highRangeExclusive?: boolean, reverseOrSortOrder?: boolean | QuerySortOrder, limit?: number, offset?: number)
208213
: SyncTasks.Promise<ItemType[]> {
209214
return this._getStoreIndexTransaction(storeName, false, indexName).then(index => {
210-
return index.getRange(keyLowRange, keyHighRange, lowRangeExclusive, highRangeExclusive, reverse, limit, offset);
215+
return index.getRange(keyLowRange, keyHighRange, lowRangeExclusive, highRangeExclusive, reverseOrSortOrder, limit, offset);
211216
});
212217
}
213218

src/SqlProviderBase.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,8 +1118,13 @@ class SqlStoreIndex implements NoSqlProvider.DbIndex {
11181118
}
11191119
}
11201120

1121-
private _handleQuery(sql: string, args?: any[], reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
1122-
sql += ' ORDER BY ' + this._queryColumn + (reverse ? ' DESC' : ' ASC');
1121+
private _handleQuery(sql: string, args?: any[], reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number,
1122+
offset?: number): SyncTasks.Promise<ItemType[]> {
1123+
// Check if we must do some sort of ordering
1124+
if (reverseOrSortOrder !== NoSqlProvider.QuerySortOrder.None) {
1125+
const reverse = reverseOrSortOrder === true || reverseOrSortOrder === NoSqlProvider.QuerySortOrder.Reverse;
1126+
sql += ' ORDER BY ' + this._queryColumn + (reverse ? ' DESC' : ' ASC');
1127+
}
11231128

11241129
if (limit) {
11251130
if (limit > LimitMax) {
@@ -1138,13 +1143,13 @@ class SqlStoreIndex implements NoSqlProvider.DbIndex {
11381143
return this._trans.internal_getResultsFromQuery(sql, args);
11391144
}
11401145

1141-
getAll(reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
1146+
getAll(reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
11421147
let startTime: number;
11431148
if (this._verbose) {
11441149
startTime = Date.now();
11451150
}
11461151

1147-
let promise = this._handleQuery('SELECT nsp_data FROM ' + this._tableName, undefined, reverse, limit, offset);
1152+
let promise = this._handleQuery('SELECT nsp_data FROM ' + this._tableName, undefined, reverseOrSortOrder, limit, offset);
11481153
if (this._verbose) {
11491154
promise = promise.finally(() => {
11501155
console.log('SqlStoreIndex (' + this._rawTableName + '/' + this._indexTableName + ') getAll: (' +
@@ -1154,7 +1159,8 @@ class SqlStoreIndex implements NoSqlProvider.DbIndex {
11541159
return promise;
11551160
}
11561161

1157-
getOnly(key: KeyType, reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
1162+
getOnly(key: KeyType, reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number)
1163+
: SyncTasks.Promise<ItemType[]> {
11581164
const joinedKey = _.attempt(() => {
11591165
return NoSqlProviderUtils.serializeKeyToString(key, this._keyPath);
11601166
});
@@ -1168,8 +1174,7 @@ class SqlStoreIndex implements NoSqlProvider.DbIndex {
11681174
}
11691175

11701176
let promise = this._handleQuery('SELECT nsp_data FROM ' + this._tableName + ' WHERE ' + this._queryColumn + ' = ?',
1171-
[joinedKey],
1172-
reverse, limit, offset);
1177+
[joinedKey], reverseOrSortOrder, limit, offset);
11731178
if (this._verbose) {
11741179
promise = promise.finally(() => {
11751180
console.log('SqlStoreIndex (' + this._rawTableName + '/' + this._indexTableName + ') getOnly: (' +
@@ -1180,7 +1185,7 @@ class SqlStoreIndex implements NoSqlProvider.DbIndex {
11801185
}
11811186

11821187
getRange(keyLowRange: KeyType, keyHighRange: KeyType, lowRangeExclusive?: boolean, highRangeExclusive?: boolean,
1183-
reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
1188+
reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ItemType[]> {
11841189
let checks: string;
11851190
let args: string[];
11861191
const err = _.attempt(() => {
@@ -1198,7 +1203,7 @@ class SqlStoreIndex implements NoSqlProvider.DbIndex {
11981203
}
11991204

12001205
let promise = this._handleQuery('SELECT nsp_data FROM ' + this._tableName + ' WHERE ' + checks!!!, args!!!,
1201-
reverse, limit, offset);
1206+
reverseOrSortOrder, limit, offset);
12021207
if (this._verbose) {
12031208
promise = promise.finally(() => {
12041209
console.log('SqlStoreIndex (' + this._rawTableName + '/' + this._indexTableName + ') getRange: (' +

src/StoreHelpers.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,21 @@ export class SimpleTransactionIndexHelper<ObjectType extends ItemType, IndexKeyF
2626
// Nothing to see here
2727
}
2828

29-
getAll(reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ObjectType[]> {
30-
let promise = this._index.getAll(reverse, limit, offset) as SyncTasks.Promise<ObjectType[]>;
29+
getAll(reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ObjectType[]> {
30+
let promise = this._index.getAll(reverseOrSortOrder, limit, offset) as SyncTasks.Promise<ObjectType[]>;
3131
return ErrorCatcher ? promise.catch(ErrorCatcher) : promise;
3232
}
3333

34-
getOnly(key: IndexKeyFormat, reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ObjectType[]> {
35-
let promise = this._index.getOnly(key, reverse, limit, offset) as SyncTasks.Promise<ObjectType[]>;
34+
getOnly(key: IndexKeyFormat, reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number)
35+
: SyncTasks.Promise<ObjectType[]> {
36+
let promise = this._index.getOnly(key, reverseOrSortOrder, limit, offset) as SyncTasks.Promise<ObjectType[]>;
3637
return ErrorCatcher ? promise.catch(ErrorCatcher) : promise;
3738
}
3839

39-
getRange(keyLowRange: IndexKeyFormat, keyHighRange: IndexKeyFormat,
40-
lowRangeExclusive?: boolean, highRangeExclusive?: boolean, reverse?: boolean, limit?: number, offset?: number)
41-
: SyncTasks.Promise<ObjectType[]> {
40+
getRange(keyLowRange: IndexKeyFormat, keyHighRange: IndexKeyFormat, lowRangeExclusive?: boolean, highRangeExclusive?: boolean,
41+
reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ObjectType[]> {
4242
let promise = this._index.getRange(keyLowRange, keyHighRange, lowRangeExclusive,
43-
highRangeExclusive, reverse, limit, offset) as SyncTasks.Promise<ObjectType[]>;
43+
highRangeExclusive, reverseOrSortOrder, limit, offset) as SyncTasks.Promise<ObjectType[]>;
4444
return ErrorCatcher ? promise.catch(ErrorCatcher) : promise;
4545
}
4646

@@ -84,16 +84,16 @@ export class SimpleTransactionStoreHelper<StoreName extends string, ObjectType e
8484
return ErrorCatcher ? promise.catch(ErrorCatcher) : promise;
8585
}
8686

87-
getOnly(key: KeyFormat, reverse?: boolean, limit?: number, offset?: number): SyncTasks.Promise<ObjectType[]> {
88-
let promise = this._store.openPrimaryKey().getOnly(key, reverse, limit, offset) as SyncTasks.Promise<ObjectType[]>;
87+
getOnly(key: KeyFormat, reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number)
88+
: SyncTasks.Promise<ObjectType[]> {
89+
let promise = this._store.openPrimaryKey().getOnly(key, reverseOrSortOrder, limit, offset) as SyncTasks.Promise<ObjectType[]>;
8990
return ErrorCatcher ? promise.catch(ErrorCatcher) : promise;
9091
}
9192

92-
getRange(keyLowRange: KeyFormat, keyHighRange: KeyFormat,
93-
lowRangeExclusive?: boolean, highRangeExclusive?: boolean, reverse?: boolean, limit?: number, offset?: number)
94-
: SyncTasks.Promise<ObjectType[]> {
93+
getRange(keyLowRange: KeyFormat, keyHighRange: KeyFormat, lowRangeExclusive?: boolean, highRangeExclusive?: boolean,
94+
reverseOrSortOrder?: boolean | NoSqlProvider.QuerySortOrder, limit?: number, offset?: number): SyncTasks.Promise<ObjectType[]> {
9595
let promise = this._store.openPrimaryKey().getRange(keyLowRange, keyHighRange,
96-
lowRangeExclusive, highRangeExclusive, reverse, limit, offset) as SyncTasks.Promise<ObjectType[]>;
96+
lowRangeExclusive, highRangeExclusive, reverseOrSortOrder, limit, offset) as SyncTasks.Promise<ObjectType[]>;
9797
return ErrorCatcher ? promise.catch(ErrorCatcher) : promise;
9898
}
9999

0 commit comments

Comments
 (0)