schema_plus 1.5.3 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 98695abbf9f44e746dda323f7312d0b206b74b33
4
- data.tar.gz: f9402bff3980025c1f6a1b6e052f9ec1cf0f2bfe
3
+ metadata.gz: 620224f986e74b013fddffb7147eecfabe3f27bd
4
+ data.tar.gz: 323fdba9ed583753abfbdaee67353391356213f0
5
5
  SHA512:
6
- metadata.gz: 1ac7c8fb9f854adb5bd455b19e93427829dffab2ceccbf59044116f1bdee8783acb5d98ede537a9af118e1d44a7872e306700e8ae9f4153c4d523ba7c4da4803
7
- data.tar.gz: 521da3cda682a2ab9dc0126a093c3f6b21e5a49a19d7dded7662a5c7d8729671f9a71aa672e01150d4078cf2b076d20974a7a41e825a4616f7c5fae3386bcb72
6
+ metadata.gz: 8510bd7c390e12f5e4f2c113395dcde1831e46c9b525a90bb9a5cb2a4e48095840467e03dcac5229fdcab72abc11089d3d14c72ef535c6751fed159578f41bd6
7
+ data.tar.gz: 47df08a80fb0257e6cc1fa632005517685424af5f717ad847ef817b579288803c36e14f1cf2a96c7bb9442e288aaae08cd328e16ca0bfadda8a47f0910d8aa13
data/.travis.yml CHANGED
@@ -18,7 +18,7 @@ before_script:
18
18
  - rake create_databases
19
19
  after_script:
20
20
  - rake drop_databases
21
- env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER="travis"'
21
+ env: 'POSTGRESQL_DB_USER=postgres MYSQL_DB_USER="travis"'
22
22
  notifications:
23
23
  recipients:
24
24
  - michal.lomnicki@gmail.com
@@ -27,22 +27,22 @@ matrix:
27
27
  exclude:
28
28
  - rvm: jruby
29
29
  gemfile: gemfiles/rails-3.2/Gemfile.sqlite3
30
- env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER="travis"'
30
+ env: 'POSTGRESQL_DB_USER=postgres MYSQL_DB_USER="travis"'
31
31
  - rvm: jruby
32
32
  gemfile: gemfiles/rails-4.0/Gemfile.postgresql
33
- env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER="travis"'
33
+ env: 'POSTGRESQL_DB_USER=postgres MYSQL_DB_USER="travis"'
34
34
  - rvm: jruby
35
35
  gemfile: gemfiles/rails-4.0/Gemfile.sqlite3
36
- env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER="travis"'
36
+ env: 'POSTGRESQL_DB_USER=postgres MYSQL_DB_USER="travis"'
37
37
  - rvm: jruby
38
38
  gemfile: gemfiles/rails-4.0/Gemfile.mysql2
39
- env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER="travis"'
39
+ env: 'POSTGRESQL_DB_USER=postgres MYSQL_DB_USER="travis"'
40
40
  - rvm: jruby
41
41
  gemfile: gemfiles/rails-4.1/Gemfile.postgresql
42
- env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER="travis"'
42
+ env: 'POSTGRESQL_DB_USER=postgres MYSQL_DB_USER="travis"'
43
43
  - rvm: jruby
44
44
  gemfile: gemfiles/rails-4.1/Gemfile.sqlite3
45
- env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER="travis"'
45
+ env: 'POSTGRESQL_DB_USER=postgres MYSQL_DB_USER="travis"'
46
46
  - rvm: jruby
47
47
  gemfile: gemfiles/rails-4.1/Gemfile.mysql2
48
- env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER="travis"'
48
+ env: 'POSTGRESQL_DB_USER=postgres MYSQL_DB_USER="travis"'
data/CHANGELOG.md CHANGED
@@ -2,12 +2,18 @@
2
2
 
3
3
  ## Change Log
4
4
 
5
+ ### 1.6.0
6
+
7
+ * Added PostgreSQL enum support (thanks to [@juike](https://github.com/juike)) (issue #167)
8
+ * Added if_exists to drop_view (thanks to [@abrom](https://github.com/abrom)) (issue #171)
9
+ * Partial support for AR 4.* with jRuby (thanks to [@bacrossland])) (issue #172)
10
+
5
11
  ### 1.5.3
6
12
 
7
13
  * No longer limited to rails 4.1.1 (issue #159)
8
14
  * Bug fix: multiple competing indexes created for `t.references... index: :unique` (issue #157)
9
- * Now works with rspec 3 (thanks to [@robababa](https://github.com/robababa) (issue #160)
10
- * Improvements to ./runspecs (thanks to [@robababa](https://github.com/robababa) (issue #162)
15
+ * Now works with rspec 3 (thanks to [@robababa](https://github.com/robababa)) (issue #160)
16
+ * Improvements to ./runspecs (thanks to [@robababa](https://github.com/robababa)) (issue #162)
11
17
 
12
18
  ### 1.5.2
13
19
 
@@ -19,7 +25,7 @@
19
25
 
20
26
  ### 1.5.0
21
27
  * Can now be used with activerecord standalone, doesn't need all of rails.
22
- * `views` ignores postgres internal views, thanks to [@everplays](https://github.com/everplays) (issue #147)
28
+ * `views` ignores PostgreSQL internal views, thanks to [@everplays](https://github.com/everplays) (issue #147)
23
29
 
24
30
  ### 1.4.1
25
31
 
@@ -103,7 +109,7 @@
103
109
  [@zaadjis](https://github.com/zaadjis))
104
110
  * New feature: renaming a table renames its indexes and constraints
105
111
  correspondingly.
106
- * Bug fix for postgres :kind index attribute (thanks to [@eugenebolshakov](https://github.com/eugenebolshakov))
112
+ * Bug fix for PostgreSQL :kind index attribute (thanks to [@eugenebolshakov](https://github.com/eugenebolshakov))
107
113
  * Sort fks in dump for stability (thanks to [@zephyr-dev](https://github.com/zephyr-dev))
108
114
  * Bug fix: change_column should maintain foreign key constraints even when
109
115
  config.foreign_keys.auto_create is false
data/README.md CHANGED
@@ -211,7 +211,7 @@ a view can be created using a rails relation or literal sql:
211
211
  And can be dropped:
212
212
 
213
213
  drop_view :posts_commented_by_staff
214
- drop_view :uncommented_posts
214
+ drop_view :uncommented_posts, :if_exists => true
215
215
 
216
216
  ActiveRecord works with views the same as with ordinary tables. That is, for
217
217
  the above views you can define
@@ -223,7 +223,7 @@ the above views you can define
223
223
  class UncommentedPost < ActiveRecord::Base
224
224
  end
225
225
 
226
- Note: In Postgres, all internal views (the ones with `pg_` prefix) will be skipped.
226
+ Note: In PostgreSQL, all internal views (the ones with `pg_` prefix) will be skipped.
227
227
 
228
228
  ### Column Defaults: Expressions
229
229
 
@@ -267,6 +267,26 @@ Note that after updating, you would need to reload a record to replace
267
267
  Note also that Sqlite3 does not support `ActiveRecord::DB_DEFAULT`; attempting
268
268
  to use it will raise `ActiveRecord::StatementInvalid`
269
269
 
270
+ ### Enums (PostgreSQL only)
271
+
272
+ SchemaPlus provides support for creating, altering and dropping enums. In a migration,
273
+ a enum can be created:
274
+
275
+ create_enum :color, :red, :green, :blue # default schema is 'public'
276
+ create_enum :cmyk, :cyan, :magenta, :yellow, :black, :schema => 'color'
277
+
278
+ And can be altered: (added a new value)
279
+
280
+ alter_enum :color, :black
281
+ alter_enum :color, :purple, :after => 'red'
282
+ alter_enum :color, :pink, :before => 'purple'
283
+ alter_enum :color, :white, :schema => 'public'
284
+
285
+ Finally, a enum can be dropped:
286
+
287
+ drop_enum :color
288
+ drop_enum :cmyk, :schema => 'color'
289
+
270
290
  ### Schema Dump and Load (schema.rb)
271
291
 
272
292
  When dumping `schema.rb`, SchemaPlus orders the views and tables in the schema
@@ -316,9 +336,9 @@ Schema_plus has a full set of rspec tests. [travis-ci](http://travis-ci.org/lom
316
336
 
317
337
  * Of course you must have installed whichever databases you want to test. The default set is: PostgreSQL, MySQL, and SQLite3.
318
338
 
319
- * For PostgreSQL and MySQL the tests need a db user with permissions to create and access databases: The default username used by the specs is 'postgres' for Postgresql and 'schema_plus' for MySQL; you can change them via:
339
+ * For PostgreSQL and MySQL the tests need a db user with permissions to create and access databases: The default username used by the specs is 'postgres' for PostgreSQL and 'schema_plus' for MySQL; you can change them via:
320
340
 
321
- $ export POSTGRES_DB_USER = pgusername
341
+ $ export POSTGRESQL_DB_USER = pgusername
322
342
  $ export MYSQL_DB_USER = mysqlusername
323
343
 
324
344
  * For PostgreSQL and MySQL you must explicitly create the databases used by the tests:
data/Rakefile CHANGED
@@ -37,7 +37,7 @@ end
37
37
 
38
38
  DATABASES = %w[schema_plus_test]
39
39
  [
40
- { namespace: :postgresql, uservar: 'POSTGRES_DB_USER', defaultuser: 'postgres', create: "createdb -U '%{user}' %{dbname}", drop: "dropdb -U '%{user}' %{dbname}" },
40
+ { namespace: :postgresql, uservar: 'POSTGRESQL_DB_USER', defaultuser: 'postgres', create: "createdb -U '%{user}' %{dbname}", drop: "dropdb -U '%{user}' %{dbname}" },
41
41
  { namespace: :mysql, uservar: 'MYSQL_DB_USER', defaultuser: 'schema_plus', create: "mysqladmin -u '%{user}' create %{dbname}", drop: "mysqladmin -u '%{user}' -f drop %{dbname}" }
42
42
  ].each do |db|
43
43
  namespace db[:namespace] do
@@ -1,3 +1,3 @@
1
1
  eval File.read File.expand_path('../../Gemfile.base', __FILE__)
2
2
 
3
- gem "rails", ">= 4.1.0.beta1"
3
+ gem "rails", "~> 4.1.0"
@@ -27,8 +27,10 @@ module SchemaPlus
27
27
  when 'PostgreSQL', 'PostGIS' then 'PostgresqlAdapter'
28
28
  when 'SQLite' then 'Sqlite3Adapter'
29
29
  end
30
- unless adapter
31
- ::ActiveRecord::Base.logger.warn "SchemaPlus: Unsupported adapter name #{adapter_name.inspect}. Leaving it alone."
30
+ if adapter.nil?
31
+ unless adapter_name == 'JDBC' # ARJDBC
32
+ ::ActiveRecord::Base.logger.warn "SchemaPlus: Unsupported adapter name #{adapter_name.inspect}. Leaving it alone."
33
+ end
32
34
  return
33
35
  end
34
36
  adapter_module = SchemaPlus::ActiveRecord::ConnectionAdapters.const_get(adapter)
@@ -51,9 +53,13 @@ module SchemaPlus
51
53
  execute "CREATE VIEW #{quote_table_name(view_name)} AS #{definition}"
52
54
  end
53
55
 
54
- # Drop the named view
55
- def drop_view(view_name)
56
- execute "DROP VIEW #{quote_table_name(view_name)}"
56
+ # Drop the named view. Specify :if_exists => true
57
+ # to fail silently if the view doesn't exist.
58
+ def drop_view(view_name, options = {})
59
+ sql = "DROP VIEW"
60
+ sql += " IF EXISTS" if options[:if_exists]
61
+ sql += " #{quote_table_name(view_name)}"
62
+ execute sql
57
63
  end
58
64
 
59
65
 
@@ -68,7 +68,7 @@ module SchemaPlus
68
68
  ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn.send(:include, PostgreSQLColumn) unless ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn.include?(PostgreSQLColumn)
69
69
  end
70
70
 
71
- # SchemaPlus provides the following extra options for Postgres
71
+ # SchemaPlus provides the following extra options for PostgreSQL
72
72
  # indexes:
73
73
  # * +:conditions+ - SQL conditions for the WHERE clause of the index
74
74
  # * +:expression+ - SQL expression to index. column_name can be nil or ommitted, in which case :name must be provided
@@ -154,7 +154,7 @@ module SchemaPlus
154
154
  SQL
155
155
 
156
156
  result.map do |(index_name, is_unique, indkey, inddef, oid, kind, conditions, expression)|
157
- unique = (is_unique == 't')
157
+ unique = (is_unique == 't' || is_unique == true) # The test against true is for JDBC which is returning a boolean and not a String.
158
158
  index_keys = indkey.split(" ")
159
159
 
160
160
  rows = query(<<-SQL, "Columns for index #{index_name} on #{table_name}")
@@ -282,8 +282,64 @@ module SchemaPlus
282
282
  row.first.chomp(';') unless row.nil?
283
283
  end
284
284
 
285
+ def enums #:nodoc:
286
+ result = query(<<-SQL)
287
+ SELECT
288
+ N.nspname AS schema_name,
289
+ T.typname AS enum_name,
290
+ E.enumlabel AS enum_label,
291
+ E.enumsortorder AS enum_sort_order
292
+ --array_agg(E.enumlabel ORDER BY enumsortorder) AS labels
293
+ FROM pg_type T
294
+ JOIN pg_enum E ON E.enumtypid = T.oid
295
+ JOIN pg_namespace N ON N.oid = T.typnamespace
296
+ ORDER BY 1, 2, 4
297
+ SQL
298
+
299
+ result.reduce([]) do |res, row|
300
+ last = res.last
301
+ if last && last[0] == row[0] && last[1] == row[1]
302
+ last[2] << row[2]
303
+ else
304
+ res << (row[0..1] << [row[2]])
305
+ end
306
+ res
307
+ end
308
+ end
309
+
310
+ def create_enum(name, *values)
311
+ options = values.extract_options!
312
+ list = values.map { |value| escape_enum_value(value) }
313
+ execute "CREATE TYPE #{enum_name(name, options[:schema])} AS ENUM (#{list.join(',')})"
314
+ end
315
+
316
+ def alter_enum(name, value, options = {})
317
+ opts = case
318
+ when options[:before] then "BEFORE #{escape_enum_value(options[:before])}"
319
+ when options[:after] then "AFTER #{escape_enum_value(options[:after])}"
320
+ else
321
+ ''
322
+ end
323
+ execute "ALTER TYPE #{enum_name(name, options[:schema])} ADD VALUE #{escape_enum_value(value)} #{opts}"
324
+ end
325
+
326
+ def drop_enum(name, options = {})
327
+ execute "DROP TYPE #{enum_name(name, options[:schema])}"
328
+ end
329
+
285
330
  private
286
331
 
332
+ def enum_name(name, schema)
333
+ [schema || 'public', name].map { |s|
334
+ %Q{"#{s}"}
335
+ }.join('.')
336
+ end
337
+
338
+ def escape_enum_value(value)
339
+ escaped_value = value.sub("'", "''")
340
+ "'#{escaped_value}'"
341
+ end
342
+
287
343
  def namespace_sql(table_name)
288
344
  (table_name.to_s =~ /(.*)[.]/) ? "'#{$1}'" : "ANY (current_schemas(false))"
289
345
  end
@@ -49,6 +49,16 @@ module SchemaPlus
49
49
  @backref_fks = Hash.new{ |h, k| h[k] = [] }
50
50
  @dump_dependencies = {}
51
51
 
52
+ if @connection.respond_to?(:enums)
53
+ @connection.enums.each do |schema, name, values|
54
+ params = [name.inspect]
55
+ params << values.map(&:inspect).join(', ')
56
+ params << ":schema => #{schema.inspect}" if schema != 'public'
57
+
58
+ stream.puts " create_enum #{params.join(', ')}"
59
+ end
60
+ end
61
+
52
62
  tables_without_schema_plus(nil)
53
63
 
54
64
  @connection.views.each do |view_name|
@@ -1,3 +1,3 @@
1
1
  module SchemaPlus
2
- VERSION = "1.5.3"
2
+ VERSION = "1.6.0"
3
3
  end
data/runspecs CHANGED
@@ -47,7 +47,7 @@ OptionParser.new do |opts|
47
47
  o.db_adapters = DB_ADAPTERS
48
48
  end
49
49
 
50
- opts.on("--quick", "quick run on Postgres, ruby #{RUBY_VERSIONS.last} and rails #{RAILS_VERSIONS.last}") do
50
+ opts.on("--quick", "quick run on PostgreSQL, ruby #{RUBY_VERSIONS.last} and rails #{RAILS_VERSIONS.last}") do
51
51
  o.ruby_versions = [RUBY_VERSIONS.last]
52
52
  o.rails_versions = [RAILS_VERSIONS.last]
53
53
  o.db_adapters = ["postgresql"]
@@ -70,14 +70,12 @@ describe "Column definition" do
70
70
  end
71
71
  end
72
72
 
73
- if SchemaPlusHelpers.mysql?
74
- it "should raise an error" do
75
- expect(@raised_argument_error).to be_a ArgumentError
76
- end
77
- else
78
- it "should use NOW() as the default" do
79
- is_expected.to match @nowish
80
- end
73
+ it "should use NOW() as the default", :mysql => :skip do
74
+ is_expected.to match @nowish
75
+ end
76
+
77
+ it "should raise an error", :mysql => :only do
78
+ expect(@raised_argument_error).to be_a ArgumentError
81
79
  end
82
80
  end
83
81
 
@@ -90,29 +88,25 @@ describe "Column definition" do
90
88
  end
91
89
  end
92
90
 
93
- if SchemaPlusHelpers.mysql?
94
- it "should raise an error" do
95
- expect(@raised_argument_error).to be_a ArgumentError
96
- end
97
- else
98
- it "should use NOW() as the default" do
99
- is_expected.to match @nowish
100
- end
91
+ it "should use NOW() as the default", :mysql => :skip do
92
+ is_expected.to match @nowish
93
+ end
94
+
95
+ it "should raise an error", :mysql => :only do
96
+ expect(@raised_argument_error).to be_a ArgumentError
101
97
  end
102
98
  end
103
99
 
104
100
  context "valid expr passed as default" do
105
- if SchemaPlusHelpers.mysql?
106
- it "raises an error" do
107
- expect {
108
- define_test_column(:string, :default => { :expr => "(replace('THIS IS A TEST', 'TEST', 'DOG'))" })
109
- }.to raise_error ArgumentError
110
- end
111
- else
112
- it "uses the expression" do
101
+ it "uses the expression", :mysql => :skip do
102
+ define_test_column(:string, :default => { :expr => "(replace('THIS IS A TEST', 'TEST', 'DOG'))" })
103
+ is_expected.to eq "THIS IS A DOG"
104
+ end
105
+
106
+ it "raises an error", :mysql => :only do
107
+ expect {
113
108
  define_test_column(:string, :default => { :expr => "(replace('THIS IS A TEST', 'TEST', 'DOG'))" })
114
- is_expected.to eq "THIS IS A DOG"
115
- end
109
+ }.to raise_error ArgumentError
116
110
  end
117
111
  end
118
112
 
data/spec/column_spec.rb CHANGED
@@ -101,32 +101,30 @@ describe "Column" do
101
101
  create_table(User, :alpha => { :default => "gabba" }, :beta => {})
102
102
  end
103
103
 
104
- if SchemaPlusHelpers.sqlite3?
105
- it "creating a record should raise an error" do
106
- expect { User.create!(:alpha => ActiveRecord::DB_DEFAULT, :beta => "hello") }.to raise_error ActiveRecord::StatementInvalid
107
- end
108
- it "updating a record should raise an error" do
109
- u = User.create!(:alpha => "hey", :beta => "hello")
110
- expect { u.update_attributes(:alpha => ActiveRecord::DB_DEFAULT, :beta => "goodbye") }.to raise_error ActiveRecord::StatementInvalid
111
- end
112
- else
104
+ it "creating a record should respect default expression", :sqlite3 => :skip do
105
+ User.create!(:alpha => ActiveRecord::DB_DEFAULT, :beta => "hello")
106
+ expect(User.last.alpha).to eq("gabba")
107
+ expect(User.last.beta).to eq("hello")
108
+ end
113
109
 
114
- it "creating a record should respect default expression" do
115
- User.create!(:alpha => ActiveRecord::DB_DEFAULT, :beta => "hello")
116
- expect(User.last.alpha).to eq("gabba")
117
- expect(User.last.beta).to eq("hello")
118
- end
110
+ it "creating a record should raise an error", :sqlite3 => :only do
111
+ expect { User.create!(:alpha => ActiveRecord::DB_DEFAULT, :beta => "hello") }.to raise_error ActiveRecord::StatementInvalid
112
+ end
119
113
 
120
- it "updating a record should respect default expression" do
121
- u = User.create!(:alpha => "hey", :beta => "hello")
122
- u.reload
123
- expect(u.alpha).to eq("hey")
124
- expect(u.beta).to eq("hello")
125
- u.update_attributes(:alpha => ActiveRecord::DB_DEFAULT, :beta => "goodbye")
126
- u.reload
127
- expect(u.alpha).to eq("gabba")
128
- expect(u.beta).to eq("goodbye")
129
- end
114
+ it "updating a record should respect default expression", :sqlite3 => :skip do
115
+ u = User.create!(:alpha => "hey", :beta => "hello")
116
+ u.reload
117
+ expect(u.alpha).to eq("hey")
118
+ expect(u.beta).to eq("hello")
119
+ u.update_attributes(:alpha => ActiveRecord::DB_DEFAULT, :beta => "goodbye")
120
+ u.reload
121
+ expect(u.alpha).to eq("gabba")
122
+ expect(u.beta).to eq("goodbye")
123
+ end
124
+
125
+ it "updating a record should raise an error", :sqlite3 => :only do
126
+ u = User.create!(:alpha => "hey", :beta => "hello")
127
+ expect { u.update_attributes(:alpha => ActiveRecord::DB_DEFAULT, :beta => "goodbye") }.to raise_error ActiveRecord::StatementInvalid
130
128
  end
131
129
  end
132
130
 
@@ -6,7 +6,7 @@ ActiveRecord::Base.logger = Logger.new(File.open("postgresql.log", "w"))
6
6
  ActiveRecord::Base.configurations = {
7
7
  'schema_plus' => {
8
8
  :adapter => 'postgresql',
9
- :username => ENV['POSTGRES_DB_USER'],
9
+ :username => ENV['POSTGRESQL_DB_USER'],
10
10
  :database => 'schema_plus_test',
11
11
  :min_messages => 'warning'
12
12
  }
data/spec/enum_spec.rb ADDED
@@ -0,0 +1,132 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ def enum_fields(name, schema = 'public')
4
+ sql = <<-SQL
5
+ SELECT array_to_string(array_agg(E.enumlabel ORDER BY enumsortorder), ' ') AS "values"
6
+ FROM pg_enum E
7
+ JOIN pg_type T ON E.enumtypid = T.oid
8
+ JOIN pg_namespace N ON N.oid = T.typnamespace
9
+ WHERE N.nspname = '#{schema}' AND T.typname = '#{name}'
10
+ GROUP BY T.oid;
11
+ SQL
12
+
13
+ data = ActiveRecord::Base.connection.select_all(sql)
14
+ return nil if data.empty?
15
+ data[0]['values'].split(' ')
16
+ end
17
+
18
+ describe 'enum', :postgresql => :only do
19
+ before(:all) do ActiveRecord::Migration.verbose = false end
20
+
21
+ let(:migration) { ActiveRecord::Migration }
22
+
23
+ describe 'enums' do
24
+ it 'should return all enums' do
25
+ begin
26
+ migration.execute 'create schema cmyk'
27
+ migration.create_enum 'color', 'red', 'green', 'blue'
28
+ migration.create_enum 'color', 'cyan', 'magenta', 'yellow', 'black', schema: 'cmyk'
29
+
30
+ expect(migration.enums).to match_array [['cmyk', 'color', %w|cyan magenta yellow black|], ['public', 'color', %w|red green blue|]]
31
+ ensure
32
+ migration.drop_enum 'color'
33
+ migration.execute 'drop schema cmyk cascade'
34
+ end
35
+ end
36
+ end
37
+
38
+ describe 'create_enum' do
39
+ it 'should create enum with given values' do
40
+ begin
41
+ migration.create_enum 'color', *%w|red green blue|
42
+ expect(enum_fields('color')).to eq(%w|red green blue|)
43
+ ensure
44
+ migration.execute 'DROP TYPE IF EXISTS color'
45
+ end
46
+ end
47
+
48
+ it 'should create enum with schema' do
49
+ begin
50
+ migration.execute 'CREATE SCHEMA colors'
51
+ migration.create_enum 'color', *%|red green blue|, schema: 'colors'
52
+ expect(enum_fields('color', 'colors')).to eq(%w|red green blue|)
53
+ ensure
54
+ migration.execute 'DROP SCHEMA IF EXISTS colors CASCADE'
55
+ end
56
+ end
57
+
58
+ it 'should escape enum value' do
59
+ begin
60
+ migration.create_enum('names', "O'Neal")
61
+ expect(enum_fields('names')).to eq(["O'Neal"])
62
+ ensure
63
+ migration.execute "DROP TYPE IF EXISTS names"
64
+ end
65
+ end
66
+
67
+ it 'should escape schame name and enum name' do
68
+ begin
69
+ migration.execute 'CREATE SCHEMA "select"'
70
+ migration.create_enum 'where', *%|red green blue|, schema: 'select'
71
+ expect(enum_fields('where', 'select')).to eq(%w|red green blue|)
72
+ ensure
73
+ migration.execute 'DROP SCHEMA IF EXISTS "select" CASCADE'
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ describe 'alter_enum' do
80
+ before(:each) do migration.create_enum('color', 'red', 'green', 'blue') end
81
+ after(:each) do migration.execute 'DROP TYPE IF EXISTS color' end
82
+
83
+ it 'should add new value after all values' do
84
+ migration.alter_enum('color', 'magenta')
85
+ expect(enum_fields('color')).to eq(%w|red green blue magenta|)
86
+ end
87
+
88
+ it 'should add new value after existed' do
89
+ migration.alter_enum('color', 'magenta', after: 'red')
90
+ expect(enum_fields('color')).to eq(%w|red magenta green blue|)
91
+ end
92
+
93
+ it 'should add new value before existed' do
94
+ migration.alter_enum('color', 'magenta', before: 'green')
95
+ expect(enum_fields('color')).to eq(%w|red magenta green blue|)
96
+ end
97
+
98
+ it 'should add new value within given schema' do
99
+ begin
100
+ migration.execute 'CREATE SCHEMA colors'
101
+ migration.create_enum('color', 'red', schema: 'colors')
102
+ migration.alter_enum('color', 'green', schema: 'colors')
103
+
104
+ expect(enum_fields('color', 'colors')).to eq(%w|red green|)
105
+ ensure
106
+ migration.execute 'DROP SCHEMA colors CASCADE'
107
+ end
108
+ end
109
+ end
110
+
111
+ describe 'drop_enum' do
112
+ it 'should drop enum with given name' do
113
+ migration.execute "CREATE TYPE color AS ENUM ('red', 'blue')"
114
+ expect(enum_fields('color')).to eq(%w|red blue|)
115
+ migration.drop_enum('color')
116
+
117
+ expect(enum_fields('color')).to be_nil
118
+ end
119
+
120
+ it 'should drop enum within given name and schema' do
121
+ begin
122
+ migration.execute "CREATE SCHEMA colors; CREATE TYPE colors.color AS ENUM ('red', 'blue')"
123
+ expect(enum_fields('color', 'colors')).to eq(%w|red blue|)
124
+ migration.drop_enum('color', schema: 'colors')
125
+
126
+ expect(enum_fields('color', 'colors')).to be_nil
127
+ ensure
128
+ migration.execute "DROP SCHEMA colors CASCADE"
129
+ end
130
+ end
131
+ end
132
+ end
@@ -79,25 +79,12 @@ describe "Foreign Key" do
79
79
  class Comment < ::ActiveRecord::Base ; end
80
80
  end
81
81
 
82
- if SchemaPlusHelpers.sqlite3?
83
82
 
84
- it "raises an exception when attempting to add" do
85
- expect {
86
- add_foreign_key(:posts, :author_id, :users, :id, :on_update => :cascade, :on_delete => :restrict)
87
- }.to raise_error(NotImplementedError)
88
- end
89
-
90
- it "raises an exception when attempting to remove" do
91
- expect {
92
- remove_foreign_key(:posts, "dummy")
93
- }.to raise_error(NotImplementedError)
94
- end
95
-
96
- else
83
+ context "works", :sqlite3 => :skip do
97
84
 
98
85
  context "when is added", "posts(author_id)" do
99
86
 
100
- before(:each) do
87
+ before(:each) do
101
88
  add_foreign_key(:posts, :author_id, :users, :id, :on_update => :cascade, :on_delete => :restrict)
102
89
  end
103
90
 
@@ -186,6 +173,22 @@ describe "Foreign Key" do
186
173
  end
187
174
 
188
175
  end
176
+
177
+ context "raises an exception", :sqlite3 => :only do
178
+
179
+ it "when attempting to add" do
180
+ expect {
181
+ add_foreign_key(:posts, :author_id, :users, :id, :on_update => :cascade, :on_delete => :restrict)
182
+ }.to raise_error(NotImplementedError)
183
+ end
184
+
185
+ it "when attempting to remove" do
186
+ expect {
187
+ remove_foreign_key(:posts, "dummy")
188
+ }.to raise_error(NotImplementedError)
189
+ end
190
+
191
+ end
189
192
  end
190
193
 
191
194
  protected