composite_primary_keys 9.0.4 → 9.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +20 -0
  3. data/Rakefile +37 -34
  4. data/lib/composite_primary_keys.rb +5 -10
  5. data/lib/composite_primary_keys/arel/in.rb +6 -6
  6. data/lib/composite_primary_keys/arel/sqlserver.rb +36 -0
  7. data/lib/composite_primary_keys/associations/association_scope.rb +51 -29
  8. data/lib/composite_primary_keys/attribute_methods/read.rb +3 -1
  9. data/lib/composite_primary_keys/connection_adapters/abstract_mysql_adapter.rb +22 -0
  10. data/lib/composite_primary_keys/relation.rb +30 -0
  11. data/lib/composite_primary_keys/relation/query_methods.rb +25 -36
  12. data/lib/composite_primary_keys/sanitization.rb +31 -47
  13. data/lib/composite_primary_keys/version.rb +1 -1
  14. data/tasks/databases/mysql.rake +40 -42
  15. data/tasks/databases/oracle.rake +29 -15
  16. data/tasks/databases/postgresql.rake +38 -47
  17. data/tasks/databases/sqlite.rake +25 -0
  18. data/tasks/databases/sqlserver.rake +32 -16
  19. data/test/abstract_unit.rb +12 -11
  20. data/test/connections/connection_spec.rb +27 -18
  21. data/test/connections/databases.ci.yml +5 -4
  22. data/test/connections/databases.example.yml +19 -4
  23. data/test/connections/databases.yml +25 -4
  24. data/test/fixtures/article.rb +6 -5
  25. data/test/fixtures/db_definitions/mysql.sql +16 -7
  26. data/test/fixtures/db_definitions/oracle.drop.sql +2 -0
  27. data/test/fixtures/db_definitions/oracle.sql +25 -15
  28. data/test/fixtures/db_definitions/postgresql.sql +11 -2
  29. data/test/fixtures/db_definitions/sqlite.sql +8 -0
  30. data/test/fixtures/db_definitions/sqlserver.sql +19 -33
  31. data/test/fixtures/pk_called_id.rb +5 -0
  32. data/test/fixtures/pk_called_ids.yml +11 -0
  33. data/test/test_associations.rb +334 -332
  34. data/test/test_create.rb +9 -1
  35. data/test/test_delete.rb +17 -39
  36. data/test/test_ids.rb +113 -109
  37. data/test/test_preload.rb +94 -0
  38. data/test/test_suite.rb +1 -1
  39. data/test/test_update.rb +12 -7
  40. metadata +14 -24
  41. data/lib/composite_primary_keys/associations/singular_association.rb +0 -14
  42. data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb +0 -71
  43. data/lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb +0 -50
  44. data/lib/composite_primary_keys/dirty.rb +0 -19
  45. data/lib/composite_primary_keys/validations/uniqueness.rb +0 -41
  46. data/tasks/databases/oracle_enhanced.rake +0 -27
  47. data/tasks/databases/sqlite3.rake +0 -27
  48. data/test/connections/native_ibm_db/connection.rb +0 -19
  49. data/test/connections/native_mysql/connection.rb +0 -17
  50. data/test/connections/native_oracle/connection.rb +0 -11
  51. data/test/connections/native_oracle_enhanced/connection.rb +0 -16
  52. data/test/connections/native_postgresql/connection.rb +0 -13
  53. data/test/connections/native_sqlite3/connection.rb +0 -9
  54. data/test/connections/native_sqlserver/connection.rb +0 -11
  55. data/test/fixtures/db_definitions/sqlserver.drop.sql +0 -92
  56. data/test/test_delete_all.rb +0 -29
@@ -1,7 +1,7 @@
1
1
  require File.expand_path('../abstract_unit', __FILE__)
2
2
 
3
3
  class TestCreate < ActiveSupport::TestCase
4
- fixtures :students, :dorms, :rooms, :room_assignments, :reference_types, :reference_codes, :streets, :suburbs
4
+ fixtures :articles, :students, :dorms, :rooms, :room_assignments, :reference_types, :reference_codes, :streets, :suburbs
5
5
 
6
6
  CLASSES = {
7
7
  :single => {
@@ -153,4 +153,12 @@ class TestCreate < ActiveSupport::TestCase
153
153
  assert_equal(assignment1, room.room_assignments[0])
154
154
  assert_equal(assignment2, room.room_assignments[1])
155
155
  end
156
+
157
+ def test_create_article_invalid_id
158
+ error = assert_raises(ActiveRecord::RecordInvalid) do
159
+ article = Article.create!(:id => 1)
160
+ end
161
+
162
+ assert_equal('Validation failed: Id has already been taken', error.to_s)
163
+ end
156
164
  end
@@ -4,50 +4,28 @@ class TestDelete < ActiveSupport::TestCase
4
4
  fixtures :articles, :departments, :employees, :products, :tariffs, :product_tariffs,
5
5
  :reference_types, :reference_codes
6
6
 
7
- CLASSES = {
8
- :single => {
9
- :class => ReferenceType,
10
- :primary_keys => :reference_type_id,
11
- },
12
- :dual => {
13
- :class => ReferenceCode,
14
- :primary_keys => [:reference_type_id, :reference_code],
15
- },
16
- }
17
-
18
- def setup
19
- self.class.classes = CLASSES
20
- end
21
-
22
- def test_destroy_one
23
- testing_with do
24
- assert @first.destroy
25
- end
26
- end
27
-
28
- def test_destroy_one_alone_via_class
29
- testing_with do
30
- assert @klass.destroy(@first.id)
31
- end
7
+ def test_delete_one
8
+ assert_equal(5, ReferenceCode.count)
9
+ ReferenceCode.first.delete
10
+ assert_equal(4, ReferenceCode.count)
32
11
  end
33
12
 
34
- def test_delete_one_alone
35
- testing_with do
36
- assert @klass.delete(@first.id)
37
- end
13
+ def test_delete_one_with_id
14
+ assert_equal(5, ReferenceCode.count)
15
+ ReferenceCode.delete(ReferenceCode.first.id)
16
+ assert_equal(4, ReferenceCode.count)
38
17
  end
39
18
 
40
- def test_delete_many
41
- testing_with do
42
- to_delete = @klass.limit(2)
43
- assert_equal 2, to_delete.length
44
- end
19
+ def test_destroy_one
20
+ assert_equal(5, ReferenceCode.count)
21
+ ReferenceCode.first.destroy
22
+ assert_equal(4, ReferenceCode.count)
45
23
  end
46
24
 
47
25
  def test_delete_all
48
- testing_with do
49
- @klass.delete_all
50
- end
26
+ refute_empty(ReferenceCode.all)
27
+ ReferenceCode.delete_all
28
+ assert_empty(ReferenceCode.all)
51
29
  end
52
30
 
53
31
  def test_delete_all_with_join
@@ -56,8 +34,8 @@ class TestDelete < ActiveSupport::TestCase
56
34
  assert_equal(4, Department.count)
57
35
 
58
36
  Department.joins(:employees).
59
- where('departments.department_id = ?', department.department_id).
60
- where('departments.location_id = ?', department.location_id).
37
+ where('departments.department_id = ?', department.department_id).
38
+ where('departments.location_id = ?', department.location_id).
61
39
  delete_all
62
40
 
63
41
  assert_equal(3, Department.count)
@@ -1,109 +1,113 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class ChildCpkTest < ReferenceCode
4
- end
5
-
6
- class TestIds < ActiveSupport::TestCase
7
- fixtures :reference_types, :reference_codes
8
-
9
- CLASSES = {
10
- :single => {
11
- :class => ReferenceType,
12
- :primary_keys => [:reference_type_id],
13
- },
14
- :dual => {
15
- :class => ReferenceCode,
16
- :primary_keys => [:reference_type_id, :reference_code],
17
- },
18
- :dual_strs => {
19
- :class => ReferenceCode,
20
- :primary_keys => ['reference_type_id', 'reference_code'],
21
- },
22
- }
23
-
24
- def setup
25
- self.class.classes = CLASSES
26
- end
27
-
28
- def test_id
29
- testing_with do
30
- assert_equal @first.id, @first.ids if composite?
31
- assert_kind_of(CompositePrimaryKeys::CompositeKeys, @first.id) if composite?
32
- end
33
- end
34
-
35
- def test_to_param
36
- testing_with do
37
- assert_equal '1,1', @first.to_param if composite?
38
- end
39
- end
40
-
41
- def test_ids_to_s
42
- testing_with do
43
- order = @klass.primary_key.is_a?(String) ? @klass.primary_key : @klass.primary_key.join(',')
44
- to_test = @klass.order(order)[0..1].map(&:id)
45
- assert_equal '(1,1),(1,2)', @klass.ids_to_s(to_test) if @key_test == :dual
46
- assert_equal '1,1;1,2', @klass.ids_to_s(to_test, ',', ';', '', '') if @key_test == :dual
47
- end
48
- end
49
-
50
- def test_set_ids_string
51
- testing_with do
52
- array = @primary_keys.collect {|key| 5}
53
- expected = composite? ? array.to_composite_keys : array.first
54
- @first.id = expected.to_s
55
- assert_equal expected, @first.id
56
- end
57
- end
58
-
59
- def test_set_ids_array
60
- testing_with do
61
- array = @primary_keys.collect {|key| 5}
62
- expected = composite? ? array.to_composite_keys : array.first
63
- @first.id = expected
64
- assert_equal expected, @first.id
65
- end
66
- end
67
-
68
- def test_set_ids_comp
69
- testing_with do
70
- array = @primary_keys.collect {|key| 5}
71
- expected = composite? ? array.to_composite_keys : array.first
72
- @first.id = expected
73
- assert_equal expected, @first.id
74
- end
75
- end
76
-
77
- def test_primary_keys
78
- testing_with do
79
- if composite?
80
- assert_not_nil @klass.primary_keys
81
- assert_equal @primary_keys.map {|key| key.to_s}, @klass.primary_keys
82
- assert_equal @klass.primary_keys, @klass.primary_key
83
- assert_kind_of(CompositePrimaryKeys::CompositeKeys, @klass.primary_keys)
84
- assert_equal @primary_keys.map {|key| key.to_sym}.join(','), @klass.primary_key.to_s
85
- else
86
- assert_not_nil @klass.primary_key
87
- assert_equal @primary_keys.first, @klass.primary_key.to_sym
88
- assert_equal @primary_keys.first.to_s, @klass.primary_key.to_s
89
- end
90
- end
91
- end
92
-
93
- def test_inherited_primary_keys
94
- assert_equal(["reference_type_id", "reference_code"], ChildCpkTest.primary_keys)
95
- end
96
-
97
- def test_inherited_ids
98
- cpk_test = ChildCpkTest.new
99
- assert_equal([nil, nil], cpk_test.id)
100
- end
101
-
102
- def test_assign_ids
103
- ref_code = ReferenceCode.new
104
- assert_equal([nil, nil], ref_code.id)
105
-
106
- ref_code.id = [2,1]
107
- assert_equal([2,1], ref_code.id)
108
- end
109
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class ChildCpkTest < ReferenceCode
4
+ end
5
+
6
+ class TestIds < ActiveSupport::TestCase
7
+ fixtures :reference_types, :reference_codes, :pk_called_ids
8
+
9
+ CLASSES = {
10
+ :single => {
11
+ :class => ReferenceType,
12
+ :primary_keys => [:reference_type_id],
13
+ },
14
+ :dual => {
15
+ :class => ReferenceCode,
16
+ :primary_keys => [:reference_type_id, :reference_code],
17
+ },
18
+ :dual_strs => {
19
+ :class => ReferenceCode,
20
+ :primary_keys => ['reference_type_id', 'reference_code'],
21
+ },
22
+ :pk_called_id => {
23
+ :class => PkCalledId,
24
+ :primary_keys => ['id', 'reference_code'],
25
+ },
26
+ }
27
+
28
+ def setup
29
+ self.class.classes = CLASSES
30
+ end
31
+
32
+ def test_id
33
+ testing_with do
34
+ assert_equal @first.id, @first.ids if composite?
35
+ assert_kind_of(CompositePrimaryKeys::CompositeKeys, @first.id) if composite?
36
+ end
37
+ end
38
+
39
+ def test_to_param
40
+ testing_with do
41
+ assert_equal '1,1', @first.to_param if composite?
42
+ end
43
+ end
44
+
45
+ def test_ids_to_s
46
+ testing_with do
47
+ order = @klass.primary_key.is_a?(String) ? @klass.primary_key : @klass.primary_key.join(',')
48
+ to_test = @klass.order(order)[0..1].map(&:id)
49
+ assert_equal '(1,1),(1,2)', @klass.ids_to_s(to_test) if @key_test == :dual
50
+ assert_equal '1,1;1,2', @klass.ids_to_s(to_test, ',', ';', '', '') if @key_test == :dual
51
+ end
52
+ end
53
+
54
+ def test_set_ids_string
55
+ testing_with do
56
+ array = @primary_keys.collect {|key| 5}
57
+ expected = composite? ? array.to_composite_keys : array.first
58
+ @first.id = expected.to_s
59
+ assert_equal expected, @first.id
60
+ end
61
+ end
62
+
63
+ def test_set_ids_array
64
+ testing_with do
65
+ array = @primary_keys.collect {|key| 5}
66
+ expected = composite? ? array.to_composite_keys : array.first
67
+ @first.id = expected
68
+ assert_equal expected, @first.id
69
+ end
70
+ end
71
+
72
+ def test_set_ids_comp
73
+ testing_with do
74
+ array = @primary_keys.collect {|key| 5}
75
+ expected = composite? ? array.to_composite_keys : array.first
76
+ @first.id = expected
77
+ assert_equal expected, @first.id
78
+ end
79
+ end
80
+
81
+ def test_primary_keys
82
+ testing_with do
83
+ if composite?
84
+ assert_not_nil @klass.primary_keys
85
+ assert_equal @primary_keys.map {|key| key.to_s}, @klass.primary_keys
86
+ assert_equal @klass.primary_keys, @klass.primary_key
87
+ assert_kind_of(CompositePrimaryKeys::CompositeKeys, @klass.primary_keys)
88
+ assert_equal @primary_keys.map {|key| key.to_sym}.join(','), @klass.primary_key.to_s
89
+ else
90
+ assert_not_nil @klass.primary_key
91
+ assert_equal @primary_keys.first, @klass.primary_key.to_sym
92
+ assert_equal @primary_keys.first.to_s, @klass.primary_key.to_s
93
+ end
94
+ end
95
+ end
96
+
97
+ def test_inherited_primary_keys
98
+ assert_equal(["reference_type_id", "reference_code"], ChildCpkTest.primary_keys)
99
+ end
100
+
101
+ def test_inherited_ids
102
+ cpk_test = ChildCpkTest.new
103
+ assert_equal([nil, nil], cpk_test.id)
104
+ end
105
+
106
+ def test_assign_ids
107
+ ref_code = ReferenceCode.new
108
+ assert_equal([nil, nil], ref_code.id)
109
+
110
+ ref_code.id = [2,1]
111
+ assert_equal([2,1], ref_code.id)
112
+ end
113
+ end
@@ -0,0 +1,94 @@
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestPreload < ActiveSupport::TestCase
4
+ fixtures :comments, :users, :employees, :groups
5
+
6
+ class UserForPreload < User
7
+ has_many :comments_with_include_condition, -> { where('person_type = ?', 'User')},
8
+ class_name: 'Comment', foreign_key: 'person_id', as: :person
9
+ has_many :comments_with_exclude_condition, -> { where('person_type <> ?', 'SomeType')},
10
+ class_name: 'Comment', foreign_key: 'person_id', as: :person
11
+ end
12
+
13
+ class EmployeeForPreload < Employee
14
+ # this is a rather random condition, which should not interfere with the normal test queries
15
+ has_and_belongs_to_many :groups_2, class_name: 'Group', foreign_key: 'employee_id', join_table: 'employees_groups'
16
+ end
17
+
18
+ def test_preload_of_polymorphic_association
19
+ comment = Comment.where(id: [1, 2, 3]).all
20
+ persons = comment.map(&:person)
21
+ persons.each do |person|
22
+ assert_kind_of(ActiveRecord::Base, person)
23
+ end
24
+
25
+ comment = Comment.where(id: [1, 2, 3]).preload(:person).all
26
+ persons = comment.map(&:person)
27
+ persons.each do |person|
28
+ assert_kind_of(ActiveRecord::Base, person)
29
+ end
30
+ end
31
+
32
+ def test_preload_for_conditioned_has_many_association
33
+ # has one comment
34
+ user1 = users(:santiago)
35
+ user2 = UserForPreload.create(name: 'TestPreload')
36
+ Comment.create(person: user2, person_type: 'User')
37
+ Comment.create(person: user2, person_type: 'User')
38
+
39
+ users = UserForPreload.where(id: [user1.id, user2.id]).all
40
+ assert_equal(1, users.first.comments_with_include_condition.size)
41
+ assert_equal(2, users.second.comments_with_include_condition.size)
42
+
43
+ users = UserForPreload.where(id: [user1.id, user2.id]).preload(:comments_with_include_condition).all
44
+ assert_equal(1, users.first.comments_with_include_condition.size)
45
+ assert_equal(2, users.second.comments_with_include_condition.size)
46
+
47
+ users = UserForPreload.where(id: [user1.id, user2.id]).all
48
+ assert_equal(1, users.first.comments_with_exclude_condition.size)
49
+ assert_equal(2, users.second.comments_with_exclude_condition.size)
50
+
51
+ users = UserForPreload.where(id: [user1.id, user2.id]).preload(:comments_with_exclude_condition).all
52
+ assert_equal(1, users.first.comments_with_exclude_condition.size)
53
+ assert_equal(2, users.second.comments_with_exclude_condition.size)
54
+ end
55
+
56
+ def test_preload_for_unconditioned_habtm_association
57
+ employee1 = employees(:steve)
58
+ employee2 = employees(:jill)
59
+ employee1.groups = [groups(:cpk)]
60
+ employee2.groups = [groups(:cpk), groups(:group2)]
61
+ employee1.save!; employee2.save!
62
+
63
+ employees = Employee.where(id: [1, 2]).all
64
+ assert_equal(1, employees.first.groups.size)
65
+ assert_equal(2, employees.second.groups.size)
66
+
67
+ employees = Employee.where(id: [1, 2]).preload(:groups).all
68
+ assert_equal(1, employees.first.groups.size)
69
+ assert_equal(2, employees.second.groups.size)
70
+ end
71
+
72
+ def test_preload_for_conditioned_habtm_association
73
+ employee1 = employees(:steve)
74
+ employee2 = employees(:jill)
75
+ employee1.groups = [groups(:cpk)]
76
+ employee2.groups = [groups(:cpk), groups(:group2)]
77
+ employee1.save!; employee2.save!
78
+
79
+ employees = EmployeeForPreload.where(id: [1, 2]).all.order(:id)
80
+
81
+ # Even without preload two errors: First Employee has Group 1 loaded twice,
82
+ # Second Employee has only Group 2 instead of Group 1&2
83
+ assert_equal(1, employees.first.groups.size)
84
+ assert_equal(1, employees.first.groups_2.size)
85
+ assert_equal(2, employees.second.groups.size)
86
+ assert_equal(2, employees.second.groups_2.size)
87
+
88
+ employees = EmployeeForPreload.where(id: [1, 2]).preload(:groups_2).all.order(:id)
89
+
90
+ # with preloading, the first assertion is valid, but the second only gets Group 2 instead of 1&2
91
+ assert_equal(1, employees.first.groups_2.size)
92
+ assert_equal(2, employees.second.groups_2.size)
93
+ end
94
+ end
@@ -8,7 +8,6 @@
8
8
  test_composite_arrays
9
9
  test_create
10
10
  test_delete
11
- test_delete_all
12
11
  test_dumpable
13
12
  test_dup
14
13
  test_enum
@@ -23,6 +22,7 @@
23
22
  test_pagination
24
23
  test_polymorphic
25
24
  test_predicates
25
+ test_preload
26
26
  test_santiago
27
27
  test_serialize
28
28
  test_touch
@@ -40,8 +40,6 @@ class TestUpdate < ActiveSupport::TestCase
40
40
  obj = ReferenceCode.find([1,1])
41
41
  obj.reference_type_id = 2
42
42
  obj.reference_code = 3
43
- assert(obj.primary_key_changed?)
44
- assert_equal({"reference_type_id" => 1, "reference_code" => 1}, obj.primary_key_was)
45
43
  assert_equal({"reference_type_id" => 2, "reference_code" => 3}, obj.ids_hash)
46
44
  assert(obj.save)
47
45
  assert(obj.reload)
@@ -61,11 +59,18 @@ class TestUpdate < ActiveSupport::TestCase
61
59
  end
62
60
 
63
61
  def test_update_all
64
- assert_nothing_raised do
65
- reference_code = ReferenceCode.create
66
- primary_key = reference_code.class.primary_key
67
- ReferenceCode.where(primary_key => reference_code[primary_key]).
68
- update_all(description: 'random value')
62
+ ReferenceCode.update_all(description: 'random value')
63
+
64
+ ReferenceCode.all.each do |reference_code|
65
+ assert_equal('random value', reference_code.description)
66
+ end
67
+ end
68
+
69
+ def test_update_all_join
70
+ ReferenceCode.joins(:reference_type).update_all(description: 'random value')
71
+
72
+ ReferenceCode.all.each do |reference_code|
73
+ assert_equal('random value', reference_code.description)
69
74
  end
70
75
  end
71
76
  end