mv-core 0.1.1 → 1.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 (35) hide show
  1. checksums.yaml +7 -0
  2. data/README.rdoc +15 -1
  3. data/lib/migration_validators/active_record/base.rb +8 -3
  4. data/lib/migration_validators/active_record/connection_adapters/abstract_adapter.rb +6 -4
  5. data/lib/migration_validators/active_record/connection_adapters/native_adapter.rb +18 -7
  6. data/lib/migration_validators/active_record/connection_adapters/table.rb +4 -2
  7. data/lib/migration_validators/active_record/connection_adapters/table_definition.rb +4 -2
  8. data/lib/migration_validators/active_record/migration.rb +5 -4
  9. data/lib/migration_validators/active_record/schema.rb +4 -3
  10. data/lib/migration_validators/active_record/schema_dumper.rb +5 -6
  11. data/lib/migration_validators/adapters/containers.rb +9 -11
  12. data/lib/migration_validators/adapters/routing.rb +1 -3
  13. data/lib/migration_validators/adapters/syntax.rb +1 -3
  14. data/lib/migration_validators/adapters/validator_definitions.rb +14 -13
  15. data/lib/migration_validators/core/db_validator.rb +63 -110
  16. data/lib/migration_validators/core/statement_builder.rb +1 -0
  17. data/lib/migration_validators/core/validator_constraints_list.rb +32 -0
  18. data/lib/migration_validators/core/validator_container.rb +2 -2
  19. data/lib/migration_validators/core/validator_definition.rb +9 -9
  20. data/lib/mv-core.rb +7 -2
  21. metadata +86 -99
  22. data/spec/migration_validators/active_record/connection_adapters/abstract_adapter_spec.rb +0 -440
  23. data/spec/migration_validators/active_record/connection_adapters/table_definition_spec.rb +0 -4
  24. data/spec/migration_validators/active_record/migration.rb +0 -82
  25. data/spec/migration_validators/active_record/schema_dumper_spec.rb +0 -44
  26. data/spec/migration_validators/adapters/base_spec.rb +0 -89
  27. data/spec/migration_validators/core/adapter_wrapper_spec.rb +0 -168
  28. data/spec/migration_validators/core/db_validator_spec.rb +0 -347
  29. data/spec/migration_validators/core/statement_builder_spec.rb +0 -36
  30. data/spec/migration_validators/core/validator_container_spec.rb +0 -121
  31. data/spec/migration_validators/core/validator_definition_spec.rb +0 -131
  32. data/spec/migration_validators/core/validator_router_spec.rb +0 -60
  33. data/spec/mv-core_spec.rb +0 -4
  34. data/spec/spec_helper.rb +0 -15
  35. data/spec/support/factories/db_validator.rb +0 -43
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 175b29c2732cf8425f8a8b94c623b878519b4852
4
+ data.tar.gz: 901c6991b9f82011409146b4230ce4b399bb2aba
5
+ SHA512:
6
+ metadata.gz: 79a5f8408f2d70deb379c1482639d34e56aeb292ce1c8bbd0a0ffab7d1fc6f1293c40a99864953f1a3ef590280fe530bc6e44ee452aba9f92b36ed246e046172
7
+ data.tar.gz: 2f76dbeeb166d54ae2a7a1880f8a3ee9f327e806b89a1c5fe0c2858bcaea9f070a2f5cbf531adc8c855d8dbbb2017010a35f0b1151274324781da741e118f135
@@ -10,6 +10,20 @@ Main goal of the project is to allow developer to express database constraints i
10
10
 
11
11
  mv-core is a set of core classes that are used everywhere across Migration Validators project gems.
12
12
 
13
+ = Install
14
+
15
+ PostgreSQL:
16
+
17
+ gem install mv-postgresql
18
+
19
+ MySQL:
20
+
21
+ gem install mv-mysql
22
+
23
+ SQLite:
24
+
25
+ gem install mv-sqlite
26
+
13
27
  = Usage
14
28
 
15
29
  Create new table:
@@ -55,7 +69,7 @@ mv-core is a set of core classes that are used everywhere across Migration Valid
55
69
 
56
70
  or while updating of existing record:
57
71
 
58
- validate_column :table_name, :str_column, :validates => {:uniqueness => true, :on => :create }
72
+ validate_column :table_name, :str_column, :validates => {:uniqueness => true, :on => :update }
59
73
 
60
74
  Supported validators and their properties might vary from one db driver to another. See detailed properties description in correspondent driver section.
61
75
 
@@ -1,9 +1,10 @@
1
1
  module MigrationValidators
2
2
  module ActiveRecord
3
3
  module Base
4
- def self.included(base)
5
- base.extend ClassMethods
6
- base.class_eval do
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ class_eval do
7
8
  class << self
8
9
  alias_method_chain :establish_connection, :validators
9
10
  end
@@ -17,6 +18,10 @@ module MigrationValidators
17
18
  connection.class.class_eval {
18
19
  include MigrationValidators::ActiveRecord::ConnectionAdapters::NativeAdapter
19
20
  } unless connection.class.include?(MigrationValidators::ActiveRecord::ConnectionAdapters::NativeAdapter)
21
+
22
+ connection.class.class_eval {
23
+ include MigrationValidators::ActiveRecord::ConnectionAdapters::AbstractAdapter
24
+ } unless connection.class.include?(MigrationValidators::ActiveRecord::ConnectionAdapters::AbstractAdapter)
20
25
  end
21
26
  end
22
27
  end
@@ -2,8 +2,10 @@ module MigrationValidators
2
2
  module ActiveRecord
3
3
  module ConnectionAdapters
4
4
  module AbstractAdapter
5
- def self.included(base)
6
- base.class_eval do
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_eval do
7
9
  alias_method_chain :initialize_schema_migrations_table, :validators
8
10
  end
9
11
  end
@@ -16,8 +18,8 @@ module MigrationValidators
16
18
  t.string :table_name, :null => false, :limit => 255
17
19
  t.string :column_name, :null => true, :limit => 255
18
20
  t.string :validator_name, :null => false, :limit => 255
19
- t.text :options
20
- t.text :constraints
21
+ t.text :options#, default: {}.to_yaml
22
+ t.text :constraints#, default: [].to_yaml
21
23
  end
22
24
 
23
25
  add_index migrations_table, :table_name
@@ -1,9 +1,13 @@
1
+ # DbValidator = MigrationValidators::Core::DbValidator
2
+
1
3
  module MigrationValidators
2
4
  module ActiveRecord
3
5
  module ConnectionAdapters
4
6
  module NativeAdapter
5
- def self.included(base)
6
- base.class_eval do
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ class_eval do
7
11
  alias_method_chain :drop_table, :validators
8
12
  alias_method_chain :remove_column, :validators
9
13
  alias_method_chain :rename_column, :validators
@@ -23,10 +27,16 @@ module MigrationValidators
23
27
  if validator_options.blank?
24
28
  raise MigrationValidatorsException.new("use false to remove column validator") unless validator_options == false
25
29
 
26
- MigrationValidators::Core::DbValidator.remove_column_validator table_name, column_name, validator_name
30
+ MigrationValidators::Core::DbValidator.on_table(table_name)
31
+ .on_column(column_name)
32
+ .with_name(validator_name)
33
+ .delayed_destroy
27
34
  else
28
35
  validator_options = {} if validator_options == true
29
- MigrationValidators::Core::DbValidator.add_column_validator table_name, column_name, validator_name, validator_options
36
+ MigrationValidators::Core::DbValidator.new(table_name: table_name,
37
+ column_name: column_name,
38
+ validator_name: validator_name,
39
+ options: validator_options).delayed_save
30
40
  end
31
41
  end
32
42
  end
@@ -65,14 +75,15 @@ module MigrationValidators
65
75
 
66
76
 
67
77
  def drop_table_with_validators table_name
68
- do_enabled { MigrationValidators::Core::DbValidator.remove_table_validators table_name }
78
+ do_enabled { MigrationValidators::Core::DbValidator.on_table(table_name).delayed_destroy }
69
79
  do_internally { drop_table_without_validators table_name }
70
80
  end
71
81
 
72
82
  def remove_column_with_validators table_name, *column_names
73
83
  do_enabled do
74
84
  column_names.flatten.each do |column_name|
75
- MigrationValidators::Core::DbValidator.remove_column_validators table_name, column_name
85
+ # MigrationValidators::Core::DbValidator.remove_column_validators table_name, column_name
86
+ MigrationValidators::Core::DbValidator.on_table(table_name).on_column(column_name).delayed_destroy
76
87
  end
77
88
  end
78
89
 
@@ -100,7 +111,7 @@ module MigrationValidators
100
111
  def change_column_with_validators table_name, column_name, type, opts
101
112
  validates = opts.delete(:validates)
102
113
 
103
- do_enabled { MigrationValidators::Core::DbValidator.remove_column_validators table_name, column_name }
114
+ do_enabled { MigrationValidators::Core::DbValidator.on_table(table_name).on_column(column_name).delayed_destroy }
104
115
 
105
116
  do_internally { change_column_without_validators table_name, column_name, type, opts }
106
117
 
@@ -2,8 +2,10 @@ module MigrationValidators
2
2
  module ActiveRecord
3
3
  module ConnectionAdapters
4
4
  module Table
5
- def self.included(base)
6
- base.class_eval do
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_eval do
7
9
  def change_validates column_name, opts
8
10
  ::ActiveRecord::Base.connection.validate_column(@table_name, column_name, opts) unless opts.blank?
9
11
  end
@@ -2,8 +2,10 @@ module MigrationValidators
2
2
  module ActiveRecord
3
3
  module ConnectionAdapters
4
4
  module TableDefinition
5
- def self.included(base)
6
- base.class_eval do
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_eval do
7
9
  alias_method_chain :column, :validators
8
10
 
9
11
  def change_validates *args
@@ -1,11 +1,12 @@
1
1
  module MigrationValidators
2
2
  module ActiveRecord
3
3
  module Migration
4
- def self.included(base)
5
- base.extend ClassMethods
6
- base.class_eval do
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ class_eval do
7
8
  class << self
8
- alias_method_chain :migrate, :validators
9
+ self.alias_method_chain :migrate, :validators
9
10
  end
10
11
  end
11
12
  end
@@ -1,9 +1,10 @@
1
1
  module MigrationValidators
2
2
  module ActiveRecord
3
3
  module Schema
4
- def self.included(base)
5
- base.extend ClassMethods
6
- base.class_eval do
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ class_eval do
7
8
  class << self
8
9
  alias_method_chain :define, :validators
9
10
  end
@@ -1,8 +1,10 @@
1
1
  module MigrationValidators
2
2
  module ActiveRecord
3
3
  module SchemaDumper
4
- def self.included(base)
5
- base.class_eval do
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ class_eval do
6
8
  alias_method_chain :tables, :validators
7
9
  end
8
10
  end
@@ -12,13 +14,10 @@ module MigrationValidators
12
14
 
13
15
  stream.puts ""
14
16
  stream.puts " #Validators"
15
- MigrationValidators::Core::DbValidator.find(:all, :order => "table_name, column_name").each do |validator|
17
+ MigrationValidators::Core::DbValidator.order([:table_name, :column_name]).each do |validator|
16
18
  stream.puts " validate_column :#{validator.table_name}, :#{validator.column_name}, :#{validator.validator_name} => #{validator.options.inspect}"
17
19
  end
18
20
  end
19
-
20
- private
21
-
22
21
  end
23
22
  end
24
23
  end
@@ -1,9 +1,7 @@
1
1
  module MigrationValidators
2
2
  module Adapters
3
3
  module Containers
4
- def self.included(base)
5
- base.extend ClassMethods
6
- end
4
+ extend ActiveSupport::Concern
7
5
 
8
6
  module ClassMethods
9
7
  def containers
@@ -29,10 +27,10 @@ module MigrationValidators
29
27
  end
30
28
 
31
29
  operation :create do |stmt, trigger_name, group_name|
32
- "CREATE TRIGGER #{trigger_name} BEFORE INSERT ON #{group_name.first} FOR EACH ROW
33
- BEGIN
34
- #{stmt};
35
- END;"
30
+ ["CREATE TRIGGER #{trigger_name} BEFORE INSERT ON #{group_name.first} FOR EACH ROW",
31
+ "BEGIN",
32
+ "#{stmt}; ",
33
+ "END;"].join(' ')
36
34
  end
37
35
 
38
36
  operation :drop do |stmt, trigger_name, group_name|
@@ -59,10 +57,10 @@ module MigrationValidators
59
57
  end
60
58
 
61
59
  operation :create do |stmt, trigger_name, group_name|
62
- "CREATE TRIGGER #{trigger_name} BEFORE UPDATE ON #{group_name.first} FOR EACH ROW
63
- BEGIN
64
- #{stmt};
65
- END;"
60
+ ["CREATE TRIGGER #{trigger_name} BEFORE UPDATE ON #{group_name.first} FOR EACH ROW",
61
+ "BEGIN",
62
+ "#{stmt}; ",
63
+ "END;"].join(' ')
66
64
  end
67
65
 
68
66
  operation :drop do |stmt, trigger_name, group_name|
@@ -1,9 +1,7 @@
1
1
  module MigrationValidators
2
2
  module Adapters
3
3
  module Routing
4
- def self.included(base)
5
- base.extend ClassMethods
6
- end
4
+ extend ActiveSupport::Concern
7
5
 
8
6
  ###################################################################
9
7
  ## UNIQUENESS
@@ -1,9 +1,7 @@
1
1
  module MigrationValidators
2
2
  module Adapters
3
3
  module Syntax
4
- def self.included(base)
5
- base.extend ClassMethods
6
- end
4
+ extend ActiveSupport::Concern
7
5
 
8
6
  module ClassMethods
9
7
  def define_base_syntax
@@ -1,9 +1,7 @@
1
1
  module MigrationValidators
2
2
  module Adapters
3
3
  module ValidatorDefinitions
4
- def self.included(base)
5
- base.extend ClassMethods
6
- end
4
+ extend ActiveSupport::Concern
7
5
 
8
6
  module ClassMethods
9
7
  def validators
@@ -11,15 +9,20 @@ module MigrationValidators
11
9
  end
12
10
 
13
11
  def validator name, opts = {}, &block
14
- validator = validators[name] ||= MigrationValidators::Core::ValidatorDefinition.new(syntax)
12
+ validator = validators[name]
13
+
14
+ unless validator
15
+ validator = validators[name] = MigrationValidators::Core::ValidatorDefinition.new(syntax)
15
16
 
16
- validator.post :allow_nil => true do
17
- self.wrap.or(column.db_name.null)
18
- end if opts[:allow_nil] || !opts.key?(:allow_nil)
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
19
25
 
20
- validator.post :allow_blank => true do
21
- self.wrap.or(column.db_name.coalesce.trim.length.equal_to(0))
22
- end if opts[:allow_blank] || !opts.key?(:allow_blank)
23
26
 
24
27
  validator.instance_eval(&block) if block
25
28
  end
@@ -119,9 +122,7 @@ module MigrationValidators
119
122
 
120
123
  validator :uniqueness do
121
124
  property do |value|
122
- "NOT EXISTS(SELECT #{column}
123
- FROM #{validator.table_name}
124
- WHERE (#{column.db_name} = #{column}))"
125
+ "NOT EXISTS(SELECT #{column.to_s} FROM #{validator.table_name} tbl WHERE (#{column.db_name} = #{column.to_s}))"
125
126
  end
126
127
  end
127
128
  end
@@ -1,7 +1,11 @@
1
1
  module MigrationValidators
2
2
  module Core
3
3
  class DbValidator < ::ActiveRecord::Base
4
- set_table_name MigrationValidators.migration_validators_table_name
4
+ @@validators_to_remove = []
5
+ @@validators_to_add = []
6
+
7
+
8
+ self.table_name = MigrationValidators.migration_validators_table_name
5
9
 
6
10
  validates_presence_of :table_name
7
11
  validates_length_of :table_name, :maximum => 255
@@ -23,13 +27,20 @@ module MigrationValidators
23
27
  before_save :prepare_options
24
28
 
25
29
  serialize :options, Hash
26
- serialize :constraints, Array
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
27
39
 
28
40
  def name
29
41
  "#{table_name}_#{column_name}_#{validator_name}"
30
42
  end
31
43
 
32
-
33
44
  def error_message
34
45
  unless (options.blank? || (message = options[:message]).blank?)
35
46
  message
@@ -42,135 +53,77 @@ module MigrationValidators
42
53
  return true if opts.blank?
43
54
 
44
55
  opts.collect do |property_name, property_value|
45
- [property_name, property_value.kind_of?(Array) ? property_value : [property_value]]
56
+ [property_name, [property_value].flatten]
46
57
  end.all? do |property_name, property_value|
47
58
  property_value.include?(options[property_name])
48
59
  end
49
60
  end
50
61
 
51
- def save_to_constraint constraint_name
52
- self.constraints ||= []
53
- self.constraints << constraint_name.to_s unless self.constraints.include?(constraint_name.to_s)
54
- end
55
-
56
- def remove_from_constraint constraint_name
57
- self.constraints.delete(constraint_name.to_s) if self.constraints
62
+ def delayed_destroy
63
+ @@validators_to_remove << self unless @@validators_to_remove.include?(self)
58
64
  end
59
65
 
60
- def in_constraint? constraint_name
61
- self.constraints && self.constraints.include?(constraint_name.to_s)
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)
62
73
  end
63
74
 
64
75
  private
65
- def prepare_options
66
- options = options.inject({}) do |res, (key, value)|
67
- res[key.to_s] = value
68
- res
69
- end unless options.blank?
70
-
71
- true
72
- end
73
-
74
- class << self
75
-
76
- def add_column_validator table_name, column_name, validator_name, opts
77
- remove_validators(:table_name => table_name.to_s,
78
- :column_name => column_name.to_s,
79
- :validator_name => validator_name.to_s)
80
-
81
- add_new_validator(:table_name => table_name.to_s,
82
- :column_name => column_name.to_s,
83
- :validator_name => validator_name.to_s,
84
- :options => opts)
85
- end
86
-
87
- def remove_column_validator table_name, column_name, validator_name
88
- remove_validators :table_name => table_name.to_s, :column_name => column_name.to_s, :validator_name => validator_name.to_s
89
- end
90
-
91
- def remove_column_validators table_name, column_name
92
- remove_validators :table_name => table_name.to_s, :column_name => column_name.to_s
93
- end
94
-
95
- def table_validators table_name, opts = {}
96
- with_options opts do
97
- DbValidator.find(:all, :conditions => { :table_name => table_name.to_s })
98
- end
99
- end
100
76
 
101
- def constraint_validators constraint
102
- (DbValidator.find(:all, :conditions => ["constraints LIKE ?", "%#{constraint}%"]) + validators_to_add - validators_to_remove).select{|validator| validator.in_constraint?(constraint)}
103
- end
104
-
105
- def remove_table_validators table_name
106
- remove_validators :table_name => table_name.to_s
107
- end
108
-
109
- def column_validators table_name, column_name, opts = {}
110
- with_options opts do
111
- DbValidator.find :all, :conditions => { :table_name => table_name.to_s, :column_name => column_name.to_s }
112
- end
113
- end
114
-
115
- def rename_column table_name, old_column_name, new_column_name
116
- DbValidator.update_all({:column_name => new_column_name.to_s}, :column_name => old_column_name.to_s)
117
- end
118
-
119
- def rename_table old_table_name, new_table_name
120
- DbValidator.update_all({:table_name => new_table_name.to_s}, :table_name => old_table_name.to_s)
121
- end
122
-
123
- def commit adapter = nil
124
- adapter.remove_validators(validators_to_remove.select{|validator| ::ActiveRecord::Base.connection.table_exists?(validator.table_name)}) if adapter
125
- validators_to_remove.each(&:destroy)
126
- validators_to_remove.clear
127
-
128
- adapter.create_validators(validators_to_add) if adapter
129
- validators_to_add.each(&:save!)
130
- validators_to_add.clear
131
- end
132
-
133
- def rollback
134
- validators_to_remove.clear
135
- validators_to_add.clear
136
- end
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?
137
82
 
83
+ true
84
+ end
138
85
 
139
- def clear_all
140
- rollback
141
- DbValidator.delete_all
142
- end
86
+ class << self
143
87
 
144
- def validators_to_remove
145
- @validators_to_remove ||= []
146
- end
88
+ def satisfies opts
89
+ all.select{|validator| validator.satisfies(opts) }
90
+ end
147
91
 
148
- def validators_to_add
149
- @validators_to_add ||= []
150
- end
92
+ def delayed_destroy
93
+ all.each(&:delayed_destroy)
94
+ end
151
95
 
152
- private
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
153
99
 
154
- def validators_to_remove
155
- @validators_to_remove ||= []
156
- end
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
157
103
 
158
- def validators_to_add
159
- @validators_to_add ||= []
160
- end
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
161
107
 
162
- def with_options opts, &block
163
- block.call.select {|validator| validator.satisfies(opts) }
164
- end
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
165
112
 
166
- def add_new_validator opts
167
- validators_to_add << new(opts)
168
- end
113
+ adapter.create_validators(@@validators_to_add) if adapter
114
+ @@validators_to_add.each(&:save!)
115
+ @@validators_to_add.clear
116
+ end
169
117
 
170
- def remove_validators opts
171
- DbValidator.find(:all, :conditions => opts).each { |validator| validators_to_remove << validator }
172
- end
118
+ def rollback
119
+ @@validators_to_remove.clear
120
+ @@validators_to_add.clear
121
+ end
173
122
 
123
+ def clear_all
124
+ rollback
125
+ DbValidator.delete_all
126
+ end
174
127
 
175
128
  end
176
129
  end