activerecord 1.15.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (185) hide show
  1. data/CHANGELOG +2454 -34
  2. data/README +1 -1
  3. data/RUNNING_UNIT_TESTS +3 -34
  4. data/Rakefile +98 -77
  5. data/install.rb +1 -1
  6. data/lib/active_record.rb +13 -22
  7. data/lib/active_record/aggregations.rb +38 -49
  8. data/lib/active_record/associations.rb +452 -333
  9. data/lib/active_record/associations/association_collection.rb +66 -20
  10. data/lib/active_record/associations/association_proxy.rb +9 -8
  11. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +46 -51
  12. data/lib/active_record/associations/has_many_association.rb +21 -57
  13. data/lib/active_record/associations/has_many_through_association.rb +38 -18
  14. data/lib/active_record/associations/has_one_association.rb +30 -14
  15. data/lib/active_record/attribute_methods.rb +253 -0
  16. data/lib/active_record/base.rb +719 -494
  17. data/lib/active_record/calculations.rb +62 -63
  18. data/lib/active_record/callbacks.rb +57 -83
  19. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +38 -9
  20. data/lib/active_record/connection_adapters/abstract/database_statements.rb +56 -15
  21. data/lib/active_record/connection_adapters/abstract/query_cache.rb +87 -0
  22. data/lib/active_record/connection_adapters/abstract/quoting.rb +23 -12
  23. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +191 -62
  24. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +37 -34
  25. data/lib/active_record/connection_adapters/abstract_adapter.rb +28 -17
  26. data/lib/active_record/connection_adapters/mysql_adapter.rb +119 -37
  27. data/lib/active_record/connection_adapters/postgresql_adapter.rb +473 -210
  28. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -0
  29. data/lib/active_record/connection_adapters/sqlite_adapter.rb +91 -107
  30. data/lib/active_record/fixtures.rb +503 -113
  31. data/lib/active_record/locking/optimistic.rb +72 -34
  32. data/lib/active_record/migration.rb +80 -57
  33. data/lib/active_record/observer.rb +13 -10
  34. data/lib/active_record/query_cache.rb +16 -57
  35. data/lib/active_record/reflection.rb +35 -38
  36. data/lib/active_record/schema.rb +5 -5
  37. data/lib/active_record/schema_dumper.rb +35 -13
  38. data/lib/active_record/serialization.rb +98 -0
  39. data/lib/active_record/serializers/json_serializer.rb +71 -0
  40. data/lib/active_record/{xml_serialization.rb → serializers/xml_serializer.rb} +90 -83
  41. data/lib/active_record/timestamp.rb +20 -21
  42. data/lib/active_record/transactions.rb +39 -43
  43. data/lib/active_record/validations.rb +256 -107
  44. data/lib/active_record/version.rb +3 -3
  45. data/lib/activerecord.rb +1 -0
  46. data/test/aaa_create_tables_test.rb +15 -2
  47. data/test/abstract_unit.rb +24 -17
  48. data/test/active_schema_test_mysql.rb +20 -8
  49. data/test/adapter_test.rb +23 -5
  50. data/test/adapter_test_sqlserver.rb +15 -1
  51. data/test/aggregations_test.rb +16 -1
  52. data/test/all.sh +2 -2
  53. data/test/associations/ar_joins_test.rb +0 -0
  54. data/test/associations/callbacks_test.rb +51 -30
  55. data/test/associations/cascaded_eager_loading_test.rb +1 -29
  56. data/test/associations/eager_singularization_test.rb +145 -0
  57. data/test/associations/eager_test.rb +42 -6
  58. data/test/associations/extension_test.rb +6 -1
  59. data/test/associations/inner_join_association_test.rb +88 -0
  60. data/test/associations/join_model_test.rb +47 -16
  61. data/test/associations_test.rb +449 -226
  62. data/test/attribute_methods_test.rb +97 -0
  63. data/test/base_test.rb +251 -105
  64. data/test/binary_test.rb +22 -27
  65. data/test/calculations_test.rb +37 -5
  66. data/test/callbacks_test.rb +23 -0
  67. data/test/connection_test_firebird.rb +2 -2
  68. data/test/connection_test_mysql.rb +30 -0
  69. data/test/connections/native_mysql/connection.rb +3 -0
  70. data/test/connections/native_sqlite/connection.rb +5 -14
  71. data/test/connections/native_sqlite3/connection.rb +5 -14
  72. data/test/connections/native_sqlite3/in_memory_connection.rb +1 -1
  73. data/test/{copy_table_sqlite.rb → copy_table_test_sqlite.rb} +8 -3
  74. data/test/datatype_test_postgresql.rb +178 -27
  75. data/test/{empty_date_time_test.rb → date_time_test.rb} +13 -1
  76. data/test/defaults_test.rb +8 -1
  77. data/test/deprecated_finder_test.rb +7 -128
  78. data/test/finder_test.rb +192 -54
  79. data/test/fixtures/all/developers.yml +0 -0
  80. data/test/fixtures/all/people.csv +0 -0
  81. data/test/fixtures/all/tasks.yml +0 -0
  82. data/test/fixtures/author.rb +12 -5
  83. data/test/fixtures/binaries.yml +130 -435
  84. data/test/fixtures/category.rb +6 -0
  85. data/test/fixtures/company.rb +8 -1
  86. data/test/fixtures/computer.rb +1 -0
  87. data/test/fixtures/contact.rb +16 -0
  88. data/test/fixtures/customer.rb +2 -2
  89. data/test/fixtures/db_definitions/db2.drop.sql +1 -0
  90. data/test/fixtures/db_definitions/db2.sql +4 -0
  91. data/test/fixtures/db_definitions/firebird.drop.sql +3 -1
  92. data/test/fixtures/db_definitions/firebird.sql +6 -0
  93. data/test/fixtures/db_definitions/frontbase.drop.sql +1 -0
  94. data/test/fixtures/db_definitions/frontbase.sql +5 -0
  95. data/test/fixtures/db_definitions/openbase.sql +41 -25
  96. data/test/fixtures/db_definitions/oracle.drop.sql +2 -0
  97. data/test/fixtures/db_definitions/oracle.sql +5 -0
  98. data/test/fixtures/db_definitions/postgresql.drop.sql +7 -0
  99. data/test/fixtures/db_definitions/postgresql.sql +87 -58
  100. data/test/fixtures/db_definitions/postgresql2.sql +1 -2
  101. data/test/fixtures/db_definitions/schema.rb +280 -0
  102. data/test/fixtures/db_definitions/schema2.rb +11 -0
  103. data/test/fixtures/db_definitions/sqlite.drop.sql +1 -0
  104. data/test/fixtures/db_definitions/sqlite.sql +4 -0
  105. data/test/fixtures/db_definitions/sybase.drop.sql +1 -0
  106. data/test/fixtures/db_definitions/sybase.sql +4 -0
  107. data/test/fixtures/developer.rb +10 -0
  108. data/test/fixtures/example.log +1 -0
  109. data/test/fixtures/flowers.jpg +0 -0
  110. data/test/fixtures/item.rb +7 -0
  111. data/test/fixtures/items.yml +4 -0
  112. data/test/fixtures/joke.rb +0 -3
  113. data/test/fixtures/matey.rb +4 -0
  114. data/test/fixtures/mateys.yml +4 -0
  115. data/test/fixtures/minimalistic.rb +2 -0
  116. data/test/fixtures/minimalistics.yml +2 -0
  117. data/test/fixtures/mixins.yml +2 -100
  118. data/test/fixtures/parrot.rb +13 -0
  119. data/test/fixtures/parrots.yml +27 -0
  120. data/test/fixtures/parrots_pirates.yml +7 -0
  121. data/test/fixtures/pirate.rb +5 -0
  122. data/test/fixtures/pirates.yml +9 -0
  123. data/test/fixtures/post.rb +1 -0
  124. data/test/fixtures/project.rb +3 -2
  125. data/test/fixtures/reserved_words/distinct.yml +5 -0
  126. data/test/fixtures/reserved_words/distincts_selects.yml +11 -0
  127. data/test/fixtures/reserved_words/group.yml +14 -0
  128. data/test/fixtures/reserved_words/select.yml +8 -0
  129. data/test/fixtures/reserved_words/values.yml +7 -0
  130. data/test/fixtures/ship.rb +3 -0
  131. data/test/fixtures/ships.yml +5 -0
  132. data/test/fixtures/tagging.rb +4 -0
  133. data/test/fixtures/taggings.yml +8 -1
  134. data/test/fixtures/topic.rb +13 -1
  135. data/test/fixtures/treasure.rb +4 -0
  136. data/test/fixtures/treasures.yml +10 -0
  137. data/test/fixtures_test.rb +205 -24
  138. data/test/inheritance_test.rb +7 -1
  139. data/test/json_serialization_test.rb +180 -0
  140. data/test/lifecycle_test.rb +1 -1
  141. data/test/locking_test.rb +85 -2
  142. data/test/migration_test.rb +206 -40
  143. data/test/mixin_test.rb +13 -515
  144. data/test/pk_test.rb +3 -6
  145. data/test/query_cache_test.rb +104 -0
  146. data/test/reflection_test.rb +16 -0
  147. data/test/reserved_word_test_mysql.rb +177 -0
  148. data/test/schema_dumper_test.rb +38 -3
  149. data/test/serialization_test.rb +47 -0
  150. data/test/transactions_test.rb +74 -23
  151. data/test/unconnected_test.rb +1 -1
  152. data/test/validations_test.rb +322 -32
  153. data/test/xml_serialization_test.rb +121 -44
  154. metadata +48 -41
  155. data/examples/associations.rb +0 -87
  156. data/examples/shared_setup.rb +0 -15
  157. data/examples/validation.rb +0 -85
  158. data/lib/active_record/acts/list.rb +0 -256
  159. data/lib/active_record/acts/nested_set.rb +0 -211
  160. data/lib/active_record/acts/tree.rb +0 -96
  161. data/lib/active_record/connection_adapters/db2_adapter.rb +0 -228
  162. data/lib/active_record/connection_adapters/firebird_adapter.rb +0 -728
  163. data/lib/active_record/connection_adapters/frontbase_adapter.rb +0 -861
  164. data/lib/active_record/connection_adapters/openbase_adapter.rb +0 -350
  165. data/lib/active_record/connection_adapters/oracle_adapter.rb +0 -690
  166. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +0 -591
  167. data/lib/active_record/connection_adapters/sybase_adapter.rb +0 -662
  168. data/lib/active_record/deprecated_associations.rb +0 -104
  169. data/lib/active_record/deprecated_finders.rb +0 -44
  170. data/lib/active_record/vendor/simple.rb +0 -693
  171. data/lib/active_record/wrappers/yaml_wrapper.rb +0 -15
  172. data/lib/active_record/wrappings.rb +0 -58
  173. data/test/connections/native_sqlserver/connection.rb +0 -23
  174. data/test/connections/native_sqlserver_odbc/connection.rb +0 -25
  175. data/test/deprecated_associations_test.rb +0 -396
  176. data/test/fixtures/db_definitions/mysql.drop.sql +0 -32
  177. data/test/fixtures/db_definitions/mysql.sql +0 -234
  178. data/test/fixtures/db_definitions/mysql2.drop.sql +0 -2
  179. data/test/fixtures/db_definitions/mysql2.sql +0 -5
  180. data/test/fixtures/db_definitions/sqlserver.drop.sql +0 -34
  181. data/test/fixtures/db_definitions/sqlserver.sql +0 -243
  182. data/test/fixtures/db_definitions/sqlserver2.drop.sql +0 -2
  183. data/test/fixtures/db_definitions/sqlserver2.sql +0 -5
  184. data/test/fixtures/mixin.rb +0 -63
  185. data/test/mixin_nested_set_test.rb +0 -196
@@ -1,37 +1,32 @@
1
1
  require 'abstract_unit'
2
- require 'fixtures/binary'
3
2
 
4
- class BinaryTest < Test::Unit::TestCase
5
- BINARY_FIXTURE_PATH = File.dirname(__FILE__) + '/fixtures/flowers.jpg'
3
+ # Without using prepared statements, it makes no sense to test
4
+ # BLOB data with SQL Server, because the length of a statement is
5
+ # limited to 8KB.
6
+ #
7
+ # Without using prepared statements, it makes no sense to test
8
+ # BLOB data with DB2 or Firebird, because the length of a statement
9
+ # is limited to 32KB.
10
+ unless current_adapter?(:SQLServerAdapter, :SybaseAdapter, :DB2Adapter, :FirebirdAdapter)
11
+ require 'fixtures/binary'
6
12
 
7
- def setup
8
- Binary.connection.execute 'DELETE FROM binaries'
9
- @data = File.read(BINARY_FIXTURE_PATH).freeze
10
- end
11
-
12
- def test_truth
13
- assert true
14
- end
13
+ class BinaryTest < Test::Unit::TestCase
14
+ FIXTURES = %w(flowers.jpg example.log)
15
15
 
16
- # Without using prepared statements, it makes no sense to test
17
- # BLOB data with SQL Server, because the length of a statement is
18
- # limited to 8KB.
19
- #
20
- # Without using prepared statements, it makes no sense to test
21
- # BLOB data with DB2 or Firebird, because the length of a statement
22
- # is limited to 32KB.
23
- unless %w(SQLServer Sybase DB2 Oracle Firebird).include? ActiveRecord::Base.connection.adapter_name
24
16
  def test_load_save
25
- bin = Binary.new
26
- bin.data = @data
17
+ Binary.delete_all
18
+
19
+ FIXTURES.each do |filename|
20
+ data = File.read("#{File.dirname(__FILE__)}/fixtures/#{filename}").freeze
21
+
22
+ bin = Binary.new(:data => data)
23
+ assert_equal data, bin.data, 'Newly assigned data differs from original'
27
24
 
28
- assert @data == bin.data, 'Newly assigned data differs from original'
29
-
30
- bin.save
31
- assert @data == bin.data, 'Data differs from original after save'
25
+ bin.save!
26
+ assert_equal data, bin.data, 'Data differs from original after save'
32
27
 
33
- db_bin = Binary.find(bin.id)
34
- assert @data == db_bin.data, 'Reloaded data differs from original'
28
+ assert_equal data, bin.reload.data, 'Reloaded data differs from original'
29
+ end
35
30
  end
36
31
  end
37
32
  end
@@ -4,6 +4,10 @@ require 'fixtures/topic'
4
4
 
5
5
  Company.has_many :accounts
6
6
 
7
+ class NumericData < ActiveRecord::Base
8
+ self.table_name = 'numeric_data'
9
+ end
10
+
7
11
  class CalculationsTest < Test::Unit::TestCase
8
12
  fixtures :companies, :accounts, :topics
9
13
 
@@ -17,6 +21,10 @@ class CalculationsTest < Test::Unit::TestCase
17
21
  assert_in_delta 53.0, value, 0.001
18
22
  end
19
23
 
24
+ def test_should_return_nil_as_average
25
+ assert_nil NumericData.average(:bank_balance)
26
+ end
27
+
20
28
  def test_should_get_maximum_of_field
21
29
  assert_equal 60, Account.maximum(:credit_limit)
22
30
  end
@@ -131,6 +139,26 @@ class CalculationsTest < Test::Unit::TestCase
131
139
  assert_equal 2, c[companies(:rails_core)]
132
140
  assert_equal 1, c[companies(:first_client)]
133
141
  end
142
+
143
+ uses_mocha 'group_by_non_numeric_foreign_key_association' do
144
+ def test_should_group_by_association_with_non_numeric_foreign_key
145
+ ActiveRecord::Base.connection.expects(:select_all).returns([{"count_all" => 1, "firm_id" => "ABC"}])
146
+
147
+ firm = mock()
148
+ firm.expects(:id).returns("ABC")
149
+ firm.expects(:class).returns(Firm)
150
+ Company.expects(:find).with(["ABC"]).returns([firm])
151
+
152
+ column = mock()
153
+ column.expects(:name).at_least_once.returns(:firm_id)
154
+ column.expects(:type_cast).with("ABC").returns("ABC")
155
+ Account.expects(:columns).at_least_once.returns([column])
156
+
157
+ c = Account.count(:all, :group => :firm)
158
+ assert_equal Firm, c.first.first.class
159
+ assert_equal 1, c.first.last
160
+ end
161
+ end
134
162
 
135
163
  def test_should_not_modify_options_when_using_includes
136
164
  options = {:conditions => 'companies.id > 1', :include => :firm}
@@ -199,16 +227,20 @@ class CalculationsTest < Test::Unit::TestCase
199
227
  assert_raises(ArgumentError) { Company.send(:validate_calculation_options, :sum, :foo => :bar) }
200
228
  assert_raises(ArgumentError) { Company.send(:validate_calculation_options, :count, :foo => :bar) }
201
229
  end
202
-
230
+
203
231
  def test_should_count_selected_field_with_include
204
232
  assert_equal 6, Account.count(:distinct => true, :include => :firm)
205
233
  assert_equal 4, Account.count(:distinct => true, :include => :firm, :select => :credit_limit)
206
234
  end
207
-
208
- def test_deprecated_count_with_string_parameters
209
- assert_deprecated('count') { Account.count('credit_limit > 50') }
235
+
236
+ def test_count_with_column_parameter
237
+ assert_equal 5, Account.count(:firm_id)
210
238
  end
211
-
239
+
240
+ def test_count_with_column_and_options_parameter
241
+ assert_equal 2, Account.count(:firm_id, :conditions => "credit_limit = 50")
242
+ end
243
+
212
244
  def test_count_with_no_parameters_isnt_deprecated
213
245
  assert_not_deprecated { Account.count }
214
246
  end
@@ -49,6 +49,16 @@ class CallbackDeveloper < ActiveRecord::Base
49
49
  end
50
50
  end
51
51
 
52
+ class ParentDeveloper < ActiveRecord::Base
53
+ set_table_name 'developers'
54
+ attr_accessor :after_save_called
55
+ before_validation {|record| record.after_save_called = true}
56
+ end
57
+
58
+ class ChildDeveloper < ParentDeveloper
59
+
60
+ end
61
+
52
62
  class RecursiveCallbackDeveloper < ActiveRecord::Base
53
63
  set_table_name 'developers'
54
64
 
@@ -374,4 +384,17 @@ class CallbacksTest < Test::Unit::TestCase
374
384
  [ :before_validation, :returning_false ]
375
385
  ], david.history
376
386
  end
387
+
388
+ def test_inheritence_of_callbacks
389
+ parent = ParentDeveloper.new
390
+ assert !parent.after_save_called
391
+ parent.save
392
+ assert parent.after_save_called
393
+
394
+ child = ChildDeveloper.new
395
+ assert !child.after_save_called
396
+ child.save
397
+ assert child.after_save_called
398
+ end
399
+
377
400
  end
@@ -1,6 +1,6 @@
1
- require 'abstract_unit'
1
+ require "#{File.dirname(__FILE__)}/abstract_unit"
2
2
 
3
- class ConnectionTest < Test::Unit::TestCase
3
+ class FirebirdConnectionTest < Test::Unit::TestCase
4
4
  def test_charset_properly_set
5
5
  fb_conn = ActiveRecord::Base.connection.instance_variable_get(:@connection)
6
6
  assert_equal 'UTF8', fb_conn.database.character_set
@@ -0,0 +1,30 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_unit"
2
+
3
+ class MysqlConnectionTest < Test::Unit::TestCase
4
+ def setup
5
+ @connection = ActiveRecord::Base.connection
6
+ end
7
+
8
+ def test_no_automatic_reconnection_after_timeout
9
+ assert @connection.active?
10
+ @connection.update('set @@wait_timeout=1')
11
+ sleep 2
12
+ assert !@connection.active?
13
+ end
14
+
15
+ def test_successful_reconnection_after_timeout_with_manual_reconnect
16
+ assert @connection.active?
17
+ @connection.update('set @@wait_timeout=1')
18
+ sleep 2
19
+ @connection.reconnect!
20
+ assert @connection.active?
21
+ end
22
+
23
+ def test_successful_reconnection_after_timeout_with_verify
24
+ assert @connection.active?
25
+ @connection.update('set @@wait_timeout=1')
26
+ sleep 2
27
+ @connection.verify!(0)
28
+ assert @connection.active?
29
+ end
30
+ end
@@ -6,6 +6,9 @@ RAILS_DEFAULT_LOGGER = Logger.new('debug.log')
6
6
  RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
7
7
  ActiveRecord::Base.logger = RAILS_DEFAULT_LOGGER
8
8
 
9
+ # GRANT ALL PRIVILEGES ON activerecord_unittest.* to 'rails'@'localhost';
10
+ # GRANT ALL PRIVILEGES ON activerecord_unittest2.* to 'rails'@'localhost';
11
+
9
12
  ActiveRecord::Base.configurations = {
10
13
  'arunit' => {
11
14
  :adapter => 'mysql',
@@ -10,25 +10,16 @@ BASE_DIR = File.expand_path(File.dirname(__FILE__) + '/../../fixtures')
10
10
  sqlite_test_db = "#{BASE_DIR}/fixture_database.sqlite"
11
11
  sqlite_test_db2 = "#{BASE_DIR}/fixture_database_2.sqlite"
12
12
 
13
- def make_connection(clazz, db_file, db_definitions_file)
13
+ def make_connection(clazz, db_file)
14
14
  ActiveRecord::Base.configurations = { clazz.name => { :adapter => 'sqlite', :database => db_file } }
15
15
  unless File.exist?(db_file)
16
16
  puts "SQLite database not found at #{db_file}. Rebuilding it."
17
- sqlite_command = %Q{sqlite #{db_file} "create table a (a integer); drop table a;"}
17
+ sqlite_command = %Q{sqlite "#{db_file}" "create table a (a integer); drop table a;"}
18
18
  puts "Executing '#{sqlite_command}'"
19
19
  raise SqliteError.new("Seems that there is no sqlite executable available") unless system(sqlite_command)
20
- clazz.establish_connection(clazz.name)
21
- script = File.read("#{BASE_DIR}/db_definitions/#{db_definitions_file}")
22
- # SQLite-Ruby has problems with semi-colon separated commands, so split and execute one at a time
23
- script.split(';').each do
24
- |command|
25
- clazz.connection.execute(command) unless command.strip.empty?
26
- end
27
- else
28
- clazz.establish_connection(clazz.name)
29
20
  end
21
+ clazz.establish_connection(clazz.name)
30
22
  end
31
23
 
32
- make_connection(ActiveRecord::Base, sqlite_test_db, 'sqlite.sql')
33
- make_connection(Course, sqlite_test_db2, 'sqlite2.sql')
34
- load(File.join(BASE_DIR, 'db_definitions', 'schema.rb'))
24
+ make_connection(ActiveRecord::Base, sqlite_test_db)
25
+ make_connection(Course, sqlite_test_db2)
@@ -10,25 +10,16 @@ BASE_DIR = File.expand_path(File.dirname(__FILE__) + '/../../fixtures')
10
10
  sqlite_test_db = "#{BASE_DIR}/fixture_database.sqlite3"
11
11
  sqlite_test_db2 = "#{BASE_DIR}/fixture_database_2.sqlite3"
12
12
 
13
- def make_connection(clazz, db_file, db_definitions_file)
13
+ def make_connection(clazz, db_file)
14
14
  ActiveRecord::Base.configurations = { clazz.name => { :adapter => 'sqlite3', :database => db_file, :timeout => 5000 } }
15
15
  unless File.exist?(db_file)
16
16
  puts "SQLite3 database not found at #{db_file}. Rebuilding it."
17
- sqlite_command = %Q{sqlite3 #{db_file} "create table a (a integer); drop table a;"}
17
+ sqlite_command = %Q{sqlite3 "#{db_file}" "create table a (a integer); drop table a;"}
18
18
  puts "Executing '#{sqlite_command}'"
19
19
  raise SqliteError.new("Seems that there is no sqlite3 executable available") unless system(sqlite_command)
20
- clazz.establish_connection(clazz.name)
21
- script = File.read("#{BASE_DIR}/db_definitions/#{db_definitions_file}")
22
- # SQLite-Ruby has problems with semi-colon separated commands, so split and execute one at a time
23
- script.split(';').each do
24
- |command|
25
- clazz.connection.execute(command) unless command.strip.empty?
26
- end
27
- else
28
- clazz.establish_connection(clazz.name)
29
20
  end
21
+ clazz.establish_connection(clazz.name)
30
22
  end
31
23
 
32
- make_connection(ActiveRecord::Base, sqlite_test_db, 'sqlite.sql')
33
- make_connection(Course, sqlite_test_db2, 'sqlite2.sql')
34
- load(File.join(BASE_DIR, 'db_definitions', 'schema.rb'))
24
+ make_connection(ActiveRecord::Base, sqlite_test_db)
25
+ make_connection(Course, sqlite_test_db2)
@@ -15,4 +15,4 @@ end
15
15
 
16
16
  make_connection(ActiveRecord::Base, 'sqlite.sql')
17
17
  make_connection(Course, 'sqlite2.sql')
18
- load("#{File.dirname(__FILE__)}/../../fixtures/db_definitions/schema.rb"))
18
+ load("#{File.dirname(__FILE__)}/../../fixtures/db_definitions/schema.rb")
@@ -26,8 +26,9 @@ class CopyTableTest < Test::Unit::TestCase
26
26
  def test_copy_table_renaming_column
27
27
  test_copy_table('companies', 'companies2',
28
28
  :rename => {'client_of' => 'fan_of'}) do |from, to, options|
29
- assert_equal column_values(from, 'client_of').compact.sort,
30
- column_values(to, 'fan_of').compact.sort
29
+ expected = column_values(from, 'client_of')
30
+ assert expected.any?, 'only nils in resultset; real values are needed'
31
+ assert_equal expected, column_values(to, 'fan_of')
31
32
  end
32
33
  end
33
34
 
@@ -41,6 +42,10 @@ class CopyTableTest < Test::Unit::TestCase
41
42
  end
42
43
  end
43
44
 
45
+ def test_copy_table_without_primary_key
46
+ test_copy_table('developers_projects', 'programmers_projects')
47
+ end
48
+
44
49
  protected
45
50
  def copy_table(from, to, options = {})
46
51
  @connection.copy_table(from, to, {:temporary => true}.merge(options))
@@ -51,7 +56,7 @@ protected
51
56
  end
52
57
 
53
58
  def column_values(table, column)
54
- @connection.select_all("SELECT #{column} FROM #{table}").map {|row| row[column]}
59
+ @connection.select_all("SELECT #{column} FROM #{table} ORDER BY id").map {|row| row[column]}
55
60
  end
56
61
 
57
62
  def table_indexes_without_name(table)
@@ -1,52 +1,203 @@
1
1
  require 'abstract_unit'
2
2
 
3
- class PostgresqlDatatype < ActiveRecord::Base
3
+ class PostgresqlArray < ActiveRecord::Base
4
4
  end
5
5
 
6
- class PGDataTypeTest < Test::Unit::TestCase
7
- self.use_transactional_fixtures = false
6
+ class PostgresqlMoney < ActiveRecord::Base
7
+ end
8
+
9
+ class PostgresqlNumber < ActiveRecord::Base
10
+ end
11
+
12
+ class PostgresqlTime < ActiveRecord::Base
13
+ end
14
+
15
+ class PostgresqlNetworkAddress < ActiveRecord::Base
16
+ end
17
+
18
+ class PostgresqlBitString < ActiveRecord::Base
19
+ end
8
20
 
9
- TABLE_NAME = 'postgresql_datatypes'
10
- COLUMNS = [
11
- 'id SERIAL PRIMARY KEY',
12
- 'commission_by_quarter INTEGER[]',
13
- 'nicknames TEXT[]'
14
- ]
21
+ class PostgresqlOid < ActiveRecord::Base
22
+ end
23
+
24
+ class PostgresqlDataTypeTest < Test::Unit::TestCase
25
+ self.use_transactional_fixtures = false
15
26
 
16
27
  def setup
17
28
  @connection = ActiveRecord::Base.connection
18
- @connection.execute "CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
19
- @connection.execute "INSERT INTO #{TABLE_NAME} (commission_by_quarter, nicknames) VALUES ( '{35000,21000,18000,17000}', '{foo,bar,baz}' )"
20
- @first = PostgresqlDatatype.find( 1 )
21
- end
22
29
 
23
- def teardown
24
- @connection.execute "DROP TABLE #{TABLE_NAME}"
30
+ @connection.execute("INSERT INTO postgresql_arrays (commission_by_quarter, nicknames) VALUES ( '{35000,21000,18000,17000}', '{foo,bar,baz}' )")
31
+ @first_array = PostgresqlArray.find(1)
32
+
33
+ @connection.execute("INSERT INTO postgresql_moneys (wealth) VALUES ('$567.89')")
34
+ @connection.execute("INSERT INTO postgresql_moneys (wealth) VALUES ('-$567.89')")
35
+ @first_money = PostgresqlMoney.find(1)
36
+ @second_money = PostgresqlMoney.find(2)
37
+
38
+ @connection.execute("INSERT INTO postgresql_numbers (single, double) VALUES (123.456, 123456.789)")
39
+ @first_number = PostgresqlNumber.find(1)
40
+
41
+ @connection.execute("INSERT INTO postgresql_times (time_interval) VALUES ('1 year 2 days ago')")
42
+ @first_time = PostgresqlTime.find(1)
43
+
44
+ @connection.execute("INSERT INTO postgresql_network_addresses (cidr_address, inet_address, mac_address) VALUES('192.168.0/24', '172.16.1.254/32', '01:23:45:67:89:0a')")
45
+ @first_network_address = PostgresqlNetworkAddress.find(1)
46
+
47
+ @connection.execute("INSERT INTO postgresql_bit_strings (bit_string, bit_string_varying) VALUES (B'00010101', X'15')")
48
+ @first_bit_string = PostgresqlBitString.find(1)
49
+
50
+ @connection.execute("INSERT INTO postgresql_oids (obj_id) VALUES (1234)")
51
+ @first_oid = PostgresqlOid.find(1)
25
52
  end
26
53
 
27
54
  def test_data_type_of_array_types
28
- assert_equal :string, @first.column_for_attribute("commission_by_quarter").type
29
- assert_equal :string, @first.column_for_attribute("nicknames").type
55
+ assert_equal :string, @first_array.column_for_attribute(:commission_by_quarter).type
56
+ assert_equal :string, @first_array.column_for_attribute(:nicknames).type
57
+ end
58
+
59
+ def test_data_type_of_money_types
60
+ assert_equal :decimal, @first_money.column_for_attribute(:wealth).type
61
+ end
62
+
63
+ def test_data_type_of_number_types
64
+ assert_equal :float, @first_number.column_for_attribute(:single).type
65
+ assert_equal :float, @first_number.column_for_attribute(:double).type
66
+ end
67
+
68
+ def test_data_type_of_time_types
69
+ assert_equal :string, @first_time.column_for_attribute(:time_interval).type
70
+ end
71
+
72
+ def test_data_type_of_network_address_types
73
+ assert_equal :string, @first_network_address.column_for_attribute(:cidr_address).type
74
+ assert_equal :string, @first_network_address.column_for_attribute(:inet_address).type
75
+ assert_equal :string, @first_network_address.column_for_attribute(:mac_address).type
76
+ end
77
+
78
+ def test_data_type_of_bit_string_types
79
+ assert_equal :string, @first_bit_string.column_for_attribute(:bit_string).type
80
+ assert_equal :string, @first_bit_string.column_for_attribute(:bit_string_varying).type
81
+ end
82
+
83
+ def test_data_type_of_oid_types
84
+ assert_equal :integer, @first_oid.column_for_attribute(:obj_id).type
30
85
  end
31
86
 
32
87
  def test_array_values
33
- assert_equal '{35000,21000,18000,17000}', @first.commission_by_quarter
34
- assert_equal '{foo,bar,baz}', @first.nicknames
88
+ assert_equal '{35000,21000,18000,17000}', @first_array.commission_by_quarter
89
+ assert_equal '{foo,bar,baz}', @first_array.nicknames
90
+ end
91
+
92
+ def test_money_values
93
+ assert_equal 567.89, @first_money.wealth
94
+ assert_equal -567.89, @second_money.wealth
95
+ end
96
+
97
+ def test_number_values
98
+ assert_equal 123.456, @first_number.single
99
+ assert_equal 123456.789, @first_number.double
100
+ end
101
+
102
+ def test_time_values
103
+ assert_equal '-1 years -2 days', @first_time.time_interval
104
+ end
105
+
106
+ def test_network_address_values
107
+ assert_equal '192.168.0.0/24', @first_network_address.cidr_address
108
+ assert_equal '172.16.1.254', @first_network_address.inet_address
109
+ assert_equal '01:23:45:67:89:0a', @first_network_address.mac_address
110
+ end
111
+
112
+ def test_bit_string_values
113
+ assert_equal '00010101', @first_bit_string.bit_string
114
+ assert_equal '00010101', @first_bit_string.bit_string_varying
115
+ end
116
+
117
+ def test_oid_values
118
+ assert_equal 1234, @first_oid.obj_id
35
119
  end
36
120
 
37
121
  def test_update_integer_array
38
122
  new_value = '{32800,95000,29350,17000}'
39
- assert @first.commission_by_quarter = new_value
40
- assert @first.save
41
- assert @first.reload
42
- assert_equal @first.commission_by_quarter, new_value
123
+ assert @first_array.commission_by_quarter = new_value
124
+ assert @first_array.save
125
+ assert @first_array.reload
126
+ assert_equal @first_array.commission_by_quarter, new_value
127
+ assert @first_array.commission_by_quarter = new_value
128
+ assert @first_array.save
129
+ assert @first_array.reload
130
+ assert_equal @first_array.commission_by_quarter, new_value
43
131
  end
44
132
 
45
133
  def test_update_text_array
46
134
  new_value = '{robby,robert,rob,robbie}'
47
- assert @first.nicknames = new_value
48
- assert @first.save
49
- assert @first.reload
50
- assert_equal @first.nicknames, new_value
135
+ assert @first_array.nicknames = new_value
136
+ assert @first_array.save
137
+ assert @first_array.reload
138
+ assert_equal @first_array.nicknames, new_value
139
+ assert @first_array.nicknames = new_value
140
+ assert @first_array.save
141
+ assert @first_array.reload
142
+ assert_equal @first_array.nicknames, new_value
143
+ end
144
+
145
+ def test_update_money
146
+ new_value = 123.45
147
+ assert @first_money.wealth = new_value
148
+ assert @first_money.save
149
+ assert @first_money.reload
150
+ assert_equal @first_money.wealth, new_value
151
+ end
152
+
153
+ def test_update_number
154
+ new_single = 789.012
155
+ new_double = 789012.345
156
+ assert @first_number.single = new_single
157
+ assert @first_number.double = new_double
158
+ assert @first_number.save
159
+ assert @first_number.reload
160
+ assert_equal @first_number.single, new_single
161
+ assert_equal @first_number.double, new_double
162
+ end
163
+
164
+ def test_update_time
165
+ assert @first_time.time_interval = '2 years 3 minutes'
166
+ assert @first_time.save
167
+ assert @first_time.reload
168
+ assert_equal @first_time.time_interval, '2 years 00:03:00'
169
+ end
170
+
171
+ def test_update_network_address
172
+ new_cidr_address = '10.1.2.3/32'
173
+ new_inet_address = '10.0.0.0/8'
174
+ new_mac_address = 'bc:de:f0:12:34:56'
175
+ assert @first_network_address.cidr_address = new_cidr_address
176
+ assert @first_network_address.inet_address = new_inet_address
177
+ assert @first_network_address.mac_address = new_mac_address
178
+ assert @first_network_address.save
179
+ assert @first_network_address.reload
180
+ assert_equal @first_network_address.cidr_address, new_cidr_address
181
+ assert_equal @first_network_address.inet_address, new_inet_address
182
+ assert_equal @first_network_address.mac_address, new_mac_address
183
+ end
184
+
185
+ def test_update_bit_string
186
+ new_bit_string = '11111111'
187
+ new_bit_string_varying = 'FF'
188
+ assert @first_bit_string.bit_string = new_bit_string
189
+ assert @first_bit_string.bit_string_varying = new_bit_string_varying
190
+ assert @first_bit_string.save
191
+ assert @first_bit_string.reload
192
+ assert_equal @first_bit_string.bit_string, new_bit_string
193
+ assert_equal @first_bit_string.bit_string, @first_bit_string.bit_string_varying
194
+ end
195
+
196
+ def test_update_oid
197
+ new_value = 567890
198
+ assert @first_oid.obj_id = new_value
199
+ assert @first_oid.save
200
+ assert @first_oid.reload
201
+ assert_equal @first_oid.obj_id, new_value
51
202
  end
52
203
  end