mv-core 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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