composite_primary_keys 7.0.16 → 8.0.0

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 (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)