Skip to content

Commit

Permalink
feat(db): simple foreign key constraint in CREATE TABLE
Browse files Browse the repository at this point in the history
Signed-off-by: KSD <[email protected]>
  • Loading branch information
kremio committed Jul 31, 2018
1 parent bf2e7c4 commit 3b81f0a
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 16 deletions.
27 changes: 22 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,21 @@ var Sqlite3Driver = Base.extend({
callback(null);
},

createColumnDef: function(name, spec, options) {
name = '"' + name + '"';
createColumnDef: function(name, spec, options, tableName) {
var quotedName = '"' + name + '"';
var dType = this.mapDataType(spec.type);
var len = spec.length ? util.format('(%s)', spec.length) : '';
var constraint = this.createColumnConstraint(spec, options);
var constraint = this.createColumnConstraint(spec, options, tableName, name);

if(spec.type === type.INTEGER)
len = '';

return { foreignKey: null,
constraints: [name, dType, len, constraint].join(' ') };
constraints: [quotedName, dType, len, constraint].join(' ') };
},

createColumnConstraint: function(spec, options) {
createColumnConstraint: function(spec, options, tableName, columnName) {
var cb;
var constraint = [];
if (spec.primaryKey && options.emitPrimaryKey) {
constraint.push('PRIMARY KEY');
Expand All @@ -95,6 +96,22 @@ var Sqlite3Driver = Base.extend({
constraint.push(spec.defaultValue);
}

if (spec.foreignKey) {
constraint.push(`REFERENCES ${spec.foreignKey.table}(${spec.foreignKey.mapping})`)
if( spec.foreignKey.rules ){
Object.keys(spec.foreignKey.rules)
.forEach( (rule) => {
switch(rule){
case 'onDelete': constraint.push(`ON DELETE ${spec.foreignKey.rules[rule]}`)
break
case 'onUpdate': constraint.push(`ON UPDATE ${spec.foreignKey.rules[rule]}`)
break
default: throw new Error('Unsupported foreign key action trigger: ' + rule )
}
})
}
}

return constraint.join(' ');
},

Expand Down
77 changes: 77 additions & 0 deletions test/foreign_key_batch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const dbmeta = require('db-meta')
const dataType = require('db-migrate-shared').dataType
const fs = require('fs')
const assert = require('assert')

module.exports = (driver, config, internals) => ({
'columnForeignKeySpec': {
topic: function () {
driver.connect(config, internals, function (err, db) {
db.createTable('event_type', {

id: { type: dataType.INTEGER, primaryKey: true, autoIncrement: true },
title: { type: dataType.STRING }
}, function(err) {
if (err) {
return this.callback(err);
}
db.createTable('event', {
id: {
type: dataType.INTEGER,
primaryKey: true,
autoIncrement: true
},
event_type_id: {
type: dataType.INTEGER,
notNull: true,
foreignKey: {
name: 'fk_event_event_type',
table: 'event_type',
mapping: 'id',
rules: {
onDelete: 'CASCADE'
},
} },
title: {
type: dataType.STRING
}
}, this.callback.bind(this, null, db));
}.bind(this));
}.bind(this))
},

teardown: function(db) {
db.close(function (err) {
fs.unlink(config.filename, this.callback);
}.bind(this));
},

'sets usage and constraints': {
topic: function (db) {
dbmeta('sqlite3', {connection: db.connection}, function (err, meta) {
if (err) {
return this.callback(err);
}
meta.getTables( (err, tables) => {
if (err) {
return this.callback(err)
}
this.callback( undefined, tables.find( (table) => table.getName() == "event" ) )
})
}.bind(this));
},
'that has foreign key column with the expected reference': function (err, table) {
const foreignKeyDefinition = table.meta
.sql
.match(/"event_type_id"[^,]+/)[0]
.replace(/\s{2,}/g,' ')

assert.equal(
foreignKeyDefinition,
'"event_type_id" INTEGER NOT NULL REFERENCES event_type(id) ON DELETE CASCADE'
)
}

}
}
})
25 changes: 14 additions & 11 deletions test/sqlite3_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ var driver = require('../');

var config = require('./db.config.json').sqlite3;

var foreignKeyBatch = require('./foreign_key_batch')

var internals = {};
internals.mod = {
log: log,
Expand Down Expand Up @@ -38,7 +40,7 @@ vows.describe('sqlite3').addBatch({
teardown: function (db) {
db.close(function (err) {
fs.unlink(config.filename, this.callback);
});
}.bind(this));
},

'has resulting table metadata': {
Expand Down Expand Up @@ -138,7 +140,7 @@ vows.describe('sqlite3').addBatch({
teardown: function (db) {
db.close(function (err) {
fs.unlink(config.filename, this.callback);
});
}.bind(this));
},

'has table metadata': {
Expand Down Expand Up @@ -172,7 +174,7 @@ vows.describe('sqlite3').addBatch({
teardown: function (db) {
db.close(function (err) {
fs.unlink(config.filename, this.callback);
});
}.bind(this));
},

'has table metadata': {
Expand Down Expand Up @@ -208,7 +210,7 @@ vows.describe('sqlite3').addBatch({
teardown: function (db) {
db.close(function (err) {
fs.unlink(config.filename, this.callback);
});
}.bind(this));
},

'has column metadata': {
Expand Down Expand Up @@ -249,7 +251,7 @@ vows.describe('sqlite3').addBatch({
teardown: function (db) {
db.close(function (err) {
fs.unlink(config.filename, this.callback);
});
}.bind(this));
},

'has resulting index metadata': {
Expand Down Expand Up @@ -287,7 +289,7 @@ vows.describe('sqlite3').addBatch({
teardown: function (db) {
db.close(function (err) {
fs.unlink(config.filename, this.callback);
});
}.bind(this));
},

'with additional row': function (db) {
Expand All @@ -312,7 +314,7 @@ vows.describe('sqlite3').addBatch({
teardown: function (db) {
db.close(function (err) {
fs.unlink(config.filename, this.callback);
});
}.bind(this));
},

'with additional row': function (db) {
Expand All @@ -339,7 +341,7 @@ vows.describe('sqlite3').addBatch({
teardown: function (db) {
db.close(function (err) {
fs.unlink(config.filename, this.callback);
});
}.bind(this));
},

'has resulting index metadata': {
Expand Down Expand Up @@ -376,7 +378,7 @@ vows.describe('sqlite3').addBatch({
teardown: function (db) {
db.close(function (err) {
fs.unlink(config.filename, this.callback);
});
}.bind(this));
},

'has resulting index metadata': {
Expand Down Expand Up @@ -406,7 +408,7 @@ vows.describe('sqlite3').addBatch({
teardown: function (db) {
db.close(function (err) {
fs.unlink(config.filename, this.callback);
});
}.bind(this));
},

'has migrations table': {
Expand Down Expand Up @@ -452,7 +454,8 @@ vows.describe('sqlite3').addBatch({
}
}
}
}).export(module);
}).addBatch( foreignKeyBatch(driver, config, internals) )
.export(module);

function findByName(columns, name) {
for (var i = 0; i < columns.length; i++) {
Expand Down

0 comments on commit 3b81f0a

Please sign in to comment.