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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +2 -7
- data/CHANGELOG.md +150 -0
- data/CONTRIBUTING.md +3 -3
- data/Gemfile +11 -1
- data/README.md +2 -0
- data/bin/rake +2 -3
- data/bin/rspec +13 -3
- data/bin/standardrb +27 -0
- data/bin/yard +13 -3
- data/fx.gemspec +10 -15
- data/lib/fx/adapters/postgres/connection.rb +20 -0
- data/lib/fx/adapters/postgres/functions.rb +11 -28
- data/lib/fx/adapters/postgres/query_executor.rb +34 -0
- data/lib/fx/adapters/postgres/triggers.rb +14 -29
- data/lib/fx/adapters/postgres.rb +16 -24
- data/lib/fx/command_recorder.rb +87 -6
- data/lib/fx/configuration.rb +2 -27
- data/lib/fx/definition.rb +16 -6
- data/lib/fx/function.rb +3 -3
- data/lib/fx/schema_dumper.rb +37 -5
- data/lib/fx/statements.rb +231 -6
- data/lib/fx/trigger.rb +3 -3
- data/lib/fx/version.rb +1 -1
- data/lib/fx.rb +30 -12
- data/lib/generators/fx/function/function_generator.rb +50 -53
- data/lib/generators/fx/function/templates/db/migrate/create_function.erb +1 -1
- data/lib/generators/fx/function/templates/db/migrate/update_function.erb +1 -1
- data/lib/generators/fx/migration_helper.rb +53 -0
- data/lib/generators/fx/name_helper.rb +33 -0
- data/lib/generators/fx/trigger/templates/db/migrate/create_trigger.erb +1 -1
- data/lib/generators/fx/trigger/templates/db/migrate/update_trigger.erb +1 -1
- data/lib/generators/fx/trigger/trigger_generator.rb +44 -67
- data/lib/generators/fx/version_helper.rb +55 -0
- data/spec/acceptance/user_manages_functions_spec.rb +7 -7
- data/spec/acceptance/user_manages_triggers_spec.rb +11 -11
- data/spec/acceptance_helper.rb +4 -4
- data/spec/dummy/config/application.rb +5 -1
- data/spec/features/functions/migrations_spec.rb +5 -5
- data/spec/features/functions/revert_spec.rb +5 -5
- data/spec/features/triggers/migrations_spec.rb +7 -7
- data/spec/features/triggers/revert_spec.rb +9 -9
- data/spec/fx/adapters/postgres/functions_spec.rb +33 -30
- data/spec/fx/adapters/postgres/query_executor_spec.rb +75 -0
- data/spec/fx/adapters/postgres/triggers_spec.rb +41 -38
- data/spec/fx/adapters/postgres_spec.rb +155 -115
- data/spec/fx/command_recorder_spec.rb +27 -25
- data/spec/fx/configuration_spec.rb +20 -9
- data/spec/fx/definition_spec.rb +31 -39
- data/spec/fx/function_spec.rb +45 -48
- data/spec/fx/schema_dumper_spec.rb +169 -0
- data/spec/fx/statements_spec.rb +217 -0
- data/spec/fx/trigger_spec.rb +37 -40
- data/spec/fx_spec.rb +28 -0
- data/spec/generators/fx/function/function_generator_spec.rb +11 -11
- data/spec/generators/fx/migration_helper_spec.rb +133 -0
- data/spec/generators/fx/name_helper_spec.rb +114 -0
- data/spec/generators/fx/trigger/trigger_generator_spec.rb +45 -22
- data/spec/generators/fx/version_helper_spec.rb +157 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/definition_helpers.rb +2 -6
- data/spec/support/generator_setup.rb +46 -5
- data/spec/support/warning_helper.rb +5 -0
- metadata +40 -165
- data/lib/fx/command_recorder/arguments.rb +0 -43
- data/lib/fx/command_recorder/function.rb +0 -30
- data/lib/fx/command_recorder/trigger.rb +0 -30
- data/lib/fx/schema_dumper/function.rb +0 -38
- data/lib/fx/schema_dumper/trigger.rb +0 -29
- data/lib/fx/statements/function.rb +0 -113
- data/lib/fx/statements/trigger.rb +0 -144
- data/spec/fx/command_recorder/arguments_spec.rb +0 -41
- data/spec/fx/schema_dumper/function_spec.rb +0 -78
- data/spec/fx/schema_dumper/trigger_spec.rb +0 -40
- data/spec/fx/statements/function_spec.rb +0 -103
- data/spec/fx/statements/trigger_spec.rb +0 -132
|
@@ -1,146 +1,186 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
describe
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
RETURNS text AS $$
|
|
12
|
-
BEGIN
|
|
13
|
-
RETURN 'test';
|
|
14
|
-
END;
|
|
15
|
-
$$ LANGUAGE plpgsql;
|
|
16
|
-
EOS
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
expect(adapter.functions.map(&:name)).to include("test")
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
describe "#create_trigger" do
|
|
24
|
-
it "successfully creates a trigger" do
|
|
25
|
-
connection.execute <<-EOS
|
|
26
|
-
CREATE TABLE users (
|
|
27
|
-
id int PRIMARY KEY,
|
|
28
|
-
name varchar(256),
|
|
29
|
-
upper_name varchar(256)
|
|
30
|
-
);
|
|
31
|
-
EOS
|
|
32
|
-
adapter = Postgres.new
|
|
33
|
-
adapter.create_function <<-EOS
|
|
34
|
-
CREATE OR REPLACE FUNCTION uppercase_users_name()
|
|
35
|
-
RETURNS trigger AS $$
|
|
3
|
+
RSpec.describe Fx::Adapters::Postgres, :db do
|
|
4
|
+
describe "#create_function" do
|
|
5
|
+
it "successfully creates a function" do
|
|
6
|
+
adapter = Fx::Adapters::Postgres.new
|
|
7
|
+
adapter.create_function(
|
|
8
|
+
<<~SQL
|
|
9
|
+
CREATE OR REPLACE FUNCTION test()
|
|
10
|
+
RETURNS text AS $$
|
|
36
11
|
BEGIN
|
|
37
|
-
|
|
38
|
-
RETURN NEW;
|
|
12
|
+
RETURN 'test';
|
|
39
13
|
END;
|
|
40
14
|
$$ LANGUAGE plpgsql;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<<-EOS
|
|
44
|
-
CREATE TRIGGER uppercase_users_name
|
|
45
|
-
BEFORE INSERT ON users
|
|
46
|
-
FOR EACH ROW
|
|
47
|
-
EXECUTE FUNCTION uppercase_users_name();
|
|
48
|
-
EOS
|
|
49
|
-
)
|
|
15
|
+
SQL
|
|
16
|
+
)
|
|
50
17
|
|
|
51
|
-
|
|
52
|
-
end
|
|
18
|
+
expect(adapter.functions.map(&:name)).to include("test")
|
|
53
19
|
end
|
|
20
|
+
end
|
|
54
21
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
22
|
+
describe "#create_trigger" do
|
|
23
|
+
it "successfully creates a trigger" do
|
|
24
|
+
connection.execute <<~SQL
|
|
25
|
+
CREATE TABLE users (
|
|
26
|
+
id int PRIMARY KEY,
|
|
27
|
+
name varchar(256),
|
|
28
|
+
upper_name varchar(256)
|
|
29
|
+
);
|
|
30
|
+
SQL
|
|
31
|
+
adapter = Fx::Adapters::Postgres.new
|
|
32
|
+
adapter.create_function <<~SQL
|
|
33
|
+
CREATE OR REPLACE FUNCTION uppercase_users_name()
|
|
34
|
+
RETURNS trigger AS $$
|
|
35
|
+
BEGIN
|
|
36
|
+
NEW.upper_name = UPPER(NEW.name);
|
|
37
|
+
RETURN NEW;
|
|
38
|
+
END;
|
|
39
|
+
$$ LANGUAGE plpgsql;
|
|
40
|
+
SQL
|
|
41
|
+
adapter.create_trigger(
|
|
42
|
+
<<~SQL
|
|
43
|
+
CREATE TRIGGER uppercase_users_name
|
|
44
|
+
BEFORE INSERT ON users
|
|
45
|
+
FOR EACH ROW
|
|
46
|
+
EXECUTE FUNCTION uppercase_users_name();
|
|
47
|
+
SQL
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
expect(adapter.triggers.map(&:name)).to include("uppercase_users_name")
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe "#drop_function" do
|
|
55
|
+
context "when the function has arguments" do
|
|
56
|
+
it "successfully drops a function with the entire function signature" do
|
|
57
|
+
adapter = Fx::Adapters::Postgres.new
|
|
58
|
+
adapter.create_function(
|
|
59
|
+
<<~SQL
|
|
60
|
+
CREATE FUNCTION adder(x int, y int)
|
|
61
|
+
RETURNS int AS $$
|
|
62
|
+
BEGIN
|
|
63
|
+
RETURN $1 + $2;
|
|
64
|
+
END;
|
|
65
|
+
$$ LANGUAGE plpgsql;
|
|
66
|
+
SQL
|
|
67
|
+
)
|
|
75
68
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
)
|
|
89
|
-
|
|
90
|
-
adapter.drop_function(:test)
|
|
91
|
-
|
|
92
|
-
expect(adapter.functions.map(&:name)).not_to include("test")
|
|
93
|
-
end
|
|
69
|
+
adapter.drop_function(:adder)
|
|
70
|
+
|
|
71
|
+
expect(adapter.functions.map(&:name)).not_to include("adder")
|
|
94
72
|
end
|
|
95
73
|
end
|
|
96
74
|
|
|
97
|
-
|
|
98
|
-
it "
|
|
99
|
-
adapter = Postgres.new
|
|
75
|
+
context "when the function does not have arguments" do
|
|
76
|
+
it "successfully drops a function" do
|
|
77
|
+
adapter = Fx::Adapters::Postgres.new
|
|
100
78
|
adapter.create_function(
|
|
101
|
-
|
|
79
|
+
<<~SQL
|
|
102
80
|
CREATE OR REPLACE FUNCTION test()
|
|
103
81
|
RETURNS text AS $$
|
|
104
82
|
BEGIN
|
|
105
83
|
RETURN 'test';
|
|
106
84
|
END;
|
|
107
85
|
$$ LANGUAGE plpgsql;
|
|
108
|
-
|
|
86
|
+
SQL
|
|
109
87
|
)
|
|
110
88
|
|
|
111
|
-
|
|
89
|
+
adapter.drop_function(:test)
|
|
90
|
+
|
|
91
|
+
expect(adapter.functions.map(&:name)).not_to include("test")
|
|
112
92
|
end
|
|
113
93
|
end
|
|
94
|
+
end
|
|
114
95
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
);
|
|
123
|
-
EOS
|
|
124
|
-
adapter = Postgres.new
|
|
125
|
-
adapter.create_function <<-EOS
|
|
126
|
-
CREATE OR REPLACE FUNCTION uppercase_users_name()
|
|
127
|
-
RETURNS trigger AS $$
|
|
96
|
+
describe "#functions" do
|
|
97
|
+
it "finds functions and builds Fx::Function objects" do
|
|
98
|
+
adapter = Fx::Adapters::Postgres.new
|
|
99
|
+
adapter.create_function(
|
|
100
|
+
<<~SQL
|
|
101
|
+
CREATE OR REPLACE FUNCTION test()
|
|
102
|
+
RETURNS text AS $$
|
|
128
103
|
BEGIN
|
|
129
|
-
|
|
130
|
-
RETURN NEW;
|
|
104
|
+
RETURN 'test';
|
|
131
105
|
END;
|
|
132
106
|
$$ LANGUAGE plpgsql;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
CREATE TRIGGER uppercase_users_name
|
|
136
|
-
BEFORE INSERT ON users
|
|
137
|
-
FOR EACH ROW
|
|
138
|
-
EXECUTE FUNCTION uppercase_users_name()
|
|
139
|
-
EOS
|
|
140
|
-
adapter.create_trigger(sql_definition)
|
|
107
|
+
SQL
|
|
108
|
+
)
|
|
141
109
|
|
|
142
|
-
|
|
143
|
-
|
|
110
|
+
expect(adapter.functions.map(&:name)).to eq ["test"]
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe "#triggers" do
|
|
115
|
+
it "finds triggers and builds Fx::Trigger objects" do
|
|
116
|
+
connection.execute <<~SQL
|
|
117
|
+
CREATE TABLE users (
|
|
118
|
+
id int PRIMARY KEY,
|
|
119
|
+
name varchar(256),
|
|
120
|
+
upper_name varchar(256)
|
|
121
|
+
);
|
|
122
|
+
SQL
|
|
123
|
+
adapter = Fx::Adapters::Postgres.new
|
|
124
|
+
adapter.create_function <<~SQL
|
|
125
|
+
CREATE OR REPLACE FUNCTION uppercase_users_name()
|
|
126
|
+
RETURNS trigger AS $$
|
|
127
|
+
BEGIN
|
|
128
|
+
NEW.upper_name = UPPER(NEW.name);
|
|
129
|
+
RETURN NEW;
|
|
130
|
+
END;
|
|
131
|
+
$$ LANGUAGE plpgsql;
|
|
132
|
+
SQL
|
|
133
|
+
sql_definition = <<~SQL
|
|
134
|
+
CREATE TRIGGER uppercase_users_name
|
|
135
|
+
BEFORE INSERT ON users
|
|
136
|
+
FOR EACH ROW
|
|
137
|
+
EXECUTE FUNCTION uppercase_users_name()
|
|
138
|
+
SQL
|
|
139
|
+
adapter.create_trigger(sql_definition)
|
|
140
|
+
|
|
141
|
+
expect(adapter.triggers.map(&:name)).to eq ["uppercase_users_name"]
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
describe "#support_drop_function_without_args" do
|
|
146
|
+
it "returns true for PostgreSQL version 10.0" do
|
|
147
|
+
adapter = Fx::Adapters::Postgres.new
|
|
148
|
+
connection = adapter.send(:connection)
|
|
149
|
+
allow(connection).to receive(:server_version).and_return(10_00_00)
|
|
150
|
+
|
|
151
|
+
result = connection.support_drop_function_without_args
|
|
152
|
+
|
|
153
|
+
expect(result).to be(true)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "returns true for PostgreSQL version 11.0" do
|
|
157
|
+
adapter = Fx::Adapters::Postgres.new
|
|
158
|
+
connection = adapter.send(:connection)
|
|
159
|
+
allow(connection).to receive(:server_version).and_return(11_00_00)
|
|
160
|
+
|
|
161
|
+
result = connection.support_drop_function_without_args
|
|
162
|
+
|
|
163
|
+
expect(result).to be(true)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "returns false for PostgreSQL version 9.6" do
|
|
167
|
+
adapter = Fx::Adapters::Postgres.new
|
|
168
|
+
connection = adapter.send(:connection)
|
|
169
|
+
allow(connection).to receive(:server_version).and_return(9_06_00)
|
|
170
|
+
|
|
171
|
+
result = connection.support_drop_function_without_args
|
|
172
|
+
|
|
173
|
+
expect(result).to be(false)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "returns false for PostgreSQL version 9.5" do
|
|
177
|
+
adapter = Fx::Adapters::Postgres.new
|
|
178
|
+
connection = adapter.send(:connection)
|
|
179
|
+
allow(connection).to receive(:server_version).and_return(9_05_00)
|
|
180
|
+
|
|
181
|
+
result = connection.support_drop_function_without_args
|
|
182
|
+
|
|
183
|
+
expect(result).to be(false)
|
|
144
184
|
end
|
|
145
185
|
end
|
|
146
186
|
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
|
-
describe Fx::CommandRecorder, :db do
|
|
3
|
+
RSpec.describe Fx::CommandRecorder, :db do
|
|
4
4
|
describe "#create_function" do
|
|
5
5
|
it "records the created function" do
|
|
6
6
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
7
7
|
|
|
8
8
|
recorder.create_function :test
|
|
9
9
|
|
|
10
|
-
expect(recorder.commands).to eq
|
|
10
|
+
expect(recorder.commands).to eq([[:create_function, [:test], nil]])
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
it "reverts to drop_function" do
|
|
@@ -15,7 +15,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
15
15
|
|
|
16
16
|
recorder.create_function :test
|
|
17
17
|
|
|
18
|
-
expect(recorder.commands).to eq
|
|
18
|
+
expect(recorder.commands).to eq([[:create_function, [:test], nil]])
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
it "reverts to drop_function" do
|
|
@@ -23,7 +23,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
23
23
|
|
|
24
24
|
recorder.revert { recorder.create_function :test }
|
|
25
25
|
|
|
26
|
-
expect(recorder.commands).to eq
|
|
26
|
+
expect(recorder.commands).to eq([[:drop_function, [:test]]])
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -33,7 +33,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
33
33
|
|
|
34
34
|
recorder.drop_function :test
|
|
35
35
|
|
|
36
|
-
expect(recorder.commands).to eq
|
|
36
|
+
expect(recorder.commands).to eq([[:drop_function, [:test], nil]])
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
it "reverts to create_function with specified revert_to_version" do
|
|
@@ -43,15 +43,16 @@ describe Fx::CommandRecorder, :db do
|
|
|
43
43
|
|
|
44
44
|
recorder.revert { recorder.drop_function(*args) }
|
|
45
45
|
|
|
46
|
-
expect(recorder.commands).to eq
|
|
46
|
+
expect(recorder.commands).to eq([[:create_function, revert_args]])
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
it "raises when reverting without revert_to_version set" do
|
|
50
50
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
51
51
|
args = [:test, {another_argument: 1}]
|
|
52
52
|
|
|
53
|
-
expect
|
|
54
|
-
.
|
|
53
|
+
expect do
|
|
54
|
+
recorder.revert { recorder.drop_function(*args) }
|
|
55
|
+
end.to raise_error(ActiveRecord::IrreversibleMigration)
|
|
55
56
|
end
|
|
56
57
|
end
|
|
57
58
|
|
|
@@ -62,7 +63,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
62
63
|
|
|
63
64
|
recorder.update_function(*args)
|
|
64
65
|
|
|
65
|
-
expect(recorder.commands).to eq
|
|
66
|
+
expect(recorder.commands).to eq([[:update_function, args, nil]])
|
|
66
67
|
end
|
|
67
68
|
|
|
68
69
|
it "reverts to update_function with the specified revert_to_version" do
|
|
@@ -72,15 +73,16 @@ describe Fx::CommandRecorder, :db do
|
|
|
72
73
|
|
|
73
74
|
recorder.revert { recorder.update_function(*args) }
|
|
74
75
|
|
|
75
|
-
expect(recorder.commands).to eq
|
|
76
|
+
expect(recorder.commands).to eq([[:update_function, revert_args]])
|
|
76
77
|
end
|
|
77
78
|
|
|
78
79
|
it "raises when reverting without revert_to_version set" do
|
|
79
80
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
80
81
|
args = [:test, {version: 42, another_argument: 1}]
|
|
81
82
|
|
|
82
|
-
expect
|
|
83
|
-
.
|
|
83
|
+
expect do
|
|
84
|
+
recorder.revert { recorder.update_function(*args) }
|
|
85
|
+
end.to raise_error(ActiveRecord::IrreversibleMigration)
|
|
84
86
|
end
|
|
85
87
|
end
|
|
86
88
|
|
|
@@ -90,7 +92,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
90
92
|
|
|
91
93
|
recorder.create_trigger :greetings
|
|
92
94
|
|
|
93
|
-
expect(recorder.commands).to eq
|
|
95
|
+
expect(recorder.commands).to eq([[:create_trigger, [:greetings], nil]])
|
|
94
96
|
end
|
|
95
97
|
|
|
96
98
|
it "reverts to drop_trigger" do
|
|
@@ -98,9 +100,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
98
100
|
|
|
99
101
|
recorder.create_trigger :greetings
|
|
100
102
|
|
|
101
|
-
expect(recorder.commands).to eq [
|
|
102
|
-
[:create_trigger, [:greetings], nil]
|
|
103
|
-
]
|
|
103
|
+
expect(recorder.commands).to eq([[:create_trigger, [:greetings], nil]])
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
it "reverts to drop_trigger" do
|
|
@@ -108,7 +108,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
108
108
|
|
|
109
109
|
recorder.revert { recorder.create_trigger :greetings }
|
|
110
110
|
|
|
111
|
-
expect(recorder.commands).to eq
|
|
111
|
+
expect(recorder.commands).to eq([[:drop_trigger, [:greetings]]])
|
|
112
112
|
end
|
|
113
113
|
end
|
|
114
114
|
|
|
@@ -118,7 +118,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
118
118
|
|
|
119
119
|
recorder.drop_trigger :users
|
|
120
120
|
|
|
121
|
-
expect(recorder.commands).to eq
|
|
121
|
+
expect(recorder.commands).to eq([[:drop_trigger, [:users], nil]])
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
it "reverts to create_trigger with specified revert_to_version" do
|
|
@@ -128,15 +128,16 @@ describe Fx::CommandRecorder, :db do
|
|
|
128
128
|
|
|
129
129
|
recorder.revert { recorder.drop_trigger(*args) }
|
|
130
130
|
|
|
131
|
-
expect(recorder.commands).to eq
|
|
131
|
+
expect(recorder.commands).to eq([[:create_trigger, revert_args]])
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
it "raises when reverting without revert_to_version set" do
|
|
135
135
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
136
136
|
args = [:users, {another_argument: 1}]
|
|
137
137
|
|
|
138
|
-
expect
|
|
139
|
-
.
|
|
138
|
+
expect do
|
|
139
|
+
recorder.revert { recorder.drop_trigger(*args) }
|
|
140
|
+
end.to raise_error(ActiveRecord::IrreversibleMigration)
|
|
140
141
|
end
|
|
141
142
|
end
|
|
142
143
|
|
|
@@ -147,7 +148,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
147
148
|
|
|
148
149
|
recorder.update_trigger(*args)
|
|
149
150
|
|
|
150
|
-
expect(recorder.commands).to eq
|
|
151
|
+
expect(recorder.commands).to eq([[:update_trigger, args, nil]])
|
|
151
152
|
end
|
|
152
153
|
|
|
153
154
|
it "reverts to update_trigger with the specified revert_to_version" do
|
|
@@ -157,15 +158,16 @@ describe Fx::CommandRecorder, :db do
|
|
|
157
158
|
|
|
158
159
|
recorder.revert { recorder.update_trigger(*args) }
|
|
159
160
|
|
|
160
|
-
expect(recorder.commands).to eq
|
|
161
|
+
expect(recorder.commands).to eq([[:update_trigger, revert_args]])
|
|
161
162
|
end
|
|
162
163
|
|
|
163
164
|
it "raises when reverting without revert_to_version set" do
|
|
164
165
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
165
166
|
args = [:users, {version: 42, another_argument: 1}]
|
|
166
167
|
|
|
167
|
-
expect
|
|
168
|
-
.
|
|
168
|
+
expect do
|
|
169
|
+
recorder.revert { recorder.update_trigger(*args) }
|
|
170
|
+
end.to raise_error(ActiveRecord::IrreversibleMigration)
|
|
169
171
|
end
|
|
170
172
|
end
|
|
171
173
|
end
|
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
|
-
describe Fx::Configuration do
|
|
3
|
+
RSpec.describe Fx::Configuration do
|
|
4
4
|
it "defaults the database adapter to postgres" do
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
configuration = Fx::Configuration.new
|
|
6
|
+
|
|
7
|
+
expect(configuration.database).to be_a(Fx::Adapters::Postgres)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "defaults `dump_functions_at_beginning_of_schema` to false" do
|
|
11
|
+
configuration = Fx::Configuration.new
|
|
12
|
+
|
|
13
|
+
expect(configuration.dump_functions_at_beginning_of_schema).to eq(false)
|
|
7
14
|
end
|
|
8
15
|
|
|
9
16
|
it "allows the database adapter to be set" do
|
|
17
|
+
configuration = Fx::Configuration.new
|
|
10
18
|
adapter = double("Fx Adapter")
|
|
11
19
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
configuration.database = adapter
|
|
21
|
+
|
|
22
|
+
expect(configuration.database).to eq(adapter)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "allows `dump_functions_at_beginning_of_schema` to be set" do
|
|
26
|
+
configuration = Fx::Configuration.new
|
|
15
27
|
|
|
16
|
-
|
|
17
|
-
expect(Fx.database).to eq adapter
|
|
28
|
+
configuration.dump_functions_at_beginning_of_schema = true
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
expect(configuration.dump_functions_at_beginning_of_schema).to eq(true)
|
|
20
31
|
end
|
|
21
32
|
end
|
data/spec/fx/definition_spec.rb
CHANGED
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
|
-
describe Fx::Definition do
|
|
3
|
+
RSpec.describe Fx::Definition do
|
|
4
4
|
describe "#to_sql" do
|
|
5
5
|
context "representing a function definition" do
|
|
6
6
|
it "returns the content of a function definition" do
|
|
7
|
-
sql_definition =
|
|
7
|
+
sql_definition = <<~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
|
-
|
|
14
|
+
SQL
|
|
15
15
|
allow(File).to receive(:read).and_return(sql_definition)
|
|
16
16
|
|
|
17
|
-
definition = Fx::Definition.
|
|
17
|
+
definition = Fx::Definition.function(name: "test", version: 1)
|
|
18
18
|
|
|
19
|
-
expect(definition.to_sql).to eq
|
|
19
|
+
expect(definition.to_sql).to eq(sql_definition)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
it "raises an error if the file is empty" do
|
|
23
23
|
allow(File).to receive(:read).and_return("")
|
|
24
|
-
definition = Fx::Definition.
|
|
24
|
+
definition = Fx::Definition.function(name: "test", version: 1)
|
|
25
25
|
|
|
26
|
-
expect
|
|
26
|
+
expect do
|
|
27
|
+
definition.to_sql
|
|
28
|
+
end.to raise_error(
|
|
27
29
|
RuntimeError,
|
|
28
30
|
%r{Define function in db/functions/test_v01.sql before migrating}
|
|
29
31
|
)
|
|
@@ -31,22 +33,22 @@ describe Fx::Definition do
|
|
|
31
33
|
|
|
32
34
|
context "when definition is at Rails engine" do
|
|
33
35
|
it "returns the content of a function definition" do
|
|
34
|
-
sql_definition =
|
|
36
|
+
sql_definition = <<~SQL
|
|
35
37
|
CREATE OR REPLACE FUNCTION test()
|
|
36
38
|
RETURNS text AS $$
|
|
37
39
|
BEGIN
|
|
38
40
|
RETURN 'test';
|
|
39
41
|
END;
|
|
40
42
|
$$ LANGUAGE plpgsql;
|
|
41
|
-
|
|
43
|
+
SQL
|
|
42
44
|
engine_path = Rails.root.join("tmp", "engine")
|
|
43
45
|
FileUtils.mkdir_p(engine_path.join("db", "functions"))
|
|
44
46
|
File.write(engine_path.join("db", "functions", "custom_test_v01.sql"), sql_definition)
|
|
45
47
|
Rails.application.config.paths["db/migrate"].push(engine_path.join("db", "migrate"))
|
|
46
48
|
|
|
47
|
-
definition = Fx::Definition.
|
|
49
|
+
definition = Fx::Definition.function(name: "custom_test", version: 1)
|
|
48
50
|
|
|
49
|
-
expect(definition.to_sql).to eq
|
|
51
|
+
expect(definition.to_sql).to eq(sql_definition)
|
|
50
52
|
|
|
51
53
|
FileUtils.rm_rf(engine_path)
|
|
52
54
|
end
|
|
@@ -55,32 +57,26 @@ describe Fx::Definition do
|
|
|
55
57
|
|
|
56
58
|
context "representing a trigger definition" do
|
|
57
59
|
it "returns the content of a trigger definition" do
|
|
58
|
-
sql_definition =
|
|
60
|
+
sql_definition = <<~SQL
|
|
59
61
|
CREATE TRIGGER check_update
|
|
60
62
|
BEFORE UPDATE ON accounts
|
|
61
63
|
FOR EACH ROW
|
|
62
64
|
EXECUTE FUNCTION check_account_update();
|
|
63
|
-
|
|
65
|
+
SQL
|
|
64
66
|
allow(File).to receive(:read).and_return(sql_definition)
|
|
65
67
|
|
|
66
|
-
definition = Fx::Definition.
|
|
67
|
-
name: "test",
|
|
68
|
-
version: 1,
|
|
69
|
-
type: "trigger"
|
|
70
|
-
)
|
|
68
|
+
definition = Fx::Definition.trigger(name: "test", version: 1)
|
|
71
69
|
|
|
72
|
-
expect(definition.to_sql).to eq
|
|
70
|
+
expect(definition.to_sql).to eq(sql_definition)
|
|
73
71
|
end
|
|
74
72
|
|
|
75
73
|
it "raises an error if the file is empty" do
|
|
76
74
|
allow(File).to receive(:read).and_return("")
|
|
77
|
-
definition = Fx::Definition.
|
|
78
|
-
name: "test",
|
|
79
|
-
version: 1,
|
|
80
|
-
type: "trigger"
|
|
81
|
-
)
|
|
75
|
+
definition = Fx::Definition.trigger(name: "test", version: 1)
|
|
82
76
|
|
|
83
|
-
expect
|
|
77
|
+
expect do
|
|
78
|
+
definition.to_sql
|
|
79
|
+
end.to raise_error(
|
|
84
80
|
RuntimeError,
|
|
85
81
|
%r{Define trigger in db/triggers/test_v01.sql before migrating}
|
|
86
82
|
)
|
|
@@ -91,44 +87,40 @@ describe Fx::Definition do
|
|
|
91
87
|
describe "#path" do
|
|
92
88
|
context "representing a function definition" do
|
|
93
89
|
it "returns a sql file with padded version and function name" do
|
|
94
|
-
definition = Fx::Definition.
|
|
90
|
+
definition = Fx::Definition.function(name: "test", version: 1)
|
|
95
91
|
|
|
96
|
-
expect(definition.path).to eq
|
|
92
|
+
expect(definition.path).to eq("db/functions/test_v01.sql")
|
|
97
93
|
end
|
|
98
94
|
end
|
|
99
95
|
|
|
100
96
|
context "representing a trigger definition" do
|
|
101
97
|
it "returns a sql file with padded version and trigger name" do
|
|
102
|
-
definition = Fx::Definition.
|
|
103
|
-
name: "test",
|
|
104
|
-
version: 1,
|
|
105
|
-
type: "trigger"
|
|
106
|
-
)
|
|
98
|
+
definition = Fx::Definition.trigger(name: "test", version: 1)
|
|
107
99
|
|
|
108
|
-
expect(definition.path).to eq
|
|
100
|
+
expect(definition.path).to eq("db/triggers/test_v01.sql")
|
|
109
101
|
end
|
|
110
102
|
end
|
|
111
103
|
end
|
|
112
104
|
|
|
113
105
|
describe "#full_path" do
|
|
114
106
|
it "joins the path with Rails.root" do
|
|
115
|
-
definition = Fx::Definition.
|
|
107
|
+
definition = Fx::Definition.function(name: "test", version: 15)
|
|
116
108
|
|
|
117
|
-
expect(definition.full_path).to eq
|
|
109
|
+
expect(definition.full_path).to eq(Rails.root.join(definition.path))
|
|
118
110
|
end
|
|
119
111
|
end
|
|
120
112
|
|
|
121
113
|
describe "#version" do
|
|
122
114
|
it "pads the version number with 0" do
|
|
123
|
-
definition = Fx::Definition.
|
|
115
|
+
definition = Fx::Definition.function(name: :_, version: 1)
|
|
124
116
|
|
|
125
|
-
expect(definition.version).to eq
|
|
117
|
+
expect(definition.version).to eq("01")
|
|
126
118
|
end
|
|
127
119
|
|
|
128
120
|
it "does not pad more than 2 characters" do
|
|
129
|
-
definition = Fx::Definition.
|
|
121
|
+
definition = Fx::Definition.function(name: :_, version: 15)
|
|
130
122
|
|
|
131
|
-
expect(definition.version).to eq
|
|
123
|
+
expect(definition.version).to eq("15")
|
|
132
124
|
end
|
|
133
125
|
end
|
|
134
126
|
end
|