Html5 IndexedDB - get value by its key

Most turingarias show how to extract all records from the object store, iterate over them with the cursor. But how do you retrieve a value from the object store by its key "myKey"?

+4
source share
2 answers

If you are looking for a simple key / value store, you can consider localStorage . This is much simpler than using IndexedDB. It only works with strings (for now), but objects are easily pulled through a JSON object.

 console.log( 'BEFORE', localStorage.getItem( 'test-key' ) ); localStorage.setItem( 'test-key', JSON.stringify( { 'foo': Math.round( Math.random() * 1000 ) } ) ); console.log( 'AFTER', JSON.parse( localStorage.getItem( 'test-key' ) ) ); 

However, you do not need a cursor to get a single value from a key in IndexedDB, only if you need to get multiple values ​​for a key or range of keys. To get a value from a key, you do one of two things:

1) If myKey is your primary key (added when creating the store):

 var request = transaction.get( key ); 

You can then add the onsuccess and onerror to parse the resulting event object from which you want to extract the value of event.target.result .

2) If myKey is in a non-primary index (which you added after creating the repository), you open the index in your transaction and then open the cursor in the index.

 var transaction_index = transaction.index( index ); var request = transaction_index.get( key ); 

As for cursors (which are likely to be discussed more often because you will need it every time you have several values ​​stored under the same key), you can use them to get values ​​for the same key. Speaks specification :

A range of keys may consist of a single value.

You need to create keyRange using the IDBKeyRange object. Here's a helper method for a MIT-licensed InDB (my incomplete version of IndexedDB) that handles opening the cursor on a single value (for example, InDB.range.get( value ) ) or a range of keys.

 InDB.range.get = function ( value, left_bound, right_bound, includes_left_bound, includes_right_bound ) { if ( InDB.exists( left_bound ) && InDB.exists( right_bound ) && InDB.exists( includes_left_bound ) && InDB.exists( includes_right_bound ) ) { return IDBKeyRange.bound( left_bound, right_bound, includes_left_bound, includes_right_bound ); } else if ( InDB.exists( left_bound ) && InDB.exists( includes_left_bound ) ) { return IDBKeyRange.lowerBound( left_bound, includes_left_bound ); } else if ( InDB.exists( right_bound ) && InDB.exists( includes_right_bound ) ) { return IDBKeyRange.upperBound( right_bound, includes_right_bound ); } else if ( InDB.exists( value ) ) { return IDBKeyRange.only( value ); } else { return false; } } 

Once you have keyRange , you will do one of two keyRange :

1) If myKey is your primary key (added when creating the store), you open a regular cursor for your transaction (with an additional direction).

 var request = transaction.openCursor( keyRange, direction ); 

2) If myKey is in a non-primary index (which you added after creating the repository), you open the index in your transaction and then open the cursor in the index.

 var transaction_index = transaction.index( index ); var request = transaction_index.openCursor( keyRange, direction ); 
+5
source

There are some libraries that can help you use IndexedDB, such as Dexie , JsStore , LocalForage and SFDatabase-js .

This is easier for me with SFDatabase-js, because the use is almost the same as the PHP version when using MySQL / Redis as the database. This also works for NodeJS. All you need to do is determine the structure of the database indexes and initialize the database.

 var myDB = new SFDatabase('myDB', { websql:false, idbVersion:1, databaseStructure:{ Users:{ // rowid -> always unique and incremental name:['text', 'unique'] } } }, function(){ // database initialized }); 

And after that you can store almost everything in the database.

 myDB.insert('Users', {name:"Alex", age:17}); myDB.insert('Users', {name:"Ander", age:12}); myDB.insert('Users', {name:"Bell", age:30, admin:true}); 

If you like to receive single-row data, you can use get .

 myDB.get('Users', 'age', {name:"Ander"}, console.log); //-> 12 myDB.get('Users', ['name', 'age'], {admin:true}, console.log); //-> {name:"Bell", age:30} 

As well as obtaining multi-line data.

 // Age more than 15 myDB.select('Users', ['name'], {'age[>]':15}, console.log); //-> [{name: "Alex"}, {name: "Bell"}] // Any name with 'e' and without 'A', and limit to two result myDB.select('Users', ['name'], {'name[~]':'e', 'name[!~]'=>'A', LIMIT:2}, console.log); //-> [{name: "Bell"}] 
0
source

Source: https://habr.com/ru/post/1382872/


All Articles