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

Commit 3ae6e0aa by Joel Trost Committed by Matt Broadstone

All but the last test pass in Query Interface

1 parent 0fdc27fe
...@@ -35,8 +35,5 @@ ...@@ -35,8 +35,5 @@
"beforeEach", "beforeEach",
"after", "after",
"afterEach" "afterEach"
], ]
"globals":{
"Promise": true
}
} }
...@@ -451,7 +451,7 @@ module.exports = (function() { ...@@ -451,7 +451,7 @@ module.exports = (function() {
result += ' COLLATE ' + this.quoteIdentifier(attribute.collate); result += ' COLLATE ' + this.quoteIdentifier(attribute.collate);
} }
if (this._dialect.supports.index.length && attribute.length) { if (this._dialect.supports.index.length && attribute.length) {
result += '(' + attribute.length + ')'; result += '(' + attribute.length + ')';
} }
......
var DataTypes = require('../../data-types');
//drop table Group
DataTypes.BOOLEAN = 'BIT';
DataTypes.DATE = 'DATETIME2';
module.exports = DataTypes;
\ No newline at end of file
...@@ -12,6 +12,17 @@ var MssqlDialect = function(sequelize) { ...@@ -12,6 +12,17 @@ var MssqlDialect = function(sequelize) {
}; };
MssqlDialect.prototype.supports = _.merge(_.cloneDeep(Abstract.prototype.supports), { MssqlDialect.prototype.supports = _.merge(_.cloneDeep(Abstract.prototype.supports), {
'RETURNING': true,
'LIMIT ON UPDATE': true,
lock: true,
forShare: 'LOCK IN SHARE MODE',
index: {
collate: false,
length: false,
parser: false,
type: true,
using: 1,
}
}); });
MssqlDialect.prototype.Query = Query; MssqlDialect.prototype.Query = Query;
......
...@@ -31,15 +31,15 @@ module.exports = (function() { ...@@ -31,15 +31,15 @@ module.exports = (function() {
} }
var promise = new Utils.Promise(function(resolve, reject) { var promise = new Utils.Promise(function(resolve, reject) {
//console.log(self.sql); console.log(self.sql);
self self
.connection .connection
.lib .lib
.execute(self.connection.config, { query: self.sql }) .execute(self.connection.config, { query: self.sql })
.then( .then(
function (data) { resolve(self.formatResults(data.result)); }, function (data) { resolve(self.formatResults(data.result)); }
function (err) { reject(self.formatError(err)); } //function (err) { reject(self.formatError(err)); }
); );
}); });
...@@ -74,6 +74,8 @@ module.exports = (function() { ...@@ -74,6 +74,8 @@ module.exports = (function() {
if (this.sql.toLowerCase().indexOf("select c.name, t.name as 'type', c.is_nullable as isnull") === 0) { if (this.sql.toLowerCase().indexOf("select c.name, t.name as 'type', c.is_nullable as isnull") === 0) {
result = {}; result = {};
data.forEach(function(_result) { data.forEach(function(_result) {
if(_result.Default)
_result.Default = _result.Default.replace('(\'','').replace('\')','').replace(/'/g,'');
result[_result.Name] = { result[_result.Name] = {
type: _result.Type.toUpperCase(), type: _result.Type.toUpperCase(),
allowNull: _result.IsNull, allowNull: _result.IsNull,
......
'use strict';
var Utils = require('../../utils')
, SqlString = require('../../sql-string')
, DataTypes = require('./data-types');
/*
Escape a value (e.g. a string, number or date)
*/
var dialect = 'mssql';
//mssql doesnt support time zone
function escape(value, field) {
if (value && value._isSequelizeMethod) {
return value.toString();
} else {
return SqlString.escape(value, false, null, dialect, field);
}
}
function quoteIdentifier(identifier, force) {
if (identifier === '*') return identifier;
return Utils.addTicks(identifier, '"');
}
/*
Split an identifier into .-separated tokens and quote each part
*/
function quoteIdentifiers(identifiers, force) {
if (identifiers.indexOf('.') !== -1) {
identifiers = identifiers.split('.');
return quoteIdentifier(identifiers.slice(0, identifiers.length - 1).join('.'))
+ '.' + quoteIdentifier(identifiers[identifiers.length - 1]);
} else {
return quoteIdentifier(identifiers);
}
}
function wrapSingleQuote(identifier){
return Utils.addTicks(identifier, "'");
}
function nameIndexes(indexes, rawTablename) {
return Utils._.map(indexes, function (index) {
if (!index.hasOwnProperty('name')) {
var onlyAttributeNames = index.fields.map(function(attribute) {
return (typeof attribute === 'string') ? attribute : attribute.attribute;
}.bind(this));
index.name = Utils.inflection.underscore(rawTablename + '_' + onlyAttributeNames.join('_'));
}
return index;
});
}
function loadColumn(attributes){
var attrStr = [];
for (var attr in attributes) {
var dataType = attributes[attr];
attrStr.push(quoteIdentifier(dataType));
}
return attrStr;
}
function loadColumnWithTypes(attributes){
var attrStr = [];
for (var attr in attributes) {
var dataType = attributes[attr];
attrStr.push(quoteIdentifier(attr) + " " + dataType);
}
return attrStr;
}
function addTableExistsWrapper(tableName, query){
return [
"IF (NOT EXISTS (",
"SELECT * FROM INFORMATION_SCHEMA.TABLES",
"WHERE TABLE_NAME='<%= unquotedTable %>'))",
"BEGIN",
query,
"END"
].join(" ");
}
module.exports = {
getCreateTableSql: function(tableName, attributes, options) {
var query = "CREATE TABLE <%= tableName %> (<%= attributes%>)";
var attrStr = []
, self = this
, primaryKeys = Utils._.keys(Utils._.pick(attributes, function(dataType){
return dataType.indexOf('PRIMARY KEY') >= 0;
}));
attrStr = loadColumnWithTypes(attributes);
var values = {
unquotedTable: tableName,
tableName: quoteIdentifier(tableName),
attributes: attrStr.join(", ")
};
query = addTableExistsWrapper(tableName, query);
return Utils._.template(query)(values).trim() + ";";
},
insertSql: function(table, valueHash, modelAttributes, options) {
options = options || {};
var query
, valueQuery = 'INSERT INTO <%= table %> (<%= attributes %>)'
, emptyQuery = 'INSERT INTO <%= table %>'
, fields = []
, selFields = []
, values = []
, key
, value
, modelAttributeMap = {};
if (this._dialect.supports['RETURNING'] && options.returning) {
valueQuery += ' OUTPUT <%= selFields %> VALUES (<%= values %>)';
emptyQuery += ' OUTPUT <%= selFields %> VALUES ()';
}else{
valueQuery += ' VALUES (<%= values %>)';
}
valueHash = Utils.removeNullValuesFromHash(valueHash, this.options.omitNull);
for (key in valueHash) {
if (valueHash.hasOwnProperty(key)) {
value = valueHash[key];
// SERIALS' can't be NULL in postgresql, use DEFAULT where supported
if(modelAttributeMap && modelAttributeMap[key] && modelAttributeMap[key].autoIncrement && value){
fields.push(quoteIdentifier(key));
selFields.push(wrapSingleQuote(key));
valueQuery = 'SET IDENTITY_INSERT <%= table %> ON;'
+ valueQuery
+ '; SET IDENTITY_INSERT <%= table %> OFF';
values.push(escape(value, (modelAttributeMap && modelAttributeMap[key]) || undefined));
}else if(value) {
fields.push(quoteIdentifier(key));
selFields.push(wrapSingleQuote(key));
values.push(escape(value, (modelAttributeMap && modelAttributeMap[key]) || undefined));
}
}
}
var replacements = {
table: this.quoteTable(table),
attributes: fields.join(','),
selFields: selFields.join(','),
values: values.join(',')
};
query = (replacements.attributes.length ? valueQuery : emptyQuery) + ';';
return Utils._.template(query)(replacements);
},
addIndexSql: function(tableName, attributes, options, rawTablename){
if (!options.name) {
// Mostly for cases where addIndex is called directly by the user without an options object (for example in migrations)
// All calls that go through sequelize should already have a name
options.fields = options.fields || attributes;
options = nameIndexes([options], rawTablename)[0];
}
options = Utils._.defaults(options, {
type: '',
indicesType: options.type || '',
indexType: options.method || undefined,
indexName: options.name,
parser: null
});
var attrStr = loadColumn(attributes);
return Utils._.compact([
'CREATE',
options.unique ? 'UNIQUE' : '',
options.indicesType, 'INDEX',
quoteIdentifiers(options.indexName),
'ON', quoteIdentifiers(tableName),
'(' + attrStr.join(', ') + ')'
]).join(' ');
},
removeIndexSql: function(tableName, indexNameOrAttributes){
var sql = 'DROP INDEX <%= indexName %> ON <%= tableName %>'
, indexName = indexNameOrAttributes;
if (typeof indexName !== 'string') {
indexName = Utils.inflection.underscore(tableName + '_' + indexNameOrAttributes.join('_'));
}
var values = {
tableName: quoteIdentifiers(tableName),
indexName: indexName
};
return Utils._.template(sql)(values);
},
attributeMap:{
notNull:"NOT NULL",
isNull:"NULL",
autoIncrement:"IDENTITY(1,1)",
defaultValue:"DEFAULT",
unique:"UNIQUE",
primaryKey:"PRIMARY KEY",
comment:"COMMENT",
references:"REFERENCES",
onDelete:"ON DELETE",
onUpdate:"ON UPDATE"
},
attributeToSQL: function(attribute, options) {
if (!Utils._.isPlainObject(attribute)) {
attribute = {
type: attribute
};
}
var template;
var isEnum = false;
if (attribute.type.toString() === DataTypes.ENUM.toString()) {
isEnum = true;
template = 'VARCHAR(10) NOT NULL CHECK ("'
+ attribute.field + '" IN('
+ Utils._.map(attribute.values, function(value) {
return escape(value);
}.bind(this)).join(', ') + '))';
} else {
template = attribute.type.toString();
}
template += ' ';
if (attribute.allowNull === false && !isEnum && !attribute.primaryKey) {
template += this.attributeMap.notNull;
}else if(!isEnum && !attribute.primaryKey){
template += this.attributeMap.isNull;
}else if(!isEnum) {
template += 'PRIMARY KEY';
}
if (attribute.autoIncrement) {
template += ' ' + this.attributeMap.autoIncrement;
}
// Blobs/texts cannot have a defaultValue
if (attribute.type !== 'TEXT'
&& attribute.type._binary !== true
&& Utils.defaultValueSchemable(attribute.defaultValue)) {
if(options){
if(escape(attribute.defaultValue) !== 'NULL'){
template += ' DEFAULT ' + wrapSingleQuote(attribute.defaultValue);
}
}
}
if (attribute.unique === true) {
template += ' UNIQUE';
}
if (attribute.references) {
template += ' REFERENCES ' + quoteIdentifier(attribute.references);
if (attribute.referencesKey) {
template += ' (' + quoteIdentifier(attribute.referencesKey) + ')';
} else {
template += ' (' + quoteIdentifier('id') + ')';
}
if (attribute.onDelete) {
if(attribute.onDelete.toUpperCase() !== 'RESTRICT'){
template += ' ON DELETE ' + attribute.onDelete.toUpperCase();
}
}
if (attribute.onUpdate) {
template += ' ON UPDATE ' + attribute.onUpdate.toUpperCase();
}
}
return template;
},
describeTableSql: function(tableName, schema, schemaDelimiter){
var qry = ["SELECT c.Name, t.Name AS 'Type', c.IS_NULLABLE as IsNull",
", object_definition(c.default_object_id) AS 'Default'",
"FROM sys.Columns c",
"INNER JOIN sys.types t",
"ON t.system_type_id = c.system_type_id",
"WHERE object_id = object_id(",
wrapSingleQuote(tableName),
");"].join(" ");
return qry;
},
getForeignKeysSql: function(tableName){
return [
"SELECT",
"constraint_name = C.CONSTRAINT_NAME",
"FROM",
"INFORMATION_SCHEMA.TABLE_CONSTRAINTS C",
"WHERE C.CONSTRAINT_TYPE != 'PRIMARY KEY'",
"AND C.TABLE_NAME = ", wrapSingleQuote(tableName)
].join(" ");
},
dropForeignKeySql: function(tableName, foreignKey){
return ['ALTER TABLE',
quoteIdentifier(tableName),
'DROP',
quoteIdentifier(foreignKey),
';'].join(' ');
}
};
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!