Browse Source

Auto-join based on column information

for usage please see test/dialects/join-to-tests.js
auto-join
Brian Carlson 12 years ago
parent
commit
2b010dd7be
  1. 39
      lib/joiner.js
  2. 6
      lib/table.js
  3. 54
      test/dialects/join-to-tests.js

39
lib/joiner.js

@ -0,0 +1,39 @@
var getPrimaryKeyColumn = function(table) {
for(var i = 0; i < table.columns.length; i++) {
var col = table.columns[i];
if(col.primaryKey) {
return col;
}
}
};
var findReference = function(left, right) {
//find reference
for(var i = 0; i < right.columns.length; i++) {
var col = right.columns[i];
if(col.references) {
var leftName = left.getName();
if(col.references == leftName || col.references.table == leftName) {
var leftCol = left[col.references.column] || getPrimaryKeyColumn(left);
return {
left: leftCol,
right: col
};
}
}
}
};
module.exports = {
//auto-join two tables based on column properties
//requires one column to have { references: {table: 'foreignTableName', column: 'foreignColumnName'}}
//or to have { references: 'foreignTableName'} -- in which case the foreign table's primary key is assumed
leftJoin: function(left, right) {
var leftCol, rightCol;
var ref = findReference(left, right);
if(!ref) {
ref = findReference(right, left);
}
return left.join(right).on(ref.left.equals(ref.right));
}
}

6
lib/table.js

@ -6,6 +6,7 @@ var Query = require(__dirname + '/node/query');
var Column = require(__dirname + '/column');
var TableNode = require(__dirname + '/node/table');
var JoinNode = require(__dirname + '/node/join');
var Joiner = require(__dirname + '/joiner');
var Table = function(config) {
this._schema = config.schema;
@ -170,6 +171,11 @@ Table.prototype.leftJoin = function(other) {
return new JoinNode('LEFT', this.toNode(), other.toNode());
};
//auto-join tables based on column intropsection
Table.prototype.joinTo = function(other) {
return Joiner.leftJoin(this, other);
};
Table.prototype.as = function(alias) {
//TODO could this be cleaner?
var t = Table.define(this._initialConfig);

54
test/dialects/join-to-tests.js

@ -0,0 +1,54 @@
'use strict';
var sql = require(__dirname + '/../../lib');
var Harness = require('./support');
var user = sql.define({
name: 'user',
columns: {
id: { primaryKey: true }
}
});
var photo = sql.define({
name: 'photo',
columns: {
ownerId: {
references: 'user'
}
}
});
var post = sql.define({
name: 'post',
columns: {
id: { primaryKey: true },
ownerId: {
references: {
table: 'user',
column: 'id'
}
}
}
});
Harness.test({
query : user.joinTo(post),
pg : '"user" INNER JOIN "post" ON ("user"."id" = "post"."ownerId")',
sqlite: '"user" INNER JOIN "post" ON ("user"."id" = "post"."ownerId")',
mysql : '`user` INNER JOIN `post` ON (`user`.`id` = `post`.`ownerId`)'
});
Harness.test({
query : post.joinTo(user),
pg : '"post" INNER JOIN "user" ON ("user"."id" = "post"."ownerId")',
sqlite: '"post" INNER JOIN "user" ON ("user"."id" = "post"."ownerId")',
mysql : '`post` INNER JOIN `user` ON (`user`.`id` = `post`.`ownerId`)'
});
Harness.test({
query : user.joinTo(photo),
pg : '"user" INNER JOIN "photo" ON ("user"."id" = "photo"."ownerId")',
sqlite: '"user" INNER JOIN "photo" ON ("user"."id" = "photo"."ownerId")',
mysql : '`user` INNER JOIN `photo` ON (`user`.`id` = `photo`.`ownerId`)'
});
Loading…
Cancel
Save