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