composite_primary_keys 8.1.1 → 8.1.2
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/History.rdoc +4 -1
- data/lib/composite_primary_keys.rb +5 -1
- data/lib/composite_primary_keys/arel/visitors/to_sql.rb +24 -0
- data/lib/composite_primary_keys/associations/association_scope.rb +32 -58
- data/lib/composite_primary_keys/associations/join_dependency/join_association.rb +22 -22
- data/lib/composite_primary_keys/associations/preloader/association.rb +12 -6
- data/lib/composite_primary_keys/associations/preloader/belongs_to.rb +19 -19
- data/lib/composite_primary_keys/attribute_methods/primary_key.rb +1 -2
- data/lib/composite_primary_keys/attribute_methods/read.rb +2 -2
- data/lib/composite_primary_keys/attribute_methods/write.rb +1 -1
- data/lib/composite_primary_keys/composite_predicates.rb +55 -50
- data/lib/composite_primary_keys/composite_relation.rb +48 -48
- data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb +2 -2
- data/lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb +19 -46
- data/lib/composite_primary_keys/connection_adapters/sqlserver_adapter.rb +8 -4
- data/lib/composite_primary_keys/fixtures.rb +26 -22
- data/lib/composite_primary_keys/locking/optimistic.rb +54 -55
- data/lib/composite_primary_keys/relation.rb +15 -8
- data/lib/composite_primary_keys/relation/batches.rb +23 -19
- data/lib/composite_primary_keys/relation/calculations.rb +4 -2
- data/lib/composite_primary_keys/relation/finder_methods.rb +33 -27
- data/lib/composite_primary_keys/relation/predicate_builder.rb +18 -3
- data/lib/composite_primary_keys/relation/query_methods.rb +41 -41
- data/lib/composite_primary_keys/sanitization.rb +7 -5
- data/lib/composite_primary_keys/validations/uniqueness.rb +20 -16
- data/lib/composite_primary_keys/version.rb +1 -1
- data/tasks/databases/oracle.rake +27 -25
- data/tasks/databases/oracle_enhanced.rake +27 -0
- data/test/connections/databases.ci.yml +15 -15
- data/test/connections/native_oracle/connection.rb +11 -11
- data/test/connections/native_oracle_enhanced/connection.rb +16 -16
- data/test/fixtures/comment.rb +7 -7
- data/test/fixtures/db_definitions/db2-create-tables.sql +126 -126
- data/test/fixtures/db_definitions/db2-drop-tables.sql +18 -18
- data/test/fixtures/db_definitions/oracle.drop.sql +48 -45
- data/test/fixtures/db_definitions/oracle.sql +236 -223
- data/test/fixtures/dorm.rb +2 -2
- data/test/fixtures/membership.rb +6 -6
- data/test/fixtures/membership_statuses.yml +16 -16
- data/test/fixtures/memberships.yml +10 -10
- data/test/fixtures/product_tariffs.yml +14 -14
- data/test/fixtures/reference_code.rb +7 -7
- data/test/fixtures/restaurants_suburb.rb +2 -2
- data/test/fixtures/suburb.rb +5 -5
- data/test/fixtures/topic.rb +5 -5
- data/test/fixtures/topic_source.rb +6 -6
- data/test/fixtures/topic_sources.yml +3 -3
- data/test/fixtures/topics.yml +8 -8
- data/test/fixtures/users.yml +10 -10
- data/test/test_attribute_methods.rb +63 -63
- data/test/test_calculations.rb +42 -37
- data/test/test_callbacks.rb +99 -99
- data/test/test_delete.rb +28 -21
- data/test/test_delete_all.rb +5 -4
- data/test/test_dumpable.rb +15 -15
- data/test/test_nested_attributes.rb +124 -124
- data/test/test_optimistic.rb +18 -18
- data/test/test_polymorphic.rb +1 -1
- data/test/test_predicates.rb +40 -40
- data/test/test_santiago.rb +23 -23
- data/test/test_suite.rb +34 -34
- data/test/test_touch.rb +23 -23
- data/test/test_update.rb +71 -71
- metadata +9 -8
- data/lib/composite_primary_keys/model_schema.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce98265078e9df3388a619400153228e3d060120
|
4
|
+
data.tar.gz: 02bfe6e56836f6a5c6f6e73ca8bcc1af3502a729
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47e1b2d9385bdc3222d316989aad9c876d218cc985cbf4a11cfa66cf4de0fe67a466891242b8f2b38af96e1a0e2a6d34da7176ff2ca55b5445c2c43c94a46fe5
|
7
|
+
data.tar.gz: e7c96de2cb63e3512f511b9d46a81df2154fe05d4ed7547d65ea101e691f90f484df3f9d8da3aaa269ba5a0054ebac48e92738064d51e5d1e39fb41df9189f69
|
data/History.rdoc
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
== 8.1.2 (2015-12-13)
|
2
|
+
|
3
|
+
* Fix failing tests
|
4
|
+
|
1
5
|
== 8.1.1 (2015-08-04)
|
2
6
|
|
3
7
|
* Updates to make Travis CI green (Laust Rud Jacobsen)
|
@@ -8,7 +12,6 @@
|
|
8
12
|
* Remove call to verify_active_connections! which was removed from AR 4.1 (Steve Pletcher)
|
9
13
|
* Aligned the establish connection paramater handling to be similar to latest version of rails (Harish Shetty)
|
10
14
|
|
11
|
-
|
12
15
|
== 8.1.0 (2014-03-23)
|
13
16
|
|
14
17
|
* ActiveRecord 4.2.1 support (Charlie Savage)
|
@@ -30,6 +30,9 @@ unless defined?(ActiveRecord)
|
|
30
30
|
require 'active_record'
|
31
31
|
end
|
32
32
|
|
33
|
+
# Arel files we override
|
34
|
+
require 'arel/visitors/to_sql'
|
35
|
+
|
33
36
|
# AR files we override
|
34
37
|
require 'active_record/counter_cache'
|
35
38
|
require 'active_record/fixtures'
|
@@ -68,13 +71,14 @@ require 'active_record/relation/query_methods'
|
|
68
71
|
require 'active_record/validations/uniqueness'
|
69
72
|
|
70
73
|
# CPK files
|
74
|
+
require 'composite_primary_keys/arel/visitors/to_sql'
|
75
|
+
|
71
76
|
require 'composite_primary_keys/persistence'
|
72
77
|
require 'composite_primary_keys/base'
|
73
78
|
require 'composite_primary_keys/core'
|
74
79
|
require 'composite_primary_keys/composite_arrays'
|
75
80
|
require 'composite_primary_keys/composite_predicates'
|
76
81
|
require 'composite_primary_keys/fixtures'
|
77
|
-
require 'composite_primary_keys/model_schema'
|
78
82
|
require 'composite_primary_keys/relation'
|
79
83
|
require 'composite_primary_keys/sanitization'
|
80
84
|
require 'composite_primary_keys/attribute_set/builder'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class ToSql
|
4
|
+
def visit_Arel_Nodes_In o, collector
|
5
|
+
if Array === o.right && o.right.empty?
|
6
|
+
collector << '1=0'
|
7
|
+
else
|
8
|
+
# CPK
|
9
|
+
# collector = visit o.left, collector
|
10
|
+
if o.left.name.is_a?(Array)
|
11
|
+
collector << "("
|
12
|
+
collector = visit(o.left, collector)
|
13
|
+
collector << ")"
|
14
|
+
else
|
15
|
+
collector = visit o.left, collector
|
16
|
+
end
|
17
|
+
|
18
|
+
collector << " IN ("
|
19
|
+
visit(o.right, collector) << ")"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,72 +1,46 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Associations
|
3
3
|
class AssociationScope
|
4
|
-
def add_constraints(scope, owner, assoc_klass, refl, tracker)
|
5
|
-
chain = refl.chain
|
6
|
-
scope_chain = refl.scope_chain
|
7
4
|
|
8
|
-
|
5
|
+
def next_chain_scope(scope, table, reflection, tracker, assoc_klass, foreign_table, next_reflection)
|
6
|
+
join_keys = reflection.join_keys(assoc_klass)
|
7
|
+
key = join_keys.key
|
8
|
+
foreign_key = join_keys.foreign_key
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
# CPK
|
11
|
+
# constraint = table[key].eq(foreign_table[foreign_key])
|
12
|
+
constraint = cpk_join_predicate(table, key, foreign_table, foreign_key)
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
# CPK - TODO add back in tracker support
|
19
|
-
if key.kind_of?(Array) || foreign_key.kind_of?(Array)
|
20
|
-
predicate = cpk_join_predicate(table, key, owner, foreign_key)
|
21
|
-
scope = scope.where(predicate)
|
22
|
-
else
|
23
|
-
bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key], tracker
|
24
|
-
scope = scope.where(table[key].eq(bind_val))
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
if reflection.type
|
29
|
-
value = owner.class.base_class.name
|
30
|
-
bind_val = bind scope, table.table_name, reflection.type, value, tracker
|
31
|
-
scope = scope.where(table[reflection.type].eq(bind_val))
|
32
|
-
end
|
33
|
-
else
|
34
|
-
# CPK
|
35
|
-
#constraint = table[key].eq(foreign_table[foreign_key])
|
36
|
-
constraint = cpk_join_predicate(table, key, foreign_table, foreign_key)
|
37
|
-
|
38
|
-
if reflection.type
|
39
|
-
value = chain[i + 1].klass.base_class.name
|
40
|
-
bind_val = bind scope, table.table_name, reflection.type, value, tracker
|
41
|
-
scope = scope.where(table[reflection.type].eq(bind_val))
|
42
|
-
end
|
43
|
-
|
44
|
-
scope = scope.joins(join(foreign_table, constraint))
|
45
|
-
end
|
46
|
-
|
47
|
-
is_first_chain = i == 0
|
48
|
-
klass = is_first_chain ? assoc_klass : reflection.klass
|
14
|
+
if reflection.type
|
15
|
+
value = next_reflection.klass.base_class.name
|
16
|
+
bind_val = bind scope, table.table_name, reflection.type, value, tracker
|
17
|
+
scope = scope.where(table[reflection.type].eq(bind_val))
|
18
|
+
end
|
49
19
|
|
50
|
-
|
51
|
-
|
52
|
-
scope_chain[i].each do |scope_chain_item|
|
53
|
-
item = eval_scope(klass, scope_chain_item, owner)
|
20
|
+
scope.joins(join(foreign_table, constraint))
|
21
|
+
end
|
54
22
|
|
55
|
-
|
56
|
-
|
57
|
-
|
23
|
+
def last_chain_scope(scope, table, reflection, owner, tracker, assoc_klass)
|
24
|
+
join_keys = reflection.join_keys(assoc_klass)
|
25
|
+
key = join_keys.key
|
26
|
+
foreign_key = join_keys.foreign_key
|
27
|
+
|
28
|
+
if key.kind_of?(Array) || foreign_key.kind_of?(Array)
|
29
|
+
predicate = cpk_join_predicate(table, key, owner, foreign_key)
|
30
|
+
scope = scope.where(predicate)
|
31
|
+
else
|
32
|
+
bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key], tracker
|
33
|
+
scope = scope.where(table[key].eq(bind_val))
|
34
|
+
end
|
58
35
|
|
59
|
-
|
60
|
-
|
61
|
-
|
36
|
+
if reflection.type
|
37
|
+
value = owner.class.base_class.name
|
38
|
+
bind_val = bind scope, table.table_name, reflection.type, value, tracker
|
62
39
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
40
|
+
scope.where(table[reflection.type].eq(bind_val))
|
41
|
+
else
|
42
|
+
scope
|
67
43
|
end
|
68
|
-
|
69
|
-
scope
|
70
44
|
end
|
71
45
|
end
|
72
46
|
end
|
@@ -1,22 +1,22 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Associations
|
3
|
-
class JoinDependency
|
4
|
-
class JoinAssociation
|
5
|
-
def build_constraint(klass, table, key, foreign_table, foreign_key)
|
6
|
-
# CPK
|
7
|
-
# constraint = table[key].eq(foreign_table[foreign_key])
|
8
|
-
constraint = cpk_join_predicate(table, key, foreign_table, foreign_key)
|
9
|
-
|
10
|
-
if klass.finder_needs_type_condition?
|
11
|
-
constraint = table.create_and([
|
12
|
-
constraint,
|
13
|
-
klass.send(:type_condition, table)
|
14
|
-
])
|
15
|
-
end
|
16
|
-
|
17
|
-
constraint
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class JoinDependency
|
4
|
+
class JoinAssociation
|
5
|
+
def build_constraint(klass, table, key, foreign_table, foreign_key)
|
6
|
+
# CPK
|
7
|
+
# constraint = table[key].eq(foreign_table[foreign_key])
|
8
|
+
constraint = cpk_join_predicate(table, key, foreign_table, foreign_key)
|
9
|
+
|
10
|
+
if klass.finder_needs_type_condition?
|
11
|
+
constraint = table.create_and([
|
12
|
+
constraint,
|
13
|
+
klass.send(:type_condition, table)
|
14
|
+
])
|
15
|
+
end
|
16
|
+
|
17
|
+
constraint
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -54,13 +54,19 @@ module ActiveRecord
|
|
54
54
|
records_for(slice)
|
55
55
|
}
|
56
56
|
|
57
|
+
# CPK
|
58
|
+
# @preloaded_records.map { |record|
|
59
|
+
# key = record[association_key_name]
|
60
|
+
# key = key.to_s if key_conversion_required?
|
61
|
+
#
|
62
|
+
# [record, key]
|
63
|
+
# }
|
57
64
|
@preloaded_records.map { |record|
|
58
|
-
|
59
|
-
#[record, record[association_key_name]]
|
60
|
-
owner_key = Array(association_key_name).map do |key_name|
|
65
|
+
key = Array(association_key_name).map do |key_name|
|
61
66
|
record[key_name]
|
62
67
|
end.join(CompositePrimaryKeys::ID_SEP)
|
63
|
-
|
68
|
+
|
69
|
+
[record, key]
|
64
70
|
}
|
65
71
|
end
|
66
72
|
|
@@ -69,7 +75,7 @@ module ActiveRecord
|
|
69
75
|
owners.group_by do |owner|
|
70
76
|
# CPK
|
71
77
|
# owner[owner_key_name].to_s
|
72
|
-
|
78
|
+
Array(owner_key_name).map do |key_name|
|
73
79
|
owner[key_name]
|
74
80
|
end.join(CompositePrimaryKeys::ID_SEP)
|
75
81
|
end
|
@@ -77,7 +83,7 @@ module ActiveRecord
|
|
77
83
|
owners.group_by do |owner|
|
78
84
|
# CPK
|
79
85
|
# owner[owner_key_name]
|
80
|
-
|
86
|
+
Array(owner_key_name).map do |key_name|
|
81
87
|
owner[key_name]
|
82
88
|
end.join(CompositePrimaryKeys::ID_SEP)
|
83
89
|
end
|
@@ -1,19 +1,19 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Associations
|
3
|
-
class Preloader
|
4
|
-
class BelongsTo
|
5
|
-
def query_scope(ids)
|
6
|
-
# CPK
|
7
|
-
# scope.where(association_key.in(ids))
|
8
|
-
|
9
|
-
if association_key_name.is_a?(Array)
|
10
|
-
predicate = cpk_in_predicate(table, association_key_name, ids)
|
11
|
-
scope.where(predicate)
|
12
|
-
else
|
13
|
-
scope.where(association_key.in(ids))
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class Preloader
|
4
|
+
class BelongsTo
|
5
|
+
def query_scope(ids)
|
6
|
+
# CPK
|
7
|
+
# scope.where(association_key.in(ids))
|
8
|
+
|
9
|
+
if association_key_name.is_a?(Array)
|
10
|
+
predicate = cpk_in_predicate(table, association_key_name, ids)
|
11
|
+
scope.where(predicate)
|
12
|
+
else
|
13
|
+
scope.where(association_key.in(ids))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -5,8 +5,7 @@ module ActiveRecord
|
|
5
5
|
def id_was
|
6
6
|
sync_with_transaction_state
|
7
7
|
# CPK
|
8
|
-
#attribute_was(self.class.primary_key)
|
9
|
-
|
8
|
+
# attribute_was(self.class.primary_key)
|
10
9
|
if self.composite?
|
11
10
|
self.class.primary_keys.map do |key_attr|
|
12
11
|
attribute_changed?(key_attr) ? changed_attributes[key_attr] : self.ids_hash[key_attr]
|
@@ -7,7 +7,7 @@ module ActiveRecord
|
|
7
7
|
_read_attribute(attr_name, &block)
|
8
8
|
else
|
9
9
|
name = attr_name.to_s
|
10
|
-
name = self.class.primary_key if name == 'id'
|
10
|
+
name = self.class.primary_key if name == 'id'.freeze
|
11
11
|
_read_attribute(name, &block)
|
12
12
|
end
|
13
13
|
end
|
@@ -22,4 +22,4 @@ module ActiveRecord
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
|
-
end
|
25
|
+
end
|
@@ -1,51 +1,56 @@
|
|
1
|
-
module CompositePrimaryKeys
|
2
|
-
module Predicates
|
3
|
-
def cpk_and_predicate(predicates)
|
4
|
-
if predicates.length == 1
|
5
|
-
predicates.first
|
6
|
-
else
|
7
|
-
Arel::Nodes::And.new(predicates)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def cpk_or_predicate(predicates)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
1
|
+
module CompositePrimaryKeys
|
2
|
+
module Predicates
|
3
|
+
def cpk_and_predicate(predicates)
|
4
|
+
if predicates.length == 1
|
5
|
+
predicates.first
|
6
|
+
else
|
7
|
+
Arel::Nodes::And.new(predicates)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def cpk_or_predicate(predicates)
|
12
|
+
if predicates.length <= 1
|
13
|
+
predicates.first
|
14
|
+
else
|
15
|
+
predicates_copy = predicates.dup
|
16
|
+
predicate = predicates_copy.shift
|
17
|
+
|
18
|
+
or_predicate = predicates_copy.inject(predicate) do |mem, predicate|
|
19
|
+
::Arel::Nodes::Or.new(mem, predicate)
|
20
|
+
end
|
21
|
+
::Arel::Nodes::Grouping.new(or_predicate)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def cpk_id_predicate(table, keys, values)
|
26
|
+
eq_predicates = keys.zip(values).map do |key, value|
|
27
|
+
table[key].eq(value)
|
28
|
+
end
|
29
|
+
cpk_and_predicate(eq_predicates)
|
30
|
+
end
|
31
|
+
|
32
|
+
def cpk_join_predicate(table1, key1, table2, key2)
|
33
|
+
key1_fields = Array(key1).map {|key| table1[key]}
|
34
|
+
key2_fields = Array(key2).map {|key| table2[key]}
|
35
|
+
|
36
|
+
eq_predicates = key1_fields.zip(key2_fields).map do |key_field1, key_field2|
|
37
|
+
key_field1.eq(key_field2)
|
38
|
+
end
|
39
|
+
cpk_and_predicate(eq_predicates)
|
40
|
+
end
|
41
|
+
|
42
|
+
def cpk_in_predicate(table, primary_keys, ids)
|
43
|
+
and_predicates = ids.map do |id|
|
44
|
+
cpk_id_predicate(table, primary_keys, id)
|
45
|
+
end
|
46
|
+
cpk_or_predicate(and_predicates)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
ActiveRecord::Associations::AssociationScope.send(:include, CompositePrimaryKeys::Predicates)
|
52
|
+
ActiveRecord::Associations::JoinDependency::JoinAssociation.send(:include, CompositePrimaryKeys::Predicates)
|
53
|
+
ActiveRecord::Associations::Preloader::Association.send(:include, CompositePrimaryKeys::Predicates)
|
54
|
+
ActiveRecord::Associations::HasManyThroughAssociation.send(:include, CompositePrimaryKeys::Predicates)
|
55
|
+
ActiveRecord::Relation.send(:include, CompositePrimaryKeys::Predicates)
|
51
56
|
ActiveRecord::PredicateBuilder.send(:extend, CompositePrimaryKeys::Predicates)
|