2

if I try to override an existing indexed field, I do not get an error. It should error, because it is not update()!

var loki = require('lokijs');
var db = new loki('test.json');
var users = db.addCollection('users', { indices: ['userID']});
users.insert(
   {
     'name': 'Anna',
     'userID': 1
   },
   {
     'name': 'Bernd',
     'userID': 2
   },
   {
     'name': 'Christa',
     'userID': 3
   });
db.save();
users.insert({'name': 'Dieter','userID': 2}); // this should error!!

How can I make an unique index to get an error when trying to inset an existing userID ?

Danny
  • 1,078
  • 7
  • 22

2 Answers2

1

the indices option creates an index on the field, which allows for faster retrieval because the index lives in a separate sorted array within the collection (so Loki can use binary-search instead of a full loop to fetch records). However, you're looking for a unique index, which is created with ensureUniqueIndex (check here, scroll down to Finding Documents, there's a section on unique indexes.). With that, you can use the collection method by(field, value) (which can even be curried if you only pass the field value), which uses the unique index to full potential (about 2x the speed of an indexed field). Remember that you need to explicitly call ensureUniqueIndex because unique indexes cannot be serialized and persisted.

update: once the ensureUniqueIndex method is called, the collection will throw an error if you try to insert a duplicate key record. If you have repository checked out you can take a look at spec/generic/unique.spec.js for an example ( here )

Joe Minichino
  • 2,793
  • 20
  • 20
  • 1
    The question was about **WRITE** unique index. I need to get back a database-error if I try to **insert** an existing value to an indexed field. – Danny Jul 06 '15 at 09:28
  • 1
    @Danny see my update. Sorry I forgot to specify the detail you were actually looking for. – Joe Minichino Jul 06 '15 at 11:20
  • 1
    I cannot catch the thrown "Duplicate" error :( ... I will post my code in a new answer – Danny Jul 06 '15 at 12:40
  • 2
    It looks like you are the maintainer :-) ... the documentation needs a rework I think. It is hard to find your way without reading the code. I tried to fix the bug locally by adding try catch on several parts of `src/lokijs.js` but the scope doesn't chain. So that thrown error is not noticed! I cannot fix this bug myself (I tried!). – Danny Jul 06 '15 at 12:51
  • 2
    @Danny maybe it's worth opening an issue on github – Joe Minichino Jul 06 '15 at 13:22
0
var loki = require('lokijs');
var db = new loki('test.json');
var users = db.addCollection('users', { indices: ['userID']});
users.ensureUniqueIndex('userID');

users.on('error',function(obj){
  console.log('error ... adding 1 to userID');
  obj.userID = obj.userID+1;
  return obj;
});
users.insert(
   {
     'name': 'Anna',
     'userID': 1
   });
users.insert(
    {
     'name': 'Bernd',
     'userID': 2
   });
users.insert(   
  {
     'name': 'Christa',
     'userID': 3
   });
db.save();
console.log(users.data);
try {
users.insert({'name': 'Dieter','userID': 2}); // this should error!!

} catch(e){
  var i = 2+1;
  users.insert({'name': 'Dieter','userID': i}); // this should error!!

}
db.save();
db2 = new loki('test.json');
db2.loadDatabase({}, function () {
  var users2 = db2.getCollection('users')
  console.log(users2.data);
});

Either users.on('error',...) nor try{ users.insert...} catch(e){// id+1} handles the thrown error

That's my console:

[ { name: 'Anna',
    userID: 1,
    meta: { revision: 0, created: 1436186694342, version: 0 },
    '$loki': 1 },
  { name: 'Bernd',
    userID: 2,
    meta: { revision: 0, created: 1436186694342, version: 0 },
    '$loki': 2 },
  { name: 'Christa',
    userID: 3,
    meta: { revision: 0, created: 1436186694342, version: 0 },
    '$loki': 3 } ]
Duplicate key for property userID: 2
[ { name: 'Anna',
    userID: 1,
    meta: { revision: 0, created: 1436186694342, version: 0 },
    '$loki': 1 },
  { name: 'Bernd',
    userID: 2,
    meta: { revision: 0, created: 1436186694342, version: 0 },
    '$loki': 2 },
  { name: 'Christa',
    userID: 3,
    meta: { revision: 0, created: 1436186694342, version: 0 },
    '$loki': 3 },
  { name: 'Dieter',
    userID: 2,
    meta: { revision: 0, created: 0, version: 0 },
    '$loki': 4 } ]
Danny
  • 1,078
  • 7
  • 22