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

Commit b47f5cdd by Jan Aagaard Meier

Merge PR #4464 and add tests

1 parent 680b4328
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
- [ADDED] Support silent: true in bulk update [#5200](https://github.com/sequelize/sequelize/issues/5200) - [ADDED] Support silent: true in bulk update [#5200](https://github.com/sequelize/sequelize/issues/5200)
- [ADDED] `retry` object now part of global settings and can be overridden per call. The default is 5 retries with a backoff function. `retry` object can be passed to options with max: 0 to turn off this behavior. - [ADDED] `retry` object now part of global settings and can be overridden per call. The default is 5 retries with a backoff function. `retry` object can be passed to options with max: 0 to turn off this behavior.
- [ADDED] Sqlite now retries database queries that return SQL_BUSY as the status. - [ADDED] Sqlite now retries database queries that return SQL_BUSY as the status.
- [ADDED] Add `IF EXIST` to postgres alter enum [#4464](https://github.com/sequelize/sequelize/pull/4464)
- [FIXED] Postgres destroy with `where` fails on JSONB data [#5092](https://github.com/sequelize/sequelize/issues/5092) - [FIXED] Postgres destroy with `where` fails on JSONB data [#5092](https://github.com/sequelize/sequelize/issues/5092)
# 3.17.3 # 3.17.3
......
...@@ -743,7 +743,7 @@ var QueryGenerator = { ...@@ -743,7 +743,7 @@ var QueryGenerator = {
enumName = ' AND t.typname=' + this.pgEnumName(tableDetails.tableName, attrName, { schema: false }).replace(/"/g, "'"); enumName = ' AND t.typname=' + this.pgEnumName(tableDetails.tableName, attrName, { schema: false }).replace(/"/g, "'");
} }
var query = 'SELECT t.typname enum_name, array_agg(e.enumlabel) enum_value FROM pg_type t ' + var query = 'SELECT t.typname enum_name, array_agg(e.enumlabel ORDER BY enumsortorder) enum_value FROM pg_type t ' +
'JOIN pg_enum e ON t.oid = e.enumtypid ' + 'JOIN pg_enum e ON t.oid = e.enumtypid ' +
'JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace ' + 'JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace ' +
"WHERE n.nspname = '" + tableDetails.schema + "'" + enumName + ' GROUP BY 1'; "WHERE n.nspname = '" + tableDetails.schema + "'" + enumName + ' GROUP BY 1';
...@@ -770,12 +770,16 @@ var QueryGenerator = { ...@@ -770,12 +770,16 @@ var QueryGenerator = {
pgEnumAdd: function(tableName, attr, value, options) { pgEnumAdd: function(tableName, attr, value, options) {
var enumName = this.pgEnumName(tableName, attr) var enumName = this.pgEnumName(tableName, attr)
, sql = 'ALTER TYPE ' + enumName + ' ADD VALUE ' + this.escape(value); , sql = 'ALTER TYPE ' + enumName + ' ADD VALUE ';
if (semver.gte(this.sequelize.options.databaseVersion, '9.3.0')) {
sql += 'IF NOT EXISTS ';
}
sql += this.escape(value);
if (!!options.before) { if (!!options.before) {
sql += ' BEFORE ' + this.escape(options.before); sql += ' BEFORE ' + this.escape(options.before);
} } else if (!!options.after) {
else if (!!options.after) {
sql += ' AFTER ' + this.escape(options.after); sql += ' AFTER ' + this.escape(options.after);
} }
......
...@@ -274,13 +274,9 @@ QueryInterface.prototype.dropAllEnums = function(options) { ...@@ -274,13 +274,9 @@ QueryInterface.prototype.dropAllEnums = function(options) {
options = options || {}; options = options || {};
var self = this var self = this;
, sql = this.QueryGenerator.pgListEnums();
return this.sequelize.query( return this.pgListEnums(options).map(function(result) {
sql,
_.assign({}, options, { plain: false, raw: true, type: QueryTypes.SELECT })
).map(function(result) {
return self.sequelize.query( return self.sequelize.query(
self.QueryGenerator.pgEnumDrop(null, null, self.QueryGenerator.pgEscapeAndQuote(result.enum_name)), self.QueryGenerator.pgEnumDrop(null, null, self.QueryGenerator.pgEscapeAndQuote(result.enum_name)),
_.assign({}, options, { raw: true }) _.assign({}, options, { raw: true })
...@@ -288,6 +284,12 @@ QueryInterface.prototype.dropAllEnums = function(options) { ...@@ -288,6 +284,12 @@ QueryInterface.prototype.dropAllEnums = function(options) {
}); });
}; };
QueryInterface.prototype.pgListEnums = function (tableName, options) {
options = options || {};
var sql = this.QueryGenerator.pgListEnums(tableName);
return this.sequelize.query(sql, _.assign({}, options, { plain: false, raw: true, type: QueryTypes.SELECT }));
};
QueryInterface.prototype.renameTable = function(before, after, options) { QueryInterface.prototype.renameTable = function(before, after, options) {
options = options || {}; options = options || {};
var sql = this.QueryGenerator.renameTableQuery(before, after); var sql = this.QueryGenerator.renameTableQuery(before, after);
......
...@@ -375,37 +375,22 @@ if (dialect.match(/^postgres/)) { ...@@ -375,37 +375,22 @@ if (dialect.match(/^postgres/)) {
}); });
}); });
it('should be able to add enum types', function() { it('should be able to add values to enum types', function() {
var self = this var User = this.sequelize.define('UserEnums', {
, User = this.sequelize.define('UserEnums', {
mood: DataTypes.ENUM('happy', 'sad', 'meh') mood: DataTypes.ENUM('happy', 'sad', 'meh')
}) });
, count = 0;
return User.sync({ force: true }).then(function() { return User.sync({ force: true }).bind(this).then(function() {
User = self.sequelize.define('UserEnums', { User = this.sequelize.define('UserEnums', {
mood: DataTypes.ENUM('neutral', 'happy', 'sad', 'ecstatic', 'meh', 'joyful') mood: DataTypes.ENUM('neutral', 'happy', 'sad', 'ecstatic', 'meh', 'joyful')
}); });
return User.sync({ return User.sync();
logging: function (sql) {
if (sql.indexOf('neutral') > -1) {
expect(sql.indexOf("ALTER TYPE \"public\".\"enum_UserEnums_mood\" ADD VALUE 'neutral' BEFORE 'happy'")).to.not.be.equal(-1);
count++;
}
else if (sql.indexOf('ecstatic') > -1) {
expect(sql.indexOf("ALTER TYPE \"public\".\"enum_UserEnums_mood\" ADD VALUE 'ecstatic' BEFORE 'meh'")).to.not.be.equal(-1);
count++;
}
else if (sql.indexOf('joyful') > -1) {
expect(sql.indexOf("ALTER TYPE \"public\".\"enum_UserEnums_mood\" ADD VALUE 'joyful' AFTER 'meh'")).to.not.be.equal(-1);
count++;
}
}
}).then(function() { }).then(function() {
expect(User.rawAttributes.mood.values).to.deep.equal(['neutral', 'happy', 'sad', 'ecstatic', 'meh', 'joyful']); return this.sequelize.getQueryInterface().pgListEnums(User.getTableName());
expect(count).to.equal(3); }).then(function (enums) {
}); expect(enums).to.have.length(1);
expect(enums[0].enum_value).to.equal("{neutral,happy,sad,ecstatic,meh,joyful}");
}); });
}); });
}); });
......
...@@ -55,16 +55,32 @@ describe(Support.getTestDialectTeaser('SQL'), function() { ...@@ -55,16 +55,32 @@ describe(Support.getTestDialectTeaser('SQL'), function() {
}); });
}); });
describe('pgEnumAdd', function () {
it('creates alter type with exists on 9.4', function () {
current.options.databaseVersion = '9.4.0';
expectsql(sql.pgEnumAdd(PublicUser.getTableName(), 'mood', 'neutral', { after: 'happy' }), {
postgres: 'ALTER TYPE "public"."enum_users_mood" ADD VALUE IF NOT EXISTS \'neutral\' AFTER \'happy\''
});
});
it('creates alter type without exists on 9.2 ', function () {
current.options.databaseVersion = '9.2.0';
expectsql(sql.pgEnumAdd(PublicUser.getTableName(), 'mood', 'neutral', { after: 'happy' }), {
postgres: 'ALTER TYPE "public"."enum_users_mood" ADD VALUE \'neutral\' AFTER \'happy\''
});
});
});
describe('pgListEnums', function () { describe('pgListEnums', function () {
it('works with schema #3563', function () { it('works with schema #3563', function () {
expectsql(sql.pgListEnums(FooUser.getTableName(), 'mood'), { expectsql(sql.pgListEnums(FooUser.getTableName(), 'mood'), {
postgres: 'SELECT t.typname enum_name, array_agg(e.enumlabel) enum_value FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = \'foo\' AND t.typname=\'enum_users_mood\' GROUP BY 1' postgres: 'SELECT t.typname enum_name, array_agg(e.enumlabel ORDER BY enumsortorder) enum_value FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = \'foo\' AND t.typname=\'enum_users_mood\' GROUP BY 1'
}); });
}); });
it('uses the default schema if no options given', function () { it('uses the default schema if no options given', function () {
expectsql(sql.pgListEnums(), { expectsql(sql.pgListEnums(), {
postgres: 'SELECT t.typname enum_name, array_agg(e.enumlabel) enum_value FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = \'public\' GROUP BY 1' postgres: 'SELECT t.typname enum_name, array_agg(e.enumlabel ORDER BY enumsortorder) enum_value FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = \'public\' GROUP BY 1'
}); });
}); });
}); });
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!