activerecord-pg_enum 0.0.1 → 0.1.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
  SHA256:
3
- metadata.gz: 67d75573d2938384fe7b152068e7ea8574c06edd54a568288d32fc02e97ba91d
4
- data.tar.gz: 8eb7a669608474a001058437252519035b6a59d4663ab83aab470b92603f3869
3
+ metadata.gz: 33a876e540cf1813b1d54ed406ce47ef39c49168e45967452e587f3e34617348
4
+ data.tar.gz: acd215db0882fac1c90303721b1118b06a036f006e7b4eb66a1efbb6df5d781c
5
5
  SHA512:
6
- metadata.gz: da008c7e1bbc9304dd4ce5570b4800abefc6e1caca83d20c11fa1bdf3e29e8665ff6184f569edde7a1b106b5b4976ad23eb3dc4dc62b7c2d8854b66935f5483a
7
- data.tar.gz: dd7f6e35923433c9cc97cc44560904407a04c1f50036fcb3e5ec13b8a9be41e65de3b1b67632dbc0d0f98130e36fedeeee4407070e15e36a111bde4e19ec9984
6
+ metadata.gz: 4d897a53720eebf23d808eb4a5c927db868a69055d6f77919a0f3f20d6a8ece2a27be4d53edc0e94d767e17711b8e50d24e30055f37da8985e2e3ecefe26bab9
7
+ data.tar.gz: 5c733a6b3c41a56325c290ee6f46756f18217f3d64b0a8e9b70d9bccbe4a6b01be893f788ddf3fc4ccb92c1de64573b590b11a95eb226e4252077b41b65a98e3
data/.travis.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
+ - 2.1
4
5
  - 2.5
5
6
  services:
6
7
  - postgresql
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2018-08-12
10
+ ### Added
11
+ - `add_to_enum` for modifying existing types
12
+ - `ActiveRecord::Migration::CommandRecorder` is patched to make `create_enum`, and `drop_enum` reversible.
13
+
14
+ ### Changed
15
+ - Ruby 2.1 is defined as the earliest supported version (for kwargs)
16
+ - `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#enum_types` returns a Hash instead of a nested Array
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
18
18
  f.match(%r{^(test|spec|features)/})
19
19
  end
20
20
 
21
+ spec.required_ruby_version = ">= 2.1"
22
+
21
23
  spec.bindir = "exe"
22
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
25
  spec.require_paths = ["lib"]
@@ -5,6 +5,7 @@ require "active_record/connection_adapters/postgresql_adapter"
5
5
  require "active_support/lazy_load_hooks"
6
6
 
7
7
  ActiveSupport.on_load(:active_record) do
8
+ require "active_record/pg_enum/command_recorder"
8
9
  require "active_record/pg_enum/postgresql_adapter"
9
10
  require "active_record/pg_enum/schema_dumper"
10
11
  require "active_record/pg_enum/schema_statements"
@@ -16,4 +17,5 @@ ActiveSupport.on_load(:active_record) do
16
17
 
17
18
  ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.include ActiveRecord::PGEnum::PostgreSQLAdapter
18
19
  ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.include ActiveRecord::PGEnum::SchemaStatements
20
+ ActiveRecord::Migration::CommandRecorder.include ActiveRecord::PGEnum::CommandRecorder
19
21
  end
@@ -0,0 +1,48 @@
1
+ module ActiveRecord
2
+ module PGEnum
3
+ # ActiveRecord::Migration::CommandRecorder is a class used by reversible migrations.
4
+ # It captures the forward migration commands and translates them into their inverse
5
+ # by way of some simple metaprogramming.
6
+ #
7
+ # The Migrator class uses CommandRecorder during the reverse migration instead of
8
+ # the connection object. Forward migration calls are translated to their inverse
9
+ # where possible, and then forwarded to the connetion. Irreversible migrations
10
+ # raise an exception.
11
+ #
12
+ # Known schema statement methods are metaprogrammed into an inverse method like so:
13
+ #
14
+ # create_table => invert_create_table
15
+ #
16
+ # which returns:
17
+ #
18
+ # [:drop_table, args.first]
19
+ module CommandRecorder
20
+ def create_enum(*args, &block)
21
+ record(:create_enum, args, &block)
22
+ end
23
+
24
+ def drop_enum(*args, &block)
25
+ record(:drop_enum, args, &block)
26
+ end
27
+
28
+ def add_enum_value(*args, &block)
29
+ record(:add_enum_value, args, &block)
30
+ end
31
+
32
+ private
33
+
34
+ def invert_create_enum(args)
35
+ [:drop_enum, args]
36
+ end
37
+
38
+ def invert_drop_enum(args)
39
+ raise ActiveRecord::IrreversibleMigration, "drop_enum is only reversible if given a list of values" unless args.length > 1
40
+ [:create_enum, args]
41
+ end
42
+
43
+ def invert_add_enum_value(args)
44
+ raise ActiveRecord::IrreversibleMigration, "ENUM values cannot be removed once added. Drop and Replace it instead at your own risk."
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,6 +1,11 @@
1
1
  module ActiveRecord
2
2
  module PGEnum
3
3
  module PostgreSQLAdapter
4
+ # Helper method used by the monkeypatch internals. Provides a hash of ENUM types as they exist currently.
5
+ #
6
+ # Example:
7
+ #
8
+ # { "foo_type" => ["foo", "bar", "baz"] }
4
9
  def enum_types
5
10
  res = exec_query(<<-SQL.strip_heredoc, "SCHEMA").cast_values
6
11
  SELECT t.typname AS enum_name, string_agg(e.enumlabel, ' ' ORDER BY e.enumsortorder) AS enum_value
@@ -11,8 +16,9 @@ module ActiveRecord
11
16
  GROUP BY enum_name
12
17
  SQL
13
18
 
14
- res.map do |(name, values)|
15
- [name, values.split(" ")]
19
+ res.inject({}) do |memo, (name, values)|
20
+ memo[name] = values.split(" ")
21
+ memo
16
22
  end
17
23
  end
18
24
  end
@@ -13,13 +13,14 @@ module ActiveRecord
13
13
 
14
14
  stream.puts " # These are custom enum types that must be created before they can be used in the schema definition"
15
15
 
16
- enum_types.each do |enum_type|
17
- stream.puts %Q{ create_enum "#{enum_type.first}", "#{enum_type.second.join("\", \"")}"}
16
+ enum_types.each do |name, definition|
17
+ stream.puts %Q{ create_enum "#{name}", "#{definition.join("\", \"")}"}
18
18
  end
19
19
 
20
20
  stream.puts
21
21
  end
22
22
 
23
+ # Gathers the arguments needed for the column line inside the create_table block.
23
24
  def column_spec(column)
24
25
  if column.type == :enum
25
26
  ["column", [column.sql_type.inspect, prepare_column_options(column)]]
@@ -28,6 +29,7 @@ module ActiveRecord
28
29
  end
29
30
  end
30
31
 
32
+ # Takes a column specification in Object form and serializes it into a String.
31
33
  def format_colspec(colspec)
32
34
  case colspec
33
35
  when String
@@ -1,13 +1,43 @@
1
1
  module ActiveRecord
2
2
  module PGEnum
3
3
  module SchemaStatements
4
+ # Create a new ENUM type, with an arbitrary number of values.
5
+ #
6
+ # Example:
7
+ #
8
+ # create_enum("foo_type", "foo", "bar", "baz")
4
9
  def create_enum(name, *values)
5
10
  execute "CREATE TYPE #{name} AS ENUM (#{values.map { |v| "'#{v}'" }.join(", ")})"
6
11
  end
7
12
 
8
- def drop_enum(name)
13
+ # Drop an ENUM type from the database.
14
+ def drop_enum(name, *values_for_revert)
9
15
  execute "DROP TYPE #{name}"
10
16
  end
17
+
18
+ # Add a new value to an existing ENUM type.
19
+ # Only one value at a time is supported by PostgreSQL.
20
+ #
21
+ # Options:
22
+ # before: add value BEFORE the given value
23
+ # after: add value AFTER the given value
24
+ #
25
+ # Example:
26
+ #
27
+ # add_enum_value("foo_type", "quux", before: "bar")
28
+ def add_enum_value(type, value, before: nil, after: nil)
29
+ cmd = "ALTER TYPE #{type} ADD VALUE '#{value}'"
30
+
31
+ if before && after
32
+ raise ArgumentError, "Cannot have both :before and :after at the same time"
33
+ elsif before
34
+ cmd << " BEFORE '#{before}'"
35
+ elsif after
36
+ cmd << " AFTER '#{after}'"
37
+ end
38
+
39
+ execute cmd
40
+ end
11
41
  end
12
42
  end
13
43
  end
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module PGEnum
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-pg_enum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Lassek
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-06 00:00:00.000000000 Z
11
+ date: 2018-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -119,6 +119,7 @@ files:
119
119
  - ".rspec"
120
120
  - ".rubocop.yml"
121
121
  - ".travis.yml"
122
+ - CHANGELOG.md
122
123
  - Gemfile
123
124
  - LICENSE
124
125
  - README.md
@@ -127,6 +128,7 @@ files:
127
128
  - bin/console
128
129
  - bin/setup
129
130
  - lib/active_record/pg_enum.rb
131
+ - lib/active_record/pg_enum/command_recorder.rb
130
132
  - lib/active_record/pg_enum/helper.rb
131
133
  - lib/active_record/pg_enum/postgresql_adapter.rb
132
134
  - lib/active_record/pg_enum/schema_dumper.rb
@@ -145,7 +147,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
145
147
  requirements:
146
148
  - - ">="
147
149
  - !ruby/object:Gem::Version
148
- version: '0'
150
+ version: '2.1'
149
151
  required_rubygems_version: !ruby/object:Gem::Requirement
150
152
  requirements:
151
153
  - - ">="
@@ -153,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
155
  version: '0'
154
156
  requirements: []
155
157
  rubyforge_project:
156
- rubygems_version: 2.7.6
158
+ rubygems_version: 2.7.7
157
159
  signing_key:
158
160
  specification_version: 4
159
161
  summary: Integrate PostgreSQL's enumerated types with the Rails enum feature