composite_primary_keys 12.0.9 → 14.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +894 -877
  3. data/README.rdoc +182 -180
  4. data/Rakefile +37 -37
  5. data/lib/composite_primary_keys/active_model/attribute_assignment.rb +19 -19
  6. data/lib/composite_primary_keys/arel/sqlserver.rb +37 -37
  7. data/lib/composite_primary_keys/arel/to_sql.rb +18 -18
  8. data/lib/composite_primary_keys/associations/association.rb +23 -23
  9. data/lib/composite_primary_keys/associations/association_scope.rb +66 -68
  10. data/lib/composite_primary_keys/associations/collection_association.rb +31 -31
  11. data/lib/composite_primary_keys/associations/foreign_association.rb +15 -15
  12. data/lib/composite_primary_keys/associations/has_many_association.rb +35 -35
  13. data/lib/composite_primary_keys/associations/join_dependency.rb +137 -103
  14. data/lib/composite_primary_keys/associations/preloader/association.rb +68 -53
  15. data/lib/composite_primary_keys/associations/through_association.rb +25 -25
  16. data/lib/composite_primary_keys/attribute_methods/primary_key.rb +0 -2
  17. data/lib/composite_primary_keys/attribute_methods/read.rb +30 -30
  18. data/lib/composite_primary_keys/attribute_methods/write.rb +35 -35
  19. data/lib/composite_primary_keys/attribute_methods.rb +21 -9
  20. data/lib/composite_primary_keys/autosave_association.rb +60 -60
  21. data/lib/composite_primary_keys/base.rb +141 -141
  22. data/lib/composite_primary_keys/composite_arrays.rb +86 -86
  23. data/lib/composite_primary_keys/composite_predicates.rb +71 -69
  24. data/lib/composite_primary_keys/composite_relation.rb +29 -29
  25. data/lib/composite_primary_keys/connection_adapters/abstract/database_statements.rb +37 -37
  26. data/lib/composite_primary_keys/connection_adapters/abstract_adapter.rb +10 -10
  27. data/lib/composite_primary_keys/connection_adapters/postgresql/database_statements.rb +26 -26
  28. data/lib/composite_primary_keys/connection_adapters/sqlserver/database_statements.rb +44 -44
  29. data/lib/composite_primary_keys/core.rb +48 -48
  30. data/lib/composite_primary_keys/counter_cache.rb +15 -15
  31. data/lib/composite_primary_keys/fixtures.rb +21 -21
  32. data/lib/composite_primary_keys/nested_attributes.rb +1 -1
  33. data/lib/composite_primary_keys/persistence.rb +96 -81
  34. data/lib/composite_primary_keys/reflection.rb +91 -29
  35. data/lib/composite_primary_keys/relation/batches.rb +15 -7
  36. data/lib/composite_primary_keys/relation/calculations.rb +110 -81
  37. data/lib/composite_primary_keys/relation/finder_methods.rb +235 -235
  38. data/lib/composite_primary_keys/relation/predicate_builder/association_query_value.rb +39 -20
  39. data/lib/composite_primary_keys/relation/query_methods.rb +42 -42
  40. data/lib/composite_primary_keys/relation/where_clause.rb +18 -23
  41. data/lib/composite_primary_keys/relation.rb +197 -193
  42. data/lib/composite_primary_keys/sanitization.rb +42 -42
  43. data/lib/composite_primary_keys/table_metadata.rb +11 -0
  44. data/lib/composite_primary_keys/transactions.rb +34 -34
  45. data/lib/composite_primary_keys/validations/uniqueness.rb +31 -31
  46. data/lib/composite_primary_keys/version.rb +8 -8
  47. data/lib/composite_primary_keys.rb +119 -117
  48. data/scripts/console.rb +48 -48
  49. data/scripts/txt2html +76 -76
  50. data/scripts/txt2js +65 -65
  51. data/tasks/databases/mysql.rake +40 -40
  52. data/tasks/databases/oracle.rake +41 -41
  53. data/tasks/databases/postgresql.rake +38 -38
  54. data/tasks/databases/sqlite.rake +25 -25
  55. data/tasks/databases/sqlserver.rake +43 -43
  56. data/tasks/website.rake +18 -18
  57. data/test/README_tests.rdoc +56 -56
  58. data/test/abstract_unit.rb +118 -114
  59. data/test/connections/connection_spec.rb +27 -27
  60. data/test/connections/databases.ci.yml +22 -22
  61. data/test/connections/databases.example.yml +40 -40
  62. data/test/connections/databases.yml +40 -39
  63. data/test/fixtures/article.rb +10 -10
  64. data/test/fixtures/articles.yml +7 -7
  65. data/test/fixtures/capitol.rb +3 -3
  66. data/test/fixtures/capitols.yml +16 -16
  67. data/test/fixtures/comment.rb +5 -5
  68. data/test/fixtures/comments.yml +17 -17
  69. data/test/fixtures/db_definitions/db2-create-tables.sql +112 -112
  70. data/test/fixtures/db_definitions/db2-drop-tables.sql +16 -16
  71. data/test/fixtures/db_definitions/mysql.sql +180 -180
  72. data/test/fixtures/db_definitions/oracle.drop.sql +41 -41
  73. data/test/fixtures/db_definitions/oracle.sql +199 -199
  74. data/test/fixtures/db_definitions/postgresql.sql +182 -182
  75. data/test/fixtures/db_definitions/sqlite.sql +169 -169
  76. data/test/fixtures/db_definitions/sqlserver.sql +176 -176
  77. data/test/fixtures/department.rb +16 -16
  78. data/test/fixtures/departments.yml +19 -15
  79. data/test/fixtures/dorm.rb +2 -2
  80. data/test/fixtures/dorms.yml +4 -4
  81. data/test/fixtures/employee.rb +5 -5
  82. data/test/fixtures/employees.yml +33 -28
  83. data/test/fixtures/group.rb +2 -2
  84. data/test/fixtures/groups.yml +6 -6
  85. data/test/fixtures/membership.rb +8 -6
  86. data/test/fixtures/membership_status.rb +2 -2
  87. data/test/fixtures/membership_statuses.yml +16 -16
  88. data/test/fixtures/memberships.yml +10 -10
  89. data/test/fixtures/product.rb +9 -9
  90. data/test/fixtures/product_tariff.rb +5 -5
  91. data/test/fixtures/product_tariffs.yml +14 -14
  92. data/test/fixtures/products.yml +11 -11
  93. data/test/fixtures/reading.rb +4 -4
  94. data/test/fixtures/readings.yml +10 -10
  95. data/test/fixtures/reference_code.rb +7 -7
  96. data/test/fixtures/reference_codes.yml +28 -28
  97. data/test/fixtures/reference_type.rb +12 -12
  98. data/test/fixtures/reference_types.yml +9 -9
  99. data/test/fixtures/restaurant.rb +9 -9
  100. data/test/fixtures/restaurants.yml +14 -14
  101. data/test/fixtures/restaurants_suburb.rb +2 -2
  102. data/test/fixtures/restaurants_suburbs.yml +10 -10
  103. data/test/fixtures/room.rb +11 -11
  104. data/test/fixtures/room_assignment.rb +13 -13
  105. data/test/fixtures/room_assignments.yml +24 -24
  106. data/test/fixtures/room_attribute.rb +2 -2
  107. data/test/fixtures/room_attribute_assignment.rb +4 -4
  108. data/test/fixtures/room_attribute_assignments.yml +4 -4
  109. data/test/fixtures/room_attributes.yml +2 -2
  110. data/test/fixtures/rooms.yml +12 -12
  111. data/test/fixtures/street.rb +2 -2
  112. data/test/fixtures/streets.yml +16 -16
  113. data/test/fixtures/student.rb +3 -3
  114. data/test/fixtures/students.yml +15 -15
  115. data/test/fixtures/suburb.rb +5 -5
  116. data/test/fixtures/suburbs.yml +14 -14
  117. data/test/fixtures/tariff.rb +5 -5
  118. data/test/fixtures/tariffs.yml +14 -14
  119. data/test/fixtures/topic_sources.yml +3 -3
  120. data/test/fixtures/topics.yml +8 -8
  121. data/test/fixtures/user.rb +11 -11
  122. data/test/fixtures/users.yml +10 -10
  123. data/test/plugins/pagination.rb +405 -405
  124. data/test/plugins/pagination_helper.rb +135 -135
  125. data/test/test_associations.rb +372 -358
  126. data/test/test_attribute_methods.rb +63 -63
  127. data/test/test_attributes.rb +75 -60
  128. data/test/test_calculations.rb +49 -42
  129. data/test/test_callbacks.rb +99 -99
  130. data/test/test_composite_arrays.rb +38 -38
  131. data/test/test_counter_cache.rb +30 -30
  132. data/test/test_create.rb +218 -206
  133. data/test/test_delete.rb +188 -179
  134. data/test/test_dumpable.rb +15 -15
  135. data/test/test_dup.rb +37 -37
  136. data/test/test_equal.rb +26 -26
  137. data/test/test_exists.rb +39 -39
  138. data/test/test_find.rb +170 -164
  139. data/test/test_habtm.rb +141 -141
  140. data/test/test_ids.rb +112 -112
  141. data/test/test_miscellaneous.rb +32 -32
  142. data/test/test_nested_attributes.rb +67 -67
  143. data/test/test_optimistic.rb +18 -18
  144. data/test/test_pagination.rb +35 -35
  145. data/test/test_polymorphic.rb +43 -43
  146. data/test/test_predicates.rb +59 -59
  147. data/test/test_preload.rb +102 -102
  148. data/test/test_santiago.rb +23 -23
  149. data/test/test_touch.rb +23 -23
  150. data/test/test_tutorial_example.rb +25 -25
  151. data/test/test_update.rb +102 -96
  152. data/test/test_validations.rb +13 -13
  153. metadata +7 -6
@@ -1,235 +1,235 @@
1
- module CompositePrimaryKeys
2
- module ActiveRecord
3
- module FinderMethods
4
- def apply_join_dependency(eager_loading: group_values.empty?)
5
- join_dependency = construct_join_dependency(eager_load_values + includes_values, Arel::Nodes::OuterJoin)
6
- relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
7
-
8
- if eager_loading && !using_limitable_reflections?(join_dependency.reflections)
9
- if has_limit_or_offset?
10
- limited_ids = limited_ids_for(relation)
11
-
12
- # CPK
13
- # limited_ids.empty? ? relation.none! : relation.where!(primary_key => limited_ids)
14
- limited_ids.empty? ? relation.none! : relation.where!(cpk_in_predicate(table, self.primary_keys, limited_ids))
15
- end
16
- relation.limit_value = relation.offset_value = nil
17
- end
18
-
19
- if block_given?
20
- yield relation, join_dependency
21
- else
22
- relation
23
- end
24
- end
25
-
26
- def limited_ids_for(relation)
27
- # CPK
28
- # values = @klass.connection.columns_for_distinct(
29
- # connection.column_name_from_arel_node(arel_attribute(primary_key)),
30
- # relation.order_values
31
- # )
32
-
33
- columns = @klass.primary_keys.map do |key|
34
- connection.visitor.compile(arel_attribute(key))
35
- end
36
- values = @klass.connection.columns_for_distinct(columns, relation.order_values)
37
-
38
- relation = relation.except(:select).select(values).distinct!
39
-
40
- id_rows = skip_query_cache_if_necessary { @klass.connection.select_all(relation.arel, "SQL") }
41
- # CPK
42
- #id_rows.map { |row| row[primary_key] }
43
- id_rows.map do |row|
44
- @klass.primary_keys.map do |key|
45
- row[key]
46
- end
47
- end
48
- end
49
-
50
- def construct_relation_for_exists(conditions)
51
- conditions = sanitize_forbidden_attributes(conditions)
52
-
53
- if distinct_value && offset_value
54
- relation = except(:order).limit!(1)
55
- else
56
- relation = except(:select, :distinct, :order)._select!(::ActiveRecord::FinderMethods::ONE_AS_ONE).limit!(1)
57
- end
58
-
59
- case conditions
60
- # CPK
61
- when CompositePrimaryKeys::CompositeKeys
62
- relation = relation.where(cpk_id_predicate(table, primary_key, conditions))
63
- # CPK
64
- when Array
65
- pk_length = @klass.primary_keys.length
66
-
67
- if conditions.length == pk_length # E.g. conditions = ['France', 'Paris']
68
- return self.construct_relation_for_exists(conditions.to_composite_keys)
69
- else # Assume that conditions contains where relation
70
- relation = relation.where(conditions)
71
- end
72
- when Array, Hash
73
- relation.where!(conditions) unless conditions.empty?
74
- else
75
- relation.where!(primary_key => conditions) unless conditions == :none
76
- end
77
-
78
- relation
79
- end
80
-
81
- def find_with_ids(*ids)
82
- raise UnknownPrimaryKey.new(@klass) if primary_key.nil?
83
-
84
- # CPK
85
- # expects_array = ids.first.kind_of?(Array)
86
- ids = CompositePrimaryKeys.normalize(ids, @klass.primary_keys.length)
87
- expects_array = ids.flatten != ids.flatten(1)
88
- return ids.first if expects_array && ids.first.empty?
89
-
90
- # CPK
91
- # ids = ids.flatten.compact.uniq
92
- ids = expects_array ? ids.first : ids
93
-
94
- model_name = @klass.name
95
-
96
- case ids.size
97
- when 0
98
- error_message = "Couldn't find #{model_name} without an ID"
99
- raise ::ActiveRecord::RecordNotFound.new(error_message, model_name, primary_key)
100
- when 1
101
- result = find_one(ids.first)
102
- expects_array ? [ result ] : result
103
- else
104
- find_some(ids)
105
- end
106
- end
107
-
108
- # def last(limit = nil)
109
- # return find_last(limit) if loaded? || has_limit_or_offset?
110
- #
111
- # result = limit(limit || 1)
112
- # # CPK
113
- # # result.order!(arel_attribute(primary_key)) if order_values.empty? && primary_key
114
- # if order_values.empty? && primary_key
115
- # if composite?
116
- # result.order!(primary_keys.map { |pk| arel_attribute(pk).asc })
117
- # elsif
118
- # result.order!(arel_attribute(primary_key))
119
- # end
120
- # end
121
- #
122
- # result = result.reverse_order!
123
- #
124
- # limit ? result.reverse : result.first
125
- # rescue ::ActiveRecord::IrreversibleOrderError
126
- # ActiveSupport::Deprecation.warn(<<-WARNING.squish)
127
- # Finding a last element by loading the relation when SQL ORDER
128
- # can not be reversed is deprecated.
129
- # Rails 5.1 will raise ActiveRecord::IrreversibleOrderError in this case.
130
- # Please call `to_a.last` if you still want to load the relation.
131
- # WARNING
132
- # find_last(limit)
133
- # end
134
-
135
- def find_one(id)
136
- if ::ActiveRecord::Base === id
137
- raise ArgumentError, <<-MSG.squish
138
- You are passing an instance of ActiveRecord::Base to `find`.
139
- Please pass the id of the object by calling `.id`.
140
- MSG
141
- end
142
-
143
- # CPK
144
- #relation = where(primary_key => id)
145
- relation = where(cpk_id_predicate(table, primary_keys, id))
146
- record = relation.take
147
-
148
- raise_record_not_found_exception!(id, 0, 1) unless record
149
-
150
- record
151
- end
152
-
153
- def find_some(ids)
154
- # CPK
155
- if composite?
156
- ids = if ids.length == 1
157
- CompositePrimaryKeys::CompositeKeys.parse(ids.first)
158
- else
159
- ids.to_composite_keys
160
- end
161
- end
162
-
163
- return find_some_ordered(ids) unless order_values.present?
164
-
165
- # CPK
166
- # result = where(primary_key => ids).to_a
167
- result = if composite?
168
- result = where(cpk_in_predicate(table, primary_keys, ids)).to_a
169
- else
170
- result = where(primary_key => ids).to_a
171
- end
172
-
173
- expected_size =
174
- if limit_value && ids.size > limit_value
175
- limit_value
176
- else
177
- ids.size
178
- end
179
-
180
- # 11 ids with limit 3, offset 9 should give 2 results.
181
- if offset_value && (ids.size - offset_value < expected_size)
182
- expected_size = ids.size - offset_value
183
- end
184
-
185
- if result.size == expected_size
186
- result
187
- else
188
- raise_record_not_found_exception!(ids, result.size, expected_size)
189
- end
190
- end
191
-
192
- def find_some_ordered(ids)
193
- ids = ids.slice(offset_value || 0, limit_value || ids.size) || []
194
-
195
- # CPK
196
- # result = except(:limit, :offset).where(primary_key => ids).records
197
- result = if composite?
198
- except(:limit, :offset).where(cpk_in_predicate(table, primary_keys, ids)).records
199
- else
200
- except(:limit, :offset).where(primary_key => ids).records
201
- end
202
-
203
- if result.size == ids.size
204
- pk_type = @klass.type_for_attribute(primary_key)
205
-
206
- records_by_id = result.index_by(&:id)
207
- # CPK
208
- # ids.map { |id| records_by_id.fetch(pk_type.cast(id)) }
209
- if composite?
210
- ids.map do |id|
211
- typecasted_id = primary_keys.zip(id).map do |col, val|
212
- @klass.type_for_attribute(col).cast(val)
213
- end
214
- records_by_id.fetch(typecasted_id)
215
- end
216
- else
217
- ids.map { |id| records_by_id.fetch(pk_type.cast(id)) }
218
- end
219
- else
220
- raise_record_not_found_exception!(ids, result.size, ids.size)
221
- end
222
- end
223
-
224
- def ordered_relation
225
- if order_values.empty? && (implicit_order_column || primary_key)
226
- # CPK
227
- # order(arel_attribute(implicit_order_column || primary_key).asc)
228
- order(Array(implicit_order_column || primary_key).map {|key| arel_attribute(key).asc})
229
- else
230
- self
231
- end
232
- end
233
- end
234
- end
235
- end
1
+ module CompositePrimaryKeys
2
+ module ActiveRecord
3
+ module FinderMethods
4
+ def apply_join_dependency(eager_loading: group_values.empty?)
5
+ join_dependency = construct_join_dependency(eager_load_values + includes_values, Arel::Nodes::OuterJoin)
6
+ relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
7
+
8
+ if eager_loading && !using_limitable_reflections?(join_dependency.reflections)
9
+ if has_limit_or_offset?
10
+ limited_ids = limited_ids_for(relation)
11
+
12
+ # CPK
13
+ # limited_ids.empty? ? relation.none! : relation.where!(primary_key => limited_ids)
14
+ limited_ids.empty? ? relation.none! : relation.where!(cpk_in_predicate(table, self.primary_keys, limited_ids))
15
+ end
16
+ relation.limit_value = relation.offset_value = nil
17
+ end
18
+
19
+ if block_given?
20
+ yield relation, join_dependency
21
+ else
22
+ relation
23
+ end
24
+ end
25
+
26
+ def limited_ids_for(relation)
27
+ # CPK
28
+ # values = @klass.connection.columns_for_distinct(
29
+ # connection.column_name_from_arel_node(table[primary_key]),
30
+ # relation.order_values
31
+ # )
32
+
33
+ columns = @klass.primary_keys.map do |key|
34
+ connection.visitor.compile(table[key])
35
+ end
36
+ values = @klass.connection.columns_for_distinct(columns, relation.order_values)
37
+
38
+ relation = relation.except(:select).select(values).distinct!
39
+
40
+ id_rows = skip_query_cache_if_necessary { @klass.connection.select_all(relation.arel, "SQL") }
41
+ # CPK
42
+ #id_rows.map { |row| row[primary_key] }
43
+ id_rows.map do |row|
44
+ @klass.primary_keys.map do |key|
45
+ row[key]
46
+ end
47
+ end
48
+ end
49
+
50
+ def construct_relation_for_exists(conditions)
51
+ conditions = sanitize_forbidden_attributes(conditions)
52
+
53
+ if distinct_value && offset_value
54
+ relation = except(:order).limit!(1)
55
+ else
56
+ relation = except(:select, :distinct, :order)._select!(::ActiveRecord::FinderMethods::ONE_AS_ONE).limit!(1)
57
+ end
58
+
59
+ case conditions
60
+ # CPK
61
+ when CompositePrimaryKeys::CompositeKeys
62
+ relation = relation.where(cpk_id_predicate(table, primary_key, conditions))
63
+ # CPK
64
+ when Array
65
+ pk_length = @klass.primary_keys.length
66
+
67
+ if conditions.length == pk_length # E.g. conditions = ['France', 'Paris']
68
+ return self.construct_relation_for_exists(conditions.to_composite_keys)
69
+ else # Assume that conditions contains where relation
70
+ relation = relation.where(conditions)
71
+ end
72
+ when Array, Hash
73
+ relation.where!(conditions) unless conditions.empty?
74
+ else
75
+ relation.where!(primary_key => conditions) unless conditions == :none
76
+ end
77
+
78
+ relation
79
+ end
80
+
81
+ def find_with_ids(*ids)
82
+ raise UnknownPrimaryKey.new(@klass) if primary_key.nil?
83
+
84
+ # CPK
85
+ # expects_array = ids.first.kind_of?(Array)
86
+ ids = CompositePrimaryKeys.normalize(ids, @klass.primary_keys.length)
87
+ expects_array = ids.flatten != ids.flatten(1)
88
+ return ids.first if expects_array && ids.first.empty?
89
+
90
+ # CPK
91
+ # ids = ids.flatten.compact.uniq
92
+ ids = expects_array ? ids.first : ids
93
+
94
+ model_name = @klass.name
95
+
96
+ case ids.size
97
+ when 0
98
+ error_message = "Couldn't find #{model_name} without an ID"
99
+ raise ::ActiveRecord::RecordNotFound.new(error_message, model_name, primary_key)
100
+ when 1
101
+ result = find_one(ids.first)
102
+ expects_array ? [ result ] : result
103
+ else
104
+ find_some(ids)
105
+ end
106
+ end
107
+
108
+ # def last(limit = nil)
109
+ # return find_last(limit) if loaded? || has_limit_or_offset?
110
+ #
111
+ # result = limit(limit || 1)
112
+ # # CPK
113
+ # # result.order!(table[primary_key]) if order_values.empty? && primary_key
114
+ # if order_values.empty? && primary_key
115
+ # if composite?
116
+ # result.order!(primary_keys.map { |pk| table[pk].asc })
117
+ # elsif
118
+ # result.order!(table[primary_key])
119
+ # end
120
+ # end
121
+ #
122
+ # result = result.reverse_order!
123
+ #
124
+ # limit ? result.reverse : result.first
125
+ # rescue ::ActiveRecord::IrreversibleOrderError
126
+ # ActiveSupport::Deprecation.warn(<<-WARNING.squish)
127
+ # Finding a last element by loading the relation when SQL ORDER
128
+ # can not be reversed is deprecated.
129
+ # Rails 5.1 will raise ActiveRecord::IrreversibleOrderError in this case.
130
+ # Please call `to_a.last` if you still want to load the relation.
131
+ # WARNING
132
+ # find_last(limit)
133
+ # end
134
+
135
+ def find_one(id)
136
+ if ::ActiveRecord::Base === id
137
+ raise ArgumentError, <<-MSG.squish
138
+ You are passing an instance of ActiveRecord::Base to `find`.
139
+ Please pass the id of the object by calling `.id`.
140
+ MSG
141
+ end
142
+
143
+ # CPK
144
+ #relation = where(primary_key => id)
145
+ relation = where(cpk_id_predicate(table, primary_keys, id))
146
+ record = relation.take
147
+
148
+ raise_record_not_found_exception!(id, 0, 1) unless record
149
+
150
+ record
151
+ end
152
+
153
+ def find_some(ids)
154
+ # CPK
155
+ if composite?
156
+ ids = if ids.length == 1
157
+ CompositePrimaryKeys::CompositeKeys.parse(ids.first)
158
+ else
159
+ ids.to_composite_keys
160
+ end
161
+ end
162
+
163
+ return find_some_ordered(ids) unless order_values.present?
164
+
165
+ # CPK
166
+ # result = where(primary_key => ids).to_a
167
+ result = if composite?
168
+ result = where(cpk_in_predicate(table, primary_keys, ids)).to_a
169
+ else
170
+ result = where(primary_key => ids).to_a
171
+ end
172
+
173
+ expected_size =
174
+ if limit_value && ids.size > limit_value
175
+ limit_value
176
+ else
177
+ ids.size
178
+ end
179
+
180
+ # 11 ids with limit 3, offset 9 should give 2 results.
181
+ if offset_value && (ids.size - offset_value < expected_size)
182
+ expected_size = ids.size - offset_value
183
+ end
184
+
185
+ if result.size == expected_size
186
+ result
187
+ else
188
+ raise_record_not_found_exception!(ids, result.size, expected_size)
189
+ end
190
+ end
191
+
192
+ def find_some_ordered(ids)
193
+ ids = ids.slice(offset_value || 0, limit_value || ids.size) || []
194
+
195
+ # CPK
196
+ # result = except(:limit, :offset).where(primary_key => ids).records
197
+ result = if composite?
198
+ except(:limit, :offset).where(cpk_in_predicate(table, primary_keys, ids)).records
199
+ else
200
+ except(:limit, :offset).where(primary_key => ids).records
201
+ end
202
+
203
+ if result.size == ids.size
204
+ pk_type = @klass.type_for_attribute(primary_key)
205
+
206
+ records_by_id = result.index_by(&:id)
207
+ # CPK
208
+ # ids.map { |id| records_by_id.fetch(pk_type.cast(id)) }
209
+ if composite?
210
+ ids.map do |id|
211
+ typecasted_id = primary_keys.zip(id).map do |col, val|
212
+ @klass.type_for_attribute(col).cast(val)
213
+ end
214
+ records_by_id.fetch(typecasted_id)
215
+ end
216
+ else
217
+ ids.map { |id| records_by_id.fetch(pk_type.cast(id)) }
218
+ end
219
+ else
220
+ raise_record_not_found_exception!(ids, result.size, ids.size)
221
+ end
222
+ end
223
+
224
+ def ordered_relation
225
+ if order_values.empty? && (implicit_order_column || primary_key)
226
+ # CPK
227
+ # order(table[implicit_order_column || primary_key].asc)
228
+ order(Array(implicit_order_column || primary_key).map {|key| table[key].asc})
229
+ else
230
+ self
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
@@ -1,20 +1,39 @@
1
- module ActiveRecord
2
- class PredicateBuilder
3
- class AssociationQueryValue
4
- def queries
5
- # CPK
6
- if associated_table.association_join_foreign_key.is_a?(Array)
7
- if ids.is_a?(ActiveRecord::Relation)
8
- ids.map do |id|
9
- associated_table.association_join_foreign_key.zip(id.id).to_h
10
- end
11
- else
12
- [associated_table.association_join_foreign_key.zip(ids).to_h]
13
- end
14
- else
15
- [associated_table.association_join_foreign_key.to_s => ids]
16
- end
17
- end
18
- end
19
- end
20
- end
1
+ module ActiveRecord
2
+ class PredicateBuilder
3
+ class AssociationQueryValue
4
+ def queries
5
+ # CPK
6
+ if associated_table.join_foreign_key.is_a?(Array)
7
+ if ids.is_a?(ActiveRecord::Relation)
8
+ ids.map do |id|
9
+ associated_table.join_foreign_key.zip(id.id).to_h
10
+ end
11
+ else
12
+ [associated_table.join_foreign_key.zip(ids).to_h]
13
+ end
14
+ else
15
+ [associated_table.join_foreign_key => ids]
16
+ end
17
+ end
18
+
19
+ def ids
20
+ case value
21
+ when Relation
22
+ value.select_values.empty? ? value.select(primary_key) : value
23
+ when Array
24
+ value.map { |v| convert_to_id(v) }
25
+ else
26
+ # CPK
27
+ # convert_to_id(value)
28
+ if value.nil?
29
+ nil
30
+ elsif value.respond_to?(:composite?) && value.composite?
31
+ value.class.primary_keys.zip(value.id)
32
+ else
33
+ convert_to_id(value)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,43 +1,43 @@
1
- module CompositePrimaryKeys
2
- module ActiveRecord
3
- module QueryMethods
4
- def reverse_sql_order(order_query)
5
- if order_query.empty?
6
- # CPK
7
- # return [arel_attribute(primary_key).desc] if primary_key
8
-
9
- if primary_key
10
- # break apart CPKs
11
- return primary_key.map do |key|
12
- arel_attribute(key).desc
13
- end
14
- else
15
- raise IrreversibleOrderError,
16
- "Relation has no current order and table has no primary key to be used as default order"
17
- end
18
- end
19
-
20
- order_query.flat_map do |o|
21
- order_query.flat_map do |o|
22
- case o
23
- when Arel::Attribute
24
- o.desc
25
- when Arel::Nodes::Ordering
26
- o.reverse
27
- when String
28
- if does_not_support_reverse?(o)
29
- raise IrreversibleOrderError, "Order #{o.inspect} can not be reversed automatically"
30
- end
31
- o.split(",").map! do |s|
32
- s.strip!
33
- s.gsub!(/\sasc\Z/i, " DESC") || s.gsub!(/\sdesc\Z/i, " ASC") || (s << " DESC")
34
- end
35
- else
36
- o
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
1
+ module CompositePrimaryKeys
2
+ module ActiveRecord
3
+ module QueryMethods
4
+ def reverse_sql_order(order_query)
5
+ if order_query.empty?
6
+ # CPK
7
+ # return [table[primary_key].desc] if primary_key
8
+
9
+ if primary_key
10
+ # break apart CPKs
11
+ return primary_key.map do |key|
12
+ table[key].desc
13
+ end
14
+ else
15
+ raise IrreversibleOrderError,
16
+ "Relation has no current order and table has no primary key to be used as default order"
17
+ end
18
+ end
19
+
20
+ order_query.flat_map do |o|
21
+ order_query.flat_map do |o|
22
+ case o
23
+ when Arel::Attribute
24
+ o.desc
25
+ when Arel::Nodes::Ordering
26
+ o.reverse
27
+ when String
28
+ if does_not_support_reverse?(o)
29
+ raise IrreversibleOrderError, "Order #{o.inspect} can not be reversed automatically"
30
+ end
31
+ o.split(",").map! do |s|
32
+ s.strip!
33
+ s.gsub!(/\sasc\Z/i, " DESC") || s.gsub!(/\sdesc\Z/i, " ASC") || (s << " DESC")
34
+ end
35
+ else
36
+ o
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
43
  end
@@ -1,24 +1,19 @@
1
- module ActiveRecord
2
- class Relation
3
- class WhereClause
4
- def to_h(table_name = nil)
5
- equalities = equalities(predicates)
6
-
7
- # CPK Adds this line, because ours are coming in with AND->{EQUALITY, EQUALITY}
8
- equalities = predicates.grep(Arel::Nodes::And).map(&:children).flatten.grep(Arel::Nodes::Equality) if equalities.empty?
9
-
10
- if table_name
11
- equalities = equalities.select do |node|
12
- node.left.relation.name == table_name
13
- end
14
- end
15
-
16
- equalities.map { |node|
17
- name = node.left.name.to_s
18
- value = extract_node_value(node.right)
19
- [name, value]
20
- }.to_h
21
- end
22
- end
23
- end
1
+ module ActiveRecord
2
+ class Relation
3
+ class WhereClause
4
+ def to_h(table_name = nil, equality_only: false)
5
+ equalities = equalities(predicates, equality_only)
6
+
7
+ # CPK Adds this line, because ours are coming in with AND->{EQUALITY, EQUALITY}
8
+ equalities = predicates.grep(Arel::Nodes::And).map(&:children).flatten.grep(Arel::Nodes::Equality) if equalities.empty?
9
+
10
+ equalities.each_with_object({}) do |node, hash|
11
+ next if table_name&.!= node.left.relation.name
12
+ name = node.left.name.to_s
13
+ value = extract_node_value(node.right)
14
+ hash[name] = value
15
+ end
16
+ end
17
+ end
18
+ end
24
19
  end