rein 3.2.0 → 3.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +77 -32
- data/lib/rein.rb +14 -12
- data/lib/rein/constraint/foreign_key.rb +12 -12
- data/lib/rein/constraint/inclusion.rb +6 -6
- data/lib/rein/constraint/length.rb +8 -8
- data/lib/rein/constraint/match.rb +8 -8
- data/lib/rein/constraint/null.rb +5 -5
- data/lib/rein/constraint/numericality.rb +8 -8
- data/lib/rein/constraint/presence.rb +5 -5
- data/lib/rein/constraint/primary_key.rb +4 -4
- data/lib/rein/constraint/unique.rb +41 -0
- data/lib/rein/schema.rb +2 -2
- data/lib/rein/type/enum.rb +4 -4
- data/lib/rein/version.rb +1 -1
- data/lib/rein/view.rb +2 -2
- metadata +11 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c092acce07a6896465dbff427aa22bbac84a4b9
|
4
|
+
data.tar.gz: 7cdc3ad273b86b172930826e82264d29c938326a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 591a05bf15e0857934e00ec98cc91644fed9d5ba5d793dfd8216e9cf51b5ecf797e16f7e78cd43aaef887299b079b7d0c2702c4210f742b38e385c604083b378
|
7
|
+
data.tar.gz: cd84ac0a68c41f37969debd3c719e502750f002725287f72a2e829bcce58a998239935d503144553d7d5ab48444c2675a335913e72472b36754aa95532f2f7bb
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -15,27 +15,26 @@ can easily tame the data in your database.
|
|
15
15
|
All methods in the DSL are automatically *reversible*, so you can take
|
16
16
|
advantage of reversible Rails migrations.
|
17
17
|
|
18
|
-
## Table of
|
19
|
-
|
20
|
-
* [
|
21
|
-
|
22
|
-
* [
|
23
|
-
* [
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
* [
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
## Getting started
|
18
|
+
## Table of Contents
|
19
|
+
|
20
|
+
* [Getting Started](#getting-started)
|
21
|
+
* [Constraint Types](#constraint-types)
|
22
|
+
* [Foreign Key Constraints](#foreign-key-constraints)
|
23
|
+
* [Unique Constraints](#unique-constraints)
|
24
|
+
* [Inclusion Constraints](#inclusion-constraints)
|
25
|
+
* [Length Constraints](#length-constraints)
|
26
|
+
* [Match Constraints](#match-constraints)
|
27
|
+
* [Numericality Constraints](#numericality-constraints)
|
28
|
+
* [Presence Constraints](#presence-constraints)
|
29
|
+
* [Null Constraints](#null-constraints)
|
30
|
+
* [Data Types](#data-types)
|
31
|
+
* [Enumerated Types](#enumerated-types)
|
32
|
+
* [Views](#views)
|
33
|
+
* [Schemas](#schemas)
|
34
|
+
* [Examples](#examples)
|
35
|
+
* [License](#license)
|
36
|
+
|
37
|
+
## Getting Started
|
39
38
|
|
40
39
|
Install the gem:
|
41
40
|
|
@@ -58,9 +57,9 @@ class CreateAuthorsTable < ActiveRecord::Migration
|
|
58
57
|
end
|
59
58
|
```
|
60
59
|
|
61
|
-
## Constraint
|
60
|
+
## Constraint Types
|
62
61
|
|
63
|
-
### Foreign
|
62
|
+
### Foreign Key Constraints
|
64
63
|
|
65
64
|
A foreign key constraint specifies that the values in a column must match the
|
66
65
|
values appearing in some row of another table.
|
@@ -113,7 +112,53 @@ To remove a foreign key constraint:
|
|
113
112
|
remove_foreign_key_constraint :books, :authors
|
114
113
|
```
|
115
114
|
|
116
|
-
###
|
115
|
+
### Unique Constraints
|
116
|
+
|
117
|
+
A unique constraint specifies that certain columns in a table must be unique.
|
118
|
+
|
119
|
+
For example, all the books should have unique ISBNs:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
add_unique_constraint :books, :isbn
|
123
|
+
```
|
124
|
+
|
125
|
+
By default, the database checks unique constraints immediately (i.e. as soon as
|
126
|
+
a record is created or updated). If a record with a duplicate value exists,
|
127
|
+
then the database will raise an error.
|
128
|
+
|
129
|
+
Sometimes it is necessary to wait until the end of a transaction to do the
|
130
|
+
checking (e.g. maybe you want to swap the ISBNs for two books). To do so, you
|
131
|
+
need to tell the database to *defer* checking the constraint until the end of
|
132
|
+
the current transaction:
|
133
|
+
|
134
|
+
```sql
|
135
|
+
BEGIN;
|
136
|
+
SET CONSTRAINTS books_isbn_unique DEFERRED;
|
137
|
+
UPDATE books SET isbn = 'foo' WHERE id = 1;
|
138
|
+
UPDATE books SET isbn = 'bar' WHERE id = 2;
|
139
|
+
COMMIT;
|
140
|
+
```
|
141
|
+
|
142
|
+
This [blog
|
143
|
+
post](https://hashrocket.com/blog/posts/deferring-database-constraints) offers
|
144
|
+
a good explanation of how to do this in a Rails app when using the
|
145
|
+
`acts_as_list` plugin.
|
146
|
+
|
147
|
+
If you *always* want to defer checking a unique constraint, then you can set
|
148
|
+
the `deferred` option to `true`:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
add_unique_constraint :books, :isbn, deferred: true
|
152
|
+
```
|
153
|
+
|
154
|
+
If you really don't want the ability to optionally defer a unique constraint in
|
155
|
+
a transaction, then you can set the `deferrable` option to `false`:
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
add_unique_constraint :authors, :name, deferrable: false
|
159
|
+
```
|
160
|
+
|
161
|
+
### Inclusion Constraints
|
117
162
|
|
118
163
|
An inclusion constraint specifies the possible values that a column value can
|
119
164
|
take.
|
@@ -148,7 +193,7 @@ add_inclusion_constraint :books, :state,
|
|
148
193
|
name: "books_state_is_valid"
|
149
194
|
```
|
150
195
|
|
151
|
-
### Length
|
196
|
+
### Length Constraints
|
152
197
|
|
153
198
|
A length constraint specifies the range of values that the length of a string
|
154
199
|
column value can take.
|
@@ -196,7 +241,7 @@ To remove a length constraint:
|
|
196
241
|
remove_length_constraint :books, :call_number
|
197
242
|
```
|
198
243
|
|
199
|
-
### Match
|
244
|
+
### Match Constraints
|
200
245
|
|
201
246
|
A match constraint ensures that a string column value matches (or does not match)
|
202
247
|
a POSIX-style regular expression.
|
@@ -227,7 +272,7 @@ To remove a match constraint:
|
|
227
272
|
remove_match_constraint :books, :title
|
228
273
|
```
|
229
274
|
|
230
|
-
### Numericality
|
275
|
+
### Numericality Constraints
|
231
276
|
|
232
277
|
A numericality constraint specifies the range of values that a numeric column
|
233
278
|
value can take.
|
@@ -275,7 +320,7 @@ To remove a numericality constraint:
|
|
275
320
|
remove_numericality_constraint :books, :publication_month
|
276
321
|
```
|
277
322
|
|
278
|
-
### Presence
|
323
|
+
### Presence Constraints
|
279
324
|
|
280
325
|
A presence constraint ensures that a string column value is non-empty.
|
281
326
|
|
@@ -305,7 +350,7 @@ To remove a presence constraint:
|
|
305
350
|
remove_presence_constraint :books, :title
|
306
351
|
```
|
307
352
|
|
308
|
-
### Null
|
353
|
+
### Null Constraints
|
309
354
|
|
310
355
|
A null constraint ensures that a column does *not* contain a null value. This
|
311
356
|
is the same as adding `NOT NULL` to a column, the difference being that it can
|
@@ -324,9 +369,9 @@ To remove a null constraint:
|
|
324
369
|
remove_null_constraint :books, :due_date
|
325
370
|
```
|
326
371
|
|
327
|
-
## Data
|
372
|
+
## Data Types
|
328
373
|
|
329
|
-
### Enumerated
|
374
|
+
### Enumerated Types
|
330
375
|
|
331
376
|
An enum is a data type that represents a static, ordered set of values.
|
332
377
|
|
@@ -374,7 +419,7 @@ To drop a schema from the database:
|
|
374
419
|
drop_schema :archive
|
375
420
|
```
|
376
421
|
|
377
|
-
##
|
422
|
+
## Examples
|
378
423
|
|
379
424
|
Let's have a look at some example migrations to constrain database values for
|
380
425
|
our simple library application:
|
data/lib/rein.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
1
|
+
require 'active_record'
|
2
|
+
require 'rein/constraint/foreign_key'
|
3
|
+
require 'rein/constraint/inclusion'
|
4
|
+
require 'rein/constraint/length'
|
5
|
+
require 'rein/constraint/match'
|
6
|
+
require 'rein/constraint/null'
|
7
|
+
require 'rein/constraint/numericality'
|
8
|
+
require 'rein/constraint/presence'
|
9
|
+
require 'rein/constraint/primary_key'
|
10
|
+
require 'rein/constraint/unique'
|
11
|
+
require 'rein/schema'
|
12
|
+
require 'rein/type/enum'
|
13
|
+
require 'rein/view'
|
13
14
|
|
14
15
|
module ActiveRecord
|
15
16
|
class Migration # :nodoc:
|
@@ -21,6 +22,7 @@ module ActiveRecord
|
|
21
22
|
include Rein::Constraint::Numericality
|
22
23
|
include Rein::Constraint::Presence
|
23
24
|
include Rein::Constraint::PrimaryKey
|
25
|
+
include Rein::Constraint::Unique
|
24
26
|
include Rein::Schema
|
25
27
|
include Rein::Type::Enum
|
26
28
|
include Rein::View
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'active_support/inflector'
|
2
|
+
require 'rein/util'
|
3
3
|
|
4
4
|
module Rein
|
5
5
|
module Constraint
|
@@ -7,14 +7,14 @@ module Rein
|
|
7
7
|
module ForeignKey
|
8
8
|
def add_foreign_key_constraint(*args)
|
9
9
|
reversible do |dir|
|
10
|
-
dir.up
|
10
|
+
dir.up do _add_foreign_key_constraint(*args) end
|
11
11
|
dir.down { _remove_foreign_key_constraint(*args) }
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
def remove_foreign_key_constraint(*args)
|
16
16
|
reversible do |dir|
|
17
|
-
dir.up
|
17
|
+
dir.up do _remove_foreign_key_constraint(*args) end
|
18
18
|
dir.down { _add_foreign_key_constraint(*args) }
|
19
19
|
end
|
20
20
|
end
|
@@ -23,8 +23,8 @@ module Rein
|
|
23
23
|
|
24
24
|
def _add_foreign_key_constraint(referencing_table, referenced_table, options = {})
|
25
25
|
referencing_attribute = (options[:referencing] || "#{referenced_table.to_s.singularize}_id").to_sym
|
26
|
-
referenced_attribute = (options[:referenced] ||
|
27
|
-
name = Util.constraint_name(referencing_table, referencing_attribute,
|
26
|
+
referenced_attribute = (options[:referenced] || 'id').to_sym
|
27
|
+
name = Util.constraint_name(referencing_table, referencing_attribute, 'fk', options)
|
28
28
|
sql = "ALTER TABLE #{referencing_table}"
|
29
29
|
sql << " ADD CONSTRAINT #{name}"
|
30
30
|
sql << " FOREIGN KEY (#{referencing_attribute})"
|
@@ -37,18 +37,18 @@ module Rein
|
|
37
37
|
|
38
38
|
def _remove_foreign_key_constraint(referencing_table, referenced_table, options = {})
|
39
39
|
referencing_attribute = options[:referencing] || "#{referenced_table.to_s.singularize}_id".to_sym
|
40
|
-
name = Util.constraint_name(referencing_table, referencing_attribute,
|
40
|
+
name = Util.constraint_name(referencing_table, referencing_attribute, 'fk', options)
|
41
41
|
execute("ALTER TABLE #{referencing_table} DROP CONSTRAINT #{name}")
|
42
42
|
remove_index(referencing_table, referencing_attribute) if options[:index] == true
|
43
43
|
end
|
44
44
|
|
45
45
|
def referential_action(action)
|
46
46
|
case action.to_sym
|
47
|
-
when :no_action then
|
48
|
-
when :cascade then
|
49
|
-
when :restrict then
|
50
|
-
when :set_null, :nullify then
|
51
|
-
when :set_default, :default then
|
47
|
+
when :no_action then 'NO ACTION'
|
48
|
+
when :cascade then 'CASCADE'
|
49
|
+
when :restrict then 'RESTRICT'
|
50
|
+
when :set_null, :nullify then 'SET NULL'
|
51
|
+
when :set_default, :default then 'SET DEFAULT'
|
52
52
|
else raise "Unknown referential action '#{action}'"
|
53
53
|
end
|
54
54
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'rein/util'
|
2
2
|
|
3
3
|
module Rein
|
4
4
|
module Constraint
|
@@ -8,14 +8,14 @@ module Rein
|
|
8
8
|
|
9
9
|
def add_inclusion_constraint(*args)
|
10
10
|
reversible do |dir|
|
11
|
-
dir.up
|
11
|
+
dir.up do _add_inclusion_constraint(*args) end
|
12
12
|
dir.down { _remove_inclusion_constraint(*args) }
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
def remove_inclusion_constraint(*args)
|
17
17
|
reversible do |dir|
|
18
|
-
dir.up
|
18
|
+
dir.up do _remove_inclusion_constraint(*args) end
|
19
19
|
dir.down { _add_inclusion_constraint(*args) }
|
20
20
|
end
|
21
21
|
end
|
@@ -23,14 +23,14 @@ module Rein
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def _add_inclusion_constraint(table, attribute, options = {})
|
26
|
-
name = Util.constraint_name(table, attribute,
|
27
|
-
values = options[:in].map { |value| quote(value) }.join(
|
26
|
+
name = Util.constraint_name(table, attribute, 'inclusion', options)
|
27
|
+
values = options[:in].map { |value| quote(value) }.join(', ')
|
28
28
|
conditions = Util.conditions_with_if("#{attribute} IN (#{values})", options)
|
29
29
|
execute("ALTER TABLE #{table} ADD CONSTRAINT #{name} CHECK (#{conditions})")
|
30
30
|
end
|
31
31
|
|
32
32
|
def _remove_inclusion_constraint(table, attribute, options = {})
|
33
|
-
name = Util.constraint_name(table, attribute,
|
33
|
+
name = Util.constraint_name(table, attribute, 'inclusion', options)
|
34
34
|
execute("ALTER TABLE #{table} DROP CONSTRAINT #{name}")
|
35
35
|
end
|
36
36
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'rein/util'
|
2
2
|
|
3
3
|
module Rein
|
4
4
|
module Constraint
|
@@ -15,14 +15,14 @@ module Rein
|
|
15
15
|
|
16
16
|
def add_length_constraint(*args)
|
17
17
|
reversible do |dir|
|
18
|
-
dir.up
|
18
|
+
dir.up do _add_length_constraint(*args) end
|
19
19
|
dir.down { _remove_length_constraint(*args) }
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def remove_length_constraint(*args)
|
24
24
|
reversible do |dir|
|
25
|
-
dir.up
|
25
|
+
dir.up do _remove_length_constraint(*args) end
|
26
26
|
dir.down { _add_length_constraint(*args) }
|
27
27
|
end
|
28
28
|
end
|
@@ -30,18 +30,18 @@ module Rein
|
|
30
30
|
private
|
31
31
|
|
32
32
|
def _add_length_constraint(table, attribute, options = {})
|
33
|
-
name = Util.constraint_name(table, attribute,
|
33
|
+
name = Util.constraint_name(table, attribute, 'length', options)
|
34
34
|
attribute_length = "length(#{attribute})"
|
35
|
-
conditions = OPERATORS.slice(*options.keys).map
|
35
|
+
conditions = OPERATORS.slice(*options.keys).map { |key, operator|
|
36
36
|
value = options[key]
|
37
|
-
[attribute_length, operator, value].join(
|
38
|
-
|
37
|
+
[attribute_length, operator, value].join(' ')
|
38
|
+
}.join(' AND ')
|
39
39
|
conditions = Util.conditions_with_if(conditions, options)
|
40
40
|
execute("ALTER TABLE #{table} ADD CONSTRAINT #{name} CHECK (#{conditions})")
|
41
41
|
end
|
42
42
|
|
43
43
|
def _remove_length_constraint(table, attribute, options = {})
|
44
|
-
name = Util.constraint_name(table, attribute,
|
44
|
+
name = Util.constraint_name(table, attribute, 'length', options)
|
45
45
|
execute("ALTER TABLE #{table} DROP CONSTRAINT #{name}")
|
46
46
|
end
|
47
47
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'rein/util'
|
2
2
|
|
3
3
|
module Rein
|
4
4
|
module Constraint
|
@@ -13,14 +13,14 @@ module Rein
|
|
13
13
|
|
14
14
|
def add_match_constraint(*args)
|
15
15
|
reversible do |dir|
|
16
|
-
dir.up
|
16
|
+
dir.up do _add_match_constraint(*args) end
|
17
17
|
dir.down { _remove_match_constraint(*args) }
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
def remove_match_constraint(*args)
|
22
22
|
reversible do |dir|
|
23
|
-
dir.up
|
23
|
+
dir.up do _remove_match_constraint(*args) end
|
24
24
|
dir.down { _add_match_constraint(*args) }
|
25
25
|
end
|
26
26
|
end
|
@@ -28,17 +28,17 @@ module Rein
|
|
28
28
|
private
|
29
29
|
|
30
30
|
def _add_match_constraint(table, attribute, options = {})
|
31
|
-
name = Util.constraint_name(table, attribute,
|
32
|
-
conditions = OPERATORS.slice(*options.keys).map
|
31
|
+
name = Util.constraint_name(table, attribute, 'match', options)
|
32
|
+
conditions = OPERATORS.slice(*options.keys).map { |key, operator|
|
33
33
|
value = options[key]
|
34
|
-
[attribute, operator, "'#{value}'"].join(
|
35
|
-
|
34
|
+
[attribute, operator, "'#{value}'"].join(' ')
|
35
|
+
}.join(' AND ')
|
36
36
|
conditions = Util.conditions_with_if(conditions, options)
|
37
37
|
execute("ALTER TABLE #{table} ADD CONSTRAINT #{name} CHECK (#{conditions})")
|
38
38
|
end
|
39
39
|
|
40
40
|
def _remove_match_constraint(table, attribute, options = {})
|
41
|
-
name = Util.constraint_name(table, attribute,
|
41
|
+
name = Util.constraint_name(table, attribute, 'match', options)
|
42
42
|
execute("ALTER TABLE #{table} DROP CONSTRAINT #{name}")
|
43
43
|
end
|
44
44
|
end
|
data/lib/rein/constraint/null.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'rein/util'
|
2
2
|
|
3
3
|
module Rein
|
4
4
|
module Constraint
|
@@ -8,14 +8,14 @@ module Rein
|
|
8
8
|
|
9
9
|
def add_null_constraint(*args)
|
10
10
|
reversible do |dir|
|
11
|
-
dir.up
|
11
|
+
dir.up do _add_null_constraint(*args) end
|
12
12
|
dir.down { _remove_null_constraint(*args) }
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
def remove_null_constraint(*args)
|
17
17
|
reversible do |dir|
|
18
|
-
dir.up
|
18
|
+
dir.up do _remove_null_constraint(*args) end
|
19
19
|
dir.down { _add_null_constraint(*args) }
|
20
20
|
end
|
21
21
|
end
|
@@ -23,13 +23,13 @@ module Rein
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def _add_null_constraint(table, attribute, options = {})
|
26
|
-
name = Util.constraint_name(table, attribute,
|
26
|
+
name = Util.constraint_name(table, attribute, 'null', options)
|
27
27
|
conditions = Util.conditions_with_if("#{attribute} IS NOT NULL", options)
|
28
28
|
execute("ALTER TABLE #{table} ADD CONSTRAINT #{name} CHECK (#{conditions})")
|
29
29
|
end
|
30
30
|
|
31
31
|
def _remove_null_constraint(table, attribute, options = {})
|
32
|
-
name = Util.constraint_name(table, attribute,
|
32
|
+
name = Util.constraint_name(table, attribute, 'null', options)
|
33
33
|
execute("ALTER TABLE #{table} DROP CONSTRAINT #{name}")
|
34
34
|
end
|
35
35
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'rein/util'
|
2
2
|
|
3
3
|
module Rein
|
4
4
|
module Constraint
|
@@ -15,14 +15,14 @@ module Rein
|
|
15
15
|
|
16
16
|
def add_numericality_constraint(*args)
|
17
17
|
reversible do |dir|
|
18
|
-
dir.up
|
18
|
+
dir.up do _add_numericality_constraint(*args) end
|
19
19
|
dir.down { _remove_numericality_constraint(*args) }
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def remove_numericality_constraint(*args)
|
24
24
|
reversible do |dir|
|
25
|
-
dir.up
|
25
|
+
dir.up do _remove_numericality_constraint(*args) end
|
26
26
|
dir.down { _add_numericality_constraint(*args) }
|
27
27
|
end
|
28
28
|
end
|
@@ -30,17 +30,17 @@ module Rein
|
|
30
30
|
private
|
31
31
|
|
32
32
|
def _add_numericality_constraint(table, attribute, options = {})
|
33
|
-
name = Util.constraint_name(table, attribute,
|
34
|
-
conditions = OPERATORS.slice(*options.keys).map
|
33
|
+
name = Util.constraint_name(table, attribute, 'numericality', options)
|
34
|
+
conditions = OPERATORS.slice(*options.keys).map { |key, operator|
|
35
35
|
value = options[key]
|
36
|
-
[attribute, operator, value].join(
|
37
|
-
|
36
|
+
[attribute, operator, value].join(' ')
|
37
|
+
}.join(' AND ')
|
38
38
|
conditions = Util.conditions_with_if(conditions, options)
|
39
39
|
execute("ALTER TABLE #{table} ADD CONSTRAINT #{name} CHECK (#{conditions})")
|
40
40
|
end
|
41
41
|
|
42
42
|
def _remove_numericality_constraint(table, attribute, options = {})
|
43
|
-
name = Util.constraint_name(table, attribute,
|
43
|
+
name = Util.constraint_name(table, attribute, 'numericality', options)
|
44
44
|
execute("ALTER TABLE #{table} DROP CONSTRAINT #{name}")
|
45
45
|
end
|
46
46
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'rein/util'
|
2
2
|
|
3
3
|
module Rein
|
4
4
|
module Constraint
|
@@ -8,14 +8,14 @@ module Rein
|
|
8
8
|
|
9
9
|
def add_presence_constraint(*args)
|
10
10
|
reversible do |dir|
|
11
|
-
dir.up
|
11
|
+
dir.up do _add_presence_constraint(*args) end
|
12
12
|
dir.down { _remove_presence_constraint(*args) }
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
def remove_presence_constraint(*args)
|
17
17
|
reversible do |dir|
|
18
|
-
dir.up
|
18
|
+
dir.up do _remove_presence_constraint(*args) end
|
19
19
|
dir.down { _add_presence_constraint(*args) }
|
20
20
|
end
|
21
21
|
end
|
@@ -23,7 +23,7 @@ module Rein
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def _add_presence_constraint(table, attribute, options = {})
|
26
|
-
name = Util.constraint_name(table, attribute,
|
26
|
+
name = Util.constraint_name(table, attribute, 'presence', options)
|
27
27
|
conditions = Util.conditions_with_if(
|
28
28
|
"(#{attribute} IS NOT NULL) AND (#{attribute} !~ '^\\s*$')",
|
29
29
|
options
|
@@ -32,7 +32,7 @@ module Rein
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def _remove_presence_constraint(table, attribute, options = {})
|
35
|
-
name = Util.constraint_name(table, attribute,
|
35
|
+
name = Util.constraint_name(table, attribute, 'presence', options)
|
36
36
|
execute("ALTER TABLE #{table} DROP CONSTRAINT #{name}")
|
37
37
|
end
|
38
38
|
end
|
@@ -4,14 +4,14 @@ module Rein
|
|
4
4
|
module PrimaryKey
|
5
5
|
def add_primary_key(*args)
|
6
6
|
reversible do |dir|
|
7
|
-
dir.up
|
7
|
+
dir.up do _add_primary_key(*args) end
|
8
8
|
dir.down { _remove_primary_key(*args) }
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
def remove_primary_key(*args)
|
13
13
|
reversible do |dir|
|
14
|
-
dir.up
|
14
|
+
dir.up do _remove_primary_key(*args) end
|
15
15
|
dir.down { _add_primary_key(*args) }
|
16
16
|
end
|
17
17
|
end
|
@@ -19,12 +19,12 @@ module Rein
|
|
19
19
|
private
|
20
20
|
|
21
21
|
def _add_primary_key(table, options = {})
|
22
|
-
attribute = (options[:column] ||
|
22
|
+
attribute = (options[:column] || 'id').to_sym
|
23
23
|
execute("ALTER TABLE #{table} ADD PRIMARY KEY (#{attribute})")
|
24
24
|
end
|
25
25
|
|
26
26
|
def _remove_primary_key(table, options = {})
|
27
|
-
attribute = (options[:column] ||
|
27
|
+
attribute = (options[:column] || 'id').to_sym
|
28
28
|
execute("ALTER TABLE #{table} DROP CONSTRAINT #{attribute}_pkey")
|
29
29
|
end
|
30
30
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rein/util'
|
2
|
+
|
3
|
+
module Rein
|
4
|
+
module Constraint
|
5
|
+
# This module contains methods for defining unique constraints.
|
6
|
+
module Unique
|
7
|
+
include ActiveRecord::ConnectionAdapters::Quoting
|
8
|
+
|
9
|
+
def add_unique_constraint(*args)
|
10
|
+
reversible do |dir|
|
11
|
+
dir.up do _add_unique_constraint(*args) end
|
12
|
+
dir.down { _remove_unique_constraint(*args) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def remove_unique_constraint(*args)
|
17
|
+
reversible do |dir|
|
18
|
+
dir.up do _remove_unique_constraint(*args) end
|
19
|
+
dir.down { _add_unique_constraint(*args) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def _add_unique_constraint(table, attributes, options = {})
|
26
|
+
attributes = [attributes].flatten
|
27
|
+
name = Util.constraint_name(table, attributes.join('_'), 'unique', options)
|
28
|
+
initially = options[:deferred] ? 'DEFERRED' : 'IMMEDIATE'
|
29
|
+
sql = "ALTER TABLE #{table} ADD CONSTRAINT #{name} UNIQUE (#{attributes.join(', ')})"
|
30
|
+
sql << " DEFERRABLE INITIALLY #{initially}" unless options[:deferrable] == false
|
31
|
+
execute(sql)
|
32
|
+
end
|
33
|
+
|
34
|
+
def _remove_unique_constraint(table, attributes, options = {})
|
35
|
+
attributes = [attributes].flatten
|
36
|
+
name = Util.constraint_name(table, attributes.join('_'), 'unique', options)
|
37
|
+
execute("ALTER TABLE #{table} DROP CONSTRAINT #{name}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/rein/schema.rb
CHANGED
@@ -3,14 +3,14 @@ module Rein
|
|
3
3
|
module Schema
|
4
4
|
def create_schema(*args)
|
5
5
|
reversible do |dir|
|
6
|
-
dir.up
|
6
|
+
dir.up do _create_schema(*args) end
|
7
7
|
dir.down { _drop_schema(*args) }
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
11
|
def drop_schema(*args)
|
12
12
|
reversible do |dir|
|
13
|
-
dir.up
|
13
|
+
dir.up do _drop_schema(*args) end
|
14
14
|
dir.down { _create_schema(*args) }
|
15
15
|
end
|
16
16
|
end
|
data/lib/rein/type/enum.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'active_record/connection_adapters/abstract/quoting'
|
2
2
|
|
3
3
|
module Rein
|
4
4
|
module Type
|
@@ -8,14 +8,14 @@ module Rein
|
|
8
8
|
|
9
9
|
def create_enum_type(*args)
|
10
10
|
reversible do |dir|
|
11
|
-
dir.up
|
11
|
+
dir.up do _create_enum_type(*args) end
|
12
12
|
dir.down { _drop_enum_type(*args) }
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
def drop_enum_type(*args)
|
17
17
|
reversible do |dir|
|
18
|
-
dir.up
|
18
|
+
dir.up do _drop_enum_type(*args) end
|
19
19
|
dir.down { _create_enum_type(*args) }
|
20
20
|
end
|
21
21
|
end
|
@@ -27,7 +27,7 @@ module Rein
|
|
27
27
|
private
|
28
28
|
|
29
29
|
def _create_enum_type(enum_name, enum_values = [])
|
30
|
-
enum_values = enum_values.map { |value| quote(value) }.join(
|
30
|
+
enum_values = enum_values.map { |value| quote(value) }.join(', ')
|
31
31
|
execute("CREATE TYPE #{enum_name} AS ENUM (#{enum_values})")
|
32
32
|
end
|
33
33
|
|
data/lib/rein/version.rb
CHANGED
data/lib/rein/view.rb
CHANGED
@@ -3,14 +3,14 @@ module Rein
|
|
3
3
|
module View
|
4
4
|
def create_view(*args)
|
5
5
|
reversible do |dir|
|
6
|
-
dir.up
|
6
|
+
dir.up do _create_view(*args) end
|
7
7
|
dir.down { _drop_view(*args) }
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
11
|
def drop_view(*args)
|
12
12
|
reversible do |dir|
|
13
|
-
dir.up
|
13
|
+
dir.up do _drop_view(*args) end
|
14
14
|
dir.down { _create_view(*args) }
|
15
15
|
end
|
16
16
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rein
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Bassett
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -56,56 +56,56 @@ dependencies:
|
|
56
56
|
requirements:
|
57
57
|
- - "~>"
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: '2.
|
59
|
+
version: '2.2'
|
60
60
|
type: :development
|
61
61
|
prerelease: false
|
62
62
|
version_requirements: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
64
|
- - "~>"
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: '2.
|
66
|
+
version: '2.2'
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
68
|
name: bundler
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
70
70
|
requirements:
|
71
71
|
- - "~>"
|
72
72
|
- !ruby/object:Gem::Version
|
73
|
-
version: '1.
|
73
|
+
version: '1.16'
|
74
74
|
type: :development
|
75
75
|
prerelease: false
|
76
76
|
version_requirements: !ruby/object:Gem::Requirement
|
77
77
|
requirements:
|
78
78
|
- - "~>"
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: '1.
|
80
|
+
version: '1.16'
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: pg
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
84
84
|
requirements:
|
85
85
|
- - "~>"
|
86
86
|
- !ruby/object:Gem::Version
|
87
|
-
version: '0.
|
87
|
+
version: '0.21'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
90
|
version_requirements: !ruby/object:Gem::Requirement
|
91
91
|
requirements:
|
92
92
|
- - "~>"
|
93
93
|
- !ruby/object:Gem::Version
|
94
|
-
version: '0.
|
94
|
+
version: '0.21'
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
96
|
name: rake
|
97
97
|
requirement: !ruby/object:Gem::Requirement
|
98
98
|
requirements:
|
99
99
|
- - "~>"
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version: '12.
|
101
|
+
version: '12.3'
|
102
102
|
type: :development
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
106
|
- - "~>"
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version: '12.
|
108
|
+
version: '12.3'
|
109
109
|
- !ruby/object:Gem::Dependency
|
110
110
|
name: rspec
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
@@ -153,6 +153,7 @@ files:
|
|
153
153
|
- lib/rein/constraint/numericality.rb
|
154
154
|
- lib/rein/constraint/presence.rb
|
155
155
|
- lib/rein/constraint/primary_key.rb
|
156
|
+
- lib/rein/constraint/unique.rb
|
156
157
|
- lib/rein/schema.rb
|
157
158
|
- lib/rein/type/enum.rb
|
158
159
|
- lib/rein/util.rb
|