Skip to content

Commit

Permalink
Unique index support
Browse files Browse the repository at this point in the history
  • Loading branch information
sylvinus committed Dec 2, 2010
1 parent 495d05e commit bb7fe5b
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 13 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,11 @@ It is possible to create indexes on one or more columns using
`EntityName.index`, for instance:

Task.index('done');
Task.index('done', 'name');
Task.index(['done', 'name']);

These indexes can also be used to impose unique constraints :

Task.index(['done', 'name'],{unique:true});

Relationships between entities are defined using the constructor
function's `hasMany` call:
Expand Down Expand Up @@ -391,8 +395,9 @@ all
for a particular object based on a property value (this is assumed to
be unique), the callback function is called with the found object or
`null` if it has not been found.
* `EntityName.index(col1, col2, ..., colN)` creates an index on a column
of a combination of columns, for faster searching.
* `EntityName.index([col1, col2, ..., colN], options)` creates an index on a column
of a combination of columns, for faster searching. If options.unique is true,
the index will impose a unique constraint on the values of the columns.

And of course the methods to define relationships to other entities:

Expand Down
11 changes: 6 additions & 5 deletions lib/persistence.js
Original file line number Diff line number Diff line change
Expand Up @@ -830,12 +830,13 @@ persistence.get = function(arg1, arg2) {
}


Entity.index = function(col1, col2, colN) {
var cols = [];
for(var i = 0; i < arguments.length; i++) {
cols.push(arguments[i]);
Entity.index = function(cols,options) {
var opts = options || {};
if (typeof cols=="string") {
cols = [cols];
}
meta.indexes.push(cols);
opts.columns = cols;
meta.indexes.push(opts);
};

/**
Expand Down
5 changes: 3 additions & 2 deletions lib/persistence.store.mysql.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@ exports.config = function(persistence, hostname, port, db, username, password) {

// columns is array of column names, e.g.
// ["id"]
createIndex: function(tableName, columns) {
return "CREATE INDEX `" + tableName + "__" + columns.join("_") +
createIndex: function(tableName, columns, options) {
options = options || {};
return "CREATE "+(options.unique?"UNIQUE ":"")+"INDEX `" + tableName + "__" + columns.join("_") +
"` ON `" + tableName + "` (" +
columns.map(function(col) { return "`" + col + "`"; }).join(", ") + ")";
}
Expand Down
2 changes: 1 addition & 1 deletion lib/persistence.store.sql.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ persistence.store.sql.config = function(persistence, dialect) {
}
}
for (var i = 0; i < meta.indexes.length; i++) {
queries.push([dialect.createIndex(meta.name, meta.indexes[i]), null]);
queries.push([dialect.createIndex(meta.name, meta.indexes[i].columns, meta.indexes[i]), null]);
}
}
for (var rel in meta.hasMany) {
Expand Down
5 changes: 3 additions & 2 deletions lib/persistence.store.websql.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,9 @@ persistence.store.websql.config = function(persistence, dbname, description, siz

// columns is array of column names, e.g.
// ["id"]
createIndex: function(tableName, columns) {
return "CREATE INDEX IF NOT EXISTS `" + tableName + "__" + columns.join("_") +
createIndex: function(tableName, columns, options) {
options = options || {};
return "CREATE "+(options.unique?"UNIQUE ":"")+"INDEX IF NOT EXISTS `" + tableName + "__" + columns.join("_") +
"` ON `" + tableName + "` (" +
columns.map(function(col) { return "`" + col + "`"; }).join(", ") + ")";
}
Expand Down
71 changes: 71 additions & 0 deletions test/test.persistence.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ $(document).ready(function(){
var Tag = persistence.define('Tag', {
name: "TEXT"
});

var UniqueIndexTest = persistence.define('UniqueIndexTest', {
id1: "INT",
id2: "INT",
id3p1: "INT",
id3p2: "INT"
});

UniqueIndexTest.index('id1');
UniqueIndexTest.index('id2',{unique:true});
UniqueIndexTest.index(['id3p1','id3p2'],{unique:true});


Task.hasMany('tags', Tag, 'tasks');
Tag.hasMany('tasks', Task, 'tags');
Expand All @@ -31,6 +43,8 @@ $(document).ready(function(){
window.Project = Project;
window.Task = Task
window.Project = Project;
window.UniqueIndexTest = UniqueIndexTest;


module("Setup");

Expand Down Expand Up @@ -624,4 +638,61 @@ $(document).ready(function(){
});
});
});



module("Indexes");


asyncTest("unique indexes", function() {

persistence.reset(function() {

persistence.schemaSync(function() {

var o1 = new UniqueIndexTest({"id1":101,"id2":102,"id3p1":103,"id3p2":104});

// id1 is not unique
var o2 = new UniqueIndexTest({"id1":101,"id2":202,"id3p1":203,"id3p2":204});

//shouldn't work, id2 is unique
var o3 = new UniqueIndexTest({"id1":301,"id2":102,"id3p1":303,"id3p2":304});

// id3p1 itself is not unique
var o4 = new UniqueIndexTest({"id1":401,"id2":402,"id3p1":103,"id3p2":404});

//shouldn't work, id3p1+id3p2 are unique
var o5 = new UniqueIndexTest({"id1":501,"id2":502,"id3p1":103,"id3p2":104});


persistence.add(o1);
persistence.add(o2);
try {
persistence.add(o3);
} catch (e) {
console.log("err",e);
}

persistence.add(o4);
try {
//persistence.add(o5);
} catch (e) {
console.log("err",e);
}


UniqueIndexTest.all().order("id2",true).list(function(results) {
console.log("HAA");
equals(3,results.length,"skipped 2 duplicate rows");
if (results.length==3) {
equals(102,results[0].id2);
equals(202,results[1].id2);
equals(402,results[2].id2);
}
start();
});
});
});
});

});

0 comments on commit bb7fe5b

Please sign in to comment.