fx 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f93c422563a987d0fe73c448281d14f34380b5eb8fd90b1673083f72497746f
4
- data.tar.gz: 0ef187b03d6dc9fd3930744adff67f8b7275cc9a75b0d13195c190d4050821fd
3
+ metadata.gz: d43846b73aa7466215723a28e398085fdcbb0a99f8b376cdda619abf91a8c8ba
4
+ data.tar.gz: 38de2d17cfca402804b1b9fa2148488abeadb8e4da7f28cfd0850601d99f7fa5
5
5
  SHA512:
6
- metadata.gz: 720481484ebb0d87e0b1f18d95a0eb73aa3675b847f302218c942433d8c037170fd2f3ca7c5b32336d3ef4c284faf1d768b7a0064eed7918d3b130b08bb6c2e7
7
- data.tar.gz: 84e37e4a184a75b62d332b882bb759c9561938a8988fe5375581562c258a85e23c1b94c128265757e7010a5ecbc2b2dad1e10cd9e0eb8ae4c4184523cb4fb85e
6
+ metadata.gz: 586e3528b79ab504d0667136e819488c1b6338de3e765baaabcf545570d40ea816e5a2ec052be33d1ed48c4a3492cffd8cc1dafed39c1d011730c439f40a5d30
7
+ data.tar.gz: f648185b7c8857263415a7c8287eb0f258d195cca05a481c86ceff3c7bdd818bddb8eac65258c2f8023f8cd6716f2458145e5a9094e25806f2569606d86524d4
@@ -1,5 +1,9 @@
1
1
  addons:
2
- postgresql: "9.4"
2
+ postgresql: "10"
3
+ apt:
4
+ packages:
5
+ - postgresql-10
6
+ - postgresql-client-10
3
7
  before_install:
4
8
  - "echo '--colour' > ~/.rspec"
5
9
  - "echo 'gem: --no-document' > ~/.gemrc"
@@ -23,12 +27,13 @@ gemfile:
23
27
  - gemfiles/rails50.gemfile
24
28
  - gemfiles/rails51.gemfile
25
29
  - gemfiles/rails52.gemfile
30
+ - gemfiles/rails60.gemfile
26
31
  - gemfiles/rails_edge.gemfile
27
32
  matrix:
28
33
  allow_failures:
29
34
  - gemfile: gemfiles/rails_edge.gemfile
30
- - gemfile: gemfiles/rails40.gemfile
31
- - gemfile: gemfiles/rails41.gemfile
32
35
  exclude:
33
36
  - rvm: 2.4
34
37
  gemfile: gemfiles/rails_edge.gemfile
38
+ - rvm: 2.4
39
+ gemfile: gemfiles/rails60.gemfile
data/Appraisals CHANGED
@@ -20,6 +20,11 @@ if RUBY_VERSION > "2.2.0"
20
20
  gem "railties", "~> 5.2"
21
21
  end
22
22
 
23
+ appraise "rails60" do
24
+ gem "activerecord", "~> 6.0"
25
+ gem "railties", "~> 6.0"
26
+ end
27
+
23
28
  appraise "rails-edge" do
24
29
  gem "rails", github: "rails/rails"
25
30
  gem "arel", :github => "rails/arel"
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright 2016 Teo Ljungberg
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -84,3 +84,30 @@ def change
84
84
  drop_function :uppercase_users_name, revert_to_version: 2
85
85
  end
86
86
  ```
87
+
88
+ ## What if I need to use a function as the default value of a column?
89
+
90
+ You need to set F(x) to dump the functions in the beginning of db/schema.rb in a
91
+ initializer:
92
+
93
+ ```ruby
94
+ # config/initializers/fx.rb
95
+ Fx.configure do |config|
96
+ config.dump_functions_at_beginning_of_schema = true
97
+ end
98
+ ```
99
+
100
+ And then you can use a lambda in your migration file:
101
+
102
+ ```ruby
103
+ create_table :my_table do |t|
104
+ t.string :my_column, default: -> { "my_function()" }
105
+ end
106
+ ```
107
+
108
+ That's how you tell Rails to use the default as a literal SQL for the default
109
+ column value instead of a plain string.
110
+
111
+ ## Contributing
112
+
113
+ See [contributing](CONTRIBUTING.md) for more details.
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 6.0"
6
+ gem "railties", "~> 6.0"
7
+
8
+ gemspec path: "../"
data/lib/fx.rb CHANGED
@@ -7,10 +7,32 @@ require "fx/function"
7
7
  require "fx/statements"
8
8
  require "fx/schema_dumper"
9
9
  require "fx/trigger"
10
+ require "fx/railtie"
10
11
 
11
12
  # F(x) adds methods `ActiveRecord::Migration` to create and manage database
12
13
  # triggers and functions in Rails applications.
13
14
  module Fx
15
+ # Hooks Fx into Rails.
16
+ #
17
+ # Enables fx migration methods, migration reversability, and `schema.rb`
18
+ # dumping.
19
+ def self.load
20
+ ActiveRecord::Migration::CommandRecorder.send(
21
+ :include,
22
+ Fx::CommandRecorder,
23
+ )
24
+
25
+ ActiveRecord::SchemaDumper.send(
26
+ :prepend,
27
+ Fx::SchemaDumper,
28
+ )
29
+
30
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.send(
31
+ :include,
32
+ Fx::Statements,
33
+ )
34
+ end
35
+
14
36
  # The current database adapter used by F(x).
15
37
  #
16
38
  # This defaults to {Fx::Adapters::Postgres} but can be overridden
@@ -125,7 +125,11 @@ module Fx
125
125
  #
126
126
  # @return [void]
127
127
  def drop_function(name)
128
- execute "DROP FUNCTION #{name}();"
128
+ if support_drop_function_without_args
129
+ execute "DROP FUNCTION #{name};"
130
+ else
131
+ execute "DROP FUNCTION #{name}();"
132
+ end
129
133
  end
130
134
 
131
135
  # Drops the trigger from the database
@@ -150,6 +154,14 @@ module Fx
150
154
  def connection
151
155
  Connection.new(connectable.connection)
152
156
  end
157
+
158
+ def support_drop_function_without_args
159
+ # https://www.postgresql.org/docs/9.6/sql-dropfunction.html
160
+ # https://www.postgresql.org/docs/10/sql-dropfunction.html
161
+
162
+ pg_connection = connectable.connection.raw_connection
163
+ pg_connection.server_version >= 10_00_00
164
+ end
153
165
  end
154
166
  end
155
167
  end
@@ -17,7 +17,10 @@ module Fx
17
17
  ON pn.oid = pp.pronamespace
18
18
  LEFT JOIN pg_depend pd
19
19
  ON pd.objid = pp.oid AND pd.deptype = 'e'
20
+ LEFT JOIN pg_aggregate pa
21
+ ON pa.aggfnoid = pp.oid
20
22
  WHERE pn.nspname = 'public' AND pd.objid IS NULL
23
+ AND pa.aggfnoid IS NULL
21
24
  ORDER BY pp.oid;
22
25
  EOS
23
26
 
@@ -22,8 +22,3 @@ module Fx
22
22
  end
23
23
  end
24
24
  end
25
-
26
- ActiveRecord::Migration::CommandRecorder.send(
27
- :include,
28
- Fx::CommandRecorder,
29
- )
@@ -17,6 +17,7 @@ module Fx
17
17
  # ```
18
18
  # Fx.configure do |config|
19
19
  # config.database = Fx::Adapters::Postgres
20
+ # config.dump_functions_at_beginning_of_schema = true
20
21
  # end
21
22
  # ```
22
23
  def self.configure
@@ -31,8 +32,17 @@ module Fx
31
32
  # @return Fx adapter
32
33
  attr_accessor :database
33
34
 
35
+ # Prioritizes the order in the schema.rb of functions before other
36
+ # statements in order to make directly schema load work when using functions
37
+ # in statements below, i.e.: default column values.
38
+ #
39
+ # Defaults to false
40
+ # @return Boolean
41
+ attr_accessor :dump_functions_at_beginning_of_schema
42
+
34
43
  def initialize
35
44
  @database = Fx::Adapters::Postgres.new
45
+ @dump_functions_at_beginning_of_schema = false
36
46
  end
37
47
  end
38
48
  end
@@ -0,0 +1,15 @@
1
+ require "rails/railtie"
2
+
3
+ module Fx
4
+ # Automatically initializes Fx in the context of a Rails application when
5
+ # ActiveRecord is loaded.
6
+ #
7
+ # @see Fx.load
8
+ class Railtie < Rails::Railtie
9
+ initializer "fx.load" do
10
+ ActiveSupport.on_load :active_record do
11
+ Fx.load
12
+ end
13
+ end
14
+ end
15
+ end
@@ -8,8 +8,3 @@ module Fx
8
8
  include Trigger
9
9
  end
10
10
  end
11
-
12
- ActiveRecord::SchemaDumper.send(
13
- :prepend,
14
- Fx::SchemaDumper,
15
- )
@@ -5,15 +5,24 @@ module Fx
5
5
  # @api private
6
6
  module Function
7
7
  def tables(stream)
8
+ if Fx.configuration.dump_functions_at_beginning_of_schema
9
+ functions(stream)
10
+ empty_line(stream)
11
+ end
12
+
8
13
  super
9
- functions(stream)
10
- end
11
14
 
12
- def functions(stream)
13
- if dumpable_functions_in_database.any?
14
- stream.puts
15
+ unless Fx.configuration.dump_functions_at_beginning_of_schema
16
+ functions(stream)
17
+ empty_line(stream)
15
18
  end
19
+ end
20
+
21
+ def empty_line(stream)
22
+ stream.puts if dumpable_functions_in_database.any?
23
+ end
16
24
 
25
+ def functions(stream)
17
26
  dumpable_functions_in_database.each do |function|
18
27
  stream.puts(function.to_schema)
19
28
  end
@@ -9,8 +9,3 @@ module Fx
9
9
  include Trigger
10
10
  end
11
11
  end
12
-
13
- ActiveRecord::ConnectionAdapters::AbstractAdapter.send(
14
- :include,
15
- Fx::Statements,
16
- )
@@ -1,4 +1,4 @@
1
1
  module Fx
2
2
  # @api private
3
- VERSION = "0.5.0"
3
+ VERSION = "0.6.0"
4
4
  end
@@ -2,6 +2,8 @@ Description:
2
2
  Create a new database function for your application. This will create a new
3
3
  function definition file and the accompanying migration.
4
4
 
5
+ When --no-migration is passed, skips generating a migration.
6
+
5
7
  Examples:
6
8
  rails generate fx:function test
7
9
 
@@ -8,6 +8,8 @@ module Fx
8
8
  include Rails::Generators::Migration
9
9
  source_root File.expand_path("../templates", __FILE__)
10
10
 
11
+ class_option :migration, type: :boolean
12
+
11
13
  def create_functions_directory
12
14
  unless function_definition_path.exist?
13
15
  empty_directory(function_definition_path)
@@ -23,6 +25,7 @@ module Fx
23
25
  end
24
26
 
25
27
  def create_migration_file
28
+ return if skip_migration_creation?
26
29
  if updating_existing_function?
27
30
  migration_template(
28
31
  "db/migrate/update_function.erb",
@@ -61,7 +64,7 @@ module Fx
61
64
 
62
65
  def activerecord_migration_class
63
66
  if ActiveRecord::Migration.respond_to?(:current_version)
64
- "ActiveRecord::Migration[5.0]"
67
+ "ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]"
65
68
  else
66
69
  "ActiveRecord::Migration"
67
70
  end
@@ -101,6 +104,16 @@ module Fx
101
104
  def previous_definition
102
105
  Fx::Definition.new(name: file_name, version: previous_version)
103
106
  end
107
+
108
+ # Skip creating migration file if:
109
+ # - migrations option is nil or false
110
+ def skip_migration_creation?
111
+ !migration
112
+ end
113
+
114
+ def migration
115
+ options[:migration]
116
+ end
104
117
  end
105
118
  end
106
119
  end
@@ -5,6 +5,8 @@ Description:
5
5
  If a trigger of the given name already exists, create a new version of the
6
6
  trigger and a migration to replace the old version with the new.
7
7
 
8
+ When --no-migration is passed, skips generating a migration.
9
+
8
10
  Examples:
9
11
 
10
12
  rails generate fx:trigger test
@@ -9,6 +9,8 @@ module Fx
9
9
  source_root File.expand_path("../templates", __FILE__)
10
10
  argument :table_name, type: :hash, required: true
11
11
 
12
+ class_option :migration, type: :boolean
13
+
12
14
  def create_triggers_directory
13
15
  unless trigger_definition_path.exist?
14
16
  empty_directory(trigger_definition_path)
@@ -20,6 +22,7 @@ module Fx
20
22
  end
21
23
 
22
24
  def create_migration_file
25
+ return if skip_migration_creation?
23
26
  if updating_existing_trigger?
24
27
  migration_template(
25
28
  "db/migrate/update_trigger.erb",
@@ -58,7 +61,7 @@ module Fx
58
61
 
59
62
  def activerecord_migration_class
60
63
  if ActiveRecord::Migration.respond_to?(:current_version)
61
- "ActiveRecord::Migration[5.0]"
64
+ "ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]"
62
65
  else
63
66
  "ActiveRecord::Migration"
64
67
  end
@@ -111,6 +114,16 @@ module Fx
111
114
  def trigger_definition_path
112
115
  @_trigger_definition_path ||= Rails.root.join(*["db", "triggers"])
113
116
  end
117
+
118
+ # Skip creating migration file if:
119
+ # - migrations option is nil or false
120
+ def skip_migration_creation?
121
+ !migration
122
+ end
123
+
124
+ def migration
125
+ options[:migration]
126
+ end
114
127
  end
115
128
  end
116
129
  end
@@ -34,4 +34,24 @@ describe "User manages functions" do
34
34
  result = execute("SELECT * FROM test() AS result")
35
35
  expect(result).to eq("result" => "testest")
36
36
  end
37
+
38
+ it "handles functions with arguments" do
39
+ successfully "rails generate fx:function adder"
40
+ write_function_definition "adder_v01", <<-EOS
41
+ CREATE FUNCTION adder(x int, y int)
42
+ RETURNS int AS $$
43
+ BEGIN
44
+ RETURN $1 + $2;
45
+ END;
46
+ $$ LANGUAGE plpgsql;
47
+ EOS
48
+ successfully "rake db:migrate"
49
+
50
+ result = execute("SELECT * FROM adder(1, 2) AS result")
51
+ result["result"] = result["result"].to_i
52
+ expect(result).to eq("result" => 3)
53
+
54
+ successfully "rails destroy fx:function adder"
55
+ successfully "rake db:migrate"
56
+ end
37
57
  end
@@ -53,22 +53,44 @@ module Fx::Adapters
53
53
  end
54
54
 
55
55
  describe "#drop_function" do
56
- it "successfully drops a function" do
57
- adapter = Postgres.new
58
- adapter.create_function(
59
- <<-EOS
60
- CREATE OR REPLACE FUNCTION test()
61
- RETURNS text AS $$
62
- BEGIN
63
- RETURN 'test';
64
- END;
65
- $$ LANGUAGE plpgsql;
66
- EOS
67
- )
56
+ context "when the function has arguments" do
57
+ it "successfully drops a function with the entire function signature" do
58
+ adapter = Postgres.new
59
+ adapter.create_function(
60
+ <<-EOS
61
+ CREATE FUNCTION adder(x int, y int)
62
+ RETURNS int AS $$
63
+ BEGIN
64
+ RETURN $1 + $2;
65
+ END;
66
+ $$ LANGUAGE plpgsql;
67
+ EOS
68
+ )
69
+
70
+ adapter.drop_function(:adder)
71
+
72
+ expect(adapter.functions.map(&:name)).not_to include("adder")
73
+ end
74
+ end
75
+
76
+ context "when the function does not have arguments" do
77
+ it "successfully drops a function" do
78
+ adapter = Postgres.new
79
+ adapter.create_function(
80
+ <<-EOS
81
+ CREATE OR REPLACE FUNCTION test()
82
+ RETURNS text AS $$
83
+ BEGIN
84
+ RETURN 'test';
85
+ END;
86
+ $$ LANGUAGE plpgsql;
87
+ EOS
88
+ )
68
89
 
69
- adapter.drop_function(:test)
90
+ adapter.drop_function(:test)
70
91
 
71
- expect(adapter.functions.map(&:name)).not_to include("test")
92
+ expect(adapter.functions.map(&:name)).not_to include("test")
93
+ end
72
94
  end
73
95
  end
74
96
 
@@ -3,14 +3,69 @@ require "spec_helper"
3
3
  describe Fx::SchemaDumper::Function, :db do
4
4
  it "dumps a create_function for a function in the database" do
5
5
  sql_definition = <<-EOS
6
- CREATE OR REPLACE FUNCTION test()
6
+ CREATE OR REPLACE FUNCTION my_function()
7
7
  RETURNS text AS $$
8
8
  BEGIN
9
9
  RETURN 'test';
10
10
  END;
11
11
  $$ LANGUAGE plpgsql;
12
12
  EOS
13
+ connection.create_function :my_function, sql_definition: sql_definition
14
+ connection.create_table :my_table
15
+ stream = StringIO.new
16
+ output = stream.string
17
+
18
+ ActiveRecord::SchemaDumper.dump(connection, stream)
19
+
20
+ expect(output).to(
21
+ match(/table "my_table".*function :my_function.*RETURN 'test';/m),
22
+ )
23
+ end
24
+
25
+ it "dumps a create_function for a function in the database" do
26
+ Fx.configuration.dump_functions_at_beginning_of_schema = true
27
+ sql_definition = <<-EOS
28
+ CREATE OR REPLACE FUNCTION my_function()
29
+ RETURNS text AS $$
30
+ BEGIN
31
+ RETURN 'test';
32
+ END;
33
+ $$ LANGUAGE plpgsql;
34
+ EOS
35
+ connection.create_function :my_function, sql_definition: sql_definition
36
+ connection.create_table :my_table
37
+ stream = StringIO.new
38
+ output = stream.string
39
+
40
+ ActiveRecord::SchemaDumper.dump(connection, stream)
41
+
42
+ expect(output).to(
43
+ match(/function :my_function.*RETURN 'test';.*table "my_table"/m),
44
+ )
45
+ ensure
46
+ Fx.configuration.dump_functions_at_beginning_of_schema = false
47
+ end
48
+
49
+ it "does not dump a create_function for aggregates in the database" do
50
+ sql_definition = <<-EOS
51
+ CREATE OR REPLACE FUNCTION test(text, text)
52
+ RETURNS text AS $$
53
+ BEGIN
54
+ RETURN 'test';
55
+ END;
56
+ $$ LANGUAGE plpgsql;
57
+ EOS
58
+
59
+ aggregate_sql_definition = <<-EOS
60
+ CREATE AGGREGATE aggregate_test(text)
61
+ (
62
+ sfunc = test,
63
+ stype = text
64
+ );
65
+ EOS
66
+
13
67
  connection.create_function :test, sql_definition: sql_definition
68
+ connection.execute aggregate_sql_definition
14
69
  stream = StringIO.new
15
70
 
16
71
  ActiveRecord::SchemaDumper.dump(connection, stream)
@@ -18,5 +73,6 @@ describe Fx::SchemaDumper::Function, :db do
18
73
  output = stream.string
19
74
  expect(output).to include "create_function :test, sql_definition: <<-SQL"
20
75
  expect(output).to include "RETURN 'test';"
76
+ expect(output).not_to include "aggregate_test"
21
77
  end
22
78
  end
@@ -13,6 +13,18 @@ describe Fx::Generators::FunctionGenerator, :generator do
13
13
  expect(migration_file(migration)).to contain "CreateFunctionTest"
14
14
  end
15
15
 
16
+ context "when passed --no-migration" do
17
+ it "creates a only function definition file" do
18
+ migration = file("db/migrate/create_function_test.rb")
19
+ function_definition = file("db/functions/test_v01.sql")
20
+
21
+ run_generator ["test", "--no-migration"]
22
+
23
+ expect(function_definition).to exist
24
+ expect(migration_file(migration)).not_to exist
25
+ end
26
+ end
27
+
16
28
  it "updates an existing function" do
17
29
  with_function_definition(
18
30
  name: "test",
@@ -14,6 +14,18 @@ describe Fx::Generators::TriggerGenerator, :generator do
14
14
  expect(migration_file(migration)).to contain "on: :some_table"
15
15
  end
16
16
 
17
+ context "when passed --no-migration" do
18
+ it "creates a only trigger definition file" do
19
+ migration = file("db/migrate/create_trigger_test.rb")
20
+ trigger_definition = file("db/triggers/test_v01.sql")
21
+
22
+ run_generator ["test", "--no-migration"]
23
+
24
+ expect(trigger_definition).to exist
25
+ expect(migration_file(migration)).not_to exist
26
+ end
27
+ end
28
+
17
29
  it "supports naming the table as `on` aswell as `table_name`" do
18
30
  migration = file("db/migrate/create_trigger_test.rb")
19
31
  trigger_definition = file("db/triggers/test_v01.sql")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Teo Ljungberg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-07 00:00:00.000000000 Z
11
+ date: 2020-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal
@@ -196,6 +196,7 @@ files:
196
196
  - Appraisals
197
197
  - CONTRIBUTING.md
198
198
  - Gemfile
199
+ - LICENSE
199
200
  - README.md
200
201
  - Rakefile
201
202
  - bin/appraisal
@@ -209,6 +210,7 @@ files:
209
210
  - gemfiles/rails50.gemfile
210
211
  - gemfiles/rails51.gemfile
211
212
  - gemfiles/rails52.gemfile
213
+ - gemfiles/rails60.gemfile
212
214
  - gemfiles/rails_edge.gemfile
213
215
  - lib/fx.rb
214
216
  - lib/fx/adapters/postgres.rb
@@ -222,6 +224,7 @@ files:
222
224
  - lib/fx/configuration.rb
223
225
  - lib/fx/definition.rb
224
226
  - lib/fx/function.rb
227
+ - lib/fx/railtie.rb
225
228
  - lib/fx/schema_dumper.rb
226
229
  - lib/fx/schema_dumper/function.rb
227
230
  - lib/fx/schema_dumper/trigger.rb
@@ -295,7 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
295
298
  - !ruby/object:Gem::Version
296
299
  version: '0'
297
300
  requirements: []
298
- rubygems_version: 3.0.3
301
+ rubygems_version: 3.1.4
299
302
  signing_key:
300
303
  specification_version: 4
301
304
  summary: Support for database functions and triggers in Rails migrations