不要怂,就是干,撸起袖子干!

Commit 644f6eff by Martin Aspeli

Support for foreign keys in creating tables

1 parent 750817c5
......@@ -45,6 +45,7 @@ module.exports = (function() {
var query = "CREATE TABLE IF NOT EXISTS <%= table %> (<%= attributes%>) ENGINE=<%= engine %> <%= charset %>"
, primaryKeys = []
, foreignKeys = {}
, attrStr = []
for (var attr in attributes) {
......@@ -54,6 +55,11 @@ module.exports = (function() {
if (Utils._.includes(dataType, 'PRIMARY KEY')) {
primaryKeys.push(attr)
attrStr.push(QueryGenerator.addQuotes(attr) + " " + dataType.replace(/PRIMARY KEY/, ''))
} else if (Utils._.includes(dataType, 'REFERENCES')) {
// MySQL doesn't support inline REFERENCES declarations: move to the end
var m = dataType.match(/^(.+) (REFERENCES.*)$/)
attrStr.push(QueryGenerator.addQuotes(attr) + " " + m[1])
foreignKeys[attr] = m[2]
} else {
attrStr.push(QueryGenerator.addQuotes(attr) + " " + dataType)
}
......@@ -72,6 +78,12 @@ module.exports = (function() {
values.attributes += ", PRIMARY KEY (" + pkString + ")"
}
for (var fkey in foreignKeys) {
if(foreignKeys.hasOwnProperty(fkey)) {
values.attributes += ", FOREIGN KEY (" + QueryGenerator.addQuotes(fkey) + ") " + foreignKeys[fkey]
}
}
return Utils._.template(query)(values).trim() + ";"
},
......@@ -438,6 +450,27 @@ module.exports = (function() {
template += " PRIMARY KEY"
}
if(dataType.references) {
template += " REFERENCES " + Utils.escape(dataType.references)
if(dataType.referencesKeys) {
// TODO: This isn't really right - for composite primary keys we need a different approach
template += "(" + dataType.referencesKeys.map(Utils.escape).join(', ') + ")"
} else {
template += "(" + Utils.escape('id') + ")"
}
if(dataType.onDelete) {
template += " ON DELETE " + dataType.onDeleteAction.toUpperCase()
}
if(dataType.onUpdate) {
template += " ON UPDATE " + dataType.onUpdateAction.toUpperCase()
}
}
result[name] = template
} else {
result[name] = dataType
......
......@@ -62,7 +62,7 @@ module.exports = (function() {
var values = {
table: QueryGenerator.addQuotes(tableName),
attributes: attrStr.join(", "),
attributes: attrStr.join(", ")
}
var pks = primaryKeys[tableName].map(function(pk){
......@@ -556,6 +556,29 @@ module.exports = (function() {
template += " PRIMARY KEY"
}
if(dataType.references) {
template += " REFERENCES <%= referencesTable %> (<%= referencesKeys %>)"
replacements.referencesTable = dataType.references
if(dataType.referencesKeys) {
// TODO: This isn't really right - for composite primary keys we need a different approach
replacements.referencesKeys = dataType.referencesKeys.map(Utils.escape).join(', ')
} else {
replacements.referencesKeys = Utils.escape('id')
}
if(dataType.onDelete) {
template += " ON DELETE <%= onDeleteAction %>"
replacements.onDeleteAction = dataType.onDeleteAction.toUpperCase()
}
if(dataType.onUpdate) {
template += " ON UPDATE <%= onUpdateAction %>"
replacements.onUpdateAction = dataType.onUpdateAction.toUpperCase()
}
}
result[name] = Utils._.template(template)(replacements)
} else {
result[name] = dataType
......
......@@ -217,6 +217,29 @@ module.exports = (function() {
}
}
if(dataType.references) {
template += " REFERENCES <%= referencesTable %> (<%= referencesKeys %>)"
replacements.referencesTable = dataType.references
if(dataType.referencesKeys) {
// TODO: This isn't really right - for composite primary keys we need a different approach
replacements.referencesKeys = dataType.referencesKeys.map(Utils.escape).join(', ')
} else {
replacements.referencesKeys = Utils.escape('id')
}
if(dataType.onDelete) {
template += " ON DELETE <%= onDeleteAction %>"
replacements.onDeleteAction = dataType.onDeleteAction.toUpperCase()
}
if(dataType.onUpdate) {
template += " ON UPDATE <%= onUpdateAction %>"
replacements.onUpdateAction = dataType.onUpdateAction.toUpperCase()
}
}
result[name] = Utils._.template(template)(replacements)
} else {
result[name] = dataType
......
......@@ -10,6 +10,9 @@ describe('QueryGenerator', function() {
afterEach(function() { Helpers.drop() })
var suites = {
// TODO: Test attributesToSQL
createTableQuery: [
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)'}],
......@@ -26,6 +29,14 @@ describe('QueryGenerator', function() {
{
arguments: ['myTable', {title: 'ENUM("A", "B", "C")', name: 'VARCHAR(255)'}, {charset: 'latin1'}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` ENUM(\"A\", \"B\", \"C\"), `name` VARCHAR(255)) ENGINE=InnoDB DEFAULT CHARSET=latin1;"
},
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)', id: 'INTEGER PRIMARY KEY'}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` VARCHAR(255), `name` VARCHAR(255), `id` INTEGER , PRIMARY KEY (`id`)) ENGINE=InnoDB;"
},
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)', otherId: 'INTEGER REFERENCES `otherTable` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION'}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` VARCHAR(255), `name` VARCHAR(255), `otherId` INTEGER, FOREIGN KEY (`otherId`) REFERENCES `otherTable` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB;"
}
],
......
......@@ -14,6 +14,9 @@ describe('QueryGenerator', function() {
afterEach(function() { Helpers.drop() })
var suites = {
// TODO: Test attributesToSQL
createTableQuery: [
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)'}],
......@@ -26,6 +29,14 @@ describe('QueryGenerator', function() {
{
arguments: ['myTable', {title: 'ENUM("A", "B", "C")', name: 'VARCHAR(255)'}],
expectation: "DROP TYPE IF EXISTS \"enum_myTable_title\"; CREATE TYPE \"enum_myTable_title\" AS ENUM(\"A\", \"B\", \"C\"); CREATE TABLE IF NOT EXISTS \"myTable\" (\"title\" \"enum_myTable_title\", \"name\" VARCHAR(255));"
},
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)', id: 'INTEGER PRIMARY KEY'}],
expectation: "CREATE TABLE IF NOT EXISTS \"myTable\" (\"title\" VARCHAR(255), \"name\" VARCHAR(255), \"id\" INTEGER , PRIMARY KEY (\"id\"));"
},
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)', otherId: 'INTEGER REFERENCES "otherTable" ("id") ON DELETE CASCADE ON UPDATE NO ACTION'}],
expectation: "CREATE TABLE IF NOT EXISTS \"myTable\" (\"title\" VARCHAR(255), \"name\" VARCHAR(255), \"otherId\" INTEGER REFERENCES \"otherTable\" (\"id\") ON DELETE CASCADE ON UPDATE NO ACTION);"
}
],
......
......@@ -9,6 +9,36 @@ describe('QueryGenerator', function() {
afterEach(function() { Helpers.drop() })
var suites = {
// TODO: Test attributesToSQL
createTableQuery: [
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)'}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` VARCHAR(255), `name` VARCHAR(255));"
},
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)'}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` VARCHAR(255), `name` VARCHAR(255));"
},
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)'}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` VARCHAR(255), `name` VARCHAR(255));"
},
{
arguments: ['myTable', {title: 'ENUM("A", "B", "C")', name: 'VARCHAR(255)'}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` ENUM(\"A\", \"B\", \"C\"), `name` VARCHAR(255));"
},
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)', id: 'INTEGER PRIMARY KEY'}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` VARCHAR(255), `name` VARCHAR(255), `id` INTEGER PRIMARY KEY);"
},
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)', otherId: 'INTEGER REFERENCES `otherTable` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION'}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` VARCHAR(255), `name` VARCHAR(255), `otherId` INTEGER REFERENCES `otherTable` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION);"
}
],
insertQuery: [
{
arguments: ['myTable', { name: 'foo' }],
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!