knex/lib/dialects/sqlite3/schema.js

216 lines
6.7 KiB
JavaScript

// SQLite3 SchemaGrammar
// -------
module.exports = function(client) {
var _ = require('lodash');
var inherits = require('inherits');
var Promise = require('../../promise');
var SchemaBuilder = require('../../schema/builder');
var SchemaCompiler = require('../../schema/compiler');
var TableBuilder = require('../../schema/tablebuilder');
var TableCompiler = require('../../schema/tablecompiler');
var ColumnBuilder = require('../../schema/columnbuilder');
var ColumnCompiler = require('../../schema/columncompiler');
function SchemaBuilder_SQLite3() {
SchemaBuilder.apply(this, arguments);
}
inherits(SchemaBuilder_SQLite3, SchemaBuilder);
function SchemaCompiler_SQLite3() {
this.Formatter = client.Formatter;
}
inherits(SchemaCompiler_SQLite3, SchemaBuilder);
// Compile the query to determine if a table exists.
SchemaCompiler_SQLite3.prototype.hasTable = function(tableName) {
this.sequence.push({
sql: "select * from sqlite_master where type = 'table' and name = ?",
bindings: [tableName],
output: function(resp) {
return resp.length > 0;
}
});
return this;
},
// Compile the query to determine if a column exists.
SchemaCompiler_SQLite3.prototype.hasColumn = function(tableName, column) {
this.push({
sql: 'PRAGMA table_info(' + this.formatter.wrap(tableName) + ')',
output: function(resp) {
return _.findWhere(resp, {name: column}) != null;
}
});
},
// Compile a rename table command.
SchemaCompiler_SQLite3.prototype.renameTable = function(from, to) {
this.push('alter table ' + this.formatter.wrap(from) + ' rename to ' + this.formatter.wrap(to));
};
function TableBuilder_SQLite3() {
TableBuilder.apply(this, arguments);
}
inherits(TableBuilder_SQLite3, TableBuilder);
function TableCompiler_SQLite3() {
this.modifierTypes = ['nullable', 'defaultTo'];
TableCompiler.apply(this, arguments);
}
inherits(TableCompiler_SQLite3, TableCompiler);
// All of the SQLite3 specific DDL helpers for renaming/dropping columns
// and changing datatypes.
var SQLite3_DDL = require('./ddl')(client);
// All modifiers for the sqlite3 builder.
TableCompiler_SQLite3.prototype.modifiers = require('./tablecompiler/modifiers')(client),
// All key related statements for the sqlite3 builder.
TableCompiler_SQLite3.prototype.keys = require('./tablecompiler/keys')(client),
// Create a new table.
TableCompiler_SQLite3.prototype.create = function() {
var returnSql = this.returnSql = [];
returnSql.push({sql: '', bindings: []});
var sql = 'create table ' + this.tableName + ' (' + this.getColumns().join(', ');
// SQLite forces primary keys to be added when the table is initially created
// so we will need to check for a primary key commands and add the columns
// to the table's declaration here so they can be created on the tables.
sql += this.foreignKeys() || '';
sql += this.primaryKeys() || '';
returnSql[0].sql = sql + ')';
this.alterColumns();
this.addIndexes();
return returnSql;
};
TableCompiler_SQLite3.prototype.alter = function() {
var returnSql = this.returnSql = [];
var columns = this.getColumns();
for (var i = 0, l = columns.length; i < l; i++) {
var column = columns[i];
this.returnSql.push({sql: 'alter table ' + this.tableName + ' add column ' + column});
}
this.alterColumns();
this.addIndexes();
return returnSql;
};
TableCompiler_SQLite3.prototype.foreignKeys = function() {
var sql = '';
var foreignKeys = _.where(this.statements, {type: 'indexes', method: 'foreign'});
for (var i = 0, l = foreignKeys.length; i < l; i++) {
var foreign = foreignKeys[i].args[0];
var column = this.formatter.columnize(foreign.column);
var references = this.formatter.columnize(foreign.references);
var foreignTable = this.formatter.wrap(foreign.inTable);
sql += ', foreign key(' + column + ') references ' + foreignTable + '(' + references + ')';
}
return sql;
};
TableCompiler_SQLite3.prototype.primaryKeys = function() {
var indexes = _.where(this.statements, {type: 'indexes', method: 'primary'});
if (indexes.length > 0) {
var primary = indexes[0];
var columns = primary.args[0];
if (columns) {
return ', primary key (' + this.formatter.columnize(columns) + ')';
}
}
};
TableCompiler_SQLite3.prototype.createTableBlock = function() {
return this.getColumns().concat().join(',');
};
// Compile a rename column command... very complex in sqlite
TableCompiler_SQLite3.prototype.renameColumn = function(from, to) {
var tableCompiler = this;
return {
sql: 'PRAGMA table_info(' + this.tableName + ')',
output: function(pragma) {
return new SQLite3_DDL(this, tableCompiler, pragma)
.renameColumn(from, to);
}
};
};
TableCompiler_SQLite3.prototype.dropColumn = function(column) {
return {
sql: 'PRAGMA table_info(' + this.tableName + ')',
output: function(pragma) {
return new SQLite3_DDL(this, tableCompiler, pragma)
.dropColumn(column);
}
};
};
function ColumnBuilder_SQLite3() {
ColumnBuilder.apply(this, arguments);
}
inherits(ColumnBuilder_SQLite3, ColumnBuilder);
function ColumnCompiler_SQLite3() {
ColumnBuilder.apply(this, arguments);
}
inherits(ColumnCompiler_SQLite3, ColumnCompiler);
ColumnCompiler_SQLite3.prototype.double =
ColumnCompiler_SQLite3.prototype.decimal =
ColumnCompiler_SQLite3.prototype.floating = 'float';
ColumnCompiler_SQLite3.prototype.timestamp = 'datetime';
// Handled on create table.
ColumnCompiler_SQLite3.prototype.primary =
ColumnCompiler_SQLite3.prototype.foreign = function() {};
// Compile a unique key command.
ColumnCompiler_SQLite3.prototype.unique = function(columns, indexName) {
indexName = indexName || this._indexCommand('unique', this.tableNameRaw, columns);
columns = this.formatter.columnize(columns);
return {
sql: 'create unique index ' + indexName + ' on ' + this.tableName + ' (' + columns + ')'
};
};
// Compile a plain index key command.
ColumnCompiler_SQLite3.prototype.index = function(columns, indexName) {
indexName = indexName || this._indexCommand('index', this.tableNameRaw, columns);
columns = this.formatter.columnize(columns);
return {
sql: 'create index ' + indexName + ' on ' + this.tableName + ' (' + columns + ')'
};
};
// Compile a drop column command.
ColumnCompiler_SQLite3.prototype.dropColumn = function() {
throw new Error("Drop column not supported for SQLite.");
};
// Compile a drop unique key command.
ColumnCompiler_SQLite3.prototype.dropUnique = function(value) {
return 'drop index ' + value;
};
ColumnCompiler_SQLite3.prototype.dropIndex = function(index) {
return 'drop index ' + index;
};
client.ColumnBuilder = ColumnBuilder_SQLite3;
client.ColumnCompiler = ColumnCompiler_SQLite3;
};