mv-core 1.0.1 → 2.0.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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +67 -12
  3. data/lib/mv-core.rb +18 -100
  4. data/lib/mv/core/active_record/connection_adapters/abstract_adapter_decorator.rb +51 -0
  5. data/lib/mv/core/active_record/connection_adapters/table_decorator.rb +13 -0
  6. data/lib/mv/core/active_record/connection_adapters/table_definition_decorator.rb +21 -0
  7. data/lib/mv/core/active_record/migration/command_recorder_decorator.rb +13 -0
  8. data/lib/mv/core/active_record/migration_decorator.rb +14 -0
  9. data/lib/mv/core/active_record/schema_decorator.rb +16 -0
  10. data/lib/mv/core/active_record/schema_dumper_decorator.rb +29 -0
  11. data/lib/mv/core/constraint/base.rb +33 -0
  12. data/lib/mv/core/constraint/builder/base.rb +45 -0
  13. data/lib/mv/core/constraint/builder/factory.rb +42 -0
  14. data/lib/mv/core/constraint/builder/index.rb +50 -0
  15. data/lib/mv/core/constraint/builder/trigger.rb +13 -0
  16. data/lib/mv/core/constraint/description.rb +24 -0
  17. data/lib/mv/core/constraint/factory.rb +33 -0
  18. data/lib/mv/core/constraint/index.rb +13 -0
  19. data/lib/mv/core/constraint/trigger.rb +20 -0
  20. data/lib/mv/core/db/helpers/column_validators.rb +57 -0
  21. data/lib/mv/core/db/helpers/table_validators.rb +38 -0
  22. data/lib/mv/core/db/migration_validator.rb +26 -0
  23. data/lib/mv/core/error.rb +25 -0
  24. data/lib/mv/core/migration/base.rb +94 -0
  25. data/lib/mv/core/migration/operations/add_column.rb +27 -0
  26. data/lib/mv/core/migration/operations/change_column.rb +31 -0
  27. data/lib/mv/core/migration/operations/drop_table.rb +21 -0
  28. data/lib/mv/core/migration/operations/factory.rb +20 -0
  29. data/lib/mv/core/migration/operations/list.rb +28 -0
  30. data/lib/mv/core/migration/operations/remove_column.rb +22 -0
  31. data/lib/mv/core/migration/operations/rename_column.rb +26 -0
  32. data/lib/mv/core/migration/operations/rename_table.rb +25 -0
  33. data/lib/mv/core/presenter/constraint/description.rb +26 -0
  34. data/lib/mv/core/presenter/validation/base.rb +73 -0
  35. data/lib/mv/core/railtie.rb +40 -0
  36. data/lib/mv/core/route/base.rb +25 -0
  37. data/lib/mv/core/route/index.rb +17 -0
  38. data/lib/mv/core/route/trigger.rb +22 -0
  39. data/lib/mv/core/router.rb +33 -0
  40. data/lib/mv/core/services/compare_constraint_arrays.rb +50 -0
  41. data/lib/mv/core/services/compare_constraints.rb +31 -0
  42. data/lib/mv/core/services/create_constraints.rb +30 -0
  43. data/lib/mv/core/services/create_migration_validators_table.rb +31 -0
  44. data/lib/mv/core/services/delete_constraints.rb +30 -0
  45. data/lib/mv/core/services/load_constraints.rb +45 -0
  46. data/lib/mv/core/services/say_constraints_diff.rb +66 -0
  47. data/lib/mv/core/services/show_constraints.rb +41 -0
  48. data/lib/mv/core/services/synchronize_constraints.rb +54 -0
  49. data/lib/mv/core/services/uninstall.rb +25 -0
  50. data/lib/mv/core/validation/absence.rb +35 -0
  51. data/lib/mv/core/validation/base.rb +98 -0
  52. data/lib/mv/core/validation/builder/absence.rb +19 -0
  53. data/lib/mv/core/validation/builder/base.rb +58 -0
  54. data/lib/mv/core/validation/builder/exclusion.rb +42 -0
  55. data/lib/mv/core/validation/builder/factory.rb +43 -0
  56. data/lib/mv/core/validation/builder/inclusion.rb +42 -0
  57. data/lib/mv/core/validation/builder/length.rb +68 -0
  58. data/lib/mv/core/validation/builder/presence.rb +19 -0
  59. data/lib/mv/core/validation/builder/uniqueness.rb +19 -0
  60. data/lib/mv/core/validation/exclusion.rb +27 -0
  61. data/lib/mv/core/validation/factory.rb +56 -0
  62. data/lib/mv/core/validation/inclusion.rb +27 -0
  63. data/lib/mv/core/validation/length.rb +59 -0
  64. data/lib/mv/core/validation/presence.rb +25 -0
  65. data/lib/mv/core/validation/uniqueness.rb +45 -0
  66. data/lib/mv/core/validators/array_validator.rb +5 -0
  67. data/lib/mv/core/validators/integers_array_validator.rb +12 -0
  68. data/lib/mv/core/validators/valid_validator.rb +9 -0
  69. metadata +158 -30
  70. data/lib/migration_validators/active_record/base.rb +0 -29
  71. data/lib/migration_validators/active_record/connection_adapters/abstract_adapter.rb +0 -38
  72. data/lib/migration_validators/active_record/connection_adapters/native_adapter.rb +0 -129
  73. data/lib/migration_validators/active_record/connection_adapters/table.rb +0 -17
  74. data/lib/migration_validators/active_record/connection_adapters/table_definition.rb +0 -33
  75. data/lib/migration_validators/active_record/migration.rb +0 -25
  76. data/lib/migration_validators/active_record/schema.rb +0 -32
  77. data/lib/migration_validators/active_record/schema_dumper.rb +0 -25
  78. data/lib/migration_validators/adapters/base.rb +0 -15
  79. data/lib/migration_validators/adapters/containers.rb +0 -100
  80. data/lib/migration_validators/adapters/routing.rb +0 -102
  81. data/lib/migration_validators/adapters/syntax.rb +0 -51
  82. data/lib/migration_validators/adapters/validator_definitions.rb +0 -132
  83. data/lib/migration_validators/core/adapter_wrapper.rb +0 -88
  84. data/lib/migration_validators/core/db_validator.rb +0 -131
  85. data/lib/migration_validators/core/statement_builder.rb +0 -61
  86. data/lib/migration_validators/core/validator_constraints_list.rb +0 -32
  87. data/lib/migration_validators/core/validator_container.rb +0 -110
  88. data/lib/migration_validators/core/validator_definition.rb +0 -91
  89. data/lib/migration_validators/core/validator_router.rb +0 -45
  90. data/lib/options.rb +0 -7
@@ -1,102 +0,0 @@
1
- module MigrationValidators
2
- module Adapters
3
- module Routing
4
- extend ActiveSupport::Concern
5
-
6
- ###################################################################
7
- ## UNIQUENESS
8
- ###################################################################
9
- def validate_uniqueness_index validators
10
- add_index validators.first
11
- [validators.first]
12
- end
13
-
14
- def remove_validate_uniqueness_index validators
15
- remove_index(validators.first)
16
- [validators.first]
17
- end
18
-
19
- def validate_uniqueness validators
20
- validate_uniqueness_index validators
21
- end
22
-
23
- def remove_validate_uniqueness validators
24
- remove_validate_uniqueness_index validators
25
- end
26
-
27
- private
28
-
29
- def compose_index_name validator
30
- if validator.options.blank? || (index_name = validator.options[:index_name]).blank?
31
- "idx_mgr_validates_#{validator.table_name}_#{validator.column_name}_#{validator.validator_name}"
32
- else
33
- index_name
34
- end
35
- end
36
-
37
- def add_index validator
38
- ::ActiveRecord::Base.connection.add_index validator.table_name,
39
- validator.column_name,
40
- :name => compose_index_name(validator),
41
- :unique => true
42
- end
43
-
44
- def remove_index validator
45
- ::ActiveRecord::Base.connection.remove_index validator.table_name,
46
- :name => compose_index_name(validator)
47
- end
48
-
49
- def execute statements
50
- statements = [statements] if statements.kind_of?(String)
51
-
52
- statements.each {|stmt| ::ActiveRecord::Base.connection.execute(stmt) }
53
- end
54
-
55
- module ClassMethods
56
- def routers to = nil
57
- @routers ||= {}
58
- end
59
-
60
-
61
- def router validator_name, container_type, &block
62
- router = routers["#{validator_name}_#{container_type}"] ||= MigrationValidators::Core::ValidatorRouter.new(containers)
63
- router.instance_eval(&block) if block
64
- router
65
- end
66
-
67
- def route validator_name, container_type, opts = {}, &block
68
- router validator_name, container_type, &block
69
-
70
- default = opts.delete(:default)
71
- remove = opts.delete(:remove)
72
- remove = true if remove.nil?
73
-
74
- if (to = opts[:to])
75
- to = [to] unless to.kind_of?(Array)
76
- to.each {|container_name| router(validator_name, container_type).to container_name}
77
- end
78
-
79
- define_method :"validate_#{validator_name}_#{container_type}" do |validators|
80
- execute(self.class.router(validator_name, container_type).add_validators(validators))
81
- validators
82
- end
83
- alias_method(:"validate_#{validator_name}", :"validate_#{validator_name}_#{container_type}") if default
84
-
85
- if remove
86
- define_method :"remove_validate_#{validator_name}_#{container_type}" do |validators|
87
- execute(self.class.router(validator_name, container_type).remove_validators(validators))
88
- validators
89
- end
90
- alias_method(:"remove_validate_#{validator_name}", :"remove_validate_#{validator_name}_#{container_type}") if default
91
- end
92
- end
93
-
94
- def clear_routing
95
- public_instance_methods.grep(/^remove_validate_/) { |method_name| undef_method method_name }
96
- public_instance_methods.grep(/^validate_/) { |method_name| undef_method method_name }
97
- end
98
- end
99
-
100
- end
101
- end
102
- end
@@ -1,51 +0,0 @@
1
- module MigrationValidators
2
- module Adapters
3
- module Syntax
4
- extend ActiveSupport::Concern
5
-
6
- module ClassMethods
7
- def define_base_syntax
8
- syntax do
9
- operation(:db_name)
10
- operation(:db_value)
11
- operation(:wrap) {|value| "(#{value})"}
12
- operation(:and) {|stmt, value| "#{stmt} AND #{value}"}
13
- operation(:or) {|stmt, value| "#{stmt} OR #{value}"}
14
- operation(:length) {|value| "LENGTH(#{stmt})"}
15
- operation(:trim) {|value| "TRIM(#{stmt})"}
16
- operation(:coalesce) {|value| "COALESCE(#{stmt}, '')"}
17
- operation(:if) {|if_stmt, then_stmt| "IF #{if_stmt} THEN #{then_stmt} ENDIF"}
18
- operation(:regexp) {|stmt, value| "#{stmt} REGEXP #{value}"}
19
- operation(:greater_than) {|stmt, value| "#{stmt} > #{value}"}
20
- operation(:greater_or_equal_to) {|stmt, value| "#{stmt} >= #{value}"}
21
- operation(:less_than) {|stmt, value| "#{stmt} < #{value}"}
22
- operation(:less_or_equal_to) {|stmt, value| "#{stmt} <= #{value}"}
23
- operation(:equal_to) {|stmt, value| "#{stmt} = #{value}"}
24
- operation(:between) do |stmt, range|
25
- "#{@stmt} >= #{compile(range.first).db_value} AND #{@stmt} <#{range.exclude_end? ? '' : '='} #{compile(range.last).db_value}"
26
- end
27
- operation(:in) do |stmt, array|
28
- "#{@stmt} IN (#{array.collect{|value| compile(value).db_value}.join(', ')})"
29
- end
30
- operation(:not_in) do |stmt, array|
31
- "#{@stmt} NOT IN (#{array.collect{|value| compile(value).db_value}.join(', ')})"
32
- end
33
- operation(:not_null) {|value| "#{value} IS NOT NULL"}
34
- operation(:null) {|value| "#{value} IS NULL"}
35
- operation(:not) {|value| "NOT #{value}"}
36
- operation(:exists) {|value| "EXISTS #{value}"}
37
- operation(:select) {|value| "SELECT #{value}"}
38
- operation(:from) {|value| " FROM #{value}"}
39
- operation(:where) {|value| "WHERE #{value}"}
40
- end
41
- end
42
-
43
- def syntax &block
44
- @builder ||= MigrationValidators::Core::StatementBuilder.new
45
- @builder.instance_eval(&block) if block
46
- @builder
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,132 +0,0 @@
1
- module MigrationValidators
2
- module Adapters
3
- module ValidatorDefinitions
4
- extend ActiveSupport::Concern
5
-
6
- module ClassMethods
7
- def validators
8
- @validators ||= {}
9
- end
10
-
11
- def validator name, opts = {}, &block
12
- validator = validators[name]
13
-
14
- unless validator
15
- validator = validators[name] = MigrationValidators::Core::ValidatorDefinition.new(syntax)
16
-
17
- validator.post :allow_nil => true do
18
- self.wrap.or(column.db_name.null)
19
- end if opts[:allow_nil] || !opts.key?(:allow_nil)
20
-
21
- validator.post :allow_blank => true do
22
- self.wrap.or(column.db_name.coalesce.trim.length.equal_to(0))
23
- end if opts[:allow_blank] || !opts.key?(:allow_blank)
24
- end
25
-
26
-
27
- validator.instance_eval(&block) if block
28
- end
29
-
30
- def define_base_validators
31
- validator :inclusion do
32
- property :in do |value|
33
- if value.kind_of?(Array)
34
- column.db_name.not_null.and(column.db_name.in(value))
35
- elsif value.kind_of?(Range)
36
- column.db_name.not_null.and(db_name.between(value))
37
- else
38
- column.db_name.not_null.and(column.db_name.equal_to(compile(value).db_value))
39
- end
40
- end
41
- end
42
-
43
- validator :exclusion do
44
- property :in do |value|
45
- if value.kind_of?(Array)
46
- column.db_name.not_in(value)
47
- elsif value.kind_of?(Range)
48
- column.db_name.between(value).wrap.not
49
- else
50
- column.db_name.equal_to(compile(value).db_value).not
51
- end
52
- end
53
- end
54
-
55
- validator :format do
56
- property :with do |value|
57
- column.db_name.not_null.and(column.db_name.regexp(compile(value).db_value))
58
- end
59
- end
60
-
61
- validator :length do
62
- property :is, :message => :wrong_length do |value|
63
- column.db_name.coalesce.length.equal_to(compile(value).db_value)
64
- end
65
- property :maximum, :message => :too_long do |value|
66
- column.db_name.coalesce.length.less_or_equal_to(compile(value).db_value)
67
- end
68
- property :minimum, :message => :too_short do |value|
69
- column.db_name.coalesce.length.greater_or_equal_to(compile(value).db_value)
70
- end
71
-
72
- property :in do |value|
73
- case value.class.name
74
- when "Array" then column.db_name.coalesce.length.in(value)
75
- when "Range" then column.db_name.coalesce.length.between(value)
76
- else column.db_name.coalesce.length.equal_to(compile(value).db_value)
77
- end
78
- end
79
-
80
- property :within do |value|
81
- case value.class.name
82
- when "Array" then column.db_name.coalesce.length.in(value)
83
- when "Range" then column.db_name.coalesce.length.between(value)
84
- else column.db_name.coalesce.length.equal_to(compile(value).db_value)
85
- end
86
- end
87
- end
88
-
89
- validator :size do
90
- property :is, :message => :wrong_length do |value|
91
- column.db_name.coalesce.length.equal_to(compile(value).db_value)
92
- end
93
- property :maximum, :message => :too_long do |value|
94
- column.db_name.coalesce.length.less_or_equal_to(compile(value).db_value)
95
- end
96
- property :minimum, :message => :too_short do |value|
97
- column.db_name.coalesce.length.greater_or_equal_to(compile(value).db_value)
98
- end
99
-
100
- property :in do |value|
101
- case value.class.name
102
- when "Array" then column.db_name.coalesce.length.in(value)
103
- when "Range" then column.db_name.coalesce.length.between(value)
104
- else column.db_name.coalesce.length.equal_to(compile(value).db_value)
105
- end
106
- end
107
-
108
- property :within do |value|
109
- case value.class.name
110
- when "Array" then column.db_name.coalesce.length.in(value)
111
- when "Range" then column.db_name.coalesce.length.between(value)
112
- else column.db_name.coalesce.length.equal_to(compile(value).db_value)
113
- end
114
- end
115
- end
116
-
117
- validator :presence do
118
- property do |value|
119
- column.db_name.not_null.and(column.db_name.trim.length.greater_than(0))
120
- end
121
- end
122
-
123
- validator :uniqueness do
124
- property do |value|
125
- "NOT EXISTS(SELECT #{column.to_s} FROM #{validator.table_name} tbl WHERE (#{column.db_name} = #{column.to_s}))"
126
- end
127
- end
128
- end
129
- end
130
- end
131
- end
132
- end
@@ -1,88 +0,0 @@
1
- module MigrationValidators
2
- module Core
3
- class AdapterWrapper
4
- class AdapterCaller
5
- def initialize adapter, action
6
- @adapter = adapter
7
- @action = action
8
- end
9
-
10
- def process validators
11
- return if validators.blank?
12
-
13
- check_validators(validators)
14
-
15
- validators.group_by{|validator| [validator.table_name, compose_method_name(validator)]}.each do |group_id, group|
16
-
17
- until group.blank?
18
- handled_validators = @adapter.send(group_id.last, group)
19
-
20
- break if handled_validators.blank?
21
-
22
- group = group - handled_validators
23
- end
24
- end
25
- end
26
-
27
- private
28
-
29
- def compose_method_name validator
30
- method_suffix = validator.options.blank? || validator.options[:as].blank? ? "" : "_#{validator.options[:as]}"
31
- :"#{@action}_#{validator.validator_name}#{method_suffix}"
32
- end
33
-
34
- def grep_public_instance_methods expr
35
- @adapter.class.public_instance_methods.collect{|method| method.to_s.match(expr)}.compact.collect{|match| match[1]}
36
- end
37
-
38
- def supported_validators
39
- grep_public_instance_methods(/^#{@action}_([a-z]*)/).uniq
40
- end
41
-
42
- def supported_db_forms validator_name
43
- grep_public_instance_methods(/^#{@action}_#{validator_name}_([a-z]*)/).uniq
44
- end
45
-
46
- def default_db_form_supported? validator_name
47
- @adapter.class.method_defined? :"#{@action}_#{validator_name}"
48
- end
49
-
50
- def array2str array
51
- "[" + array.collect {|elem| "'#{elem}'"}.join(',') + "]"
52
- end
53
-
54
- def check_validators validators
55
- validators.each do |validator|
56
-
57
- unless supported_validators.include?(validator.validator_name.to_s)
58
- raise MigrationValidatorsException.new("Adapter '#{@adapter.name}'. 'Action '#{@action}' for '#{validator.validator_name}' is not supported. Available validators: #{array2str(supported_validators)}")
59
- end
60
-
61
- if validator.options && (db_form = validator.options[:as])
62
- unless supported_db_forms(validator.validator_name).include?(db_form.to_s)
63
- raise MigrationValidatorsException.new("Adapter '#{@adapter.name}'. Action '#{@action}' for db form '#{db_form}' for validator '#{validator.validator_name}' is not supported. Available db forms: #{array2str(supported_db_forms(validator.validator_name))}")
64
- end
65
- else
66
- unless default_db_form_supported?(validator.validator_name.to_s)
67
- raise MigrationValidatorsException.new("Adapter '#{@adapter.name}'. 'Action '#{@action}' for '#{validator.validator_name}' with default db form is not supported")
68
- end
69
- end
70
- end
71
- end
72
- end
73
-
74
- def initialize adapter
75
- @creator = AdapterCaller.new adapter, :validate
76
- @remover = AdapterCaller.new adapter, :remove_validate
77
- end
78
-
79
- def create_validators validators
80
- @creator.process validators
81
- end
82
-
83
- def remove_validators validators
84
- @remover.process validators
85
- end
86
- end
87
- end
88
- end
@@ -1,131 +0,0 @@
1
- module MigrationValidators
2
- module Core
3
- class DbValidator < ::ActiveRecord::Base
4
- @@validators_to_remove = []
5
- @@validators_to_add = []
6
-
7
-
8
- self.table_name = MigrationValidators.migration_validators_table_name
9
-
10
- validates_presence_of :table_name
11
- validates_length_of :table_name, :maximum => 255
12
- validates_length_of :column_name, :maximum => 255
13
-
14
- validates_presence_of :validator_name
15
- validates_length_of :validator_name, :maximum => 255
16
-
17
- validate do |validator|
18
- unless ::ActiveRecord::Base.connection.table_exists?(validator.table_name)
19
- validator.errors[:table_name] << "table '#{table_name}' does not exist"
20
- else
21
- unless ::ActiveRecord::Base.connection.columns(validator.table_name).any?{|col| col.name == validator.column_name.to_s}
22
- validator.errors[:column_name] << "column '#{column_name}' does not exist in the table '#{table_name}'"
23
- end
24
- end
25
- end
26
-
27
- before_save :prepare_options
28
-
29
- serialize :options, Hash
30
- serialize :constraints, ValidatorConstraintsList
31
-
32
- scope :on_table, -> (table_name) { where table_name: table_name }
33
- scope :on_column, -> (column_name) { where column_name: column_name }
34
- scope :with_name, -> (validator_name) { where validator_name: validator_name }
35
-
36
- def options
37
- attributes['options'] ||= {}
38
- end
39
-
40
- def name
41
- "#{table_name}_#{column_name}_#{validator_name}"
42
- end
43
-
44
- def error_message
45
- unless (options.blank? || (message = options[:message]).blank?)
46
- message
47
- else
48
- "#{validator_name} violated for #{table_name} field #{column_name}"
49
- end
50
- end
51
-
52
- def satisfies opts
53
- return true if opts.blank?
54
-
55
- opts.collect do |property_name, property_value|
56
- [property_name, [property_value].flatten]
57
- end.all? do |property_name, property_value|
58
- property_value.include?(options[property_name])
59
- end
60
- end
61
-
62
- def delayed_destroy
63
- @@validators_to_remove << self unless @@validators_to_remove.include?(self)
64
- end
65
-
66
- def delayed_save
67
- DbValidator.on_table(table_name)
68
- .on_column(column_name)
69
- .with_name(validator_name)
70
- .delayed_destroy
71
-
72
- @@validators_to_add << self unless @@validators_to_add.include?(self)
73
- end
74
-
75
- private
76
-
77
- def prepare_options
78
- options = options.inject({}) do |res, (key, value)|
79
- res[key.to_s] = value
80
- res
81
- end unless options.blank?
82
-
83
- true
84
- end
85
-
86
- class << self
87
-
88
- def satisfies opts
89
- all.select{|validator| validator.satisfies(opts) }
90
- end
91
-
92
- def delayed_destroy
93
- all.each(&:delayed_destroy)
94
- end
95
-
96
- def constraint_validators constraint
97
- (DbValidator.where("constraints LIKE ?", "%#{constraint}%").all + @@validators_to_add - @@validators_to_remove).select{|validator| validator.constraints.include?(constraint)}
98
- end
99
-
100
- def rename_column table_name, old_column_name, new_column_name
101
- all.on_table(table_name).on_column(old_column_name).update_all(column_name: new_column_name)
102
- end
103
-
104
- def rename_table old_table_name, new_table_name
105
- all.on_table(old_table_name).update_all(table_name: new_table_name)
106
- end
107
-
108
- def commit adapter = nil
109
- adapter.remove_validators(@@validators_to_remove.select{|validator| ::ActiveRecord::Base.connection.table_exists?(validator.table_name)}) if adapter
110
- @@validators_to_remove.each(&:destroy)
111
- @@validators_to_remove.clear
112
-
113
- adapter.create_validators(@@validators_to_add) if adapter
114
- @@validators_to_add.each(&:save!)
115
- @@validators_to_add.clear
116
- end
117
-
118
- def rollback
119
- @@validators_to_remove.clear
120
- @@validators_to_add.clear
121
- end
122
-
123
- def clear_all
124
- rollback
125
- DbValidator.delete_all
126
- end
127
-
128
- end
129
- end
130
- end
131
- end