OR or IN in IndexedDB

Is there a way to make an OR or IN query on the same property in IndexedDB?

Another word, how do I get results for

SELECT * FROM MyTable WHERE columnA IN ('ABC','DFT') AND columnB = '123thd'

Thank!

+4
source share
4 answers

It is impossible to make a request ORor IN-like out of the box without using multiple requests. Typically, the template for such problems is "on reaching the goal, pulling out more records than you need, and filter them to exact matches."

The Chrome team has proposed a openKeyCursor()as a solution for this kind of request (thanks to a proposal from Kyaw Tun , a member of SO and the author of ydn ), but this is not standard and is not accepted in other browsers.

, , # 4 w3:

  • columnB, '123thd'
  • , columnA "ABC" "DFT"

, , columnB "123thd", , "ABC" "DFT" , - columnA w/value "ABC" , - "DFT" . , .

+5

2 :

  • A columnB. . .
  • ['ABC', '123thd'] .
  • ['DFT', '123thd'] .

1 :

, , . , SQL. , , , indexedDB. .

// In onupgradeneeded
function myOnUpgradeNeeded(event) {
  var db = event.target.result;
  var store = db.createObjectStore('MyTable');

  // Create a compound index on the derived property of columnA
  // and the normal property of columnB
  store.createIndex('A_ABC_OR_DFT_AND_B', ['ABC_OR_DFT_FLAG','columnB']);
}


function wrappedPut(db, obj, callback) {
  // Set the flag property
  // indexedDB cannot index booleans, so we use simple integer representation
  // where 1 represents true, 0 represents false. But we can go further since
  // we know that undefined properties dont appear in the index.

 if(obj.columnA=='ABC'||obj.columnA=='DFT') {
   obj.ABC_OR_DFT_FLAG = 1;
 } else {
   delete obj.ABC_OR_DFT_FLAG;
 }

 put(db, obj, callback);
}

// In your add/update function
function put(db, obj, callback) {
 db.transaction('MyTable','readwrite').objectStore('myTable').put(obj).onsuccess = callback;
}

// Voila, a single efficient high speed query over all items 
// in MyTable where columnA is ABC or DFT and where columnB 
// is 123thd, using a single index, without using a 3rd party
// library, and without doing some horrible double cursor stuff
// in javascript, and just using the indexedDB API.
function runTheABCDFT123Query(db, onSuccess, onComplete) {
  var tx = db.transaction('MyTable');
  tx.onComplete = onComplete;
  tx.objectStore('MyTable').index('A_ABC_OR_DFT_AND_B').openCursor(
    IDBKeyRange.only([1,'123thd'])).onsuccess = function(event) {
    if(event.target) {
      onSuccess(event.target.value);
      event.target.continue();
    }
  };
}
+1

API DB. . , indexedDB API. .

0
source

This is a simple query equivalent to your sql query using the JsStore Library

var Connection = new JsStore.Instance("MyDatabase");
Connection.select({
    From: "MyTable",
    Where:{
        columnA : {In:['ABC','DFT')]},
        columnB : '123thd'
    },
    OnSuccess:function (results){
        console.log(results);
    },
    OnError:function (error) {
        console.log(error);
    }
});

Hope this saves you time and code :).

0
source

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


All Articles