Basic IndexedDB wrapper.
var db = new dbproto("database_name", 12, $q)
db.upgradeHook = event => {
//onupgrade hook goes here
}
db.query("my_store").then(r => console.log(r))
Currently dbproto
is defined as a global variable.
(NEW) Now also suports UMD require('dbproto')
.
constructor(name:string,version:string,promise?:any)
promise
allows you to pass Angular's $q
(or any other promise implementation), so that db operations trigger a scope digest.
upgradeHook(event:IDBVersionChangeEvent)
Wraps IDBOpenRequest:onupgradeneeded
.
query(objstore:string, queryOptions?:DbQueryOptions):Promise<any[]>
Everything query.
db.query("object_store").then(r => console.log(r))
Gets the whole object store.
OPTIONAL:
interface DbQueryOptions {
//define a function to filter each output
filterFunc?: (input: any) => boolean
//use a index
index?: string
//use a key range
keyRange?: IDBKeyRange
}
db
.query("object_store", { index: "my_index", keyRange: IDBKeyRange.only(123) })
.then(r => console.log(r))
getObject(objstore:string, id:string|number|any[]):Promise<any>
Gets a single object, based on the primary key (keypath).
getByIndex(store_name:string, indexName:string, value:IDBKeyRange|string|number|string[]|number[]):Promise<any[]>
Queries some index. If the parameter is not an IDBKeyRange, we wrap it with IDBKeyRange.only
.
upsert(storename:string, inputobj:any|any[], ignoreError:boolean = true):Promise<any>
Inserts/replaces objects. ignoreError
controls whether the whole transaction is aborted
or if just an error is logged when problems like failed constraints arise.
deleteObject(store_name:string, key:number|string|any[]):Promise<any>
Removes an entry(ies) based on the key path.
clearAll(storeNames?:string[]):Promise<any>
Clears the selected object stores (all stores on no parameter passed).
load():Promise<any>
Load is internally called in all the other methods. You don't need to call it.
deleteDatabase(name:string)
augmentJoin(srcObject:any, joinBy:JoinSpec[]|JoinSpec) : Promise<any>
Transforms an object, replacing fields with query results. Just in case stores have some relational-like structure...
export interface JoinSpec {
//the field which will have the queried data injected
sourceContainer: string
//the field which data will be passed to the query
//if empty, used sourceContainer
sourceField?: any
//the store to be queried
destStore: string | ((store: any) => string)
//the index from the queried store. Gets key path if empty.
destIndex?: string
cardinality: Cardinality
}
Example
src = {
customerId : 123 ,
customer : null ,
phoneNumbers : null
}
db.augmentJoin(src,[
{ sourceContainer : 'customer' , sourceField : 'customerId' ,
destStore : 'customer_store' , cardinality : dbproto.Cartinality.ONE } ,
{ sourceContainer : 'phoneNumbers' , sourceField : 'customerId' ,
destStore : 'customer_phone' , destIndex : 'customer_id' ,
cardinality : dbproto.Cardinality.MANY }
]).then( ... )
===>
{
customerId : 123 ,
customer : { name : 'John' } ,
phoneNumbers : [{ phone : 1234 } , { phone : 4567 }]
}
You are required to extend the interface Stores
inside the global scope DbProtoTypes
.
declare global {
namespace DbProtoTypes {
export interface Stores {
names: { first: string; second: string }
cats: { color: string; size: number }
}
}
}
const cat = await db.getObject("cats") //will have the cat type inferred
We try to use the indexed DB shim when on IOS or safari. It must be previously loaded for that.