Skip to content
This repository was archived by the owner on Jul 27, 2020. It is now read-only.

Commit d59c30d

Browse files
committed
feature(db): add get and query
1 parent a7ae4be commit d59c30d

File tree

2 files changed

+118
-2
lines changed

2 files changed

+118
-2
lines changed

spec/db_spec.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,55 @@ describe('database functionality', () => {
9696
idb.changes.subscribe(notif => {
9797
notificationCount++;
9898
});
99-
idb.insert('todos',[{name: 'todo3'}, {name: 'todo4'}])
99+
idb.insert('todos',[{name: 'todo5'}, {name: 'todo6'}])
100100
.toArray()
101101
.subscribe(() => {}, (err) => {}, () => {
102102
expect(notificationCount).toBe(2);
103103
done();
104104
});
105105
});
106106

107+
it('should get a record by key', (done) => {
108+
let found;
109+
idb.get('todos', 3)
110+
.subscribe(record => {
111+
found = record;
112+
}, err => {
113+
console.error(err);
114+
done(err);
115+
}, () => {
116+
expect(found).toEqual({name: 'todo3'});
117+
done()
118+
});
119+
});
120+
121+
it('should iterate records', (done) => {
122+
let found;
123+
idb.query('todos').toArray()
124+
.subscribe(records => {
125+
found = records;
126+
}, err => {
127+
console.error(err);
128+
done(err);
129+
}, () => {
130+
expect(found.length).toEqual(6);
131+
done()
132+
});
133+
});
134+
135+
it('should iterate records with a predicate fn', (done) => {
136+
let found;
137+
idb.query('todos', (rec) => rec.name === 'todo5').toArray()
138+
.subscribe(records => {
139+
found = records;
140+
}, err => {
141+
console.error(err);
142+
done(err);
143+
}, () => {
144+
expect(found.length).toEqual(1);
145+
done()
146+
});
147+
});
148+
107149
});
108150

src/database.ts

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const IDB_COMPLETE = 'complete';
99
const IDB_ERROR = 'error';
1010
const IDB_UPGRADE_NEEDED = 'upgradeneeded';
1111

12-
const IDB_TXN_READ = 'read';
12+
const IDB_TXN_READ = 'readonly';
1313
const IDB_TXN_READWRITE = 'readwrite';
1414

1515
export const DB_INSERT = 'DB_INSERT';
@@ -120,6 +120,80 @@ export class Database {
120120
.do(payload => notify ? this.changes.next({type: DB_INSERT, payload }) : ({}));
121121
}
122122

123+
get(storeName:string, key:any){
124+
return this.open(this._schema.name)
125+
.mergeMap(db => {
126+
return new Observable(txnObserver => {
127+
const txn = db.transaction([storeName], IDB_TXN_READ);
128+
const objectStore = txn.objectStore(storeName);
129+
130+
const getRequest = objectStore.get(key);
131+
132+
const onTxnError = (err) => txnObserver.error(err);
133+
const onTxnComplete = () => txnObserver.complete();
134+
const onRecordFound = (ev) => txnObserver.next(getRequest.result);
135+
136+
txn.addEventListener(IDB_COMPLETE, onTxnComplete);
137+
txn.addEventListener(IDB_ERROR, onTxnError);
138+
139+
getRequest.addEventListener(IDB_SUCCESS, onRecordFound);
140+
getRequest.addEventListener(IDB_ERROR, onTxnError);
141+
142+
return () => {
143+
getRequest.removeEventListener(IDB_SUCCESS, onRecordFound);
144+
getRequest.removeEventListener(IDB_ERROR, onTxnError);
145+
txn.removeEventListener(IDB_COMPLETE, onTxnComplete);
146+
txn.removeEventListener(IDB_ERROR, onTxnError);
147+
}
148+
149+
});
150+
});
151+
}
152+
153+
query(storeName:string, predicate?:(rec:any) => boolean){
154+
return this.open(this._schema.name)
155+
.mergeMap(db => {
156+
return new Observable(txnObserver => {
157+
const txn = db.transaction([storeName], IDB_TXN_READ);
158+
const objectStore = txn.objectStore(storeName);
159+
160+
const getRequest = objectStore.openCursor();
161+
162+
const onTxnError = (err) => txnObserver.error(err);
163+
const onRecordFound = (ev) => {
164+
let cursor = ev.target.result;
165+
if(cursor){
166+
if(predicate){
167+
const match = predicate(cursor.value);
168+
if(match){
169+
txnObserver.next(cursor.value);
170+
}
171+
}
172+
else{
173+
txnObserver.next(cursor.value);
174+
}
175+
cursor.continue();
176+
}
177+
else {
178+
txnObserver.complete();
179+
}
180+
}
181+
182+
txn.addEventListener(IDB_ERROR, onTxnError);
183+
184+
getRequest.addEventListener(IDB_SUCCESS, onRecordFound);
185+
getRequest.addEventListener(IDB_ERROR, onTxnError);
186+
187+
return () => {
188+
getRequest.removeEventListener(IDB_SUCCESS, onRecordFound);
189+
getRequest.removeEventListener(IDB_ERROR, onTxnError);
190+
txn.removeEventListener(IDB_ERROR, onTxnError);
191+
}
192+
193+
});
194+
});
195+
}
196+
123197
executeWrite(storeName:string, actionType:string, records:any[]){
124198
const changes = this.changes;
125199
return this.open(this._schema.name)

0 commit comments

Comments
 (0)