pg_trunk 0.1.2 → 0.1.3

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +4 -15
  3. data/CHANGELOG.md +6 -0
  4. data/README.md +1 -0
  5. data/lib/pg_trunk/operations/check_constraints/add_check_constraint.rb +3 -3
  6. data/lib/pg_trunk/operations/check_constraints/drop_check_constraint.rb +4 -4
  7. data/lib/pg_trunk/operations/check_constraints/rename_check_constraint.rb +2 -2
  8. data/lib/pg_trunk/operations/check_constraints/validate_check_constraint.rb +1 -1
  9. data/lib/pg_trunk/operations/composite_types/change_composite_type.rb +2 -2
  10. data/lib/pg_trunk/operations/composite_types/create_composite_type.rb +1 -1
  11. data/lib/pg_trunk/operations/composite_types/drop_composite_type.rb +3 -3
  12. data/lib/pg_trunk/operations/composite_types/rename_composite_type.rb +1 -1
  13. data/lib/pg_trunk/operations/domains/create_domain.rb +5 -5
  14. data/lib/pg_trunk/operations/domains/drop_domain.rb +6 -6
  15. data/lib/pg_trunk/operations/domains/rename_domain.rb +1 -1
  16. data/lib/pg_trunk/operations/enums/create_enum.rb +2 -2
  17. data/lib/pg_trunk/operations/enums/drop_enum.rb +4 -4
  18. data/lib/pg_trunk/operations/enums/rename_enum.rb +1 -1
  19. data/lib/pg_trunk/operations/foreign_keys/add_foreign_key.rb +8 -8
  20. data/lib/pg_trunk/operations/foreign_keys/drop_foreign_key.rb +9 -9
  21. data/lib/pg_trunk/operations/foreign_keys/rename_foreign_key.rb +5 -5
  22. data/lib/pg_trunk/operations/functions/change_function.rb +1 -1
  23. data/lib/pg_trunk/operations/functions/create_function.rb +11 -11
  24. data/lib/pg_trunk/operations/functions/drop_function.rb +12 -12
  25. data/lib/pg_trunk/operations/functions/rename_function.rb +1 -1
  26. data/lib/pg_trunk/operations/materialized_views/change_materialized_view.rb +1 -1
  27. data/lib/pg_trunk/operations/materialized_views/create_materialized_view.rb +6 -6
  28. data/lib/pg_trunk/operations/materialized_views/drop_materialized_view.rb +7 -7
  29. data/lib/pg_trunk/operations/materialized_views/refresh_materialized_view.rb +2 -2
  30. data/lib/pg_trunk/operations/materialized_views/rename_materialized_view.rb +2 -2
  31. data/lib/pg_trunk/operations/procedures/change_procedure.rb +1 -1
  32. data/lib/pg_trunk/operations/procedures/create_procedure.rb +5 -5
  33. data/lib/pg_trunk/operations/procedures/drop_procedure.rb +5 -5
  34. data/lib/pg_trunk/operations/procedures/rename_procedure.rb +1 -1
  35. data/lib/pg_trunk/operations/rules/base.rb +77 -0
  36. data/lib/pg_trunk/operations/rules/create_rule.rb +155 -0
  37. data/lib/pg_trunk/operations/rules/drop_rule.rb +94 -0
  38. data/lib/pg_trunk/operations/rules/rename_rule.rb +62 -0
  39. data/lib/pg_trunk/operations/rules.rb +13 -0
  40. data/lib/pg_trunk/operations/statistics/create_statistics.rb +4 -4
  41. data/lib/pg_trunk/operations/statistics/drop_statistics.rb +5 -5
  42. data/lib/pg_trunk/operations/statistics/rename_statistics.rb +1 -1
  43. data/lib/pg_trunk/operations/triggers/change_trigger.rb +1 -1
  44. data/lib/pg_trunk/operations/triggers/create_trigger.rb +9 -9
  45. data/lib/pg_trunk/operations/triggers/drop_trigger.rb +9 -9
  46. data/lib/pg_trunk/operations/triggers/rename_trigger.rb +6 -6
  47. data/lib/pg_trunk/operations/views/change_view.rb +1 -1
  48. data/lib/pg_trunk/operations/views/create_view.rb +5 -5
  49. data/lib/pg_trunk/operations/views/drop_view.rb +7 -7
  50. data/lib/pg_trunk/operations/views/rename_view.rb +2 -2
  51. data/lib/pg_trunk/operations.rb +1 -0
  52. data/lib/pg_trunk/version.rb +1 -1
  53. data/pg_trunk.gemspec +0 -1
  54. data/spec/operations/rules/create_rule_spec.rb +119 -0
  55. data/spec/operations/rules/drop_rule_spec.rb +117 -0
  56. data/spec/operations/rules/rename_rule_spec.rb +148 -0
  57. metadata +12 -68
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: false
2
+
3
+ module PGTrunk::Operations::Rules
4
+ # @abstract
5
+ # @private
6
+ # Base class for operations with rules
7
+ class Base < PGTrunk::Operation
8
+ attribute :command, :string
9
+ attribute :event, :pg_trunk_symbol
10
+ attribute :kind, :pg_trunk_symbol
11
+ attribute :replace_existing, :boolean
12
+ attribute :table, :pg_trunk_qualified_name
13
+ attribute :where, :string
14
+
15
+ # Generate missed name from table & expression
16
+ after_initialize { self.name = generated_name if name.blank? }
17
+
18
+ # Ensure correctness of present values
19
+ # The table must be defined because the name only
20
+ # is not enough to identify the constraint.
21
+ validates :if_not_exists, absence: true
22
+ validates :table, :name, presence: true
23
+ validates :kind, inclusion: { in: %i[instead also] }, allow_nil: true
24
+ validates :event, inclusion: { in: %i[insert update delete] }, allow_nil: true
25
+
26
+ # By default foreign keys are sorted by tables and names.
27
+ def <=>(other)
28
+ return unless other.is_a?(self.class)
29
+
30
+ result = table <=> other.table
31
+ result.zero? ? super : result
32
+ end
33
+
34
+ # Support `table` and `name` in positional arguments
35
+ # @example
36
+ # create_rule :users, "_do_nothing"
37
+ ruby_params :table, :name
38
+
39
+ # Snippet to be used in all operations with rules
40
+ ruby_snippet do |s|
41
+ s.ruby_param(table.lean) if table.present?
42
+ s.ruby_param(name.name) if custom_name?
43
+ s.ruby_param(if_exists: true) if if_exists
44
+ s.ruby_param(replace_existing: true) if replace_existing
45
+ s.ruby_param(force: :cascade) if force == :cascade
46
+
47
+ s.ruby_line(:event, event) if event.present?
48
+ s.ruby_line(:kind, :instead) if kind == :instead
49
+ s.ruby_line(:where, where) if where.present?
50
+ s.ruby_line(:command, command) if command.present?
51
+ s.ruby_line(:comment, comment) if comment.present?
52
+ end
53
+
54
+ private
55
+
56
+ # *************************************************************************
57
+ # Helpers for operation definitions
58
+ # *************************************************************************
59
+
60
+ def generated_name
61
+ return @generated_name if instance_variable_defined?(:@generated_name)
62
+
63
+ @generated_name = begin
64
+ return if table.blank? || event.blank?
65
+
66
+ key_options = { event: event, kind: (kind || :also) }
67
+ identifier = "#{table.lean}_#{key_options}_rule"
68
+ hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10)
69
+ PGTrunk::QualifiedName.wrap("rule_rails_#{hashed_identifier}")
70
+ end
71
+ end
72
+
73
+ def custom_name?(qname = name)
74
+ qname&.differs_from?(/^rule_rails_\w+$/)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: false
2
+
3
+ # @!parse
4
+ # class ActiveRecord::Migration
5
+ # # Create a rule
6
+ # #
7
+ # # @param [#to_s] table (nil) The qualified name of the table
8
+ # # @param [#to_s] name (nil) The name of the rule (unique within the table)
9
+ # # @option options [Boolean] :replace_existing (false) If the rule should overwrite an existing one
10
+ # # @option options [Symbol] :event (nil) The type of the query the rule is applied to.
11
+ # # Supported values: :update, :insert, :delete
12
+ # # @option options [Symbol] :kind (:also) The kind of the rule (either :also or :instead).
13
+ # # In case of `instead` the original query wouldn't be executed, only the `command` is.
14
+ # # @option options [String] :where (nil) The condition (SQL) for the rule to be applied.
15
+ # # @option options [String] :command (nil) The SQL command to be added by the rule.
16
+ # # @yield [r] the block with the rule's definition
17
+ # # @yieldparam Object receiver of methods specifying the procedure
18
+ # # @return [void]
19
+ # #
20
+ # # @notice `SELECT` rules are not supported by the gem.
21
+ # #
22
+ # # To create a rule you must define table, and event (operation) for the rule.
23
+ # # Usually you also supposed to define a command, but in case the `kind` is set
24
+ # # to `:instead`, missing the command would provide `INSTEAD DO NOTHING` rule.
25
+ # #
26
+ # # ```ruby
27
+ # # create_rule "users" do |r|
28
+ # # r.event :insert
29
+ # # r.kind :instead
30
+ # # r.comment "Forbid insertion to the table"
31
+ # # SQL
32
+ # # ```
33
+ # #
34
+ # # By default the kind is set to `:also`, in this case the `command` is needed as well:
35
+ # #
36
+ # # ```ruby
37
+ # # create_rule "users", "_count_insertion" do |r|
38
+ # # r.event :insert
39
+ # # r.command <<~SQL
40
+ # # UPDATE counters SET user_inserts = user_inserts + 1
41
+ # # SQL
42
+ # # r.comment "Count insertion to the table"
43
+ # # SQL
44
+ # # ```
45
+ # #
46
+ # # With a `when` option you can also specify a condition:
47
+ # #
48
+ # # ```ruby
49
+ # # create_rule "users", "_forbid_grants" do |r|
50
+ # # r.event :update
51
+ # # r.kind :instead
52
+ # # r.where "NOT old.admin AND new.admin"
53
+ # # r.comment "Forbid granting admin rights"
54
+ # # SQL
55
+ # # ```
56
+ # #
57
+ # # With a `replace_existing: true` option,
58
+ # # the rule will be created using the `CREATE OR REPLACE` clause.
59
+ # # In this case the migration is irreversible because we
60
+ # # don't know if and how to restore the previous definition.
61
+ # #
62
+ # # ```ruby
63
+ # # create_rule "users", "_forbid_insertion", replace_existing: true do |r|
64
+ # # r.event :insert
65
+ # # r.kind :instead
66
+ # # r.comment "Forbid insertion to the table"
67
+ # # SQL
68
+ # # ```
69
+ # def create_rule(table, name = nil, **options, &block); end
70
+ # end
71
+ module PGTrunk::Operations::Rules
72
+ # @private
73
+ class CreateRule < Base
74
+ validates :if_exists, :force, :new_name, absence: true
75
+ validates :event, presence: true
76
+ validate do
77
+ errors.add :command, :blank if kind != :instead && command.blank?
78
+ end
79
+
80
+ from_sql do |_server_version|
81
+ <<~SQL
82
+ SELECT
83
+ r.oid,
84
+ (c.relnamespace::regnamespace || '.' || c.relname) AS table,
85
+ r.rulename AS name,
86
+ (
87
+ CASE
88
+ WHEN r.ev_type = '1' THEN 'select'
89
+ WHEN r.ev_type = '2' THEN 'update'
90
+ WHEN r.ev_type = '3' THEN 'insert'
91
+ WHEN r.ev_type = '4' THEN 'delete'
92
+ END
93
+ ) AS event,
94
+ ( CASE WHEN r.is_instead THEN 'instead' ELSE 'also' END ) AS kind,
95
+ pg_get_expr(r.ev_qual, r.oid, true) AS "where",
96
+ regexp_replace(
97
+ regexp_replace(
98
+ pg_get_ruledef(r.oid, true),
99
+ '.+ DO +(INSTEAD +)?(ALSO +)?(NOTHING *)?| *;',
100
+ '',
101
+ 'g'
102
+ ), '(\n|\s)+', ' ', 'g'
103
+ ) AS command,
104
+ d.description AS comment
105
+ FROM pg_rewrite r
106
+ JOIN pg_class c ON c.oid = r.ev_class
107
+ JOIN pg_trunk t ON t.oid = r.oid
108
+ AND t.classid = 'pg_rewrite'::regclass
109
+ LEFT JOIN pg_description d ON d.objoid = r.oid
110
+ AND d.classoid = 'pg_rewrite'::regclass
111
+ SQL
112
+ end
113
+
114
+ def to_sql(_server_version)
115
+ [create_rule, *comment_rule, register_rule].join(" ")
116
+ end
117
+
118
+ def invert
119
+ irreversible!("replace_existing: true") if replace_existing
120
+ DropRule.new(**to_h)
121
+ end
122
+
123
+ private
124
+
125
+ def create_rule
126
+ sql = "CREATE"
127
+ sql << " OR REPLACE" if replace_existing
128
+ sql << " RULE #{name.to_sql} AS ON #{event.to_s.upcase}"
129
+ sql << " TO #{table.to_sql}"
130
+ sql << " WHERE #{where}" if where.present?
131
+ sql << " DO #{kind == :instead ? 'INSTEAD' : 'ALSO'}"
132
+ sql << " #{command.presence || 'NOTHING'}"
133
+ sql << ";"
134
+ end
135
+
136
+ def comment_rule
137
+ <<~SQL.squish if comment.present?
138
+ COMMENT ON RULE #{name.to_sql} ON #{table.to_sql}#{' '}
139
+ IS $comment$#{comment}$comment$;
140
+ SQL
141
+ end
142
+
143
+ def register_rule
144
+ <<~SQL.squish
145
+ INSERT INTO pg_trunk (oid, classid)
146
+ SELECT r.oid, 'pg_rewrite'::regclass
147
+ FROM pg_rewrite r JOIN pg_class c ON c.oid = r.ev_class
148
+ WHERE r.rulename = #{name.quoted}
149
+ AND c.relname = '#{table.name}'
150
+ AND c.relnamespace = #{table.namespace}
151
+ ON CONFLICT DO NOTHING;
152
+ SQL
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: false
2
+
3
+ # @!parse
4
+ # class ActiveRecord::Migration
5
+ # # Drop a rule
6
+ # #
7
+ # # @param [#to_s] table (nil) The qualified name of the table
8
+ # # @param [#to_s] name (nil) The name of the rule (unique within the table)
9
+ # # @option options [Boolean] :if_exists (false) Suppress the error when the rule is absent.
10
+ # # @option options [Symbol] :force (:restrict) Define how to process dependent objects
11
+ # # Supported values: :restrict (default), :cascade (for cascade deletion)
12
+ # # @option options [Symbol] :event (nil) The type of the query the rule is applied to.
13
+ # # Supported values: :update, :insert, :delete
14
+ # # @option options [Symbol] :kind (:also) The kind of the rule (either :also or :instead).
15
+ # # In case of `instead` the original query wouldn't be executed, only the `command` is.
16
+ # # @option options [String] :where (nil) The condition (SQL) for the rule to be applied.
17
+ # # @option options [String] :command (nil) The SQL command to be added by the rule.
18
+ # # @yield [r] the block with the rule's definition
19
+ # # @yieldparam Object receiver of methods specifying the procedure
20
+ # # @return [void]
21
+ # #
22
+ # # The rule can be identified by the table and explicit name
23
+ # #
24
+ # # ```ruby
25
+ # # drop_rule :users, "_forbid_insertion"
26
+ # # ```
27
+ # #
28
+ # # Alternatively the name can be got from kind and event.
29
+ # #
30
+ # # ```ruby
31
+ # # drop_rule :users do |r|
32
+ # # r.event :insert
33
+ # # r.kind :instead
34
+ # # r.comment "Forbid insertion to the table"
35
+ # # end
36
+ # # ```
37
+ # #
38
+ # # To made operation reversible all the necessary parameters must be provided
39
+ # # like in the `create_rule` operation:
40
+ # #
41
+ # # ```ruby
42
+ # # drop_rule "users", "_count_insertion" do |r|
43
+ # # r.event :insert
44
+ # # r.command <<~SQL
45
+ # # UPDATE counters SET user_inserts = user_inserts + 1
46
+ # # SQL
47
+ # # r.comment "Count insertion to the table"
48
+ # # SQL
49
+ # # ```
50
+ # #
51
+ # # The operation can be called with `if_exists` option.
52
+ # #
53
+ # # ```ruby
54
+ # # drop_rule :users, if_exists: true do |r|
55
+ # # # event and kind here are used to define a name
56
+ # # r.event :insert
57
+ # # r.kind :instead
58
+ # # end
59
+ # # ```
60
+ # #
61
+ # # With the `force: :cascade` option the operation would remove
62
+ # # all the objects that use the type.
63
+ # #
64
+ # # ```ruby
65
+ # # drop_rule :users, force: :cascade do |r|
66
+ # # r.event :insert
67
+ # # r.kind :instead
68
+ # # end
69
+ # # ```
70
+ # #
71
+ # # In both cases the operation becomes irreversible due to
72
+ # # uncertainty of the previous state of the database.
73
+ # def drop_rule(table, name = nil, **options, &block); end
74
+ # end
75
+ module PGTrunk::Operations::Rules
76
+ # @private
77
+ class DropRule < Base
78
+ validates :replace_existing, :new_name, absence: true
79
+
80
+ def to_sql(_version)
81
+ sql = "DROP RULE"
82
+ sql << " IF EXISTS" if if_exists
83
+ sql << " #{name.name.inspect} ON #{table.to_sql}"
84
+ sql << " CASCADE" if force == :cascade
85
+ sql << ";"
86
+ end
87
+
88
+ def invert
89
+ irreversible!("if_exists: true") if if_exists
90
+ irreversible!("force: :cascade") if force == :cascade
91
+ CreateRule.new(**to_h.except(:force))
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: false
2
+
3
+ # @!parse
4
+ # class ActiveRecord::Migration
5
+ # # Rename a rule
6
+ # #
7
+ # # @param [#to_s] table (nil) The qualified name of the table
8
+ # # @param [#to_s] name (nil) The current name of the rule
9
+ # # @option options [#to_s] :to (nil) The new name for the rule
10
+ # # @yield [c] the block with the constraint's definition
11
+ # # @yieldparam Object receiver of methods specifying the constraint
12
+ # # @return [void]
13
+ # #
14
+ # # A constraint can be identified by the table and explicit name
15
+ # #
16
+ # # ```ruby
17
+ # # rename_rule :users, "_forbid_insertion", to: "_skip_insertion"
18
+ # # ```
19
+ # #
20
+ # # Alternatively the name can be got from the event and kind.
21
+ # #
22
+ # # ```ruby
23
+ # # rename_rule :users, to: "_skip_insertion" do |r|
24
+ # # r.event :insert
25
+ # # r.kind :instead
26
+ # # end
27
+ # # ```
28
+ # #
29
+ # # The name can be reset to auto-generated when
30
+ # # the `:to` option is missed or blank:
31
+ # #
32
+ # # ```ruby
33
+ # # rename_rule :users, "_skip_insertion" do |r|
34
+ # # r.event :insert
35
+ # # r.kind :instead
36
+ # # end
37
+ # # ```
38
+ # #
39
+ # # The operation is always reversible.
40
+ # def rename_rule(table, name = nil, **options, &block); end
41
+ # end
42
+ module PGTrunk::Operations::Rules
43
+ # @private
44
+ class RenameRule < Base
45
+ after_initialize { self.new_name = generated_name if new_name.blank? }
46
+
47
+ validates :new_name, presence: true
48
+ validates :where, :command, :replace_existing, :force, :if_exists,
49
+ absence: true
50
+
51
+ def to_sql(_version)
52
+ <<~SQL
53
+ ALTER RULE #{name.to_sql} ON #{table.to_sql}
54
+ RENAME TO #{new_name.to_sql};
55
+ SQL
56
+ end
57
+
58
+ def invert
59
+ self.class.new(**to_h, name: new_name, to: name)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # nodoc
4
+ module PGTrunk::Rules
5
+ # @private
6
+ # Namespace for operations with rules
7
+ module Rules
8
+ require_relative "rules/base"
9
+ require_relative "rules/create_rule"
10
+ require_relative "rules/drop_rule"
11
+ require_relative "rules/rename_rule"
12
+ end
13
+ end
@@ -5,14 +5,14 @@
5
5
  # # Create a custom statistics
6
6
  # #
7
7
  # # @param [#to_s] name (nil) The qualified name of the statistics
8
- # # @option [Boolean] :if_not_exists (false)
8
+ # # @option options [Boolean] :if_not_exists (false)
9
9
  # # Suppress the error when the statistics is already exist
10
- # # @option [#to_s] table (nil)
10
+ # # @option options [#to_s] table (nil)
11
11
  # # The qualified name of the table whose statistics will be collected
12
- # # @option [Array<Symbol>] kinds ([:dependencies, :mcv, :ndistinct])
12
+ # # @option options [Array<Symbol>] kinds ([:dependencies, :mcv, :ndistinct])
13
13
  # # The kinds of statistics to be collected (all by default).
14
14
  # # Supported values in the array: :dependencies, :mcv, :ndistinct
15
- # # @option [#to_s] :comment The description of the statistics
15
+ # # @option options [#to_s] :comment The description of the statistics
16
16
  # # @yield [s] the block with the statistics' definition
17
17
  # # @yieldparam Object receiver of methods specifying the statistics
18
18
  # # @return [void]
@@ -5,14 +5,14 @@
5
5
  # # Drop a custom statistics
6
6
  # #
7
7
  # # @param [#to_s] name (nil) The qualified name of the statistics
8
- # # @option [Boolean] :if_exists (false) Suppress the error when the statistics is absent
9
- # # @option [Symbol] :force (:restrict) How to process dependent objects (`:cascade` or `:restrict`)
10
- # # @option [#to_s] table (nil)
8
+ # # @option options [Boolean] :if_exists (false) Suppress the error when the statistics is absent
9
+ # # @option options [Symbol] :force (:restrict) How to process dependent objects (`:cascade` or `:restrict`)
10
+ # # @option options [#to_s] table (nil)
11
11
  # # The qualified name of the table whose statistics will be collected
12
- # # @option [Array<Symbol>] kinds ([:dependencies, :mcv, :ndistinct])
12
+ # # @option options [Array<Symbol>] kinds ([:dependencies, :mcv, :ndistinct])
13
13
  # # The kinds of statistics to be collected (all by default).
14
14
  # # Supported values in the array: :dependencies, :mcv, :ndistinct
15
- # # @option [#to_s] :comment The description of the statistics
15
+ # # @option options [#to_s] :comment The description of the statistics
16
16
  # # @yield [s] the block with the statistics' definition
17
17
  # # @yieldparam Object receiver of methods specifying the statistics
18
18
  # # @return [void]
@@ -5,7 +5,7 @@
5
5
  # # Change the name and/or schema of a statistics
6
6
  # #
7
7
  # # @param [#to_s] :name (nil) The qualified name of the statistics
8
- # # @option [#to_s] :to (nil) The new qualified name for the statistics
8
+ # # @option options [#to_s] :to (nil) The new qualified name for the statistics
9
9
  # # @return [void]
10
10
  # #
11
11
  # # A custom statistics can be renamed by changing both the name
@@ -6,7 +6,7 @@
6
6
  # #
7
7
  # # @param [#to_s] table (nil) The qualified name of the table
8
8
  # # @param [#to_s] name (nil) The name of the trigger
9
- # # @option [Boolean] :if_exists (false) Suppress the error when the trigger is absent
9
+ # # @option options [Boolean] :if_exists (false) Suppress the error when the trigger is absent
10
10
  # # @yield [t] the block with the trigger's definition
11
11
  # # @yieldparam Object receiver of methods specifying the trigger
12
12
  # # @return [void]
@@ -6,19 +6,19 @@
6
6
  # #
7
7
  # # @param [#to_s] table (nil) The qualified name of the table
8
8
  # # @param [#to_s] name (nil) The name of the trigger
9
- # # @option [Boolean] :replace_existing (false) If the trigger should overwrite an existing one
10
- # # @option [#to_s] :function (nil) The qualified name of the function to be called
11
- # # @option [Symbol] :type (nil) When the trigger should be run
9
+ # # @option options [Boolean] :replace_existing (false) If the trigger should overwrite an existing one
10
+ # # @option options [#to_s] :function (nil) The qualified name of the function to be called
11
+ # # @option options [Symbol] :type (nil) When the trigger should be run
12
12
  # # Supported values: :before, :after, :instead_of
13
- # # @option [Array<Symbol>] :events List of events running the trigger
13
+ # # @option options [Array<Symbol>] :events List of events running the trigger
14
14
  # # Supported values in the array: :insert, :update, :delete, :truncate
15
- # # @option [Boolean] :constraint (false) If the trigger is a constraint
16
- # # @option [Symbol] :initially (:immediate) If the constraint check should be deferred
15
+ # # @option options [Boolean] :constraint (false) If the trigger is a constraint
16
+ # # @option options [Symbol] :initially (:immediate) If the constraint check should be deferred
17
17
  # # Supported values: :immediate (default), :deferred
18
- # # @option [#to_s] :when (nil) The SQL snippet definiing a condition for the trigger
19
- # # @option [Symbol] :for_each (:statement) Define if a trigger should be run for every row
18
+ # # @option options [#to_s] :when (nil) The SQL snippet definiing a condition for the trigger
19
+ # # @option options [Symbol] :for_each (:statement) Define if a trigger should be run for every row
20
20
  # # Supported values: :statement (default), :row
21
- # # @option [#to_s] :comment (nil) The commend describing the trigger
21
+ # # @option options [#to_s] :comment (nil) The commend describing the trigger
22
22
  # # @yield [t] the block with the trigger's definition
23
23
  # # @yieldparam Object receiver of methods specifying the trigger
24
24
  # # @return [void]
@@ -6,19 +6,19 @@
6
6
  # #
7
7
  # # @param [#to_s] table (nil) The qualified name of the table
8
8
  # # @param [#to_s] name (nil) The name of the trigger
9
- # # @option [Boolean] :if_exists (false) Suppress the error when the trigger is absent
10
- # # @option [#to_s] :function (nil) The qualified name of the function to be called
11
- # # @option [Symbol] :type (nil) When the trigger should be run
9
+ # # @option options [Boolean] :if_exists (false) Suppress the error when the trigger is absent
10
+ # # @option options [#to_s] :function (nil) The qualified name of the function to be called
11
+ # # @option options [Symbol] :type (nil) When the trigger should be run
12
12
  # # Supported values: :before, :after, :instead_of
13
- # # @option [Array<Symbol>] :events List of events running the trigger
13
+ # # @option options [Array<Symbol>] :events List of events running the trigger
14
14
  # # Supported values in the array: :insert, :update, :delete, :truncate
15
- # # @option [Boolean] :constraint (false) If the trigger is a constraint
16
- # # @option [Symbol] :initially (:immediate) If the constraint check should be deferred
15
+ # # @option options [Boolean] :constraint (false) If the trigger is a constraint
16
+ # # @option options [Symbol] :initially (:immediate) If the constraint check should be deferred
17
17
  # # Supported values: :immediate (default), :deferred
18
- # # @option [#to_s] :when (nil) The SQL snippet definiing a condition for the trigger
19
- # # @option [Symbol] :for_each (:statement) Define if a trigger should be run for every row
18
+ # # @option options [#to_s] :when (nil) The SQL snippet definiing a condition for the trigger
19
+ # # @option options [Symbol] :for_each (:statement) Define if a trigger should be run for every row
20
20
  # # Supported values: :statement (default), :row
21
- # # @option [#to_s] :comment (nil) The commend describing the trigger
21
+ # # @option options [#to_s] :comment (nil) The commend describing the trigger
22
22
  # # @yield [t] the block with the trigger's definition
23
23
  # # @yieldparam Object receiver of methods specifying the trigger
24
24
  # # @return [void]
@@ -6,16 +6,16 @@
6
6
  # #
7
7
  # # @param [#to_s] table (nil) The qualified name of the table
8
8
  # # @param [#to_s] name (nil) The name of the trigger
9
- # # @option [#to_s] :to (nil) The new name of the trigger
9
+ # # @option options [#to_s] :to (nil) The new name of the trigger
10
10
  # # @param [#to_s] table (nil) The qualified name of the table
11
11
  # # @param [#to_s] name (nil) The current name of the trigger
12
- # # @option [#to_s] :to (nil) The new name for the trigger
13
- # # @option [#to_s] :function (nil) The qualified name of the function to be called
14
- # # @option [Symbol] :type (nil) When the trigger should be run
12
+ # # @option options [#to_s] :to (nil) The new name for the trigger
13
+ # # @option options [#to_s] :function (nil) The qualified name of the function to be called
14
+ # # @option options [Symbol] :type (nil) When the trigger should be run
15
15
  # # Supported values: :before, :after, :instead_of
16
- # # @option [Array<Symbol>] :events List of events running the trigger
16
+ # # @option options [Array<Symbol>] :events List of events running the trigger
17
17
  # # Supported values in the array: :insert, :update, :delete, :truncate
18
- # # @option [Symbol] :for_each (:statement) Define if a trigger should be run for every row
18
+ # # @option options [Symbol] :for_each (:statement) Define if a trigger should be run for every row
19
19
  # # Supported values: :statement (default), :row
20
20
  # # @yield [t] the block with the trigger's definition
21
21
  # # @yieldparam Object receiver of methods specifying the trigger
@@ -5,7 +5,7 @@
5
5
  # # Modify a view
6
6
  # #
7
7
  # # @param [#to_s] name (nil) The qualified name of the view
8
- # # @option [Boolean] :if_exists (false) Suppress the error when the view is absent
8
+ # # @option options [Boolean] :if_exists (false) Suppress the error when the view is absent
9
9
  # # @yield [v] the block with the view's definition
10
10
  # # @yieldparam Object receiver of methods specifying the view
11
11
  # # @return [void]
@@ -5,13 +5,13 @@
5
5
  # # Create a view
6
6
  # #
7
7
  # # @param [#to_s] name (nil) The qualified name of the view
8
- # # @option [Boolean] :replace_existing (false) If the view should overwrite an existing one
9
- # # @option [#to_s] :sql_definition (nil) The snippet containing the query
10
- # # @option [#to_i] :version (nil)
8
+ # # @option options [Boolean] :replace_existing (false) If the view should overwrite an existing one
9
+ # # @option options [#to_s] :sql_definition (nil) The snippet containing the query
10
+ # # @option options [#to_i] :version (nil)
11
11
  # # The alternative way to set sql_definition by referencing to a file containing the snippet
12
- # # @option [#to_s] :check (nil) Controls the behavior of automatically updatable views
12
+ # # @option options [#to_s] :check (nil) Controls the behavior of automatically updatable views
13
13
  # # Supported values: :local, :cascaded
14
- # # @option [#to_s] :comment (nil) The comment describing the view
14
+ # # @option options [#to_s] :comment (nil) The comment describing the view
15
15
  # # @yield [v] the block with the view's definition
16
16
  # # @yieldparam Object receiver of methods specifying the view
17
17
  # # @return [void]
@@ -5,15 +5,15 @@
5
5
  # # Drop a view
6
6
  # #
7
7
  # # @param [#to_s] name (nil) The qualified name of the view
8
- # # @option [Boolean] :replace_existing (false) If the view should overwrite an existing one
9
- # # @option [Boolean] :if_exists (false) Suppress the error when the view is absent
10
- # # @option [Symbol] :force (:restrict) How to process dependent objects (`:cascade` or `:restrict`)
11
- # # @option [#to_s] :sql_definition (nil) The snippet containing the query
12
- # # @option [#to_i] :revert_to_version (nil)
8
+ # # @option options [Boolean] :replace_existing (false) If the view should overwrite an existing one
9
+ # # @option options [Boolean] :if_exists (false) Suppress the error when the view is absent
10
+ # # @option options [Symbol] :force (:restrict) How to process dependent objects (`:cascade` or `:restrict`)
11
+ # # @option options [#to_s] :sql_definition (nil) The snippet containing the query
12
+ # # @option options [#to_i] :revert_to_version (nil)
13
13
  # # The alternative way to set sql_definition by referencing to a file containing the snippet
14
- # # @option [#to_s] :check (nil) Controls the behavior of automatically updatable views
14
+ # # @option options [#to_s] :check (nil) Controls the behavior of automatically updatable views
15
15
  # # Supported values: :local, :cascaded
16
- # # @option [#to_s] :comment (nil) The comment describing the view
16
+ # # @option options [#to_s] :comment (nil) The comment describing the view
17
17
  # # @yield [v] the block with the view's definition
18
18
  # # @yieldparam Object receiver of methods specifying the view
19
19
  # # @return [void]
@@ -5,8 +5,8 @@
5
5
  # # Change the name and/or schema of a view
6
6
  # #
7
7
  # # @param [#to_s] :name (nil) The qualified name of the view
8
- # # @option [#to_s] :to (nil) The new qualified name for the view
9
- # # @option [Boolean] :if_exists (false) Suppress the error when the view is absent
8
+ # # @option options [#to_s] :to (nil) The new qualified name for the view
9
+ # # @option options [Boolean] :if_exists (false) Suppress the error when the view is absent
10
10
  # # @return [void]
11
11
  # #
12
12
  # # A view can be renamed by changing both the name
@@ -18,6 +18,7 @@ module PGTrunk
18
18
  require_relative "operations/foreign_keys"
19
19
  require_relative "operations/procedures"
20
20
  require_relative "operations/triggers"
21
+ require_relative "operations/rules"
21
22
  require_relative "operations/statistics"
22
23
  end
23
24
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module PGTrunk
4
4
  # @private
5
- VERSION = "0.1.2"
5
+ VERSION = "0.1.3"
6
6
  end
data/pg_trunk.gemspec CHANGED
@@ -23,7 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.metadata["rubygems_mfa_required"] = "true"
24
24
 
25
25
  spec.files = `git ls-files -z`.split("\x0")
26
- spec.test_files = spec.files.grep(%r{^spec/})
27
26
  spec.require_paths = ["lib"]
28
27
 
29
28
  spec.add_dependency "activerecord", ">= 4.0.0"