fx 0.8.0 → 0.10.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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -7
  3. data/CHANGELOG.md +150 -0
  4. data/CONTRIBUTING.md +3 -3
  5. data/Gemfile +11 -1
  6. data/README.md +2 -0
  7. data/bin/rake +2 -3
  8. data/bin/rspec +13 -3
  9. data/bin/standardrb +27 -0
  10. data/bin/yard +13 -3
  11. data/fx.gemspec +10 -15
  12. data/lib/fx/adapters/postgres/connection.rb +20 -0
  13. data/lib/fx/adapters/postgres/functions.rb +11 -28
  14. data/lib/fx/adapters/postgres/query_executor.rb +34 -0
  15. data/lib/fx/adapters/postgres/triggers.rb +14 -29
  16. data/lib/fx/adapters/postgres.rb +16 -24
  17. data/lib/fx/command_recorder.rb +87 -6
  18. data/lib/fx/configuration.rb +2 -27
  19. data/lib/fx/definition.rb +16 -6
  20. data/lib/fx/function.rb +3 -3
  21. data/lib/fx/schema_dumper.rb +37 -5
  22. data/lib/fx/statements.rb +231 -6
  23. data/lib/fx/trigger.rb +3 -3
  24. data/lib/fx/version.rb +1 -1
  25. data/lib/fx.rb +30 -12
  26. data/lib/generators/fx/function/function_generator.rb +50 -53
  27. data/lib/generators/fx/function/templates/db/migrate/create_function.erb +1 -1
  28. data/lib/generators/fx/function/templates/db/migrate/update_function.erb +1 -1
  29. data/lib/generators/fx/migration_helper.rb +53 -0
  30. data/lib/generators/fx/name_helper.rb +33 -0
  31. data/lib/generators/fx/trigger/templates/db/migrate/create_trigger.erb +1 -1
  32. data/lib/generators/fx/trigger/templates/db/migrate/update_trigger.erb +1 -1
  33. data/lib/generators/fx/trigger/trigger_generator.rb +44 -67
  34. data/lib/generators/fx/version_helper.rb +55 -0
  35. data/spec/acceptance/user_manages_functions_spec.rb +7 -7
  36. data/spec/acceptance/user_manages_triggers_spec.rb +11 -11
  37. data/spec/acceptance_helper.rb +4 -4
  38. data/spec/dummy/config/application.rb +5 -1
  39. data/spec/features/functions/migrations_spec.rb +5 -5
  40. data/spec/features/functions/revert_spec.rb +5 -5
  41. data/spec/features/triggers/migrations_spec.rb +7 -7
  42. data/spec/features/triggers/revert_spec.rb +9 -9
  43. data/spec/fx/adapters/postgres/functions_spec.rb +33 -30
  44. data/spec/fx/adapters/postgres/query_executor_spec.rb +75 -0
  45. data/spec/fx/adapters/postgres/triggers_spec.rb +41 -38
  46. data/spec/fx/adapters/postgres_spec.rb +155 -115
  47. data/spec/fx/command_recorder_spec.rb +27 -25
  48. data/spec/fx/configuration_spec.rb +20 -9
  49. data/spec/fx/definition_spec.rb +31 -39
  50. data/spec/fx/function_spec.rb +45 -48
  51. data/spec/fx/schema_dumper_spec.rb +169 -0
  52. data/spec/fx/statements_spec.rb +217 -0
  53. data/spec/fx/trigger_spec.rb +37 -40
  54. data/spec/fx_spec.rb +28 -0
  55. data/spec/generators/fx/function/function_generator_spec.rb +11 -11
  56. data/spec/generators/fx/migration_helper_spec.rb +133 -0
  57. data/spec/generators/fx/name_helper_spec.rb +114 -0
  58. data/spec/generators/fx/trigger/trigger_generator_spec.rb +45 -22
  59. data/spec/generators/fx/version_helper_spec.rb +157 -0
  60. data/spec/spec_helper.rb +7 -0
  61. data/spec/support/definition_helpers.rb +2 -6
  62. data/spec/support/generator_setup.rb +46 -5
  63. data/spec/support/warning_helper.rb +5 -0
  64. metadata +40 -165
  65. data/lib/fx/command_recorder/arguments.rb +0 -43
  66. data/lib/fx/command_recorder/function.rb +0 -30
  67. data/lib/fx/command_recorder/trigger.rb +0 -30
  68. data/lib/fx/schema_dumper/function.rb +0 -38
  69. data/lib/fx/schema_dumper/trigger.rb +0 -29
  70. data/lib/fx/statements/function.rb +0 -113
  71. data/lib/fx/statements/trigger.rb +0 -144
  72. data/spec/fx/command_recorder/arguments_spec.rb +0 -41
  73. data/spec/fx/schema_dumper/function_spec.rb +0 -78
  74. data/spec/fx/schema_dumper/trigger_spec.rb +0 -40
  75. data/spec/fx/statements/function_spec.rb +0 -103
  76. data/spec/fx/statements/trigger_spec.rb +0 -132
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bfa4dae8b8e550ee4ddc34b4d0d78c50cc085d01662993f0874f804525fdd51f
4
- data.tar.gz: 6e57a6df8b97e7638de3b05d9204c4bdcf2db90b585dfb617a1c2e3492d9f8b5
3
+ metadata.gz: 817dff811b3dc0f946828957f9274117436ac97b273416cfdffdcf7bccf493fd
4
+ data.tar.gz: 88d246804584933f266198d0edf384bfdd09eb0f6e7f57be5d4cbebcb8f7843e
5
5
  SHA512:
6
- metadata.gz: c4cf689e5a1847b7ad45b2679dd45046555f750fb7bc8ed9dc2c473da1e6a6eba344a312fa0b33852197ec7c5d81dc92a3ff416939ba8f5435f8a5da16c928df
7
- data.tar.gz: 1d59049f9bb409bcbb56c3126f9675f1492e0a3d434858d2cb44af8a3d5aba74ee1fe5f78bbc73bab707aae05cfe8d8ed671a4a7e5dc8fa4841df176ebd88c30
6
+ metadata.gz: f414bb7dc859d720dc4d9e4e5f48a37cb0745e63a03d109824c5d17230d1384f53eb013c122a675c17c78e8e9d8f4c71dbf944ec351b8ee8c3df0e406556e241
7
+ data.tar.gz: d5caa370b2a0f132fd7aff53de631a2a836ba71ea8ac4c2eec79b73ea151d5df9615183855e3a2e0a4a608e45d8d43f2ea9c28ef66f53320ca6cc95ad2bdd215
@@ -14,14 +14,9 @@ jobs:
14
14
  strategy:
15
15
  fail-fast: false
16
16
  matrix:
17
- ruby: ["2.7", "3.0", "3.1", "3.2"]
18
- rails: ["6.0", "6.1", "7.0"]
17
+ ruby: ["3.2", "3.3", "3.4"]
18
+ rails: ["7.2", "8.0", "8.1"]
19
19
  continue-on-error: [false]
20
- exclude:
21
- - ruby: "3.2"
22
- rails: "6.0"
23
- - ruby: "3.2"
24
- rails: "6.1"
25
20
 
26
21
  services:
27
22
  postgres:
data/CHANGELOG.md ADDED
@@ -0,0 +1,150 @@
1
+ # Changelog
2
+
3
+ The noteworthy changes for each version are included here. For a complete
4
+ changelog, see the [commits] for each version via the version links.
5
+
6
+ [commits]: https://github.com/teoljungberg/fx/commits/master
7
+
8
+ ## [Unreleased]
9
+
10
+ [Unreleased]: https://github.com/teoljungberg/fx/compare/v0.10.0..HEAD
11
+
12
+ ## [0.10.0]
13
+
14
+ [0.10.0]: https://github.com/teoljungberg/fx/compare/v0.9.0...v0.10.0
15
+
16
+ - Scope functions and triggers to schema search path (#168)
17
+ - Ensure multi-schema dumping in Rails 8.1.0 does not dump the same objects for
18
+ all schemas (#177)
19
+ - Require Ruby >= 3.2 (#166)
20
+ - Require Ruby >= 3.1 (#162)
21
+ - New version support
22
+ - Add Rails 8.1 to the test matrix (#175)
23
+ - Add Ruby 3.4 to the test matrix (#161)
24
+ - Removed version support
25
+ - Drop Rails 7.1 due to EOL (#176)
26
+ - Drop EOL Ruby versions (3.0) (#162)
27
+ - Drop EOL Rails versions (7.0) (#162)
28
+ - Internal refactorings / improvements
29
+ - Extract validation methods in `Statements` module (#184)
30
+ - Refactor generators with helper classes and improvements (#183)
31
+ - Extract `QueryExecutor` to remove duplication (#182)
32
+ - Extract PostgreSQL version constants (#181)
33
+ - YARD documentation improvements (#179)
34
+ - Ensure fx has been loaded (#173)
35
+ - Replace ammeter (#172)
36
+ - Remove teardown phase (#171)
37
+
38
+ ## [0.9.0]
39
+
40
+ [0.9.0]: https://github.com/teoljungberg/fx/compare/v0.8.0...v0.9.0
41
+
42
+ - Drop EOL Rails versions (6.2)
43
+ - Add Ruby 3.4.0 preview's to the test matrix (#152)
44
+ - Add Rails 8.0.0 to the test matrix (#152)
45
+ - Add Rails 7.2 to the test matrix (#150)
46
+ - Fix deprecation warnings in Rails (#148)
47
+ - Mark `Fx::CommandRecorder::Arguments` as private.
48
+ - Add Ruby 3.3 to the test matrix (#144)
49
+ - Internal refactorings:
50
+ - Move development dependencies to Gemfile (#145)
51
+ - Inline `Fx::CommandRecorder::Arguments`
52
+ - Inline `Fx::{CommandRecorder,SchemaDumper,Statements}::{Function,Trigger}`
53
+ - Move configuration methods to `Fx`
54
+ - Add `Fx::Definition.{function,trigger}` (#119)
55
+ - Add Rails 7.1 to the test matrix (#136)
56
+ - Add Rubygems metadata to gemspec (#132)
57
+ - Disable RSpec's monkey patching (#121)
58
+ - Raise on warnings (#124)
59
+ - Require Ruby >= 3.0 (#128)
60
+ - Require Rails >= 6.1 (#127)
61
+
62
+ ## [0.8.0]
63
+
64
+ [0.8.0]: https://github.com/teoljungberg/fx/compare/v0.7.0...v0.8.0
65
+
66
+ - Replace Travis CI with GitHub Actions.
67
+ - Bump minimum Ruby version to 2.7.
68
+ - Ruby 2.7 will be dropped in end of March 2023, so a release to drop it will
69
+ happen afterwards.
70
+ - Bump minimum Rails version to 6.0.0
71
+ - Rails 6.0 will be dropped in June 2023, so a release to drop it will happen
72
+ afterwards
73
+ - Adopt standard.rb
74
+ - Contributing improvements
75
+ - Test-suite improvements
76
+
77
+ ## [0.7.0]
78
+
79
+ [0.7.0]: https://github.com/teoljungberg/fx/compare/v0.6.2...v0.7.0
80
+
81
+ - Support Ruby 3 (#76)
82
+ - Preserve backslashes when dumping the schema (#71)
83
+ - Add a link to F(x) SqlServer Adapter in the README (#80)
84
+
85
+ ## [0.6.2]
86
+
87
+ [0.6.2]: https://github.com/teoljungberg/fx/compare/v0.6.1...v0.6.2
88
+
89
+ - Add support for Ruby 3
90
+
91
+ ## [0.6.1]
92
+
93
+ [0.6.1]: https://github.com/teoljungberg/fx/compare/v0.6.0...v0.6.1
94
+
95
+ - Fix: Support --no-migration generator flag (#62)
96
+
97
+ ## [0.6.0]
98
+
99
+ [0.6.0]: https://github.com/teoljungberg/fx/compare/v0.5.0...v0.6.0
100
+
101
+ - Support unique functions with parameters (#27)
102
+ - Use db connection provided by Rails (#49)
103
+ - Support `--no-migration` generator flag (#60)
104
+ - Use current ActiveRecord version in migrations (#59)
105
+ - Does not include aggregates when dumping schema (#50)
106
+ - Dump functions in the beginning of the schema (#53)
107
+
108
+ ## [0.5.0]
109
+
110
+ [0.5.0]: https://github.com/teoljungberg/fx/compare/v0.4.0...v0.5.0
111
+
112
+ - Drop EOL Ruby versions.
113
+ - Drop EOL Rails versions.
114
+
115
+ ## [0.4.0]
116
+
117
+ [0.4.0]: https://github.com/teoljungberg/fx/compare/v0.3.1...v0.4.0
118
+
119
+ - Add table_name to README (#15)
120
+ - Reverse function/trigger order in README (#17)
121
+ - Split up Trigger#definition test (#19)
122
+ - Find definitions in engines (#18)
123
+
124
+ ## [0.3.1]
125
+
126
+ [0.3.1]: https://github.com/teoljungberg/fx/compare/v0.3.0...v0.3.1
127
+
128
+ - Strip shared leading whitespace from sql_definitions (#13)
129
+ - Update documentation for `drop_function`
130
+ - Document `Fx::Adapters::Postgres#initialize`
131
+ - Fix test suite issues:
132
+ - Add unit test coverage for `Fx::Adapters::Triggers`
133
+ - Add unit test coverage for `Fx::Adapters::Functions`
134
+ - Add unit test coverage for `Fx::Trigger`
135
+ - Add unit test coverage for `Fx::Function`
136
+
137
+ ## [0.3.0]
138
+
139
+ [0.3.0]: https://github.com/teoljungberg/fx/compare/v0.2.0...v0.3.0
140
+
141
+ ## [0.2.0]
142
+
143
+ [0.2.0]: https://github.com/teoljungberg/fx/compare/v0.1.0...v0.2.0
144
+
145
+ ## [0.1.0]
146
+
147
+ F(x) adds methods to `ActiveRecord::Migration` to create and manage database
148
+ functions and triggers in Rails.
149
+
150
+ [0.1.0]: https://github.com/teoljungberg/fx/compare/4ccf986643d9de82038977eff8c6b1a4a716d698...v0.1.0
data/CONTRIBUTING.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Contributing
2
2
 
3
- We love contributions from everyone. By participating in this project, you
3
+ We love contributions from everyone. By participating in this project, you
4
4
  agree to abide by our [code of conduct].
5
5
 
6
- [code of conduct]: CODE_OF_CONDUCT.md
6
+ [code of conduct]: https://thoughtbot.com/open-source-code-of-conduct
7
7
 
8
8
  ## Contributing Code
9
9
 
@@ -19,6 +19,6 @@ agree to abide by our [code of conduct].
19
19
 
20
20
  [good commit message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
21
21
 
22
- Others will give constructive feedback. This is a time for discussion and
22
+ Others will give constructive feedback. This is a time for discussion and
23
23
  improvements, and making the necessary changes will be required before we can
24
24
  merge the contribution.
data/Gemfile CHANGED
@@ -1,4 +1,14 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in fx.gemspec
4
3
  gemspec
4
+
5
+ gem "bundler", ">= 1.5"
6
+ gem "database_cleaner"
7
+ gem "pg"
8
+ gem "pry"
9
+ gem "rake"
10
+ gem "redcarpet"
11
+ gem "rspec", ">= 3.3"
12
+ gem "standardrb"
13
+ gem "yard"
14
+ gem "warning"
data/README.md CHANGED
@@ -110,6 +110,8 @@ column value instead of a plain string.
110
110
 
111
111
  ## Plugins/Adapters
112
112
 
113
+ - [MySQL](https://github.com/f-mer/fx-adapters-mysql/)
114
+ - [Oracle](https://github.com/zygotecnologia/fx-oracle-adapter)
113
115
  - [SQLserver](https://github.com/tarellel/fx-sqlserver-adapter)
114
116
 
115
117
  ## Contributing
data/bin/rake CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -7,9 +8,7 @@
7
8
  # this file is here to facilitate running it.
8
9
  #
9
10
 
10
- require "pathname"
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
- Pathname.new(__FILE__).realpath)
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
13
12
 
14
13
  require "rubygems"
15
14
  require "bundler/setup"
data/bin/rspec CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -7,9 +8,18 @@
7
8
  # this file is here to facilitate running it.
8
9
  #
9
10
 
10
- require "pathname"
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
- Pathname.new(__FILE__).realpath)
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
13
23
 
14
24
  require "rubygems"
15
25
  require "bundler/setup"
data/bin/standardrb ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'standardrb' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("standard", "standardrb")
data/bin/yard CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  #
4
5
  # This file was generated by Bundler.
5
6
  #
@@ -7,9 +8,18 @@
7
8
  # this file is here to facilitate running it.
8
9
  #
9
10
 
10
- require "pathname"
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
- Pathname.new(__FILE__).realpath)
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
13
23
 
14
24
  require "rubygems"
15
25
  require "bundler/setup"
data/fx.gemspec CHANGED
@@ -8,29 +8,24 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Teo Ljungberg"]
9
9
  spec.email = ["teo@teoljungberg.com"]
10
10
  spec.summary = "Support for database functions and triggers in Rails migrations"
11
- spec.description = <<-DESCRIPTION
11
+ spec.description = <<~DESCRIPTION
12
12
  Adds methods to ActiveRecord::Migration to create and manage database functions
13
13
  and triggers in Rails
14
14
  DESCRIPTION
15
15
  spec.homepage = "https://github.com/teoljungberg/fx"
16
16
  spec.license = "MIT"
17
+ spec.metadata = {
18
+ "bug_tracker_uri" => "#{spec.homepage}/issues",
19
+ "changelog_uri" => "#{spec.homepage}/blob/v#{spec.version}/CHANGELOG.md",
20
+ "homepage_uri" => spec.homepage,
21
+ "source_code_uri" => spec.homepage
22
+ }
17
23
 
18
24
  spec.files = `git ls-files -z`.split("\x0")
19
25
  spec.require_paths = ["lib"]
20
26
 
21
- spec.add_development_dependency "ammeter", ">= 1.1.3"
22
- spec.add_development_dependency "bundler", ">= 1.5"
23
- spec.add_development_dependency "database_cleaner"
24
- spec.add_development_dependency "pg"
25
- spec.add_development_dependency "pry"
26
- spec.add_development_dependency "rake"
27
- spec.add_development_dependency "redcarpet"
28
- spec.add_development_dependency "rspec", ">= 3.3"
29
- spec.add_development_dependency "standardrb"
30
- spec.add_development_dependency "yard"
27
+ spec.add_dependency "activerecord", ">= 7.2", "< 8.2"
28
+ spec.add_dependency "railties", ">= 7.2", "< 8.2"
31
29
 
32
- spec.add_dependency "activerecord", ">= 6.0.0"
33
- spec.add_dependency "railties", ">= 6.0.0"
34
-
35
- spec.required_ruby_version = ">= 2.7"
30
+ spec.required_ruby_version = ">= 3.2"
36
31
  end
@@ -10,6 +10,26 @@ module Fx
10
10
  #
11
11
  # @api private
12
12
  class Connection < SimpleDelegator
13
+ # PostgreSQL version constants for feature support
14
+ POSTGRES_VERSIONS = {
15
+ # PostgreSQL 10.0 - introduced DROP FUNCTION without args
16
+ # https://www.postgresql.org/docs/10/sql-dropfunction.html
17
+ v10: 10_00_00
18
+ }.freeze
19
+
20
+ def support_drop_function_without_args
21
+ server_version >= POSTGRES_VERSIONS[:v10]
22
+ end
23
+
24
+ private
25
+
26
+ def server_version
27
+ undecorated_connection.raw_connection.server_version
28
+ end
29
+
30
+ def undecorated_connection
31
+ __getobj__
32
+ end
13
33
  end
14
34
  end
15
35
  end
@@ -1,4 +1,5 @@
1
1
  require "fx/function"
2
+ require "fx/adapters/postgres/query_executor"
2
3
 
3
4
  module Fx
4
5
  module Adapters
@@ -8,7 +9,7 @@ module Fx
8
9
  class Functions
9
10
  # The SQL query used by F(x) to retrieve the functions considered
10
11
  # dumpable into `db/schema.rb`.
11
- FUNCTIONS_WITH_DEFINITIONS_QUERY = <<-EOS.freeze
12
+ FUNCTIONS_WITH_DEFINITIONS_QUERY = <<~SQL.freeze
12
13
  SELECT
13
14
  pp.proname AS name,
14
15
  pg_get_functiondef(pp.oid) AS definition
@@ -19,39 +20,21 @@ module Fx
19
20
  ON pd.objid = pp.oid AND pd.deptype = 'e'
20
21
  LEFT JOIN pg_aggregate pa
21
22
  ON pa.aggfnoid = pp.oid
22
- WHERE pn.nspname = 'public' AND pd.objid IS NULL
23
+ WHERE pn.nspname = ANY (current_schemas(false))
24
+ AND pd.objid IS NULL
23
25
  AND pa.aggfnoid IS NULL
24
26
  ORDER BY pp.oid;
25
- EOS
27
+ SQL
26
28
 
27
29
  # Wraps #all as a static facade.
28
30
  #
29
31
  # @return [Array<Fx::Function>]
30
- def self.all(*args)
31
- new(*args).all
32
- end
33
-
34
- def initialize(connection)
35
- @connection = connection
36
- end
37
-
38
- # All of the functions that this connection has defined.
39
- #
40
- # @return [Array<Fx::Function>]
41
- def all
42
- functions_from_postgres.map { |function| to_fx_function(function) }
43
- end
44
-
45
- private
46
-
47
- attr_reader :connection
48
-
49
- def functions_from_postgres
50
- connection.execute(FUNCTIONS_WITH_DEFINITIONS_QUERY)
51
- end
52
-
53
- def to_fx_function(result)
54
- Fx::Function.new(result)
32
+ def self.all(connection)
33
+ QueryExecutor.call(
34
+ connection: connection,
35
+ query: FUNCTIONS_WITH_DEFINITIONS_QUERY,
36
+ model_class: Fx::Function
37
+ )
55
38
  end
56
39
  end
57
40
  end
@@ -0,0 +1,34 @@
1
+ module Fx
2
+ module Adapters
3
+ class Postgres
4
+ # Executes database queries and maps results to domain objects.
5
+ # @api private
6
+ class QueryExecutor
7
+ def self.call(...)
8
+ new(...).call
9
+ end
10
+
11
+ def initialize(connection:, query:, model_class:)
12
+ @connection = connection
13
+ @query = query
14
+ @model_class = model_class
15
+ end
16
+
17
+ # Executes the query and maps results to domain objects.
18
+ #
19
+ # @return [Array] Array of domain objects (Functions or Triggers)
20
+ def call
21
+ results_from_postgres.map { |result| model_class.new(result) }
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :connection, :query, :model_class
27
+
28
+ def results_from_postgres
29
+ connection.execute(query)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,4 +1,5 @@
1
1
  require "fx/trigger"
2
+ require "fx/adapters/postgres/query_executor"
2
3
 
3
4
  module Fx
4
5
  module Adapters
@@ -8,7 +9,7 @@ module Fx
8
9
  class Triggers
9
10
  # The SQL query used by F(x) to retrieve the triggers considered
10
11
  # dumpable into `db/schema.rb`.
11
- TRIGGERS_WITH_DEFINITIONS_QUERY = <<-EOS.freeze
12
+ TRIGGERS_WITH_DEFINITIONS_QUERY = <<~SQL.freeze
12
13
  SELECT
13
14
  pt.tgname AS name,
14
15
  pg_get_triggerdef(pt.oid) AS definition
@@ -17,39 +18,23 @@ module Fx
17
18
  ON (pc.oid = pt.tgrelid)
18
19
  JOIN pg_proc pp
19
20
  ON (pp.oid = pt.tgfoid)
20
- WHERE pt.tgname
21
- NOT ILIKE '%constraint%' AND pt.tgname NOT ILIKE 'pg%'
21
+ JOIN pg_namespace pn
22
+ ON pn.oid = pc.relnamespace
23
+ WHERE pn.nspname = ANY (current_schemas(false))
24
+ AND pt.tgname NOT ILIKE '%constraint%'
25
+ AND pt.tgname NOT ILIKE 'pg%'
22
26
  ORDER BY pc.oid;
23
- EOS
27
+ SQL
24
28
 
25
29
  # Wraps #all as a static facade.
26
30
  #
27
31
  # @return [Array<Fx::Trigger>]
28
- def self.all(*args)
29
- new(*args).all
30
- end
31
-
32
- def initialize(connection)
33
- @connection = connection
34
- end
35
-
36
- # All of the triggers that this connection has defined.
37
- #
38
- # @return [Array<Fx::Trigger>]
39
- def all
40
- triggers_from_postgres.map { |trigger| to_fx_trigger(trigger) }
41
- end
42
-
43
- private
44
-
45
- attr_reader :connection
46
-
47
- def triggers_from_postgres
48
- connection.execute(TRIGGERS_WITH_DEFINITIONS_QUERY)
49
- end
50
-
51
- def to_fx_trigger(result)
52
- Fx::Trigger.new(result)
32
+ def self.all(connection)
33
+ QueryExecutor.call(
34
+ connection: connection,
35
+ query: TRIGGERS_WITH_DEFINITIONS_QUERY,
36
+ model_class: Fx::Trigger
37
+ )
53
38
  end
54
39
  end
55
40
  end
@@ -65,11 +65,11 @@ module Fx
65
65
  # This is typically called in a migration via
66
66
  # {Fx::Statements::Function#create_function}.
67
67
  #
68
- # @param sql_definition The SQL schema for the function.
68
+ # @param sql_definition [String] The SQL schema for the function.
69
69
  #
70
70
  # @return [void]
71
71
  def create_function(sql_definition)
72
- execute sql_definition
72
+ execute(sql_definition)
73
73
  end
74
74
 
75
75
  # Creates a trigger in the database.
@@ -77,11 +77,11 @@ module Fx
77
77
  # This is typically called in a migration via
78
78
  # {Fx::Statements::Trigger#create_trigger}.
79
79
  #
80
- # @param sql_definition The SQL schema for the trigger.
80
+ # @param sql_definition [String] The SQL schema for the trigger.
81
81
  #
82
82
  # @return [void]
83
83
  def create_trigger(sql_definition)
84
- execute sql_definition
84
+ execute(sql_definition)
85
85
  end
86
86
 
87
87
  # Updates a function in the database.
@@ -89,8 +89,8 @@ module Fx
89
89
  # This is typically called in a migration via
90
90
  # {Fx::Statements::Function#update_function}.
91
91
  #
92
- # @param name The name of the function.
93
- # @param sql_definition The SQL schema for the function.
92
+ # @param name [String, Symbol] The name of the function.
93
+ # @param sql_definition [String] The SQL schema for the function.
94
94
  #
95
95
  # @return [void]
96
96
  def update_function(name, sql_definition)
@@ -106,9 +106,9 @@ module Fx
106
106
  # This is typically called in a migration via
107
107
  # {Fx::Statements::Function#update_trigger}.
108
108
  #
109
- # @param name The name of the trigger.
110
- # @param on The associated table for the trigger to drop
111
- # @param sql_definition The SQL schema for the function.
109
+ # @param name [String, Symbol] The name of the trigger.
110
+ # @param on [String, Symbol] The associated table for the trigger to update
111
+ # @param sql_definition [String] The SQL schema for the trigger.
112
112
  #
113
113
  # @return [void]
114
114
  def update_trigger(name, on:, sql_definition:)
@@ -121,14 +121,14 @@ module Fx
121
121
  # This is typically called in a migration via
122
122
  # {Fx::Statements::Function#drop_function}.
123
123
  #
124
- # @param name The name of the function to drop
124
+ # @param name [String, Symbol] The name of the function to drop
125
125
  #
126
126
  # @return [void]
127
127
  def drop_function(name)
128
- if support_drop_function_without_args
129
- execute "DROP FUNCTION #{name};"
128
+ if connection.support_drop_function_without_args
129
+ execute("DROP FUNCTION #{name};")
130
130
  else
131
- execute "DROP FUNCTION #{name}();"
131
+ execute("DROP FUNCTION #{name}();")
132
132
  end
133
133
  end
134
134
 
@@ -137,12 +137,12 @@ module Fx
137
137
  # This is typically called in a migration via
138
138
  # {Fx::Statements::Trigger#drop_trigger}.
139
139
  #
140
- # @param name The name of the trigger to drop
141
- # @param on The associated table for the trigger to drop
140
+ # @param name [String, Symbol] The name of the trigger to drop
141
+ # @param on [String, Symbol] The associated table for the trigger to drop
142
142
  #
143
143
  # @return [void]
144
144
  def drop_trigger(name, on:)
145
- execute "DROP TRIGGER #{name} ON #{on};"
145
+ execute("DROP TRIGGER #{name} ON #{on};")
146
146
  end
147
147
 
148
148
  private
@@ -154,14 +154,6 @@ module Fx
154
154
  def connection
155
155
  Connection.new(connectable.connection)
156
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
165
157
  end
166
158
  end
167
159
  end