rein 0.8.3 → 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.
- checksums.yaml +7 -0
- data/.gitignore +1 -1
- data/.rspec +2 -1
- data/.rubocop.yml +35 -0
- data/.travis.yml +2 -0
- data/.yardopts +1 -0
- data/LICENSE +1 -1
- data/README.md +12 -24
- data/Rakefile +4 -2
- data/lib/rein.rb +21 -27
- data/lib/rein/constraint/foreign_key.rb +43 -45
- data/lib/rein/constraint/inclusion.rb +12 -9
- data/lib/rein/constraint/numericality.rb +20 -17
- data/lib/rein/constraint/presence.rb +10 -7
- data/lib/rein/constraint/primary_key.rb +9 -6
- data/lib/rein/version.rb +1 -1
- data/lib/rein/view.rb +1 -0
- data/rein.gemspec +20 -22
- metadata +44 -66
- data/spec/rein/constraint/foreign_key_spec.rb +0 -107
- data/spec/rein/constraint/inclusion_spec.rb +0 -23
- data/spec/rein/constraint/numericality_spec.rb +0 -48
- data/spec/rein/constraint/presence_spec.rb +0 -18
- data/spec/rein/constraint/primary_key_spec.rb +0 -18
- data/spec/rein/view_spec.rb +0 -23
- data/spec/spec_helper.rb +0 -17
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: '059c6905ac22b82e4b73c05511b549eec26803f6'
|
4
|
+
data.tar.gz: c77740f464a4d9b203dffabc4afb67a764416206
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8ae2b21f190d38839fbe44a28bea29ab3188ef9411f11c0e691e89a67d1646e31c77489cc8b36dd5560d977791116d57076317bed24467cee6feab554a5badff
|
7
|
+
data.tar.gz: e8c19eb0e51beb7d11a47198a26564692418bf65256e8382bfc87f6aa079f1ec568aacd4c050326455e5a7ac1245e1c28cdd161cc8bd521b6d5bad4bd51e2eaa
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
--
|
1
|
+
--format documentation
|
2
|
+
--color
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- "bin/**/*"
|
4
|
+
- "rein.gemspec"
|
5
|
+
|
6
|
+
Metrics/AbcSize:
|
7
|
+
Max: 27
|
8
|
+
|
9
|
+
Metrics/BlockLength:
|
10
|
+
ExcludedMethods: describe
|
11
|
+
|
12
|
+
Metrics/CyclomaticComplexity:
|
13
|
+
Max: 7
|
14
|
+
|
15
|
+
Metrics/LineLength:
|
16
|
+
Enabled: false
|
17
|
+
|
18
|
+
Metrics/MethodLength:
|
19
|
+
Max: 11
|
20
|
+
|
21
|
+
Style/BlockDelimiters:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
Style/Documentation:
|
25
|
+
Exclude:
|
26
|
+
- "spec/**/*"
|
27
|
+
|
28
|
+
Style/FrozenStringLiteralComment:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Style/SpaceInsideHashLiteralBraces:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Style/StringLiterals:
|
35
|
+
EnforcedStyle: double_quotes
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,27 +1,19 @@
|
|
1
1
|
# Rein
|
2
2
|
|
3
|
-
Database constraints made easy for ActiveRecord. Rein currently supports
|
4
|
-
|
3
|
+
Database constraints made easy for ActiveRecord. Rein currently supports
|
4
|
+
PostgreSQL and MySQL (foreign keys only).
|
5
5
|
|
6
6
|
## Introduction
|
7
7
|
|
8
|
-
[Database integrity](http://en.wikipedia.org/wiki/Database_integrity) is a
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
## FAQ
|
14
|
-
|
15
|
-
### How is Rein different to other gems like [foreigner](http://github.com/matthuhiggins/foreigner) or [redhillonrails](http://github.com/mlomnicki/redhillonrails_core), which do the same thing?
|
16
|
-
|
17
|
-
If you're using MySQL then there is no difference, Rein should work as a drop-in replacement. If you're using PostgreSQL however, then Rein provides you with extra methods for placing check constraints on your data.
|
18
|
-
|
19
|
-
### If [DHH](http://en.wikipedia.org/wiki/David_Heinemeier_Hansson) wanted my app to have database constraints then Rails would have been born with them?
|
20
|
-
|
21
|
-
Rails is an opinionated piece of software. One opinion is that your database should simply function as a "dumb" container which your application controls. This is the opinion of Rails.
|
22
|
-
|
23
|
-
Another opinion is that your database is actually a powerful [DBMS](http://en.wikipedia.org/wiki/Database_management_system) which has already solved problems like data integrity, and your application should wield this power.
|
8
|
+
[Database integrity](http://en.wikipedia.org/wiki/Database_integrity) is a
|
9
|
+
"good thing". Constraining the allowed values in your database at the
|
10
|
+
database-level (rather than solely at the application-level) is a much more
|
11
|
+
robust way of ensuring your data stays sane.
|
24
12
|
|
13
|
+
Unfortunately, ActiveRecord doesn't encourage (or even allow) you to use
|
14
|
+
database integrity without resorting to hand-crafted SQL. Rein adds a handful
|
15
|
+
of methods to your ActiveRecord migrations so that you can easily tame your
|
16
|
+
database.
|
25
17
|
|
26
18
|
## Quick Start
|
27
19
|
|
@@ -41,7 +33,6 @@ Add an inclusion constraint (PostgreSQL only):
|
|
41
33
|
|
42
34
|
add_inclusion_constraint :books, :state, :in => %w(available on_loan)
|
43
35
|
|
44
|
-
|
45
36
|
## Example
|
46
37
|
|
47
38
|
Let's look at constraining values for this simple library application.
|
@@ -79,9 +70,6 @@ And here we have a table of books:
|
|
79
70
|
# State is always either "available" or "on_loan".
|
80
71
|
add_inclusion_constraint :books, :state, :in => %w(available on_loan)
|
81
72
|
|
73
|
+
## License
|
82
74
|
|
83
|
-
|
84
|
-
|
85
|
-
* [Marcus Crafter](http://github.com/crafterm)
|
86
|
-
* [Tim Lucas](http://github.com/toolmantim)
|
87
|
-
* [Xavier Shay](http://github.com/xaviershay)
|
75
|
+
This project is licensed under the [MIT License](/LICENSE).
|
data/Rakefile
CHANGED
data/lib/rein.rb
CHANGED
@@ -1,13 +1,5 @@
|
|
1
|
-
module Rein
|
2
|
-
module Constraint
|
3
|
-
end
|
4
|
-
end
|
5
|
-
|
6
|
-
RC = Rein::Constraint
|
7
|
-
|
8
1
|
require "active_record"
|
9
|
-
require "
|
10
|
-
require "active_support/inflector"
|
2
|
+
require "active_record/connection_adapters/abstract_mysql_adapter"
|
11
3
|
|
12
4
|
require "rein/constraint/primary_key"
|
13
5
|
require "rein/constraint/foreign_key"
|
@@ -16,25 +8,27 @@ require "rein/constraint/numericality"
|
|
16
8
|
require "rein/constraint/presence"
|
17
9
|
require "rein/view"
|
18
10
|
|
19
|
-
module ActiveRecord
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
11
|
+
module ActiveRecord
|
12
|
+
module ConnectionAdapters # :nodoc:
|
13
|
+
class MysqlAdapter < AbstractAdapter # :nodoc:
|
14
|
+
include Rein::Constraint::PrimaryKey
|
15
|
+
include Rein::Constraint::ForeignKey
|
16
|
+
include Rein::View
|
17
|
+
end
|
25
18
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
19
|
+
class Mysql2Adapter < AbstractMysqlAdapter # :nodoc:
|
20
|
+
include Rein::Constraint::PrimaryKey
|
21
|
+
include Rein::Constraint::ForeignKey
|
22
|
+
include Rein::View
|
23
|
+
end
|
31
24
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
25
|
+
class PostgreSQLAdapter < AbstractAdapter # :nodoc:
|
26
|
+
include Rein::Constraint::PrimaryKey
|
27
|
+
include Rein::Constraint::ForeignKey
|
28
|
+
include Rein::Constraint::Inclusion
|
29
|
+
include Rein::Constraint::Numericality
|
30
|
+
include Rein::Constraint::Presence
|
31
|
+
include Rein::View
|
32
|
+
end
|
39
33
|
end
|
40
34
|
end
|
@@ -1,66 +1,64 @@
|
|
1
|
-
module
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module Rein
|
2
|
+
module Constraint
|
3
|
+
# This module contains methods for defining foreign key constraints.
|
4
|
+
module ForeignKey
|
5
|
+
def add_foreign_key_constraint(referencing_table, referenced_table, options = {})
|
6
|
+
referencing_attribute = (options[:referencing] || "#{referenced_table.to_s.singularize}_id").to_sym
|
7
|
+
referenced_attribute = (options[:referenced] || "id").to_sym
|
6
8
|
|
7
|
-
|
9
|
+
name = options[:name] || default_constraint_name(referencing_table, referencing_attribute)
|
8
10
|
|
9
|
-
|
11
|
+
sql = "ALTER TABLE #{referencing_table}"
|
10
12
|
sql << " ADD CONSTRAINT #{name}"
|
11
13
|
sql << " FOREIGN KEY (#{referencing_attribute})"
|
12
14
|
sql << " REFERENCES #{referenced_table} (#{referenced_attribute})"
|
13
15
|
sql << " ON DELETE #{referential_action(options[:on_delete])}" if options[:on_delete].present?
|
14
16
|
sql << " ON UPDATE #{referential_action(options[:on_update])}" if options[:on_update].present?
|
15
|
-
end
|
16
17
|
|
17
|
-
|
18
|
+
execute(sql)
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
# A foreign key constraint doesn't have an implicit index.
|
21
|
+
add_index(referencing_table, referencing_attribute) if options[:add_index] == true
|
22
|
+
end
|
23
|
+
alias add_foreign_key add_foreign_key_constraint
|
23
24
|
|
24
|
-
|
25
|
-
|
25
|
+
def remove_foreign_key_constraint(referencing_table, referenced_table, options = {})
|
26
|
+
referencing_attribute = options[:referencing] || "#{referenced_table.to_s.singularize}_id".to_sym
|
26
27
|
|
27
|
-
|
28
|
+
name = options[:name] || default_constraint_name(referencing_table, referencing_attribute)
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
if mysql_adapter?
|
31
|
+
execute "ALTER TABLE #{referencing_table} DROP FOREIGN KEY #{name}"
|
32
|
+
else
|
33
|
+
execute "ALTER TABLE #{referencing_table} DROP CONSTRAINT #{name}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# A foreign key constraint doesn't have an implicit index.
|
37
|
+
remove_index(referencing_table, referencing_attribute) if options[:remove_index] == true
|
33
38
|
end
|
39
|
+
alias remove_foreign_key remove_foreign_key_constraint
|
34
40
|
|
35
|
-
|
36
|
-
remove_index(referencing_table, referencing_attribute) if options[:remove_index] == true
|
37
|
-
end
|
38
|
-
alias_method :remove_foreign_key, :remove_foreign_key_constraint
|
41
|
+
private
|
39
42
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
"
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
"SET NULL"
|
51
|
-
when :default
|
52
|
-
"SET DEFAULT"
|
53
|
-
else
|
54
|
-
raise "Unknown referential action '#{action}'"
|
43
|
+
def referential_action(action)
|
44
|
+
case action.to_sym
|
45
|
+
when :no_action then "NO ACTION"
|
46
|
+
when :cascade then "CASCADE"
|
47
|
+
when :restrict then "RESTRICT"
|
48
|
+
when :nullify then "SET NULL"
|
49
|
+
when :default then "SET DEFAULT"
|
50
|
+
else
|
51
|
+
raise "Unknown referential action '#{action}'"
|
52
|
+
end
|
55
53
|
end
|
56
|
-
end
|
57
54
|
|
58
|
-
|
59
|
-
|
60
|
-
|
55
|
+
def mysql_adapter?
|
56
|
+
self.class.to_s =~ /Mysql[2]?Adapter/
|
57
|
+
end
|
61
58
|
|
62
|
-
|
63
|
-
|
59
|
+
def default_constraint_name(referencing_table, referencing_attribute)
|
60
|
+
"#{referencing_table}_#{referencing_attribute}_fk".to_sym
|
61
|
+
end
|
64
62
|
end
|
65
63
|
end
|
66
64
|
end
|
@@ -1,14 +1,17 @@
|
|
1
|
-
require
|
1
|
+
require "active_record/connection_adapters/abstract/quoting"
|
2
2
|
|
3
|
-
module
|
4
|
-
module
|
5
|
-
|
3
|
+
module Rein
|
4
|
+
module Constraint
|
5
|
+
# This module contains methods for defining inclusion constraints.
|
6
|
+
module Inclusion
|
7
|
+
include ActiveRecord::ConnectionAdapters::Quoting
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
def add_inclusion_constraint(table, attribute, options = {})
|
10
|
+
name = "#{table}_#{attribute}"
|
11
|
+
values = options[:in].map { |value| quote(value) }.join(", ")
|
12
|
+
conditions = "#{attribute} IN (#{values})"
|
13
|
+
execute("ALTER TABLE #{table} ADD CONSTRAINT #{name} CHECK (#{conditions})")
|
14
|
+
end
|
12
15
|
end
|
13
16
|
end
|
14
17
|
end
|
@@ -1,23 +1,26 @@
|
|
1
|
-
module
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
module Rein
|
2
|
+
module Constraint
|
3
|
+
# This module contains methods for defining numericality constraints.
|
4
|
+
module Numericality
|
5
|
+
OPERATORS = {
|
6
|
+
greater_than: :>,
|
7
|
+
greater_than_or_equal_to: :>=,
|
8
|
+
equal_to: :"=",
|
9
|
+
not_equal_to: :"!=",
|
10
|
+
less_than: :<,
|
11
|
+
less_than_or_equal_to: :<=
|
12
|
+
}.freeze
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
+
def add_numericality_constraint(table, attribute, options = {})
|
15
|
+
name = "#{table}_#{attribute}"
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
conditions = OPERATORS.slice(*options.keys).map do |key, operator|
|
18
|
+
value = options[key]
|
19
|
+
[attribute, operator, value].join(" ")
|
20
|
+
end.join(" AND ")
|
19
21
|
|
20
|
-
|
22
|
+
execute("ALTER TABLE #{table} ADD CONSTRAINT #{name} CHECK (#{conditions})")
|
23
|
+
end
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
@@ -1,11 +1,14 @@
|
|
1
|
-
module
|
2
|
-
module
|
3
|
-
|
1
|
+
module Rein
|
2
|
+
module Constraint
|
3
|
+
# This module contains methods for defining presence constraints.
|
4
|
+
module Presence
|
5
|
+
include ActiveRecord::ConnectionAdapters::Quoting
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
def add_presence_constraint(table, attribute)
|
8
|
+
name = "#{table}_#{attribute}"
|
9
|
+
conditions = "#{attribute} !~ '^\s*$'"
|
10
|
+
execute("ALTER TABLE #{table} ADD CONSTRAINT #{name} CHECK (#{conditions})")
|
11
|
+
end
|
9
12
|
end
|
10
13
|
end
|
11
14
|
end
|
@@ -1,9 +1,12 @@
|
|
1
|
-
module
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Rein
|
2
|
+
module Constraint
|
3
|
+
# This module contains methods for defining primary key constraints.
|
4
|
+
module PrimaryKey
|
5
|
+
def add_primary_key(table, options = {})
|
6
|
+
attribute = (options[:column] || "id").to_sym
|
7
|
+
sql = "ALTER TABLE #{table} ADD PRIMARY KEY (#{attribute})"
|
8
|
+
execute(sql)
|
9
|
+
end
|
7
10
|
end
|
8
11
|
end
|
9
12
|
end
|
data/lib/rein/version.rb
CHANGED
data/lib/rein/view.rb
CHANGED
data/rein.gemspec
CHANGED
@@ -1,28 +1,26 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
$:.push File.expand_path("../lib", __FILE__)
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
|
5
4
|
require "rein/version"
|
6
5
|
|
7
|
-
Gem::Specification.new do |
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rein"
|
8
|
+
spec.version = Rein::VERSION
|
9
|
+
spec.author = "Joshua Bassett"
|
10
|
+
spec.email = "josh.bassett@gmail.com"
|
11
|
+
spec.summary = "Database constraints made easy for ActiveRecord."
|
12
|
+
spec.description = "Rein adds bunch of methods to your ActiveRecord migrations so you can easily tame your database."
|
13
|
+
spec.homepage = "http://github.com/nullobject/rein"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.require_paths = ["lib"]
|
15
19
|
|
16
|
-
|
20
|
+
spec.add_runtime_dependency "activerecord", ">= 3.2.0"
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
s.add_development_dependency "rake"
|
23
|
-
s.add_development_dependency "rspec"
|
24
|
-
s.add_development_dependency "rr"
|
25
|
-
s.add_development_dependency "simplecov"
|
26
|
-
|
27
|
-
s.add_runtime_dependency "activerecord"
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
23
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.5"
|
25
|
+
spec.add_development_dependency "rubocop", "~> 0.47"
|
28
26
|
end
|
metadata
CHANGED
@@ -1,96 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rein
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
|
-
-
|
7
|
+
- Joshua Bassett
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2017-03-14 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
14
|
+
name: activerecord
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
22
|
-
type: :
|
19
|
+
version: 3.2.0
|
20
|
+
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
26
|
+
version: 3.2.0
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
28
|
+
name: bundler
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
|
-
version: '
|
33
|
+
version: '1.14'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
|
-
version: '
|
40
|
+
version: '1.14'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
42
|
+
name: rake
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
|
-
version: '0'
|
47
|
+
version: '12.0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - "~>"
|
60
53
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
54
|
+
version: '12.0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
56
|
+
name: rspec
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - "~>"
|
68
60
|
- !ruby/object:Gem::Version
|
69
|
-
version: '
|
61
|
+
version: '3.5'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - "~>"
|
76
67
|
- !ruby/object:Gem::Version
|
77
|
-
version: '
|
68
|
+
version: '3.5'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
|
-
name:
|
70
|
+
name: rubocop
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - "~>"
|
84
74
|
- !ruby/object:Gem::Version
|
85
|
-
version: '0'
|
86
|
-
type: :
|
75
|
+
version: '0.47'
|
76
|
+
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - "~>"
|
92
81
|
- !ruby/object:Gem::Version
|
93
|
-
version: '0'
|
82
|
+
version: '0.47'
|
94
83
|
description: Rein adds bunch of methods to your ActiveRecord migrations so you can
|
95
84
|
easily tame your database.
|
96
85
|
email: josh.bassett@gmail.com
|
@@ -98,8 +87,11 @@ executables: []
|
|
98
87
|
extensions: []
|
99
88
|
extra_rdoc_files: []
|
100
89
|
files:
|
101
|
-
- .gitignore
|
102
|
-
- .rspec
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- ".rubocop.yml"
|
93
|
+
- ".travis.yml"
|
94
|
+
- ".yardopts"
|
103
95
|
- Gemfile
|
104
96
|
- LICENSE
|
105
97
|
- README.md
|
@@ -113,42 +105,28 @@ files:
|
|
113
105
|
- lib/rein/version.rb
|
114
106
|
- lib/rein/view.rb
|
115
107
|
- rein.gemspec
|
116
|
-
- spec/rein/constraint/foreign_key_spec.rb
|
117
|
-
- spec/rein/constraint/inclusion_spec.rb
|
118
|
-
- spec/rein/constraint/numericality_spec.rb
|
119
|
-
- spec/rein/constraint/presence_spec.rb
|
120
|
-
- spec/rein/constraint/primary_key_spec.rb
|
121
|
-
- spec/rein/view_spec.rb
|
122
|
-
- spec/spec_helper.rb
|
123
108
|
homepage: http://github.com/nullobject/rein
|
124
|
-
licenses:
|
109
|
+
licenses:
|
110
|
+
- MIT
|
111
|
+
metadata: {}
|
125
112
|
post_install_message:
|
126
113
|
rdoc_options: []
|
127
114
|
require_paths:
|
128
115
|
- lib
|
129
116
|
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
-
none: false
|
131
117
|
requirements:
|
132
|
-
- -
|
118
|
+
- - ">="
|
133
119
|
- !ruby/object:Gem::Version
|
134
120
|
version: '0'
|
135
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
-
none: false
|
137
122
|
requirements:
|
138
|
-
- -
|
123
|
+
- - ">="
|
139
124
|
- !ruby/object:Gem::Version
|
140
125
|
version: '0'
|
141
126
|
requirements: []
|
142
|
-
rubyforge_project:
|
143
|
-
rubygems_version:
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 2.5.2
|
144
129
|
signing_key:
|
145
|
-
specification_version:
|
130
|
+
specification_version: 4
|
146
131
|
summary: Database constraints made easy for ActiveRecord.
|
147
|
-
test_files:
|
148
|
-
- spec/rein/constraint/foreign_key_spec.rb
|
149
|
-
- spec/rein/constraint/inclusion_spec.rb
|
150
|
-
- spec/rein/constraint/numericality_spec.rb
|
151
|
-
- spec/rein/constraint/presence_spec.rb
|
152
|
-
- spec/rein/constraint/primary_key_spec.rb
|
153
|
-
- spec/rein/view_spec.rb
|
154
|
-
- spec/spec_helper.rb
|
132
|
+
test_files: []
|
@@ -1,107 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RC::ForeignKey do
|
4
|
-
let(:adapter) do
|
5
|
-
Class.new do
|
6
|
-
include RC::ForeignKey
|
7
|
-
end.new
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "#add_foreign_key_constraint" do
|
11
|
-
subject { adapter }
|
12
|
-
|
13
|
-
before do
|
14
|
-
stub(adapter).execute
|
15
|
-
stub(adapter).add_index
|
16
|
-
end
|
17
|
-
|
18
|
-
context "with no options" do
|
19
|
-
before { adapter.add_foreign_key_constraint(:books, :people) }
|
20
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_person_id_fk FOREIGN KEY (person_id) REFERENCES people (id)") }
|
21
|
-
end
|
22
|
-
|
23
|
-
context "with a given referencing attribute" do
|
24
|
-
before { adapter.add_foreign_key_constraint(:books, :people, :referencing => :author_id) }
|
25
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_author_id_fk FOREIGN KEY (author_id) REFERENCES people (id)") }
|
26
|
-
end
|
27
|
-
|
28
|
-
context "with a given referenced attribute" do
|
29
|
-
before { adapter.add_foreign_key_constraint(:books, :people, :referenced => :person_id) }
|
30
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_person_id_fk FOREIGN KEY (person_id) REFERENCES people (person_id)") }
|
31
|
-
end
|
32
|
-
|
33
|
-
context "with a given referencing attribute and referenced attribute" do
|
34
|
-
before { adapter.add_foreign_key_constraint(:books, :people, :referencing => :author_id, :referenced => :person_id) }
|
35
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_author_id_fk FOREIGN KEY (author_id) REFERENCES people (person_id)") }
|
36
|
-
end
|
37
|
-
|
38
|
-
context "with a given name" do
|
39
|
-
before { adapter.add_foreign_key_constraint(:books, :people, :name => :foo) }
|
40
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT foo FOREIGN KEY (person_id) REFERENCES people (id)") }
|
41
|
-
end
|
42
|
-
|
43
|
-
context "with a given on delete referential action" do
|
44
|
-
before { adapter.add_foreign_key_constraint(:books, :people, :on_delete => :cascade) }
|
45
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_person_id_fk FOREIGN KEY (person_id) REFERENCES people (id) ON DELETE CASCADE") }
|
46
|
-
end
|
47
|
-
|
48
|
-
context "with a given on update referential action" do
|
49
|
-
before { adapter.add_foreign_key_constraint(:books, :people, :on_update => :cascade) }
|
50
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_person_id_fk FOREIGN KEY (person_id) REFERENCES people (id) ON UPDATE CASCADE") }
|
51
|
-
end
|
52
|
-
|
53
|
-
context "with a 'cascade' on delete and update referential action" do
|
54
|
-
before { adapter.add_foreign_key_constraint(:books, :people, :on_delete => :cascade, :on_update => :cascade) }
|
55
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_person_id_fk FOREIGN KEY (person_id) REFERENCES people (id) ON DELETE CASCADE ON UPDATE CASCADE") }
|
56
|
-
end
|
57
|
-
|
58
|
-
context "with a 'no action' on delete and update referential action" do
|
59
|
-
before { adapter.add_foreign_key_constraint(:books, :people, :on_delete => :no_action, :on_update => :no_action) }
|
60
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_person_id_fk FOREIGN KEY (person_id) REFERENCES people (id) ON DELETE NO ACTION ON UPDATE NO ACTION") }
|
61
|
-
end
|
62
|
-
|
63
|
-
describe "with a given add_index option" do
|
64
|
-
before { adapter.add_foreign_key_constraint(:books, :people, :add_index => true) }
|
65
|
-
it { should have_received.add_index(:books, :person_id) }
|
66
|
-
end
|
67
|
-
|
68
|
-
describe "with a referencing attribute and a add_index option" do
|
69
|
-
before { adapter.add_foreign_key_constraint(:books, :people, :referencing => :author_id, :add_index => true) }
|
70
|
-
it { should have_received.add_index(:books, :author_id) }
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
describe "#remove_foreign_key_constraint" do
|
75
|
-
subject { adapter }
|
76
|
-
|
77
|
-
before do
|
78
|
-
stub(adapter).execute
|
79
|
-
stub(adapter).remove_index
|
80
|
-
end
|
81
|
-
|
82
|
-
context "with no options" do
|
83
|
-
before { adapter.remove_foreign_key_constraint(:books, :people) }
|
84
|
-
it { should have_received.execute("ALTER TABLE books DROP CONSTRAINT books_person_id_fk") }
|
85
|
-
end
|
86
|
-
|
87
|
-
context "with a given referencing attribute" do
|
88
|
-
before { adapter.remove_foreign_key_constraint(:books, :people, :referencing => :author_id) }
|
89
|
-
it { should have_received.execute("ALTER TABLE books DROP CONSTRAINT books_author_id_fk") }
|
90
|
-
end
|
91
|
-
|
92
|
-
context "with a given name" do
|
93
|
-
before { adapter.remove_foreign_key_constraint(:books, :people, :name => :foo) }
|
94
|
-
it { should have_received.execute("ALTER TABLE books DROP CONSTRAINT foo") }
|
95
|
-
end
|
96
|
-
|
97
|
-
describe "with a given remove_index option" do
|
98
|
-
before { adapter.remove_foreign_key_constraint(:books, :people, :remove_index => true) }
|
99
|
-
it { should have_received.remove_index(:books, :person_id) }
|
100
|
-
end
|
101
|
-
|
102
|
-
describe "with a referencing attribute and a remove_index option" do
|
103
|
-
before { adapter.remove_foreign_key_constraint(:books, :people, :referencing => :author_id, :remove_index => true) }
|
104
|
-
it { should have_received.remove_index(:books, :author_id) }
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RC::Inclusion, "#add_inclusion_constraint" do
|
4
|
-
let(:adapter) do
|
5
|
-
Class.new do
|
6
|
-
include RC::Inclusion
|
7
|
-
end.new
|
8
|
-
end
|
9
|
-
|
10
|
-
subject { adapter }
|
11
|
-
|
12
|
-
before { stub(adapter).execute }
|
13
|
-
|
14
|
-
context "given an array of string values" do
|
15
|
-
before { adapter.add_inclusion_constraint(:books, :state, :in => %w(available on_loan)) }
|
16
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_state CHECK (state IN ('available', 'on_loan'))") }
|
17
|
-
end
|
18
|
-
|
19
|
-
context "given an array of numeric values" do
|
20
|
-
before { adapter.add_inclusion_constraint(:books, :state, :in => [1, 2, 3]) }
|
21
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_state CHECK (state IN (1, 2, 3))") }
|
22
|
-
end
|
23
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RC::Numericality, "#add_numericality_constraint" do
|
4
|
-
let(:adapter) do
|
5
|
-
Class.new do
|
6
|
-
include RC::Numericality
|
7
|
-
end.new
|
8
|
-
end
|
9
|
-
|
10
|
-
subject { adapter }
|
11
|
-
|
12
|
-
before { stub(adapter).execute }
|
13
|
-
|
14
|
-
context "greater_than" do
|
15
|
-
before { adapter.add_numericality_constraint(:books, :published_month, :greater_than => 1) }
|
16
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_published_month CHECK (published_month > 1)") }
|
17
|
-
end
|
18
|
-
|
19
|
-
context "greater_than_or_equal_to" do
|
20
|
-
before { adapter.add_numericality_constraint(:books, :published_month, :greater_than_or_equal_to => 2) }
|
21
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_published_month CHECK (published_month >= 2)") }
|
22
|
-
end
|
23
|
-
|
24
|
-
context "equal_to" do
|
25
|
-
before { adapter.add_numericality_constraint(:books, :published_month, :equal_to => 3) }
|
26
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_published_month CHECK (published_month = 3)") }
|
27
|
-
end
|
28
|
-
|
29
|
-
context "not_equal_to" do
|
30
|
-
before { adapter.add_numericality_constraint(:books, :published_month, :not_equal_to => 0) }
|
31
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_published_month CHECK (published_month != 0)") }
|
32
|
-
end
|
33
|
-
|
34
|
-
context "less_than" do
|
35
|
-
before { adapter.add_numericality_constraint(:books, :published_month, :less_than => 4) }
|
36
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_published_month CHECK (published_month < 4)") }
|
37
|
-
end
|
38
|
-
|
39
|
-
context "less_than_or_equal_to" do
|
40
|
-
before { adapter.add_numericality_constraint(:books, :published_month, :less_than_or_equal_to => 5) }
|
41
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_published_month CHECK (published_month <= 5)") }
|
42
|
-
end
|
43
|
-
|
44
|
-
context "greater_than_or_equal_to and less_than_or_equal_to" do
|
45
|
-
before { adapter.add_numericality_constraint(:books, :published_month, :greater_than_or_equal_to => 5, :less_than_or_equal_to => 6) }
|
46
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_published_month CHECK (published_month >= 5 AND published_month <= 6)") }
|
47
|
-
end
|
48
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RC::Presence, "#add_presence_constraint" do
|
4
|
-
let(:adapter) do
|
5
|
-
Class.new do
|
6
|
-
include RC::Presence
|
7
|
-
end.new
|
8
|
-
end
|
9
|
-
|
10
|
-
subject { adapter }
|
11
|
-
|
12
|
-
before { stub(adapter).execute }
|
13
|
-
|
14
|
-
context "given a table and attribute" do
|
15
|
-
before { adapter.add_presence_constraint(:books, :state) }
|
16
|
-
it { should have_received.execute("ALTER TABLE books ADD CONSTRAINT books_state CHECK (state !~ '^\s*$')") }
|
17
|
-
end
|
18
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RC::PrimaryKey, "#add_primary_key" do
|
4
|
-
let(:adapter) do
|
5
|
-
Class.new do
|
6
|
-
include RC::PrimaryKey
|
7
|
-
end.new
|
8
|
-
end
|
9
|
-
|
10
|
-
subject { adapter }
|
11
|
-
|
12
|
-
before { stub(adapter).execute }
|
13
|
-
|
14
|
-
context "with no options" do
|
15
|
-
before { adapter.add_primary_key(:books) }
|
16
|
-
it { should have_received.execute("ALTER TABLE books ADD PRIMARY KEY (id)") }
|
17
|
-
end
|
18
|
-
end
|
data/spec/rein/view_spec.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Rein::View do
|
4
|
-
let(:adapter) do
|
5
|
-
Class.new do
|
6
|
-
include Rein::View
|
7
|
-
end.new
|
8
|
-
end
|
9
|
-
|
10
|
-
subject { adapter }
|
11
|
-
|
12
|
-
before { stub(adapter).execute }
|
13
|
-
|
14
|
-
describe "#create_view" do
|
15
|
-
before { adapter.create_view(:foo, "SELECT * FROM bar") }
|
16
|
-
it { should have_received.execute("CREATE VIEW foo AS SELECT * FROM bar") }
|
17
|
-
end
|
18
|
-
|
19
|
-
describe "#drop_view" do
|
20
|
-
before { adapter.drop_view(:foo) }
|
21
|
-
it { should have_received.execute("DROP VIEW foo") }
|
22
|
-
end
|
23
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
require "rr"
|
2
|
-
require "rr/adapters/rspec"
|
3
|
-
require "rspec"
|
4
|
-
require "simplecov"
|
5
|
-
|
6
|
-
SimpleCov.start
|
7
|
-
|
8
|
-
require "rein"
|
9
|
-
|
10
|
-
RSpec.configure do |config|
|
11
|
-
config.mock_with :rr
|
12
|
-
end
|
13
|
-
|
14
|
-
# FIXME: This is a workaround to get RSpec 2 to play nicely with RR.
|
15
|
-
def have_received(method = nil)
|
16
|
-
RR::Adapters::Rspec::InvocationMatcher.new(method)
|
17
|
-
end
|