Sequelize v5 will only support Node 6 and up [#9015](https://github.com/sequelize/sequelize/issues/9015)
__DEV__: _Done, no deprecation_
### Secure Operators
With v4 you started to get a deprecation warning `String based operators are now deprecated`. Also concept of operators was introduced. These operators are Symbols which prevent hash injection attacks.
* Generates an SQL query that returns all foreign keys of a table.
...
...
@@ -513,7 +489,7 @@ const QueryGenerator = {
getForeignKeysQuery(tableName,schemaName){
return'SELECT '+this._getForeignKeysQueryFields()+' FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = \''+tableName+/* jshint ignore: line */
'\' AND CONSTRAINT_NAME!=\'PRIMARY\' AND CONSTRAINT_SCHEMA=\''+schemaName+'\' AND REFERENCED_TABLE_NAME IS NOT NULL;';/* jshint ignore: line */
},
}
/**
* Generates an SQL query that returns the foreign key constraint of a given column.
...
...
@@ -537,7 +513,7 @@ const QueryGenerator = {
+' AND COLUMN_NAME = '+wrapSingleQuote(columnName)
+' AND REFERENCED_TABLE_NAME IS NOT NULL'
+')';
},
}
/**
* Generates an SQL query that removes a foreign key from a table.
...
...
@@ -557,4 +533,4 @@ function wrapSingleQuote(identifier) {
return"SELECT schema_name FROM information_schema.schemata WHERE schema_name <> 'information_schema' AND schema_name != 'public' AND schema_name !~ E'^pg_';";
},
}
versionQuery(){
return'SHOW SERVER_VERSION';
},
}
createTableQuery(tableName,attributes,options){
options=_.extend({},options||{});
...
...
@@ -88,16 +84,16 @@ const QueryGenerator = {
}
return`CREATE TABLE ${databaseVersion===0||semver.gte(databaseVersion,'9.1.0')?'IF NOT EXISTS ':''}${values.table} (${values.attributes})${values.comments};`;
},
}
dropTableQuery(tableName,options){
options=options||{};
return`DROP TABLE IF EXISTS ${this.quoteTable(tableName)}${options.cascade?' CASCADE':''};`;
},
}
showTablesQuery(){
return"SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type LIKE '%TABLE' AND table_name != 'spatial_ref_sys';";
},
}
describeTableQuery(tableName,schema){
if(!schema){
...
...
@@ -121,7 +117,7 @@ const QueryGenerator = {
'AND pk.table_name=c.table_name '+
'AND pk.column_name=c.column_name '+
`WHERE c.table_name = ${this.escape(tableName)} AND c.table_schema = ${this.escape(schema)} `;
},
}
/**
* Check whether the statmement is json function or simple path
...
...
@@ -188,22 +184,7 @@ const QueryGenerator = {
// return true if the statement has valid json function
returnhasJsonFunction;
},
/**
* Generates an SQL query that extract JSON property of given path.
*
* @param {String} column The JSON column
* @param {String|Array<String>} [path] The path to extract (optional)
return`CREATE OR REPLACE FUNCTION pg_temp.${fnName}(${parameters}) ${returns} AS $func$ BEGIN ${body} END; $func$ LANGUAGE ${language}; SELECT * FROM pg_temp.${fnName}();`;
if(!functionName||!returnType||!language||!body)thrownewError('createFunction missing some parameters. Did you pass functionName, returnType, language and body?');
...
...
@@ -643,19 +624,19 @@ const QueryGenerator = {
+`\t${indentedBody}\n`
+'END;\n'
+`$func$ language '${language}'${expandedOptions};`;
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.attributes)).to.deep.equal({username:'VARCHAR(255) NOT NULL',id:'INTEGER NOT NULL auto_increment PRIMARY KEY'});
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.rawAttributes)).to.deep.equal({username:'VARCHAR(255) NOT NULL',id:'INTEGER NOT NULL auto_increment PRIMARY KEY'});
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User1.attributes)).to.deep.equal({id:'INTEGER NOT NULL auto_increment PRIMARY KEY',updatedAt:'DATETIME NOT NULL',createdAt:'DATETIME NOT NULL'});
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User2.attributes)).to.deep.equal({id:'INTEGER NOT NULL auto_increment PRIMARY KEY',updatedAt:'DATETIME NOT NULL',createdAt:'DATETIME NOT NULL'});
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User1.rawAttributes)).to.deep.equal({id:'INTEGER NOT NULL auto_increment PRIMARY KEY',updatedAt:'DATETIME NOT NULL',createdAt:'DATETIME NOT NULL'});
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User2.rawAttributes)).to.deep.equal({id:'INTEGER NOT NULL auto_increment PRIMARY KEY',updatedAt:'DATETIME NOT NULL',createdAt:'DATETIME NOT NULL'});
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.attributes)).to.deep.equal({id:'INTEGER NOT NULL auto_increment PRIMARY KEY',deletedAt:'DATETIME',updatedAt:'DATETIME NOT NULL',createdAt:'DATETIME NOT NULL'});
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.rawAttributes)).to.deep.equal({id:'INTEGER NOT NULL auto_increment PRIMARY KEY',deletedAt:'DATETIME',updatedAt:'DATETIME NOT NULL',createdAt:'DATETIME NOT NULL'});
});
it('underscores timestamps if underscored',function(){
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.attributes)).to.deep.equal({id:'INTEGER NOT NULL auto_increment PRIMARY KEY',deleted_at:'DATETIME',updated_at:'DATETIME NOT NULL',created_at:'DATETIME NOT NULL'});
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.rawAttributes)).to.deep.equal({id:'INTEGER NOT NULL auto_increment PRIMARY KEY',deleted_at:'DATETIME',updated_at:'DATETIME NOT NULL',created_at:'DATETIME NOT NULL'});
});
it('omits text fields with defaultValues',function(){
mssql:"SELECT name FROM SYS.DEFAULT_CONSTRAINTS WHERE PARENT_OBJECT_ID = OBJECT_ID('[mySchema].[myTable]', 'U') AND PARENT_COLUMN_ID = (SELECT column_id FROM sys.columns WHERE NAME = ('myColumn') AND object_id = OBJECT_ID('[mySchema].[myTable]', 'U'));"
mssql:'SELECT K.TABLE_NAME AS tableName, K.COLUMN_NAME AS columnName, K.CONSTRAINT_NAME AS constraintName FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K ON C.TABLE_NAME = K.TABLE_NAME AND C.CONSTRAINT_CATALOG = K.CONSTRAINT_CATALOG AND C.CONSTRAINT_SCHEMA = K.CONSTRAINT_SCHEMA AND C.CONSTRAINT_NAME = K.CONSTRAINT_NAME WHERE C.CONSTRAINT_TYPE = \'PRIMARY KEY\' AND K.COLUMN_NAME = \'myColumnName\' AND K.TABLE_NAME = \'myTable\';'
mssql:'IF NOT EXISTS (SELECT schema_name FROM information_schema.schemata WHERE schema_name = \'mySchema\' ) BEGIN EXEC sp_executesql N\'CREATE SCHEMA [mySchema] ;\' END;'
mssql:'IF EXISTS (SELECT schema_name FROM information_schema.schemata WHERE schema_name = \'mySchema\' ) BEGIN DECLARE @id INT, @ms_sql NVARCHAR(2000); DECLARE @cascade TABLE ( id INT NOT NULL IDENTITY PRIMARY KEY, ms_sql NVARCHAR(2000) NOT NULL ); INSERT INTO @cascade ( ms_sql ) SELECT CASE WHEN o.type IN (\'F\',\'PK\') THEN N\'ALTER TABLE [\'+ s.name + N\'].[\' + p.name + N\'] DROP CONSTRAINT [\' + o.name + N\']\' ELSE N\'DROP TABLE [\'+ s.name + N\'].[\' + o.name + N\']\' END FROM sys.objects o JOIN sys.schemas s on o.schema_id = s.schema_id LEFT OUTER JOIN sys.objects p on o.parent_object_id = p.object_id WHERE o.type IN (\'F\', \'PK\', \'U\') AND s.name = \'mySchema\' ORDER BY o.type ASC; SELECT TOP 1 @id = id, @ms_sql = ms_sql FROM @cascade ORDER BY id; WHILE @id IS NOT NULL BEGIN BEGIN TRY EXEC sp_executesql @ms_sql; END TRY BEGIN CATCH BREAK; THROW; END CATCH; DELETE FROM @cascade WHERE id = @id; SELECT @id = NULL, @ms_sql = NULL; SELECT TOP 1 @id = id, @ms_sql = ms_sql FROM @cascade ORDER BY id; END EXEC sp_executesql N\'DROP SCHEMA [mySchema] ;\' END;'
mssql:'SELECT "name" as "schema_name" FROM sys.schemas as s WHERE "s"."name" NOT IN ( \'INFORMATION_SCHEMA\', \'dbo\', \'guest\', \'sys\', \'archive\' ) AND "s"."name" NOT LIKE \'db_%\''
});
});
test('versionQuery',()=>{
expectsql(QueryGenerator.versionQuery(),{
it('versionQuery',function(){
expectsql(this.queryGenerator.versionQuery(),{
mssql:"DECLARE @ms_ver NVARCHAR(20); SET @ms_ver = REVERSE(CONVERT(NVARCHAR(20), SERVERPROPERTY('ProductVersion'))); SELECT REVERSE(SUBSTRING(@ms_ver, CHARINDEX('.', @ms_ver)+1, 20)) AS 'version'"