fx 0.9.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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -2
  3. data/CHANGELOG.md +27 -1
  4. data/Gemfile +0 -1
  5. data/bin/rake +2 -3
  6. data/bin/rspec +13 -3
  7. data/bin/yard +13 -3
  8. data/fx.gemspec +3 -3
  9. data/lib/fx/adapters/postgres/connection.rb +12 -4
  10. data/lib/fx/adapters/postgres/functions.rb +11 -28
  11. data/lib/fx/adapters/postgres/query_executor.rb +34 -0
  12. data/lib/fx/adapters/postgres/triggers.rb +14 -29
  13. data/lib/fx/adapters/postgres.rb +10 -10
  14. data/lib/fx/configuration.rb +2 -2
  15. data/lib/fx/schema_dumper.rb +6 -14
  16. data/lib/fx/statements.rb +61 -58
  17. data/lib/fx/version.rb +1 -1
  18. data/lib/generators/fx/function/function_generator.rb +50 -53
  19. data/lib/generators/fx/function/templates/db/migrate/create_function.erb +1 -1
  20. data/lib/generators/fx/function/templates/db/migrate/update_function.erb +1 -1
  21. data/lib/generators/fx/migration_helper.rb +53 -0
  22. data/lib/generators/fx/name_helper.rb +33 -0
  23. data/lib/generators/fx/trigger/templates/db/migrate/create_trigger.erb +1 -1
  24. data/lib/generators/fx/trigger/templates/db/migrate/update_trigger.erb +1 -1
  25. data/lib/generators/fx/trigger/trigger_generator.rb +45 -64
  26. data/lib/generators/fx/version_helper.rb +55 -0
  27. data/spec/acceptance/user_manages_functions_spec.rb +6 -6
  28. data/spec/acceptance/user_manages_triggers_spec.rb +10 -10
  29. data/spec/acceptance_helper.rb +2 -2
  30. data/spec/features/functions/migrations_spec.rb +4 -4
  31. data/spec/features/functions/revert_spec.rb +4 -4
  32. data/spec/features/triggers/migrations_spec.rb +6 -6
  33. data/spec/features/triggers/revert_spec.rb +8 -8
  34. data/spec/fx/adapters/postgres/functions_spec.rb +12 -5
  35. data/spec/fx/adapters/postgres/query_executor_spec.rb +75 -0
  36. data/spec/fx/adapters/postgres/triggers_spec.rb +14 -7
  37. data/spec/fx/adapters/postgres_spec.rb +62 -20
  38. data/spec/fx/definition_spec.rb +6 -6
  39. data/spec/fx/schema_dumper_spec.rb +60 -14
  40. data/spec/fx_spec.rb +1 -1
  41. data/spec/generators/fx/function/function_generator_spec.rb +10 -10
  42. data/spec/generators/fx/migration_helper_spec.rb +133 -0
  43. data/spec/generators/fx/name_helper_spec.rb +114 -0
  44. data/spec/generators/fx/trigger/trigger_generator_spec.rb +42 -19
  45. data/spec/generators/fx/version_helper_spec.rb +157 -0
  46. data/spec/spec_helper.rb +2 -0
  47. data/spec/support/generator_setup.rb +46 -5
  48. metadata +28 -11
@@ -1,39 +1,43 @@
1
1
  require "rails/generators"
2
2
  require "rails/generators/active_record"
3
+ require "generators/fx/version_helper"
4
+ require "generators/fx/migration_helper"
5
+ require "generators/fx/name_helper"
3
6
 
4
7
  module Fx
5
8
  module Generators
6
9
  # @api private
7
10
  class TriggerGenerator < Rails::Generators::NamedBase
8
11
  include Rails::Generators::Migration
12
+
9
13
  source_root File.expand_path("../templates", __FILE__)
10
14
  argument :table_name, type: :hash, required: true
11
15
 
16
+ DEFINITION_PATH = %w[db triggers].freeze
17
+
12
18
  class_option :migration, type: :boolean
13
19
 
14
20
  def create_triggers_directory
15
- unless trigger_definition_path.exist?
16
- empty_directory(trigger_definition_path)
17
- end
21
+ return if trigger_definition_path.exist?
22
+
23
+ empty_directory(trigger_definition_path)
18
24
  end
19
25
 
20
26
  def create_trigger_definition
21
- create_file definition.path
27
+ create_file(definition.path)
22
28
  end
23
29
 
24
30
  def create_migration_file
25
- return if skip_migration_creation?
26
- if updating_existing_trigger?
27
- migration_template(
28
- "db/migrate/update_trigger.erb",
29
- "db/migrate/update_trigger_#{file_name}_to_version_#{version}.rb"
30
- )
31
- else
32
- migration_template(
33
- "db/migrate/create_trigger.erb",
34
- "db/migrate/create_trigger_#{file_name}.rb"
35
- )
36
- end
31
+ return if migration_helper.skip_creation?
32
+
33
+ template_info = migration_helper.migration_template_info(
34
+ object_type: :trigger,
35
+ file_name: file_name,
36
+ updating_existing: version_helper.updating_existing?,
37
+ version: version_helper.current_version
38
+ )
39
+
40
+ migration_template(template_info[:template], template_info[:filename])
37
41
  end
38
42
 
39
43
  def self.next_migration_number(dir)
@@ -42,84 +46,61 @@ module Fx
42
46
 
43
47
  no_tasks do
44
48
  def previous_version
45
- @_previous_version ||= Dir.entries(trigger_definition_path)
46
- .map { |name| version_regex.match(name).try(:[], "version").to_i }
47
- .max
49
+ version_helper.previous_version
48
50
  end
49
51
 
50
52
  def version
51
- @_version ||= previous_version.next
53
+ version_helper.current_version
52
54
  end
53
55
 
54
56
  def migration_class_name
55
- if updating_existing_trigger?
56
- "UpdateTrigger#{class_name}ToVersion#{version}"
57
+ if version_helper.updating_existing?
58
+ migration_helper.update_migration_class_name(
59
+ object_type: :trigger,
60
+ class_name: class_name,
61
+ version: version
62
+ )
57
63
  else
58
64
  super
59
65
  end
60
66
  end
61
67
 
62
- def activerecord_migration_class
63
- if ActiveRecord::Migration.respond_to?(:current_version)
64
- "ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]"
65
- else
66
- "ActiveRecord::Migration"
67
- end
68
+ def active_record_migration_class
69
+ migration_helper.active_record_migration_class
68
70
  end
69
71
 
70
72
  def formatted_name
71
- if singular_name.include?(".")
72
- "\"#{singular_name}\""
73
- else
74
- ":#{singular_name}"
75
- end
73
+ NameHelper.format_for_migration(singular_name)
76
74
  end
77
75
 
78
76
  def formatted_table_name
79
- name = table_name["table_name"] || table_name["on"]
80
-
81
- if name.nil?
82
- raise(
83
- ArgumentError,
84
- "Either `table_name:NAME` or `on:NAME` must be specified"
85
- )
86
- end
87
-
88
- if name.include?(".")
89
- "\"#{name}\""
90
- else
91
- ":#{name}"
92
- end
77
+ NameHelper.format_table_name_from_hash(table_name)
93
78
  end
94
79
  end
95
80
 
96
81
  private
97
82
 
98
- def version_regex
99
- /\A#{file_name}_v(?<version>\d+)\.sql\z/
100
- end
101
-
102
- def updating_existing_trigger?
103
- previous_version > 0
83
+ def trigger_definition_path
84
+ @_trigger_definition_path ||= Rails.root.join(*DEFINITION_PATH)
104
85
  end
105
86
 
106
- def definition
107
- Fx::Definition.trigger(name: file_name, version: version)
87
+ def version_helper
88
+ @_version_helper ||= Fx::Generators::VersionHelper.new(
89
+ file_name: file_name,
90
+ definition_path: trigger_definition_path
91
+ )
108
92
  end
109
93
 
110
- def trigger_definition_path
111
- @_trigger_definition_path ||= Rails.root.join("db", "triggers")
94
+ def migration_helper
95
+ @_migration_helper ||= Fx::Generators::MigrationHelper.new(options)
112
96
  end
113
97
 
114
- # Skip creating migration file if:
115
- # - migrations option is nil or false
116
- def skip_migration_creation?
117
- !migration
98
+ def definition
99
+ version_helper.definition_for_version(version: version, type: :trigger)
118
100
  end
119
101
 
120
- # True unless explicitly false
121
- def migration
122
- options[:migration] != false
102
+ def updating_existing_trigger?
103
+ version_helper.updating_existing?
123
104
  end
124
105
  end
125
106
  end
@@ -0,0 +1,55 @@
1
+ module Fx
2
+ module Generators
3
+ # @api private
4
+ class VersionHelper
5
+ def initialize(file_name:, definition_path:)
6
+ @file_name = file_name
7
+ @definition_path = definition_path
8
+ end
9
+
10
+ def previous_version
11
+ @previous_version ||= existing_versions.max || 0
12
+ end
13
+
14
+ def current_version
15
+ previous_version.next
16
+ end
17
+
18
+ def updating_existing?
19
+ previous_version > 0
20
+ end
21
+
22
+ def creating_new?
23
+ previous_version == 0
24
+ end
25
+
26
+ def definition_for_version(version:, type:)
27
+ case type
28
+ when :function
29
+ Fx::Definition.function(name: file_name, version: version)
30
+ when :trigger
31
+ Fx::Definition.trigger(name: file_name, version: version)
32
+ else
33
+ raise(
34
+ ArgumentError,
35
+ "Unknown type: #{type}. Must be :function or :trigger"
36
+ )
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ VERSION_PATTERN = /v(\d+)/
43
+ private_constant :VERSION_PATTERN
44
+
45
+ attr_reader :file_name, :definition_path
46
+
47
+ def existing_versions
48
+ Dir
49
+ .glob("#{file_name}_v*.sql", base: definition_path)
50
+ .map { |file| file[VERSION_PATTERN, 1].to_i }
51
+ .compact
52
+ end
53
+ end
54
+ end
55
+ end
@@ -3,14 +3,14 @@ require "acceptance_helper"
3
3
  RSpec.describe "User manages functions" do
4
4
  it "handles simple functions" do
5
5
  successfully "rails generate fx:function test"
6
- write_function_definition "test_v01", <<~EOS
6
+ write_function_definition "test_v01", <<~SQL
7
7
  CREATE OR REPLACE FUNCTION test()
8
8
  RETURNS text AS $$
9
9
  BEGIN
10
10
  RETURN 'test';
11
11
  END;
12
12
  $$ LANGUAGE plpgsql;
13
- EOS
13
+ SQL
14
14
  successfully "rake db:migrate"
15
15
 
16
16
  result = execute("SELECT * FROM test() AS result")
@@ -21,14 +21,14 @@ RSpec.describe "User manages functions" do
21
21
  "db/functions/test_v01.sql",
22
22
  "db/functions/test_v02.sql"
23
23
  )
24
- write_function_definition "test_v02", <<~EOS
24
+ write_function_definition "test_v02", <<~SQL
25
25
  CREATE OR REPLACE FUNCTION test()
26
26
  RETURNS text AS $$
27
27
  BEGIN
28
28
  RETURN 'testest';
29
29
  END;
30
30
  $$ LANGUAGE plpgsql;
31
- EOS
31
+ SQL
32
32
  successfully "rake db:migrate"
33
33
 
34
34
  result = execute("SELECT * FROM test() AS result")
@@ -37,14 +37,14 @@ RSpec.describe "User manages functions" do
37
37
 
38
38
  it "handles functions with arguments" do
39
39
  successfully "rails generate fx:function adder"
40
- write_function_definition "adder_v01", <<~EOS
40
+ write_function_definition "adder_v01", <<~SQL
41
41
  CREATE FUNCTION adder(x int, y int)
42
42
  RETURNS int AS $$
43
43
  BEGIN
44
44
  RETURN $1 + $2;
45
45
  END;
46
46
  $$ LANGUAGE plpgsql;
47
- EOS
47
+ SQL
48
48
  successfully "rake db:migrate"
49
49
 
50
50
  result = execute("SELECT * FROM adder(1, 2) AS result")
@@ -4,7 +4,7 @@ RSpec.describe "User manages triggers" do
4
4
  it "handles simple triggers" do
5
5
  successfully "rails generate model user name:string upper_name:string"
6
6
  successfully "rails generate fx:function uppercase_users_name"
7
- write_function_definition "uppercase_users_name_v01", <<~EOS
7
+ write_function_definition "uppercase_users_name_v01", <<~SQL
8
8
  CREATE OR REPLACE FUNCTION uppercase_users_name()
9
9
  RETURNS trigger AS $$
10
10
  BEGIN
@@ -12,38 +12,38 @@ RSpec.describe "User manages triggers" do
12
12
  RETURN NEW;
13
13
  END;
14
14
  $$ LANGUAGE plpgsql;
15
- EOS
15
+ SQL
16
16
  successfully "rails generate fx:trigger uppercase_users_name table_name:users"
17
- write_trigger_definition "uppercase_users_name_v01", <<~EOS
17
+ write_trigger_definition "uppercase_users_name_v01", <<~SQL
18
18
  CREATE TRIGGER uppercase_users_name
19
19
  BEFORE INSERT ON users
20
20
  FOR EACH ROW
21
21
  EXECUTE FUNCTION uppercase_users_name();
22
- EOS
22
+ SQL
23
23
  successfully "rake db:migrate"
24
24
 
25
- execute <<~EOS
25
+ execute <<~SQL
26
26
  INSERT INTO users
27
27
  (name, created_at, updated_at)
28
28
  VALUES
29
29
  ('Bob', NOW(), NOW());
30
- EOS
30
+ SQL
31
31
  result = execute("SELECT upper_name FROM users WHERE name = 'Bob';")
32
32
  expect(result).to eq("upper_name" => "BOB")
33
33
 
34
34
  successfully "rails generate fx:trigger uppercase_users_name table_name:users"
35
- write_trigger_definition "uppercase_users_name_v02", <<~EOS
35
+ write_trigger_definition "uppercase_users_name_v02", <<~SQL
36
36
  CREATE TRIGGER uppercase_users_name
37
37
  BEFORE UPDATE ON users
38
38
  FOR EACH ROW
39
39
  EXECUTE FUNCTION uppercase_users_name();
40
- EOS
40
+ SQL
41
41
  successfully "rake db:migrate"
42
- execute <<~EOS
42
+ execute <<~SQL
43
43
  UPDATE users
44
44
  SET name = 'Alice'
45
45
  WHERE id = 1;
46
- EOS
46
+ SQL
47
47
 
48
48
  result = execute("SELECT upper_name FROM users WHERE name = 'Alice';")
49
49
  expect(result).to eq("upper_name" => "ALICE")
@@ -13,8 +13,8 @@ RSpec.configure do |config|
13
13
  Dir.chdir("spec/dummy") do
14
14
  system <<~CMD
15
15
  git init -b master 1>/dev/null &&
16
- git config user.email "fx@example.com"
17
- git config user.name "Fx"
16
+ git config user.email "fx@example.com" &&
17
+ git config user.name "Fx" &&
18
18
  git add -A &&
19
19
  git commit --no-gpg-sign --message 'initial' 1>/dev/null
20
20
  CMD
@@ -2,14 +2,14 @@ require "spec_helper"
2
2
 
3
3
  RSpec.describe "Function migrations", :db do
4
4
  around do |example|
5
- sql_definition = <<~EOS
5
+ sql_definition = <<~SQL
6
6
  CREATE OR REPLACE FUNCTION test()
7
7
  RETURNS text AS $$
8
8
  BEGIN
9
9
  RETURN 'test';
10
10
  END;
11
11
  $$ LANGUAGE plpgsql;
12
- EOS
12
+ SQL
13
13
  with_function_definition(name: :test, sql_definition: sql_definition) do
14
14
  example.run
15
15
  end
@@ -40,14 +40,14 @@ RSpec.describe "Function migrations", :db do
40
40
  it "can run migrations that updates functions" do
41
41
  connection.create_function(:test)
42
42
 
43
- sql_definition = <<~EOS
43
+ sql_definition = <<~SQL
44
44
  CREATE OR REPLACE FUNCTION test()
45
45
  RETURNS text AS $$
46
46
  BEGIN
47
47
  RETURN 'testest';
48
48
  END;
49
49
  $$ LANGUAGE plpgsql;
50
- EOS
50
+ SQL
51
51
  with_function_definition(
52
52
  name: :test,
53
53
  version: 2,
@@ -2,14 +2,14 @@ require "spec_helper"
2
2
 
3
3
  RSpec.describe "Reverting migrations", :db do
4
4
  around do |example|
5
- sql_definition = <<~EOS
5
+ sql_definition = <<~SQL
6
6
  CREATE OR REPLACE FUNCTION test()
7
7
  RETURNS text AS $$
8
8
  BEGIN
9
9
  RETURN 'test';
10
10
  END;
11
11
  $$ LANGUAGE plpgsql;
12
- EOS
12
+ SQL
13
13
  with_function_definition(name: :test, sql_definition: sql_definition) do
14
14
  example.run
15
15
  end
@@ -50,14 +50,14 @@ RSpec.describe "Reverting migrations", :db do
50
50
  it "can run reversible migrations for updating functions" do
51
51
  connection.create_function(:test)
52
52
 
53
- sql_definition = <<~EOS
53
+ sql_definition = <<~SQL
54
54
  CREATE OR REPLACE FUNCTION test()
55
55
  RETURNS text AS $$
56
56
  BEGIN
57
57
  RETURN 'bar';
58
58
  END;
59
59
  $$ LANGUAGE plpgsql;
60
- EOS
60
+ SQL
61
61
  with_function_definition(
62
62
  name: :test,
63
63
  version: 2,
@@ -2,14 +2,14 @@ require "spec_helper"
2
2
 
3
3
  RSpec.describe "Trigger migrations", :db do
4
4
  around do |example|
5
- connection.execute <<~EOS
5
+ connection.execute <<~SQL
6
6
  CREATE TABLE users (
7
7
  id int PRIMARY KEY,
8
8
  name varchar(256),
9
9
  upper_name varchar(256)
10
10
  );
11
- EOS
12
- Fx.database.create_function <<~EOS
11
+ SQL
12
+ Fx.database.create_function <<~SQL
13
13
  CREATE OR REPLACE FUNCTION uppercase_users_name()
14
14
  RETURNS trigger AS $$
15
15
  BEGIN
@@ -17,13 +17,13 @@ RSpec.describe "Trigger migrations", :db do
17
17
  RETURN NEW;
18
18
  END;
19
19
  $$ LANGUAGE plpgsql;
20
- EOS
21
- sql_definition = <<~EOS
20
+ SQL
21
+ sql_definition = <<~SQL
22
22
  CREATE TRIGGER uppercase_users_name
23
23
  BEFORE INSERT ON users
24
24
  FOR EACH ROW
25
25
  EXECUTE FUNCTION uppercase_users_name();
26
- EOS
26
+ SQL
27
27
  with_trigger_definition(
28
28
  name: :uppercase_users_name,
29
29
  sql_definition: sql_definition
@@ -2,14 +2,14 @@ require "spec_helper"
2
2
 
3
3
  RSpec.describe "Reverting migrations", :db do
4
4
  around do |example|
5
- connection.execute <<~EOS
5
+ connection.execute <<~SQL
6
6
  CREATE TABLE users (
7
7
  id int PRIMARY KEY,
8
8
  name varchar(256),
9
9
  upper_name varchar(256)
10
10
  );
11
- EOS
12
- Fx.database.create_function <<~EOS
11
+ SQL
12
+ Fx.database.create_function <<~SQL
13
13
  CREATE OR REPLACE FUNCTION uppercase_users_name()
14
14
  RETURNS trigger AS $$
15
15
  BEGIN
@@ -17,13 +17,13 @@ RSpec.describe "Reverting migrations", :db do
17
17
  RETURN NEW;
18
18
  END;
19
19
  $$ LANGUAGE plpgsql;
20
- EOS
21
- sql_definition = <<~EOS
20
+ SQL
21
+ sql_definition = <<~SQL
22
22
  CREATE TRIGGER uppercase_users_name
23
23
  BEFORE INSERT ON users
24
24
  FOR EACH ROW
25
25
  EXECUTE FUNCTION uppercase_users_name();
26
- EOS
26
+ SQL
27
27
  with_trigger_definition(
28
28
  name: :uppercase_users_name,
29
29
  sql_definition: sql_definition
@@ -67,12 +67,12 @@ RSpec.describe "Reverting migrations", :db do
67
67
  it "can run reversible migrations for updating triggers" do
68
68
  connection.create_trigger(:uppercase_users_name)
69
69
 
70
- sql_definition = <<~EOS
70
+ sql_definition = <<~SQL
71
71
  CREATE TRIGGER uppercase_users_name
72
72
  BEFORE UPDATE ON users
73
73
  FOR EACH ROW
74
74
  EXECUTE FUNCTION uppercase_users_name();
75
- EOS
75
+ SQL
76
76
  with_trigger_definition(
77
77
  name: :uppercase_users_name,
78
78
  sql_definition: sql_definition,
@@ -4,21 +4,21 @@ RSpec.describe Fx::Adapters::Postgres::Functions, :db do
4
4
  describe ".all" do
5
5
  it "returns `Function` objects" do
6
6
  connection = ActiveRecord::Base.connection
7
- connection.execute <<~EOS
7
+ connection.execute <<~SQL
8
8
  CREATE OR REPLACE FUNCTION test()
9
9
  RETURNS text AS $$
10
10
  BEGIN
11
11
  RETURN 'test';
12
12
  END;
13
13
  $$ LANGUAGE plpgsql;
14
- EOS
14
+ SQL
15
15
 
16
- functions = Fx::Adapters::Postgres::Functions.new(connection).all
16
+ functions = Fx::Adapters::Postgres::Functions.all(connection)
17
17
 
18
18
  first = functions.first
19
19
  expect(functions.size).to eq(1)
20
20
  expect(first.name).to eq("test")
21
- expect(first.definition).to eq(<<~EOS)
21
+ expect(first.definition).to eq(<<~SQL)
22
22
  CREATE OR REPLACE FUNCTION public.test()
23
23
  RETURNS text
24
24
  LANGUAGE plpgsql
@@ -27,7 +27,14 @@ RSpec.describe Fx::Adapters::Postgres::Functions, :db do
27
27
  RETURN 'test';
28
28
  END;
29
29
  $function$
30
- EOS
30
+ SQL
31
+
32
+ connection.execute "CREATE SCHEMA IF NOT EXISTS other;"
33
+ connection.execute "SET search_path = 'other';"
34
+
35
+ functions = Fx::Adapters::Postgres::Functions.all(connection)
36
+
37
+ expect(functions).to be_empty
31
38
  end
32
39
  end
33
40
  end
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Fx::Adapters::Postgres::QueryExecutor, :db do
4
+ it "executes the query and maps results to objects" do
5
+ connection = ActiveRecord::Base.connection
6
+ query = "SELECT 'Hello World' as message, 'english' as language"
7
+ greeter = Class.new do
8
+ attr_reader :message, :language
9
+
10
+ def initialize(row)
11
+ @message = row.fetch("message")
12
+ @language = row.fetch("language")
13
+ end
14
+ end
15
+
16
+ results = described_class.call(
17
+ connection: connection,
18
+ query: query,
19
+ model_class: greeter
20
+ )
21
+
22
+ expect(results.size).to eq(1)
23
+ expect(results.first).to be_a(greeter)
24
+ expect(results.first.message).to eq("Hello World")
25
+ expect(results.first.language).to eq("english")
26
+ end
27
+
28
+ it "executes query with multiple results" do
29
+ connection = ActiveRecord::Base.connection
30
+ query = <<~SQL
31
+ SELECT 'first' as name
32
+ UNION ALL
33
+ SELECT 'second' as name
34
+ ORDER BY name
35
+ SQL
36
+ simple_name = Class.new do
37
+ attr_reader :name
38
+
39
+ def initialize(row)
40
+ @name = row.fetch("name")
41
+ end
42
+ end
43
+
44
+ results = described_class.call(
45
+ connection: connection,
46
+ query: query,
47
+ model_class: simple_name
48
+ )
49
+
50
+ expect(results.size).to eq(2)
51
+ expect(results).to all(be_a(simple_name))
52
+ expect(results.first.name).to eq("first")
53
+ expect(results.last.name).to eq("second")
54
+ end
55
+
56
+ it "returns an empty array when query returns no results" do
57
+ connection = ActiveRecord::Base.connection
58
+ query = "SELECT 'test' as name WHERE 1 = 0"
59
+ simple_name = Class.new do
60
+ attr_reader :name
61
+
62
+ def initialize(row)
63
+ @name = row.fetch("name")
64
+ end
65
+ end
66
+
67
+ results = described_class.call(
68
+ connection: connection,
69
+ query: query,
70
+ model_class: simple_name
71
+ )
72
+
73
+ expect(results).to eq([])
74
+ end
75
+ end
@@ -4,14 +4,14 @@ RSpec.describe Fx::Adapters::Postgres::Triggers, :db do
4
4
  describe ".all" do
5
5
  it "returns `Trigger` objects" do
6
6
  connection = ActiveRecord::Base.connection
7
- connection.execute <<~EOS
7
+ connection.execute <<~SQL
8
8
  CREATE TABLE users (
9
9
  id int PRIMARY KEY,
10
10
  name varchar(256),
11
11
  upper_name varchar(256)
12
12
  );
13
- EOS
14
- connection.execute <<~EOS
13
+ SQL
14
+ connection.execute <<~SQL
15
15
  CREATE OR REPLACE FUNCTION uppercase_users_name()
16
16
  RETURNS trigger AS $$
17
17
  BEGIN
@@ -19,15 +19,15 @@ RSpec.describe Fx::Adapters::Postgres::Triggers, :db do
19
19
  RETURN NEW;
20
20
  END;
21
21
  $$ LANGUAGE plpgsql;
22
- EOS
23
- connection.execute <<~EOS
22
+ SQL
23
+ connection.execute <<~SQL
24
24
  CREATE TRIGGER uppercase_users_name
25
25
  BEFORE INSERT ON users
26
26
  FOR EACH ROW
27
27
  EXECUTE FUNCTION uppercase_users_name();
28
- EOS
28
+ SQL
29
29
 
30
- triggers = Fx::Adapters::Postgres::Triggers.new(connection).all
30
+ triggers = Fx::Adapters::Postgres::Triggers.all(connection)
31
31
 
32
32
  first = triggers.first
33
33
  expect(triggers.size).to eq(1)
@@ -36,6 +36,13 @@ RSpec.describe Fx::Adapters::Postgres::Triggers, :db do
36
36
  expect(first.definition).to match(/ON [public.ser|]/)
37
37
  expect(first.definition).to include("FOR EACH ROW")
38
38
  expect(first.definition).to include("EXECUTE FUNCTION uppercase_users_name()")
39
+
40
+ connection.execute "CREATE SCHEMA IF NOT EXISTS other;"
41
+ connection.execute "SET search_path = 'other';"
42
+
43
+ triggers = Fx::Adapters::Postgres::Triggers.all(connection)
44
+
45
+ expect(triggers).to be_empty
39
46
  end
40
47
  end
41
48
  end