activerecord-jdbc-adapter-onsite 1.2.2

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 (228) hide show
  1. data/.gitignore +22 -0
  2. data/.travis.yml +14 -0
  3. data/Appraisals +16 -0
  4. data/Gemfile +11 -0
  5. data/Gemfile.lock +45 -0
  6. data/History.txt +488 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.rdoc +214 -0
  9. data/Rakefile +62 -0
  10. data/activerecord-jdbc-adapter.gemspec +23 -0
  11. data/bench/bench_attributes.rb +13 -0
  12. data/bench/bench_attributes_new.rb +14 -0
  13. data/bench/bench_create.rb +12 -0
  14. data/bench/bench_find_all.rb +12 -0
  15. data/bench/bench_find_all_mt.rb +25 -0
  16. data/bench/bench_model.rb +85 -0
  17. data/bench/bench_new.rb +12 -0
  18. data/bench/bench_new_valid.rb +12 -0
  19. data/bench/bench_valid.rb +13 -0
  20. data/gemfiles/rails23.gemfile +10 -0
  21. data/gemfiles/rails23.gemfile.lock +38 -0
  22. data/gemfiles/rails30.gemfile +9 -0
  23. data/gemfiles/rails30.gemfile.lock +33 -0
  24. data/gemfiles/rails31.gemfile +9 -0
  25. data/gemfiles/rails31.gemfile.lock +35 -0
  26. data/gemfiles/rails32.gemfile +9 -0
  27. data/gemfiles/rails32.gemfile.lock +35 -0
  28. data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
  29. data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
  30. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
  31. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
  32. data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
  33. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  34. data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
  35. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
  36. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
  37. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  38. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
  39. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
  40. data/lib/activerecord-jdbc-adapter.rb +8 -0
  41. data/lib/arel/engines/sql/compilers/db2_compiler.rb +9 -0
  42. data/lib/arel/engines/sql/compilers/derby_compiler.rb +6 -0
  43. data/lib/arel/engines/sql/compilers/h2_compiler.rb +6 -0
  44. data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +15 -0
  45. data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +6 -0
  46. data/lib/arel/engines/sql/compilers/mssql_compiler.rb +46 -0
  47. data/lib/arel/visitors/compat.rb +13 -0
  48. data/lib/arel/visitors/db2.rb +17 -0
  49. data/lib/arel/visitors/derby.rb +32 -0
  50. data/lib/arel/visitors/firebird.rb +24 -0
  51. data/lib/arel/visitors/hsqldb.rb +26 -0
  52. data/lib/arel/visitors/sql_server.rb +46 -0
  53. data/lib/arjdbc.rb +24 -0
  54. data/lib/arjdbc/db2.rb +2 -0
  55. data/lib/arjdbc/db2/adapter.rb +541 -0
  56. data/lib/arjdbc/derby.rb +7 -0
  57. data/lib/arjdbc/derby/adapter.rb +358 -0
  58. data/lib/arjdbc/derby/connection_methods.rb +19 -0
  59. data/lib/arjdbc/discover.rb +92 -0
  60. data/lib/arjdbc/firebird.rb +2 -0
  61. data/lib/arjdbc/firebird/adapter.rb +140 -0
  62. data/lib/arjdbc/h2.rb +4 -0
  63. data/lib/arjdbc/h2/adapter.rb +54 -0
  64. data/lib/arjdbc/h2/connection_methods.rb +13 -0
  65. data/lib/arjdbc/hsqldb.rb +4 -0
  66. data/lib/arjdbc/hsqldb/adapter.rb +184 -0
  67. data/lib/arjdbc/hsqldb/connection_methods.rb +15 -0
  68. data/lib/arjdbc/informix.rb +3 -0
  69. data/lib/arjdbc/informix/adapter.rb +142 -0
  70. data/lib/arjdbc/informix/connection_methods.rb +11 -0
  71. data/lib/arjdbc/jdbc.rb +2 -0
  72. data/lib/arjdbc/jdbc/adapter.rb +356 -0
  73. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  74. data/lib/arjdbc/jdbc/base_ext.rb +15 -0
  75. data/lib/arjdbc/jdbc/callbacks.rb +44 -0
  76. data/lib/arjdbc/jdbc/column.rb +47 -0
  77. data/lib/arjdbc/jdbc/compatibility.rb +51 -0
  78. data/lib/arjdbc/jdbc/connection.rb +134 -0
  79. data/lib/arjdbc/jdbc/connection_methods.rb +16 -0
  80. data/lib/arjdbc/jdbc/core_ext.rb +24 -0
  81. data/lib/arjdbc/jdbc/discover.rb +18 -0
  82. data/lib/arjdbc/jdbc/driver.rb +35 -0
  83. data/lib/arjdbc/jdbc/extension.rb +47 -0
  84. data/lib/arjdbc/jdbc/java.rb +14 -0
  85. data/lib/arjdbc/jdbc/jdbc.rake +131 -0
  86. data/lib/arjdbc/jdbc/missing_functionality_helper.rb +88 -0
  87. data/lib/arjdbc/jdbc/quoted_primary_key.rb +28 -0
  88. data/lib/arjdbc/jdbc/railtie.rb +9 -0
  89. data/lib/arjdbc/jdbc/rake_tasks.rb +10 -0
  90. data/lib/arjdbc/jdbc/require_driver.rb +16 -0
  91. data/lib/arjdbc/jdbc/type_converter.rb +126 -0
  92. data/lib/arjdbc/mimer.rb +2 -0
  93. data/lib/arjdbc/mimer/adapter.rb +142 -0
  94. data/lib/arjdbc/mssql.rb +4 -0
  95. data/lib/arjdbc/mssql/adapter.rb +477 -0
  96. data/lib/arjdbc/mssql/connection_methods.rb +31 -0
  97. data/lib/arjdbc/mssql/limit_helpers.rb +101 -0
  98. data/lib/arjdbc/mssql/lock_helpers.rb +72 -0
  99. data/lib/arjdbc/mssql/tsql_helper.rb +61 -0
  100. data/lib/arjdbc/mysql.rb +4 -0
  101. data/lib/arjdbc/mysql/adapter.rb +505 -0
  102. data/lib/arjdbc/mysql/connection_methods.rb +28 -0
  103. data/lib/arjdbc/oracle.rb +3 -0
  104. data/lib/arjdbc/oracle/adapter.rb +432 -0
  105. data/lib/arjdbc/oracle/connection_methods.rb +12 -0
  106. data/lib/arjdbc/postgresql.rb +4 -0
  107. data/lib/arjdbc/postgresql/adapter.rb +861 -0
  108. data/lib/arjdbc/postgresql/connection_methods.rb +23 -0
  109. data/lib/arjdbc/sqlite3.rb +4 -0
  110. data/lib/arjdbc/sqlite3/adapter.rb +389 -0
  111. data/lib/arjdbc/sqlite3/connection_methods.rb +35 -0
  112. data/lib/arjdbc/sybase.rb +2 -0
  113. data/lib/arjdbc/sybase/adapter.rb +46 -0
  114. data/lib/arjdbc/version.rb +8 -0
  115. data/lib/generators/jdbc/USAGE +10 -0
  116. data/lib/generators/jdbc/jdbc_generator.rb +9 -0
  117. data/lib/jdbc_adapter.rb +2 -0
  118. data/lib/jdbc_adapter/rake_tasks.rb +3 -0
  119. data/lib/jdbc_adapter/version.rb +3 -0
  120. data/lib/pg.rb +26 -0
  121. data/pom.xml +57 -0
  122. data/rails_generators/jdbc_generator.rb +15 -0
  123. data/rails_generators/templates/config/initializers/jdbc.rb +7 -0
  124. data/rails_generators/templates/lib/tasks/jdbc.rake +8 -0
  125. data/rakelib/bundler_ext.rb +11 -0
  126. data/rakelib/compile.rake +23 -0
  127. data/rakelib/db.rake +39 -0
  128. data/rakelib/rails.rake +41 -0
  129. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +69 -0
  130. data/src/java/arjdbc/derby/DerbyModule.java +324 -0
  131. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +70 -0
  132. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +74 -0
  133. data/src/java/arjdbc/jdbc/AdapterJavaService.java +68 -0
  134. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +36 -0
  135. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1346 -0
  136. data/src/java/arjdbc/jdbc/SQLBlock.java +48 -0
  137. data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +127 -0
  138. data/src/java/arjdbc/mysql/MySQLModule.java +134 -0
  139. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +161 -0
  140. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +85 -0
  141. data/src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java +82 -0
  142. data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +126 -0
  143. data/test/abstract_db_create.rb +135 -0
  144. data/test/activerecord/connection_adapters/type_conversion_test.rb +31 -0
  145. data/test/activerecord/connections/native_jdbc_mysql/connection.rb +25 -0
  146. data/test/activerecord/jall.sh +7 -0
  147. data/test/activerecord/jtest.sh +3 -0
  148. data/test/db/db2.rb +11 -0
  149. data/test/db/derby.rb +12 -0
  150. data/test/db/h2.rb +11 -0
  151. data/test/db/hsqldb.rb +13 -0
  152. data/test/db/informix.rb +11 -0
  153. data/test/db/jdbc.rb +12 -0
  154. data/test/db/jndi_config.rb +40 -0
  155. data/test/db/logger.rb +3 -0
  156. data/test/db/mssql.rb +9 -0
  157. data/test/db/mysql.rb +10 -0
  158. data/test/db/oracle.rb +34 -0
  159. data/test/db/postgres.rb +18 -0
  160. data/test/db/sqlite3.rb +11 -0
  161. data/test/db2_reset_column_information_test.rb +8 -0
  162. data/test/db2_simple_test.rb +66 -0
  163. data/test/derby_migration_test.rb +68 -0
  164. data/test/derby_multibyte_test.rb +12 -0
  165. data/test/derby_reset_column_information_test.rb +8 -0
  166. data/test/derby_row_locking_test.rb +9 -0
  167. data/test/derby_simple_test.rb +139 -0
  168. data/test/generic_jdbc_connection_test.rb +29 -0
  169. data/test/h2_change_column_test.rb +68 -0
  170. data/test/h2_simple_test.rb +41 -0
  171. data/test/has_many_through.rb +79 -0
  172. data/test/helper.rb +108 -0
  173. data/test/hsqldb_simple_test.rb +6 -0
  174. data/test/informix_simple_test.rb +48 -0
  175. data/test/jdbc_common.rb +28 -0
  176. data/test/jndi_callbacks_test.rb +36 -0
  177. data/test/jndi_test.rb +25 -0
  178. data/test/manualTestDatabase.rb +191 -0
  179. data/test/models/add_not_null_column_to_table.rb +9 -0
  180. data/test/models/auto_id.rb +15 -0
  181. data/test/models/custom_pk_name.rb +14 -0
  182. data/test/models/data_types.rb +30 -0
  183. data/test/models/entry.rb +40 -0
  184. data/test/models/mixed_case.rb +22 -0
  185. data/test/models/reserved_word.rb +15 -0
  186. data/test/models/string_id.rb +17 -0
  187. data/test/models/thing.rb +16 -0
  188. data/test/models/validates_uniqueness_of_string.rb +19 -0
  189. data/test/mssql_db_create_test.rb +26 -0
  190. data/test/mssql_identity_insert_test.rb +19 -0
  191. data/test/mssql_ignore_system_views_test.rb +27 -0
  192. data/test/mssql_legacy_types_test.rb +58 -0
  193. data/test/mssql_limit_offset_test.rb +136 -0
  194. data/test/mssql_multibyte_test.rb +18 -0
  195. data/test/mssql_null_test.rb +14 -0
  196. data/test/mssql_reset_column_information_test.rb +8 -0
  197. data/test/mssql_row_locking_sql_test.rb +159 -0
  198. data/test/mssql_row_locking_test.rb +9 -0
  199. data/test/mssql_simple_test.rb +55 -0
  200. data/test/mysql_db_create_test.rb +27 -0
  201. data/test/mysql_index_length_test.rb +58 -0
  202. data/test/mysql_info_test.rb +123 -0
  203. data/test/mysql_multibyte_test.rb +10 -0
  204. data/test/mysql_nonstandard_primary_key_test.rb +42 -0
  205. data/test/mysql_reset_column_information_test.rb +8 -0
  206. data/test/mysql_simple_test.rb +125 -0
  207. data/test/oracle_reset_column_information_test.rb +8 -0
  208. data/test/oracle_simple_test.rb +18 -0
  209. data/test/oracle_specific_test.rb +83 -0
  210. data/test/postgres_db_create_test.rb +32 -0
  211. data/test/postgres_drop_db_test.rb +16 -0
  212. data/test/postgres_information_schema_leak_test.rb +29 -0
  213. data/test/postgres_mixed_case_test.rb +29 -0
  214. data/test/postgres_native_type_mapping_test.rb +93 -0
  215. data/test/postgres_nonseq_pkey_test.rb +38 -0
  216. data/test/postgres_reserved_test.rb +22 -0
  217. data/test/postgres_reset_column_information_test.rb +8 -0
  218. data/test/postgres_schema_search_path_test.rb +48 -0
  219. data/test/postgres_simple_test.rb +168 -0
  220. data/test/postgres_table_alias_length_test.rb +15 -0
  221. data/test/postgres_type_conversion_test.rb +34 -0
  222. data/test/row_locking.rb +90 -0
  223. data/test/simple.rb +731 -0
  224. data/test/sqlite3_reset_column_information_test.rb +8 -0
  225. data/test/sqlite3_simple_test.rb +316 -0
  226. data/test/sybase_jtds_simple_test.rb +28 -0
  227. data/test/sybase_reset_column_information_test.rb +8 -0
  228. metadata +288 -0
@@ -0,0 +1,15 @@
1
+ require 'jdbc_common'
2
+ require 'db/postgres'
3
+
4
+ class PostgresTableAliasLengthTest < Test::Unit::TestCase
5
+ def test_table_alias_length
6
+ result = ActiveRecord::Base.connection.select_one("SELECT 1 AS " + "a" * 2048)
7
+
8
+ actual_table_alias_length = result.keys.first.size
9
+ actual_table_alias_length = 0 if actual_table_alias_length == 2048
10
+
11
+ assert_equal(actual_table_alias_length,
12
+ ActiveRecord::Base.connection.table_alias_length)
13
+ end
14
+ end
15
+
@@ -0,0 +1,34 @@
1
+ require 'jdbc_common'
2
+ require 'db/postgres'
3
+
4
+ class BooleanSchema < ActiveRecord::Migration
5
+ def self.up
6
+ create_table :booleans do |t|
7
+ t.boolean :value, :default => false, :null => false
8
+ end
9
+ end
10
+
11
+ def self.down
12
+ drop_table :booleans
13
+ end
14
+ end
15
+
16
+ class Boolean < ActiveRecord::Base
17
+ end
18
+
19
+ class PostgresTypeConversionTest < Test::Unit::TestCase
20
+ def setup
21
+ BooleanSchema.up
22
+ end
23
+
24
+ def teardown
25
+ BooleanSchema.down
26
+ end
27
+
28
+ def test_should_handle_bool_conversion_with_boolean_relation
29
+ assert_nothing_raised do
30
+ ActiveRecord::Base.connection.raw_connection.set_native_database_types
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,90 @@
1
+ #! /usr/bin/env jruby
2
+
3
+ require 'thread'
4
+
5
+ module RowLockingTestMethods
6
+
7
+ def test_row_locking
8
+ row_locking_test_template
9
+ end
10
+
11
+ def test_row_locking_with_limit
12
+ row_locking_test_template(:limit => 1)
13
+ end
14
+
15
+ private
16
+
17
+ def row_locking_test_template(options={})
18
+ # Create two rows that we will work with
19
+ @row1_id = Entry.create!(:title => "row1").id
20
+ @row2_id = Entry.create!(:title => "row2").id
21
+
22
+ @result_queue = Queue.new
23
+ signal_queue = Queue.new
24
+ t1 = Thread.new { thread_helper { thread1_main(signal_queue, options) } }
25
+ t2 = Thread.new { thread_helper { thread2_main(signal_queue, options) } }
26
+ t1.join
27
+ t2.join
28
+
29
+ result = []
30
+ result << @result_queue.shift until @result_queue.empty? # Convert the queue into an array
31
+
32
+ expected = [
33
+ :t1_locking_row2,
34
+ :t1_locked_row2,
35
+
36
+ :t2_locking_row1,
37
+ :t2_locked_row1,
38
+
39
+ :t2_locking_row2, # thread 2 tries to lock row2 ...
40
+ :t1_committed,
41
+ :t2_locked_row2, # ... but it doesn't succeed until after thread 1 commits its transaction
42
+
43
+ :t2_committed,
44
+ ]
45
+
46
+ assert_equal expected, result, "thread2 should lock row1 immediately but wait for thread1 to commit before getting the lock on row2"
47
+ end
48
+
49
+ def thread1_main(signal_queue, options={})
50
+ Entry.transaction do
51
+ @result_queue << :t1_locking_row2
52
+ Entry.find(@row2_id, {:lock=>true}.merge(options)) # acquire a row lock on r2
53
+ @result_queue << :t1_locked_row2
54
+ signal_queue << :go # signal thread2 to start
55
+ sleep 2.0 # Wait for a few seconds, to allow the other thread to race with this thread.
56
+ @result_queue << :t1_committed
57
+ end
58
+ end
59
+
60
+ def thread2_main(signal_queue, options={})
61
+ Entry.transaction do
62
+ signal_queue.shift # wait until we get the signal from thread1
63
+ @result_queue << :t2_locking_row1
64
+ Entry.find(@row1_id, {:lock=>true}.merge(options)) # should return immediately
65
+ @result_queue << :t2_locked_row1
66
+ @result_queue << :t2_locking_row2
67
+ Entry.find(@row2_id, {:lock=>true}.merge(options)) # should block until thread1 commits its transaction
68
+ @result_queue << :t2_locked_row2
69
+ @result_queue << :t2_committed
70
+ end
71
+ end
72
+
73
+ def thread_helper
74
+ yield
75
+ rescue Exception => exc
76
+ # Output backtrace, since otherwise we won't see anything until the main thread joins this thread.
77
+ display_exception(exc)
78
+ raise
79
+ ensure
80
+ # This is needed. Otherwise, the database connections aren't returned to the pool and things break.
81
+ ActiveRecord::Base.connection_handler.clear_active_connections!
82
+ end
83
+
84
+ def display_exception(exception)
85
+ lines = []
86
+ lines << "#{exception.class.name}: #{exception.message}\n"
87
+ lines += exception.backtrace.map{|line| "\tfrom #{line}"}
88
+ $stderr.puts lines.join("\n")
89
+ end
90
+ end
@@ -0,0 +1,731 @@
1
+ # -*- coding: utf-8 -*-
2
+ ActiveRecord::Schema.verbose = false
3
+ ActiveRecord::Base.time_zone_aware_attributes = true if ActiveRecord::Base.respond_to?(:time_zone_aware_attributes)
4
+ ActiveRecord::Base.default_timezone = :utc
5
+ #just a random zone, unlikely to be local, and not utc
6
+ Time.zone = 'Moscow' if Time.respond_to?(:zone)
7
+
8
+ module MigrationSetup
9
+ def setup
10
+ DbTypeMigration.up
11
+ CreateStringIds.up
12
+ CreateEntries.up
13
+ CreateUsers.up
14
+ CreateAutoIds.up
15
+ CreateValidatesUniquenessOf.up
16
+ CreateThings.up
17
+ CreateCustomPkName.up
18
+ @connection = ActiveRecord::Base.connection
19
+ end
20
+
21
+ def teardown
22
+ DbTypeMigration.down
23
+ CreateStringIds.down
24
+ CreateEntries.down
25
+ CreateUsers.down
26
+ CreateAutoIds.down
27
+ CreateValidatesUniquenessOf.down
28
+ CreateThings.down
29
+ CreateCustomPkName.down
30
+ ActiveRecord::Base.clear_active_connections!
31
+ end
32
+ end
33
+
34
+ module FixtureSetup
35
+ include MigrationSetup
36
+ def setup
37
+ super
38
+ @title = "First post!"
39
+ @content = "Hello from JRuby on Rails!"
40
+ @new_title = "First post updated title"
41
+ @rating = 205.76
42
+ @user = User.create :login=>"something"
43
+ @entry = Entry.create :title => @title, :content => @content, :rating => @rating, :user=>@user
44
+ DbType.create
45
+ end
46
+ end
47
+
48
+ module ColumnNameQuotingTests
49
+ def self.included(base)
50
+ base.class_eval do
51
+ @@column_quote_char = "\""
52
+
53
+ def self.column_quote_char(char)
54
+ @@column_quote_char = char
55
+ end
56
+ end
57
+ end
58
+
59
+ def test_column_names_are_escaped
60
+ conn = ActiveRecord::Base.connection
61
+ quoted = conn.quote_column_name "foo#{column_quote_char}bar"
62
+ assert_equal "#{column_quote_char}foo#{column_quote_char * 2}bar#{column_quote_char}", quoted
63
+ end
64
+
65
+ protected
66
+ def column_quote_char
67
+ @@column_quote_char || "\""
68
+ end
69
+ end
70
+
71
+ module DirtyAttributeTests
72
+ def test_partial_update
73
+ entry = Entry.new(:title => 'foo')
74
+ old_updated_on = 1.hour.ago.beginning_of_day
75
+
76
+ with_partial_updates Entry, false do
77
+ assert_queries(2) { 2.times { entry.save! } }
78
+ Entry.update_all({ :updated_on => old_updated_on }, :id => entry.id)
79
+ end
80
+
81
+ with_partial_updates Entry, true do
82
+ assert_queries(0) { 2.times { entry.save! } }
83
+ assert_equal old_updated_on, entry.reload.updated_on
84
+
85
+ assert_queries(1) { entry.title = 'bar'; entry.save! }
86
+ assert_not_equal old_updated_on, entry.reload.updated_on
87
+ end
88
+ end
89
+
90
+ private
91
+ def with_partial_updates(klass, on = true)
92
+ old = klass.partial_updates?
93
+ klass.partial_updates = on
94
+ yield
95
+ ensure
96
+ klass.partial_updates = old
97
+ end
98
+ end
99
+
100
+ module SimpleTestMethods
101
+ include FixtureSetup
102
+
103
+ def test_substitute_binds_has_no_side_effect_on_binds_parameter
104
+ binds = [[Entry.columns_hash['title'], 'test1']]
105
+ binds2 = binds.dup
106
+ sql = 'select * from entries where title = ?'
107
+ Entry.connection.substitute_binds(sql, binds)
108
+ assert_equal binds2, binds
109
+ end
110
+
111
+ def test_entries_created
112
+ assert ActiveRecord::Base.connection.tables.find{|t| t =~ /^entries$/i}, "entries not created"
113
+ end
114
+
115
+ def test_users_created
116
+ assert ActiveRecord::Base.connection.tables.find{|t| t =~ /^users$/i}, "users not created"
117
+ end
118
+
119
+ def test_entries_empty
120
+ Entry.delete_all
121
+ assert_equal 0, Entry.count
122
+ end
123
+
124
+ def test_find_with_string_slug
125
+ new_entry = Entry.create(:title => "Blah")
126
+ entry = Entry.find(new_entry.to_param)
127
+ assert_equal new_entry.id, entry.id
128
+ end
129
+
130
+ def test_insert_returns_id
131
+ unless ActiveRecord::Base.connection.adapter_name =~ /oracle/i
132
+ value = ActiveRecord::Base.connection.insert("INSERT INTO entries (title, content, rating) VALUES('insert_title', 'some content', 1)")
133
+ assert !value.nil?
134
+ entry = Entry.find_by_title('insert_title')
135
+ assert_equal entry.id, value
136
+
137
+ # Ensure we get the id even if the PK column is not named 'id'
138
+ 1.upto(4) do |i|
139
+ cpn_name = "return id test#{i}"
140
+ cpn = CustomPkName.new
141
+ cpn.name = cpn_name
142
+ cpn.save
143
+ value = cpn.custom_id
144
+ assert !value.nil?
145
+ cpn = CustomPkName.find_by_name(cpn_name)
146
+ assert_equal cpn.custom_id, value
147
+ end
148
+ end
149
+ end
150
+
151
+ def test_create_new_entry
152
+ Entry.delete_all
153
+
154
+ post = Entry.new
155
+ post.title = @title
156
+ post.content = @content
157
+ post.rating = @rating
158
+ post.save
159
+
160
+ assert_equal 1, Entry.count
161
+ end
162
+
163
+ def test_create_partial_new_entry
164
+ new_entry = Entry.create(:title => "Blah")
165
+ new_entry2 = Entry.create(:title => "Bloh")
166
+ end
167
+
168
+ def test_find_and_update_entry
169
+ post = Entry.find(:first)
170
+ assert_equal @title, post.title
171
+ assert_equal @content, post.content
172
+ assert_equal @rating, post.rating
173
+
174
+ post.title = @new_title
175
+ post.save
176
+
177
+ post = Entry.find(:first)
178
+ assert_equal @new_title, post.title
179
+ end
180
+
181
+ def test_destroy_entry
182
+ prev_count = Entry.count
183
+ post = Entry.find(:first)
184
+ post.destroy
185
+
186
+ assert_equal prev_count - 1, Entry.count
187
+ end
188
+
189
+ if Entry.respond_to?(:limit)
190
+ def test_limit
191
+ Entry.limit(10).to_a
192
+ end
193
+
194
+ def test_count_with_limit
195
+ assert_equal Entry.count, Entry.limit(10).count
196
+ end
197
+ end
198
+
199
+ if Time.respond_to?(:zone)
200
+ def test_save_time_with_utc
201
+ current_zone = Time.zone
202
+ default_zone = ActiveRecord::Base.default_timezone
203
+ ActiveRecord::Base.default_timezone = Time.zone = :utc
204
+ now = Time.now
205
+ my_time = Time.local now.year, now.month, now.day, now.hour, now.min, now.sec
206
+ m = DbType.create! :sample_datetime => my_time
207
+ m.reload
208
+ assert_equal my_time, m.sample_datetime
209
+ rescue
210
+ Time.zone = current_zone
211
+ ActiveRecord::Base.default_timezone = default_zone
212
+ end
213
+
214
+ def test_save_time
215
+ t = Time.now
216
+ #precision will only be expected to the second.
217
+ time = Time.local(t.year, t.month, t.day, t.hour, t.min, t.sec)
218
+ e = DbType.find(:first)
219
+ e.sample_datetime = time
220
+ e.save!
221
+ e = DbType.find(:first)
222
+ assert_equal time.in_time_zone, e.sample_datetime
223
+ end
224
+
225
+ def test_save_date_time
226
+ t = Time.now
227
+ #precision will only be expected to the second.
228
+ time = Time.local(t.year, t.month, t.day, t.hour, t.min, t.sec)
229
+ datetime = time.to_datetime
230
+ e = DbType.find(:first)
231
+ e.sample_datetime = datetime
232
+ e.save!
233
+ e = DbType.find(:first)
234
+ assert_equal time, e.sample_datetime.localtime
235
+ end
236
+
237
+ def test_save_time_with_zone
238
+ t = Time.now
239
+ #precision will only be expected to the second.
240
+ original_time = Time.local(t.year, t.month, t.day, t.hour, t.min, t.sec)
241
+ time = original_time.in_time_zone
242
+ e = DbType.find(:first)
243
+ e.sample_datetime = time
244
+ e.save!
245
+ e = DbType.find(:first)
246
+ assert_equal time, e.sample_datetime
247
+ end
248
+ end
249
+
250
+ def test_save_float
251
+ e = DbType.find(:first)
252
+ e.sample_float = 12.0
253
+ e.save!
254
+
255
+ e = DbType.find(:first)
256
+ assert_equal(12.0, e.sample_float)
257
+ end
258
+
259
+ def test_save_date
260
+ date = Date.new(2007)
261
+ e = DbType.find(:first)
262
+ e.sample_date = date
263
+ e.save!
264
+ e = DbType.find(:first)
265
+ if DbType.columns_hash["sample_date"].type == :datetime
266
+ # Oracle doesn't distinguish btw date/datetime
267
+ assert_equal date, e.sample_date.to_date
268
+ else
269
+ assert_equal date, e.sample_date
270
+ end
271
+ end
272
+
273
+ def test_boolean
274
+ # An unset boolean should default to nil
275
+ e = DbType.find(:first)
276
+ assert_equal(nil, e.sample_boolean)
277
+
278
+ e.sample_boolean = true
279
+ e.save!
280
+
281
+ e = DbType.find(:first)
282
+ assert_equal(true, e.sample_boolean)
283
+ end
284
+
285
+ def test_integer
286
+ # An unset boolean should default to nil
287
+ e = DbType.find(:first)
288
+ assert_equal(nil, e.sample_integer)
289
+
290
+ e.sample_integer = 10
291
+ e.save!
292
+
293
+ e = DbType.find(:first)
294
+ assert_equal(10, e.sample_integer)
295
+ end
296
+
297
+ def test_text
298
+ # An unset boolean should default to nil
299
+ e = DbType.find(:first)
300
+
301
+ # Oracle adapter initializes all CLOB fields with empty_clob() function,
302
+ # so they all have a initial value of an empty string ''
303
+ assert_equal(nil, e.sample_text) unless ActiveRecord::Base.connection.adapter_name =~ /oracle/i
304
+
305
+ e.sample_text = "ooop?"
306
+ e.save!
307
+
308
+ e = DbType.find(:first)
309
+ assert_equal("ooop?", e.sample_text)
310
+ end
311
+
312
+ def test_string
313
+ e = DbType.find(:first)
314
+
315
+ # An empty string is treated as a null value in Oracle: http://www.techonthenet.com/oracle/questions/empty_null.php
316
+ assert_equal('', e.sample_string) unless ActiveRecord::Base.connection.adapter_name =~ /oracle/i
317
+ e.sample_string = "ooop?"
318
+ e.save!
319
+
320
+ e = DbType.find(:first)
321
+ assert_equal("ooop?", e.sample_string)
322
+ end
323
+
324
+ def test_save_binary
325
+ #string is 60_000 bytes
326
+ binary_string = "\000ABCDEFGHIJKLMNOPQRSTUVWXYZ'\001\003"*1#2_000
327
+ e = DbType.find(:first)
328
+ e.sample_binary = binary_string
329
+ e.save!
330
+ e = DbType.find(:first)
331
+ assert_equal binary_string, e.sample_binary
332
+ end
333
+
334
+ def test_default_decimal_should_keep_fractional_part
335
+ expected = 7.3
336
+ db_type = DbType.new(:sample_small_decimal => expected)
337
+ assert db_type.save
338
+ db_type = DbType.find(db_type.id)
339
+ assert_equal BigDecimal.new(expected.to_s), db_type.sample_small_decimal
340
+ end
341
+
342
+ def test_decimal_with_scale
343
+ test_value = 7.3
344
+ db_type = DbType.new(:sample_small_decimal => test_value)
345
+ assert db_type.save
346
+ db_type = DbType.find(db_type.id)
347
+ assert_kind_of BigDecimal, db_type.sample_small_decimal
348
+ assert_equal BigDecimal.new(test_value.to_s), db_type.sample_small_decimal
349
+ end
350
+
351
+ def test_decimal_with_zero_scale
352
+ test_value = 7000.0
353
+ db_type = DbType.new(:sample_decimal => test_value)
354
+ assert db_type.save
355
+ db_type = DbType.find(db_type.id)
356
+ assert_kind_of Integer, db_type.sample_decimal
357
+ assert_equal test_value.to_i, db_type.sample_decimal
358
+ end
359
+
360
+ def test_negative_default_value
361
+ assert_equal(-1, DbType.columns_hash['sample_integer_neg_default'].default)
362
+ assert_equal(-1, DbType.new.sample_integer_neg_default)
363
+ end
364
+
365
+ def test_indexes
366
+ # Only test indexes if we have implemented it for the particular adapter
367
+ if @connection.respond_to?(:indexes)
368
+ indexes = @connection.indexes(:entries)
369
+ assert_equal(0, indexes.size)
370
+
371
+ index_name = "entries_index"
372
+ @connection.add_index(:entries, :updated_on, :name => index_name)
373
+
374
+ indexes = @connection.indexes(:entries)
375
+ assert_equal(1, indexes.size)
376
+ assert_equal "entries", indexes.first.table.to_s
377
+ assert_equal index_name, indexes.first.name
378
+ assert !indexes.first.unique
379
+ assert_equal ["updated_on"], indexes.first.columns
380
+ end
381
+ end
382
+
383
+ def test_remove_nonexistent_index
384
+ assert_raise(ArgumentError, ActiveRecord::StatementInvalid, ActiveRecord::JDBCError) do
385
+ @connection.remove_index :entries, :nonexistent_index
386
+ end
387
+ end
388
+
389
+ def test_add_index_with_invalid_name_length
390
+ index_name = 'x' * (@connection.index_name_length + 1)
391
+ assert_raise(ArgumentError) do
392
+ @connection.add_index "entries", "title", :name => index_name
393
+ end
394
+ end
395
+
396
+ def test_dumping_schema
397
+ require 'active_record/schema_dumper'
398
+ @connection.add_index :entries, :title
399
+ StringIO.open do |io|
400
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, io)
401
+ assert_match(/add_index "entries",/, io.string)
402
+ end
403
+ @connection.remove_index :entries, :title
404
+
405
+ end
406
+
407
+ def test_nil_values
408
+ test = AutoId.create('value' => '')
409
+ assert_nil AutoId.find(test.id).value
410
+ end
411
+
412
+ # These should make no difference, but might due to the wacky regexp SQL rewriting we do.
413
+ def test_save_value_containing_sql
414
+ e = DbType.first
415
+ e.save
416
+
417
+ e.sample_string = e.sample_text = "\n\nselect from nothing where id = 'foo'"
418
+ e.save
419
+ end
420
+
421
+ def test_invalid
422
+ e = Entry.new(:title => @title, :content => @content, :rating => ' ')
423
+ assert e.valid?
424
+ end
425
+
426
+ def test_reconnect
427
+ assert_equal 1, Entry.count
428
+ @connection.reconnect!
429
+ assert_equal 1, Entry.count
430
+ end
431
+
432
+ if jruby?
433
+ def test_connection_valid
434
+ assert_raises(ActiveRecord::JDBCError) do
435
+ @connection.raw_connection.with_connection_retry_guard do |c|
436
+ begin
437
+ stmt = c.createStatement
438
+ stmt.execute "bogus sql"
439
+ ensure
440
+ stmt.close rescue nil
441
+ end
442
+ end
443
+ end
444
+ end
445
+
446
+ class Animal < ActiveRecord::Base; end
447
+
448
+ def test_fetching_columns_for_nonexistent_table_should_raise
449
+ assert_raises(ActiveRecord::ActiveRecordError,
450
+ ActiveRecord::StatementInvalid, ActiveRecord::JDBCError) do
451
+ Animal.columns
452
+ end
453
+ end
454
+ end
455
+
456
+ def test_disconnect
457
+ assert_equal 1, Entry.count
458
+ ActiveRecord::Base.clear_active_connections!
459
+ ActiveRecord::Base.connection_pool.disconnect! if ActiveRecord::Base.respond_to?(:connection_pool)
460
+ assert !ActiveRecord::Base.connected?
461
+ assert_equal 1, Entry.count
462
+ assert ActiveRecord::Base.connected?
463
+ end
464
+
465
+ def test_add_not_null_column_to_table
466
+ AddNotNullColumnToTable.up
467
+ AddNotNullColumnToTable.down
468
+ end
469
+
470
+ def test_add_null_column_with_default
471
+ Entry.connection.add_column :entries, :color, :string, :null => false, :default => "blue"
472
+ created_columns = Entry.connection.columns('entries')
473
+
474
+ color = created_columns.detect { |c| c.name == 'color' }
475
+ assert !color.null
476
+ end
477
+
478
+ def test_add_null_column_with_no_default
479
+ # You must specify a default value with most databases
480
+ if ActiveRecord::Base.connection.adapter_name =~ /mysql/i
481
+ Entry.connection.add_column :entries, :color, :string, :null => false
482
+ created_columns = Entry.connection.columns('entries')
483
+
484
+ color = created_columns.detect { |c| c.name == 'color' }
485
+ assert !color.null
486
+ end
487
+ end
488
+
489
+ def test_add_null_column_with_nil_default
490
+ # You must specify a default value with most databases
491
+ if ActiveRecord::Base.connection.adapter_name =~ /mysql/i
492
+ Entry.connection.add_column :entries, :color, :string, :null => false, :default => nil
493
+ created_columns = Entry.connection.columns('entries')
494
+
495
+ color = created_columns.detect { |c| c.name == 'color' }
496
+ assert !color.null
497
+ end
498
+ end
499
+
500
+ def test_validates_uniqueness_of_strings_case_sensitive
501
+ name_lower = ValidatesUniquenessOfString.new(:cs_string => "name", :ci_string => '1')
502
+ name_lower.save!
503
+
504
+ name_upper = ValidatesUniquenessOfString.new(:cs_string => "NAME", :ci_string => '2')
505
+ assert_nothing_raised do
506
+ name_upper.save!
507
+ end
508
+
509
+ name_lower_collision = ValidatesUniquenessOfString.new(:cs_string => "name", :ci_string => '3')
510
+ assert_raise ActiveRecord::RecordInvalid do
511
+ name_lower_collision.save!
512
+ end
513
+
514
+ name_upper_collision = ValidatesUniquenessOfString.new(:cs_string => "NAME", :ci_string => '4')
515
+ assert_raise ActiveRecord::RecordInvalid do
516
+ name_upper_collision.save!
517
+ end
518
+ end
519
+
520
+ def test_validates_uniqueness_of_strings_case_insensitive
521
+ name_lower = ValidatesUniquenessOfString.new(:cs_string => '1', :ci_string => "name")
522
+ name_lower.save!
523
+
524
+ name_upper = ValidatesUniquenessOfString.new(:cs_string => '2', :ci_string => "NAME")
525
+ assert_raise ActiveRecord::RecordInvalid do
526
+ name_upper.save!
527
+ end
528
+
529
+ name_lower_collision = ValidatesUniquenessOfString.new(:cs_string => '3', :ci_string => "name")
530
+ assert_raise ActiveRecord::RecordInvalid do
531
+ name_lower_collision.save!
532
+ end
533
+
534
+ alternate_name_upper = ValidatesUniquenessOfString.new(:cs_string => '4', :ci_string => "ALTERNATE_NAME")
535
+ assert_nothing_raised do
536
+ alternate_name_upper.save!
537
+ end
538
+
539
+ alternate_name_upper_collision = ValidatesUniquenessOfString.new(:cs_string => '5', :ci_string => "ALTERNATE_NAME")
540
+ assert_raise ActiveRecord::RecordInvalid do
541
+ alternate_name_upper_collision.save!
542
+ end
543
+
544
+ alternate_name_lower = ValidatesUniquenessOfString.new(:cs_string => '6', :ci_string => "alternate_name")
545
+ assert_raise ActiveRecord::RecordInvalid do
546
+ alternate_name_lower.save!
547
+ end
548
+ end
549
+
550
+ class ChangeEntriesTable < ActiveRecord::Migration
551
+ def self.up
552
+ change_table :entries do |t|
553
+ t.string :author
554
+ end if respond_to?(:change_table)
555
+ end
556
+ def self.down
557
+ change_table :entries do |t|
558
+ t.remove :author
559
+ end if respond_to?(:change_table)
560
+ end
561
+ end
562
+ def test_change_table
563
+ ChangeEntriesTable.up
564
+ ChangeEntriesTable.down
565
+ end
566
+
567
+ def test_string_id
568
+ f = StringId.new
569
+ f.id = "some_string"
570
+ f.save
571
+ f = StringId.first #reload is essential
572
+ assert_equal "some_string", f.id
573
+ end
574
+
575
+ def test_model_with_no_id
576
+ assert_nothing_raised do
577
+ Thing.create! :name => "a thing"
578
+ end
579
+ assert_equal 1, Thing.find(:all).size
580
+ end
581
+ end
582
+
583
+ module MultibyteTestMethods
584
+ include MigrationSetup
585
+
586
+ if defined?(JRUBY_VERSION)
587
+ def setup
588
+ super
589
+ config = ActiveRecord::Base.connection.config
590
+ @jdbc_driver = ActiveRecord::ConnectionAdapters::JdbcDriver.new(config[:driver])
591
+ @java_con = @jdbc_driver.connection(config[:url], config[:username], config[:password])
592
+ @java_con.setAutoCommit(true)
593
+ end
594
+
595
+ def teardown
596
+ @java_con.close
597
+ @jdbc_driver = nil
598
+ super
599
+ end
600
+
601
+ def test_select_multibyte_string
602
+ @java_con.createStatement().execute("insert into entries (id, title, content) values (1, 'テスト', '本文')")
603
+ entry = Entry.find(:first)
604
+ assert_equal "テスト", entry.title
605
+ assert_equal "本文", entry.content
606
+ assert_equal entry, Entry.find_by_title("テスト")
607
+ end
608
+
609
+ def test_update_multibyte_string
610
+ Entry.create!(:title => "テスト", :content => "本文")
611
+ rs = @java_con.createStatement().executeQuery("select title, content from entries")
612
+ assert rs.next
613
+ assert_equal "テスト", rs.getString(1)
614
+ assert_equal "本文", rs.getString(2)
615
+ end
616
+ end
617
+
618
+ def test_multibyte_aliasing
619
+ str = "テスト"
620
+ quoted_alias = Entry.connection.quote_column_name(str)
621
+ sql = "SELECT title AS #{quoted_alias} from entries"
622
+ records = Entry.connection.select_all(sql)
623
+ records.each do |rec|
624
+ rec.keys.each do |key|
625
+ assert_equal str, key
626
+ end
627
+ end
628
+ end
629
+
630
+ def test_chinese_word
631
+ chinese_word = '中文'
632
+ new_entry = Entry.create(:title => chinese_word)
633
+ new_entry.reload
634
+ assert_equal chinese_word, new_entry.title
635
+ end
636
+ end
637
+
638
+ module NonUTF8EncodingMethods
639
+ def setup
640
+ @connection = ActiveRecord::Base.remove_connection
641
+ latin2_connection = @connection.dup
642
+ latin2_connection[:encoding] = 'latin2'
643
+ latin2_connection.delete(:url) # pre-gen url gets stashed; remove to re-gen
644
+ ActiveRecord::Base.establish_connection latin2_connection
645
+ CreateEntries.up
646
+ end
647
+
648
+ def teardown
649
+ CreateEntries.down
650
+ ActiveRecord::Base.establish_connection @connection
651
+ end
652
+
653
+ def test_nonutf8_encoding_in_entry
654
+ prague_district = 'hradčany'
655
+ new_entry = Entry.create :title => prague_district
656
+ new_entry.reload
657
+ assert_equal prague_district, new_entry.title
658
+ end
659
+ end
660
+
661
+ module ActiveRecord3TestMethods
662
+ def self.included(base)
663
+ base.send :include, Tests if ActiveRecord::VERSION::MAJOR == 3
664
+ end
665
+
666
+ module Tests
667
+ if ActiveRecord::VERSION::MINOR == 2
668
+ def test_visitor_accessor
669
+ adapter = Entry.connection
670
+ expected_visitors = adapter.config[:adapter_spec].
671
+ arel2_visitors(adapter).values
672
+ assert !adapter.visitor.nil?
673
+ assert expected_visitors.include?(adapter.visitor.class)
674
+ end
675
+ end
676
+
677
+ def test_where
678
+ entries = Entry.where(:title => @entry.title)
679
+ assert_equal @entry, entries.first
680
+ end
681
+ end
682
+ end
683
+
684
+ module ResetColumnInformationTestMethods
685
+ class Fhqwhgad < ActiveRecord::Base
686
+ end
687
+
688
+ def test_reset_column_information
689
+ drop_fhqwhgads_table!
690
+ create_fhqwhgads_table_1!
691
+ Fhqwhgad.reset_column_information
692
+ assert_equal ["id", "come_on"].sort, Fhqwhgad.columns.map{|c| c.name}.sort, "columns should be correct the first time"
693
+
694
+ drop_fhqwhgads_table!
695
+ create_fhqwhgads_table_2!
696
+ Fhqwhgad.reset_column_information
697
+ assert_equal ["id", "to_the_limit"].sort, Fhqwhgad.columns.map{|c| c.name}.sort, "columns should be correct the second time"
698
+ ensure
699
+ drop_fhqwhgads_table!
700
+ end
701
+
702
+ private
703
+
704
+ def drop_fhqwhgads_table!
705
+ ActiveRecord::Schema.define do
706
+ suppress_messages do
707
+ drop_table :fhqwhgads if table_exists? :fhqwhgads
708
+ end
709
+ end
710
+ end
711
+
712
+ def create_fhqwhgads_table_1!
713
+ ActiveRecord::Schema.define do
714
+ suppress_messages do
715
+ create_table :fhqwhgads do |t|
716
+ t.string :come_on
717
+ end
718
+ end
719
+ end
720
+ end
721
+
722
+ def create_fhqwhgads_table_2!
723
+ ActiveRecord::Schema.define do
724
+ suppress_messages do
725
+ create_table :fhqwhgads do |t|
726
+ t.string :to_the_limit, :null=>false, :default=>'everybody'
727
+ end
728
+ end
729
+ end
730
+ end
731
+ end