mv-postgresql 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 (29) hide show
  1. checksums.yaml +4 -4
  2. data/{README.rdoc → README.md} +69 -24
  3. data/lib/mv-postgresql.rb +68 -1
  4. data/lib/mv/postgresql/active_record/connection_adapters/postgresql_adapter_decorator.rb +11 -0
  5. data/lib/mv/postgresql/constraint/builder/check.rb +45 -0
  6. data/lib/mv/postgresql/constraint/builder/trigger.rb +69 -0
  7. data/lib/mv/postgresql/constraint/check.rb +11 -0
  8. data/lib/mv/postgresql/railtie.rb +11 -0
  9. data/lib/mv/postgresql/route/check.rb +17 -0
  10. data/lib/mv/postgresql/validation/absence.rb +11 -0
  11. data/lib/mv/postgresql/validation/builder/exclusion.rb +18 -0
  12. data/lib/mv/postgresql/validation/builder/format.rb +34 -0
  13. data/lib/mv/postgresql/validation/builder/inclusion.rb +18 -0
  14. data/lib/mv/postgresql/validation/builder/trigger/absence.rb +15 -0
  15. data/lib/mv/postgresql/validation/builder/trigger/exclusion.rb +16 -0
  16. data/lib/mv/postgresql/validation/builder/trigger/format.rb +16 -0
  17. data/lib/mv/postgresql/validation/builder/trigger/inclusion.rb +16 -0
  18. data/lib/mv/postgresql/validation/builder/trigger/length.rb +15 -0
  19. data/lib/mv/postgresql/validation/builder/trigger/presence.rb +15 -0
  20. data/lib/mv/postgresql/validation/builder/trigger/trigger_column.rb +17 -0
  21. data/lib/mv/postgresql/validation/builder/trigger/uniqueness.rb +15 -0
  22. data/lib/mv/postgresql/validation/check_support.rb +44 -0
  23. data/lib/mv/postgresql/validation/exclusion.rb +11 -0
  24. data/lib/mv/postgresql/validation/format.rb +25 -0
  25. data/lib/mv/postgresql/validation/inclusion.rb +11 -0
  26. data/lib/mv/postgresql/validation/length.rb +11 -0
  27. data/lib/mv/postgresql/validation/presence.rb +11 -0
  28. metadata +101 -8
  29. data/lib/migration_validators/adapters/postgresql.rb +0 -146
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 13c089d60aae49617aa26da0fe977a1908b03e3c
4
- data.tar.gz: 08cc2f9ed8b940c4075f78db5af52459b81800bd
3
+ metadata.gz: 6193f8d0d4867e6732ce747329a8779eb32778b1
4
+ data.tar.gz: d21b9c03169d1aa29db9c528d670f2676cdeac7a
5
5
  SHA512:
6
- metadata.gz: b14170815495b1c873fde107ad3a441e967b78c815e46c9ec49848152373da3f0c56b994ca96d7bce6494c13088888eac6a1566f52eb2c5c3fe31e1f2d51fcfe
7
- data.tar.gz: c08a261687f1d624d7d690737dfee64175a960e5abc693261c593ac39f4acceec48b87e8501d6acade946bffcd91b45065c4d554402fa3a1ea35b5fc885320ca
6
+ metadata.gz: 1895ba7e873687b119e4623366e9c9f089c1e75e39ad1b8eb4dd19b54324369e6973d50498d35d03fa8bd2b3cd7f64f37e1145be9094db96839f95bdc5058872
7
+ data.tar.gz: 270ede9167f1321282eb28028f5a3dd7d84562305fa8ba82ce19e15662d8e9a1a52a37fd0f16e534164b41ef0c01a5fc0cb5639a5ddf3a5cde154ad908774c25
@@ -1,9 +1,12 @@
1
+ [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/vprokopchuk256/mv-postgresql/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
2
+ [![Build Status](https://travis-ci.org/vprokopchuk256/mv-postgresql.svg?branch=master)](https://travis-ci.org/vprokopchuk256/mv-postgresql)
3
+ [![Coverage Status](https://coveralls.io/repos/vprokopchuk256/mv-postgresql/badge.png?branch=master)](https://coveralls.io/r/vprokopchuk256/mv-postgresql?branch=master)
4
+ [![Gem Version](https://badge.fury.io/rb/mv-postgresql.svg)](http://badge.fury.io/rb/mv-postgresql)
5
+
1
6
  # Introduction
2
7
 
3
8
  mv-postgresql is the PostgreSQL driver for Migration Validators project (details here: https://github.com/vprokopchuk256/mv-core)
4
9
 
5
- # Validators
6
-
7
10
  ### uniqueness
8
11
 
9
12
  Examples:
@@ -11,20 +14,20 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
11
14
  validate uniqueness of the column 'column_name':
12
15
 
13
16
  ```ruby
14
- validate_column :table_name, :column_name, uniqueness: true
17
+ validates :table_name, :column_name, uniqueness: true
15
18
  ```
16
19
 
17
20
  define validation as trigger with specified failure message:
18
21
 
19
22
  ```ruby
20
- validate_column :table_name, :column_name,
23
+ validates :table_name, :column_name,
21
24
  uniqueness: { message: 'Error message', as: :trigger }
22
25
  ```
23
26
 
24
27
  define validation as unique index:
25
28
 
26
29
  ```ruby
27
- validate_column :table_name, :column_name, uniqueness: { as: :index }
30
+ validates :table_name, :column_name, uniqueness: { as: :index }
28
31
  ```
29
32
 
30
33
  all above are available in a create and change table blocks:
@@ -57,7 +60,7 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
57
60
  Examples:
58
61
 
59
62
  ```ruby
60
- validate_column :table_name, :column_name,
63
+ validates :table_name, :column_name,
61
64
  length: { in: 5..8,
62
65
  message: 'Wrong length message'}
63
66
  ```
@@ -65,14 +68,14 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
65
68
  allow `NULL`:
66
69
 
67
70
  ```ruby
68
- validate_column :table_name, :column_name,
71
+ validates :table_name, :column_name,
69
72
  length: { is: 3, allow_nil: true}
70
73
  ```
71
74
 
72
75
  allow blank values:
73
76
 
74
77
  ```ruby
75
- validate_column :table_name, :column_name,
78
+ validates :table_name, :column_name,
76
79
  length: { maximum: 3,
77
80
  too_long: 'Value is longer than 3 symbols' }
78
81
  ```
@@ -80,7 +83,7 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
80
83
  define constraint in trigger:
81
84
 
82
85
  ```ruby
83
- validate_column :table_name, :column_name,
86
+ validates :table_name, :column_name,
84
87
  length: { maximum: 3,
85
88
  as: :trigger,
86
89
  too_long: 'Value is longer than 3 symbols' }
@@ -110,13 +113,13 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
110
113
  valid values array:
111
114
 
112
115
  ```ruby
113
- validate_column :table_name, :column_name, inclusion: { in: [1, 2, 3] }
116
+ validates :table_name, :column_name, inclusion: { in: [1, 2, 3] }
114
117
  ```
115
118
 
116
119
  with failure message specified:
117
120
 
118
121
  ```ruby
119
- validate_column :table_name, :column_name,
122
+ validates :table_name, :column_name,
120
123
  inclusion: { in: [1, 2, 3],
121
124
  message: "Column 'column_name' should be equal to 1 or 2 or 3" }
122
125
  ```
@@ -124,7 +127,7 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
124
127
  make it as check constraint:
125
128
 
126
129
  ```ruby
127
- validate_column :table_name, :column_name,
130
+ validates :table_name, :column_name,
128
131
  inclusion: { in: [1, 2, 3],
129
132
  on: :update,
130
133
  as: :check }
@@ -133,7 +136,7 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
133
136
  make it in trigger:
134
137
 
135
138
  ```ruby
136
- validate_column :table_name, :column_name,
139
+ validates :table_name, :column_name,
137
140
  inclusion: { in: 1..3,
138
141
  on: :create,
139
142
  as: :trigger }
@@ -158,13 +161,13 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
158
161
  exclude 1, 2, and 3:
159
162
 
160
163
  ```ruby
161
- validate_column :table_name, :column_name, exclusion: { in: [1, 2, 3] }
164
+ validates :table_name, :column_name, exclusion: { in: [1, 2, 3] }
162
165
  ```
163
166
 
164
167
  the same with failure message:
165
168
 
166
169
  ```ruby
167
- validate_column :table_name, :column_name,
170
+ validates :table_name, :column_name,
168
171
  exclusion: {
169
172
  in: [1, 2, 3],
170
173
  message: "Column 'column_name' should not be equal to 1 or 2 or 3" }
@@ -173,7 +176,7 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
173
176
  as check constraint:
174
177
 
175
178
  ```ruby
176
- validate_column :table_name, :column_name,
179
+ validates :table_name, :column_name,
177
180
  exclusion: { in: [1, 2, 3],
178
181
  on: :update,
179
182
  as: :check }
@@ -182,7 +185,7 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
182
185
  as trigger:
183
186
 
184
187
  ```ruby
185
- validate_column :table_name, :column_name,
188
+ validates :table_name, :column_name,
186
189
  exclusion: { in: 1..3,
187
190
  on: :create,
188
191
  as: :trigger }
@@ -205,20 +208,20 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
205
208
  Examples:
206
209
 
207
210
  ```ruby
208
- validate_column :table_name, :column_name, presence: true
211
+ validates :table_name, :column_name, presence: true
209
212
  ```
210
213
 
211
214
  with failure message:
212
215
 
213
216
  ```ruby
214
- validate_column :table_name, :column_name,
217
+ validates :table_name, :column_name,
215
218
  presence: { message: 'value should not be empty' }
216
219
  ```
217
220
 
218
221
  implemented as trigger:
219
222
 
220
223
  ```ruby
221
- validate_column :table_name, :column_name,
224
+ validates :table_name, :column_name,
222
225
  presence: { message: 'value should not be empty',
223
226
  as: :trigger }
224
227
  ```
@@ -226,7 +229,7 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
226
229
  check when record is inserted only:
227
230
 
228
231
  ```ruby
229
- validate_column :table_name, :column_name,
232
+ validates :table_name, :column_name,
230
233
  presence: { message: 'value should not be empty',
231
234
  as: :trigger,
232
235
  on: :create }
@@ -242,6 +245,48 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
242
245
  * `allow_blank` - ignore validation for blank values. Default value: `false`
243
246
  * `as` - defines the way how constraint will be implemented. Possible values: `[:trigger, :check]` Default value: `:check`
244
247
 
248
+ ### absence
249
+
250
+ Examples:
251
+
252
+ ```ruby
253
+ validates :table_name, :column_name, absence: true
254
+ ```
255
+
256
+ with failure message:
257
+
258
+ ```ruby
259
+ validates :table_name, :column_name,
260
+ absence: { message: 'value should be empty' }
261
+ ```
262
+
263
+ implemented as trigger:
264
+
265
+ ```ruby
266
+ validates :table_name, :column_name,
267
+ absence: { message: 'value should be empty',
268
+ as: :trigger }
269
+ ```
270
+
271
+ check when record is inserted only:
272
+
273
+ ```ruby
274
+ validates :table_name, :column_name,
275
+ absence: { message: 'value should be empty',
276
+ as: :trigger,
277
+ on: :create }
278
+ ```
279
+
280
+ Options:
281
+
282
+ * `message` - message that should be shown if validation failed
283
+ * `on` - validation event. Possible values `[:save, :update, :create]`. Ignored unless `:as == :trigger`. Default value: `:save`
284
+ * `create_tigger_name` - Name of the 'before insert' trigger that will be created if `:as == :trigger` && `:on` in `[:save, :create]`
285
+ * `update_tigger_name` - Name of the 'before update' trigger that will be created if `:as == :trigger` && `:on` in `[:save, :update]`
286
+ * `allow_nil` - ignore validation for `nil` values. Default value: `false`
287
+ * `allow_blank` - ignore validation for blank values. Default value: `false`
288
+ * `as` - defines the way how constraint will be implemented. Possible values: `[:trigger, :check]` Default value: `:check`
289
+
245
290
  ### format
246
291
 
247
292
  Examples:
@@ -249,13 +294,13 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
249
294
  allows only values that contains 'word' inside:
250
295
 
251
296
  ```ruby
252
- validate_column :table_name, :column_name, format: { with: /word/ }
297
+ validates :table_name, :column_name, format: { with: /word/ }
253
298
  ```
254
299
 
255
300
  with failure message:
256
301
 
257
302
  ```ruby
258
- validate_column :table_name, :column_name,
303
+ validates :table_name, :column_name,
259
304
  format: { with: /word/,
260
305
  message: 'Column_name value should contain start word' }
261
306
  ```
@@ -263,7 +308,7 @@ mv-postgresql is the PostgreSQL driver for Migration Validators project (details
263
308
  implemented as trigger:
264
309
 
265
310
  ```ruby
266
- validate_column :table_name, :column_name,
311
+ validates :table_name, :column_name,
267
312
  format: { with: /word/,
268
313
  message: 'Column_name value should contain start word',
269
314
  as: :trigger }
@@ -1,4 +1,71 @@
1
1
  require 'mv-core'
2
+ require 'mv/postgresql/railtie'
2
3
 
3
- require File.expand_path(File.dirname(__FILE__)) + '/migration_validators/adapters/postgresql'
4
+ require 'mv/postgresql/route/check'
5
+
6
+ require 'mv/postgresql/constraint/check'
7
+
8
+ require 'mv/postgresql/constraint/builder/trigger'
9
+ require 'mv/postgresql/constraint/builder/check'
10
+
11
+ require 'mv/postgresql/validation/exclusion'
12
+ require 'mv/postgresql/validation/format'
13
+ require 'mv/postgresql/validation/inclusion'
14
+ require 'mv/postgresql/validation/length'
15
+ require 'mv/postgresql/validation/presence'
16
+ require 'mv/postgresql/validation/absence'
17
+
18
+ require 'mv/postgresql/validation/builder/trigger/exclusion'
19
+ require 'mv/postgresql/validation/builder/trigger/inclusion'
20
+ require 'mv/postgresql/validation/builder/trigger/length'
21
+ require 'mv/postgresql/validation/builder/trigger/format'
22
+ require 'mv/postgresql/validation/builder/trigger/presence'
23
+ require 'mv/postgresql/validation/builder/trigger/absence'
24
+ require 'mv/postgresql/validation/builder/trigger/uniqueness'
25
+
26
+ ActiveSupport.on_load(:mv_core) do
27
+ #router
28
+ Mv::Core::Router.define_route(:check, Mv::Postgresql::Route::Check)
29
+
30
+ #constraints
31
+ Mv::Core::Constraint::Factory.register_constraint(:check, Mv::Postgresql::Constraint::Check)
32
+
33
+ #constraint builders
34
+ Mv::Core::Constraint::Builder::Factory.register_builders(
35
+ Mv::Core::Constraint::Trigger => Mv::Postgresql::Constraint::Builder::Trigger,
36
+ Mv::Postgresql::Constraint::Check => Mv::Postgresql::Constraint::Builder::Check
37
+ )
38
+
39
+ #validations
40
+ Mv::Core::Validation::Factory.register_validations(
41
+ :exclusion => Mv::Postgresql::Validation::Exclusion,
42
+ :format => Mv::Postgresql::Validation::Format,
43
+ :inclusion => Mv::Postgresql::Validation::Inclusion,
44
+ :length => Mv::Postgresql::Validation::Length,
45
+ :presence => Mv::Postgresql::Validation::Presence,
46
+ :absence => Mv::Postgresql::Validation::Absence
47
+ )
48
+
49
+ #validation builders in trigger
50
+ Mv::Postgresql::Constraint::Builder::Trigger.validation_builders_factory.register_builders(
51
+ Mv::Postgresql::Validation::Exclusion => Mv::Postgresql::Validation::Builder::Trigger::Exclusion,
52
+ Mv::Postgresql::Validation::Inclusion => Mv::Postgresql::Validation::Builder::Trigger::Inclusion,
53
+ Mv::Postgresql::Validation::Length => Mv::Postgresql::Validation::Builder::Trigger::Length,
54
+ Mv::Postgresql::Validation::Format => Mv::Postgresql::Validation::Builder::Trigger::Format,
55
+ Mv::Postgresql::Validation::Presence => Mv::Postgresql::Validation::Builder::Trigger::Presence,
56
+ Mv::Postgresql::Validation::Absence => Mv::Postgresql::Validation::Builder::Trigger::Absence,
57
+ Mv::Core::Validation::Uniqueness => Mv::Postgresql::Validation::Builder::Trigger::Uniqueness
58
+ )
59
+
60
+ #validation builders in check
61
+ Mv::Postgresql::Constraint::Builder::Check.validation_builders_factory.register_builders(
62
+ Mv::Postgresql::Validation::Exclusion => Mv::Postgresql::Validation::Builder::Exclusion,
63
+ Mv::Postgresql::Validation::Inclusion => Mv::Postgresql::Validation::Builder::Inclusion,
64
+ Mv::Postgresql::Validation::Length => Mv::Core::Validation::Builder::Length,
65
+ Mv::Postgresql::Validation::Format => Mv::Postgresql::Validation::Builder::Format,
66
+ Mv::Postgresql::Validation::Presence => Mv::Core::Validation::Builder::Presence,
67
+ Mv::Postgresql::Validation::Absence => Mv::Core::Validation::Builder::Absence
68
+ )
69
+
70
+ end
4
71
 
@@ -0,0 +1,11 @@
1
+ module Mv
2
+ module Postgresql
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module PostgresqlAdapterDecorator
6
+ include Mv::Core::ActiveRecord::ConnectionAdapters::AbstractAdapterDecorator
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,45 @@
1
+ module Mv
2
+ module Postgresql
3
+ module Constraint
4
+ module Builder
5
+ class Check < Mv::Core::Constraint::Builder::Base
6
+ def create
7
+ validation_builders.group_by(&:table_name).each do |table_name, validations|
8
+ db.execute(drop_check_statement(table_name))
9
+ db.execute(create_check_statement(table_name))
10
+ end
11
+ end
12
+
13
+ def update new_constraint_builder
14
+ delete
15
+ new_constraint_builder.create
16
+ end
17
+
18
+ def delete
19
+ validation_builders.group_by(&:table_name).each do |table_name, validations|
20
+ if db.table_exists?(table_name)
21
+ db.execute(drop_check_statement(table_name))
22
+ end
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def check_body(table_name)
29
+ validation_builders.select{|b| b.table_name == table_name }.collect(&:conditions).flatten.collect do |condition|
30
+ "(#{condition[:statement]})"
31
+ end.join(" AND ")
32
+ end
33
+
34
+ def create_check_statement(table_name)
35
+ "ALTER TABLE #{table_name} ADD CONSTRAINT #{name} CHECK (#{check_body(table_name)});"
36
+ end
37
+
38
+ def drop_check_statement(table_name)
39
+ "ALTER TABLE #{table_name} DROP CONSTRAINT IF EXISTS #{name};"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,69 @@
1
+ module Mv
2
+ module Postgresql
3
+ module Constraint
4
+ module Builder
5
+ class Trigger < Mv::Core::Constraint::Builder::Trigger
6
+ def create
7
+ validation_builders.group_by(&:table_name).each do |table_name, validations|
8
+ db.execute(drop_trigger_statement(table_name))
9
+ db.execute(drop_function_statement())
10
+ db.execute(create_function_statement(table_name))
11
+ db.execute(create_trigger_statement(table_name))
12
+ end
13
+ end
14
+
15
+ def delete
16
+ validation_builders.group_by(&:table_name).each do |table_name, validations|
17
+ if db.table_exists?(table_name)
18
+ db.execute(drop_trigger_statement(table_name))
19
+ db.execute(drop_function_statement())
20
+ end
21
+ end
22
+ end
23
+
24
+ def update new_constraint_builder
25
+ delete
26
+ new_constraint_builder.create
27
+ end
28
+
29
+ private
30
+
31
+ def func_name
32
+ "#{name}_func"
33
+ end
34
+
35
+ def drop_trigger_statement table_name
36
+ "DROP TRIGGER IF EXISTS #{name} ON #{table_name};"
37
+ end
38
+
39
+ def create_trigger_statement table_name
40
+ "CREATE TRIGGER #{name} BEFORE #{update? ? 'UPDATE' : 'INSERT'} ON #{table_name}
41
+ FOR EACH ROW EXECUTE PROCEDURE #{func_name}();".squish
42
+ end
43
+
44
+ def function_body(table_name)
45
+ validation_builders.select{|b| b.table_name == table_name }.collect(&:conditions).flatten.collect do |condition|
46
+ "IF NOT(#{condition[:statement]}) THEN
47
+ RAISE EXCEPTION '#{condition[:message]}';
48
+ END IF".squish
49
+ end.join("; \n")
50
+ end
51
+
52
+ def drop_function_statement
53
+ "DROP FUNCTION IF EXISTS #{func_name}();"
54
+ end
55
+
56
+ def create_function_statement table_name
57
+ "CREATE FUNCTION #{func_name}() RETURNS TRIGGER AS $#{func_name}$
58
+ BEGIN
59
+ #{function_body(table_name)};
60
+
61
+ RETURN NEW;
62
+ END;
63
+ $#{func_name}$ LANGUAGE plpgsql;"
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,11 @@
1
+ module Mv
2
+ module Postgresql
3
+ module Constraint
4
+ class Check < Mv::Core::Constraint::Base
5
+ def initialize description
6
+ super
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'mv/postgresql/active_record/connection_adapters/postgresql_adapter_decorator'
2
+
3
+ module Mv
4
+ module Postgresql
5
+ class Railtie < ::Rails::Railtie
6
+ initializer 'mv-postgresql.initialization', after: 'active_record.initialize_database' do
7
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:prepend, Mv::Postgresql::ActiveRecord::ConnectionAdapters::PostgresqlAdapterDecorator)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Mv
2
+ module Postgresql
3
+ module Route
4
+ class Check
5
+ attr_reader :validation
6
+
7
+ def initialize(validation)
8
+ @validation = validation
9
+ end
10
+
11
+ def route
12
+ [Mv::Core::Constraint::Description.new(validation.check_name, :check)]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ require 'mv/postgresql/validation/check_support'
2
+
3
+ module Mv
4
+ module Postgresql
5
+ module Validation
6
+ class Absence < Mv::Core::Validation::Absence
7
+ include CheckSupport
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ module Mv
2
+ module Postgresql
3
+ module Validation
4
+ module Builder
5
+ class Exclusion < Mv::Core::Validation::Builder::Exclusion
6
+ protected
7
+
8
+ def db_value value
9
+ return "'#{value.strftime('%Y-%m-%d %H:%M:%S')}'" if value.is_a?(DateTime)
10
+ return "'#{value.strftime('%Y-%m-%d %H:%M:%S')}'" if value.is_a?(Time)
11
+ return "'#{value.strftime('%Y-%m-%d')}'" if value.is_a?(Date)
12
+ super
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ module Mv
2
+ module Postgresql
3
+ module Validation
4
+ module Builder
5
+ class Format < Mv::Core::Validation::Builder::Base
6
+ delegate :with, to: :validation
7
+
8
+ def conditions
9
+ [{
10
+ statement: apply_allow_nil_and_blank(apply_with(column_reference)),
11
+ message: message
12
+ }]
13
+ end
14
+
15
+ protected
16
+
17
+ def db_value value
18
+ return "'#{value.source}'" if value.is_a?(Regexp)
19
+ return "'#{value.to_s}'" if value.is_a?(String)
20
+ raise Mv::Core::Error.new(table_name: table_name,
21
+ column_name: column_name,
22
+ validation_type: :inclusion,
23
+ options: { in: value },
24
+ error: "#{value.class} is not supported as :with value")
25
+ end
26
+
27
+ def apply_with stmt
28
+ "#{stmt} ~ #{db_value(with)}"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ module Mv
2
+ module Postgresql
3
+ module Validation
4
+ module Builder
5
+ class Inclusion < Mv::Core::Validation::Builder::Inclusion
6
+ protected
7
+
8
+ def db_value value
9
+ return "'#{value.strftime('%Y-%m-%d %H:%M:%S')}'" if value.is_a?(DateTime)
10
+ return "'#{value.strftime('%Y-%m-%d %H:%M:%S')}'" if value.is_a?(Time)
11
+ return "'#{value.strftime('%Y-%m-%d')}'" if value.is_a?(Date)
12
+ super
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ require 'mv/postgresql/validation/builder/trigger/trigger_column'
2
+
3
+ module Mv
4
+ module Postgresql
5
+ module Validation
6
+ module Builder
7
+ module Trigger
8
+ class Absence < Mv::Core::Validation::Builder::Absence
9
+ include TriggerColumn
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require 'mv/postgresql/validation/builder/exclusion'
2
+ require 'mv/postgresql/validation/builder/trigger/trigger_column'
3
+
4
+ module Mv
5
+ module Postgresql
6
+ module Validation
7
+ module Builder
8
+ module Trigger
9
+ class Exclusion < Mv::Postgresql::Validation::Builder::Exclusion
10
+ include TriggerColumn
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'mv/postgresql/validation/builder/format'
2
+ require 'mv/postgresql/validation/builder/trigger/trigger_column'
3
+
4
+ module Mv
5
+ module Postgresql
6
+ module Validation
7
+ module Builder
8
+ module Trigger
9
+ class Format < Mv::Postgresql::Validation::Builder::Format
10
+ include TriggerColumn
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'mv/postgresql/validation/builder/inclusion'
2
+ require 'mv/postgresql/validation/builder/trigger/trigger_column'
3
+
4
+ module Mv
5
+ module Postgresql
6
+ module Validation
7
+ module Builder
8
+ module Trigger
9
+ class Inclusion < Mv::Postgresql::Validation::Builder::Inclusion
10
+ include TriggerColumn
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ require 'mv/postgresql/validation/builder/trigger/trigger_column'
2
+
3
+ module Mv
4
+ module Postgresql
5
+ module Validation
6
+ module Builder
7
+ module Trigger
8
+ class Length < Mv::Core::Validation::Builder::Length
9
+ include TriggerColumn
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'mv/postgresql/validation/builder/trigger/trigger_column'
2
+
3
+ module Mv
4
+ module Postgresql
5
+ module Validation
6
+ module Builder
7
+ module Trigger
8
+ class Presence < Mv::Core::Validation::Builder::Presence
9
+ include TriggerColumn
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module Mv
2
+ module Postgresql
3
+ module Validation
4
+ module Builder
5
+ module Trigger
6
+ module TriggerColumn
7
+ protected
8
+
9
+ def column_reference
10
+ "NEW.#{super}"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ require 'mv/postgresql/validation/builder/trigger/trigger_column'
2
+
3
+ module Mv
4
+ module Postgresql
5
+ module Validation
6
+ module Builder
7
+ module Trigger
8
+ class Uniqueness < Mv::Core::Validation::Builder::Uniqueness
9
+ include TriggerColumn
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,44 @@
1
+ module Mv
2
+ module Postgresql
3
+ module Validation
4
+ module CheckSupport
5
+ attr_reader :check_name
6
+
7
+ def self.included mod
8
+ mod.validates :check_name, absence: { message: 'allowed when :as == :trigger' }, unless: :check?
9
+ end
10
+
11
+ def initialize(table_name, column_name, opts)
12
+ super
13
+
14
+ @check_name = opts.with_indifferent_access[:check_name] || default_check_name
15
+ end
16
+
17
+ def to_a
18
+ super + [check_name.to_s]
19
+ end
20
+
21
+ protected
22
+
23
+ def available_as
24
+ super + [:check]
25
+ end
26
+
27
+ def default_as
28
+ :check
29
+ end
30
+
31
+ def default_check_name
32
+ "chk_mv_#{table_name}_#{column_name}" if check?
33
+ end
34
+
35
+ private
36
+
37
+ def check?
38
+ as.try(:to_sym) == :check
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,11 @@
1
+ require 'mv/postgresql/validation/check_support'
2
+
3
+ module Mv
4
+ module Postgresql
5
+ module Validation
6
+ class Exclusion < Mv::Core::Validation::Exclusion
7
+ include CheckSupport
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ require 'mv/postgresql/validation/check_support'
2
+
3
+ module Mv
4
+ module Postgresql
5
+ module Validation
6
+ class Format < Mv::Core::Validation::Base
7
+ include CheckSupport
8
+
9
+ attr_reader :with
10
+
11
+ validates :with, presence: true
12
+
13
+ def initialize(table_name, column_name, opts)
14
+ super(table_name, column_name, opts)
15
+
16
+ @with = opts.with_indifferent_access[:with]
17
+ end
18
+
19
+ def to_a
20
+ super + [with.to_s]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ require 'mv/postgresql/validation/check_support'
2
+
3
+ module Mv
4
+ module Postgresql
5
+ module Validation
6
+ class Inclusion < Mv::Core::Validation::Inclusion
7
+ include CheckSupport
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'mv/postgresql/validation/check_support'
2
+
3
+ module Mv
4
+ module Postgresql
5
+ module Validation
6
+ class Length < Mv::Core::Validation::Length
7
+ include CheckSupport
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'mv/postgresql/validation/check_support'
2
+
3
+ module Mv
4
+ module Postgresql
5
+ module Validation
6
+ class Presence < Mv::Core::Validation::Presence
7
+ include CheckSupport
8
+ end
9
+ end
10
+ end
11
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mv-postgresql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Valeriy Prokopchuk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-07 00:00:00.000000000 Z
11
+ date: 2015-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '4.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '4.1'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: pg
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -30,14 +44,14 @@ dependencies:
30
44
  requirements:
31
45
  - - ~>
32
46
  - !ruby/object:Gem::Version
33
- version: '1.0'
47
+ version: '2.0'
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - ~>
39
53
  - !ruby/object:Gem::Version
40
- version: '1.0'
54
+ version: '2.0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: jeweler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -52,18 +66,97 @@ dependencies:
52
66
  - - ~>
53
67
  - !ruby/object:Gem::Version
54
68
  version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '3.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '3.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-its
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '1.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '1.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: guard-rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '4.5'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '4.5'
111
+ - !ruby/object:Gem::Dependency
112
+ name: shoulda
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '3.5'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: '3.5'
55
125
  description: Migration Validators project postgresql driver
56
126
  email: vprokopchuk@gmail.com
57
127
  executables: []
58
128
  extensions: []
59
129
  extra_rdoc_files:
60
130
  - LICENSE.txt
61
- - README.rdoc
131
+ - README.md
62
132
  files:
63
133
  - LICENSE.txt
64
- - README.rdoc
65
- - lib/migration_validators/adapters/postgresql.rb
134
+ - README.md
66
135
  - lib/mv-postgresql.rb
136
+ - lib/mv/postgresql/active_record/connection_adapters/postgresql_adapter_decorator.rb
137
+ - lib/mv/postgresql/constraint/builder/check.rb
138
+ - lib/mv/postgresql/constraint/builder/trigger.rb
139
+ - lib/mv/postgresql/constraint/check.rb
140
+ - lib/mv/postgresql/railtie.rb
141
+ - lib/mv/postgresql/route/check.rb
142
+ - lib/mv/postgresql/validation/absence.rb
143
+ - lib/mv/postgresql/validation/builder/exclusion.rb
144
+ - lib/mv/postgresql/validation/builder/format.rb
145
+ - lib/mv/postgresql/validation/builder/inclusion.rb
146
+ - lib/mv/postgresql/validation/builder/trigger/absence.rb
147
+ - lib/mv/postgresql/validation/builder/trigger/exclusion.rb
148
+ - lib/mv/postgresql/validation/builder/trigger/format.rb
149
+ - lib/mv/postgresql/validation/builder/trigger/inclusion.rb
150
+ - lib/mv/postgresql/validation/builder/trigger/length.rb
151
+ - lib/mv/postgresql/validation/builder/trigger/presence.rb
152
+ - lib/mv/postgresql/validation/builder/trigger/trigger_column.rb
153
+ - lib/mv/postgresql/validation/builder/trigger/uniqueness.rb
154
+ - lib/mv/postgresql/validation/check_support.rb
155
+ - lib/mv/postgresql/validation/exclusion.rb
156
+ - lib/mv/postgresql/validation/format.rb
157
+ - lib/mv/postgresql/validation/inclusion.rb
158
+ - lib/mv/postgresql/validation/length.rb
159
+ - lib/mv/postgresql/validation/presence.rb
67
160
  homepage: http://github.com/vprokopchuk256/mv-postgresql
68
161
  licenses:
69
162
  - MIT
@@ -84,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
177
  version: '0'
85
178
  requirements: []
86
179
  rubyforge_project:
87
- rubygems_version: 2.4.2
180
+ rubygems_version: 2.4.4
88
181
  signing_key:
89
182
  specification_version: 4
90
183
  summary: Migration Validators project postgresql driver
@@ -1,146 +0,0 @@
1
- module MigrationValidators
2
- module Adapters
3
- class Postgresql < MigrationValidators::Adapters::Base
4
- def name
5
- "PostgreSQL Migration Validators Adapter"
6
- end
7
-
8
- define_base_syntax
9
- syntax do
10
- operation(:regexp) {|stmt, value| "#{stmt} ~ #{value}"}
11
- operation :db_value do |value|
12
- case value.class.name
13
- when "String" then "'#{value}'"
14
- when "Date" then "'#{value.strftime('%Y-%m-%d')}' "
15
- when "DateTime" then "'#{value.strftime('%Y-%m-%d %H:%M:%S')}'"
16
- when "Time" then "'#{value.strftime('%Y-%m-%d %H:%M:%S')}' "
17
- when "Regexp" then "'#{value.source}'"
18
- else value.to_s
19
- end
20
- end
21
- end
22
-
23
- define_base_validators
24
-
25
- define_base_containers
26
- container :insert_trigger do
27
- operation :create do |stmt, trigger_name, group_name|
28
- func_name = "#{trigger_name}_func"
29
-
30
- "CREATE OR REPLACE FUNCTION #{func_name}() RETURNS TRIGGER AS $#{func_name}$
31
- BEGIN
32
- #{stmt};
33
-
34
- RETURN NEW;
35
- END;
36
- $#{func_name}$ LANGUAGE plpgsql;
37
-
38
- CREATE TRIGGER #{trigger_name} BEFORE INSERT ON #{group_name.first}
39
- FOR EACH ROW EXECUTE PROCEDURE #{func_name}();"
40
- end
41
-
42
- operation :drop do |stmt, trigger_name, group_name|
43
- "DROP TRIGGER IF EXISTS #{trigger_name} ON #{group_name.first};"
44
- end
45
-
46
-
47
- operation :bind_to_error do |stmt, error_message|
48
- "IF NOT(#{stmt}) THEN
49
- RAISE EXCEPTION '#{error_message}';
50
- END IF"
51
- end
52
- end
53
-
54
- container :update_trigger do
55
- operation :create do |stmt, trigger_name, group_name|
56
- func_name = "#{trigger_name}_func"
57
-
58
- "CREATE OR REPLACE FUNCTION #{func_name}() RETURNS TRIGGER AS $#{func_name}$
59
- BEGIN
60
- #{stmt};
61
-
62
- RETURN NEW;
63
- END;
64
- $#{func_name}$ LANGUAGE plpgsql;
65
-
66
- CREATE TRIGGER #{trigger_name} BEFORE UPDATE ON #{group_name.first}
67
- FOR EACH ROW EXECUTE PROCEDURE #{func_name}();"
68
- end
69
-
70
- operation :drop do |stmt, trigger_name, group_name|
71
- func_name = "#{trigger_name}_func"
72
-
73
- "DROP TRIGGER IF EXISTS #{trigger_name} ON #{group_name.first};
74
- DROP FUNCTION IF EXISTS #{func_name}();"
75
- end
76
-
77
- operation :bind_to_error do |stmt, error_message|
78
- "IF NOT(#{stmt}) THEN
79
- RAISE EXCEPTION '#{error_message}';
80
- END IF"
81
- end
82
- end
83
-
84
- container :check do
85
- operation :drop do |stmt, check_name, group_name|
86
- "CREATE OR REPLACE FUNCTION __temporary_constraint_drop_function__() RETURNS INTEGER AS $$
87
- DECLARE
88
- constraint_rec RECORD;
89
- BEGIN
90
- SELECT INTO constraint_rec * FROM pg_constraint WHERE conname='#{check_name}' AND contype='c';
91
-
92
- IF FOUND THEN
93
- ALTER TABLE #{group_name.first} DROP CONSTRAINT #{check_name};
94
- END IF;
95
-
96
- RETURN 1;
97
- END;
98
- $$ LANGUAGE plpgsql;
99
-
100
- SELECT __temporary_constraint_drop_function__();
101
-
102
- DROP FUNCTION __temporary_constraint_drop_function__();
103
- "
104
- end
105
- end
106
-
107
-
108
- route :presence, :trigger do
109
- to :insert_trigger, :if => {:on => [:save, :create, nil]}
110
- to :update_trigger, :if => {:on => [:save, :update, nil]}
111
- end
112
- route :presence, :check, :to => :check, :default => true
113
-
114
- route :inclusion, :trigger do
115
- to :insert_trigger, :if => {:on => [:save, :create, nil]}
116
- to :update_trigger, :if => {:on => [:save, :update, nil]}
117
- end
118
- route :inclusion, :check, :to => :check, :default => true
119
-
120
- route :exclusion, :trigger do
121
- to :insert_trigger, :if => {:on => [:save, :create, nil]}
122
- to :update_trigger, :if => {:on => [:save, :update, nil]}
123
- end
124
- route :exclusion, :check, :to => :check, :default => true
125
-
126
- route :length, :trigger do
127
- to :insert_trigger, :if => {:on => [:save, :create, nil]}
128
- to :update_trigger, :if => {:on => [:save, :update, nil]}
129
- end
130
- route :length, :check, :to => :check, :default => true
131
-
132
- route :format, :trigger do
133
- to :insert_trigger, :if => {:on => [:save, :create, nil]}
134
- to :update_trigger, :if => {:on => [:save, :update, nil]}
135
- end
136
- route :format, :check, :to => :check, :default => true
137
-
138
- route :uniqueness, :trigger do
139
- to :insert_trigger, :if => {:on => [:save, :create, nil]}
140
- to :update_trigger, :if => {:on => [:save, :update, nil]}
141
- end
142
- end
143
-
144
- MigrationValidators.register_adapter! "postgresql", Postgresql
145
- end
146
- end