Search code examples
javascriptweb-sqllawnchair

Why does Lawnchair's webkit-sqlite adapter converts key to string?


I got a problem on webkit-sqlite adapter. It somehow saves the key on a string format rather than integer. Indexed-db works just fine. It won't convert the key to string. Please see the code below.

var ppl = Lawnchair({adapter: 'webkit-sqlite', name:'people', record:'person'}, function(people) {
    // anon fn bound to the instance
    this.save({key:1, id:1, a:1, name:'nino'}, function(obj){
        console.log(obj);
    });

    // anon fn bound to the instance
    this.save({key:'2', id:2, a:2, name:'paolo'}, function(obj){
        console.log(obj);
   });

    // get all the keys
    this.keys(function(keys) {
        console.log('keys:', keys);
    });

    // get 1
    this.get(1, function(key) {
        console.log('key:', key);
    });

    // get '2'
    this.get('2', function(key) {
        console.log('key:', key);
    });

    // we can also clear the entire collection w/ nuke
    this.nuke()
});

Output:

undefined
Object {key: 1, id: 1, a: 1, name: "nino"}
Object {key: "2", id: 2, a: 2, name: "paolo"}
keys: ["1.0", "2"]
key: undefined
key: Object {key: "2", id: 2, a: 2, name: "paolo"}

Error:

See keys: ["1.0", "2"] it supposed to be keys: [1, "2"]

Does anyone have patch for this?

Thanks.


Solution

  • Ironically, I had exactly the same problem today experimenting with lawnchair. I ultimately decided to modify the webkit-sqlite adapter to add/edit lines for converting the key values to strings before they are passed to the db. The problem stems from the fact that the field being used (in this case id) for the lawnchair key value has to be establish as an NVARCHAR(32) data type, which for compatibility reasons makes sense. Keep in mind that you could use the webkit-sqlite db with an integer based id field, but then trying to integrate this with lawnchair would be complicated or impossible. My solution was to convert the numeric values to strings before they get passed to the db. This can be done without modifying the adapter, but for my purposes I wanted to use the integers as integers when indexeddb is available.

    Here is a link to my code: http://wemarketyour.com/lawnchair-using-indexeddb-websql-dom-localstorage-adapters/

    The lines with my code modification in the webkit-sqlite adapter are highlighted. The difference with my version is that, while still converting to strings, the data is preserved. So instead of int 1 => string "1.0", you get int 1 => string "1". Later when you retrieve the data you can convert the key back to an integer with parseInt(key).