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,42 +1,49 @@
|
|
|
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 FunctionGenerator < Rails::Generators::NamedBase
|
|
8
11
|
include Rails::Generators::Migration
|
|
12
|
+
|
|
9
13
|
source_root File.expand_path("../templates", __FILE__)
|
|
10
14
|
|
|
15
|
+
DEFINITION_PATH = %w[db functions].freeze
|
|
16
|
+
|
|
11
17
|
class_option :migration, type: :boolean
|
|
12
18
|
|
|
13
19
|
def create_functions_directory
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
return if function_definition_path.exist?
|
|
21
|
+
|
|
22
|
+
empty_directory(function_definition_path)
|
|
17
23
|
end
|
|
18
24
|
|
|
19
25
|
def create_function_definition
|
|
20
|
-
if
|
|
21
|
-
create_file
|
|
26
|
+
if version_helper.creating_new?
|
|
27
|
+
create_file(definition.path)
|
|
22
28
|
else
|
|
23
|
-
copy_file
|
|
29
|
+
copy_file(previous_definition.full_path, definition.full_path)
|
|
24
30
|
end
|
|
25
31
|
end
|
|
26
32
|
|
|
27
33
|
def create_migration_file
|
|
28
|
-
return if
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
)
|
|
39
|
-
|
|
34
|
+
return if migration_helper.skip_creation?
|
|
35
|
+
|
|
36
|
+
template_info = migration_helper.migration_template_info(
|
|
37
|
+
object_type: :function,
|
|
38
|
+
file_name: file_name,
|
|
39
|
+
updating_existing: version_helper.updating_existing?,
|
|
40
|
+
version: version_helper.current_version
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
migration_template(
|
|
44
|
+
template_info.fetch(:template),
|
|
45
|
+
template_info.fetch(:filename)
|
|
46
|
+
)
|
|
40
47
|
end
|
|
41
48
|
|
|
42
49
|
def self.next_migration_number(dir)
|
|
@@ -45,75 +52,65 @@ module Fx
|
|
|
45
52
|
|
|
46
53
|
no_tasks do
|
|
47
54
|
def previous_version
|
|
48
|
-
|
|
49
|
-
.map { |name| version_regex.match(name).try(:[], "version").to_i }
|
|
50
|
-
.max
|
|
55
|
+
version_helper.previous_version
|
|
51
56
|
end
|
|
52
57
|
|
|
53
58
|
def version
|
|
54
|
-
|
|
59
|
+
version_helper.current_version
|
|
55
60
|
end
|
|
56
61
|
|
|
57
62
|
def migration_class_name
|
|
58
|
-
if
|
|
59
|
-
|
|
63
|
+
if version_helper.updating_existing?
|
|
64
|
+
migration_helper.update_migration_class_name(
|
|
65
|
+
object_type: :function,
|
|
66
|
+
class_name: class_name,
|
|
67
|
+
version: version
|
|
68
|
+
)
|
|
60
69
|
else
|
|
61
70
|
super
|
|
62
71
|
end
|
|
63
72
|
end
|
|
64
73
|
|
|
65
|
-
def
|
|
66
|
-
|
|
67
|
-
"ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]"
|
|
68
|
-
else
|
|
69
|
-
"ActiveRecord::Migration"
|
|
70
|
-
end
|
|
74
|
+
def active_record_migration_class
|
|
75
|
+
migration_helper.active_record_migration_class
|
|
71
76
|
end
|
|
72
77
|
|
|
73
78
|
def formatted_name
|
|
74
|
-
|
|
75
|
-
"\"#{singular_name}\""
|
|
76
|
-
else
|
|
77
|
-
":#{singular_name}"
|
|
78
|
-
end
|
|
79
|
+
NameHelper.format_for_migration(singular_name)
|
|
79
80
|
end
|
|
80
81
|
end
|
|
81
82
|
|
|
82
83
|
private
|
|
83
84
|
|
|
84
85
|
def function_definition_path
|
|
85
|
-
@_function_definition_path ||= Rails.root.join(
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def version_regex
|
|
89
|
-
/\A#{file_name}_v(?<version>\d+)\.sql\z/
|
|
86
|
+
@_function_definition_path ||= Rails.root.join(*DEFINITION_PATH)
|
|
90
87
|
end
|
|
91
88
|
|
|
92
|
-
def
|
|
93
|
-
|
|
89
|
+
def version_helper
|
|
90
|
+
@_version_helper ||= Fx::Generators::VersionHelper.new(
|
|
91
|
+
file_name: file_name,
|
|
92
|
+
definition_path: function_definition_path
|
|
93
|
+
)
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
-
def
|
|
97
|
-
|
|
96
|
+
def migration_helper
|
|
97
|
+
@_migration_helper ||= Fx::Generators::MigrationHelper.new(options)
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
def definition
|
|
101
|
-
|
|
101
|
+
version_helper.definition_for_version(version: version, type: :function)
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
def previous_definition
|
|
105
|
-
|
|
105
|
+
version_helper.definition_for_version(version: previous_version, type: :function)
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def skip_migration_creation?
|
|
111
|
-
!migration
|
|
108
|
+
def updating_existing_function?
|
|
109
|
+
version_helper.updating_existing?
|
|
112
110
|
end
|
|
113
111
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
options[:migration] != false
|
|
112
|
+
def creating_new_function?
|
|
113
|
+
version_helper.creating_new?
|
|
117
114
|
end
|
|
118
115
|
end
|
|
119
116
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class <%= migration_class_name %> < <%=
|
|
1
|
+
class <%= migration_class_name %> < <%= active_record_migration_class %>
|
|
2
2
|
def change
|
|
3
3
|
update_function <%= formatted_name %>, version: <%= version %>, revert_to_version: <%= previous_version %>
|
|
4
4
|
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Fx
|
|
2
|
+
module Generators
|
|
3
|
+
# @api private
|
|
4
|
+
class MigrationHelper
|
|
5
|
+
def initialize(options)
|
|
6
|
+
@options = options
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def skip_creation?
|
|
10
|
+
!should_create_migration?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def active_record_migration_class
|
|
14
|
+
if ActiveRecord::Migration.respond_to?(:current_version)
|
|
15
|
+
"ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]"
|
|
16
|
+
else
|
|
17
|
+
"ActiveRecord::Migration"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def update_migration_class_name(object_type:, class_name:, version:)
|
|
22
|
+
"Update#{object_type.capitalize}#{class_name}ToVersion#{version}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def migration_template_info(
|
|
26
|
+
object_type:,
|
|
27
|
+
file_name:,
|
|
28
|
+
updating_existing:,
|
|
29
|
+
version:
|
|
30
|
+
)
|
|
31
|
+
if updating_existing
|
|
32
|
+
{
|
|
33
|
+
template: "db/migrate/update_#{object_type}.erb",
|
|
34
|
+
filename: "db/migrate/update_#{object_type}_#{file_name}_to_version_#{version}.rb"
|
|
35
|
+
}
|
|
36
|
+
else
|
|
37
|
+
{
|
|
38
|
+
template: "db/migrate/create_#{object_type}.erb",
|
|
39
|
+
filename: "db/migrate/create_#{object_type}_#{file_name}.rb"
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
attr_reader :options
|
|
47
|
+
|
|
48
|
+
def should_create_migration?
|
|
49
|
+
options.fetch(:migration, true)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Fx
|
|
2
|
+
module Generators
|
|
3
|
+
# @api private
|
|
4
|
+
class NameHelper
|
|
5
|
+
def self.format_for_migration(name)
|
|
6
|
+
if name.include?(".")
|
|
7
|
+
"\"#{name}\""
|
|
8
|
+
else
|
|
9
|
+
":#{name}"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.format_table_name_from_hash(table_hash)
|
|
14
|
+
name = table_hash["table_name"] || table_hash["on"]
|
|
15
|
+
|
|
16
|
+
if name.nil?
|
|
17
|
+
raise(
|
|
18
|
+
ArgumentError,
|
|
19
|
+
"Either `table_name:NAME` or `on:NAME` must be specified"
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
format_for_migration(name)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.validate_and_format(name)
|
|
27
|
+
raise ArgumentError, "Name cannot be blank" if name.blank?
|
|
28
|
+
|
|
29
|
+
format_for_migration(name)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class <%= migration_class_name %> < <%=
|
|
1
|
+
class <%= migration_class_name %> < <%= active_record_migration_class %>
|
|
2
2
|
def change
|
|
3
3
|
update_trigger <%= formatted_name %>, on: <%= formatted_table_name %>, version: <%= version %>, revert_to_version: <%= previous_version %>
|
|
4
4
|
end
|
|
@@ -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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
|
27
|
+
create_file(definition.path)
|
|
22
28
|
end
|
|
23
29
|
|
|
24
30
|
def create_migration_file
|
|
25
|
-
return if
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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,88 +46,61 @@ module Fx
|
|
|
42
46
|
|
|
43
47
|
no_tasks do
|
|
44
48
|
def previous_version
|
|
45
|
-
|
|
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
|
-
|
|
53
|
+
version_helper.current_version
|
|
52
54
|
end
|
|
53
55
|
|
|
54
56
|
def migration_class_name
|
|
55
|
-
if
|
|
56
|
-
|
|
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
|
|
63
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
99
|
-
|
|
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
|
|
107
|
-
Fx::
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
type: "trigger"
|
|
87
|
+
def version_helper
|
|
88
|
+
@_version_helper ||= Fx::Generators::VersionHelper.new(
|
|
89
|
+
file_name: file_name,
|
|
90
|
+
definition_path: trigger_definition_path
|
|
111
91
|
)
|
|
112
92
|
end
|
|
113
93
|
|
|
114
|
-
def
|
|
115
|
-
@
|
|
94
|
+
def migration_helper
|
|
95
|
+
@_migration_helper ||= Fx::Generators::MigrationHelper.new(options)
|
|
116
96
|
end
|
|
117
97
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def skip_migration_creation?
|
|
121
|
-
!migration
|
|
98
|
+
def definition
|
|
99
|
+
version_helper.definition_for_version(version: version, type: :trigger)
|
|
122
100
|
end
|
|
123
101
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
options[:migration] != false
|
|
102
|
+
def updating_existing_trigger?
|
|
103
|
+
version_helper.updating_existing?
|
|
127
104
|
end
|
|
128
105
|
end
|
|
129
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
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
require "acceptance_helper"
|
|
2
2
|
|
|
3
|
-
describe "User manages functions" do
|
|
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",
|
|
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
|
-
|
|
13
|
+
SQL
|
|
14
14
|
successfully "rake db:migrate"
|
|
15
15
|
|
|
16
16
|
result = execute("SELECT * FROM test() AS result")
|
|
@@ -21,14 +21,14 @@ 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",
|
|
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
|
-
|
|
31
|
+
SQL
|
|
32
32
|
successfully "rake db:migrate"
|
|
33
33
|
|
|
34
34
|
result = execute("SELECT * FROM test() AS result")
|
|
@@ -37,14 +37,14 @@ 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",
|
|
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
|
-
|
|
47
|
+
SQL
|
|
48
48
|
successfully "rake db:migrate"
|
|
49
49
|
|
|
50
50
|
result = execute("SELECT * FROM adder(1, 2) AS result")
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
require "acceptance_helper"
|
|
2
2
|
|
|
3
|
-
describe "User manages triggers" do
|
|
3
|
+
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",
|
|
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 @@ describe "User manages triggers" do
|
|
|
12
12
|
RETURN NEW;
|
|
13
13
|
END;
|
|
14
14
|
$$ LANGUAGE plpgsql;
|
|
15
|
-
|
|
15
|
+
SQL
|
|
16
16
|
successfully "rails generate fx:trigger uppercase_users_name table_name:users"
|
|
17
|
-
write_trigger_definition "uppercase_users_name_v01",
|
|
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
|
-
|
|
22
|
+
SQL
|
|
23
23
|
successfully "rake db:migrate"
|
|
24
24
|
|
|
25
|
-
execute
|
|
25
|
+
execute <<~SQL
|
|
26
26
|
INSERT INTO users
|
|
27
27
|
(name, created_at, updated_at)
|
|
28
28
|
VALUES
|
|
29
29
|
('Bob', NOW(), NOW());
|
|
30
|
-
|
|
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",
|
|
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
|
-
|
|
40
|
+
SQL
|
|
41
41
|
successfully "rake db:migrate"
|
|
42
|
-
execute
|
|
42
|
+
execute <<~SQL
|
|
43
43
|
UPDATE users
|
|
44
44
|
SET name = 'Alice'
|
|
45
45
|
WHERE id = 1;
|
|
46
|
-
|
|
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")
|
data/spec/acceptance_helper.rb
CHANGED
|
@@ -11,10 +11,10 @@ RSpec.configure do |config|
|
|
|
11
11
|
|
|
12
12
|
config.before(:suite) do
|
|
13
13
|
Dir.chdir("spec/dummy") do
|
|
14
|
-
system
|
|
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
|
|
@@ -24,7 +24,7 @@ RSpec.configure do |config|
|
|
|
24
24
|
config.after(:suite) do
|
|
25
25
|
Dir.chdir("spec/dummy") do
|
|
26
26
|
ActiveRecord::Base.connection.disconnect!
|
|
27
|
-
system
|
|
27
|
+
system <<~CMD
|
|
28
28
|
echo &&
|
|
29
29
|
rake db:environment:set db:drop db:create 1>/dev/null &&
|
|
30
30
|
git add -A &&
|
|
@@ -12,6 +12,10 @@ module Dummy
|
|
|
12
12
|
config.eager_load = false
|
|
13
13
|
config.active_support.deprecation = :stderr
|
|
14
14
|
|
|
15
|
-
config.
|
|
15
|
+
config.load_defaults 7.0
|
|
16
|
+
|
|
17
|
+
if Rails.version >= "8.0"
|
|
18
|
+
config.active_support.to_time_preserves_timezone = :zone
|
|
19
|
+
end
|
|
16
20
|
end
|
|
17
21
|
end
|