Skip to content

Commit 810282f

Browse files
committed
Simplify JS database to store array of modifiers rather than separate individual modifiers; Fixes issue with startAt and endAt being used together
1 parent 08eab35 commit 810282f

File tree

3 files changed

+68
-149
lines changed

3 files changed

+68
-149
lines changed

lib/modules/database/index.js

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,6 @@ import { Base } from './../base';
1313
import Reference from './reference.js';
1414
import Snapshot from './snapshot.js';
1515

16-
/**
17-
* TODO ? why is it here and in reference? make it a util
18-
* @param modifiers
19-
* @returns {*}
20-
*/
21-
function getModifiersString(modifiers) {
22-
if (!modifiers || !Array.isArray(modifiers)) {
23-
return '';
24-
}
25-
return modifiers.join('|');
26-
}
27-
2816
/**
2917
* @class Database
3018
*/
@@ -100,25 +88,23 @@ export default class Database extends Base {
10088
this.log.debug('handleDatabaseError ->', evt);
10189
}
10290

103-
on(referenceKey: string, path: string, modifiers: Array<string>, evt: string, cb: () => void) {
91+
on(referenceKey: string, path: string, modifiersString: string, modifiers: Array<string>, evt: string, cb: () => void) {
10492
this.log.debug('adding on listener', referenceKey, path, modifiers, evt);
10593
const key = this._pathKey(path);
106-
const modifiersString = getModifiersString(modifiers);
107-
const modifier = modifiersString;
10894

10995
if (!this.dbSubscriptions[key]) {
11096
this.dbSubscriptions[key] = {};
11197
}
11298

113-
if (!this.dbSubscriptions[key][modifier]) {
114-
this.dbSubscriptions[key][modifier] = {};
99+
if (!this.dbSubscriptions[key][modifiersString]) {
100+
this.dbSubscriptions[key][modifiersString] = {};
115101
}
116102

117-
if (!this.dbSubscriptions[key][modifier][evt]) {
118-
this.dbSubscriptions[key][modifier][evt] = [];
103+
if (!this.dbSubscriptions[key][modifiersString][evt]) {
104+
this.dbSubscriptions[key][modifiersString][evt] = [];
119105
}
120106

121-
this.dbSubscriptions[key][modifier][evt].push(cb);
107+
this.dbSubscriptions[key][modifiersString][evt].push(cb);
122108

123109
if (!this.successListener) {
124110
this.successListener = FirestackDatabaseEvt
@@ -139,10 +125,8 @@ export default class Database extends Base {
139125
});
140126
}
141127

142-
off(referenceKey: string, path: string, modifiers: Array<string>, eventName: string, origCB?: () => void) {
128+
off(referenceKey: string, path: string, modifiersString: string, modifiers: Array<string>, eventName: string, origCB?: () => void) {
143129
const pathKey = this._pathKey(path);
144-
const modifiersString = getModifiersString(modifiers);
145-
const modifier = modifiersString;
146130
this.log.debug('off() : ', referenceKey, pathKey, modifiersString, eventName);
147131
// Remove subscription
148132
if (this.dbSubscriptions[pathKey]) {
@@ -153,14 +137,14 @@ export default class Database extends Base {
153137
}
154138

155139
// TODO clean me - no need for this many conditionals
156-
if (this.dbSubscriptions[pathKey][modifier]) {
157-
if (this.dbSubscriptions[pathKey][modifier][eventName]) {
140+
if (this.dbSubscriptions[pathKey][modifiersString]) {
141+
if (this.dbSubscriptions[pathKey][modifiersString][eventName]) {
158142
if (origCB) {
159143
// remove only the given callback
160-
this.dbSubscriptions[pathKey][modifier][eventName].splice(this.dbSubscriptions[pathKey][modifier][eventName].indexOf(origCB), 1);
144+
this.dbSubscriptions[pathKey][modifiersString][eventName].splice(this.dbSubscriptions[pathKey][modifiersString][eventName].indexOf(origCB), 1);
161145
} else {
162146
// remove all callbacks for this path:modifier:eventType
163-
delete this.dbSubscriptions[pathKey][modifier][eventName];
147+
delete this.dbSubscriptions[pathKey][modifiersString][eventName];
164148
}
165149
} else {
166150
this.log.warn('off() called, but not currently listening at that location (bad eventName)', pathKey, modifiersString, eventName);
@@ -190,7 +174,7 @@ export default class Database extends Base {
190174
const subscriptions = [this.successListener, this.errorListener];
191175
const modifierMap = this.dbSubscriptions[path];
192176

193-
if (modifierMap && modifierMap[modifier] && modifierMap[modifier][eventName] && modifierMap[modifier][eventName].length > 0) {
177+
if (modifierMap && modifierMap[modifiersString] && modifierMap[modifiersString][eventName] && modifierMap[modifiersString][eventName].length > 0) {
194178
return Promise.resolve(subscriptions);
195179
}
196180

lib/modules/database/query.js

Lines changed: 22 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -15,87 +15,46 @@ let uid = 1000000;
1515
export default class Query extends ReferenceBase {
1616
static ref: Reference;
1717

18-
static orderBy: Array<string>;
19-
static limit: Array<string>;
20-
static filters: Object;// { [key: string]: Array<string> };
18+
static modifiers: Array<string>;
2119

2220
ref: Reference;
2321

24-
constructor(ref: Reference, path: Array<string>, existingModifiers?: { [key: string]: string }) {
22+
constructor(ref: Reference, path: Array<string>, existingModifiers?: Array<string>) {
2523
super(ref.db, path);
2624
this.log.debug('creating Query ', path, existingModifiers);
2725
this.uid = uid++; // uuid.v4();
2826
this.ref = ref;
29-
this.orderBy = undefined;
30-
this.limit = undefined;
31-
this.filters = {};
32-
33-
// parse exsitingModifiers
34-
if (existingModifiers) {
35-
this.import(existingModifiers);
36-
}
27+
this.modifiers = existingModifiers ? [...existingModifiers] : [];
3728
}
3829

39-
// noinspection ReservedWordAsName
40-
export(): { [key: string]: string } {
41-
const argsSeparator = ':';
42-
const ret = {};
43-
if (this.orderBy) {
44-
ret.orderBy = this.orderBy.join(argsSeparator);
45-
}
46-
if (this.limit) {
47-
ret.limit = this.limit.join(argsSeparator);
48-
}
49-
if (this.filters && Object.keys(this.filters).length > 0) {
50-
let filters = Object.keys(this.filters).map(key => {
51-
const filter = this.filters[key];
52-
if (filter) {
53-
return [key, filter].join(argsSeparator);
54-
}
55-
}).filter(Boolean);
56-
if (filters.length > 0) {
57-
ret.filters = filters.join('|');
58-
}
30+
setOrderBy(name: string, key?: string) {
31+
if (key) {
32+
this.modifiers.push(name + ':' + key);
33+
} else {
34+
this.modifiers.push(name);
5935
}
60-
return ret;
6136
}
6237

63-
// noinspection ReservedWordAsName
64-
import(modifiers: { [key: string]: string }) {
65-
const argsSeparator = ':';
66-
if (modifiers.orderBy) {
67-
this.setOrderBy(...modifiers.orderBy.split(argsSeparator));
68-
}
69-
70-
if (modifiers.limit) {
71-
const [name, value] = modifiers.limit.split(argsSeparator);
72-
this.setLimit(name, parseInt(value, 10));
73-
}
74-
75-
if (modifiers.filters) {
76-
modifiers.filters.split('|').forEach(filter => {
77-
this.setFilter(...filter.split(argsSeparator));
78-
});
79-
}
38+
setLimit(name: string, limit: number) {
39+
this.modifiers.push(name + ':' + limit);
8040
}
8141

82-
setOrderBy(name: string, ...args: Array<string>) {
83-
this.orderBy = [name].concat(args);
42+
setFilter(name: string, value: any, key?:string) {
43+
if (key) {
44+
this.modifiers.push(name + ':' + value + ':' + key);
45+
} else {
46+
this.modifiers.push(name + ':' + value);
47+
}
8448
}
8549

86-
setLimit(name: string, limit: number) {
87-
this.limit = [name, limit];
50+
getModifiers(): Array<string> {
51+
return [...this.modifiers];
8852
}
8953

90-
setFilter(name: string, ...args: Array<?string>) {
91-
let vals = args.filter(str => !!str);
92-
if (vals.length > 0) {
93-
this.filters[name] = vals;
54+
getModifiersString(): string {
55+
if (!this.modifiers || !Array.isArray(this.modifiers)) {
56+
return '';
9457
}
95-
}
96-
97-
build() {
98-
let exportObj = this.export();
99-
return Object.keys(exportObj).map(exportKey => exportObj[exportKey]);
58+
return this.modifiers.join('|');
10059
}
10160
}

lib/modules/database/reference.js

Lines changed: 34 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,6 @@ import Query from './query.js';
1010

1111
const FirestackDatabase = NativeModules.FirestackDatabase;
1212

13-
/**
14-
* TODO ? why is it here and in index? make it a util
15-
* @param modifiers
16-
* @returns {*}
17-
*/
18-
function getModifiersString(modifiers) {
19-
if (!modifiers || !Array.isArray(modifiers)) {
20-
return '';
21-
}
22-
return modifiers.join('|');
23-
}
24-
2513
// https://firebase.google.com/docs/reference/js/firebase.database.Reference
2614
let uid = 0;
2715

@@ -34,7 +22,7 @@ export default class Reference extends ReferenceBase {
3422
query: Query;
3523
uid: number;
3624

37-
constructor(db: FirestackDatabase, path: Array<string>, existingModifiers?: { [key: string]: string }) {
25+
constructor(db: FirestackDatabase, path: Array<string>, existingModifiers?: Array<string>) {
3826
super(db.firestack, path);
3927

4028
this.db = db;
@@ -73,8 +61,8 @@ export default class Reference extends ReferenceBase {
7361
// Get the value of a ref either with a key
7462
getAt() {
7563
const path = this.dbPath();
76-
const modifiers = this.dbModifiers();
77-
const modifiersString = getModifiersString(modifiers);
64+
const modifiers = this.query.getModifiers();
65+
const modifiersString = this.query.getModifiersString();
7866
return promisify('onOnce', FirestackDatabase)(path, modifiersString, modifiers, 'value');
7967
}
8068

@@ -108,20 +96,20 @@ export default class Reference extends ReferenceBase {
10896

10997
on(evt?: string, cb: () => any) {
11098
const path = this.dbPath();
111-
const modifiers = this.dbModifiers();
112-
const modifiersString = getModifiersString(modifiers);
99+
const modifiers = this.query.getModifiers();
100+
const modifiersString = this.query.getModifiersString();
113101
this.log.debug('adding reference.on', path, modifiersString, evt);
114102
return this.db.storeRef(this.uid, this).then(() => {
115-
return this.db.on(this.uid, path, modifiers, evt, cb).then(subscriptions => {
103+
return this.db.on(this.uid, path, modifiersString, modifiers, evt, cb).then(subscriptions => {
116104
this.listeners[evt] = subscriptions;
117105
});
118106
});
119107
}
120108

121109
once(evt?: string = 'once', cb: (snapshot: Object) => void) {
122110
const path = this.dbPath();
123-
const modifiers = this.dbModifiers();
124-
const modifiersString = getModifiersString(modifiers);
111+
const modifiers = this.query.getModifiers();
112+
const modifiersString = this.query.getModifiersString();
125113
return this.db.storeRef(this.uid, this).then(() => {
126114
return promisify('onOnce', FirestackDatabase)(path, modifiersString, modifiers, evt)
127115
.then(({ snapshot }) => new Snapshot(this, snapshot))
@@ -136,10 +124,10 @@ export default class Reference extends ReferenceBase {
136124

137125
off(evt: string = '', origCB?: () => any) {
138126
const path = this.dbPath();
139-
const modifiers = this.dbModifiers();
127+
const modifiers = this.query.getModifiers();
140128
this.log.debug('ref.off(): ', path, modifiers, evt);
141129
return this.db.unstoreRef(this.uid).then(() => {
142-
return this.db.off(this.uid, path, modifiers, evt, origCB).then(subscriptions => {
130+
return this.db.off(this.uid, path, modifiersString, modifiers, evt, origCB).then(subscriptions => {
143131
// delete this.listeners[eventName];
144132
// this.listeners[evt] = subscriptions;
145133
});
@@ -184,68 +172,60 @@ export default class Reference extends ReferenceBase {
184172
}, {});
185173
}
186174

187-
// class Query extends Reference {}
188-
189-
// let ref = firestack.database().ref('/timeline');
190-
// ref.limitToLast(1).on('child_added', () => {});
191-
// ref.limitToFirst(1).on('child_added', () => {});
192-
// ref.on('child_added', () => {})
193-
194175
// Modifiers
195176
orderByKey(): Reference {
196-
const newRef = new Reference(this.db, this.path, this.query.export());
197-
newRef.query.setOrderBy('orderByKey');
198-
return newRef;
177+
return this.orderBy('orderByKey');
199178
}
200179

201180
orderByPriority(): Reference {
202-
const newRef = new Reference(this.db, this.path, this.query.export());
203-
newRef.query.setOrderBy('orderByPriority');
204-
return newRef;
181+
return this.orderBy('orderByPriority');
205182
}
206183

207184
orderByValue(): Reference {
208-
const newRef = new Reference(this.db, this.path, this.query.export());
209-
newRef.query.setOrderBy('orderByValue');
210-
return newRef;
185+
return this.orderBy('orderByValue');
211186
}
212187

213188
orderByChild(key: string): Reference {
214-
const newRef = new Reference(this.db, this.path, this.query.export());
215-
newRef.query.setOrderBy('orderByChild', key);
189+
return this.orderBy('orderByChild', key);
190+
}
191+
192+
orderBy(name: string, key?: string): Reference {
193+
const newRef = new Reference(this.db, this.path, this.query.getModifiers());
194+
newRef.query.setOrderBy(name, key);
216195
return newRef;
217196
}
218197

219198
// Limits
220199
limitToLast(limit: number): Reference {
221-
const newRef = new Reference(this.db, this.path, this.query.export());
222-
newRef.query.setLimit('limitToLast', limit);
223-
return newRef;
200+
return this.limit('limitToLast', limit);
224201
}
225202

226203
limitToFirst(limit: number): Reference {
227-
// return this.query.setLimit('limitToFirst', limit);
228-
const newRef = new Reference(this.db, this.path, this.query.export());
229-
newRef.query.setLimit('limitToFirst', limit);
204+
return this.limit('limitToFirst', limit);
205+
}
206+
207+
limit(name: string, limit: number): Reference {
208+
const newRef = new Reference(this.db, this.path, this.query.getModifiers());
209+
newRef.query.setLimit(name, limit);
230210
return newRef;
231211
}
232212

233213
// Filters
234214
equalTo(value: any, key?: string): Reference {
235-
const newRef = new Reference(this.db, this.path, this.query.export());
236-
newRef.query.setFilter('equalTo', value, key);
237-
return newRef;
215+
return this.filter('equalTo', value, key);
238216
}
239217

240218
endAt(value: any, key?: string): Reference {
241-
const newRef = new Reference(this.db, this.path, this.query.export());
242-
newRef.query.setFilter('endAt', value, key);
243-
return newRef;
219+
return this.filter('endAt', value, key);
244220
}
245221

246222
startAt(value: any, key?: string): Reference {
247-
const newRef = new Reference(this.db, this.path, this.query.export());
248-
newRef.query.setFilter('startAt', value, key);
223+
return this.filter('startAt', value, key);
224+
}
225+
226+
filter(name: string, value: any, key?: string): Reference {
227+
const newRef = new Reference(this.db, this.path, this.query.getModifiers());
228+
newRef.query.setFilter(name, value, key);
249229
return newRef;
250230
}
251231

@@ -278,10 +258,6 @@ export default class Reference extends ReferenceBase {
278258
return pathStr;
279259
}
280260

281-
dbModifiers(): Array<string> {
282-
return this.query.build();
283-
}
284-
285261
get namespace(): string {
286262
return 'firestack:dbRef';
287263
}

0 commit comments

Comments
 (0)