activerecord-jdbc-adapter 1.2.9.1 → 1.3.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (231) hide show
  1. data/.travis.yml +3 -0
  2. data/Appraisals +12 -4
  3. data/Gemfile +3 -3
  4. data/Gemfile.lock +19 -19
  5. data/History.txt +90 -16
  6. data/LICENSE.txt +2 -1
  7. data/README.md +14 -1
  8. data/activerecord-jdbc-adapter.gemspec +2 -2
  9. data/gemfiles/rails23.gemfile +5 -5
  10. data/gemfiles/rails23.gemfile.lock +27 -27
  11. data/gemfiles/rails30.gemfile +3 -3
  12. data/gemfiles/rails30.gemfile.lock +8 -8
  13. data/gemfiles/rails31.gemfile +4 -4
  14. data/gemfiles/rails31.gemfile.lock +18 -18
  15. data/gemfiles/rails32.gemfile +4 -4
  16. data/gemfiles/rails32.gemfile.lock +17 -17
  17. data/gemfiles/rails40.gemfile +17 -0
  18. data/gemfiles/rails40.gemfile.lock +126 -0
  19. data/lib/activerecord-jdbc-adapter.rb +0 -7
  20. data/lib/arjdbc.rb +6 -5
  21. data/lib/arjdbc/db2.rb +1 -1
  22. data/lib/arjdbc/db2/adapter.rb +52 -29
  23. data/lib/arjdbc/db2/connection_methods.rb +13 -14
  24. data/lib/arjdbc/derby.rb +1 -1
  25. data/lib/arjdbc/derby/adapter.rb +29 -9
  26. data/lib/arjdbc/derby/connection_methods.rb +17 -20
  27. data/lib/arjdbc/firebird.rb +1 -1
  28. data/lib/arjdbc/h2.rb +2 -2
  29. data/lib/arjdbc/h2/adapter.rb +1 -1
  30. data/lib/arjdbc/h2/connection_methods.rb +12 -16
  31. data/lib/arjdbc/hsqldb.rb +1 -1
  32. data/lib/arjdbc/hsqldb/connection_methods.rb +13 -16
  33. data/lib/arjdbc/informix.rb +1 -1
  34. data/lib/arjdbc/informix/connection_methods.rb +8 -10
  35. data/lib/arjdbc/jdbc.rb +1 -1
  36. data/lib/arjdbc/jdbc/adapter.rb +125 -53
  37. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  38. data/lib/arjdbc/jdbc/base_ext.rb +34 -9
  39. data/lib/arjdbc/jdbc/column.rb +15 -2
  40. data/lib/arjdbc/jdbc/connection.rb +0 -2
  41. data/lib/arjdbc/jdbc/connection_methods.rb +10 -3
  42. data/lib/arjdbc/jdbc/driver.rb +2 -2
  43. data/lib/arjdbc/jdbc/extension.rb +35 -21
  44. data/lib/arjdbc/jdbc/java.rb +0 -2
  45. data/lib/arjdbc/jdbc/missing_functionality_helper.rb +35 -25
  46. data/lib/arjdbc/jdbc/railtie.rb +2 -9
  47. data/lib/arjdbc/mimer.rb +1 -1
  48. data/lib/arjdbc/mssql.rb +2 -2
  49. data/lib/arjdbc/mssql/adapter.rb +271 -92
  50. data/lib/arjdbc/mssql/connection_methods.rb +30 -32
  51. data/lib/arjdbc/mssql/explain_support.rb +107 -0
  52. data/lib/arjdbc/mssql/limit_helpers.rb +48 -18
  53. data/lib/arjdbc/mysql.rb +1 -1
  54. data/lib/arjdbc/mysql/adapter.rb +63 -14
  55. data/lib/arjdbc/mysql/connection_methods.rb +22 -24
  56. data/lib/arjdbc/mysql/explain_support.rb +2 -5
  57. data/lib/arjdbc/oracle.rb +1 -1
  58. data/lib/arjdbc/oracle/adapter.rb +78 -38
  59. data/lib/arjdbc/oracle/connection_methods.rb +9 -10
  60. data/lib/arjdbc/postgresql.rb +1 -1
  61. data/lib/arjdbc/postgresql/adapter.rb +964 -380
  62. data/lib/arjdbc/postgresql/column_cast.rb +136 -0
  63. data/lib/arjdbc/postgresql/connection_methods.rb +19 -21
  64. data/lib/arjdbc/postgresql/explain_support.rb +3 -6
  65. data/lib/arjdbc/railtie.rb +9 -0
  66. data/lib/arjdbc/sqlite3.rb +1 -1
  67. data/lib/arjdbc/sqlite3/adapter.rb +73 -26
  68. data/lib/arjdbc/sqlite3/connection_methods.rb +27 -28
  69. data/lib/arjdbc/sqlite3/explain_support.rb +2 -5
  70. data/lib/arjdbc/sybase.rb +1 -1
  71. data/lib/arjdbc/version.rb +5 -4
  72. data/pom.xml +8 -0
  73. data/rakelib/02-test.rake +57 -51
  74. data/rakelib/compile.rake +17 -5
  75. data/rakelib/rails.rake +42 -31
  76. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +4 -3
  77. data/src/java/arjdbc/derby/DerbyModule.java +98 -85
  78. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +70 -0
  79. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +0 -4
  80. data/src/java/arjdbc/jdbc/AdapterJavaService.java +26 -15
  81. data/src/java/arjdbc/jdbc/Callable.java +44 -0
  82. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +10 -2
  83. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1675 -834
  84. data/src/java/arjdbc/jdbc/SQLBlock.java +9 -3
  85. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +73 -36
  86. data/src/java/arjdbc/mysql/MySQLModule.java +11 -10
  87. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +86 -80
  88. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +27 -7
  89. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +214 -0
  90. data/src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java +25 -67
  91. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +52 -49
  92. data/src/java/arjdbc/util/QuotingUtils.java +6 -6
  93. data/test/abstract_db_create.rb +11 -11
  94. data/test/activerecord/connection_adapters/type_conversion_test.rb +18 -12
  95. data/test/db/db2.rb +1 -1
  96. data/test/{db2_binary_test.rb → db/db2/binary_test.rb} +0 -0
  97. data/test/db/db2/has_many_through_test.rb +6 -0
  98. data/test/{db2_reset_column_information_test.rb → db/db2/reset_column_information_test.rb} +1 -2
  99. data/test/{db2_serialize_test.rb → db/db2/serialize_test.rb} +0 -0
  100. data/test/{db2_simple_test.rb → db/db2/simple_test.rb} +1 -8
  101. data/test/db/db2/test_helper.rb +6 -0
  102. data/test/{db2_test.rb → db/db2/unit_test.rb} +1 -1
  103. data/test/db/derby.rb +1 -1
  104. data/test/{derby_binary_test.rb → db/derby/binary_test.rb} +0 -0
  105. data/test/{derby_migration_test.rb → db/derby/migration_test.rb} +0 -0
  106. data/test/{derby_reset_column_information_test.rb → db/derby/reset_column_information_test.rb} +0 -0
  107. data/test/{derby_row_locking_test.rb → db/derby/row_locking_test.rb} +1 -4
  108. data/test/db/derby/schema_dump_test.rb +5 -0
  109. data/test/{derby_serialize_test.rb → db/derby/serialize_test.rb} +0 -0
  110. data/test/{derby_simple_test.rb → db/derby/simple_test.rb} +23 -38
  111. data/test/db/derby/test_helper.rb +6 -0
  112. data/test/db/derby/unit_test.rb +32 -0
  113. data/test/db/derby/xml_column_test.rb +17 -0
  114. data/test/db/h2.rb +1 -1
  115. data/test/{h2_binary_test.rb → db/h2/binary_test.rb} +0 -0
  116. data/test/{h2_change_column_test.rb → db/h2/change_column_test.rb} +1 -0
  117. data/test/{h2_schema_dump_test.rb → db/h2/schema_dump_test.rb} +0 -0
  118. data/test/{h2_serialize_test.rb → db/h2/serialize_test.rb} +0 -0
  119. data/test/{h2_simple_test.rb → db/h2/simple_test.rb} +3 -1
  120. data/test/db/hsqldb.rb +1 -1
  121. data/test/{hsqldb_binary_test.rb → db/hsqldb/binary_test.rb} +0 -0
  122. data/test/{hsqldb_schema_dump_test.rb → db/hsqldb/schema_dump_test.rb} +0 -0
  123. data/test/{hsqldb_serialize_test.rb → db/hsqldb/serialize_test.rb} +0 -0
  124. data/test/{hsqldb_simple_test.rb → db/hsqldb/simple_test.rb} +3 -1
  125. data/test/db/informix.rb +1 -1
  126. data/test/db/jdbc.rb +3 -2
  127. data/test/db/jdbc_derby.rb +1 -1
  128. data/test/db/jdbc_h2.rb +1 -1
  129. data/test/db/jdbc_mysql.rb +1 -1
  130. data/test/db/jdbc_postgres.rb +1 -1
  131. data/test/db/jndi_config.rb +1 -2
  132. data/test/db/jndi_pooled_config.rb +2 -3
  133. data/test/db/mssql.rb +2 -2
  134. data/test/{mssql_binary_test.rb → db/mssql/binary_test.rb} +0 -0
  135. data/test/{mssql_db_create_test.rb → db/mssql/db_create_test.rb} +1 -1
  136. data/test/db/mssql/exec_proc_test.rb +46 -0
  137. data/test/{mssql_identity_insert_test.rb → db/mssql/identity_insert_test.rb} +0 -0
  138. data/test/db/mssql/ignore_system_views_test.rb +40 -0
  139. data/test/{mssql_limit_offset_test.rb → db/mssql/limit_offset_test.rb} +10 -1
  140. data/test/{mssql_multibyte_test.rb → db/mssql/multibyte_test.rb} +0 -0
  141. data/test/db/mssql/multiple_connections_test.rb +71 -0
  142. data/test/{mssql_reset_column_information_test.rb → db/mssql/reset_column_information_test.rb} +0 -0
  143. data/test/{mssql_row_locking_test.rb → db/mssql/row_locking_test.rb} +0 -0
  144. data/test/{mssql_serialize_test.rb → db/mssql/serialize_test.rb} +1 -1
  145. data/test/db/mssql/simple_test.rb +140 -0
  146. data/test/db/mssql/transaction_test.rb +6 -0
  147. data/test/db/mssql/types_test.rb +205 -0
  148. data/test/{mssql_test.rb → db/mssql/unit_test.rb} +2 -2
  149. data/test/db/mysql.rb +1 -2
  150. data/test/db/mysql/_rails_test_mysql.32.out +6768 -0
  151. data/test/{mysql_binary_test.rb → db/mysql/binary_test.rb} +0 -0
  152. data/test/db/mysql/connection_test.rb +51 -0
  153. data/test/{mysql_db_create_test.rb → db/mysql/db_create_test.rb} +0 -0
  154. data/test/{mysql_index_length_test.rb → db/mysql/index_length_test.rb} +0 -0
  155. data/test/{mysql_multibyte_test.rb → db/mysql/multibyte_test.rb} +0 -0
  156. data/test/{mysql_nonstandard_primary_key_test.rb → db/mysql/nonstandard_primary_key_test.rb} +0 -0
  157. data/test/{mysql_reset_column_information_test.rb → db/mysql/reset_column_information_test.rb} +0 -0
  158. data/test/{mysql_schema_dump_test.rb → db/mysql/schema_dump_test.rb} +9 -1
  159. data/test/{mysql_serialize_test.rb → db/mysql/serialize_test.rb} +0 -0
  160. data/test/{mysql_simple_test.rb → db/mysql/simple_test.rb} +16 -8
  161. data/test/db/mysql/transaction_test.rb +6 -0
  162. data/test/db/mysql/types_test.rb +30 -0
  163. data/test/{mysql_test.rb → db/mysql/unit_test.rb} +1 -1
  164. data/test/db/mysql_config.rb +1 -1
  165. data/test/db/oracle.rb +1 -1
  166. data/test/{oracle_binary_test.rb → db/oracle/binary_test.rb} +0 -0
  167. data/test/{oracle_limit_test.rb → db/oracle/limit_test.rb} +0 -0
  168. data/test/db/oracle/multibyte_test.rb +22 -0
  169. data/test/{oracle_reset_column_information_test.rb → db/oracle/reset_column_information_test.rb} +0 -0
  170. data/test/{oracle_serialize_test.rb → db/oracle/serialize_test.rb} +0 -0
  171. data/test/{oracle_simple_test.rb → db/oracle/simple_test.rb} +14 -19
  172. data/test/{oracle_specific_test.rb → db/oracle/specific_test.rb} +62 -16
  173. data/test/db/oracle/transaction_test.rb +31 -0
  174. data/test/db/oracle/unit_test.rb +31 -0
  175. data/test/db/postgres.rb +1 -1
  176. data/test/db/postgres/_rails_test_postgres.32.out +6777 -0
  177. data/test/db/postgres/a_custom_primary_key_test.rb +50 -0
  178. data/test/db/postgres/array_type_test.rb +101 -0
  179. data/test/{postgres_binary_test.rb → db/postgres/binary_test.rb} +0 -0
  180. data/test/db/postgres/connection_test.rb +55 -0
  181. data/test/db/postgres/data_types_test.rb +703 -0
  182. data/test/{postgres_db_create_test.rb → db/postgres/db_create_test.rb} +1 -1
  183. data/test/{postgres_drop_db_test.rb → db/postgres/db_drop_test.rb} +2 -0
  184. data/test/db/postgres/hstore_test.rb +200 -0
  185. data/test/db/postgres/information_schema_leak_test.rb +30 -0
  186. data/test/db/postgres/json_test.rb +86 -0
  187. data/test/db/postgres/ltree_test.rb +50 -0
  188. data/test/{postgres_mixed_case_test.rb → db/postgres/mixed_case_test.rb} +0 -0
  189. data/test/db/postgres/native_types_test.rb +128 -0
  190. data/test/{postgres_reserved_test.rb → db/postgres/reserved_test.rb} +0 -0
  191. data/test/{postgres_reset_column_information_test.rb → db/postgres/reset_column_information_test.rb} +0 -0
  192. data/test/{postgres_row_locking_test.rb → db/postgres/row_locking_test.rb} +0 -0
  193. data/test/{postgres_schema_dump_test.rb → db/postgres/schema_dump_test.rb} +4 -4
  194. data/test/db/postgres/schema_test.rb +113 -0
  195. data/test/{postgres_simple_test.rb → db/postgres/simple_test.rb} +48 -8
  196. data/test/{postgres_table_alias_length_test.rb → db/postgres/table_alias_length_test.rb} +2 -1
  197. data/test/db/postgres/transaction_test.rb +6 -0
  198. data/test/{postgres_test.rb → db/postgres/unit_test.rb} +3 -3
  199. data/test/db/sqlite3.rb +1 -1
  200. data/test/db/sqlite3/_rails_test_sqlite3.32.out +6502 -0
  201. data/test/db/sqlite3/has_many_though_test.rb +6 -0
  202. data/test/{sqlite3_reset_column_information_test.rb → db/sqlite3/reset_column_information_test.rb} +0 -0
  203. data/test/{sqlite3_schema_dump_test.rb → db/sqlite3/schema_dump_test.rb} +0 -0
  204. data/test/{sqlite3_serialize_test.rb → db/sqlite3/serialize_test.rb} +0 -0
  205. data/test/{sqlite3_simple_test.rb → db/sqlite3/simple_test.rb} +63 -63
  206. data/test/db/sqlite3/transaction_test.rb +32 -0
  207. data/test/{sqlite3_type_conversion_test.rb → db/sqlite3/type_conversion_test.rb} +0 -0
  208. data/test/has_many_through.rb +29 -64
  209. data/test/jdbc/oracle.rb +11 -0
  210. data/test/jndi_test.rb +16 -4
  211. data/test/models/auto_id.rb +1 -1
  212. data/test/models/rights_and_roles.rb +57 -0
  213. data/test/row_locking.rb +3 -0
  214. data/test/schema_dump.rb +24 -10
  215. data/test/simple.rb +359 -104
  216. data/test/test_helper.rb +4 -2
  217. data/test/transaction.rb +109 -0
  218. metadata +119 -86
  219. data/lib/arjdbc/jdbc/compatibility.rb +0 -51
  220. data/lib/arjdbc/jdbc/core_ext.rb +0 -24
  221. data/lib/arjdbc/jdbc/discover.rb +0 -18
  222. data/test/derby_schema_dump_test.rb +0 -9
  223. data/test/mssql_ignore_system_views_test.rb +0 -30
  224. data/test/mssql_legacy_types_test.rb +0 -58
  225. data/test/mssql_null_test.rb +0 -14
  226. data/test/mssql_simple_test.rb +0 -51
  227. data/test/postgres_information_schema_leak_test.rb +0 -28
  228. data/test/postgres_native_type_mapping_test.rb +0 -93
  229. data/test/postgres_nonseq_pkey_test.rb +0 -38
  230. data/test/postgres_schema_search_path_test.rb +0 -48
  231. data/test/postgres_type_conversion_test.rb +0 -33
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+ require 'db/postgres'
3
+
4
+ # NOTE: named to execute before:
5
+ # - PostgresConnectionTest
6
+ # - PostgresDbCreateTest
7
+ # - PostgresDbDropTest
8
+ # since on 3.1 otherwise starts weirdly failing (when full suite is run) :
9
+ #
10
+ # ActiveRecord::JDBCError: org.postgresql.util.PSQLException: ERROR:
11
+ # null value in column "uhash" violates not-null constraint
12
+ # Detail: Failing row contains (null, http://url.to).:
13
+ # INSERT INTO "some_urls" ("url") VALUES ('http://url.to') RETURNING "uhash"
14
+ #
15
+ class PostgresACustomPrimaryKeyTest < Test::Unit::TestCase
16
+
17
+ class CreateUrls < ActiveRecord::Migration
18
+ def self.up
19
+ create_table 'some_urls', :id => false do |t|
20
+ t.string :uhash, :null => false
21
+ t.text :url, :null => false
22
+ end
23
+ execute "ALTER TABLE some_urls ADD PRIMARY KEY (uhash)"
24
+ end
25
+ def self.down
26
+ drop_table 'some_urls'
27
+ end
28
+ end
29
+
30
+ def setup
31
+ CreateUrls.up
32
+ end
33
+
34
+ def teardown
35
+ CreateUrls.down
36
+ end
37
+
38
+ class SomeUrl < ActiveRecord::Base
39
+ self.primary_key = :uhash
40
+ end
41
+
42
+ def test_create_url
43
+ url = SomeUrl.create! do |instance|
44
+ instance.uhash = 'uhash'
45
+ instance.url = 'http://url.to'
46
+ end
47
+ assert_equal 'uhash', url.reload.uhash
48
+ end
49
+
50
+ end
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+ require 'db/postgres'
4
+
5
+ class PostgreSQLArrayTypeTest < Test::Unit::TestCase
6
+
7
+ class PgArray < ActiveRecord::Base
8
+ self.table_name = 'pg_arrays'
9
+ end
10
+
11
+ def setup
12
+ @connection = ActiveRecord::Base.connection
13
+ @connection.transaction do
14
+ @connection.create_table('pg_arrays') do |t|
15
+ t.string 'tags', :array => true
16
+ end
17
+ end
18
+ end
19
+
20
+ def teardown
21
+ @connection.execute 'DROP TABLE IF EXISTS pg_arrays'
22
+ end
23
+
24
+ def test_column
25
+ column = PgArray.columns.find { |c| c.name == 'tags' }
26
+ assert_equal :string, column.type
27
+ assert column.array
28
+ end
29
+
30
+ # def test_type_cast_array
31
+ # assert column = PgArray.columns.find { |c| c.name == 'tags' }
32
+ #
33
+ # data = '{1,2,3}'
34
+ # oid_type = column.instance_variable_get('@oid_type').subtype
35
+ # # we are getting the instance variable in this test, but in the
36
+ # # normal use of string_to_array, it's called from the OID::Array
37
+ # # class and will have the OID instance that will provide the type
38
+ # # casting
39
+ # array = column.class.string_to_array data, oid_type
40
+ # assert_equal(['1', '2', '3'], array)
41
+ # assert_equal(['1', '2', '3'], column.type_cast(data))
42
+ #
43
+ # assert_equal([], column.type_cast('{}'))
44
+ # assert_equal([nil], column.type_cast('{NULL}'))
45
+ # end
46
+
47
+ def test_rewrite
48
+ @connection.execute "INSERT INTO pg_arrays (tags) VALUES ('{1,2,3}')"
49
+ x = PgArray.first
50
+ x.tags = ['1','2','3','4']
51
+ assert x.save!
52
+ assert_equal(['1','2','3','4'], x.reload.tags)
53
+ end
54
+
55
+ def test_select
56
+ @connection.execute "INSERT INTO pg_arrays (tags) VALUES ('{1,2,3}')"
57
+ x = PgArray.first
58
+ assert_equal(['1','2','3'], x.tags)
59
+ end
60
+
61
+ def test_multi_dimensional
62
+ pend
63
+ assert_cycle([['1','2'],['2','3']])
64
+ end
65
+
66
+ def test_strings_with_quotes
67
+ assert_cycle(['this has','some "s that need to be escaped"'])
68
+ end
69
+
70
+ def test_strings_with_commas
71
+ assert_cycle(['this,has','many,values'])
72
+ end
73
+
74
+ def test_strings_with_array_delimiters
75
+ assert_cycle(['{','}'])
76
+ end
77
+
78
+ def test_strings_with_null_strings
79
+ assert_cycle(['NULL','NULL'])
80
+ end
81
+
82
+ def test_contains_nils
83
+ assert_cycle(['1',nil,nil])
84
+ end
85
+
86
+ private
87
+ def assert_cycle array
88
+ # test creation
89
+ x = PgArray.create!(:tags => array)
90
+ x.reload
91
+ assert_equal(array, x.tags)
92
+
93
+ # test updating
94
+ x = PgArray.create!(:tags => [])
95
+ x.tags = array
96
+ x.save!
97
+ x.reload
98
+ assert_equal(array, x.tags)
99
+ end
100
+
101
+ end if Test::Unit::TestCase.ar_version('4.0')
@@ -0,0 +1,55 @@
1
+ require 'db/postgres'
2
+
3
+ class PostgresConnectionTest < Test::Unit::TestCase
4
+
5
+ def test_set_session_variable_true
6
+ run_without_connection do |orig_connection|
7
+ ActiveRecord::Base.establish_connection(orig_connection.merge({:variables => {:debug_print_plan => true}}))
8
+ set_true_rows = select_rows "SHOW DEBUG_PRINT_PLAN"
9
+ assert_equal set_true_rows, [["on"]]
10
+ end
11
+ end
12
+
13
+ def test_set_session_variable_false
14
+ run_without_connection do |orig_connection|
15
+ ActiveRecord::Base.establish_connection(orig_connection.merge({:variables => {:debug_print_plan => false}}))
16
+ set_false_rows = select_rows "SHOW DEBUG_PRINT_PLAN"
17
+ assert_equal set_false_rows, [["off"]]
18
+ end
19
+ end
20
+
21
+ def test_set_session_variable_nil
22
+ run_without_connection do |orig_connection|
23
+ # This should be a no-op that does not raise an error
24
+ ActiveRecord::Base.establish_connection(orig_connection.merge({:variables => {:debug_print_plan => nil}}))
25
+ select_rows "SHOW DEBUG_PRINT_PLAN"
26
+ end
27
+ end
28
+
29
+ def test_set_session_variable_default
30
+ run_without_connection do |orig_connection|
31
+ # This should execute a query that does not raise an error
32
+ ActiveRecord::Base.establish_connection(orig_connection.merge({:variables => {:debug_print_plan => :default}}))
33
+ select_rows "SHOW DEBUG_PRINT_PLAN"
34
+ end
35
+ end
36
+
37
+ protected
38
+
39
+ def select_rows(sql)
40
+ result = ActiveRecord::Base.connection.exec_query(sql)
41
+ result.respond_to?(:rows) ? result.rows : [ result.first.map { |_,value| value } ]
42
+ end
43
+
44
+ private
45
+
46
+ def run_without_connection
47
+ original_connection = ActiveRecord::Base.remove_connection
48
+ begin
49
+ yield original_connection
50
+ ensure
51
+ ActiveRecord::Base.establish_connection POSTGRES_CONFIG
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,703 @@
1
+ require 'test_helper'
2
+ require 'db/postgres'
3
+
4
+ class PostgresqlDataTypeTest < Test::Unit::TestCase
5
+
6
+ class PostgresqlArray < ActiveRecord::Base; end
7
+ class PostgresqlUUID < ActiveRecord::Base; end
8
+ class PostgresqlRange < ActiveRecord::Base; end
9
+ class PostgresqlTsvector < ActiveRecord::Base; end
10
+ class PostgresqlMoney < ActiveRecord::Base; end
11
+ class PostgresqlNumber < ActiveRecord::Base; end
12
+ class PostgresqlTime < ActiveRecord::Base; end
13
+ class PostgresqlNetworkAddress < ActiveRecord::Base; end
14
+ class PostgresqlBitString < ActiveRecord::Base; end
15
+ class PostgresqlOid < ActiveRecord::Base; end
16
+ class PostgresqlTimestampWithZone < ActiveRecord::Base; end
17
+
18
+ # self.use_transactional_fixtures = false
19
+
20
+ def self.startup
21
+ execute <<_SQL
22
+ CREATE TABLE postgresql_arrays (
23
+ id SERIAL PRIMARY KEY,
24
+ commission_by_quarter INTEGER[],
25
+ nicknames TEXT[]
26
+ );
27
+ _SQL
28
+
29
+ execute <<_SQL
30
+ CREATE TABLE postgresql_uuids (
31
+ id SERIAL PRIMARY KEY,
32
+ guid uuid,
33
+ compact_guid uuid
34
+ );
35
+ _SQL
36
+
37
+ execute <<_SQL if supports_ranges?
38
+ CREATE TABLE postgresql_ranges (
39
+ id SERIAL PRIMARY KEY,
40
+ date_range daterange,
41
+ num_range numrange,
42
+ ts_range tsrange,
43
+ tstz_range tstzrange,
44
+ int4_range int4range,
45
+ int8_range int8range
46
+ );
47
+ _SQL
48
+
49
+ execute <<_SQL
50
+ CREATE TABLE postgresql_tsvectors (
51
+ id SERIAL PRIMARY KEY,
52
+ text_vector tsvector
53
+ );
54
+ _SQL
55
+
56
+ execute <<_SQL
57
+ CREATE TABLE postgresql_moneys (
58
+ id SERIAL PRIMARY KEY,
59
+ wealth MONEY
60
+ );
61
+ _SQL
62
+
63
+ execute <<_SQL
64
+ CREATE TABLE postgresql_numbers (
65
+ id SERIAL PRIMARY KEY,
66
+ single REAL,
67
+ double DOUBLE PRECISION
68
+ );
69
+ _SQL
70
+
71
+ execute <<_SQL
72
+ CREATE TABLE postgresql_times (
73
+ id SERIAL PRIMARY KEY,
74
+ time_interval INTERVAL,
75
+ scaled_time_interval INTERVAL(6)
76
+ );
77
+ _SQL
78
+
79
+ execute <<_SQL
80
+ CREATE TABLE postgresql_network_addresses (
81
+ id SERIAL PRIMARY KEY,
82
+ cidr_address CIDR default '192.168.1.0/24',
83
+ inet_address INET default '192.168.1.1',
84
+ mac_address MACADDR default 'ff:ff:ff:ff:ff:ff'
85
+ );
86
+ _SQL
87
+
88
+ execute <<_SQL
89
+ CREATE TABLE postgresql_bit_strings (
90
+ id SERIAL PRIMARY KEY,
91
+ bit_string BIT(8),
92
+ bit_string_varying BIT VARYING(8)
93
+ );
94
+ _SQL
95
+
96
+ execute <<_SQL
97
+ CREATE TABLE postgresql_oids (
98
+ id SERIAL PRIMARY KEY,
99
+ obj_id OID
100
+ );
101
+ _SQL
102
+
103
+ execute <<_SQL
104
+ CREATE TABLE postgresql_timestamp_with_zones (
105
+ id SERIAL PRIMARY KEY,
106
+ time TIMESTAMP WITH TIME ZONE
107
+ );
108
+ _SQL
109
+ end
110
+
111
+ def self.shutdown
112
+ %w(postgresql_arrays postgresql_uuids postgresql_ranges postgresql_tsvectors
113
+ postgresql_moneys postgresql_numbers postgresql_times postgresql_network_addresses
114
+ postgresql_bit_strings postgresql_oids postgresql_timestamp_with_zones).each do |table_name|
115
+ execute "DROP TABLE IF EXISTS #{table_name}"
116
+ end
117
+ end
118
+
119
+ def self.execute sql
120
+ connection.execute sql
121
+ end
122
+
123
+ def self.connection
124
+ ActiveRecord::Base.connection
125
+ end
126
+
127
+ def self.supports_ranges?
128
+ if connection.respond_to?(:supports_ranges?)
129
+ !! connection.supports_ranges?
130
+ else
131
+ nil
132
+ end
133
+ end
134
+
135
+ def supports_ranges?; self.class.supports_ranges?; end
136
+ private :supports_ranges?
137
+
138
+ def setup
139
+ @connection = ActiveRecord::Base.connection
140
+ @connection.execute("set lc_monetary = 'C'")
141
+
142
+ @connection.execute("INSERT INTO postgresql_arrays (id, commission_by_quarter, nicknames) VALUES (1, '{35000,21000,18000,17000}', '{foo,bar,baz}')")
143
+ @first_array = PostgresqlArray.find(1) rescue nil
144
+
145
+ @connection.execute <<_SQL if supports_ranges?
146
+ INSERT INTO postgresql_ranges (
147
+ date_range,
148
+ num_range,
149
+ ts_range,
150
+ tstz_range,
151
+ int4_range,
152
+ int8_range
153
+ ) VALUES (
154
+ '[''2012-01-02'', ''2012-01-04'']',
155
+ '[0.1, 0.2]',
156
+ '[''2010-01-01 14:30'', ''2011-01-01 14:30'']',
157
+ '[''2010-01-01 14:30:00+05'', ''2011-01-01 14:30:00-03'']',
158
+ '[1, 10]',
159
+ '[10, 100]'
160
+ )
161
+ _SQL
162
+
163
+ @connection.execute <<_SQL if supports_ranges?
164
+ INSERT INTO postgresql_ranges (
165
+ date_range,
166
+ num_range,
167
+ ts_range,
168
+ tstz_range,
169
+ int4_range,
170
+ int8_range
171
+ ) VALUES (
172
+ '(''2012-01-02'', ''2012-01-04'')',
173
+ '[0.1, 0.2)',
174
+ '[''2010-01-01 14:30'', ''2011-01-01 14:30'')',
175
+ '[''2010-01-01 14:30:00+05'', ''2011-01-01 14:30:00-03'')',
176
+ '(1, 10)',
177
+ '(10, 100)'
178
+ )
179
+ _SQL
180
+
181
+ @connection.execute <<_SQL if supports_ranges?
182
+ INSERT INTO postgresql_ranges (
183
+ date_range,
184
+ num_range,
185
+ ts_range,
186
+ tstz_range,
187
+ int4_range,
188
+ int8_range
189
+ ) VALUES (
190
+ '(''2012-01-02'',]',
191
+ '[0.1,]',
192
+ '[''2010-01-01 14:30'',]',
193
+ '[''2010-01-01 14:30:00+05'',]',
194
+ '(1,]',
195
+ '(10,]'
196
+ )
197
+ _SQL
198
+
199
+ @connection.execute <<_SQL if supports_ranges?
200
+ INSERT INTO postgresql_ranges (
201
+ date_range,
202
+ num_range,
203
+ ts_range,
204
+ tstz_range,
205
+ int4_range,
206
+ int8_range
207
+ ) VALUES (
208
+ '[,]',
209
+ '[,]',
210
+ '[,]',
211
+ '[,]',
212
+ '[,]',
213
+ '[,]'
214
+ )
215
+ _SQL
216
+
217
+ @connection.execute <<_SQL if supports_ranges?
218
+ INSERT INTO postgresql_ranges (
219
+ date_range,
220
+ num_range,
221
+ ts_range,
222
+ tstz_range,
223
+ int4_range,
224
+ int8_range
225
+ ) VALUES (
226
+ '(''2012-01-02'', ''2012-01-02'')',
227
+ '(0.1, 0.1)',
228
+ '(''2010-01-01 14:30'', ''2010-01-01 14:30'')',
229
+ '(''2010-01-01 14:30:00+05'', ''2010-01-01 06:30:00-03'')',
230
+ '(1, 1)',
231
+ '(10, 10)'
232
+ )
233
+ _SQL
234
+
235
+ if supports_ranges?
236
+ @first_range = PostgresqlRange.find(1)
237
+ @second_range = PostgresqlRange.find(2)
238
+ @third_range = PostgresqlRange.find(3)
239
+ @fourth_range = PostgresqlRange.find(4)
240
+ @empty_range = PostgresqlRange.find(5)
241
+ end
242
+
243
+ @connection.execute("INSERT INTO postgresql_tsvectors (id, text_vector) VALUES (1, ' ''text'' ''vector'' ')")
244
+
245
+ @first_tsvector = PostgresqlTsvector.find(1)
246
+
247
+ @connection.execute("INSERT INTO postgresql_moneys (id, wealth) VALUES (1, '567.89'::money)")
248
+ @connection.execute("INSERT INTO postgresql_moneys (id, wealth) VALUES (2, '-567.89'::money)")
249
+ @first_money = PostgresqlMoney.find(1)
250
+ @second_money = PostgresqlMoney.find(2)
251
+
252
+ @connection.execute("INSERT INTO postgresql_numbers (id, single, double) VALUES (1, 123.456, 123456.789)")
253
+ @first_number = PostgresqlNumber.find(1)
254
+
255
+ @connection.execute("INSERT INTO postgresql_times (id, time_interval, scaled_time_interval) VALUES (1, '1 year 2 days ago', '3 weeks ago')")
256
+ @first_time = PostgresqlTime.find(1)
257
+
258
+ @connection.execute("INSERT INTO postgresql_network_addresses (id, cidr_address, inet_address, mac_address) VALUES(1, '192.168.0/24', '172.16.1.254/32', '01:23:45:67:89:0a')")
259
+ @first_network_address = PostgresqlNetworkAddress.find(1)
260
+
261
+ @connection.execute("INSERT INTO postgresql_bit_strings (id, bit_string, bit_string_varying) VALUES (1, B'00010101', X'15')")
262
+ @first_bit_string = PostgresqlBitString.find(1)
263
+
264
+ @connection.execute("INSERT INTO postgresql_oids (id, obj_id) VALUES (1, 1234)")
265
+ @first_oid = PostgresqlOid.find(1)
266
+
267
+ @connection.execute("INSERT INTO postgresql_timestamp_with_zones (id, time) VALUES (1, '2010-01-01 10:00:00-1')")
268
+
269
+ @connection.execute("INSERT INTO postgresql_uuids (id, guid, compact_guid) VALUES(1, 'd96c3da0-96c1-012f-1316-64ce8f32c6d8', 'f06c715096c1012f131764ce8f32c6d8')")
270
+ @first_uuid = PostgresqlUUID.find(1)
271
+ end
272
+
273
+ def teardown
274
+ [PostgresqlArray, PostgresqlTsvector, PostgresqlMoney, PostgresqlNumber, PostgresqlTime, PostgresqlNetworkAddress,
275
+ PostgresqlBitString, PostgresqlOid, PostgresqlTimestampWithZone, PostgresqlUUID].each(&:delete_all)
276
+ end
277
+
278
+ def test_data_type_of_array_types
279
+ omit_unless @first_array
280
+ assert_equal :integer, @first_array.column_for_attribute(:commission_by_quarter).type
281
+ assert_equal :text, @first_array.column_for_attribute(:nicknames).type
282
+ end
283
+
284
+ def test_data_type_of_range_types
285
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
286
+ assert_equal :daterange, @first_range.column_for_attribute(:date_range).type
287
+ assert_equal :numrange, @first_range.column_for_attribute(:num_range).type
288
+ assert_equal :tsrange, @first_range.column_for_attribute(:ts_range).type
289
+ assert_equal :tstzrange, @first_range.column_for_attribute(:tstz_range).type
290
+ assert_equal :int4range, @first_range.column_for_attribute(:int4_range).type
291
+ assert_equal :int8range, @first_range.column_for_attribute(:int8_range).type
292
+ end if ar_version('4.0')
293
+
294
+ def test_data_type_of_tsvector_types
295
+ assert_equal :tsvector, @first_tsvector.column_for_attribute(:text_vector).type
296
+ end if ar_version('4.0')
297
+
298
+ def test_data_type_of_money_types
299
+ assert_equal :decimal, @first_money.column_for_attribute(:wealth).type
300
+ end
301
+
302
+ def test_data_type_of_number_types
303
+ assert_equal :float, @first_number.column_for_attribute(:single).type
304
+ assert_equal :float, @first_number.column_for_attribute(:double).type
305
+ end
306
+
307
+ def test_data_type_of_time_types
308
+ assert_equal :string, @first_time.column_for_attribute(:time_interval).type
309
+ assert_equal :string, @first_time.column_for_attribute(:scaled_time_interval).type if ar_version('4.0')
310
+ end
311
+
312
+ def test_data_type_of_network_address_types
313
+ assert_equal :cidr, @first_network_address.column_for_attribute(:cidr_address).type
314
+ assert_equal :inet, @first_network_address.column_for_attribute(:inet_address).type
315
+ assert_equal :macaddr, @first_network_address.column_for_attribute(:mac_address).type
316
+ end if ar_version('4.0')
317
+
318
+ def test_data_type_of_bit_string_types
319
+ assert_equal :string, @first_bit_string.column_for_attribute(:bit_string).type
320
+ assert_equal :string, @first_bit_string.column_for_attribute(:bit_string_varying).type
321
+ end
322
+
323
+ def test_data_type_of_oid_types
324
+ assert_equal :integer, @first_oid.column_for_attribute(:obj_id).type
325
+ end
326
+
327
+ def test_data_type_of_uuid_types
328
+ assert_equal :uuid, @first_uuid.column_for_attribute(:guid).type
329
+ end if ar_version('4.0')
330
+
331
+ def test_array_values
332
+ omit_unless @first_array
333
+ assert_equal [35000,21000,18000,17000], @first_array.commission_by_quarter
334
+ assert_equal ['foo','bar','baz'], @first_array.nicknames
335
+ end if ar_version('4.0')
336
+
337
+ def test_tsvector_values
338
+ assert_equal "'text' 'vector'", @first_tsvector.text_vector
339
+ end
340
+
341
+ def test_int4range_values
342
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
343
+ assert_equal 1...11, @first_range.int4_range
344
+ assert_equal 2...10, @second_range.int4_range
345
+ assert_equal 2...Float::INFINITY, @third_range.int4_range
346
+ assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.int4_range)
347
+ assert_equal nil, @empty_range.int4_range
348
+ end if ar_version('4.0')
349
+
350
+ def test_int8range_values
351
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
352
+ assert_equal 10...101, @first_range.int8_range
353
+ assert_equal 11...100, @second_range.int8_range
354
+ assert_equal 11...Float::INFINITY, @third_range.int8_range
355
+ assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.int8_range)
356
+ assert_equal nil, @empty_range.int8_range
357
+ end if ar_version('4.0')
358
+
359
+ def test_daterange_values
360
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
361
+ assert_equal Date.new(2012, 1, 2)...Date.new(2012, 1, 5), @first_range.date_range
362
+ assert_equal Date.new(2012, 1, 3)...Date.new(2012, 1, 4), @second_range.date_range
363
+ assert_equal Date.new(2012, 1, 3)...Float::INFINITY, @third_range.date_range
364
+ assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.date_range)
365
+ assert_equal nil, @empty_range.date_range
366
+ end if ar_version('4.0')
367
+
368
+ def test_numrange_values
369
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
370
+ assert_equal BigDecimal.new('0.1')..BigDecimal.new('0.2'), @first_range.num_range
371
+ assert_equal BigDecimal.new('0.1')...BigDecimal.new('0.2'), @second_range.num_range
372
+ assert_equal BigDecimal.new('0.1')...BigDecimal.new('Infinity'), @third_range.num_range
373
+ assert_equal BigDecimal.new('-Infinity')...BigDecimal.new('Infinity'), @fourth_range.num_range
374
+ assert_equal nil, @empty_range.num_range
375
+ end if ar_version('4.0')
376
+
377
+ def test_tsrange_values
378
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
379
+ tz = ::ActiveRecord::Base.default_timezone
380
+ assert_equal Time.send(tz, 2010, 1, 1, 14, 30, 0)..Time.send(tz, 2011, 1, 1, 14, 30, 0), @first_range.ts_range
381
+ assert_equal Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 1, 1, 14, 30, 0), @second_range.ts_range
382
+ assert_equal Time.send(tz, 2010, 1, 1, 14, 30, 0)...Float::INFINITY, @third_range.ts_range
383
+ assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.ts_range)
384
+ assert_equal nil, @empty_range.ts_range
385
+ end if ar_version('4.0')
386
+
387
+ def test_tstzrange_values
388
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
389
+ assert_equal Time.parse('2010-01-01 09:30:00 UTC')..Time.parse('2011-01-01 17:30:00 UTC'), @first_range.tstz_range
390
+ assert_equal Time.parse('2010-01-01 09:30:00 UTC')...Time.parse('2011-01-01 17:30:00 UTC'), @second_range.tstz_range
391
+ assert_equal Time.parse('2010-01-01 09:30:00 UTC')...Float::INFINITY, @third_range.tstz_range
392
+ assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.tstz_range)
393
+ assert_equal nil, @empty_range.tstz_range
394
+ end if ar_version('4.0')
395
+
396
+ def test_money_values
397
+ assert_equal 567.89, @first_money.wealth
398
+ assert_equal -567.89, @second_money.wealth
399
+ end
400
+
401
+ def test_create_tstzrange
402
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
403
+ tstzrange = Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2011-02-02 14:30:00 CDT')
404
+ range = PostgresqlRange.new(:tstz_range => tstzrange)
405
+ assert range.save
406
+ assert range.reload
407
+ assert_equal range.tstz_range, tstzrange
408
+ assert_equal range.tstz_range, Time.parse('2010-01-01 13:30:00 UTC')...Time.parse('2011-02-02 19:30:00 UTC')
409
+ end if ar_version('4.0')
410
+
411
+ def test_update_tstzrange
412
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
413
+ new_tstzrange = Time.parse('2010-01-01 14:30:00 CDT')...Time.parse('2011-02-02 14:30:00 CET')
414
+ assert @first_range.tstz_range = new_tstzrange
415
+ assert @first_range.save
416
+ assert @first_range.reload
417
+ assert_equal new_tstzrange, @first_range.tstz_range
418
+ assert @first_range.tstz_range = Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2010-01-01 13:30:00 +0000')
419
+ assert @first_range.save
420
+ assert @first_range.reload
421
+ assert_equal @first_range.tstz_range, nil
422
+ end if ar_version('4.0')
423
+
424
+ def test_create_tsrange
425
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
426
+ tz = ::ActiveRecord::Base.default_timezone
427
+ tsrange = Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 2, 2, 14, 30, 0)
428
+ range = PostgresqlRange.new(:ts_range => tsrange)
429
+ assert range.save
430
+ assert range.reload
431
+ assert_equal range.ts_range, tsrange
432
+ end if ar_version('4.0')
433
+
434
+ def test_update_tsrange
435
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
436
+ tz = ::ActiveRecord::Base.default_timezone
437
+ new_tsrange = Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 2, 2, 14, 30, 0)
438
+ assert @first_range.ts_range = new_tsrange
439
+ assert @first_range.save
440
+ assert @first_range.reload
441
+ assert_equal new_tsrange, @first_range.ts_range
442
+ assert @first_range.ts_range = Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2010, 1, 1, 14, 30, 0)
443
+ assert @first_range.save
444
+ assert @first_range.reload
445
+ assert_nil @first_range.ts_range
446
+ end if ar_version('4.0')
447
+
448
+ def test_create_numrange
449
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
450
+ numrange = BigDecimal.new('0.5')...BigDecimal.new('1')
451
+ range = PostgresqlRange.new(:num_range => numrange)
452
+ assert range.save
453
+ assert range.reload
454
+ assert_equal range.num_range, numrange
455
+ end if ar_version('4.0')
456
+
457
+ def test_update_numrange
458
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
459
+ new_numrange = BigDecimal.new('0.5')...BigDecimal.new('1')
460
+ assert @first_range.num_range = new_numrange
461
+ assert @first_range.save
462
+ assert @first_range.reload
463
+ assert_equal new_numrange, @first_range.num_range
464
+ assert @first_range.num_range = BigDecimal.new('0.5')...BigDecimal.new('0.5')
465
+ assert @first_range.save
466
+ assert @first_range.reload
467
+ assert_nil @first_range.num_range
468
+ end if ar_version('4.0')
469
+
470
+ def test_create_daterange
471
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
472
+ daterange = Range.new(Date.new(2012, 1, 1), Date.new(2013, 1, 1), true)
473
+ range = PostgresqlRange.new(:date_range => daterange)
474
+ assert range.save
475
+ assert range.reload
476
+ assert_equal daterange, range.date_range
477
+ end if ar_version('4.0')
478
+
479
+ def test_update_daterange
480
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
481
+ new_daterange = Date.new(2012, 2, 3)...Date.new(2012, 2, 10)
482
+ assert @first_range.date_range = new_daterange
483
+ assert @first_range.save
484
+ assert @first_range.reload
485
+ assert_equal new_daterange, @first_range.date_range
486
+ assert @first_range.date_range = Date.new(2012, 2, 3)...Date.new(2012, 2, 3)
487
+ assert @first_range.save
488
+ assert @first_range.reload
489
+ assert_nil @first_range.date_range
490
+ end if ar_version('4.0')
491
+
492
+ def test_create_int4range
493
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
494
+ int4range = Range.new(3, 50, true)
495
+ range = PostgresqlRange.new(:int4_range => int4range)
496
+ assert range.save
497
+ assert range.reload
498
+ assert_equal range.int4_range, int4range
499
+ end if ar_version('4.0')
500
+
501
+ def test_update_int4range
502
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
503
+ new_int4range = 6...10
504
+ assert @first_range.int4_range = new_int4range
505
+ assert @first_range.save
506
+ assert @first_range.reload
507
+ assert_equal new_int4range, @first_range.int4_range
508
+ assert @first_range.int4_range = 3...3
509
+ assert @first_range.save
510
+ assert @first_range.reload
511
+ assert_nil @first_range.int4_range
512
+ end if ar_version('4.0')
513
+
514
+ def test_create_int8range
515
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
516
+ int8range = Range.new(30, 50, true)
517
+ range = PostgresqlRange.new(:int8_range => int8range)
518
+ assert range.save
519
+ assert range.reload
520
+ assert_equal int8range, range.int8_range
521
+ end if ar_version('4.0')
522
+
523
+ def test_update_int8range
524
+ skip "PostgreSQL 9.2 required for range datatypes" unless supports_ranges?
525
+ new_int8range = 60000...10000000
526
+ assert @first_range.int8_range = new_int8range
527
+ assert @first_range.save
528
+ assert @first_range.reload
529
+ assert_equal new_int8range, @first_range.int8_range
530
+ assert @first_range.int8_range = 39999...39999
531
+ assert @first_range.save
532
+ assert @first_range.reload
533
+ assert_nil @first_range.int8_range
534
+ end if ar_version('4.0')
535
+
536
+ def test_update_tsvector
537
+ new_text_vector = "'new' 'text' 'vector'"
538
+ assert @first_tsvector.text_vector = new_text_vector
539
+ assert @first_tsvector.save
540
+ assert @first_tsvector.reload
541
+ assert @first_tsvector.text_vector = new_text_vector
542
+ assert @first_tsvector.save
543
+ assert @first_tsvector.reload
544
+ assert_equal new_text_vector, @first_tsvector.text_vector
545
+ end if ar_version('4.0')
546
+
547
+ def test_number_values
548
+ # assert_equal 123.456, @first_number.single
549
+ # NOTE: JDBC API gets us: ~ 123.456
550
+ assert_equal 123.456, ( @first_number.single * 1000 ).to_i / 1000.0
551
+ assert_equal 123456.789, @first_number.double
552
+ end
553
+
554
+ def test_time_values
555
+ # omit_unless ar_version('4.0')
556
+ assert_equal '-1 years -2 days', @first_time.time_interval
557
+ assert_equal '-21 days', @first_time.scaled_time_interval if ar_version('4.0')
558
+ end
559
+
560
+ def test_network_address_values_ipaddr
561
+ cidr_address = IPAddr.new '192.168.0.0/24'
562
+ inet_address = IPAddr.new '172.16.1.254'
563
+
564
+ assert_equal cidr_address, @first_network_address.cidr_address
565
+ assert_equal inet_address, @first_network_address.inet_address
566
+ assert_equal '01:23:45:67:89:0a', @first_network_address.mac_address
567
+ end if ar_version('4.0')
568
+
569
+ def test_uuid_values
570
+ assert_equal 'd96c3da0-96c1-012f-1316-64ce8f32c6d8', @first_uuid.guid
571
+ assert_equal 'f06c7150-96c1-012f-1317-64ce8f32c6d8', @first_uuid.compact_guid
572
+ end
573
+
574
+ def test_bit_string_values
575
+ assert_equal '00010101', @first_bit_string.bit_string
576
+ assert_equal '00010101', @first_bit_string.bit_string_varying
577
+ end
578
+
579
+ def test_oid_values
580
+ assert_equal 1234, @first_oid.obj_id
581
+ end
582
+
583
+ def test_update_integer_array
584
+ omit_unless @first_array
585
+ new_value = [32800,95000,29350,17000]
586
+ @first_array.commission_by_quarter = new_value
587
+ @first_array.save!
588
+ assert_equal new_value, @first_array.reload.commission_by_quarter
589
+ @first_array.commission_by_quarter = new_value
590
+ assert @first_array.save
591
+ assert_equal new_value, @first_array.reload.commission_by_quarter
592
+ end if ar_version('4.0')
593
+
594
+ def test_update_text_array
595
+ omit_unless @first_array
596
+ new_value = ['robby','robert','rob','robbie']
597
+ @first_array.nicknames = new_value
598
+ @first_array.save!
599
+ @first_array.reload
600
+ assert_equal new_value, @first_array.nicknames
601
+ @first_array.nicknames = new_value
602
+ @first_array.save!
603
+ @first_array.reload
604
+ assert_equal new_value, @first_array.nicknames
605
+ end if ar_version('4.0')
606
+
607
+ def test_update_money
608
+ new_value = BigDecimal.new('123.45')
609
+ @first_money.wealth = new_value
610
+ @first_money.save!
611
+ @first_money.reload
612
+ assert_equal new_value, @first_money.wealth
613
+ end
614
+
615
+ def test_update_number
616
+ new_single = 789.012
617
+ new_double = 789012.345
618
+ @first_number.single = new_single
619
+ @first_number.double = new_double
620
+ @first_number.save!
621
+ @first_number.reload
622
+ # assert_equal new_single, @first_number.single
623
+ # NOTE: JDBC API gets us: ~ 789.012 (due double precision)
624
+ assert_equal new_single, ( @first_number.single * 1000 ).to_i / 1000.0
625
+ assert_equal new_double, @first_number.double
626
+ end
627
+
628
+ def test_update_time
629
+ @first_time.time_interval = '2 years 3 minutes'
630
+ @first_time.save!
631
+ @first_time.reload
632
+ assert_equal '2 years 00:03:00', @first_time.time_interval
633
+ end
634
+
635
+ def test_update_network_address
636
+ new_inet_address = '10.1.2.3/32'
637
+ new_cidr_address = '10.0.0.0/8'
638
+ new_mac_address = 'bc:de:f0:12:34:56'
639
+ @first_network_address.cidr_address = new_cidr_address
640
+ @first_network_address.inet_address = new_inet_address
641
+ @first_network_address.mac_address = new_mac_address
642
+ @first_network_address.save!
643
+ @first_network_address.reload
644
+ assert_equal new_cidr_address, @first_network_address.cidr_address
645
+ assert_equal new_inet_address, @first_network_address.inet_address
646
+ assert_equal new_mac_address, @first_network_address.mac_address
647
+ end if ar_version('4.0')
648
+
649
+ def test_update_bit_string
650
+ new_bit_string = '11111111'
651
+ new_bit_string_varying = '11111110'
652
+ @first_bit_string.bit_string = new_bit_string
653
+ @first_bit_string.bit_string_varying = new_bit_string_varying
654
+ @first_bit_string.save!
655
+ @first_bit_string.reload
656
+ assert_equal new_bit_string, @first_bit_string.bit_string
657
+ assert_equal new_bit_string_varying, @first_bit_string.bit_string_varying
658
+ end
659
+
660
+ def test_update_oid
661
+ new_value = 567890
662
+ @first_oid.obj_id = new_value
663
+ @first_oid.save!
664
+ assert_equal new_value, @first_oid.reload.obj_id
665
+ end
666
+
667
+ # def test_timestamp_with_zone_values_with_rails_time_zone_support
668
+ # old_tz = ActiveRecord::Base.time_zone_aware_attributes
669
+ # old_default_tz = ActiveRecord::Base.default_timezone
670
+ #
671
+ # ActiveRecord::Base.time_zone_aware_attributes = true
672
+ # ActiveRecord::Base.default_timezone = :utc
673
+ #
674
+ # @connection.reconnect!
675
+ #
676
+ # @first_timestamp_with_zone = PostgresqlTimestampWithZone.find(1)
677
+ # assert_equal Time.utc(2010,1,1, 11,0,0), @first_timestamp_with_zone.time
678
+ # assert_instance_of Time, @first_timestamp_with_zone.time
679
+ # ensure
680
+ # ActiveRecord::Base.default_timezone = old_default_tz
681
+ # ActiveRecord::Base.time_zone_aware_attributes = old_tz
682
+ # @connection.reconnect!
683
+ # end
684
+ #
685
+ # def test_timestamp_with_zone_values_without_rails_time_zone_support
686
+ # old_tz = ActiveRecord::Base.time_zone_aware_attributes
687
+ # old_default_tz = ActiveRecord::Base.default_timezone
688
+ #
689
+ # ActiveRecord::Base.time_zone_aware_attributes = false
690
+ # ActiveRecord::Base.default_timezone = :local
691
+ #
692
+ # @connection.reconnect!
693
+ #
694
+ # @first_timestamp_with_zone = PostgresqlTimestampWithZone.find(1)
695
+ # assert_equal Time.utc(2010,1,1, 11,0,0), @first_timestamp_with_zone.time
696
+ # assert_instance_of Time, @first_timestamp_with_zone.time
697
+ # ensure
698
+ # ActiveRecord::Base.default_timezone = old_default_tz
699
+ # ActiveRecord::Base.time_zone_aware_attributes = old_tz
700
+ # @connection.reconnect!
701
+ # end
702
+
703
+ end # if Test::Unit::TestCase.ar_version('4.0')