composite_primary_keys 7.0.16 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +600 -623
  3. data/lib/composite_primary_keys.rb +113 -115
  4. data/lib/composite_primary_keys/associations/association.rb +23 -23
  5. data/lib/composite_primary_keys/associations/association_scope.rb +73 -77
  6. data/lib/composite_primary_keys/associations/collection_association.rb +15 -0
  7. data/lib/composite_primary_keys/associations/has_many_association.rb +69 -56
  8. data/lib/composite_primary_keys/associations/has_many_through_association.rb +30 -28
  9. data/lib/composite_primary_keys/associations/join_dependency.rb +87 -89
  10. data/lib/composite_primary_keys/associations/join_dependency/join_association.rb +22 -22
  11. data/lib/composite_primary_keys/associations/preloader/association.rb +90 -78
  12. data/lib/composite_primary_keys/associations/preloader/belongs_to.rb +19 -19
  13. data/lib/composite_primary_keys/associations/singular_association.rb +15 -0
  14. data/lib/composite_primary_keys/attribute_methods.rb +9 -0
  15. data/lib/composite_primary_keys/attribute_methods/dirty.rb +29 -26
  16. data/lib/composite_primary_keys/attribute_methods/read.rb +19 -34
  17. data/lib/composite_primary_keys/attribute_methods/write.rb +30 -36
  18. data/lib/composite_primary_keys/attribute_set/builder.rb +20 -0
  19. data/lib/composite_primary_keys/base.rb +135 -129
  20. data/lib/composite_primary_keys/composite_arrays.rb +30 -30
  21. data/lib/composite_primary_keys/composite_predicates.rb +50 -50
  22. data/lib/composite_primary_keys/composite_relation.rb +48 -48
  23. data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb +2 -4
  24. data/lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb +46 -60
  25. data/lib/composite_primary_keys/core.rb +69 -47
  26. data/lib/composite_primary_keys/fixtures.rb +22 -22
  27. data/lib/composite_primary_keys/persistence.rb +56 -60
  28. data/lib/composite_primary_keys/relation.rb +68 -56
  29. data/lib/composite_primary_keys/relation/calculations.rb +79 -75
  30. data/lib/composite_primary_keys/relation/finder_methods.rb +175 -196
  31. data/lib/composite_primary_keys/relation/query_methods.rb +40 -40
  32. data/lib/composite_primary_keys/sanitization.rb +52 -52
  33. data/lib/composite_primary_keys/validations/uniqueness.rb +36 -37
  34. data/lib/composite_primary_keys/version.rb +8 -8
  35. data/tasks/databases/oracle.rake +25 -25
  36. data/tasks/databases/sqlserver.rake +27 -40
  37. data/test/abstract_unit.rb +113 -113
  38. data/test/connections/databases.ci.yml +15 -15
  39. data/test/connections/databases.example.yml +18 -18
  40. data/test/connections/native_oracle/connection.rb +11 -11
  41. data/test/connections/native_oracle_enhanced/connection.rb +16 -16
  42. data/test/connections/native_sqlserver/connection.rb +11 -14
  43. data/test/fixtures/comment.rb +7 -7
  44. data/test/fixtures/db_definitions/db2-create-tables.sql +125 -126
  45. data/test/fixtures/db_definitions/db2-drop-tables.sql +18 -18
  46. data/test/fixtures/db_definitions/mysql.sql +207 -208
  47. data/test/fixtures/db_definitions/oracle.drop.sql +45 -45
  48. data/test/fixtures/db_definitions/oracle.sql +222 -223
  49. data/test/fixtures/db_definitions/postgresql.sql +209 -210
  50. data/test/fixtures/db_definitions/sqlite.sql +196 -197
  51. data/test/fixtures/db_definitions/sqlserver.drop.sql +91 -94
  52. data/test/fixtures/db_definitions/sqlserver.sql +225 -232
  53. data/test/fixtures/dorm.rb +2 -2
  54. data/test/fixtures/employee.rb +5 -5
  55. data/test/fixtures/membership.rb +6 -6
  56. data/test/fixtures/membership_statuses.yml +16 -16
  57. data/test/fixtures/memberships.yml +10 -10
  58. data/test/fixtures/product_tariffs.yml +14 -14
  59. data/test/fixtures/reference_code.rb +7 -7
  60. data/test/fixtures/restaurants_suburb.rb +2 -2
  61. data/test/fixtures/suburb.rb +5 -5
  62. data/test/fixtures/topic.rb +5 -5
  63. data/test/fixtures/topic_source.rb +6 -6
  64. data/test/fixtures/topic_sources.yml +3 -3
  65. data/test/fixtures/topics.yml +8 -8
  66. data/test/fixtures/users.yml +10 -10
  67. data/test/test_associations.rb +295 -275
  68. data/test/test_attribute_methods.rb +63 -63
  69. data/test/test_attributes.rb +60 -60
  70. data/test/test_calculations.rb +37 -42
  71. data/test/test_callbacks.rb +99 -99
  72. data/test/test_create.rb +112 -112
  73. data/test/test_delete.rb +148 -152
  74. data/test/test_delete_all.rb +28 -26
  75. data/test/test_dumpable.rb +15 -15
  76. data/test/test_enum.rb +21 -20
  77. data/test/test_equal.rb +26 -26
  78. data/test/test_find.rb +118 -118
  79. data/test/test_habtm.rb +113 -113
  80. data/test/test_nested_attributes.rb +124 -124
  81. data/test/test_polymorphic.rb +26 -26
  82. data/test/test_predicates.rb +40 -40
  83. data/test/test_santiago.rb +23 -23
  84. data/test/test_suite.rb +33 -34
  85. data/test/test_touch.rb +23 -23
  86. data/test/test_tutorial_example.rb +21 -21
  87. data/test/test_update.rb +71 -71
  88. metadata +9 -13
  89. data/lib/composite_primary_keys/arel/visitors/to_sql.rb +0 -20
  90. data/lib/composite_primary_keys/associations/has_and_belongs_to_many_association.rb +0 -59
  91. data/lib/composite_primary_keys/associations/join_dependency/join_part.rb +0 -39
  92. data/lib/composite_primary_keys/associations/preloader/has_and_belongs_to_many.rb +0 -46
  93. data/lib/composite_primary_keys/connection_adapters/sqlserver_adapter.rb +0 -17
  94. data/lib/composite_primary_keys/locking/optimistic.rb +0 -55
  95. data/test/test_optimistic.rb +0 -18
@@ -1,41 +1,41 @@
1
- module CompositePrimaryKeys::ActiveRecord::QueryMethods
2
-
3
- def reverse_sql_order(order_query)
4
- # CPK
5
- # order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty?
6
-
7
- # break apart CPKs
8
- order_query = primary_key.map do |key|
9
- "#{quoted_table_name}.#{connection.quote_column_name(key)} ASC"
10
- end if order_query.empty?
11
-
12
- order_query.map do |o|
13
- case o
14
- when Arel::Nodes::Ordering
15
- o.reverse
16
- when String, Symbol
17
- o.to_s.split(',').collect do |s|
18
- s.strip!
19
- s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC')
20
- end
21
- else
22
- o
23
- end
24
- end.flatten
25
- end
26
-
27
-
28
- def order(*args)
29
- args.map! do |arg|
30
- if arg.is_a?(Arel::Nodes::Ordering) && arg.expr.name.is_a?(Array)
31
- arg = arg.expr.name.map do |key|
32
- cloned_node = arg.clone
33
- cloned_node.expr.name = key
34
- cloned_node
35
- end
36
- end
37
- arg
38
- end if composite?
39
- super(*args)
40
- end
1
+ module CompositePrimaryKeys::ActiveRecord::QueryMethods
2
+
3
+ def reverse_sql_order(order_query)
4
+ # CPK
5
+ # order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty?
6
+
7
+ # break apart CPKs
8
+ order_query = primary_key.map do |key|
9
+ "#{quoted_table_name}.#{connection.quote_column_name(key)} ASC"
10
+ end if order_query.empty?
11
+
12
+ order_query.map do |o|
13
+ case o
14
+ when Arel::Nodes::Ordering
15
+ o.reverse
16
+ when String, Symbol
17
+ o.to_s.split(',').collect do |s|
18
+ s.strip!
19
+ s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC')
20
+ end
21
+ else
22
+ o
23
+ end
24
+ end.flatten
25
+ end
26
+
27
+
28
+ def order(*args)
29
+ args.map! do |arg|
30
+ if arg.is_a?(Arel::Nodes::Ordering) && arg.expr.name.is_a?(Array)
31
+ arg = arg.expr.name.map do |key|
32
+ cloned_node = arg.clone
33
+ cloned_node.expr.name = key
34
+ cloned_node
35
+ end
36
+ end
37
+ arg
38
+ end if composite?
39
+ super(*args)
40
+ end
41
41
  end
@@ -1,52 +1,52 @@
1
- module ActiveRecord
2
- module Sanitization
3
- module ClassMethods
4
- protected
5
- # Accepts a hash of SQL conditions and replaces those attributes
6
- # that correspond to a +composed_of+ relationship with their expanded
7
- # aggregate attribute values.
8
- # Given:
9
- # class Person < ActiveRecord::Base
10
- # composed_of :address, class_name: "Address",
11
- # mapping: [%w(address_street street), %w(address_city city)]
12
- # end
13
- # Then:
14
- # { address: Address.new("813 abc st.", "chicago") }
15
- # # => { address_street: "813 abc st.", address_city: "chicago" }
16
- def expand_hash_conditions_for_aggregates(attrs)
17
- expanded_attrs = {}
18
- attrs.each do |attr, value|
19
- if attr.is_a?(CompositePrimaryKeys::CompositeKeys)
20
- attr.each_with_index do |key,i|
21
- expanded_attrs[key] = value.flatten[i]
22
- end
23
- elsif aggregation = reflect_on_aggregation(attr.to_sym)
24
- mapping = aggregation.mapping
25
- mapping.each do |field_attr, aggregate_attr|
26
- if mapping.size == 1 && !value.respond_to?(aggregate_attr)
27
- expanded_attrs[field_attr] = value
28
- else
29
- expanded_attrs[field_attr] = value.send(aggregate_attr)
30
- end
31
- end
32
- else
33
- expanded_attrs[attr] = value
34
- end
35
- end
36
- expanded_attrs
37
- end
38
-
39
- def quoted_id
40
- # CPK
41
- #quote_value(id, column_for_attribute(self.class.primary_key))
42
- if self.composite?
43
- [self.class.primary_keys, ids].
44
- transpose.
45
- map {|attr_name,id| quote_value(id, column_for_attribute(attr_name))}
46
- else
47
- quote_value(id, column_for_attribute(self.class.primary_key))
48
- end
49
- end
50
- end
51
- end
52
- end
1
+ module ActiveRecord
2
+ module Sanitization
3
+ module ClassMethods
4
+ protected
5
+ # Accepts a hash of SQL conditions and replaces those attributes
6
+ # that correspond to a +composed_of+ relationship with their expanded
7
+ # aggregate attribute values.
8
+ # Given:
9
+ # class Person < ActiveRecord::Base
10
+ # composed_of :address, class_name: "Address",
11
+ # mapping: [%w(address_street street), %w(address_city city)]
12
+ # end
13
+ # Then:
14
+ # { address: Address.new("813 abc st.", "chicago") }
15
+ # # => { address_street: "813 abc st.", address_city: "chicago" }
16
+ def expand_hash_conditions_for_aggregates(attrs)
17
+ expanded_attrs = {}
18
+ attrs.each do |attr, value|
19
+ if attr.is_a?(CompositePrimaryKeys::CompositeKeys)
20
+ attr.each_with_index do |key,i|
21
+ expanded_attrs[key] = value.respond_to?(:flatten) ? value.flatten[i] : value
22
+ end
23
+ elsif aggregation = reflect_on_aggregation(attr.to_sym)
24
+ mapping = aggregation.mapping
25
+ mapping.each do |field_attr, aggregate_attr|
26
+ if mapping.size == 1 && !value.respond_to?(aggregate_attr)
27
+ expanded_attrs[field_attr] = value
28
+ else
29
+ expanded_attrs[field_attr] = value.send(aggregate_attr)
30
+ end
31
+ end
32
+ else
33
+ expanded_attrs[attr] = value
34
+ end
35
+ end
36
+ expanded_attrs
37
+ end
38
+
39
+ def quoted_id
40
+ # CPK
41
+ #quote_value(id, column_for_attribute(self.class.primary_key))
42
+ if self.composite?
43
+ [self.class.primary_keys, ids].
44
+ transpose.
45
+ map {|attr_name,id| quote_value(id, column_for_attribute(attr_name))}
46
+ else
47
+ quote_value(id, column_for_attribute(self.class.primary_key))
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,38 +1,37 @@
1
- module ActiveRecord
2
- module Validations
3
- class UniquenessValidator
4
- def validate_each(record, attribute, value)
5
- finder_class = find_finder_class_for(record)
6
- table = finder_class.arel_table
7
- value = map_enum_attribute(finder_class,attribute,value)
8
- value = deserialize_attribute(record, attribute, value)
9
-
10
- relation = build_relation(finder_class, table, attribute, value)
11
- # CPK
12
- # relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.id)) if record.persisted?
13
- if record.persisted?
14
- not_eq_conditions = Array(finder_class.primary_key).zip(Array(record.send(:id))).map do |name, value|
15
- table[name.to_sym].not_eq(value)
16
- end
17
-
18
- condition = not_eq_conditions.shift
19
- not_eq_conditions.each do |not_eq_condition|
20
- condition = condition.or(not_eq_condition)
21
- end
22
- relation = relation.and(condition)
23
- end
24
-
25
- relation = scope_relation(record, table, relation)
26
- relation = finder_class.unscoped.where(relation)
27
- relation = relation.merge(options[:conditions]) if options[:conditions]
28
-
29
- if relation.exists?
30
- error_options = options.except(:case_sensitive, :scope, :conditions)
31
- error_options[:value] = value
32
-
33
- record.errors.add(attribute, :taken, error_options)
34
- end
35
- end
36
- end
37
- end
1
+ module ActiveRecord
2
+ module Validations
3
+ class UniquenessValidator
4
+ def validate_each(record, attribute, value)
5
+ finder_class = find_finder_class_for(record)
6
+ table = finder_class.arel_table
7
+ value = map_enum_attribute(finder_class, attribute, value)
8
+
9
+ relation = build_relation(finder_class, table, attribute, value)
10
+ # CPK
11
+ # relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.id)) if record.persisted?
12
+ if record.persisted?
13
+ not_eq_conditions = Array(finder_class.primary_key).zip(Array(record.send(:id))).map do |name, value|
14
+ table[name.to_sym].not_eq(value)
15
+ end
16
+
17
+ condition = not_eq_conditions.shift
18
+ not_eq_conditions.each do |not_eq_condition|
19
+ condition = condition.or(not_eq_condition)
20
+ end
21
+ relation = relation.and(condition)
22
+ end
23
+
24
+ relation = scope_relation(record, table, relation)
25
+ relation = finder_class.unscoped.where(relation)
26
+ relation = relation.merge(options[:conditions]) if options[:conditions]
27
+
28
+ if relation.exists?
29
+ error_options = options.except(:case_sensitive, :scope, :conditions)
30
+ error_options[:value] = value
31
+
32
+ record.errors.add(attribute, :taken, error_options)
33
+ end
34
+ end
35
+ end
36
+ end
38
37
  end
@@ -1,8 +1,8 @@
1
- module CompositePrimaryKeys
2
- module VERSION
3
- MAJOR = 7
4
- MINOR = 0
5
- TINY = 16
6
- STRING = [MAJOR, MINOR, TINY].join('.')
7
- end
8
- end
1
+ module CompositePrimaryKeys
2
+ module VERSION
3
+ MAJOR = 8
4
+ MINOR = 0
5
+ TINY = 0
6
+ STRING = [MAJOR, MINOR, TINY].join('.')
7
+ end
8
+ end
@@ -1,25 +1,25 @@
1
- require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
2
- require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
3
-
4
- namespace :oracle do
5
- desc 'Build the Oracle test database'
6
- task :build_database => :load_connection do
7
- options_str = connection_string
8
-
9
- schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions', 'oracle.sql')
10
- sh %( sqlplus #{options_str} < #{schema} )
11
- end
12
-
13
- desc 'Drop the Oracle test database'
14
- task :drop_database => :load_connection do
15
- options_str = connection_string
16
- sh %( sqlplus #{options_str} < #{File.join(SCHEMA_PATH, 'oracle.drop.sql')} )
17
- end
18
-
19
- desc 'Rebuild the Oracle test database'
20
- task :rebuild_database => [:drop_database, :build_database]
21
-
22
- task :load_connection do
23
- require File.join(PROJECT_ROOT, "test", "connections", "native_oracle", "connection")
24
- end
25
- end
1
+ require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
2
+ require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
3
+
4
+ namespace :oracle do
5
+ desc 'Build the Oracle test database'
6
+ task :build_database => :load_connection do
7
+ options_str = connection_string
8
+
9
+ schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions', 'oracle.sql')
10
+ sh %( sqlplus #{options_str} < #{schema} )
11
+ end
12
+
13
+ desc 'Drop the Oracle test database'
14
+ task :drop_database => :load_connection do
15
+ options_str = connection_string
16
+ sh %( sqlplus #{options_str} < #{File.join(SCHEMA_PATH, 'oracle.drop.sql')} )
17
+ end
18
+
19
+ desc 'Rebuild the Oracle test database'
20
+ task :rebuild_database => [:drop_database, :build_database]
21
+
22
+ task :load_connection do
23
+ require File.join(PROJECT_ROOT, "test", "connections", "native_oracle", "connection")
24
+ end
25
+ end
@@ -1,40 +1,27 @@
1
- require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
2
- require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
3
-
4
- require 'rbconfig'
5
- if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
6
- sql_cmd = "osql"
7
- else
8
- sql_cmd = sqsh
9
- end
10
-
11
- namespace :sqlserver do
12
- desc 'Build the SQL Server test database'
13
- task :build_database => :load_connection do
14
- options_str = connection_string
15
-
16
- schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions',
17
- 'sqlserver.sql').gsub(File::SEPARATOR,
18
- File::ALT_SEPARATOR ||
19
- File::SEPARATOR)
20
- sh %( #{sql_cmd} #{options_str} -i #{schema} )
21
- end
22
-
23
- desc 'Drop the SQL Server test database'
24
- task :drop_database => :load_connection do
25
- options_str = connection_string
26
-
27
- schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions',
28
- 'sqlserver.drop.sql').gsub(File::SEPARATOR,
29
- File::ALT_SEPARATOR ||
30
- File::SEPARATOR)
31
- sh %( #{sql_cmd} #{options_str} -i #{schema} )
32
- end
33
-
34
- desc 'Rebuild the SQL Server test database'
35
- task :rebuild_database => [:drop_database, :build_database]
36
-
37
- task :load_connection do
38
- require File.join(PROJECT_ROOT, "test", "connections", "native_sqlserver", "connection")
39
- end
40
- end
1
+ require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
2
+ require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
3
+
4
+ namespace :sqlserver do
5
+ desc 'Build the SQL Server test database'
6
+ task :build_database => :load_connection do
7
+ options_str = connection_string
8
+
9
+ schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions', 'sqlserver.sql')
10
+ sh %( sqsh #{options_str} -i #{schema} )
11
+ end
12
+
13
+ desc 'Drop the SQL Server test database'
14
+ task :drop_database => :load_connection do
15
+ options_str = connection_string
16
+
17
+ schema = File.join(PROJECT_ROOT, 'test', 'fixtures', 'db_definitions', 'sqlserver.drop.sql')
18
+ sh %( sqsh #{options_str} -i #{schema} )
19
+ end
20
+
21
+ desc 'Rebuild the SQL Server test database'
22
+ task :rebuild_database => [:drop_database, :build_database]
23
+
24
+ task :load_connection do
25
+ require File.join(PROJECT_ROOT, "test", "connections", "native_sqlserver", "connection")
26
+ end
27
+ end
@@ -1,113 +1,113 @@
1
- PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
2
-
3
- # To make debugging easier, test within this source tree versus an installed gem
4
- $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
5
- require 'composite_primary_keys'
6
- require 'minitest/autorun'
7
- require 'active_support/test_case'
8
-
9
- # Now load the connection spec
10
- require File.join(PROJECT_ROOT, "test", "connections", "connection_spec")
11
-
12
- spec_name = ENV['ADAPTER'] || 'postgresql'
13
- spec = CompositePrimaryKeys::ConnectionSpec[spec_name]
14
-
15
- # And now connect to the database
16
- adapter = spec['adapter']
17
- require File.join(PROJECT_ROOT, "test", "connections", "native_#{spec_name}", "connection")
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_fixtures = true
33
-
34
- def assert_date_from_db(expected, actual, message = nil)
35
- # SQL Server doesn't have a separate column type just for dates,
36
- # so the time is in the string and incorrectly formatted
37
- if current_adapter?(:SQLServerAdapter)
38
- assert_equal expected.strftime("%Y/%m/%d 00:00:00"), actual.strftime("%Y/%m/%d 00:00:00")
39
- elsif current_adapter?(:SybaseAdapter)
40
- assert_equal expected.to_s, actual.to_date.to_s, message
41
- else
42
- assert_equal expected.to_s, actual.to_s, message
43
- end
44
- end
45
-
46
- def assert_queries(num = 1)
47
- ActiveRecord::Base.connection.class.class_eval do
48
- self.query_count = 0
49
- alias_method :execute, :execute_with_query_counting
50
- end
51
- yield
52
- ensure
53
- ActiveRecord::Base.connection.class.class_eval do
54
- alias_method :execute, :execute_without_query_counting
55
- end
56
- assert_equal num, ActiveRecord::Base.connection.query_count, "#{ActiveRecord::Base.connection.query_count} instead of #{num} queries were executed."
57
- end
58
-
59
- def assert_no_queries(&block)
60
- assert_queries(0, &block)
61
- end
62
-
63
- cattr_accessor :classes
64
-
65
- protected
66
-
67
- def testing_with(&block)
68
- classes.keys.each do |key_test|
69
- @key_test = key_test
70
- @klass_info = classes[@key_test]
71
- @klass, @primary_keys = @klass_info[:class], @klass_info[:primary_keys]
72
- order = @klass.primary_key.is_a?(String) ? @klass.primary_key : @klass.primary_key.join(',')
73
- @first = @klass.order(order).first
74
- yield
75
- end
76
- end
77
-
78
- def first_id
79
- ids = (1..@primary_keys.length).map {|num| 1}
80
- composite? ? ids.to_composite_ids : ids.first
81
- end
82
-
83
- def composite?
84
- @key_test != :single
85
- end
86
-
87
- # Oracle metadata is in all caps.
88
- def with_quoted_identifiers(s)
89
- s.gsub(/"(\w+)"/) { |m|
90
- if ActiveRecord::Base.configurations[:test]['adapter'] =~ /oracle/i
91
- m.upcase
92
- else
93
- m
94
- end
95
- }
96
- end
97
- end
98
-
99
- def current_adapter?(type)
100
- ActiveRecord::ConnectionAdapters.const_defined?(type) &&
101
- ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters.const_get(type))
102
- end
103
-
104
- ActiveRecord::Base.connection.class.class_eval do
105
- cattr_accessor :query_count
106
- alias_method :execute_without_query_counting, :execute
107
- def execute_with_query_counting(sql, name = nil)
108
- self.query_count += 1
109
- execute_without_query_counting(sql, name)
110
- end
111
- end
112
-
113
- ActiveRecord::Base.logger = Logger.new(ENV['CPK_LOGFILE'] || STDOUT)
1
+ PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
2
+
3
+ # To make debugging easier, test within this source tree versus an installed gem
4
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
5
+ require 'composite_primary_keys'
6
+ require 'minitest/autorun'
7
+ require 'active_support/test_case'
8
+
9
+ # Now load the connection spec
10
+ require File.join(PROJECT_ROOT, "test", "connections", "connection_spec")
11
+
12
+ spec_name = ENV['ADAPTER'] || 'postgresql'
13
+ spec = CompositePrimaryKeys::ConnectionSpec[spec_name]
14
+
15
+ # And now connect to the database
16
+ adapter = spec['adapter']
17
+ require File.join(PROJECT_ROOT, "test", "connections", "native_#{spec_name}", "connection")
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_fixtures = true
33
+
34
+ def assert_date_from_db(expected, actual, message = nil)
35
+ # SQL Server doesn't have a separate column type just for dates,
36
+ # so the time is in the string and incorrectly formatted
37
+ if current_adapter?(:SQLServerAdapter)
38
+ assert_equal expected.strftime("%Y/%m/%d 00:00:00"), actual.strftime("%Y/%m/%d 00:00:00")
39
+ elsif current_adapter?(:SybaseAdapter)
40
+ assert_equal expected.to_s, actual.to_date.to_s, message
41
+ else
42
+ assert_equal expected.to_s, actual.to_s, message
43
+ end
44
+ end
45
+
46
+ def assert_queries(num = 1)
47
+ ActiveRecord::Base.connection.class.class_eval do
48
+ self.query_count = 0
49
+ alias_method :execute, :execute_with_query_counting
50
+ end
51
+ yield
52
+ ensure
53
+ ActiveRecord::Base.connection.class.class_eval do
54
+ alias_method :execute, :execute_without_query_counting
55
+ end
56
+ assert_equal num, ActiveRecord::Base.connection.query_count, "#{ActiveRecord::Base.connection.query_count} instead of #{num} queries were executed."
57
+ end
58
+
59
+ def assert_no_queries(&block)
60
+ assert_queries(0, &block)
61
+ end
62
+
63
+ cattr_accessor :classes
64
+
65
+ protected
66
+
67
+ def testing_with(&block)
68
+ classes.keys.each do |key_test|
69
+ @key_test = key_test
70
+ @klass_info = classes[@key_test]
71
+ @klass, @primary_keys = @klass_info[:class], @klass_info[:primary_keys]
72
+ order = @klass.primary_key.is_a?(String) ? @klass.primary_key : @klass.primary_key.join(',')
73
+ @first = @klass.order(order).first
74
+ yield
75
+ end
76
+ end
77
+
78
+ def first_id
79
+ ids = (1..@primary_keys.length).map {|num| 1}
80
+ composite? ? ids.to_composite_ids : ids.first
81
+ end
82
+
83
+ def composite?
84
+ @key_test != :single
85
+ end
86
+
87
+ # Oracle metadata is in all caps.
88
+ def with_quoted_identifiers(s)
89
+ s.gsub(/"(\w+)"/) { |m|
90
+ if ActiveRecord::Base.configurations[:test]['adapter'] =~ /oracle/i
91
+ m.upcase
92
+ else
93
+ m
94
+ end
95
+ }
96
+ end
97
+ end
98
+
99
+ def current_adapter?(type)
100
+ ActiveRecord::ConnectionAdapters.const_defined?(type) &&
101
+ ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters.const_get(type))
102
+ end
103
+
104
+ ActiveRecord::Base.connection.class.class_eval do
105
+ cattr_accessor :query_count
106
+ alias_method :execute_without_query_counting, :execute
107
+ def execute_with_query_counting(sql, name = nil)
108
+ self.query_count += 1
109
+ execute_without_query_counting(sql, name)
110
+ end
111
+ end
112
+
113
+ ActiveRecord::Base.logger = Logger.new(ENV['CPK_LOGFILE'] || STDOUT)