activerecord-jdbc-adapter 1.3.0.beta2 → 1.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (282) hide show
  1. data/.gitignore +14 -8
  2. data/.travis.yml +40 -31
  3. data/.yardopts +4 -0
  4. data/Appraisals +2 -5
  5. data/CONTRIBUTING.md +46 -0
  6. data/Gemfile +21 -4
  7. data/Gemfile.lock +42 -17
  8. data/{History.txt → History.md} +142 -75
  9. data/README.md +102 -104
  10. data/RUNNING_TESTS.md +76 -0
  11. data/Rakefile.jdbc +20 -0
  12. data/activerecord-jdbc-adapter.gemspec +35 -18
  13. data/gemfiles/rails23.gemfile +4 -3
  14. data/gemfiles/rails23.gemfile.lock +9 -6
  15. data/gemfiles/rails30.gemfile +4 -3
  16. data/gemfiles/rails30.gemfile.lock +9 -6
  17. data/gemfiles/rails31.gemfile +4 -3
  18. data/gemfiles/rails31.gemfile.lock +9 -6
  19. data/gemfiles/rails32.gemfile +4 -3
  20. data/gemfiles/rails32.gemfile.lock +17 -14
  21. data/gemfiles/rails40.gemfile +5 -5
  22. data/gemfiles/rails40.gemfile.lock +17 -69
  23. data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
  24. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
  25. data/lib/arel/visitors/compat.rb +22 -3
  26. data/lib/arel/visitors/db2.rb +8 -4
  27. data/lib/arel/visitors/derby.rb +14 -13
  28. data/lib/arel/visitors/firebird.rb +5 -4
  29. data/lib/arel/visitors/hsqldb.rb +11 -9
  30. data/lib/arel/visitors/sql_server.rb +89 -61
  31. data/lib/arjdbc.rb +1 -1
  32. data/lib/arjdbc/db2/adapter.rb +181 -212
  33. data/lib/arjdbc/db2/as400.rb +31 -18
  34. data/lib/arjdbc/db2/column.rb +167 -0
  35. data/lib/arjdbc/db2/connection_methods.rb +2 -0
  36. data/lib/arjdbc/derby/adapter.rb +206 -107
  37. data/lib/arjdbc/derby/connection_methods.rb +4 -9
  38. data/lib/arjdbc/firebird.rb +1 -0
  39. data/lib/arjdbc/firebird/adapter.rb +202 -64
  40. data/lib/arjdbc/firebird/connection_methods.rb +20 -0
  41. data/lib/arjdbc/h2/adapter.rb +56 -36
  42. data/lib/arjdbc/hsqldb/adapter.rb +99 -68
  43. data/lib/arjdbc/jdbc/adapter.rb +474 -265
  44. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  45. data/lib/arjdbc/jdbc/adapter_require.rb +8 -7
  46. data/lib/arjdbc/jdbc/arel_support.rb +132 -0
  47. data/lib/arjdbc/jdbc/base_ext.rb +8 -7
  48. data/lib/arjdbc/jdbc/callbacks.rb +16 -10
  49. data/lib/arjdbc/jdbc/column.rb +25 -3
  50. data/lib/arjdbc/jdbc/connection.rb +28 -55
  51. data/lib/arjdbc/jdbc/extension.rb +14 -14
  52. data/lib/arjdbc/jdbc/java.rb +6 -3
  53. data/lib/arjdbc/jdbc/jdbc.rake +1 -1
  54. data/lib/arjdbc/jdbc/quoted_primary_key.rb +2 -2
  55. data/lib/arjdbc/jdbc/rake_tasks.rb +1 -1
  56. data/lib/arjdbc/jdbc/type_converter.rb +5 -2
  57. data/lib/arjdbc/mssql/adapter.rb +160 -280
  58. data/lib/arjdbc/mssql/column.rb +182 -0
  59. data/lib/arjdbc/mssql/connection_methods.rb +37 -4
  60. data/lib/arjdbc/mssql/explain_support.rb +13 -21
  61. data/lib/arjdbc/mssql/limit_helpers.rb +79 -42
  62. data/lib/arjdbc/mssql/lock_methods.rb +77 -0
  63. data/lib/arjdbc/mssql/utils.rb +11 -11
  64. data/lib/arjdbc/mysql/adapter.rb +165 -247
  65. data/lib/arjdbc/mysql/column.rb +123 -0
  66. data/lib/arjdbc/mysql/connection_methods.rb +3 -6
  67. data/lib/arjdbc/oracle/adapter.rb +282 -288
  68. data/lib/arjdbc/oracle/column.rb +122 -0
  69. data/lib/arjdbc/oracle/connection_methods.rb +3 -0
  70. data/lib/arjdbc/postgresql/adapter.rb +336 -574
  71. data/lib/arjdbc/postgresql/column.rb +458 -0
  72. data/lib/arjdbc/postgresql/connection_methods.rb +1 -2
  73. data/lib/arjdbc/postgresql/schema_creation.rb +38 -0
  74. data/lib/arjdbc/sqlite3/adapter.rb +189 -145
  75. data/lib/arjdbc/sqlite3/explain_support.rb +1 -1
  76. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +8 -8
  77. data/lib/arjdbc/util/quoted_cache.rb +60 -0
  78. data/lib/arjdbc/util/table_copier.rb +110 -0
  79. data/lib/arjdbc/version.rb +6 -7
  80. data/pom.xml +56 -2
  81. data/rakelib/02-test.rake +72 -83
  82. data/rakelib/db.rake +29 -17
  83. data/src/java/arjdbc/ArJdbcModule.java +21 -18
  84. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +84 -12
  85. data/src/java/arjdbc/derby/DerbyModule.java +140 -143
  86. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +58 -7
  87. data/src/java/arjdbc/h2/H2Module.java +43 -0
  88. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +7 -6
  89. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1223 -648
  90. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +24 -23
  91. data/src/java/arjdbc/mysql/MySQLModule.java +33 -32
  92. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +147 -30
  93. data/src/java/arjdbc/oracle/OracleModule.java +13 -13
  94. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +114 -6
  95. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +166 -36
  96. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +101 -19
  97. data/src/java/arjdbc/util/QuotingUtils.java +19 -19
  98. metadata +240 -394
  99. data/bench/bench_attributes.rb +0 -13
  100. data/bench/bench_attributes_new.rb +0 -14
  101. data/bench/bench_create.rb +0 -12
  102. data/bench/bench_find_all.rb +0 -12
  103. data/bench/bench_find_all_mt.rb +0 -25
  104. data/bench/bench_model.rb +0 -85
  105. data/bench/bench_new.rb +0 -12
  106. data/bench/bench_new_valid.rb +0 -12
  107. data/bench/bench_valid.rb +0 -13
  108. data/lib/arel/engines/sql/compilers/db2_compiler.rb +0 -9
  109. data/lib/arel/engines/sql/compilers/derby_compiler.rb +0 -6
  110. data/lib/arel/engines/sql/compilers/h2_compiler.rb +0 -6
  111. data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +0 -15
  112. data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +0 -6
  113. data/lib/arel/engines/sql/compilers/mssql_compiler.rb +0 -46
  114. data/lib/arjdbc/jdbc/missing_functionality_helper.rb +0 -98
  115. data/lib/arjdbc/mssql/lock_helpers.rb +0 -76
  116. data/lib/arjdbc/mssql/tsql_methods.rb +0 -58
  117. data/lib/arjdbc/postgresql/column_cast.rb +0 -134
  118. data/test/activerecord/connections/native_jdbc_mysql/connection.rb +0 -25
  119. data/test/activerecord/jall.sh +0 -7
  120. data/test/activerecord/jtest.sh +0 -3
  121. data/test/assets/flowers.jpg +0 -0
  122. data/test/binary.rb +0 -67
  123. data/test/db/db2.rb +0 -43
  124. data/test/db/db2/binary_test.rb +0 -6
  125. data/test/db/db2/has_many_through_test.rb +0 -6
  126. data/test/db/db2/rake_test.rb +0 -82
  127. data/test/db/db2/rake_test_data.sql +0 -35
  128. data/test/db/db2/reset_column_information_test.rb +0 -5
  129. data/test/db/db2/serialize_test.rb +0 -6
  130. data/test/db/db2/simple_test.rb +0 -81
  131. data/test/db/db2/test_helper.rb +0 -6
  132. data/test/db/db2/unit_test.rb +0 -73
  133. data/test/db/derby.rb +0 -12
  134. data/test/db/derby/binary_test.rb +0 -6
  135. data/test/db/derby/migration_test.rb +0 -74
  136. data/test/db/derby/rake_test.rb +0 -96
  137. data/test/db/derby/reset_column_information_test.rb +0 -6
  138. data/test/db/derby/row_locking_test.rb +0 -20
  139. data/test/db/derby/schema_dump_test.rb +0 -5
  140. data/test/db/derby/serialize_test.rb +0 -6
  141. data/test/db/derby/simple_test.rb +0 -173
  142. data/test/db/derby/test_helper.rb +0 -6
  143. data/test/db/derby/unit_test.rb +0 -32
  144. data/test/db/derby/xml_column_test.rb +0 -17
  145. data/test/db/h2.rb +0 -11
  146. data/test/db/h2/binary_test.rb +0 -6
  147. data/test/db/h2/change_column_test.rb +0 -68
  148. data/test/db/h2/identity_column_test.rb +0 -35
  149. data/test/db/h2/offset_test.rb +0 -49
  150. data/test/db/h2/rake_test.rb +0 -98
  151. data/test/db/h2/schema_dump_test.rb +0 -29
  152. data/test/db/h2/serialize_test.rb +0 -6
  153. data/test/db/h2/simple_test.rb +0 -56
  154. data/test/db/hsqldb.rb +0 -11
  155. data/test/db/hsqldb/binary_test.rb +0 -6
  156. data/test/db/hsqldb/rake_test.rb +0 -101
  157. data/test/db/hsqldb/schema_dump_test.rb +0 -19
  158. data/test/db/hsqldb/serialize_test.rb +0 -6
  159. data/test/db/hsqldb/simple_test.rb +0 -17
  160. data/test/db/informix.rb +0 -13
  161. data/test/db/jdbc.rb +0 -16
  162. data/test/db/jdbc_derby.rb +0 -14
  163. data/test/db/jdbc_h2.rb +0 -17
  164. data/test/db/jdbc_mysql.rb +0 -13
  165. data/test/db/jdbc_postgres.rb +0 -23
  166. data/test/db/jndi_config.rb +0 -32
  167. data/test/db/jndi_pooled_config.rb +0 -32
  168. data/test/db/mssql.rb +0 -11
  169. data/test/db/mssql/binary_test.rb +0 -6
  170. data/test/db/mssql/exec_proc_test.rb +0 -46
  171. data/test/db/mssql/identity_insert_test.rb +0 -18
  172. data/test/db/mssql/ignore_system_views_test.rb +0 -40
  173. data/test/db/mssql/limit_offset_test.rb +0 -190
  174. data/test/db/mssql/multibyte_test.rb +0 -16
  175. data/test/db/mssql/multiple_connections_test.rb +0 -71
  176. data/test/db/mssql/rake_test.rb +0 -143
  177. data/test/db/mssql/reset_column_information_test.rb +0 -6
  178. data/test/db/mssql/row_locking_test.rb +0 -7
  179. data/test/db/mssql/serialize_test.rb +0 -6
  180. data/test/db/mssql/simple_test.rb +0 -140
  181. data/test/db/mssql/transaction_test.rb +0 -6
  182. data/test/db/mssql/types_test.rb +0 -205
  183. data/test/db/mssql/unit_test.rb +0 -249
  184. data/test/db/mysql.rb +0 -4
  185. data/test/db/mysql/_rails_test_mysql.32.out +0 -6585
  186. data/test/db/mysql/binary_test.rb +0 -6
  187. data/test/db/mysql/connection_test.rb +0 -51
  188. data/test/db/mysql/index_length_test.rb +0 -58
  189. data/test/db/mysql/multibyte_test.rb +0 -10
  190. data/test/db/mysql/nonstandard_primary_key_test.rb +0 -39
  191. data/test/db/mysql/rake_test.rb +0 -97
  192. data/test/db/mysql/reset_column_information_test.rb +0 -6
  193. data/test/db/mysql/schema_dump_test.rb +0 -228
  194. data/test/db/mysql/serialize_test.rb +0 -6
  195. data/test/db/mysql/simple_test.rb +0 -187
  196. data/test/db/mysql/statement_escaping_test.rb +0 -46
  197. data/test/db/mysql/transaction_test.rb +0 -6
  198. data/test/db/mysql/types_test.rb +0 -30
  199. data/test/db/mysql/unit_test.rb +0 -93
  200. data/test/db/mysql_config.rb +0 -7
  201. data/test/db/oracle.rb +0 -27
  202. data/test/db/oracle/binary_test.rb +0 -6
  203. data/test/db/oracle/limit_test.rb +0 -24
  204. data/test/db/oracle/multibyte_test.rb +0 -22
  205. data/test/db/oracle/rake_test.rb +0 -100
  206. data/test/db/oracle/reset_column_information_test.rb +0 -6
  207. data/test/db/oracle/serialize_test.rb +0 -6
  208. data/test/db/oracle/simple_test.rb +0 -140
  209. data/test/db/oracle/specific_test.rb +0 -180
  210. data/test/db/oracle/transaction_test.rb +0 -31
  211. data/test/db/oracle/unit_test.rb +0 -31
  212. data/test/db/postgres.rb +0 -11
  213. data/test/db/postgres/_rails_test_postgres.32.out +0 -6405
  214. data/test/db/postgres/a_custom_primary_key_test.rb +0 -50
  215. data/test/db/postgres/active_schema_unit_test.rb +0 -68
  216. data/test/db/postgres/array_type_test.rb +0 -101
  217. data/test/db/postgres/binary_test.rb +0 -6
  218. data/test/db/postgres/connection_test.rb +0 -63
  219. data/test/db/postgres/data_types_test.rb +0 -703
  220. data/test/db/postgres/hstore_test.rb +0 -200
  221. data/test/db/postgres/information_schema_leak_test.rb +0 -30
  222. data/test/db/postgres/json_test.rb +0 -86
  223. data/test/db/postgres/ltree_test.rb +0 -51
  224. data/test/db/postgres/mixed_case_test.rb +0 -29
  225. data/test/db/postgres/native_types_test.rb +0 -124
  226. data/test/db/postgres/rake_test.rb +0 -117
  227. data/test/db/postgres/reserved_test.rb +0 -22
  228. data/test/db/postgres/reset_column_information_test.rb +0 -6
  229. data/test/db/postgres/row_locking_test.rb +0 -21
  230. data/test/db/postgres/schema_dump_test.rb +0 -95
  231. data/test/db/postgres/schema_test.rb +0 -115
  232. data/test/db/postgres/simple_test.rb +0 -260
  233. data/test/db/postgres/table_alias_length_test.rb +0 -16
  234. data/test/db/postgres/transaction_test.rb +0 -6
  235. data/test/db/postgres/unit_test.rb +0 -31
  236. data/test/db/postgres_config.rb +0 -10
  237. data/test/db/sqlite3.rb +0 -6
  238. data/test/db/sqlite3/_rails_test_sqlite3.32.out +0 -6274
  239. data/test/db/sqlite3/has_many_though_test.rb +0 -6
  240. data/test/db/sqlite3/rake_test.rb +0 -71
  241. data/test/db/sqlite3/reset_column_information_test.rb +0 -6
  242. data/test/db/sqlite3/schema_dump_test.rb +0 -6
  243. data/test/db/sqlite3/serialize_test.rb +0 -6
  244. data/test/db/sqlite3/simple_test.rb +0 -268
  245. data/test/db/sqlite3/transaction_test.rb +0 -32
  246. data/test/db/sqlite3/type_conversion_test.rb +0 -104
  247. data/test/has_many_through.rb +0 -61
  248. data/test/informix_simple_test.rb +0 -48
  249. data/test/jdbc/db2.rb +0 -36
  250. data/test/jdbc/oracle.rb +0 -34
  251. data/test/jdbc_column_test.rb +0 -23
  252. data/test/jdbc_common.rb +0 -16
  253. data/test/jdbc_connection_test.rb +0 -196
  254. data/test/jndi_callbacks_test.rb +0 -33
  255. data/test/jndi_test.rb +0 -55
  256. data/test/manualTestDatabase.rb +0 -191
  257. data/test/models/add_not_null_column_to_table.rb +0 -9
  258. data/test/models/auto_id.rb +0 -15
  259. data/test/models/binary.rb +0 -18
  260. data/test/models/custom_pk_name.rb +0 -15
  261. data/test/models/data_types.rb +0 -40
  262. data/test/models/entry.rb +0 -41
  263. data/test/models/mixed_case.rb +0 -22
  264. data/test/models/reserved_word.rb +0 -15
  265. data/test/models/rights_and_roles.rb +0 -57
  266. data/test/models/string_id.rb +0 -17
  267. data/test/models/thing.rb +0 -17
  268. data/test/models/topic.rb +0 -32
  269. data/test/models/validates_uniqueness_of_string.rb +0 -19
  270. data/test/rails/mysql.rb +0 -13
  271. data/test/rails/sqlite3/version.rb +0 -6
  272. data/test/rails_stub.rb +0 -31
  273. data/test/rake_test_support.rb +0 -298
  274. data/test/row_locking.rb +0 -102
  275. data/test/schema_dump.rb +0 -182
  276. data/test/serialize.rb +0 -275
  277. data/test/shared_helper.rb +0 -35
  278. data/test/simple.rb +0 -1317
  279. data/test/sybase_jtds_simple_test.rb +0 -28
  280. data/test/sybase_reset_column_information_test.rb +0 -6
  281. data/test/test_helper.rb +0 -304
  282. data/test/transaction.rb +0 -109
data/rakelib/db.rake CHANGED
@@ -1,41 +1,53 @@
1
1
  require File.expand_path('../../test/shared_helper', __FILE__)
2
2
 
3
3
  namespace :db do
4
- desc "Creates the test database for MySQL."
4
+
5
+ desc "Creates the test database for MySQL"
5
6
  task :mysql do
6
- load 'test/db/mysql_config.rb' rescue nil
7
- t = Tempfile.new("mysql")
8
- t.puts <<-SQL
7
+ load 'test/db/mysql_config.rb' # rescue nil
8
+ script = sql_script <<-SQL, 'mysql'
9
9
  DROP DATABASE IF EXISTS `#{MYSQL_CONFIG[:database]}`;
10
10
  CREATE DATABASE `#{MYSQL_CONFIG[:database]}` DEFAULT CHARACTER SET `utf8`;
11
11
  GRANT ALL PRIVILEGES ON `#{MYSQL_CONFIG[:database]}`.* TO #{MYSQL_CONFIG[:username]}@localhost;
12
12
  GRANT ALL PRIVILEGES ON `test\_%`.* TO #{MYSQL_CONFIG[:username]}@localhost;
13
13
  SET PASSWORD FOR #{MYSQL_CONFIG[:username]}@localhost = PASSWORD('#{MYSQL_CONFIG[:password]}');
14
14
  SQL
15
- t.close
16
- at_exit { t.unlink }
17
- password = ""
15
+ params = { '-u' => 'root' }
18
16
  if ENV['DATABASE_YML']
19
17
  require 'yaml'
20
18
  password = YAML.load(File.new(ENV['DATABASE_YML']))["production"]["password"]
21
- password_arg = " --password=#{password}"
19
+ params['--password'] = password
22
20
  end
23
- sh "cat #{t.path} | mysql -u root#{password_arg}", :verbose => false # so password is not echoed
21
+ puts "Creating MySQL (test) database: #{MYSQL_CONFIG[:database]}"
22
+ sh "cat #{script.path} | mysql #{params.to_a.join(' ')}", :verbose => $VERBOSE # so password is not echoed
24
23
  end
25
24
 
26
- desc "Creates the test database for PostgreSQL."
27
- task :postgres do
25
+ desc "Creates the test database for PostgreSQL"
26
+ task :postgresql do
28
27
  fail unless PostgresHelper.have_postgres?
29
- load 'test/db/postgres_config.rb' rescue nil
30
- t = Tempfile.new("psql")
31
- t.puts <<-SQL
28
+ load 'test/db/postgres_config.rb' # rescue nil
29
+ script = sql_script <<-SQL, 'psql'
32
30
  DROP DATABASE IF EXISTS #{POSTGRES_CONFIG[:database]};
33
31
  DROP USER IF EXISTS #{POSTGRES_CONFIG[:username]};
34
32
  CREATE USER #{POSTGRES_CONFIG[:username]} CREATEDB SUPERUSER LOGIN PASSWORD '#{POSTGRES_CONFIG[:password]}';
35
33
  CREATE DATABASE #{POSTGRES_CONFIG[:database]} OWNER #{POSTGRES_CONFIG[:username]};
36
34
  SQL
37
- t.close
38
- at_exit { t.unlink }
39
- sh "cat #{t.path} | psql -U postgres"
35
+ params = { '-U' => ENV['PSQL_USER'] || 'postgres' }
36
+ params['-q'] = nil unless $VERBOSE
37
+ puts "Creating PostgreSQL (test) database: #{POSTGRES_CONFIG[:database]}"
38
+ sh "cat #{script.path} | psql #{params.to_a.join(' ')}", :verbose => $VERBOSE
40
39
  end
40
+ task :postgres => :postgresql
41
+
42
+ private
43
+
44
+ def sql_script(sql_content, name = 'sql_script')
45
+ script = Tempfile.new(name)
46
+ script.puts sql_content
47
+ yield(script) if block_given?
48
+ script.close
49
+ at_exit { script.unlink }
50
+ script
51
+ end
52
+
41
53
  end
@@ -40,11 +40,11 @@ import org.jruby.runtime.builtin.IRubyObject;
40
40
 
41
41
  /**
42
42
  * ::ArJdbc
43
- *
43
+ *
44
44
  * @author kares
45
45
  */
46
46
  public class ArJdbcModule {
47
-
47
+
48
48
  public static RubyModule load(final Ruby runtime) {
49
49
  final RubyModule arJdbc = runtime.getOrCreateModule("ArJdbc");
50
50
  arJdbc.defineAnnotatedMethods( ArJdbcModule.class );
@@ -52,9 +52,9 @@ public class ArJdbcModule {
52
52
  }
53
53
 
54
54
  /**
55
- * Load the Java parts for the given adapter spec module, e.g. to load
55
+ * Load the Java parts for the given adapter spec module, e.g. to load
56
56
  * ArJdbc::MySQL's Java part: <code>ArJdbc.load_java_part :MySQL</code>
57
- *
57
+ *
58
58
  * NOTE: this method is not intended to be called twice for a given adapter !
59
59
  * @param context
60
60
  * @param self
@@ -62,15 +62,15 @@ public class ArJdbcModule {
62
62
  * @return true
63
63
  */
64
64
  @JRubyMethod(name = "load_java_part", meta = true, required = 1, optional = 2)
65
- public static IRubyObject load_java_part(final ThreadContext context,
65
+ public static IRubyObject load_java_part(final ThreadContext context,
66
66
  final IRubyObject self, final IRubyObject[] args) {
67
-
67
+
68
68
  String connectionClass = args.length > 1 ? args[1].toString() : null;
69
69
  String moduleClass = args.length > 2 ? args[2].toString() : null;
70
-
70
+
71
71
  final String moduleName = args[0].toString(); // e.g. 'MySQL'
72
72
  final String packagePrefix = "arjdbc." + moduleName.toLowerCase() + "."; // arjdbc.mysql
73
-
73
+
74
74
  // NOTE: due previous (backwards compatible) conventions there are
75
75
  // 2 things we load, the adapter spec module's Java implemented methods
76
76
  // and a custom JdbcConnection class (both are actually optional) e.g. :
@@ -78,7 +78,7 @@ public class ArJdbcModule {
78
78
  // MySQLModule.load(RubyModule); // 'arjdbc.mysql' package is assumed
79
79
  // MySQLRubyJdbcConnection.createMySQLJdbcConnectionClass(Ruby, RubyClass);
80
80
  //
81
-
81
+
82
82
  String connectionClass2 = null;
83
83
  if (connectionClass == null) {
84
84
  // 'arjdbc.mysql.' + 'MySQL' + 'RubyJdbcConnection'
@@ -89,10 +89,10 @@ public class ArJdbcModule {
89
89
  // 'arjdbc.mysql.' + 'MySQL' + 'Module'
90
90
  moduleClass = packagePrefix + moduleName + "Module";
91
91
  }
92
-
92
+
93
93
  final Ruby runtime = context.getRuntime();
94
94
  final RubyModule arJdbc = runtime.getModule("ArJdbc");
95
-
95
+
96
96
  try {
97
97
  final Class<?> module = Class.forName(moduleClass);
98
98
  // MySQLModule.load( arJdbc ) :
@@ -108,7 +108,7 @@ public class ArJdbcModule {
108
108
  catch (InvocationTargetException e) {
109
109
  throw newNativeException(runtime, e);
110
110
  }
111
-
111
+
112
112
  try {
113
113
  Class<?> connection = null;
114
114
  try {
@@ -136,10 +136,10 @@ public class ArJdbcModule {
136
136
  catch (InvocationTargetException e) {
137
137
  throw newNativeException(runtime, e);
138
138
  }
139
-
139
+
140
140
  return runtime.getTrue();
141
141
  }
142
-
142
+
143
143
  /**
144
144
  * <code>ArJdbc.modules</code>
145
145
  * @param context
@@ -150,26 +150,29 @@ public class ArJdbcModule {
150
150
  public static IRubyObject modules(final ThreadContext context, final IRubyObject self) {
151
151
  final Ruby runtime = context.getRuntime();
152
152
  final RubyModule arJdbc = (RubyModule) self;
153
-
153
+
154
154
  final Collection<String> constants = arJdbc.getConstantNames();
155
155
  final RubyArray modules = runtime.newArray( constants.size() );
156
-
156
+
157
157
  for ( final String name : constants ) {
158
158
  IRubyObject value = arJdbc.getConstant(name, false);
159
159
  // isModule: return false for Ruby Classes
160
160
  if ( value != null && value.isModule() ) {
161
161
  if ( "MissingFunctionalityHelper".equals(name) ) continue;
162
+ if ( "SerializedAttributesHelper".equals(name) ) continue;
163
+ if ( "QuotedPrimaryKeyExtension".equals(name) ) continue;
164
+ if ( "Util".equals(name) ) continue;
162
165
  if ( "Version".equals(name) ) continue;
163
166
  modules.append(value);
164
167
  }
165
168
  }
166
169
  return modules;
167
170
  }
168
-
171
+
169
172
  private static RaiseException newNativeException(final Ruby runtime, final Throwable cause) {
170
173
  RubyClass nativeClass = runtime.getClass(NativeException.CLASS_NAME);
171
174
  NativeException nativeException = new NativeException(runtime, nativeClass, cause);
172
175
  throw new RaiseException(cause, nativeException);
173
176
  }
174
-
177
+
175
178
  }
@@ -25,35 +25,34 @@
25
25
  ***** END LICENSE BLOCK *****/
26
26
  package arjdbc.db2;
27
27
 
28
+ import arjdbc.jdbc.Callable;
28
29
  import arjdbc.jdbc.RubyJdbcConnection;
29
30
 
31
+ import java.sql.Connection;
32
+ import java.sql.PreparedStatement;
33
+ import java.sql.ResultSet;
34
+ import java.sql.SQLException;
35
+ import java.sql.Statement;
36
+
30
37
  import org.jruby.Ruby;
31
38
  import org.jruby.RubyClass;
39
+ import org.jruby.RubyString;
40
+ import org.jruby.anno.JRubyMethod;
32
41
  import org.jruby.runtime.ObjectAllocator;
42
+ import org.jruby.runtime.ThreadContext;
33
43
  import org.jruby.runtime.builtin.IRubyObject;
44
+ import org.jruby.util.ByteList;
34
45
 
35
46
  /**
36
47
  *
37
48
  * @author mikestone
38
49
  */
39
50
  public class DB2RubyJdbcConnection extends RubyJdbcConnection {
40
-
41
- private static final String[] TABLE_TYPES = new String[]{ "TABLE", "VIEW", "SYNONYM", "MATERIALIZED QUERY TABLE", "ALIAS" };
42
51
 
43
52
  protected DB2RubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
44
53
  super(runtime, metaClass);
45
54
  }
46
55
 
47
- @Override
48
- protected String[] getTableTypes() {
49
- return TABLE_TYPES;
50
- }
51
-
52
- @Override
53
- protected boolean databaseSupportsSchemas() {
54
- return true;
55
- }
56
-
57
56
  public static RubyClass createDB2JdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
58
57
  RubyClass clazz = RubyJdbcConnection.getConnectionAdapters(runtime).defineClassUnder("DB2JdbcConnection",
59
58
  jdbcConnection, DB2_JDBCCONNECTION_ALLOCATOR);
@@ -67,4 +66,77 @@ public class DB2RubyJdbcConnection extends RubyJdbcConnection {
67
66
  return new DB2RubyJdbcConnection(runtime, klass);
68
67
  }
69
68
  };
69
+
70
+ @JRubyMethod(name = "select?", required = 1, meta = true, frame = false)
71
+ public static IRubyObject select_p(final ThreadContext context,
72
+ final IRubyObject self, final IRubyObject sql) {
73
+ if ( isValues(sql.convertToString()) ) {
74
+ return context.getRuntime().newBoolean( true );
75
+ }
76
+ return arjdbc.jdbc.RubyJdbcConnection.select_p(context, self, sql);
77
+ }
78
+
79
+ // DB2 supports 'stand-alone' VALUES expressions
80
+ private static final byte[] VALUES = new byte[]{ 'v','a','l','u', 'e', 's' };
81
+
82
+ private static boolean isValues(final RubyString sql) {
83
+ final ByteList sqlBytes = sql.getByteList();
84
+ return startsWithIgnoreCase(sqlBytes, VALUES);
85
+ }
86
+
87
+ private static final String[] TABLE_TYPES = new String[] {
88
+ "TABLE", "VIEW", "SYNONYM", "MATERIALIZED QUERY TABLE", "ALIAS"
89
+ };
90
+
91
+ @Override
92
+ protected String[] getTableTypes() {
93
+ return TABLE_TYPES;
94
+ }
95
+
96
+ @Override
97
+ protected boolean databaseSupportsSchemas() {
98
+ return true;
99
+ }
100
+
101
+ @JRubyMethod(name = {"identity_val_local", "last_insert_id"})
102
+ public IRubyObject identity_val_local(final ThreadContext context)
103
+ throws SQLException {
104
+ return withConnection(context, new Callable<IRubyObject>() {
105
+ public IRubyObject call(final Connection connection) throws SQLException {
106
+ PreparedStatement statement = null; ResultSet genKeys = null;
107
+ try {
108
+ statement = connection.prepareStatement("VALUES IDENTITY_VAL_LOCAL()");
109
+ genKeys = statement.executeQuery();
110
+ return doMapGeneratedKeys(context.getRuntime(), genKeys, true);
111
+ }
112
+ catch (final SQLException e) {
113
+ debugMessage(context, "failed to get generated keys: " + e.getMessage());
114
+ throw e;
115
+ }
116
+ finally { close(genKeys); close(statement); }
117
+ }
118
+ });
119
+ }
120
+
121
+ // NOTE: this is non-sense or DB2 - but it has been originally implemented this way !
122
+ //@JRubyMethod(name = {"identity_val_local", "last_insert_id"}, required = 1)
123
+ private IRubyObject identity_val_local(final ThreadContext context, final IRubyObject table)
124
+ throws SQLException {
125
+ return withConnection(context, new Callable<IRubyObject>() {
126
+ public IRubyObject call(final Connection connection) throws SQLException {
127
+ Statement statement = null; ResultSet genKeys = null;
128
+ try {
129
+ statement = connection.createStatement();
130
+ genKeys = statement.executeQuery("SELECT IDENTITY_VAL_LOCAL() FROM " + table);
131
+ return doMapGeneratedKeys(context.getRuntime(), genKeys, true);
132
+ }
133
+ catch (final SQLException e) {
134
+ debugMessage(context, "failed to get generated keys: " + e.getMessage());
135
+ throw e;
136
+ }
137
+ finally { close(genKeys); close(statement); }
138
+ }
139
+ });
140
+ }
141
+
70
142
  }
@@ -24,29 +24,21 @@
24
24
 
25
25
  package arjdbc.derby;
26
26
 
27
- import java.sql.SQLException;
28
-
29
27
  import static arjdbc.util.QuotingUtils.BYTES_0;
30
28
  import static arjdbc.util.QuotingUtils.BYTES_1;
31
-
32
- import arjdbc.jdbc.RubyJdbcConnection;
29
+ import static arjdbc.util.QuotingUtils.BYTES_SINGLE_Q_x2;
33
30
 
34
31
  import org.jruby.Ruby;
35
32
  import org.jruby.RubyBoolean;
36
33
  import org.jruby.RubyModule;
37
- import org.jruby.RubyObjectAdapter;
38
34
  import org.jruby.RubyString;
39
35
  import org.jruby.anno.JRubyMethod;
40
- import org.jruby.javasupport.JavaEmbedUtils;
41
- import org.jruby.runtime.Block;
42
36
  import org.jruby.runtime.ThreadContext;
43
37
  import org.jruby.runtime.builtin.IRubyObject;
44
38
  import org.jruby.util.ByteList;
45
39
 
46
40
  public class DerbyModule {
47
-
48
- static final RubyObjectAdapter rubyApi = JavaEmbedUtils.newObjectAdapter();
49
-
41
+
50
42
  public static RubyModule load(final RubyModule arJdbc) {
51
43
  RubyModule derby = arJdbc.defineModuleUnder("Derby");
52
44
  derby.defineAnnotatedMethods( DerbyModule.class );
@@ -56,170 +48,189 @@ public class DerbyModule {
56
48
  }
57
49
 
58
50
  public static class Column {
51
+
59
52
  @JRubyMethod(name = "type_cast", required = 1)
60
- public static IRubyObject type_cast(IRubyObject recv, IRubyObject value) {
61
- Ruby runtime = recv.getRuntime();
53
+ public static IRubyObject type_cast(final ThreadContext context,
54
+ final IRubyObject self, final IRubyObject value) {
62
55
 
63
- if (value.isNil() || ((value instanceof RubyString) && value.toString().trim().equalsIgnoreCase("null"))) {
64
- return runtime.getNil();
56
+ if ( value.isNil() ||
57
+ ( (value instanceof RubyString) && value.toString().trim().equalsIgnoreCase("null") ) ) {
58
+ return context.getRuntime().getNil();
65
59
  }
66
60
 
67
- String type = rubyApi.getInstanceVariable(recv, "@type").toString();
61
+ final String type = self.getInstanceVariables().getInstanceVariable("@type").toString();
68
62
 
69
63
  switch (type.charAt(0)) {
70
64
  case 's': //string
71
65
  return value;
72
66
  case 't': //text, timestamp, time
73
- if (type.equals("text")) {
74
- return value;
75
- } else if (type.equals("timestamp")) {
76
- return rubyApi.callMethod(recv.getMetaClass(), "string_to_time", value);
77
- } else { //time
78
- return rubyApi.callMethod(recv.getMetaClass(), "string_to_dummy_time", value);
67
+ if ( type.equals("time") ) {
68
+ return self.getMetaClass().callMethod(context, "string_to_dummy_time", value);
79
69
  }
70
+ if ( type.equals("timestamp") ) {
71
+ return self.getMetaClass().callMethod(context, "string_to_time", value);
72
+ }
73
+ return value; // text
80
74
  case 'i': //integer
81
75
  case 'p': //primary key
82
- if (value.respondsTo("to_i")) {
83
- return rubyApi.callMethod(value, "to_i");
84
- } else {
85
- return runtime.newFixnum(value.isTrue() ? 1 : 0);
76
+ if ( value.respondsTo("to_i") ) {
77
+ return value.callMethod(context, "to_i");
86
78
  }
79
+ return context.getRuntime().newFixnum( value.isTrue() ? 1 : 0 );
87
80
  case 'd': //decimal, datetime, date
88
- if (type.equals("datetime")) {
89
- return rubyApi.callMethod(recv.getMetaClass(), "string_to_time", value);
90
- } else if (type.equals("date")) {
91
- return rubyApi.callMethod(recv.getMetaClass(), "string_to_date", value);
92
- } else {
93
- return rubyApi.callMethod(recv.getMetaClass(), "value_to_decimal", value);
81
+ if ( type.equals("datetime") ) {
82
+ return self.getMetaClass().callMethod(context, "string_to_time", value);
83
+ }
84
+ if ( type.equals("date") ) {
85
+ return self.getMetaClass().callMethod(context, "string_to_date", value);
94
86
  }
87
+ return self.getMetaClass().callMethod(context, "value_to_decimal", value);
95
88
  case 'f': //float
96
- return rubyApi.callMethod(value, "to_f");
89
+ return value.callMethod(context, "to_f");
97
90
  case 'b': //binary, boolean
98
- if (type.equals("binary")) {
99
- return rubyApi.callMethod(recv.getMetaClass(), "binary_to_string", value);
100
- } else {
101
- return rubyApi.callMethod(recv.getMetaClass(), "value_to_boolean", value);
102
- }
91
+ return type.equals("binary") ?
92
+ self.getMetaClass().callMethod(context, "binary_to_string", value) :
93
+ self.getMetaClass().callMethod(context, "value_to_boolean", value) ;
103
94
  }
104
95
  return value;
105
96
  }
97
+
106
98
  }
107
99
 
108
100
  @JRubyMethod(name = "quote", required = 1, optional = 1)
109
- public static IRubyObject quote(final ThreadContext context, final IRubyObject self,
110
- final IRubyObject[] args) {
101
+ public static IRubyObject quote(final ThreadContext context,
102
+ final IRubyObject self, final IRubyObject[] args) {
111
103
  final Ruby runtime = self.getRuntime();
112
104
  IRubyObject value = args[0];
113
105
  if ( args.length > 1 ) {
114
106
  final IRubyObject column = args[1];
115
- final String columnType = column.isNil() ? "" : rubyApi.callMethod(column, "type").toString();
107
+ final String columnType = column.isNil() ? "" : column.callMethod(context, "type").toString();
116
108
  // intercept and change value, maybe, if the column type is :text or :string
117
109
  if ( columnType.equals("text") || columnType.equals("string") ) {
118
- value = make_ruby_string_for_text_column(context, self, runtime, value);
110
+ value = toRubyStringForTextColumn(context, runtime, self, value);
119
111
  }
120
- final String metaClass = value.getMetaClass().getName();
121
112
 
122
113
  if ( value instanceof RubyString ) {
123
114
  if ( columnType.equals("string") ) {
124
- return quote_string_with_surround(runtime, "'", (RubyString) value, "'");
125
- }
126
- else if ( columnType.equals("text") ) {
127
- return quote_string_with_surround(runtime, "CAST('", (RubyString) value, "' AS CLOB)");
115
+ return quoteString(runtime, "'", value, "'");
128
116
  }
129
- else if ( columnType.equals("binary") ) {
130
- return hexquote_string_with_surround(runtime, "CAST(X'", (RubyString) value, "' AS BLOB)");
117
+ if ( columnType.equals("text") ) {
118
+ return quoteString(runtime, "CAST('", value, "' AS CLOB)");
131
119
  }
132
- else if ( columnType.equals("xml") ) {
133
- return quote_string_with_surround(runtime, "XMLPARSE(DOCUMENT '", (RubyString) value, "' PRESERVE WHITESPACE)");
120
+ if ( columnType.equals("binary") ) {
121
+ return quoteStringHex(runtime, "CAST(X'", value, "' AS BLOB)");
134
122
  }
135
- else { // column type :integer or other numeric or date version
136
- return only_digits((RubyString) value) ? value : super_quote(context, self, runtime, value, column);
123
+ if ( columnType.equals("xml") ) {
124
+ return quoteString(runtime, "XMLPARSE(DOCUMENT '", value, "' PRESERVE WHITESPACE)");
137
125
  }
126
+ // column type :integer or other numeric or date version
127
+ return isDigitsOnly(value) ? value : quoteDefault(context, runtime, self, value, column, columnType);
138
128
  }
139
- else if ( metaClass.equals("Float") || metaClass.equals("Fixnum") || metaClass.equals("Bignum") ) {
129
+
130
+ final String metaClass = value.getMetaClass().getName();
131
+ if ( metaClass.equals("Float") || metaClass.equals("Fixnum") || metaClass.equals("Bignum") ) {
140
132
  if ( columnType.equals("string") ) {
141
- return quote_string_with_surround(runtime, "'", RubyString.objAsString(context, value), "'");
133
+ return quoteString(runtime, "'", RubyString.objAsString(context, value), "'");
142
134
  }
143
135
  }
144
136
  }
145
- return super_quote(context, self, runtime, value, runtime.getNil());
137
+ return quoteDefault(context, runtime, self, value, runtime.getNil(), null);
138
+ }
139
+
140
+ private static IRubyObject quoted_date_OR_to_yaml(final ThreadContext context,
141
+ final Ruby runtime, final IRubyObject self, final IRubyObject value) {
142
+
143
+ if ( value.callMethod(context, "acts_like?", runtime.newSymbol("date")).isTrue()
144
+ || value.callMethod(context, "acts_like?", runtime.newSymbol("time")).isTrue() ) {
145
+ return self.callMethod(context, "quoted_date", value);
146
+ }
147
+ else {
148
+ return value.callMethod(context, "to_yaml");
149
+ }
146
150
  }
147
151
 
148
152
  /*
149
- * Derby is not permissive like MySql. Try and send an Integer to a CLOB or VARCHAR column and Derby will vomit.
153
+ * Derby is not permissive like MySql. Try and send an Integer to a CLOB or
154
+ * VARCHAR column and Derby will vomit.
150
155
  * This method turns non stringy things into strings.
151
156
  */
152
- private static IRubyObject make_ruby_string_for_text_column(ThreadContext context, IRubyObject recv, Ruby runtime, IRubyObject value) {
153
- final RubyModule multibyteChars = getMultibyteChars(runtime);
154
- if (value instanceof RubyString || rubyApi.isKindOf(value, multibyteChars) || value.isNil()) {
157
+ private static IRubyObject toRubyStringForTextColumn(
158
+ final ThreadContext context, final Ruby runtime, final IRubyObject self,
159
+ final IRubyObject value) {
160
+
161
+ if ( value instanceof RubyString || value.isNil() || isMultibyteChars(runtime, value) ) {
155
162
  return value;
156
163
  }
157
164
 
158
- String metaClass = value.getMetaClass().getName();
165
+ if ( value instanceof RubyBoolean ) return quoteBoolean(runtime, value);
159
166
 
160
- if (value instanceof RubyBoolean) {
161
- return value.isTrue() ? runtime.newString("1") : runtime.newString("0");
162
- } else if (metaClass.equals("Float") || metaClass.equals("Fixnum") || metaClass.equals("Bignum")) {
167
+ final String className = value.getMetaClass().getName();
168
+ if ( className.equals("Float") || className.equals("Fixnum") || className.equals("Bignum") ) {
163
169
  return RubyString.objAsString(context, value);
164
- } else if (metaClass.equals("BigDecimal")) {
165
- return rubyApi.callMethod(value, "to_s", runtime.newString("F"));
166
- } else {
167
- if (rubyApi.callMethod(value, "acts_like?", runtime.newString("date")).isTrue() || rubyApi.callMethod(value, "acts_like?", runtime.newString("time")).isTrue()) {
168
- return (RubyString)rubyApi.callMethod(recv, "quoted_date", value);
169
- } else {
170
- return (RubyString)rubyApi.callMethod(value, "to_yaml");
171
- }
172
170
  }
171
+ if ( className.equals("BigDecimal") ) {
172
+ return value.callMethod(context, "to_s", runtime.newString("F"));
173
+ }
174
+
175
+ return quoted_date_OR_to_yaml(context, runtime, self, value);
173
176
  }
174
177
 
175
- private final static ByteList NULL = new ByteList("NULL".getBytes());
178
+ private final static ByteList NULL = new ByteList("NULL".getBytes(), false);
179
+
180
+ private static IRubyObject quoteDefault(final ThreadContext context,
181
+ final Ruby runtime, final IRubyObject self,
182
+ final IRubyObject value, final IRubyObject column, final String columnType) {
176
183
 
177
- private static IRubyObject super_quote(ThreadContext context, IRubyObject recv, Ruby runtime, IRubyObject value, IRubyObject col) {
178
- if (value.respondsTo("quoted_id")) {
179
- return rubyApi.callMethod(value, "quoted_id");
184
+ if ( value.respondsTo("quoted_id") ) {
185
+ return value.callMethod(context, "quoted_id");
180
186
  }
181
187
 
182
- String metaClass = value.getMetaClass().getName();
183
-
184
- IRubyObject type = (col.isNil()) ? col : rubyApi.callMethod(col, "type");
185
- final RubyModule multibyteChars = getMultibyteChars(runtime);
186
- if (value instanceof RubyString || rubyApi.isKindOf(value, multibyteChars)) {
187
- RubyString svalue = RubyString.objAsString(context, value);
188
- if (type == runtime.newSymbol("binary") && col.getType().respondsTo("string_to_binary")) {
189
- return quote_string_with_surround(runtime, "'", (RubyString)(rubyApi.callMethod(col.getType(), "string_to_binary", svalue)), "'");
190
- } else if (type == runtime.newSymbol("integer") || type == runtime.newSymbol("float")) {
191
- return RubyString.objAsString(context, ((type == runtime.newSymbol("integer")) ?
192
- rubyApi.callMethod(svalue, "to_i") :
193
- rubyApi.callMethod(svalue, "to_f")));
194
- } else {
195
- return quote_string_with_surround(runtime, "'", svalue, "'");
196
- }
197
- } else if (value.isNil()) {
188
+ if ( value.isNil() ) {
198
189
  return runtime.newString(NULL);
199
- } else if (value instanceof RubyBoolean) {
200
- return (value.isTrue() ?
201
- (type == runtime.newSymbol(":integer")) ? runtime.newString("1") : rubyApi.callMethod(recv, "quoted_true") :
202
- (type == runtime.newSymbol(":integer")) ? runtime.newString("0") : rubyApi.callMethod(recv, "quoted_false"));
203
- } else if (metaClass.equals("Float") || metaClass.equals("Fixnum") || metaClass.equals("Bignum")) {
190
+ }
191
+ if ( value instanceof RubyBoolean ) {
192
+ if ( columnType == (Object) "integer" ) return quoteBoolean(runtime, value);
193
+ return self.callMethod(context, value.isTrue() ? "quoted_true" : "quoted_false");
194
+ }
195
+ if ( value instanceof RubyString || isMultibyteChars(runtime, value) ) {
196
+
197
+ final RubyString strValue = RubyString.objAsString(context, value);
198
+
199
+ if ( columnType == (Object) "binary" && column.getType().respondsTo("string_to_binary") ) {
200
+ IRubyObject str = column.getType().callMethod(context, "string_to_binary", strValue);
201
+ return quoteString(runtime, "'", str, "'");
202
+ }
203
+
204
+ if ( columnType == (Object) "integer" ) {
205
+ return RubyString.objAsString( context, strValue.callMethod(context, "to_i") );
206
+ }
207
+
208
+ if ( columnType == (Object) "float" ) {
209
+ return RubyString.objAsString( context, strValue.callMethod(context, "to_f") );
210
+ }
211
+
212
+ return quoteString(runtime, "'", strValue, "'");
213
+ }
214
+
215
+ final String className = value.getMetaClass().getName();
216
+ if ( className.equals("Float") || className.equals("Fixnum") || className.equals("Bignum") ) {
204
217
  return RubyString.objAsString(context, value);
205
- } else if (metaClass.equals("BigDecimal")) {
206
- return rubyApi.callMethod(value, "to_s", runtime.newString("F"));
207
- } else if (rubyApi.callMethod(value, "acts_like?", runtime.newString("date")).isTrue() || rubyApi.callMethod(value, "acts_like?", runtime.newString("time")).isTrue()) {
208
- return quote_string_with_surround(runtime, "'", (RubyString)(rubyApi.callMethod(recv, "quoted_date", value)), "'");
209
- } else {
210
- return quote_string_with_surround(runtime, "'", (RubyString)(rubyApi.callMethod(value, "to_yaml")), "'");
211
218
  }
219
+ if ( className.equals("BigDecimal") ) {
220
+ return value.callMethod(context, "to_s", runtime.newString("F"));
221
+ }
222
+
223
+ IRubyObject strValue = quoted_date_OR_to_yaml(context, runtime, self, value);
224
+ return quoteString(runtime, "'", strValue, "'");
212
225
  }
213
226
 
214
- private final static ByteList TWO_SINGLE = new ByteList(new byte[]{'\'','\''});
227
+ private static IRubyObject quoteString(final Ruby runtime,
228
+ final String before, final IRubyObject string, final String after) {
215
229
 
216
- private static IRubyObject quote_string_with_surround(final Ruby runtime,
217
- final String before, final RubyString string, final String after) {
218
-
219
- final ByteList input = string.getByteList();
230
+ final ByteList input = ((RubyString) string).getByteList();
220
231
  final ByteList output = new ByteList(before.getBytes(), input.getEncoding());
221
232
  final byte[] inputBytes = input.unsafeBytes();
222
-
233
+
223
234
  for(int i = input.getBegin(); i< input.getBegin() + input.getRealSize(); i++) {
224
235
  switch ( inputBytes[i] ) {
225
236
  case '\'': output.append(inputBytes[i]); // FALLTHROUGH
@@ -234,13 +245,13 @@ public class DerbyModule {
234
245
 
235
246
  private final static byte[] HEX = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
236
247
 
237
- private static IRubyObject hexquote_string_with_surround(final Ruby runtime,
238
- final String before, final RubyString string, final String after) {
239
-
240
- final ByteList input = string.getByteList();
248
+ private static IRubyObject quoteStringHex(final Ruby runtime,
249
+ final String before, final IRubyObject string, final String after) {
250
+
251
+ final ByteList input = ((RubyString) string).getByteList();
241
252
  final ByteList output = new ByteList(before.getBytes());
242
253
  final byte[] inputBytes = input.unsafeBytes();
243
-
254
+
244
255
  int written = 0;
245
256
  for(int i = input.getBegin(); i< input.getBegin() + input.getRealSize(); i++) {
246
257
  byte b1 = inputBytes[i];
@@ -259,8 +270,8 @@ public class DerbyModule {
259
270
  return RubyString.newStringShared(runtime, output);
260
271
  }
261
272
 
262
- private static boolean only_digits(final RubyString string) {
263
- final ByteList input = string.getByteList();
273
+ private static boolean isDigitsOnly(final IRubyObject string) {
274
+ final ByteList input = ((RubyString) string).getByteList();
264
275
  final byte[] inputBytes = input.unsafeBytes();
265
276
  for ( int i = input.getBegin(); i< input.getBegin() + input.getRealSize(); i++ ) {
266
277
  if ( inputBytes[i] < '0' || inputBytes[i] > '9' ) {
@@ -270,10 +281,14 @@ public class DerbyModule {
270
281
  return true;
271
282
  }
272
283
 
284
+ private static boolean isMultibyteChars(final Ruby runtime, final IRubyObject value) {
285
+ return getMultibyteChars(runtime).isInstance(value);
286
+ }
287
+
273
288
  @JRubyMethod(name = "quote_string", required = 1)
274
289
  public static IRubyObject quote_string(final IRubyObject self, IRubyObject string) {
275
290
  ByteList bytes = ((RubyString) string).getByteList();
276
-
291
+
277
292
  boolean replacement = false;
278
293
  for ( int i = 0; i < bytes.length(); i++ ) {
279
294
  switch ( bytes.get(i) ) {
@@ -286,52 +301,34 @@ public class DerbyModule {
286
301
  replacement = true;
287
302
  }
288
303
 
289
- bytes.replace(i, 1, TWO_SINGLE);
304
+ bytes.replace(i, 1, BYTES_SINGLE_Q_x2);
290
305
  i += 1;
291
306
  }
292
-
307
+
293
308
  return replacement ? RubyString.newStringShared(self.getRuntime(), bytes) : string;
294
309
  }
295
310
 
296
311
  @JRubyMethod(name = "quoted_true", required = 0, frame = false)
297
312
  public static IRubyObject quoted_true(
298
- final ThreadContext context,
313
+ final ThreadContext context,
299
314
  final IRubyObject self) {
300
315
  return RubyString.newString(context.getRuntime(), BYTES_1);
301
316
  }
302
-
317
+
303
318
  @JRubyMethod(name = "quoted_false", required = 0, frame = false)
304
319
  public static IRubyObject quoted_false(
305
- final ThreadContext context,
320
+ final ThreadContext context,
306
321
  final IRubyObject self) {
307
322
  return RubyString.newString(context.getRuntime(), BYTES_0);
308
323
  }
309
324
 
310
- @JRubyMethod(name = "_execute", required = 1, optional = 1)
311
- public static IRubyObject _execute(final ThreadContext context, final IRubyObject self, final IRubyObject[] args)
312
- throws SQLException {
313
- final IRubyObject sql = args[0];
314
-
315
- String sqlStr = sql.toString().trim();
316
- if ( sqlStr.charAt(0) == '(' ) sqlStr = sqlStr.substring(1).trim();
317
- sqlStr = sqlStr.substring( 0, Math.min(6, sqlStr.length()) ).toLowerCase();
318
-
319
- final RubyJdbcConnection connection = (RubyJdbcConnection) rubyApi.getInstanceVariable(self, "@connection");
320
-
321
- if (sqlStr.startsWith("insert")) {
322
- return connection.execute_insert(context, sql);
323
- }
324
- else if (sqlStr.startsWith("select") || sqlStr.startsWith("show") || sqlStr.startsWith("values")) {
325
- return connection.execute_query_raw(context, sql, Block.NULL_BLOCK);
326
- }
327
- else {
328
- return connection.execute_update(context, sql);
329
- }
325
+ private static RubyString quoteBoolean(final Ruby runtime, final IRubyObject value) {
326
+ return value.isTrue() ? runtime.newString(BYTES_1) : runtime.newString(BYTES_0);
330
327
  }
331
-
328
+
332
329
  private static RubyModule getMultibyteChars(final Ruby runtime) {
333
330
  return (RubyModule) ((RubyModule) runtime.getModule("ActiveSupport").
334
331
  getConstant("Multibyte")).getConstantAt("Chars");
335
332
  }
336
-
333
+
337
334
  }