composite_primary_keys 8.1.0 → 8.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +642 -625
  3. data/README.rdoc +5 -2
  4. data/lib/composite_primary_keys.rb +115 -115
  5. data/lib/composite_primary_keys/associations/association.rb +23 -23
  6. data/lib/composite_primary_keys/associations/association_scope.rb +73 -73
  7. data/lib/composite_primary_keys/associations/collection_association.rb +14 -14
  8. data/lib/composite_primary_keys/associations/has_many_association.rb +69 -69
  9. data/lib/composite_primary_keys/associations/join_dependency.rb +87 -87
  10. data/lib/composite_primary_keys/associations/preloader/association.rb +90 -90
  11. data/lib/composite_primary_keys/associations/singular_association.rb +18 -18
  12. data/lib/composite_primary_keys/attribute_methods.rb +9 -9
  13. data/lib/composite_primary_keys/attribute_methods/dirty.rb +29 -29
  14. data/lib/composite_primary_keys/attribute_methods/read.rb +24 -24
  15. data/lib/composite_primary_keys/attribute_methods/write.rb +30 -30
  16. data/lib/composite_primary_keys/attribute_set/builder.rb +19 -19
  17. data/lib/composite_primary_keys/base.rb +129 -135
  18. data/lib/composite_primary_keys/composite_arrays.rb +43 -43
  19. data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb +2 -3
  20. data/lib/composite_primary_keys/core.rb +60 -60
  21. data/lib/composite_primary_keys/persistence.rb +56 -56
  22. data/lib/composite_primary_keys/relation.rb +68 -68
  23. data/lib/composite_primary_keys/relation/calculations.rb +78 -78
  24. data/lib/composite_primary_keys/relation/finder_methods.rb +179 -179
  25. data/lib/composite_primary_keys/sanitization.rb +52 -52
  26. data/lib/composite_primary_keys/validations/uniqueness.rb +36 -36
  27. data/lib/composite_primary_keys/version.rb +8 -8
  28. data/tasks/databases/sqlserver.rake +27 -27
  29. data/test/abstract_unit.rb +114 -113
  30. data/test/connections/databases.example.yml +25 -25
  31. data/test/connections/native_sqlserver/connection.rb +11 -11
  32. data/test/fixtures/db_definitions/mysql.sql +218 -218
  33. data/test/fixtures/db_definitions/postgresql.sql +220 -220
  34. data/test/fixtures/db_definitions/sqlite.sql +206 -206
  35. data/test/fixtures/db_definitions/sqlserver.drop.sql +91 -91
  36. data/test/fixtures/db_definitions/sqlserver.sql +226 -226
  37. data/test/fixtures/employee.rb +11 -11
  38. data/test/fixtures/salary.rb +5 -5
  39. data/test/test_associations.rb +341 -340
  40. data/test/test_attributes.rb +60 -60
  41. data/test/test_create.rb +157 -157
  42. data/test/test_delete.rb +158 -158
  43. data/test/test_delete_all.rb +33 -28
  44. data/test/test_enum.rb +21 -21
  45. data/test/test_equal.rb +26 -26
  46. data/test/test_find.rb +119 -118
  47. data/test/test_habtm.rb +117 -113
  48. data/test/test_polymorphic.rb +27 -26
  49. data/test/test_tutorial_example.rb +25 -25
  50. metadata +44 -2
@@ -95,9 +95,11 @@ CPK supports the following databases:
95
95
  * SQLite
96
96
  * SQLServer
97
97
 
98
- == Running Tests
98
+ == Tests
99
99
 
100
- See test/README_tests.rdoc
100
+ Travis build status: {<img src="https://travis-ci.org/composite-primary-keys/composite_primary_keys.svg" alt="Build Status" />}[https://travis-ci.org/composite-primary-keys/composite_primary_keys]
101
+
102
+ See test/README_tests.rdoc for more information about running tests.
101
103
 
102
104
  == Questions, Discussion and Contributions
103
105
 
@@ -110,3 +112,4 @@ First version was written by Dr Nic Williams.
110
112
  Maintained by Charlie Savage
111
113
 
112
114
  Contributions by many!
115
+
@@ -1,115 +1,115 @@
1
- #--
2
- # Copyright (c) 2006-2012 Nic Williams and Charlie Savage
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
-
24
- $:.unshift(File.dirname(__FILE__)) unless
25
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
26
-
27
- unless defined?(ActiveRecord)
28
- require 'rubygems'
29
- gem 'activerecord', '~>4.2.0'
30
- require 'active_record'
31
- end
32
-
33
- # AR files we override
34
- require 'active_record/counter_cache'
35
- require 'active_record/fixtures'
36
- require 'active_record/model_schema'
37
- require 'active_record/persistence'
38
- require 'active_record/relation'
39
- require 'active_record/sanitization'
40
- require 'active_record/attribute_methods'
41
-
42
- require 'active_record/associations/association'
43
- require 'active_record/associations/association_scope'
44
- require 'active_record/associations/has_many_association'
45
- require 'active_record/associations/has_many_through_association'
46
- require 'active_record/associations/join_dependency'
47
- require 'active_record/associations/join_dependency/join_association'
48
- require 'active_record/associations/preloader/association'
49
- require 'active_record/associations/preloader/belongs_to'
50
- require 'active_record/associations/singular_association'
51
- require 'active_record/associations/collection_association'
52
-
53
- require 'active_record/attribute_set/builder'
54
- require 'active_record/attribute_methods/primary_key'
55
- require 'active_record/attribute_methods/read'
56
- require 'active_record/attribute_methods/write'
57
- require 'active_record/locking/optimistic'
58
- require 'active_record/nested_attributes'
59
-
60
- require 'active_record/connection_adapters/abstract_adapter'
61
-
62
- require 'active_record/relation/batches'
63
- require 'active_record/relation/calculations'
64
- require 'active_record/relation/finder_methods'
65
- require 'active_record/relation/predicate_builder'
66
- require 'active_record/relation/query_methods'
67
-
68
- require 'active_record/validations/uniqueness'
69
-
70
- # CPK files
71
- require 'composite_primary_keys/persistence'
72
- require 'composite_primary_keys/base'
73
- require 'composite_primary_keys/core'
74
- require 'composite_primary_keys/composite_arrays'
75
- require 'composite_primary_keys/composite_predicates'
76
- require 'composite_primary_keys/fixtures'
77
- require 'composite_primary_keys/model_schema'
78
- require 'composite_primary_keys/relation'
79
- require 'composite_primary_keys/sanitization'
80
- require 'composite_primary_keys/attribute_set/builder'
81
- require 'composite_primary_keys/attribute_methods'
82
- require 'composite_primary_keys/version'
83
-
84
- require 'composite_primary_keys/associations/association'
85
- require 'composite_primary_keys/associations/association_scope'
86
- require 'composite_primary_keys/associations/has_many_association'
87
- require 'composite_primary_keys/associations/has_many_through_association'
88
- require 'composite_primary_keys/associations/join_dependency'
89
- require 'composite_primary_keys/associations/join_dependency/join_association'
90
- require 'composite_primary_keys/associations/preloader/association'
91
- require 'composite_primary_keys/associations/preloader/belongs_to'
92
- require 'composite_primary_keys/associations/singular_association'
93
- require 'composite_primary_keys/associations/collection_association'
94
-
95
- require 'composite_primary_keys/dirty'
96
-
97
- require 'composite_primary_keys/attribute_methods/primary_key'
98
- require 'composite_primary_keys/attribute_methods/dirty'
99
- require 'composite_primary_keys/attribute_methods/read'
100
- require 'composite_primary_keys/attribute_methods/write'
101
- require 'composite_primary_keys/locking/optimistic'
102
- require 'composite_primary_keys/nested_attributes'
103
-
104
- require 'composite_primary_keys/connection_adapters/abstract_adapter'
105
- require 'composite_primary_keys/connection_adapters/abstract/connection_specification_changes'
106
-
107
- require 'composite_primary_keys/relation/batches'
108
- require 'composite_primary_keys/relation/calculations'
109
- require 'composite_primary_keys/relation/finder_methods'
110
- require 'composite_primary_keys/relation/predicate_builder'
111
- require 'composite_primary_keys/relation/query_methods'
112
-
113
- require 'composite_primary_keys/validations/uniqueness'
114
-
115
- require 'composite_primary_keys/composite_relation'
1
+ #--
2
+ # Copyright (c) 2006-2012 Nic Williams and Charlie Savage
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ $:.unshift(File.dirname(__FILE__)) unless
25
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
26
+
27
+ unless defined?(ActiveRecord)
28
+ require 'rubygems'
29
+ gem 'activerecord', '~>4.2.0'
30
+ require 'active_record'
31
+ end
32
+
33
+ # AR files we override
34
+ require 'active_record/counter_cache'
35
+ require 'active_record/fixtures'
36
+ require 'active_record/model_schema'
37
+ require 'active_record/persistence'
38
+ require 'active_record/relation'
39
+ require 'active_record/sanitization'
40
+ require 'active_record/attribute_methods'
41
+
42
+ require 'active_record/associations/association'
43
+ require 'active_record/associations/association_scope'
44
+ require 'active_record/associations/has_many_association'
45
+ require 'active_record/associations/has_many_through_association'
46
+ require 'active_record/associations/join_dependency'
47
+ require 'active_record/associations/join_dependency/join_association'
48
+ require 'active_record/associations/preloader/association'
49
+ require 'active_record/associations/preloader/belongs_to'
50
+ require 'active_record/associations/singular_association'
51
+ require 'active_record/associations/collection_association'
52
+
53
+ require 'active_record/attribute_set/builder'
54
+ require 'active_record/attribute_methods/primary_key'
55
+ require 'active_record/attribute_methods/read'
56
+ require 'active_record/attribute_methods/write'
57
+ require 'active_record/locking/optimistic'
58
+ require 'active_record/nested_attributes'
59
+
60
+ require 'active_record/connection_adapters/abstract_adapter'
61
+
62
+ require 'active_record/relation/batches'
63
+ require 'active_record/relation/calculations'
64
+ require 'active_record/relation/finder_methods'
65
+ require 'active_record/relation/predicate_builder'
66
+ require 'active_record/relation/query_methods'
67
+
68
+ require 'active_record/validations/uniqueness'
69
+
70
+ # CPK files
71
+ require 'composite_primary_keys/persistence'
72
+ require 'composite_primary_keys/base'
73
+ require 'composite_primary_keys/core'
74
+ require 'composite_primary_keys/composite_arrays'
75
+ require 'composite_primary_keys/composite_predicates'
76
+ require 'composite_primary_keys/fixtures'
77
+ require 'composite_primary_keys/model_schema'
78
+ require 'composite_primary_keys/relation'
79
+ require 'composite_primary_keys/sanitization'
80
+ require 'composite_primary_keys/attribute_set/builder'
81
+ require 'composite_primary_keys/attribute_methods'
82
+ require 'composite_primary_keys/version'
83
+
84
+ require 'composite_primary_keys/associations/association'
85
+ require 'composite_primary_keys/associations/association_scope'
86
+ require 'composite_primary_keys/associations/has_many_association'
87
+ require 'composite_primary_keys/associations/has_many_through_association'
88
+ require 'composite_primary_keys/associations/join_dependency'
89
+ require 'composite_primary_keys/associations/join_dependency/join_association'
90
+ require 'composite_primary_keys/associations/preloader/association'
91
+ require 'composite_primary_keys/associations/preloader/belongs_to'
92
+ require 'composite_primary_keys/associations/singular_association'
93
+ require 'composite_primary_keys/associations/collection_association'
94
+
95
+ require 'composite_primary_keys/dirty'
96
+
97
+ require 'composite_primary_keys/attribute_methods/primary_key'
98
+ require 'composite_primary_keys/attribute_methods/dirty'
99
+ require 'composite_primary_keys/attribute_methods/read'
100
+ require 'composite_primary_keys/attribute_methods/write'
101
+ require 'composite_primary_keys/locking/optimistic'
102
+ require 'composite_primary_keys/nested_attributes'
103
+
104
+ require 'composite_primary_keys/connection_adapters/abstract_adapter'
105
+ require 'composite_primary_keys/connection_adapters/abstract/connection_specification_changes'
106
+
107
+ require 'composite_primary_keys/relation/batches'
108
+ require 'composite_primary_keys/relation/calculations'
109
+ require 'composite_primary_keys/relation/finder_methods'
110
+ require 'composite_primary_keys/relation/predicate_builder'
111
+ require 'composite_primary_keys/relation/query_methods'
112
+
113
+ require 'composite_primary_keys/validations/uniqueness'
114
+
115
+ require 'composite_primary_keys/composite_relation'
@@ -1,23 +1,23 @@
1
- module ActiveRecord
2
- module Associations
3
- class Association
4
- def creation_attributes
5
- attributes = {}
6
-
7
- if (reflection.has_one? || reflection.collection?) && !options[:through]
8
- # CPK
9
- # attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
10
- Array(reflection.foreign_key).zip(Array(reflection.active_record_primary_key)).each do |key1, key2|
11
- attributes[key1] = owner[key2]
12
- end
13
-
14
- if reflection.options[:as]
15
- attributes[reflection.type] = owner.class.base_class.name
16
- end
17
- end
18
-
19
- attributes
20
- end
21
- end
22
- end
23
- end
1
+ module ActiveRecord
2
+ module Associations
3
+ class Association
4
+ def creation_attributes
5
+ attributes = {}
6
+
7
+ if (reflection.has_one? || reflection.collection?) && !options[:through]
8
+ # CPK
9
+ # attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
10
+ Array(reflection.foreign_key).zip(Array(reflection.active_record_primary_key)).each do |key1, key2|
11
+ attributes[key1] = owner[key2]
12
+ end
13
+
14
+ if reflection.options[:as]
15
+ attributes[reflection.type] = owner.class.base_class.name
16
+ end
17
+ end
18
+
19
+ attributes
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,73 +1,73 @@
1
- module ActiveRecord
2
- module Associations
3
- class AssociationScope
4
- def add_constraints(scope, owner, assoc_klass, refl, tracker)
5
- chain = refl.chain
6
- scope_chain = refl.scope_chain
7
-
8
- tables = construct_tables(chain, assoc_klass, refl, tracker)
9
-
10
- chain.each_with_index do |reflection, i|
11
- table, foreign_table = tables.shift, tables.first
12
-
13
- join_keys = reflection.join_keys(assoc_klass)
14
- key = join_keys.key
15
- foreign_key = join_keys.foreign_key
16
-
17
- if reflection == chain.last
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
49
-
50
- # Exclude the scope of the association itself, because that
51
- # was already merged in the #scope method.
52
- scope_chain[i].each do |scope_chain_item|
53
- item = eval_scope(klass, scope_chain_item, owner)
54
-
55
- if scope_chain_item == refl.scope
56
- scope.merge! item.except(:where, :includes, :bind)
57
- end
58
-
59
- if is_first_chain
60
- scope.includes! item.includes_values
61
- end
62
-
63
- scope.where_values += item.where_values
64
- scope.bind_values += item.bind_values
65
- scope.order_values |= item.order_values
66
- end
67
- end
68
-
69
- scope
70
- end
71
- end
72
- end
73
- end
1
+ module ActiveRecord
2
+ module Associations
3
+ class AssociationScope
4
+ def add_constraints(scope, owner, assoc_klass, refl, tracker)
5
+ chain = refl.chain
6
+ scope_chain = refl.scope_chain
7
+
8
+ tables = construct_tables(chain, assoc_klass, refl, tracker)
9
+
10
+ chain.each_with_index do |reflection, i|
11
+ table, foreign_table = tables.shift, tables.first
12
+
13
+ join_keys = reflection.join_keys(assoc_klass)
14
+ key = join_keys.key
15
+ foreign_key = join_keys.foreign_key
16
+
17
+ if reflection == chain.last
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
49
+
50
+ # Exclude the scope of the association itself, because that
51
+ # was already merged in the #scope method.
52
+ scope_chain[i].each do |scope_chain_item|
53
+ item = eval_scope(klass, scope_chain_item, owner)
54
+
55
+ if scope_chain_item == refl.scope
56
+ scope.merge! item.except(:where, :includes, :bind)
57
+ end
58
+
59
+ if is_first_chain
60
+ scope.includes! item.includes_values
61
+ end
62
+
63
+ scope.where_values += item.where_values
64
+ scope.bind_values += item.bind_values
65
+ scope.order_values |= item.order_values
66
+ end
67
+ end
68
+
69
+ scope
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,15 +1,15 @@
1
- module CompositePrimaryKeys
2
- module CollectionAssociation
3
- extend ActiveSupport::Concern
4
- included do
5
- def get_records_with_cpk_support
6
- cpk_applies = (target && target.respond_to?(:composite?) && target.composite?) || (owner && owner.respond_to?(:composite?) && owner.composite?)
7
- return scope.to_a if cpk_applies
8
- get_records_without_cpk_support
9
- end
10
- alias_method_chain :get_records, :cpk_support
11
- end
12
- end
13
- end
14
-
1
+ module CompositePrimaryKeys
2
+ module CollectionAssociation
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ def get_records_with_cpk_support
6
+ cpk_applies = (target && target.respond_to?(:composite?) && target.composite?) || (owner && owner.respond_to?(:composite?) && owner.composite?)
7
+ return scope.to_a if cpk_applies
8
+ get_records_without_cpk_support
9
+ end
10
+ alias_method_chain :get_records, :cpk_support
11
+ end
12
+ end
13
+ end
14
+
15
15
  ActiveRecord::Associations::CollectionAssociation.send(:include, CompositePrimaryKeys::CollectionAssociation)