composite_primary_keys 12.0.4 → 12.0.10

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +880 -859
  3. data/README.rdoc +180 -180
  4. data/lib/composite_primary_keys.rb +117 -118
  5. data/lib/composite_primary_keys/active_model/attribute_assignment.rb +19 -19
  6. data/lib/composite_primary_keys/associations/association_scope.rb +68 -68
  7. data/lib/composite_primary_keys/associations/join_dependency.rb +103 -103
  8. data/lib/composite_primary_keys/attribute_methods.rb +9 -9
  9. data/lib/composite_primary_keys/attribute_methods/read.rb +30 -30
  10. data/lib/composite_primary_keys/attribute_methods/write.rb +35 -35
  11. data/lib/composite_primary_keys/base.rb +141 -141
  12. data/lib/composite_primary_keys/connection_adapters/abstract/database_statements.rb +37 -22
  13. data/lib/composite_primary_keys/connection_adapters/sqlserver/database_statements.rb +44 -41
  14. data/lib/composite_primary_keys/core.rb +48 -48
  15. data/lib/composite_primary_keys/persistence.rb +82 -81
  16. data/lib/composite_primary_keys/reflection.rb +29 -29
  17. data/lib/composite_primary_keys/relation.rb +193 -193
  18. data/lib/composite_primary_keys/relation/batches.rb +1 -1
  19. data/lib/composite_primary_keys/relation/calculations.rb +81 -81
  20. data/lib/composite_primary_keys/relation/finder_methods.rb +235 -235
  21. data/lib/composite_primary_keys/relation/predicate_builder/association_query_value.rb +20 -20
  22. data/lib/composite_primary_keys/relation/query_methods.rb +42 -42
  23. data/lib/composite_primary_keys/relation/where_clause.rb +23 -23
  24. data/lib/composite_primary_keys/version.rb +8 -8
  25. data/test/abstract_unit.rb +114 -114
  26. data/test/connections/databases.ci.yml +22 -19
  27. data/test/fixtures/db_definitions/db2-create-tables.sql +112 -112
  28. data/test/fixtures/db_definitions/db2-drop-tables.sql +16 -16
  29. data/test/fixtures/db_definitions/mysql.sql +180 -180
  30. data/test/fixtures/db_definitions/oracle.drop.sql +41 -41
  31. data/test/fixtures/db_definitions/oracle.sql +199 -199
  32. data/test/fixtures/db_definitions/postgresql.sql +182 -182
  33. data/test/fixtures/db_definitions/sqlite.sql +169 -169
  34. data/test/fixtures/db_definitions/sqlserver.sql +176 -176
  35. data/test/fixtures/department.rb +16 -16
  36. data/test/fixtures/departments.yml +15 -15
  37. data/test/fixtures/employees.yml +27 -27
  38. data/test/fixtures/restaurants_suburbs.yml +10 -10
  39. data/test/fixtures/streets.yml +16 -16
  40. data/test/fixtures/suburbs.yml +14 -14
  41. data/test/fixtures/user.rb +11 -11
  42. data/test/test_associations.rb +358 -358
  43. data/test/test_attributes.rb +60 -60
  44. data/test/test_calculations.rb +42 -42
  45. data/test/test_create.rb +218 -180
  46. data/test/test_delete.rb +182 -179
  47. data/test/test_exists.rb +39 -39
  48. data/test/test_find.rb +164 -157
  49. data/test/test_ids.rb +112 -112
  50. data/test/test_nested_attributes.rb +67 -67
  51. data/test/test_update.rb +96 -96
  52. metadata +2 -3
  53. data/lib/composite_primary_keys/connection_adapters/mysql/database_statements.rb +0 -24
@@ -1,20 +1,20 @@
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.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,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 [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
43
43
  end
@@ -1,24 +1,24 @@
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)
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
24
24
  end
@@ -1,8 +1,8 @@
1
- module CompositePrimaryKeys
2
- module VERSION
3
- MAJOR = 12
4
- MINOR = 0
5
- TINY = 4
6
- STRING = [MAJOR, MINOR, TINY].join('.')
7
- end
8
- end
1
+ module CompositePrimaryKeys
2
+ module VERSION
3
+ MAJOR = 12
4
+ MINOR = 0
5
+ TINY = 10
6
+ STRING = [MAJOR, MINOR, TINY].join('.')
7
+ end
8
+ end
@@ -1,114 +1,114 @@
1
- spec_name = ENV['ADAPTER'] || 'sqlite'
2
- require 'bundler'
3
- require 'minitest/autorun'
4
-
5
- Bundler.setup(:default, spec_name.to_sym)
6
- Bundler.require(:default, spec_name.to_sym)
7
- require 'composite_primary_keys'
8
-
9
- # Require the connection spec
10
- PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
11
- require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
12
-
13
- spec = CompositePrimaryKeys::ConnectionSpec[spec_name]
14
- puts "Loaded #{spec_name}"
15
-
16
- # And now connect to the database
17
- ActiveRecord::Base.establish_connection(spec)
18
-
19
- # Tell active record about the configuration
20
- ActiveRecord::Base.configurations = {test: spec}
21
-
22
- # Tell ActiveRecord where to find models
23
- ActiveSupport::Dependencies.autoload_paths << File.join(PROJECT_ROOT, 'test', 'fixtures')
24
-
25
- I18n.config.enforce_available_locales = true
26
-
27
- class ActiveSupport::TestCase
28
- include ActiveRecord::TestFixtures
29
-
30
- self.fixture_path = File.dirname(__FILE__) + '/fixtures/'
31
- self.use_instantiated_fixtures = false
32
- self.use_transactional_tests = true
33
- self.test_order = :random
34
-
35
- def assert_date_from_db(expected, actual, message = nil)
36
- # SQL Server doesn't have a separate column type just for dates,
37
- # so the time is in the string and incorrectly formatted
38
- if current_adapter?(:SQLServerAdapter)
39
- assert_equal expected.strftime('%Y/%m/%d 00:00:00'), actual.strftime('%Y/%m/%d 00:00:00')
40
- elsif current_adapter?(:SybaseAdapter)
41
- assert_equal expected.to_s, actual.to_date.to_s, message
42
- else
43
- assert_equal expected.to_s, actual.to_s, message
44
- end
45
- end
46
-
47
- def assert_queries(num = 1)
48
- ActiveRecord::Base.connection.class.class_eval do
49
- self.query_count = 0
50
- alias_method :execute, :execute_with_query_counting
51
- end
52
- yield
53
- ensure
54
- ActiveRecord::Base.connection.class.class_eval do
55
- alias_method :execute, :execute_without_query_counting
56
- end
57
- assert_equal num, ActiveRecord::Base.connection.query_count, '#{ActiveRecord::Base.connection.query_count} instead of #{num} queries were executed.'
58
- end
59
-
60
- def assert_no_queries(&block)
61
- assert_queries(0, &block)
62
- end
63
-
64
- cattr_accessor :classes
65
-
66
- protected
67
-
68
- def testing_with(&block)
69
- classes.keys.each do |key_test|
70
- @key_test = key_test
71
- @klass_info = classes[@key_test]
72
- @klass, @primary_keys = @klass_info[:class], @klass_info[:primary_keys]
73
- order = @klass.primary_key.is_a?(String) ? @klass.primary_key : @klass.primary_key.join(',')
74
- @first = @klass.order(order).first
75
- yield
76
- end
77
- end
78
-
79
- def first_id
80
- ids = (1..@primary_keys.length).map {|num| 1}
81
- composite? ? ids.to_composite_ids : ids.first
82
- end
83
-
84
- def composite?
85
- @key_test != :single
86
- end
87
-
88
- # Oracle metadata is in all caps.
89
- def with_quoted_identifiers(s)
90
- s.gsub(/'(\w+)'/) { |m|
91
- if ActiveRecord::Base.configurations[:test]['adapter'] =~ /oracle/i
92
- m.upcase
93
- else
94
- m
95
- end
96
- }
97
- end
98
- end
99
-
100
- def current_adapter?(type)
101
- ActiveRecord::ConnectionAdapters.const_defined?(type) &&
102
- ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters.const_get(type))
103
- end
104
-
105
- ActiveRecord::Base.connection.class.class_eval do
106
- cattr_accessor :query_count
107
- alias_method :execute_without_query_counting, :execute
108
- def execute_with_query_counting(sql, name = nil)
109
- self.query_count += 1
110
- execute_without_query_counting(sql, name)
111
- end
112
- end
113
-
114
- ActiveRecord::Base.logger = Logger.new(ENV['CPK_LOGFILE'] || STDOUT)
1
+ spec_name = ENV['ADAPTER'] || 'sqlite'
2
+ require 'bundler'
3
+ require 'minitest/autorun'
4
+
5
+ Bundler.setup(:default, spec_name.to_sym)
6
+ Bundler.require(:default, spec_name.to_sym)
7
+ require 'composite_primary_keys'
8
+
9
+ # Require the connection spec
10
+ PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
11
+ require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
12
+
13
+ spec = CompositePrimaryKeys::ConnectionSpec[spec_name]
14
+ puts "Loaded #{spec_name}"
15
+
16
+ # And now connect to the database
17
+ ActiveRecord::Base.establish_connection(spec)
18
+
19
+ # Tell active record about the configuration
20
+ ActiveRecord::Base.configurations = {test: spec}
21
+
22
+ # Tell ActiveRecord where to find models
23
+ ActiveSupport::Dependencies.autoload_paths << File.join(PROJECT_ROOT, 'test', 'fixtures')
24
+
25
+ I18n.config.enforce_available_locales = true
26
+
27
+ class ActiveSupport::TestCase
28
+ include ActiveRecord::TestFixtures
29
+
30
+ self.fixture_path = File.dirname(__FILE__) + '/fixtures/'
31
+ self.use_instantiated_fixtures = false
32
+ self.use_transactional_tests = true
33
+ self.test_order = :random
34
+
35
+ def assert_date_from_db(expected, actual, message = nil)
36
+ # SQL Server doesn't have a separate column type just for dates,
37
+ # so the time is in the string and incorrectly formatted
38
+ if current_adapter?(:SQLServerAdapter)
39
+ assert_equal expected.strftime('%Y/%m/%d 00:00:00'), actual.strftime('%Y/%m/%d 00:00:00')
40
+ elsif current_adapter?(:SybaseAdapter)
41
+ assert_equal expected.to_s, actual.to_date.to_s, message
42
+ else
43
+ assert_equal expected.to_s, actual.to_s, message
44
+ end
45
+ end
46
+
47
+ def assert_queries(num = 1)
48
+ ActiveRecord::Base.connection.class.class_eval do
49
+ self.query_count = 0
50
+ alias_method :execute, :execute_with_query_counting
51
+ end
52
+ yield
53
+ ensure
54
+ ActiveRecord::Base.connection.class.class_eval do
55
+ alias_method :execute, :execute_without_query_counting
56
+ end
57
+ assert_equal num, ActiveRecord::Base.connection.query_count, '#{ActiveRecord::Base.connection.query_count} instead of #{num} queries were executed.'
58
+ end
59
+
60
+ def assert_no_queries(&block)
61
+ assert_queries(0, &block)
62
+ end
63
+
64
+ cattr_accessor :classes
65
+
66
+ protected
67
+
68
+ def testing_with(&block)
69
+ classes.keys.each do |key_test|
70
+ @key_test = key_test
71
+ @klass_info = classes[@key_test]
72
+ @klass, @primary_keys = @klass_info[:class], @klass_info[:primary_keys]
73
+ order = @klass.primary_key.is_a?(String) ? @klass.primary_key : @klass.primary_key.join(',')
74
+ @first = @klass.order(order).first
75
+ yield
76
+ end
77
+ end
78
+
79
+ def first_id
80
+ ids = (1..@primary_keys.length).map {|num| 1}
81
+ composite? ? ids.to_composite_ids : ids.first
82
+ end
83
+
84
+ def composite?
85
+ @key_test != :single
86
+ end
87
+
88
+ # Oracle metadata is in all caps.
89
+ def with_quoted_identifiers(s)
90
+ s.gsub(/'(\w+)'/) { |m|
91
+ if ActiveRecord::Base.configurations[:test]['adapter'] =~ /oracle/i
92
+ m.upcase
93
+ else
94
+ m
95
+ end
96
+ }
97
+ end
98
+ end
99
+
100
+ def current_adapter?(type)
101
+ ActiveRecord::ConnectionAdapters.const_defined?(type) &&
102
+ ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters.const_get(type))
103
+ end
104
+
105
+ ActiveRecord::Base.connection.class.class_eval do
106
+ cattr_accessor :query_count
107
+ alias_method :execute_without_query_counting, :execute
108
+ def execute_with_query_counting(sql, name = nil)
109
+ self.query_count += 1
110
+ execute_without_query_counting(sql, name)
111
+ end
112
+ end
113
+
114
+ ActiveRecord::Base.logger = Logger.new(ENV['CPK_LOGFILE'] || STDOUT)
@@ -1,19 +1,22 @@
1
- mysql:
2
- adapter: mysql2
3
- username: travis
4
- password: ""
5
- encoding: utf8mb4
6
- charset: utf8mb4
7
- collation: utf8mb4_bin
8
- database: composite_primary_keys_unittest
9
-
10
- postgresql:
11
- adapter: postgresql
12
- database: composite_primary_keys_unittest
13
- username: postgres
14
- host: localhost
15
-
16
- sqlite:
17
- adapter: sqlite3
18
- database: <%= File.join(project_root, 'db', 'composite_primary_keys_unittest.sqlite') %>
19
-
1
+ mysql:
2
+ adapter: mysql2
3
+ username: github
4
+ password: github
5
+ host: 127.0.0.1
6
+ port: 3306
7
+ encoding: utf8mb4
8
+ charset: utf8mb4
9
+ collation: utf8mb4_bin
10
+ database: composite_primary_keys_unittest
11
+
12
+ postgresql:
13
+ adapter: postgresql
14
+ database: composite_primary_keys_unittest
15
+ username: postgres
16
+ password: postgres
17
+ host: localhost
18
+
19
+ sqlite:
20
+ adapter: sqlite3
21
+ database: <%= File.join(project_root, 'db', 'composite_primary_keys_unittest.sqlite') %>
22
+