composite_primary_keys 8.1.8 → 9.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/History.rdoc +3 -25
- data/README.rdoc +1 -0
- data/README_DB2.rdoc +33 -33
- data/Rakefile +34 -34
- data/lib/composite_primary_keys.rb +4 -11
- data/lib/composite_primary_keys/associations/association.rb +14 -12
- data/lib/composite_primary_keys/associations/association_scope.rb +27 -54
- data/lib/composite_primary_keys/associations/collection_association.rb +22 -8
- data/lib/composite_primary_keys/associations/has_many_association.rb +16 -54
- data/lib/composite_primary_keys/associations/has_many_through_association.rb +58 -58
- data/lib/composite_primary_keys/associations/join_dependency.rb +74 -56
- data/lib/composite_primary_keys/associations/join_dependency/join_association.rb +13 -11
- data/lib/composite_primary_keys/associations/preloader/association.rb +75 -72
- data/lib/composite_primary_keys/associations/singular_association.rb +8 -12
- data/lib/composite_primary_keys/attribute_methods.rb +6 -4
- data/lib/composite_primary_keys/attribute_methods/primary_key.rb +13 -11
- data/lib/composite_primary_keys/attribute_methods/read.rb +16 -15
- data/lib/composite_primary_keys/attribute_methods/write.rb +21 -19
- data/lib/composite_primary_keys/attribute_set/builder.rb +13 -11
- data/lib/composite_primary_keys/base.rb +5 -69
- data/lib/composite_primary_keys/composite_arrays.rb +8 -51
- data/lib/composite_primary_keys/composite_predicates.rb +7 -16
- data/lib/composite_primary_keys/connection_adapters/abstract_adapter.rb +10 -10
- data/lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb +42 -11
- data/lib/composite_primary_keys/core.rb +46 -45
- data/lib/composite_primary_keys/dirty.rb +19 -19
- data/lib/composite_primary_keys/fixtures.rb +19 -17
- data/lib/composite_primary_keys/locking/optimistic.rb +48 -44
- data/lib/composite_primary_keys/nested_attributes.rb +64 -53
- data/lib/composite_primary_keys/persistence.rb +49 -41
- data/lib/composite_primary_keys/relation.rb +22 -47
- data/lib/composite_primary_keys/relation/batches.rb +33 -30
- data/lib/composite_primary_keys/relation/calculations.rb +3 -7
- data/lib/composite_primary_keys/relation/finder_methods.rb +123 -56
- data/lib/composite_primary_keys/relation/predicate_builder.rb +18 -29
- data/lib/composite_primary_keys/relation/where_clause.rb +33 -0
- data/lib/composite_primary_keys/sanitization.rb +45 -38
- data/lib/composite_primary_keys/validations/uniqueness.rb +37 -37
- data/lib/composite_primary_keys/version.rb +4 -4
- data/scripts/console.rb +48 -48
- data/scripts/txt2html +76 -76
- data/scripts/txt2js +65 -65
- data/tasks/databases/mysql.rake +42 -42
- data/tasks/databases/postgresql.rake +47 -47
- data/tasks/databases/sqlite3.rake +27 -27
- data/tasks/website.rake +18 -18
- data/test/README_tests.rdoc +56 -56
- data/test/abstract_unit.rb +10 -9
- data/test/connections/connection_spec.rb +18 -18
- data/test/connections/databases.yml +9 -39
- data/test/connections/native_ibm_db/connection.rb +18 -18
- data/test/connections/native_mysql/connection.rb +17 -17
- data/test/connections/native_postgresql/connection.rb +12 -12
- data/test/connections/native_sqlite3/connection.rb +9 -9
- data/test/db_test.rb +52 -52
- data/test/fixtures/article.rb +5 -5
- data/test/fixtures/articles.yml +6 -6
- data/test/fixtures/capitol.rb +3 -3
- data/test/fixtures/capitols.yml +16 -16
- data/test/fixtures/comments.yml +15 -15
- data/test/fixtures/db_definitions/mysql.sql +2 -12
- data/test/fixtures/db_definitions/oracle.sql +1 -2
- data/test/fixtures/db_definitions/postgresql.sql +0 -10
- data/test/fixtures/db_definitions/sqlite.sql +0 -9
- data/test/fixtures/db_definitions/sqlserver.sql +1 -2
- data/test/fixtures/department.rb +5 -5
- data/test/fixtures/departments.yml +15 -15
- data/test/fixtures/dorms.yml +4 -4
- data/test/fixtures/employee.rb +1 -2
- data/test/fixtures/employees.yml +19 -23
- data/test/fixtures/group.rb +2 -2
- data/test/fixtures/groups.yml +6 -6
- data/test/fixtures/hack.rb +4 -4
- data/test/fixtures/hacks.yml +2 -2
- data/test/fixtures/membership_status.rb +2 -2
- data/test/fixtures/product.rb +9 -9
- data/test/fixtures/product_tariff.rb +5 -5
- data/test/fixtures/products.yml +11 -11
- data/test/fixtures/reading.rb +4 -4
- data/test/fixtures/readings.yml +10 -10
- data/test/fixtures/reference_code_using_composite_key_alias.rb +8 -8
- data/test/fixtures/reference_code_using_simple_key_alias.rb +8 -8
- data/test/fixtures/reference_codes.yml +28 -28
- data/test/fixtures/reference_type.rb +1 -1
- data/test/fixtures/reference_types.yml +9 -9
- data/test/fixtures/restaurant.rb +9 -9
- data/test/fixtures/restaurants.yml +14 -14
- data/test/fixtures/restaurants_suburbs.yml +10 -10
- data/test/fixtures/room.rb +11 -11
- data/test/fixtures/room_assignment.rb +13 -13
- data/test/fixtures/room_assignments.yml +24 -24
- data/test/fixtures/room_attribute.rb +2 -2
- data/test/fixtures/room_attribute_assignment.rb +4 -4
- data/test/fixtures/room_attribute_assignments.yml +4 -4
- data/test/fixtures/room_attributes.yml +2 -2
- data/test/fixtures/rooms.yml +12 -12
- data/test/fixtures/seat.rb +5 -5
- data/test/fixtures/seats.yml +8 -8
- data/test/fixtures/street.rb +2 -2
- data/test/fixtures/streets.yml +16 -16
- data/test/fixtures/student.rb +3 -3
- data/test/fixtures/students.yml +15 -15
- data/test/fixtures/suburbs.yml +14 -14
- data/test/fixtures/tariff.rb +5 -5
- data/test/fixtures/tariffs.yml +14 -14
- data/test/fixtures/user.rb +0 -1
- data/test/plugins/pagination.rb +405 -405
- data/test/plugins/pagination_helper.rb +135 -135
- data/test/setup.rb +50 -50
- data/test/test_aliases.rb +18 -18
- data/test/test_associations.rb +7 -18
- data/test/test_composite_arrays.rb +24 -38
- data/test/test_counter_cache.rb +30 -30
- data/test/test_create.rb +5 -5
- data/test/test_delete_all.rb +7 -13
- data/test/test_dup.rb +37 -37
- data/test/test_exists.rb +39 -39
- data/test/test_find.rb +16 -12
- data/test/test_habtm.rb +26 -2
- data/test/test_ids.rb +109 -116
- data/test/test_miscellaneous.rb +32 -32
- data/test/test_pagination.rb +35 -35
- data/test/test_polymorphic.rb +0 -7
- data/test/test_predicates.rb +9 -28
- data/test/test_update.rb +3 -5
- data/test/test_validations.rb +13 -13
- metadata +24 -32
- data/lib/composite_primary_keys/arel/visitors/to_sql.rb +0 -36
- data/lib/composite_primary_keys/attribute_methods/dirty.rb +0 -29
- data/lib/composite_primary_keys/autosave_association.rb +0 -67
- data/lib/composite_primary_keys/connection_adapters/abstract_mysql_adapter.rb +0 -23
- data/test/fixtures/pk_called_id.rb +0 -5
- data/test/fixtures/pk_called_ids.yml +0 -11
- data/test/test_find_in_batches.rb +0 -30
- data/test/test_update_all.rb +0 -17
@@ -1,36 +0,0 @@
|
|
1
|
-
module Arel
|
2
|
-
module Visitors
|
3
|
-
class ToSql
|
4
|
-
def visit_Arel_Attributes_Attribute o, collector
|
5
|
-
join_name = o.relation.table_alias || o.relation.name
|
6
|
-
table_name = quote_table_name join_name
|
7
|
-
|
8
|
-
if o.name.is_a? Array
|
9
|
-
collector <<
|
10
|
-
o.name.map{ |field| "#{table_name}.#{quote_column_name(field)}" }.join(",")
|
11
|
-
else
|
12
|
-
collector << "#{table_name}.#{quote_column_name o.name}"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def visit_Arel_Nodes_In o, collector
|
17
|
-
if Array === o.right && o.right.empty?
|
18
|
-
collector << '1=0'
|
19
|
-
else
|
20
|
-
# CPK
|
21
|
-
# collector = visit o.left, collector
|
22
|
-
if o.left.respond_to?(:name) && o.left.name.is_a?(Array)
|
23
|
-
collector << "("
|
24
|
-
collector = visit(o.left, collector)
|
25
|
-
collector << ")"
|
26
|
-
else
|
27
|
-
collector = visit o.left, collector
|
28
|
-
end
|
29
|
-
|
30
|
-
collector << " IN ("
|
31
|
-
visit(o.right, collector) << ")"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module AttributeMethods
|
3
|
-
module Dirty
|
4
|
-
def write_attribute(attr, value)
|
5
|
-
# CPK
|
6
|
-
if attr.kind_of?(Array)
|
7
|
-
# A *composite* attribute can't be marked as changed! So do nothing now.
|
8
|
-
# We will come back in here with an *individual* attribute when Write#write_attribute looks through the individual attributes comprising this composite key:
|
9
|
-
value = [nil] * attr.length if value.nil?
|
10
|
-
[attr, value].transpose.map {|name,val| write_attribute(name, val)}
|
11
|
-
else
|
12
|
-
attr = attr.to_s
|
13
|
-
|
14
|
-
old_value = old_attribute_value(attr)
|
15
|
-
|
16
|
-
result = super
|
17
|
-
store_original_raw_attribute(attr)
|
18
|
-
save_changed_attribute(attr, old_value)
|
19
|
-
result
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
ActiveRecord::Base.class_eval do
|
27
|
-
alias :[]= :write_attribute
|
28
|
-
public :[]=
|
29
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module AutosaveAssociation
|
3
|
-
private
|
4
|
-
# Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
|
5
|
-
#
|
6
|
-
# In addition, it will destroy the association if it was marked for destruction.
|
7
|
-
def save_belongs_to_association(reflection)
|
8
|
-
association = association_instance_get(reflection.name)
|
9
|
-
record = association && association.load_target
|
10
|
-
if record && !record.destroyed?
|
11
|
-
autosave = reflection.options[:autosave]
|
12
|
-
|
13
|
-
if autosave && record.marked_for_destruction?
|
14
|
-
self[reflection.foreign_key] = nil
|
15
|
-
record.destroy
|
16
|
-
elsif autosave != false
|
17
|
-
saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
|
18
|
-
|
19
|
-
if association.updated?
|
20
|
-
# CPK
|
21
|
-
# association_id = record.send(reflection.options[:primary_key] || :id)
|
22
|
-
association_id = reflection.options[:primary_key] ? record.read_attribute(reflection.options[:primary_key]) : record.id
|
23
|
-
self[reflection.foreign_key] = association_id
|
24
|
-
association.loaded!
|
25
|
-
end
|
26
|
-
|
27
|
-
saved if autosave
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Saves the associated record if it's new or <tt>:autosave</tt> is enabled
|
33
|
-
# on the association.
|
34
|
-
#
|
35
|
-
# In addition, it will destroy the association if it was marked for
|
36
|
-
# destruction with mark_for_destruction.
|
37
|
-
#
|
38
|
-
# This all happens inside a transaction, _if_ the Transactions module is included into
|
39
|
-
# ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
|
40
|
-
def save_has_one_association(reflection)
|
41
|
-
association = association_instance_get(reflection.name)
|
42
|
-
record = association && association.load_target
|
43
|
-
|
44
|
-
if record && !record.destroyed?
|
45
|
-
autosave = reflection.options[:autosave]
|
46
|
-
|
47
|
-
if autosave && record.marked_for_destruction?
|
48
|
-
record.destroy
|
49
|
-
elsif autosave != false
|
50
|
-
# CPK
|
51
|
-
#key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id
|
52
|
-
key = reflection.options[:primary_key] ? read_attribute(reflection.options[:primary_key]) : id
|
53
|
-
|
54
|
-
if (autosave && record.changed_for_autosave?) || new_record? || record_changed?(reflection, record, key)
|
55
|
-
unless reflection.through_reflection
|
56
|
-
record[reflection.foreign_key] = key
|
57
|
-
end
|
58
|
-
|
59
|
-
saved = record.save(:validate => !autosave)
|
60
|
-
raise ActiveRecord::Rollback if !saved && autosave
|
61
|
-
saved
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module ConnectionAdapters
|
3
|
-
class AbstractMysqlAdapter < AbstractAdapter
|
4
|
-
# MySQL is too stupid to create a temporary table for use subquery, so we have
|
5
|
-
# to give it some prompting in the form of a subsubquery. Ugh!
|
6
|
-
def subquery_for(key, select)
|
7
|
-
subsubselect = select.clone
|
8
|
-
subsubselect.projections = [key]
|
9
|
-
|
10
|
-
# Materialize subquery by adding distinct
|
11
|
-
# to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on'
|
12
|
-
subsubselect.distinct unless select.limit || select.offset || select.orders.any?
|
13
|
-
|
14
|
-
subselect = Arel::SelectManager.new(select.engine)
|
15
|
-
|
16
|
-
# subselect.project Arel.sql(key.name)
|
17
|
-
arel_table = select.engine.arel_table
|
18
|
-
subselect.project *[key].map { |x| arel_table[x.name] }
|
19
|
-
subselect.from subsubselect.as('__active_record_temp')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require File.expand_path('../abstract_unit', __FILE__)
|
2
|
-
|
3
|
-
class TestFindInBatches < ActiveSupport::TestCase
|
4
|
-
fixtures :capitols
|
5
|
-
|
6
|
-
def test_in_batches
|
7
|
-
capitols = []
|
8
|
-
Capitol.find_in_batches do |chunk|
|
9
|
-
capitols += chunk.map(&:country)
|
10
|
-
end
|
11
|
-
assert_equal(capitols, ['Canada', 'France', 'Mexico', 'The Netherlands'])
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_in_small_batches
|
15
|
-
capitols = []
|
16
|
-
Capitol.find_in_batches(batch_size: 2) do |chunk|
|
17
|
-
capitols += chunk.map(&:country)
|
18
|
-
end
|
19
|
-
|
20
|
-
assert_equal(capitols, ['Canada', 'France', 'Mexico', 'The Netherlands'])
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_in_one_unit_batch
|
24
|
-
capitols = []
|
25
|
-
Capitol.find_in_batches(batch_size: 1) do |chunk|
|
26
|
-
capitols += chunk.map(&:country)
|
27
|
-
end
|
28
|
-
assert_equal(capitols, ['Canada', 'France', 'Mexico', 'The Netherlands'])
|
29
|
-
end
|
30
|
-
end
|
data/test/test_update_all.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
require File.expand_path('../abstract_unit', __FILE__)
|
2
|
-
|
3
|
-
class TestUpdateAll < ActiveSupport::TestCase
|
4
|
-
fixtures :articles, :users
|
5
|
-
|
6
|
-
def test_update_all
|
7
|
-
first_article = Article.first
|
8
|
-
users_count = first_article.users.count
|
9
|
-
# limit forces a subquery
|
10
|
-
first_article.users.limit(1).update_all(name: 'test')
|
11
|
-
assert_equal(
|
12
|
-
User.joins(readings: :article)
|
13
|
-
.merge(Article.where(id: first_article))
|
14
|
-
.where(name: 'test').count, users_count
|
15
|
-
)
|
16
|
-
end
|
17
|
-
end
|