ibm_db 3.0.3 → 5.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (477) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +10 -0
  3. data/LICENSE +1 -1
  4. data/ParameterizedQueries README +6 -6
  5. data/README +38 -55
  6. data/ext/Makefile +266 -0
  7. data/ext/extconf.rb +34 -3
  8. data/ext/gil_release_version +3 -0
  9. data/ext/ibm_db.c +106 -111
  10. data/ext/ibm_db.o +0 -0
  11. data/ext/ibm_db.so +0 -0
  12. data/ext/mkmf.log +103 -0
  13. data/ext/ruby_ibm_db_cli.o +0 -0
  14. data/ext/unicode_support_version +3 -0
  15. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +937 -562
  16. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +4 -1
  17. data/lib/clidriver.tar.gz +0 -0
  18. data/lib/clidriver/bin/db2cli +0 -0
  19. data/lib/clidriver/bin/db2diag +0 -0
  20. data/lib/clidriver/bin/db2drdat +0 -0
  21. data/lib/clidriver/bin/db2dsdcfgfill +0 -0
  22. data/lib/clidriver/bin/db2ldcfg +0 -0
  23. data/lib/clidriver/bin/db2lddrg +0 -0
  24. data/lib/clidriver/bin/db2level +0 -0
  25. data/lib/clidriver/bin/db2support +0 -0
  26. data/lib/clidriver/bin/db2trc +0 -0
  27. data/lib/clidriver/bnd/db2ajgrt.bnd +0 -0
  28. data/lib/clidriver/bnd/db2cli.bnd +0 -0
  29. data/lib/clidriver/bnd/db2cli.lst +4 -0
  30. data/lib/clidriver/bnd/db2clipk.bnd +0 -0
  31. data/lib/clidriver/bnd/db2clist.bnd +0 -0
  32. data/lib/clidriver/bnd/db2spcdb.bnd +0 -0
  33. data/lib/clidriver/cfg/DigiCertGlobalRootCA.arm +22 -0
  34. data/lib/clidriver/cfg/db2cli.ini.sample +16 -0
  35. data/lib/clidriver/cfg/db2dsdriver.cfg.sample +50 -0
  36. data/lib/clidriver/cfg/db2dsdriver.xsd +216 -0
  37. data/lib/clidriver/cfgcache/conlic.bin +0 -0
  38. data/lib/clidriver/conv/alt/04370923.cnv +0 -0
  39. data/lib/clidriver/conv/alt/08500923.cnv +0 -0
  40. data/lib/clidriver/conv/alt/08501252.cnv +0 -0
  41. data/lib/clidriver/conv/alt/08600923.cnv +0 -0
  42. data/lib/clidriver/conv/alt/08630923.cnv +0 -0
  43. data/lib/clidriver/conv/alt/09230437.cnv +0 -0
  44. data/lib/clidriver/conv/alt/09230850.cnv +0 -0
  45. data/lib/clidriver/conv/alt/09230860.cnv +0 -0
  46. data/lib/clidriver/conv/alt/09231043.cnv +0 -0
  47. data/lib/clidriver/conv/alt/09231051.cnv +0 -0
  48. data/lib/clidriver/conv/alt/09231114.cnv +0 -0
  49. data/lib/clidriver/conv/alt/09231208.cnv +0 -0
  50. data/lib/clidriver/conv/alt/09231252.cnv +0 -0
  51. data/lib/clidriver/conv/alt/09231275.cnv +0 -0
  52. data/lib/clidriver/conv/alt/09241252.cnv +0 -0
  53. data/lib/clidriver/conv/alt/09370950.cnv +0 -0
  54. data/lib/clidriver/conv/alt/10430923.cnv +0 -0
  55. data/lib/clidriver/conv/alt/10510923.cnv +0 -0
  56. data/lib/clidriver/conv/alt/11140923.cnv +0 -0
  57. data/lib/clidriver/conv/alt/12080923.cnv +0 -0
  58. data/lib/clidriver/conv/alt/12520850.cnv +0 -0
  59. data/lib/clidriver/conv/alt/12520923.cnv +0 -0
  60. data/lib/clidriver/conv/alt/12750923.cnv +0 -0
  61. data/lib/clidriver/conv/alt/1388ucs2.cnv +0 -0
  62. data/lib/clidriver/conv/alt/IBM00850.ucs +0 -0
  63. data/lib/clidriver/conv/alt/IBM00923.ucs +0 -0
  64. data/lib/clidriver/conv/alt/IBM01252.ucs +0 -0
  65. data/lib/clidriver/conv/ms/0930ucs2.cnv +0 -0
  66. data/lib/clidriver/conv/ms/0939ucs2.cnv +0 -0
  67. data/lib/clidriver/conv/ms/0943ucs2.cnv +0 -0
  68. data/lib/clidriver/conv/ms/0954ucs2.cnv +0 -0
  69. data/lib/clidriver/conv/ms/1390ucs2.cnv +0 -0
  70. data/lib/clidriver/conv/ms/1399ucs2.cnv +0 -0
  71. data/lib/clidriver/conv/ms/5039ucs2.cnv +0 -0
  72. data/lib/clidriver/conv/ms/ucs20943.cnv +0 -0
  73. data/lib/clidriver/include/sql.h +3149 -0
  74. data/lib/clidriver/include/sqlca.h +119 -0
  75. data/lib/clidriver/include/sqlcli.h +1042 -0
  76. data/lib/clidriver/include/sqlcli1.h +1963 -0
  77. data/lib/clidriver/include/sqlda.h +303 -0
  78. data/lib/clidriver/include/sqlenv.h +7389 -0
  79. data/lib/clidriver/include/sqlext.h +2189 -0
  80. data/lib/clidriver/include/sqlstate.h +1397 -0
  81. data/lib/clidriver/include/sqlsystm.h +119 -0
  82. data/lib/clidriver/include/sqltypes.h +22 -0
  83. data/lib/clidriver/include/sqlucode.h +22 -0
  84. data/lib/clidriver/include/sqlunx.h +24 -0
  85. data/lib/clidriver/lib/icc/C/icc/icclib/ICCSIG.txt +23 -0
  86. data/lib/clidriver/lib/icc/C/icc/icclib/libicclib084.so +0 -0
  87. data/lib/clidriver/lib/icc/N/icc/icclib/ICCSIG.txt +23 -0
  88. data/lib/clidriver/lib/icc/N/icc/icclib/libicclib085.so +0 -0
  89. data/lib/clidriver/lib/icc/libgsk8cms_64.so +0 -0
  90. data/lib/clidriver/lib/icc/libgsk8dbfl_64.so +0 -0
  91. data/lib/clidriver/lib/icc/libgsk8iccs_64.so +0 -0
  92. data/lib/clidriver/lib/icc/libgsk8kicc_64.so +0 -0
  93. data/lib/clidriver/lib/icc/libgsk8km_64.so +0 -0
  94. data/lib/clidriver/lib/icc/libgsk8ssl_64.so +0 -0
  95. data/lib/clidriver/lib/icc/libgsk8sys_64.so +0 -0
  96. data/lib/clidriver/lib/icc/libgsk8valn_64.so +0 -0
  97. data/lib/clidriver/lib/libDB2xml4c.so +1 -0
  98. data/lib/clidriver/lib/libDB2xml4c.so.58 +1 -0
  99. data/lib/clidriver/lib/libDB2xml4c.so.58.0 +0 -0
  100. data/lib/clidriver/lib/libdb2.so +1 -0
  101. data/lib/clidriver/lib/libdb2.so.1 +0 -0
  102. data/lib/clidriver/lib/libdb2clixml4c.so +1 -0
  103. data/lib/clidriver/lib/libdb2clixml4c.so.1 +0 -0
  104. data/lib/clidriver/license/UNIX/odbc_LI_cs +278 -0
  105. data/lib/clidriver/license/UNIX/odbc_LI_de +364 -0
  106. data/lib/clidriver/license/UNIX/odbc_LI_el +294 -0
  107. data/lib/clidriver/license/UNIX/odbc_LI_en +752 -0
  108. data/lib/clidriver/license/UNIX/odbc_LI_es +338 -0
  109. data/lib/clidriver/license/UNIX/odbc_LI_fr +396 -0
  110. data/lib/clidriver/license/UNIX/odbc_LI_in +270 -0
  111. data/lib/clidriver/license/UNIX/odbc_LI_it +316 -0
  112. data/lib/clidriver/license/UNIX/odbc_LI_ja +246 -0
  113. data/lib/clidriver/license/UNIX/odbc_LI_ko +240 -0
  114. data/lib/clidriver/license/UNIX/odbc_LI_lt +302 -0
  115. data/lib/clidriver/license/UNIX/odbc_LI_pl +292 -0
  116. data/lib/clidriver/license/UNIX/odbc_LI_pt +314 -0
  117. data/lib/clidriver/license/UNIX/odbc_LI_ru +296 -0
  118. data/lib/clidriver/license/UNIX/odbc_LI_sl +278 -0
  119. data/lib/clidriver/license/UNIX/odbc_LI_tr +296 -0
  120. data/lib/clidriver/license/UNIX/odbc_LI_zh +310 -0
  121. data/lib/clidriver/license/UNIX/odbc_LI_zh_TW +310 -0
  122. data/lib/clidriver/license/odbc_REDIST.txt +128 -0
  123. data/lib/clidriver/license/odbc_notices.txt +444 -0
  124. data/lib/clidriver/msg/en_US.iso88591/db2adm.mo +0 -0
  125. data/lib/clidriver/msg/en_US.iso88591/db2admh.mo +0 -0
  126. data/lib/clidriver/msg/en_US.iso88591/db2caem.mo +0 -0
  127. data/lib/clidriver/msg/en_US.iso88591/db2cklog.mo +0 -0
  128. data/lib/clidriver/msg/en_US.iso88591/db2cli.mo +0 -0
  129. data/lib/clidriver/msg/en_US.iso88591/db2clia1.lst +35 -0
  130. data/lib/clidriver/msg/en_US.iso88591/db2clias.lst +21 -0
  131. data/lib/clidriver/msg/en_US.iso88591/db2clih.mo +0 -0
  132. data/lib/clidriver/msg/en_US.iso88591/db2clit.mo +0 -0
  133. data/lib/clidriver/msg/en_US.iso88591/db2clp.mo +0 -0
  134. data/lib/clidriver/msg/en_US.iso88591/db2clp2.mo +0 -0
  135. data/lib/clidriver/msg/en_US.iso88591/db2diag.mo +0 -0
  136. data/lib/clidriver/msg/en_US.iso88591/db2fodc.mo +0 -0
  137. data/lib/clidriver/msg/en_US.iso88591/db2sql.mo +0 -0
  138. data/lib/clidriver/msg/en_US.iso88591/db2sqlh.mo +0 -0
  139. data/lib/clidriver/msg/en_US.iso88591/db2stt.mo +0 -0
  140. data/lib/clidriver/msg/en_US.iso88591/db2supp.mo +0 -0
  141. data/lib/clidriver/security64/plugin/IBM/client/IBMIAMauth.so +0 -0
  142. data/lib/clidriver/security64/plugin/IBM/client/IBMkrb5.so +0 -0
  143. data/test/active_record/connection_adapters/fake_adapter.rb +8 -5
  144. data/test/cases/adapter_test.rb +148 -58
  145. data/test/cases/adapters/mysql2/active_schema_test.rb +193 -0
  146. data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -0
  147. data/test/cases/adapters/mysql2/boolean_test.rb +100 -0
  148. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -0
  149. data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -0
  150. data/test/cases/adapters/mysql2/connection_test.rb +210 -0
  151. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -0
  152. data/test/cases/adapters/mysql2/enum_test.rb +26 -0
  153. data/test/cases/adapters/mysql2/explain_test.rb +21 -0
  154. data/test/cases/adapters/mysql2/json_test.rb +195 -0
  155. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -0
  156. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
  157. data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -0
  158. data/test/cases/adapters/mysql2/schema_test.rb +126 -0
  159. data/test/cases/adapters/mysql2/sp_test.rb +36 -0
  160. data/test/cases/adapters/mysql2/sql_types_test.rb +14 -0
  161. data/test/cases/adapters/mysql2/table_options_test.rb +42 -0
  162. data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -0
  163. data/test/cases/adapters/postgresql/active_schema_test.rb +98 -0
  164. data/test/cases/adapters/postgresql/array_test.rb +339 -0
  165. data/test/cases/adapters/postgresql/bit_string_test.rb +82 -0
  166. data/test/cases/adapters/postgresql/bytea_test.rb +134 -0
  167. data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -0
  168. data/test/cases/adapters/postgresql/change_schema_test.rb +38 -0
  169. data/test/cases/adapters/postgresql/cidr_test.rb +25 -0
  170. data/test/cases/adapters/postgresql/citext_test.rb +78 -0
  171. data/test/cases/adapters/postgresql/collation_test.rb +53 -0
  172. data/test/cases/adapters/postgresql/composite_test.rb +132 -0
  173. data/test/cases/adapters/postgresql/connection_test.rb +257 -0
  174. data/test/cases/adapters/postgresql/datatype_test.rb +92 -0
  175. data/test/cases/adapters/postgresql/domain_test.rb +47 -0
  176. data/test/cases/adapters/postgresql/enum_test.rb +91 -0
  177. data/test/cases/adapters/postgresql/explain_test.rb +20 -0
  178. data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -0
  179. data/test/cases/adapters/postgresql/full_text_test.rb +44 -0
  180. data/test/cases/adapters/postgresql/geometric_test.rb +378 -0
  181. data/test/cases/adapters/postgresql/hstore_test.rb +382 -0
  182. data/test/cases/adapters/postgresql/infinity_test.rb +69 -0
  183. data/test/cases/adapters/postgresql/integer_test.rb +25 -0
  184. data/test/cases/adapters/postgresql/json_test.rb +237 -0
  185. data/test/cases/adapters/postgresql/ltree_test.rb +53 -0
  186. data/test/cases/adapters/postgresql/money_test.rb +96 -0
  187. data/test/cases/adapters/postgresql/network_test.rb +94 -0
  188. data/test/cases/adapters/postgresql/numbers_test.rb +49 -0
  189. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -0
  190. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
  191. data/test/cases/adapters/postgresql/quoting_test.rb +44 -0
  192. data/test/cases/adapters/postgresql/range_test.rb +343 -0
  193. data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -0
  194. data/test/cases/adapters/postgresql/rename_table_test.rb +34 -0
  195. data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -0
  196. data/test/cases/adapters/postgresql/schema_test.rb +597 -0
  197. data/test/cases/adapters/postgresql/serial_test.rb +154 -0
  198. data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -0
  199. data/test/cases/adapters/postgresql/timestamp_test.rb +90 -0
  200. data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -0
  201. data/test/cases/adapters/postgresql/utils_test.rb +62 -0
  202. data/test/cases/adapters/postgresql/uuid_test.rb +294 -0
  203. data/test/cases/adapters/postgresql/xml_test.rb +54 -0
  204. data/test/cases/adapters/sqlite3/collation_test.rb +53 -0
  205. data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -0
  206. data/test/cases/adapters/sqlite3/explain_test.rb +21 -0
  207. data/test/cases/adapters/sqlite3/quoting_test.rb +101 -0
  208. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -0
  209. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
  210. data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -0
  211. data/test/cases/aggregations_test.rb +11 -1
  212. data/test/cases/ar_schema_test.rb +35 -50
  213. data/test/cases/associations/association_scope_test.rb +1 -6
  214. data/test/cases/associations/belongs_to_associations_test.rb +122 -10
  215. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -0
  216. data/test/cases/associations/callbacks_test.rb +5 -7
  217. data/test/cases/associations/cascaded_eager_loading_test.rb +1 -1
  218. data/test/cases/associations/eager_load_nested_include_test.rb +1 -3
  219. data/test/cases/associations/eager_test.rb +176 -73
  220. data/test/cases/associations/extension_test.rb +7 -2
  221. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +104 -32
  222. data/test/cases/associations/has_many_associations_test.rb +382 -43
  223. data/test/cases/associations/has_many_through_associations_test.rb +108 -41
  224. data/test/cases/associations/has_one_associations_test.rb +105 -8
  225. data/test/cases/associations/has_one_through_associations_test.rb +6 -3
  226. data/test/cases/associations/inner_join_association_test.rb +3 -3
  227. data/test/cases/associations/inverse_associations_test.rb +51 -11
  228. data/test/cases/associations/join_model_test.rb +59 -36
  229. data/test/cases/associations/left_outer_join_association_test.rb +88 -0
  230. data/test/cases/associations/nested_through_associations_test.rb +2 -2
  231. data/test/cases/associations/required_test.rb +25 -5
  232. data/test/cases/associations_test.rb +39 -34
  233. data/test/cases/attribute_decorators_test.rb +9 -8
  234. data/test/cases/attribute_methods/read_test.rb +5 -5
  235. data/test/cases/attribute_methods_test.rb +97 -40
  236. data/test/cases/attribute_set_test.rb +74 -4
  237. data/test/cases/attribute_test.rb +84 -18
  238. data/test/cases/attributes_test.rb +151 -34
  239. data/test/cases/autosave_association_test.rb +149 -36
  240. data/test/cases/base_test.rb +311 -236
  241. data/test/cases/batches_test.rb +299 -22
  242. data/test/cases/binary_test.rb +2 -10
  243. data/test/cases/bind_parameter_test.rb +76 -66
  244. data/test/cases/cache_key_test.rb +26 -0
  245. data/test/cases/calculations_test.rb +167 -15
  246. data/test/cases/callbacks_test.rb +161 -68
  247. data/test/cases/coders/json_test.rb +15 -0
  248. data/test/cases/collection_cache_key_test.rb +115 -0
  249. data/test/cases/column_definition_test.rb +26 -57
  250. data/test/cases/comment_test.rb +145 -0
  251. data/test/cases/connection_adapters/adapter_leasing_test.rb +5 -3
  252. data/test/cases/connection_adapters/connection_handler_test.rb +128 -21
  253. data/test/cases/connection_adapters/connection_specification_test.rb +1 -1
  254. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +0 -38
  255. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -1
  256. data/test/cases/connection_adapters/schema_cache_test.rb +8 -3
  257. data/test/cases/connection_adapters/type_lookup_test.rb +15 -7
  258. data/test/cases/connection_management_test.rb +46 -56
  259. data/test/cases/connection_pool_test.rb +195 -20
  260. data/test/cases/connection_specification/resolver_test.rb +15 -0
  261. data/test/cases/counter_cache_test.rb +10 -5
  262. data/test/cases/custom_locking_test.rb +1 -1
  263. data/test/cases/database_statements_test.rb +18 -3
  264. data/test/cases/{invalid_date_test.rb → date_test.rb} +13 -1
  265. data/test/cases/date_time_precision_test.rb +107 -0
  266. data/test/cases/defaults_test.rb +85 -89
  267. data/test/cases/dirty_test.rb +32 -44
  268. data/test/cases/disconnected_test.rb +4 -2
  269. data/test/cases/enum_test.rb +178 -24
  270. data/test/cases/errors_test.rb +16 -0
  271. data/test/cases/explain_test.rb +32 -21
  272. data/test/cases/finder_test.rb +279 -151
  273. data/test/cases/fixture_set/file_test.rb +18 -0
  274. data/test/cases/fixtures_test.rb +123 -32
  275. data/test/cases/forbidden_attributes_protection_test.rb +69 -3
  276. data/test/cases/helper.rb +10 -16
  277. data/test/cases/hot_compatibility_test.rb +89 -1
  278. data/test/cases/inheritance_test.rb +284 -53
  279. data/test/cases/integration_test.rb +23 -7
  280. data/test/cases/invalid_connection_test.rb +4 -2
  281. data/test/cases/invertible_migration_test.rb +124 -32
  282. data/test/cases/json_serialization_test.rb +11 -2
  283. data/test/cases/locking_test.rb +22 -6
  284. data/test/cases/log_subscriber_test.rb +106 -17
  285. data/test/cases/migration/change_schema_test.rb +118 -132
  286. data/test/cases/migration/change_table_test.rb +34 -2
  287. data/test/cases/migration/column_attributes_test.rb +7 -23
  288. data/test/cases/migration/column_positioning_test.rb +8 -8
  289. data/test/cases/migration/columns_test.rb +17 -11
  290. data/test/cases/migration/command_recorder_test.rb +47 -2
  291. data/test/cases/migration/compatibility_test.rb +118 -0
  292. data/test/cases/migration/create_join_table_test.rb +21 -12
  293. data/test/cases/migration/foreign_key_test.rb +68 -66
  294. data/test/cases/migration/index_test.rb +14 -12
  295. data/test/cases/migration/logger_test.rb +1 -1
  296. data/test/cases/migration/pending_migrations_test.rb +0 -1
  297. data/test/cases/migration/references_foreign_key_test.rb +114 -107
  298. data/test/cases/migration/references_index_test.rb +4 -4
  299. data/test/cases/migration/references_statements_test.rb +26 -6
  300. data/test/cases/migration/rename_table_test.rb +25 -25
  301. data/test/cases/migration_test.rb +279 -81
  302. data/test/cases/migrator_test.rb +91 -8
  303. data/test/cases/mixin_test.rb +0 -2
  304. data/test/cases/modules_test.rb +3 -4
  305. data/test/cases/multiparameter_attributes_test.rb +24 -2
  306. data/test/cases/multiple_db_test.rb +18 -11
  307. data/test/cases/nested_attributes_test.rb +74 -33
  308. data/test/cases/persistence_test.rb +102 -10
  309. data/test/cases/pooled_connections_test.rb +3 -3
  310. data/test/cases/primary_keys_test.rb +170 -31
  311. data/test/cases/query_cache_test.rb +216 -96
  312. data/test/cases/quoting_test.rb +65 -19
  313. data/test/cases/readonly_test.rb +2 -1
  314. data/test/cases/reflection_test.rb +77 -22
  315. data/test/cases/relation/delegation_test.rb +3 -8
  316. data/test/cases/relation/merging_test.rb +10 -14
  317. data/test/cases/relation/mutation_test.rb +42 -24
  318. data/test/cases/relation/or_test.rb +92 -0
  319. data/test/cases/relation/predicate_builder_test.rb +4 -2
  320. data/test/cases/relation/record_fetch_warning_test.rb +40 -0
  321. data/test/cases/relation/where_chain_test.rb +23 -99
  322. data/test/cases/relation/where_clause_test.rb +182 -0
  323. data/test/cases/relation/where_test.rb +45 -23
  324. data/test/cases/relation_test.rb +89 -58
  325. data/test/cases/relations_test.rb +249 -38
  326. data/test/cases/result_test.rb +10 -0
  327. data/test/cases/sanitize_test.rb +108 -15
  328. data/test/cases/schema_dumper_test.rb +119 -125
  329. data/test/cases/schema_loading_test.rb +52 -0
  330. data/test/cases/scoping/default_scoping_test.rb +113 -39
  331. data/test/cases/scoping/named_scoping_test.rb +46 -9
  332. data/test/cases/scoping/relation_scoping_test.rb +47 -4
  333. data/test/cases/secure_token_test.rb +32 -0
  334. data/test/cases/serialization_test.rb +1 -1
  335. data/test/cases/serialized_attribute_test.rb +93 -6
  336. data/test/cases/statement_cache_test.rb +38 -0
  337. data/test/cases/store_test.rb +2 -1
  338. data/test/cases/suppressor_test.rb +63 -0
  339. data/test/cases/tasks/database_tasks_test.rb +74 -8
  340. data/test/cases/tasks/mysql_rake_test.rb +143 -109
  341. data/test/cases/tasks/postgresql_rake_test.rb +71 -12
  342. data/test/cases/tasks/sqlite_rake_test.rb +30 -3
  343. data/test/cases/test_case.rb +28 -20
  344. data/test/cases/test_fixtures_test.rb +36 -0
  345. data/test/cases/time_precision_test.rb +103 -0
  346. data/test/cases/timestamp_test.rb +47 -14
  347. data/test/cases/touch_later_test.rb +121 -0
  348. data/test/cases/transaction_callbacks_test.rb +128 -62
  349. data/test/cases/transaction_isolation_test.rb +2 -2
  350. data/test/cases/transactions_test.rb +61 -43
  351. data/test/cases/type/adapter_specific_registry_test.rb +133 -0
  352. data/test/cases/type/date_time_test.rb +14 -0
  353. data/test/cases/type/integer_test.rb +2 -96
  354. data/test/cases/type/string_test.rb +0 -14
  355. data/test/cases/type_test.rb +39 -0
  356. data/test/cases/types_test.rb +1 -118
  357. data/test/cases/unconnected_test.rb +1 -1
  358. data/test/cases/validations/absence_validation_test.rb +73 -0
  359. data/test/cases/validations/association_validation_test.rb +13 -2
  360. data/test/cases/validations/i18n_validation_test.rb +6 -10
  361. data/test/cases/validations/length_validation_test.rb +62 -30
  362. data/test/cases/validations/presence_validation_test.rb +36 -1
  363. data/test/cases/validations/uniqueness_validation_test.rb +150 -36
  364. data/test/cases/validations_repair_helper.rb +2 -6
  365. data/test/cases/validations_test.rb +36 -7
  366. data/test/cases/view_test.rb +108 -5
  367. data/test/cases/yaml_serialization_test.rb +36 -1
  368. data/test/config.example.yml +97 -0
  369. data/test/fixtures/bad_posts.yml +9 -0
  370. data/test/fixtures/books.yml +20 -0
  371. data/test/fixtures/content.yml +3 -0
  372. data/test/fixtures/content_positions.yml +3 -0
  373. data/test/fixtures/dead_parrots.yml +5 -0
  374. data/test/fixtures/live_parrots.yml +4 -0
  375. data/test/fixtures/naked/yml/parrots.yml +2 -0
  376. data/test/fixtures/naked/yml/trees.yml +3 -0
  377. data/test/fixtures/nodes.yml +29 -0
  378. data/test/fixtures/other_comments.yml +6 -0
  379. data/test/fixtures/other_dogs.yml +2 -0
  380. data/test/fixtures/other_posts.yml +7 -0
  381. data/test/fixtures/price_estimates.yml +10 -1
  382. data/test/fixtures/trees.yml +3 -0
  383. data/test/migrations/10_urban/9_add_expressions.rb +1 -1
  384. data/test/migrations/decimal/1_give_me_big_numbers.rb +1 -1
  385. data/test/migrations/magic/1_currencies_have_symbols.rb +1 -1
  386. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -2
  387. data/test/migrations/missing/1_people_have_last_names.rb +2 -2
  388. data/test/migrations/missing/3_we_need_reminders.rb +2 -2
  389. data/test/migrations/missing/4_innocent_jointable.rb +2 -2
  390. data/test/migrations/rename/1_we_need_things.rb +2 -2
  391. data/test/migrations/rename/2_rename_things.rb +2 -2
  392. data/test/migrations/to_copy/1_people_have_hobbies.rb +1 -1
  393. data/test/migrations/to_copy/2_people_have_descriptions.rb +1 -1
  394. data/test/migrations/to_copy2/1_create_articles.rb +1 -1
  395. data/test/migrations/to_copy2/2_create_comments.rb +1 -1
  396. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +1 -1
  397. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +1 -1
  398. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +1 -1
  399. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +1 -1
  400. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +1 -1
  401. data/test/migrations/valid/1_valid_people_have_last_names.rb +1 -1
  402. data/test/migrations/valid/2_we_need_reminders.rb +2 -2
  403. data/test/migrations/valid/3_innocent_jointable.rb +2 -2
  404. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +1 -1
  405. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -2
  406. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +2 -2
  407. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +1 -1
  408. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +1 -1
  409. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +1 -1
  410. data/test/migrations/version_check/20131219224947_migration_version_check.rb +1 -1
  411. data/test/models/admin/randomly_named_c1.rb +6 -2
  412. data/test/models/aircraft.rb +1 -0
  413. data/test/models/author.rb +4 -7
  414. data/test/models/bird.rb +1 -1
  415. data/test/models/book.rb +5 -0
  416. data/test/models/bulb.rb +2 -1
  417. data/test/models/car.rb +3 -0
  418. data/test/models/cat.rb +10 -0
  419. data/test/models/chef.rb +5 -0
  420. data/test/models/club.rb +2 -0
  421. data/test/models/comment.rb +17 -5
  422. data/test/models/company.rb +7 -2
  423. data/test/models/company_in_module.rb +1 -1
  424. data/test/models/contact.rb +1 -1
  425. data/test/models/content.rb +40 -0
  426. data/test/models/customer.rb +8 -2
  427. data/test/models/developer.rb +22 -0
  428. data/test/models/face.rb +1 -1
  429. data/test/models/guitar.rb +4 -0
  430. data/test/models/hotel.rb +5 -0
  431. data/test/models/member.rb +1 -0
  432. data/test/models/member_detail.rb +4 -3
  433. data/test/models/mentor.rb +3 -0
  434. data/test/models/mocktail_designer.rb +2 -0
  435. data/test/models/node.rb +5 -0
  436. data/test/models/non_primary_key.rb +2 -0
  437. data/test/models/notification.rb +3 -0
  438. data/test/models/other_dog.rb +5 -0
  439. data/test/models/owner.rb +4 -1
  440. data/test/models/parrot.rb +6 -7
  441. data/test/models/person.rb +0 -1
  442. data/test/models/pet.rb +3 -0
  443. data/test/models/pet_treasure.rb +6 -0
  444. data/test/models/pirate.rb +3 -3
  445. data/test/models/post.rb +18 -9
  446. data/test/models/project.rb +11 -0
  447. data/test/models/randomly_named_c1.rb +1 -1
  448. data/test/models/recipe.rb +3 -0
  449. data/test/models/ship.rb +8 -2
  450. data/test/models/tag.rb +6 -0
  451. data/test/models/topic.rb +2 -8
  452. data/test/models/tree.rb +3 -0
  453. data/test/models/tuning_peg.rb +4 -0
  454. data/test/models/user.rb +14 -0
  455. data/test/models/uuid_item.rb +6 -0
  456. data/test/schema/mysql2_specific_schema.rb +33 -23
  457. data/test/schema/oracle_specific_schema.rb +1 -4
  458. data/test/schema/postgresql_specific_schema.rb +36 -124
  459. data/test/schema/schema.rb +183 -64
  460. data/test/schema/schema.rb.original +1057 -0
  461. data/test/schema/sqlite_specific_schema.rb +1 -5
  462. data/test/support/connection.rb +1 -0
  463. data/test/support/schema_dumping_helper.rb +1 -1
  464. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
  465. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
  466. metadata +271 -26
  467. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +0 -26
  468. data/test/cases/attribute_methods/serialization_test.rb +0 -29
  469. data/test/cases/migration/change_schema_test - Copy.rb +0 -448
  470. data/test/cases/migration/foreign_key_test - Changed.rb +0 -325
  471. data/test/cases/migration/table_and_index_test.rb +0 -24
  472. data/test/cases/relation/where_test2.rb +0 -36
  473. data/test/cases/type/decimal_test.rb +0 -51
  474. data/test/cases/type/unsigned_integer_test.rb +0 -18
  475. data/test/cases/xml_serialization_test.rb +0 -457
  476. data/test/fixtures/naked/csv/accounts.csv +0 -1
  477. data/test/schema/mysql_specific_schema.rb +0 -70
Binary file
Binary file
@@ -0,0 +1,103 @@
1
+ gil_release_version is:
2
+ /* begin */
3
+ 1: #ifndef GIL_RELEASE_VERSION
4
+ 2: #define GIL_RELEASE_VERSION
5
+ 3: #endif
6
+ /* end */
7
+
8
+ unicode_support_version is:
9
+ /* begin */
10
+ 1: #ifndef UNICODE_SUPPORT_VERSION
11
+ 2: #define UNICODE_SUPPORT_VERSION
12
+ 3: #endif
13
+ /* end */
14
+
15
+ have_library: checking for SQLConnect() in -ldb2... -------------------- yes
16
+
17
+ "gcc -o conftest -I/home/rakhil/ruby_exe/include/ruby-2.6.0/x86_64-linux -I/home/rakhil/ruby_exe/include/ruby-2.6.0/ruby/backward -I/home/rakhil/ruby_exe/include/ruby-2.6.0 -I. -I/home/rakhil/clidriver/include -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable conftest.c -L. -L/home/rakhil/ruby_exe/lib -Wl,-rpath,/home/rakhil/ruby_exe/lib -L/home/rakhil/clidriver/lib -Wl,-rpath,/home/rakhil/clidriver/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-rpath,/home/rakhil/ruby_exe/lib -L/home/rakhil/ruby_exe/lib -lruby-static -lz -lpthread -lrt -lrt -ldl -lcrypt -lm -lm -lc"
18
+ /home/rakhil/ruby_exe/lib/ruby/2.6.0/mkmf.rb:406: warning: Insecure world writable dir /work/rakhil in PATH, mode 040777
19
+ checked program was:
20
+ /* begin */
21
+ 1: #include "ruby.h"
22
+ 2:
23
+ 3: int main(int argc, char **argv)
24
+ 4: {
25
+ 5: return 0;
26
+ 6: }
27
+ /* end */
28
+
29
+ "gcc -o conftest -I/home/rakhil/ruby_exe/include/ruby-2.6.0/x86_64-linux -I/home/rakhil/ruby_exe/include/ruby-2.6.0/ruby/backward -I/home/rakhil/ruby_exe/include/ruby-2.6.0 -I. -I/home/rakhil/clidriver/include -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable conftest.c -L. -L/home/rakhil/ruby_exe/lib -Wl,-rpath,/home/rakhil/ruby_exe/lib -L/home/rakhil/clidriver/lib -Wl,-rpath,/home/rakhil/clidriver/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-rpath,/home/rakhil/ruby_exe/lib -L/home/rakhil/ruby_exe/lib -lruby-static -lz -lpthread -lrt -lrt -ldl -lcrypt -lm -ldb2 -lm -lc"
30
+ conftest.c: In function 't':
31
+ conftest.c:14:57: error: 'SQLConnect' undeclared (first use in this function)
32
+ int t(void) { void ((*volatile p)()); p = (void ((*)()))SQLConnect; return !p; }
33
+ ^~~~~~~~~~
34
+ conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in
35
+ conftest.c: At top level:
36
+ cc1: warning: unrecognized command line option '-Wno-self-assign'
37
+ cc1: warning: unrecognized command line option '-Wno-parentheses-equality'
38
+ cc1: warning: unrecognized command line option '-Wno-constant-logical-operand'
39
+ cc1: warning: unrecognized command line option '-Wno-cast-function-type'
40
+ checked program was:
41
+ /* begin */
42
+ 1: #include "ruby.h"
43
+ 2:
44
+ 3: /*top*/
45
+ 4: extern int t(void);
46
+ 5: int main(int argc, char **argv)
47
+ 6: {
48
+ 7: if (argc > 1000000) {
49
+ 8: int (* volatile tp)(void)=(int (*)(void))&t;
50
+ 9: printf("%d", (*tp)());
51
+ 10: }
52
+ 11:
53
+ 12: return 0;
54
+ 13: }
55
+ 14: int t(void) { void ((*volatile p)()); p = (void ((*)()))SQLConnect; return !p; }
56
+ /* end */
57
+
58
+ "gcc -o conftest -I/home/rakhil/ruby_exe/include/ruby-2.6.0/x86_64-linux -I/home/rakhil/ruby_exe/include/ruby-2.6.0/ruby/backward -I/home/rakhil/ruby_exe/include/ruby-2.6.0 -I. -I/home/rakhil/clidriver/include -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable conftest.c -L. -L/home/rakhil/ruby_exe/lib -Wl,-rpath,/home/rakhil/ruby_exe/lib -L/home/rakhil/clidriver/lib -Wl,-rpath,/home/rakhil/clidriver/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-rpath,/home/rakhil/ruby_exe/lib -L/home/rakhil/ruby_exe/lib -lruby-static -lz -lpthread -lrt -lrt -ldl -lcrypt -lm -ldb2 -lm -lc"
59
+ checked program was:
60
+ /* begin */
61
+ 1: #include "ruby.h"
62
+ 2:
63
+ 3: /*top*/
64
+ 4: extern int t(void);
65
+ 5: int main(int argc, char **argv)
66
+ 6: {
67
+ 7: if (argc > 1000000) {
68
+ 8: int (* volatile tp)(void)=(int (*)(void))&t;
69
+ 9: printf("%d", (*tp)());
70
+ 10: }
71
+ 11:
72
+ 12: return 0;
73
+ 13: }
74
+ 14: extern void SQLConnect();
75
+ 15: int t(void) { SQLConnect(); return 0; }
76
+ /* end */
77
+
78
+ --------------------
79
+
80
+ have_header: checking for gil_release_version... -------------------- yes
81
+
82
+ "gcc -E -I/home/rakhil/ruby_exe/include/ruby-2.6.0/x86_64-linux -I/home/rakhil/ruby_exe/include/ruby-2.6.0/ruby/backward -I/home/rakhil/ruby_exe/include/ruby-2.6.0 -I. -I/home/rakhil/clidriver/include -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable conftest.c -o conftest.i"
83
+ checked program was:
84
+ /* begin */
85
+ 1: #include "ruby.h"
86
+ 2:
87
+ 3: #include <gil_release_version>
88
+ /* end */
89
+
90
+ --------------------
91
+
92
+ have_header: checking for unicode_support_version... -------------------- yes
93
+
94
+ "gcc -E -I/home/rakhil/ruby_exe/include/ruby-2.6.0/x86_64-linux -I/home/rakhil/ruby_exe/include/ruby-2.6.0/ruby/backward -I/home/rakhil/ruby_exe/include/ruby-2.6.0 -I. -I/home/rakhil/clidriver/include -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable conftest.c -o conftest.i"
95
+ checked program was:
96
+ /* begin */
97
+ 1: #include "ruby.h"
98
+ 2:
99
+ 3: #include <unicode_support_version>
100
+ /* end */
101
+
102
+ --------------------
103
+
Binary file
@@ -0,0 +1,3 @@
1
+ #ifndef UNICODE_SUPPORT_VERSION
2
+ #define UNICODE_SUPPORT_VERSION
3
+ #endif
@@ -1,7 +1,7 @@
1
1
  # +----------------------------------------------------------------------+
2
2
  # | Licensed Materials - Property of IBM |
3
3
  # | |
4
- # | (C) Copyright IBM Corporation 2006- 2016 |
4
+ # | (C) Copyright IBM Corporation 2006- 2018 |
5
5
  # +----------------------------------------------------------------------+
6
6
  # | Authors: Antonio Cangiano <cangiano@ca.ibm.com> |
7
7
  # | : Mario Ds Briggs <mario.briggs@in.ibm.com> |
@@ -9,115 +9,163 @@
9
9
  # | : Arvind Gupta <arvindgu@in.ibm.com> |
10
10
  # +----------------------------------------------------------------------+
11
11
 
12
+
12
13
  require 'active_record/connection_adapters/abstract_adapter'
13
- require 'arel/visitors/bind_visitor'
14
+ require 'arel/visitors/visitor'
14
15
  require 'active_support/core_ext/string/strip'
16
+ require 'active_record/type'
17
+ require 'active_record/connection_adapters/sql_type_metadata'
18
+
19
+
20
+
21
+ module CallChain
22
+ def self.caller_method(depth=1)
23
+ parse_caller(caller(depth+1).first).last
24
+ end
25
+
26
+ private
27
+
28
+ # Copied from ActionMailer
29
+ def self.parse_caller(at)
30
+ if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
31
+ file = Regexp.last_match[1]
32
+ line = Regexp.last_match[2].to_i
33
+ method = Regexp.last_match[3]
34
+ [file, line, method]
35
+ end
36
+ end
37
+ end
38
+
15
39
 
16
40
  module ActiveRecord
17
- class Relation
18
- def insert(values)
19
- primary_key_value = nil
20
41
 
21
- if primary_key && Hash === values
22
- primary_key_value = values[values.keys.find { |k|
23
- k.name == primary_key
24
- }]
25
42
 
26
- if !primary_key_value && connection.prefetch_primary_key?(klass.table_name)
27
- primary_key_value = connection.next_sequence_value(klass.sequence_name)
28
- values[klass.arel_table[klass.primary_key]] = primary_key_value
29
- end
43
+ class SchemaMigration < ActiveRecord::Base
44
+ class << self
45
+ def create_table
46
+ #puts "Calling method : " << CallChain.caller_method << "\n"
47
+ #puts "Calling method for create_table(): " << String(caller(start=1, length=nil) )
48
+ unless table_exists?
49
+ version_options = connection.internal_string_options_for_primary_key
50
+
51
+ connection.create_table(table_name,id:false) do |t|
52
+ t.string :version, version_options
53
+ end
30
54
  end
55
+ end
56
+ end
57
+ end
58
+
59
+
60
+
61
+ class Relation
31
62
 
32
- im = arel.create_insert
33
- im.into @table
63
+ def insert(values)
64
+ primary_key_value = nil
34
65
 
35
- conn = @klass.connection
66
+ if primary_key && Hash === values
67
+ primary_key_value = values[values.keys.find { |k|
68
+ k.name == primary_key
69
+ }]
36
70
 
37
- substitutes = values.sort_by { |arel_attr,_| arel_attr.name }
38
- binds = substitutes.map do |arel_attr, value|
39
- [@klass.columns_hash[arel_attr.name], value]
40
- end
71
+ if !primary_key_value && connection.prefetch_primary_key?(klass.table_name)
72
+ primary_key_value = connection.next_sequence_value(klass.sequence_name)
73
+ values[klass.arel_table[klass.primary_key]] = primary_key_value
74
+ end
75
+ end
41
76
 
42
- substitutes.each_with_index do |tuple, i|
43
- tuple[1] = conn.substitute_at(binds[i][0], i)
44
- end
77
+ im = arel.create_insert
78
+ im.into @table
45
79
 
46
- if values.empty? # empty insert
47
- im.values = Arel.sql(connection.empty_insert_statement_value(klass.primary_key))
48
- else
49
- im.insert substitutes
50
- end
80
+ conn = @klass.connection
81
+
82
+ substitutes = values.sort_by { |arel_attr,_| arel_attr.name }
83
+ binds = substitutes.map do |arel_attr, value|
84
+ [@klass.columns_hash[arel_attr.name], value]
85
+ end
86
+
87
+ #substitutes.each_with_index do |tuple, i|
88
+ # tuple[1] = conn.substitute_at(binds[i][0], i)
89
+ #end
90
+
91
+ substitutes, binds = substitute_values values
51
92
 
52
- conn.insert(
53
- im,
54
- 'SQL',
55
- primary_key,
56
- primary_key_value,
57
- nil,
58
- binds)
59
- end
60
- end
61
93
 
62
- class Base
94
+ if values.empty? # empty insert
95
+ im.values = Arel.sql(connection.empty_insert_statement_value(klass.primary_key))
96
+ else
97
+ im.insert substitutes
98
+ end
99
+ conn.insert(
100
+ im,
101
+ 'SQL',
102
+ primary_key,
103
+ primary_key_value,
104
+ nil,
105
+ binds)
106
+ end
107
+ end
108
+
109
+
110
+
111
+ class Base
63
112
  # Method required to handle LOBs and XML fields.
64
113
  # An after save callback checks if a marker has been inserted through
65
114
  # the insert or update, and then proceeds to update that record with
66
115
  # the actual large object through a prepared statement (param binding).
67
116
  after_save :handle_lobs
68
117
  def handle_lobs()
69
- if self.class.connection.kind_of?(ConnectionAdapters::IBM_DBAdapter)
70
- # Checks that the insert or update had at least a BLOB, CLOB or XML field
71
- self.class.connection.sql.each do |clob_sql|
72
- if clob_sql =~ /BLOB\('(.*)'\)/i ||
73
- clob_sql =~ /@@@IBMTEXT@@@/i ||
74
- clob_sql =~ /@@@IBMXML@@@/i ||
75
- clob_sql =~ /@@@IBMBINARY@@@/i
76
- update_query = "UPDATE #{self.class.table_name} SET ("
77
- counter = 0
78
- values = []
79
- params = []
80
- # Selects only binary, text and xml columns
81
- self.class.columns.select{|col| col.sql_type.to_s =~ /blob|binary|clob|text|xml/i
82
- }.each do |col|
83
- # Adds the selected columns to the query
84
- if counter == 0
85
- update_query << "#{col.name}"
86
- else
87
- update_query << ",#{col.name}"
88
- end
89
-
90
- # Add a '?' for the parameter or a NULL if the value is nil or empty
91
- # (except for a CLOB field where '' can be a value)
92
- if self[col.name].nil? ||
93
- self[col.name] == {} ||
94
- self[col.name] == [] ||
95
- (self[col.name] == '' && !(col.sql_type.to_s =~ /text|clob/i))
96
- params << 'NULL'
97
- else
98
- if (col.cast_type.is_a?(::ActiveRecord::Type::Serialized))
99
- values << YAML.dump(self[col.name])
100
- else
101
- values << self[col.name]
102
- end
103
- params << '?'
104
- end
105
- counter += 1
106
- end
107
- # no subsequent update is required if no relevant columns are found
108
- next if counter == 0
109
-
110
- update_query << ") = "
111
- # IBM_DB accepts 'SET (column) = NULL' but not (NULL),
112
- # therefore the sql needs to be changed for a single NULL field.
113
- if params.size==1 && params[0] == 'NULL'
114
- update_query << "NULL"
115
- else
116
- update_query << "(" + params.join(',') + ")"
117
- end
118
+ if self.class.connection.kind_of?(ConnectionAdapters::IBM_DBAdapter)
119
+ # Checks that the insert or update had at least a BLOB, CLOB or XML field
120
+ self.class.connection.sql.each do |clob_sql|
121
+ if clob_sql =~ /BLOB\('(.*)'\)/i ||
122
+ clob_sql =~ /@@@IBMTEXT@@@/i ||
123
+ clob_sql =~ /@@@IBMXML@@@/i ||
124
+ clob_sql =~ /@@@IBMBINARY@@@/i
125
+ update_query = "UPDATE #{self.class.table_name} SET ("
126
+ counter = 0
127
+ values = []
128
+ params = []
129
+ # Selects only binary, text and xml columns
130
+ self.class.columns.select{|col| col.sql_type.to_s =~ /blob|binary|clob|text|xml/i }.each do |col|
131
+
132
+ if counter == 0
133
+ update_query << "#{col.name}"
134
+ else
135
+ update_query << ",#{col.name}"
136
+ end
137
+
138
+ # Add a '?' for the parameter or a NULL if the value is nil or empty
139
+ # (except for a CLOB field where '' can be a value)
140
+ if self[col.name].nil? ||
141
+ self[col.name] == {} ||
142
+ self[col.name] == [] ||
143
+ (self[col.name] == '' && !(col.sql_type.to_s =~ /text|clob/i))
144
+ params << 'NULL'
145
+ else
146
+ if (col.cast_type.is_a?(::ActiveRecord::Type::Serialized))
147
+ values << YAML.dump(self[col.name])
148
+ else
149
+ values << self[col.name]
150
+ end
151
+ params << '?'
152
+ end
153
+ counter += 1
154
+ end
155
+ # no subsequent update is required if no relevant columns are found
156
+ next if counter == 0
157
+
158
+ update_query << ") = "
159
+ # IBM_DB accepts 'SET (column) = NULL' but not (NULL),
160
+ # therefore the sql needs to be changed for a single NULL field.
161
+ if params.size==1 && params[0] == 'NULL'
162
+ update_query << "NULL"
163
+ else
164
+ update_query << "(" + params.join(',') + ")"
165
+ end
118
166
 
119
- update_query << " WHERE #{self.class.primary_key} = ?"
120
- values << self[self.class.primary_key.downcase]
167
+ update_query << " WHERE #{self.class.primary_key} = ?"
168
+ values << self[self.class.primary_key.downcase]
121
169
 
122
170
  begin
123
171
  unless stmt = IBM_DB.prepare(self.class.connection.connection, update_query)
@@ -148,6 +196,7 @@ module ActiveRecord
148
196
  end # handle_lobs
149
197
  private :handle_lobs
150
198
 
199
+
151
200
  # Establishes a connection to a specified database using the credentials provided
152
201
  # with the +config+ argument. All the ActiveRecord objects will use this connection
153
202
  def self.ibm_db_connection(config)
@@ -159,17 +208,17 @@ module ActiveRecord
159
208
  raise LoadError, "Failed to load IBM_DB Ruby driver."
160
209
  end
161
210
 
162
- if( config.has_key?(:parameterized) && config[:parameterized] == true )
163
- require 'active_record/connection_adapters/ibm_db_pstmt'
164
- end
211
+ #if( config.has_key?(:parameterized) && config[:parameterized] == true )
212
+ # require 'active_record/connection_adapters/ibm_db_pstmt'
213
+ # end
165
214
 
166
215
  # Check if class TableDefinition responds to indexes method to determine if we are on AR 3 or AR 4.
167
216
  # This is a interim hack ti ensure backward compatibility. To remove as we move out of AR 3 support or have a better way to determine which version of AR being run against.
168
- checkClass = ActiveRecord::ConnectionAdapters::TableDefinition.new(nil)
217
+ checkClass = ActiveRecord::ConnectionAdapters::TableDefinition.new(self,nil)
169
218
  if(checkClass.respond_to?(:indexes))
170
219
  isAr3 = false
171
220
  else
172
- isAr3 = true
221
+ isAr3= true
173
222
  end
174
223
  # Converts all +config+ keys to symbols
175
224
  config = config.symbolize_keys
@@ -252,7 +301,6 @@ module ActiveRecord
252
301
  conn_string << "SECURITY=#{config[:security]};" if config.has_key?(:security)
253
302
  conn_string << "AUTHENTICATION=#{config[:authentication]};" if config.has_key?(:authentication)
254
303
  conn_string << "CONNECTTIMEOUT=#{config[:timeout]};" if config.has_key?(:timeout)
255
-
256
304
  connection = IBM_DB.connect( conn_string, '', '', conn_options, set_quoted_literal_replacement )
257
305
  else
258
306
  # No host implies a local catalog-based connection: +database+ represents catalog alias
@@ -278,40 +326,144 @@ module ActiveRecord
278
326
  end
279
327
  end # class Base
280
328
 
329
+
330
+
281
331
  module ConnectionAdapters
332
+ class Column
333
+ def self.binary_to_string(value)
334
+ # Returns a string removing the eventual BLOB scalar function
335
+ value.to_s.gsub(/"SYSIBM"."BLOB"\('(.*)'\)/i,'\1')
336
+ end
337
+ end
338
+
339
+ module Quoting
340
+ def lookup_cast_type_from_column(column) # :nodoc:
341
+ lookup_cast_type(column.sql_type_metadata)
342
+ end
343
+ end
344
+
345
+ module Savepoints
346
+ def create_savepoint(name = current_savepoint_name)
347
+ execute("SAVEPOINT #{name} ON ROLLBACK RETAIN CURSORS")
348
+ end
349
+ end
350
+
351
+
352
+ module ColumnDumper
353
+ def prepare_column_options(column)
354
+ spec = {}
355
+
356
+ if limit = schema_limit(column)
357
+ spec[:limit] = limit
358
+ end
359
+
360
+ if precision = schema_precision(column)
361
+ spec[:precision] = precision
362
+ end
363
+
364
+ if scale = schema_scale(column)
365
+ spec[:scale] = scale
366
+ end
367
+
368
+ default = schema_default(column) if column.has_default?
369
+ spec[:default] = default unless default.nil?
370
+
371
+ spec[:null] = 'false' unless column.null
372
+
373
+ if collation = schema_collation(column)
374
+ spec[:collation] = collation
375
+ end
376
+
377
+ spec[:comment] = column.comment.inspect if column.comment.present?
378
+
379
+ spec
380
+ end
381
+
382
+
383
+ def schema_limit(column)
384
+ limit = column.limit unless column.bigint?
385
+ #limit.inspect if limit && limit != native_database_types[column.type][:limit]
386
+
387
+ limit.inspect if limit && limit != native_database_types[column.type.to_sym][:limit]
388
+
389
+ end
390
+
391
+ =begin
392
+ def column_spec_for_primary_key(column)
393
+ if column.bigint?
394
+ spec = { id: :bigint.inspect }
395
+ spec[:default] = schema_default(column) || 'nil' unless column.auto_increment?
396
+ else
397
+ #spec = super
398
+ end
399
+ #spec[:unsigned] = 'true' if column.unsigned?
400
+ #spec
401
+ ""
402
+ end
403
+ =end
404
+
405
+ end
406
+
282
407
  module SchemaStatements
283
- def create_table_definition(name, temporary, options,as = nil)
408
+
409
+ def internal_string_options_for_primary_key # :nodoc:
410
+ { primary_key: true}
411
+ { version_options: "PRIMARY KEY NOT NULL"}
412
+ end
413
+
414
+ def drop_table(table_name,options={})
415
+ execute("DROP TABLE #{quote_table_name(table_name)}", options)
416
+ #execute("DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}"
417
+ end
418
+
419
+ =begin
420
+ def create_table_definition(name, temporary, options,as = nil)
284
421
  TableDefinition.new self, name, temporary, options
285
422
  end
423
+ =end
424
+ def create_table_definition(*args, **options)
425
+ TableDefinition.new(self, *args, **options)
426
+ end
286
427
 
287
- def remove_foreign_key(from_table, options_or_to_table = {})
288
- return unless supports_foreign_keys?
428
+ def remove_foreign_key(from_table, options_or_to_table = {})
429
+ return unless supports_foreign_keys?
289
430
 
290
- if options_or_to_table.is_a?(Hash)
291
- options = options_or_to_table
292
- else
293
- options = { column: foreign_key_column_for(options_or_to_table) }
294
- end
295
-
296
- fk_name_to_delete = options.fetch(:name) do
297
- fk_to_delete = foreign_keys(@servertype.set_case(from_table)).detect {|fk| "#{@servertype.set_case(fk.column)}" == "#{servertype.set_case(options[:column])}"}
298
-
299
- if fk_to_delete
300
- fk_to_delete.name
301
- else
302
- raise ArgumentError, "Table '#{from_table}' has no foreign key on column '#{options[:column]}'"
303
- end
304
- end
305
-
306
- at = create_alter_table from_table
307
- at.drop_foreign_key fk_name_to_delete
431
+ if options_or_to_table.is_a?(Hash)
432
+ options = options_or_to_table
433
+ else
434
+ options = { column: foreign_key_column_for(options_or_to_table) }
435
+ end
436
+
437
+ fk_name_to_delete = options.fetch(:name) do
438
+ fk_to_delete = foreign_keys(@servertype.set_case(from_table)).detect {|fk| "#{@servertype.set_case(fk.column)}" == "#{servertype.set_case(options[:column])}"}
439
+
440
+ if fk_to_delete
441
+ fk_to_delete.name
442
+ else
443
+ raise ArgumentError, "Table '#{from_table}' has no foreign key on column '#{options[:column]}'"
444
+ end
445
+ end
446
+
447
+ at = create_alter_table from_table
448
+ at.drop_foreign_key fk_name_to_delete
308
449
 
309
- execute schema_creation.accept(at)
310
- end
311
- end
450
+ execute schema_creation.accept(at)
451
+ end
452
+ end #end of Module SchemaStatements
312
453
 
313
- class IBM_DBColumn < Column
314
-
454
+
455
+ #class IBM_DBColumn < Column
456
+ class IBM_DBColumn < ConnectionAdapters::Column # :nodoc:
457
+ # delegate :precision, :scale, :limit, :type, :sql_type, to: :sql_type_metadata, allow_nil: true
458
+
459
+ def initialize(*)
460
+ super
461
+ end
462
+
463
+ #def initialize(column_name, column_default_value, sqltype_metadata, column_nullable, table_name, default_function, collation, comment)
464
+ #super(column_name, column_default_value, sqltype_metadata, column_nullable, table_name)
465
+ #end
466
+
315
467
  # Casts value (which is a String) to an appropriate instance
316
468
  =begin
317
469
  def type_cast(value)
@@ -321,239 +473,234 @@ module ActiveRecord
321
473
  super
322
474
  end
323
475
  =end
324
- # Used to convert from BLOBs to Strings
325
- def self.binary_to_string(value)
326
- # Returns a string removing the eventual BLOB scalar function
327
- value.to_s.gsub(/"SYSIBM"."BLOB"\('(.*)'\)/i,'\1')
328
- end
329
476
 
330
- private
331
- # Mapping IBM data servers SQL datatypes to Ruby data types
332
- def simplified_type(field_type)
333
- case field_type
334
- # if +field_type+ contains 'for bit data' handle it as a binary
335
- when /for bit data/i
336
- :binary
337
- when /smallint/i
338
- :boolean
339
- when /int|serial/i
340
- :integer
341
- when /decimal|numeric|decfloat/i
342
- :decimal
343
- when /float|double|real/i
344
- :float
345
- when /timestamp|datetime/i
346
- :timestamp
347
- when /time/i
348
- :time
349
- when /date/i
350
- :date
351
- when /vargraphic/i
352
- :vargraphic
353
- when /graphic/i
354
- :graphic
355
- when /clob|text/i
356
- :text
357
- when /xml/i
358
- :xml
359
- when /blob|binary/i
360
- :binary
361
- when /char/i
362
- :string
363
- when /boolean/i
364
- :boolean
365
- when /rowid/i # rowid is a supported datatype on z/OS and i/5
366
- :rowid
367
- end
368
- end # method simplified_type
477
+ # Used to convert from BLOBs to Strings
478
+ def self.binary_to_string(value)
479
+ # Returns a string removing the eventual BLOB scalar function
480
+ value.to_s.gsub(/"SYSIBM"."BLOB"\('(.*)'\)/i,'\1')
481
+ end
482
+
369
483
  end #class IBM_DBColumn
370
484
 
371
- class Table
372
-
373
- #Method to parse the passed arguments and create the ColumnDefinition object of the specified type
374
- def ibm_parse_column_attributes_args(type, *args)
375
- options = {}
376
- if args.last.is_a?(Hash)
377
- options = args.delete_at(args.length-1)
378
- end
379
- args.each do | name |
380
- column name,type.to_sym,options
381
- end # end args.each
382
- end
383
- private :ibm_parse_column_attributes_args
384
485
 
385
- #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type xml
386
- #This method is different as compared to def char (sql is being issued explicitly
387
- #as compared to def char where method column(which will generate the sql is being called)
388
- #in order to handle the DEFAULT and NULL option for the native XML datatype
389
- def xml(*args )
390
- options = {}
391
- if args.last.is_a?(Hash)
392
- options = args.delete_at(args.length-1)
393
- end
394
- sql_segment = "ALTER TABLE #{@base.quote_table_name(@table_name)} ADD COLUMN "
395
- args.each do | name |
396
- sql = sql_segment + " #{@base.quote_column_name(name)} xml"
397
- @base.execute(sql,"add_xml_column")
398
- end
399
- return self
400
- end
486
+ module ColumnMethods
487
+
488
+ def primary_key(name, type = :primary_key, **options)
489
+ column(name, type, options.merge(primary_key: true))
490
+ end
491
+
492
+ ##class Table
493
+ class Table < ActiveRecord::ConnectionAdapters::Table
494
+ include ColumnMethods
495
+
496
+ #Method to parse the passed arguments and create the ColumnDefinition object of the specified type
497
+ def ibm_parse_column_attributes_args(type, *args)
498
+ options = {}
499
+ if args.last.is_a?(Hash)
500
+ options = args.delete_at(args.length-1)
501
+ end
502
+ args.each do | name |
503
+ column name,type.to_sym,options
504
+ end # end args.each
505
+ end
506
+ private :ibm_parse_column_attributes_args
507
+
508
+ #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type xml
509
+ #This method is different as compared to def char (sql is being issued explicitly
510
+ #as compared to def char where method column(which will generate the sql is being called)
511
+ #in order to handle the DEFAULT and NULL option for the native XML datatype
512
+ def xml(*args )
513
+ options = {}
514
+ if args.last.is_a?(Hash)
515
+ options = args.delete_at(args.length-1)
516
+ end
517
+ sql_segment = "ALTER TABLE #{@base.quote_table_name(@table_name)} ADD COLUMN "
518
+ args.each do | name |
519
+ sql = sql_segment + " #{@base.quote_column_name(name)} xml"
520
+ @base.execute(sql,"add_xml_column")
521
+ end
522
+ return self
523
+ end
401
524
 
402
- #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type double
403
- def double(*args)
404
- ibm_parse_column_attributes_args('double',*args)
405
- return self
406
- end
525
+ #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type double
526
+ def double(*args)
527
+ ibm_parse_column_attributes_args('double',*args)
528
+ return self
529
+ end
407
530
 
408
- #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type decfloat
409
- def decfloat(*args)
410
- ibm_parse_column_attributes_args('decfloat',*args)
411
- return self
412
- end
531
+ #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type decfloat
532
+ def decfloat(*args)
533
+ ibm_parse_column_attributes_args('decfloat',*args)
534
+ return self
535
+ end
413
536
 
414
- def graphic(*args)
415
- ibm_parse_column_attributes_args('graphic',*args)
416
- return self
417
- end
537
+ def graphic(*args)
538
+ ibm_parse_column_attributes_args('graphic',*args)
539
+ return self
540
+ end
418
541
 
419
- def vargraphic(*args)
420
- ibm_parse_column_attributes_args('vargraphic',*args)
421
- return self
422
- end
542
+ def vargraphic(*args)
543
+ ibm_parse_column_attributes_args('vargraphic',*args)
544
+ return self
545
+ end
423
546
 
424
- def bigint(*args)
425
- ibm_parse_column_attributes_args('bigint',*args)
426
- return self
427
- end
547
+ def bigint(*args)
548
+ ibm_parse_column_attributes_args('bigint',*args)
549
+ return self
550
+ end
428
551
 
429
- #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type char [character]
430
- def char(*args)
431
- ibm_parse_column_attributes_args('char',*args)
432
- return self
433
- end
434
- alias_method :character, :char
435
- end
552
+ #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type char [character]
553
+ def char(*args)
554
+ ibm_parse_column_attributes_args('char',*args)
555
+ return self
556
+ end
557
+ alias_method :character, :char
558
+ end
436
559
 
437
- class TableDefinition
560
+ #class TableDefinition
561
+ class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
562
+ include ColumnMethods
438
563
 
439
- def initialize(base, name=nil, temporary=nil, options=nil)
440
- if(self.respond_to?(:indexes))
441
- @ar3 = false
442
- else
443
- @ar3 = true
444
- end
445
- @columns = []
446
- @columns_hash = {}
447
- @indexes = {}
448
- @base = base
449
- @temporary = temporary
450
- @options = options
451
- @name = name
452
- @foreign_keys = {}
453
- end
564
+ =begin
565
+ def initialize(base, name=nil, temporary=nil, options=nil)
454
566
 
455
- def native
456
- @base.native_database_types
457
- end
458
-
459
- #Method to parse the passed arguments and create the ColumnDefinition object of the specified type
460
- def ibm_parse_column_attributes_args(type, *args)
461
- options = {}
462
- if args.last.is_a?(Hash)
463
- options = args.delete_at(args.length-1)
464
- end
465
- args.each do | name |
466
- column(name,type,options)
467
- end
468
- end
469
- private :ibm_parse_column_attributes_args
567
+ if(self.respond_to?(:indexes))
568
+ @ar3 = false
569
+ else
570
+ @ar3 = true
571
+ end
470
572
 
471
- #Method to support the new syntax of rails 2.0 migrations for columns of type xml
472
- def xml(*args )
473
- ibm_parse_column_attributes_args('xml', *args)
474
- return self
475
- end
573
+ @columns = []
574
+ @columns_hash = {}
575
+ @indexes = {}
576
+ @base = base
577
+ @temporary = temporary
578
+ @options = options
579
+ @name = name
580
+ @foreign_keys = {}
581
+ end
582
+ =end
583
+
584
+ def initialize(conn, name, temporary = false, options = nil, as = nil, comment: nil)
585
+ @connection = conn
586
+ @columns_hash = {}
587
+ @indexes = []
588
+ @foreign_keys = []
589
+ @primary_keys = nil
590
+ @temporary = temporary
591
+ @options = options
592
+ @as = as
593
+ @name = name
594
+ @comment = comment
595
+ ##
596
+ #@base = base
597
+ end
598
+
599
+ def primary_keys(name = nil) # :nodoc:
600
+ @primary_keys = PrimaryKeyDefinition.new(name) if name
601
+ @primary_keys
602
+ end
476
603
 
477
- #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type double
478
- def double(*args)
479
- ibm_parse_column_attributes_args('double',*args)
480
- return self
481
- end
604
+ def native
605
+ @base.native_database_types
606
+ end
607
+
608
+ #Method to parse the passed arguments and create the ColumnDefinition object of the specified type
609
+ def ibm_parse_column_attributes_args(type, *args)
610
+ options = {}
611
+ if args.last.is_a?(Hash)
612
+ options = args.delete_at(args.length-1)
613
+ end
614
+ args.each do | name |
615
+ column(name,type,options)
616
+ end
617
+ end
618
+ private :ibm_parse_column_attributes_args
482
619
 
483
- #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type decfloat
484
- def decfloat(*args)
485
- ibm_parse_column_attributes_args('decfloat',*args)
486
- return self
487
- end
620
+ #Method to support the new syntax of rails 2.0 migrations for columns of type xml
621
+ def xml(*args )
622
+ ibm_parse_column_attributes_args('xml', *args)
623
+ return self
624
+ end
488
625
 
489
- def graphic(*args)
490
- ibm_parse_column_attributes_args('graphic',*args)
491
- return self
492
- end
626
+ #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type double
627
+ def double(*args)
628
+ ibm_parse_column_attributes_args('double',*args)
629
+ return self
630
+ end
493
631
 
494
- def vargraphic(*args)
495
- ibm_parse_column_attributes_args('vargraphic',*args)
496
- return self
497
- end
632
+ #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type decfloat
633
+ def decfloat(*args)
634
+ ibm_parse_column_attributes_args('decfloat',*args)
635
+ return self
636
+ end
498
637
 
499
- def bigint(*args)
500
- ibm_parse_column_attributes_args('bigint',*args)
501
- return self
502
- end
638
+ def graphic(*args)
639
+ ibm_parse_column_attributes_args('graphic',*args)
640
+ return self
641
+ end
503
642
 
504
- #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type char [character]
505
- def char(*args)
506
- ibm_parse_column_attributes_args('char',*args)
507
- return self
508
- end
509
- alias_method :character, :char
643
+ def vargraphic(*args)
644
+ ibm_parse_column_attributes_args('vargraphic',*args)
645
+ return self
646
+ end
510
647
 
511
- # Overrides the abstract adapter in order to handle
512
- # the DEFAULT option for the native XML datatype
513
- def column(name, type, options ={})
514
- # construct a column definition where @base is adaptor instance
515
- if(@ar3)
516
- column = ColumnDefinition.new(@base, name, type)
517
- else
518
- column = ColumnDefinition.new(name, type)
519
- end
520
- # DB2 does not accept DEFAULT NULL option for XML
521
- # for table create, but does accept nullable option
522
- unless type.to_s == 'xml'
523
- column.null = options[:null]
524
- column.default = options[:default]
525
- else
526
- column.null = options[:null]
527
- # Override column object's (instance of ColumnDefinition structure)
528
- # to_s which is expected to return the create_table SQL fragment
529
- # and bypass DEFAULT NULL option while still appending NOT NULL
530
- def column.to_s
531
- sql = "#{base.quote_column_name(name)} #{type}"
532
- unless self.null == nil
533
- sql << " NOT NULL" if (self.null == false)
534
- end
535
- return sql
536
- end
537
- end
648
+ def bigint(*args)
649
+ ibm_parse_column_attributes_args('bigint',*args)
650
+ return self
651
+ end
538
652
 
539
- column.scale = options[:scale] if options[:scale]
540
- column.precision = options[:precision] if options[:precision]
541
- # append column's limit option and yield native limits
542
- if options[:limit]
543
- column.limit = options[:limit]
544
- elsif @base.native_database_types[type.to_sym]
545
- column.limit = @base.native_database_types[type.to_sym][:limit] if @base.native_database_types[type.to_sym].has_key? :limit
546
- end
653
+ #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type char [character]
654
+ def char(*args)
655
+ ibm_parse_column_attributes_args('char',*args)
656
+ return self
657
+ end
658
+ alias_method :character, :char
547
659
 
548
- unless @columns.nil? or @columns.include? column
549
- @columns << column
550
- end
660
+ # Overrides the abstract adapter in order to handle
661
+ # the DEFAULT option for the native XML datatype
662
+ def column(name, type, options ={})
663
+ # construct a column definition where @base is adaptor instance
664
+ column = ColumnDefinition.new(name, type)
665
+
666
+ # DB2 does not accept DEFAULT NULL option for XML
667
+ # for table create, but does accept nullable option
668
+ unless type.to_s == 'xml'
669
+ column.null = options[:null]
670
+ column.default = options[:default]
671
+ else
672
+ column.null = options[:null]
673
+ # Override column object's (instance of ColumnDefinition structure)
674
+ # to_s which is expected to return the create_table SQL fragment
675
+ # and bypass DEFAULT NULL option while still appending NOT NULL
676
+ def column.to_s
677
+ sql = "#{base.quote_column_name(name)} #{type}"
678
+ unless self.null == nil
679
+ sql << " NOT NULL" if (self.null == false)
680
+ end
681
+ return sql
682
+ end
683
+ end
684
+
685
+ column.scale = options[:scale] if options[:scale]
686
+ column.precision = options[:precision] if options[:precision]
687
+ # append column's limit option and yield native limits
688
+ if options[:limit]
689
+ column.limit = options[:limit]
690
+ elsif @base.native_database_types[type.to_sym]
691
+ column.limit = @base.native_database_types[type.to_sym][:limit] if @base.native_database_types[type.to_sym].has_key? :limit
692
+ end
551
693
 
552
- @columns_hash[name] = column
694
+ unless @columns.nil? or @columns.include? column
695
+ @columns << column
696
+ end
553
697
 
554
- return self
555
- end
556
- end
698
+ @columns_hash[name] = column
699
+
700
+ return self
701
+ end
702
+ end
703
+ end
557
704
 
558
705
  # The IBM_DB Adapter requires the native Ruby driver (ibm_db)
559
706
  # for IBM data servers (ibm_db.so).
@@ -597,11 +744,12 @@ module ActiveRecord
597
744
  end
598
745
 
599
746
  class BindSubstitution < Arel::Visitors::IBM_DB # :nodoc:
600
- include Arel::Visitors::BindVisitor
747
+ include Arel::Visitors
601
748
  end
602
749
 
603
750
  def initialize(connection, ar3, logger, config, conn_options)
604
- # Caching database connection configuration (+connect+ or +reconnect+ support)
751
+ # Caching database connection configuration (+connect+ or +reconnect+ support)\
752
+ @config = config
605
753
  @connection = connection
606
754
  @isAr3 = ar3
607
755
  @conn_options = conn_options
@@ -617,14 +765,6 @@ module ActiveRecord
617
765
  @authentication = config[:authentication] || nil
618
766
  @timeout = config[:timeout] || 0 # default timeout value is 0
619
767
 
620
- if( config.has_key?(:parameterized) && config[:parameterized] == true )
621
- @pstmt_support_on = true
622
- @set_quoted_literal_replacement = IBM_DB::QUOTED_LITERAL_REPLACEMENT_OFF
623
- else
624
- @pstmt_support_on = false
625
- @set_quoted_literal_replacement = IBM_DB::QUOTED_LITERAL_REPLACEMENT_ON
626
- end
627
-
628
768
  @app_user = @account = @application = @workstation = nil
629
769
  # Caching database connection options (auditing and billing support)
630
770
  @app_user = conn_options[:app_user] if conn_options.has_key?(:app_user)
@@ -639,7 +779,7 @@ module ActiveRecord
639
779
 
640
780
  # Calls the parent class +ConnectionAdapters+' initializer
641
781
  # which sets @connection, @logger, @runtime and @last_verification
642
- super(@connection, logger)
782
+ super(@connection, logger, @config)
643
783
 
644
784
  if @connection
645
785
  server_info = IBM_DB.server_info( @connection )
@@ -701,6 +841,16 @@ module ActiveRecord
701
841
  if(@arelVersion >= 3 )
702
842
  @visitor = Arel::Visitors::IBM_DB.new self
703
843
  end
844
+
845
+ if(config.has_key?(:parameterized) && config[:parameterized] == true)
846
+ @pstmt_support_on = true
847
+ @prepared_statements = true
848
+ @set_quoted_literal_replacement = IBM_DB::QUOTED_LITERAL_REPLACEMENT_OFF
849
+ else
850
+ @pstmt_support_on = false
851
+ @prepared_statements = false
852
+ @set_quoted_literal_replacement = IBM_DB::QUOTED_LITERAL_REPLACEMENT_ON
853
+ end
704
854
  end
705
855
 
706
856
  # Optional connection attribute: database name space qualifier
@@ -761,7 +911,7 @@ module ActiveRecord
761
911
  rescue
762
912
  @arelVersion = 0
763
913
  end
764
- if(@arelVersion < 6)
914
+ if(@arelVersion < 6 )
765
915
  def to_sql(arel, binds = [])
766
916
  if arel.respond_to?(:ast)
767
917
  visitor.accept(arel.ast) do
@@ -770,7 +920,7 @@ module ActiveRecord
770
920
  else
771
921
  arel
772
922
  end
773
- end
923
+ end
774
924
  end
775
925
  # This adapter supports migrations.
776
926
  # Current limitations:
@@ -783,8 +933,11 @@ module ActiveRecord
783
933
 
784
934
  def supports_foreign_keys?
785
935
  true
936
+ end
937
+
938
+ def supports_datetime_with_precision?
939
+ true
786
940
  end
787
-
788
941
 
789
942
  # This Adapter supports DDL transactions.
790
943
  # This means CREATE TABLE and other DDL statements can be carried out as a transaction.
@@ -869,21 +1022,20 @@ module ActiveRecord
869
1022
 
870
1023
  def create_table(name, options = {})
871
1024
  @servertype.setup_for_lob_table
872
- super
873
-
874
1025
  #Table definition is complete only when a unique index is created on the primarykey column for DB2 V8 on zOS
875
1026
 
876
1027
  #create index on id column if options[:id] is nil or id ==true
877
1028
  #else check if options[:primary_key]is not nil then create an unique index on that column
878
1029
  if !options[:id].nil? || !options[:primary_key].nil?
879
1030
  if (!options[:id].nil? && options[:id] == true)
880
- @servertype.create_index_after_table(name,"id")
1031
+ @servertype.create_index_after_table(name,"id")
881
1032
  elsif !options[:primary_key].nil?
882
- @servertype.create_index_after_table(name,options[:primary_key].to_s)
1033
+ @servertype.create_index_after_table(name,options[:primary_key].to_s)
883
1034
  end
884
1035
  else
885
- @servertype.create_index_after_table(name,"id")
886
- end
1036
+ @servertype.create_index_after_table(name,"id")
1037
+ end
1038
+ super(name, options)
887
1039
  end
888
1040
 
889
1041
  # Returns an array of hashes with the column names as keys and
@@ -974,8 +1126,8 @@ module ActiveRecord
974
1126
  end
975
1127
 
976
1128
  def select(sql, name = nil, binds = [])
977
- # Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"}
978
- sql.gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" )
1129
+ # Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"
1130
+ sql.gsub( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" )
979
1131
 
980
1132
  results = []
981
1133
 
@@ -1003,7 +1155,7 @@ module ActiveRecord
1003
1155
  #+sql+ is the select query and +name+ is an optional description for logging
1004
1156
  def select_rows(sql, name = nil,binds = [])
1005
1157
  # Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"}
1006
- sql.gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" )
1158
+ sql.gsub( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" )
1007
1159
 
1008
1160
  results = []
1009
1161
  # Invokes the method +execute+ in order to log and execute the SQL
@@ -1070,10 +1222,10 @@ module ActiveRecord
1070
1222
  break
1071
1223
  end
1072
1224
  end
1225
+
1073
1226
  if item.at(1).nil? ||
1074
1227
  item.at(1) == {} ||
1075
1228
  (item.at(1) == '' && !(col.sql_type.to_s =~ /text|clob/i))
1076
-
1077
1229
  params << 'NULL'
1078
1230
 
1079
1231
  elsif (!col.nil? && (col.sql_type.to_s =~ /blob|binary|clob|text|xml/i) )
@@ -1135,27 +1287,21 @@ module ActiveRecord
1135
1287
  end
1136
1288
  end
1137
1289
 
1138
- def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [] )
1139
- if(@arelVersion < 6 )
1140
- sql, binds = [to_sql(arel),binds]
1141
- else
1142
- sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds) #[to_sql(arel),binds]
1143
- end
1290
+ def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds=[])
1291
+ if(@arelVersion < 6)
1292
+ sql, binds = [to_sql(arel), binds]
1293
+ else
1294
+ sql, binds = [to_sql(arel),binds] #sql_for_insert(to_sql(arel, binds), binds) #[to_sql(arel),binds]
1295
+ end
1144
1296
 
1145
1297
  #unless IBM_DBAdapter.respond_to?(:exec_insert)
1146
1298
  if binds.nil? || binds.empty?
1147
1299
  return insert_direct(sql, name, pk, id_value, sequence_name)
1148
1300
  end
1149
-
1150
- new_binds = Hash.new
1151
- param_array = binds.map do |column,value|
1152
- if column && column.sql_type.to_s =~ /binary|blob/i
1153
- new_binds [column] = value
1154
- end
1155
- end
1156
-
1301
+
1157
1302
  clear_query_cache if defined? clear_query_cache
1158
- if stmt = exec_insert(sql, name, new_binds)
1303
+
1304
+ if stmt = exec_insert(sql, name, binds)
1159
1305
  begin
1160
1306
  @sql << sql
1161
1307
  return id_value || @servertype.last_generated_id(stmt)
@@ -1249,14 +1395,18 @@ module ActiveRecord
1249
1395
 
1250
1396
  # Executes and logs +sql+ commands and
1251
1397
  # returns a +IBM_DB.Statement+ object.
1252
- def execute(sql, name = nil)
1398
+ def execute(sql, name=nil)
1253
1399
  # Logs and execute the sql instructions.
1254
1400
  # The +log+ method is defined in the parent class +AbstractAdapter+
1255
- log(sql, name) do
1401
+ #sql='INSERT INTO ar_internal_metadata (key, value, created_at, updated_at) VALUES ('10', '10', '10', '10')
1402
+ log(sql , name) do
1256
1403
  @servertype.execute(sql, name)
1257
1404
  end
1258
1405
  end
1259
1406
 
1407
+ def exec_insert(sql,name,binds,pk,sequence_name)
1408
+ end
1409
+
1260
1410
  # Executes an "UPDATE" SQL statement
1261
1411
  def update_direct(sql, name = nil)
1262
1412
  if @handle_lobs_triggered #Ensure the array of sql is cleared if they have been handled in the callback
@@ -1308,10 +1458,10 @@ module ActiveRecord
1308
1458
 
1309
1459
  def update(arel, name = nil, binds = [])
1310
1460
  if(@arelVersion < 6 )
1311
- sql = to_sql(arel)
1312
- else
1313
- sql = to_sql(arel,binds)
1314
- end
1461
+ sql = to_sql(arel)
1462
+ else
1463
+ sql = to_sql(arel,binds)
1464
+ end
1315
1465
 
1316
1466
  # Make sure the WHERE clause handles NULL's correctly
1317
1467
  sqlarray = sql.split(/\s*WHERE\s*/)
@@ -1333,15 +1483,8 @@ module ActiveRecord
1333
1483
  if binds.nil? || binds.empty?
1334
1484
  update_direct(sql, name)
1335
1485
  else
1336
- begin
1337
- new_binds = Hash.new
1338
- param_array = binds.map do |column,value|
1339
- if column && column.sql_type.to_s =~ /binary|blob/i
1340
- new_binds [column] = value
1341
- end
1342
- end
1343
-
1344
- if stmt = exec_query(sql,name,new_binds)
1486
+ begin
1487
+ if stmt = exec_query(sql,name,binds)
1345
1488
  IBM_DB.num_rows(stmt)
1346
1489
  end
1347
1490
  ensure
@@ -1376,6 +1519,7 @@ module ActiveRecord
1376
1519
  end
1377
1520
 
1378
1521
  def get_limit_offset_clauses(limit,offset)
1522
+
1379
1523
  if limit && limit == 0
1380
1524
  clauses = @servertype.get_limit_offset_clauses(limit,0)
1381
1525
  else
@@ -1436,6 +1580,7 @@ module ActiveRecord
1436
1580
 
1437
1581
  # Quote date/time values for use in SQL input.
1438
1582
  # Includes microseconds, if the value is a Time responding to usec.
1583
+ =begin
1439
1584
  def quoted_date(value) #:nodoc:
1440
1585
  if value.respond_to?(:usec)
1441
1586
  "#{super}.#{sprintf("%06d", value.usec)}"
@@ -1443,7 +1588,7 @@ module ActiveRecord
1443
1588
  super
1444
1589
  end
1445
1590
  end
1446
-
1591
+ =end
1447
1592
  def quote_value_for_pstmt(value, column=nil)
1448
1593
 
1449
1594
  return value.quoted_id if value.respond_to?(:quoted_id)
@@ -1472,75 +1617,82 @@ module ActiveRecord
1472
1617
  end
1473
1618
  end
1474
1619
  end
1475
-
1476
1620
  # Properly quotes the various data types.
1477
1621
  # +value+ contains the data, +column+ is optional and contains info on the field
1478
- def quote(value, column = nil)
1479
- return value.quoted_id if value.respond_to?(:quoted_id)
1480
-
1481
- case value
1482
- # If it's a numeric value and the column sql_type is not a string, it shouldn't be quoted
1483
- # (IBM_DB doesn't accept quotes on numeric types)
1484
- when Numeric
1485
- # If the column sql_type is text or string, return the quote value
1486
- if (column && ( column.sql_type.to_s =~ /text|char/i ))
1487
- unless caller[0] =~ /insert_fixture/i
1488
- "'#{value}'"
1489
- else
1490
- "#{value}"
1491
- end
1492
- else
1493
- # value is Numeric, column.sql_type is not a string,
1494
- # therefore it converts the number to string without quoting it
1495
- value.to_s
1496
- end
1497
- when String, ActiveSupport::Multibyte::Chars
1498
- if column && column.sql_type.to_s =~ /binary|blob/i && !(column.sql_type.to_s =~ /for bit data/i)
1499
- # If quoting is required for the insert/update of a BLOB
1500
- unless caller[0] =~ /add_column_options/i
1501
- # Invokes a convertion from string to binary
1502
- @servertype.set_binary_value
1503
- else
1504
- # Quoting required for the default value of a column
1505
- @servertype.set_binary_default(value)
1506
- end
1507
- elsif column && column.sql_type.to_s =~ /text|clob/i
1508
- unless caller[0] =~ /add_column_options/i
1509
- @servertype.set_text_default(quote_string(value))
1510
- else
1511
- @servertype.set_text_default(quote_string(value))
1512
- end
1513
- elsif column && column.sql_type.to_s =~ /xml/i
1514
- unless caller[0] =~ /add_column_options/i
1515
- "#{value}"
1516
- else
1517
- "#{value}"
1518
- end
1519
- else
1520
- unless caller[0] =~ /insert_fixture/i
1521
- super
1522
- else
1523
- "#{value}"
1524
- end
1525
- end
1526
- when TrueClass then quoted_true # return '1' for true
1527
- when FalseClass then quoted_false # return '0' for false
1528
- when nil then "NULL"
1529
- when Date, Time then "'#{quoted_date(value)}'"
1530
- when Symbol then "'#{quote_string(value.to_s)}'"
1531
- else
1532
- unless caller[0] =~ /insert_fixture/i
1533
- "'#{quote_string(YAML.dump(value))}'"
1534
- else
1535
- "#{quote_string(YAML.dump(value))}"
1536
- end
1537
- end
1538
- end
1539
-
1540
- # Quotes a given string, escaping single quote (') characters.
1541
- def quote_string(string)
1542
- string.gsub(/'/, "''")
1543
- end
1622
+ # def quote(value, column=nil)
1623
+ # return value.quoted_id if value.respond_to?(:quoted_id)
1624
+ # case value
1625
+ # # If it's a numeric value and the column sql_type is not a string, it shouldn't be quoted
1626
+ # # (IBM_DB doesn't accept quotes on numeric types)
1627
+ # when Numeric
1628
+ # # If the column sql_type is text or string, return the quote value
1629
+ # if (column && ( column.sql_type.to_s =~ /text|char/i ))
1630
+ # unless caller[0] =~ /insert_fixture/i
1631
+ # "'#{value}'"
1632
+ # else
1633
+ # "#{value}"
1634
+ # end
1635
+ # else
1636
+ # # value is Numeric, column.sql_type is not a string,
1637
+ # # therefore it converts the number to string without quoting it
1638
+ # value.to_s
1639
+ # end
1640
+ # when String, ActiveSupport::Multibyte::Chars
1641
+ # if column && column.sql_type.to_s =~ /binary|blob/i && !(column.sql_type.to_s =~ /for bit data/i)
1642
+ # # If quoting is required for the insert/update of a BLOB
1643
+ # unless caller[0] =~ /add_column_options/i
1644
+ # # Invokes a convertion from string to binary
1645
+ # @servertype.set_binary_value
1646
+ # else
1647
+ # # Quoting required for the default value of a column
1648
+ # @servertype.set_binary_default(value)
1649
+ # end
1650
+ # elsif column && column.sql_type.to_s =~ /text|clob/i
1651
+ # unless caller[0] =~ /add_column_options/i
1652
+ # @servertype.set_text_default(quote_string(value))
1653
+ # else
1654
+ # @servertype.set_text_default(quote_string(value))
1655
+ # end
1656
+ # elsif column && column.sql_type.to_s =~ /xml/i
1657
+ # unless caller[0] =~ /add_column_options/i
1658
+ # "#{value}"
1659
+ # else
1660
+ # "#{value}"
1661
+ # end
1662
+ # else
1663
+ # unless caller[0] =~ /insert_fixture/i
1664
+ # super(value)
1665
+ # else
1666
+ # "#{value}"
1667
+ # end
1668
+ # end
1669
+ # #when TrueClass then quoted_true # return '1' for true
1670
+ # when TrueClass
1671
+ # quoted_true
1672
+ # #when FalseClass then quoted_false # return '0' for false
1673
+ # when FalseClass
1674
+ # quoted_false
1675
+ # when nil
1676
+ # "NULL"
1677
+ # when Date
1678
+ # "'#{quoted_date(value)}'"
1679
+ # when Time
1680
+ # "'#{quoted_date(value)}'"
1681
+ # when Symbol
1682
+ # "'#{quote_string(value)}'"
1683
+ # else
1684
+ # unless caller[0] =~ /insert_fixture/i
1685
+ # "'#{quote_string(YAML.dump(value))}'"
1686
+ # else
1687
+ # "#{quote_string(YAML.dump(value))}"
1688
+ # end
1689
+ # end
1690
+ # end
1691
+ # # Quotes a given string, escaping single quote (') characters.
1692
+ # def quote_string(string)
1693
+ # #string.gsub(/'/, "''")
1694
+ # string.gsub('\\', '\&\&').gsub("'", "''")
1695
+ # end
1544
1696
 
1545
1697
  # *true* is represented by a smallint 1, *false*
1546
1698
  # by 0, as no native boolean type exists in DB2.
@@ -1560,7 +1712,7 @@ module ActiveRecord
1560
1712
  #==============================================
1561
1713
  # SCHEMA STATEMENTS
1562
1714
  #==============================================
1563
-
1715
+
1564
1716
  # Returns a Hash of mappings from the abstract data types to the native
1565
1717
  # database types
1566
1718
  def native_database_types
@@ -1570,9 +1722,9 @@ module ActiveRecord
1570
1722
  :text => { :name => "clob" },
1571
1723
  :integer => { :name => "integer" },
1572
1724
  :float => { :name => "float" },
1573
- :datetime => { :name => @servertype.get_datetime_mapping },
1574
- :timestamp => { :name => @servertype.get_datetime_mapping },
1575
- :time => { :name => @servertype.get_time_mapping },
1725
+ :datetime => { :name => "timestamp" },
1726
+ :timestamp => { :name => "timestamp" },
1727
+ :time => { :name => "time" },
1576
1728
  :date => { :name => "date" },
1577
1729
  :binary => { :name => "blob" },
1578
1730
 
@@ -1587,8 +1739,8 @@ module ActiveRecord
1587
1739
  :char => { :name => "char" },
1588
1740
  :double => { :name => @servertype.get_double_mapping },
1589
1741
  :decfloat => { :name => "decfloat"},
1590
- :graphic => { :name => "graphic", :limit => 1},
1591
- :vargraphic => { :name => "vargraphic", :limit => 1},
1742
+ :graphic => { :name => "graphic"},
1743
+ :vargraphic => { :name => "vargraphic"},
1592
1744
  :bigint => { :name => "bigint"}
1593
1745
  }
1594
1746
  end
@@ -1650,16 +1802,78 @@ module ActiveRecord
1650
1802
  end
1651
1803
  end
1652
1804
 
1805
+
1806
+
1807
+
1808
+ def valid_type?(type)
1809
+ #!native_database_types[type].nil?
1810
+ native_database_types[type].nil?
1811
+ end
1812
+
1653
1813
  # IBM data servers do not support limits on certain data types (unlike MySQL)
1654
1814
  # Limit is supported for the {float, decimal, numeric, varchar, clob, blob, graphic, vargraphic} data types.
1655
- def type_to_sql(type, limit = nil, precision = nil, scale = nil)
1815
+ def type_to_sql(type, limit=nil, precision=nil, scale=nil )
1816
+ if type.to_sym == :decimal
1817
+ if limit.class == Hash
1818
+ if limit.has_key?("precision".to_sym)
1819
+ precision = limit[:precision]
1820
+ end
1821
+ end
1822
+ if limit.class == Hash
1823
+ if limit.has_key?("scale".to_sym)
1824
+ scale = limit[:scale]
1825
+ end
1826
+ end
1827
+ sql_segment = native_database_types[type.to_sym][:name].to_s
1828
+ if !precision.nil? && !scale.nil?
1829
+ sql_segment << "(#{precision},#{scale})"
1830
+ return sql_segment
1831
+ elsif scale.nil? && !precision.nil?
1832
+ sql_segment << "(#{precision})"
1833
+ else
1834
+ return sql_segment
1835
+ end
1836
+ end
1837
+
1656
1838
  if type.to_sym == :decfloat
1657
1839
  sql_segment = native_database_types[type.to_sym][:name].to_s
1658
1840
  sql_segment << "(#{precision})" if !precision.nil?
1659
1841
  return sql_segment
1660
1842
  end
1661
-
1662
- return super if limit.nil?
1843
+
1844
+ if type.to_sym == :vargraphic
1845
+ sql_segment = native_database_types[type.to_sym][:name].to_s
1846
+ if limit.class == Hash
1847
+ if limit.has_key?("limit".to_sym)
1848
+ limit1 = limit[:limit]
1849
+ sql_segment << "(#{limit1})"
1850
+ else
1851
+ return "vargraphic(1)"
1852
+ end
1853
+ end
1854
+ return sql_segment
1855
+ end
1856
+
1857
+ if type.to_sym == :graphic
1858
+ sql_segment = native_database_types[type.to_sym][:name].to_s
1859
+ if limit.class == Hash
1860
+ if limit.has_key?("limit".to_sym)
1861
+ limit1 = limit[:limit]
1862
+ sql_segment << "(#{limit1})"
1863
+ else
1864
+ return "graphic(1)"
1865
+ end
1866
+ end
1867
+ return sql_segment
1868
+ end
1869
+
1870
+
1871
+
1872
+ if limit.class == Hash
1873
+ return super if limit.has_key?("limit".to_sym).nil?
1874
+ else
1875
+ return super if limit.nil?
1876
+ end
1663
1877
 
1664
1878
  # strip off limits on data types not supporting them
1665
1879
  if @servertype.limit_not_supported_types.include? type.to_sym
@@ -1667,16 +1881,23 @@ module ActiveRecord
1667
1881
  elsif type.to_sym == :boolean
1668
1882
  return "smallint"
1669
1883
  else
1670
- return super
1884
+ return super(type)
1671
1885
  end
1672
- end
1673
1886
 
1887
+ end
1888
+
1889
+
1890
+
1891
+
1892
+
1893
+
1674
1894
  # Returns the maximum length a table alias identifier can be.
1675
1895
  # IBM data servers (cross-platform) table limit is 128 characters
1676
1896
  def table_alias_length
1677
1897
  128
1678
1898
  end
1679
-
1899
+
1900
+
1680
1901
  # Retrieves table's metadata for a specified shema name
1681
1902
  def tables(name = nil)
1682
1903
  # Initializes the tables array
@@ -1717,6 +1938,50 @@ module ActiveRecord
1717
1938
  return tables
1718
1939
  end
1719
1940
 
1941
+ ###################################
1942
+
1943
+
1944
+ # Retrieves views's metadata for a specified shema name
1945
+ def views
1946
+ # Initializes the tables array
1947
+ tables = []
1948
+ # Retrieve view's metadata through IBM_DB driver
1949
+ stmt = IBM_DB.tables(@connection, nil,
1950
+ @servertype.set_case(@schema))
1951
+ if(stmt)
1952
+ begin
1953
+ # Fetches all the records available
1954
+ while tab = IBM_DB.fetch_assoc(stmt)
1955
+ # Adds the lowercase view's name to the array
1956
+ if(tab["table_type"]== 'V') #check, so that only views are dumped,IBM_DB.tables also returns tables,alias etc in the schema
1957
+ tables << tab["table_name"].downcase
1958
+ end
1959
+ end
1960
+ rescue StandardError => fetch_error # Handle driver fetch errors
1961
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
1962
+ if error_msg && !error_msg.empty?
1963
+ raise "Failed to retrieve views metadata during fetch: #{error_msg}"
1964
+ else
1965
+ error_msg = "An unexpected error occurred during retrieval of views metadata"
1966
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
1967
+ raise error_msg
1968
+ end
1969
+ ensure
1970
+ IBM_DB.free_stmt(stmt) if stmt # Free resources associated with the statement
1971
+ end
1972
+ else # Handle driver execution errors
1973
+ error_msg = IBM_DB.getErrormsg(@connection, IBM_DB::DB_CONN )
1974
+ if error_msg && !error_msg.empty?
1975
+ raise "Failed to retrieve tables metadata due to error: #{error_msg}"
1976
+ else
1977
+ raise StandardError.new('An unexpected error occurred during retrieval of views metadata')
1978
+ end
1979
+ end
1980
+ # Returns the tables array
1981
+ return tables
1982
+ end
1983
+
1984
+
1720
1985
  # Returns the primary key of the mentioned table
1721
1986
  def primary_key(table_name)
1722
1987
  pk_name = nil
@@ -1753,7 +2018,7 @@ module ActiveRecord
1753
2018
 
1754
2019
  # Returns an array of non-primary key indexes for a specified table name
1755
2020
  def indexes(table_name, name = nil)
1756
- # to_s required because +table_name+ may be a symbol.
2021
+ # to_s required because +table_name+ may be a symbol.
1757
2022
  table_name = table_name.to_s
1758
2023
  # Checks if a blank table name has been given.
1759
2024
  # If so it returns an empty array of columns.
@@ -1816,7 +2081,7 @@ module ActiveRecord
1816
2081
  if(stmt)
1817
2082
  begin
1818
2083
  while ( index_stats = IBM_DB.fetch_array(stmt) )
1819
- is_composite = false
2084
+ is_composite = false
1820
2085
  if index_stats[5] # INDEX_NAME
1821
2086
  index_name = index_stats[5].downcase
1822
2087
  index_unique = (index_stats[3] == 0)
@@ -1826,7 +2091,8 @@ module ActiveRecord
1826
2091
  i = 0;
1827
2092
  indexes.each do |index|
1828
2093
  if index.name == index_name && index_schema[i] == index_qualifier
1829
- index.columns = index.columns + index_columns
2094
+ #index.columns = index.columns + index_columns
2095
+ index.columns.concat index_columns
1830
2096
  is_composite = true
1831
2097
  end
1832
2098
  i = i+1
@@ -1872,10 +2138,92 @@ module ActiveRecord
1872
2138
  return indexes
1873
2139
  end
1874
2140
 
2141
+
2142
+ # Mapping IBM data servers SQL datatypes to Ruby data types
2143
+ def simplified_type2(field_type)
2144
+ case field_type
2145
+ # if +field_type+ contains 'for bit data' handle it as a binary
2146
+ when /for bit data/i
2147
+ "binary"
2148
+ when /smallint/i
2149
+ "boolean"
2150
+ when /int|serial/i
2151
+ "integer"
2152
+ when /decimal|numeric|decfloat/i
2153
+ "decimal"
2154
+ when /float|double|real/i
2155
+ "float"
2156
+ when /timestamp|datetime/i
2157
+ "timestamp"
2158
+ when /time/i
2159
+ "time"
2160
+ when /date/i
2161
+ "date"
2162
+ when /vargraphic/i
2163
+ "vargraphic"
2164
+ when /graphic/i
2165
+ "graphic"
2166
+ when /clob|text/i
2167
+ "text"
2168
+ when /xml/i
2169
+ "xml"
2170
+ when /blob|binary/i
2171
+ "binary"
2172
+ when /char/i
2173
+ "string"
2174
+ when /boolean/i
2175
+ "boolean"
2176
+ when /rowid/i # rowid is a supported datatype on z/OS and i/5
2177
+ "rowid"
2178
+ end
2179
+ end # method simplified_type
2180
+
2181
+
2182
+ # Mapping IBM data servers SQL datatypes to Ruby data types
2183
+ def simplified_type(field_type)
2184
+ case field_type
2185
+ # if +field_type+ contains 'for bit data' handle it as a binary
2186
+ when /for bit data/i
2187
+ :binary
2188
+ when /smallint/i
2189
+ :boolean
2190
+ when /int|serial/i
2191
+ :integer
2192
+ when /decimal|numeric|decfloat/i
2193
+ :decimal
2194
+ when /float|double|real/i
2195
+ :float
2196
+ when /timestamp|datetime/i
2197
+ :timestamp
2198
+ when /time/i
2199
+ :time
2200
+ when /date/i
2201
+ :date
2202
+ when /vargraphic/i
2203
+ :vargraphic
2204
+ when /graphic/i
2205
+ :graphic
2206
+ when /clob|text/i
2207
+ :text
2208
+ when /xml/i
2209
+ :xml
2210
+ when /blob|binary/i
2211
+ :binary
2212
+ when /char/i
2213
+ :string
2214
+ when /boolean/i
2215
+ :boolean
2216
+ when /rowid/i # rowid is a supported datatype on z/OS and i/5
2217
+ :rowid
2218
+ end
2219
+ end # method simplified_type
2220
+
2221
+
1875
2222
  # Returns an array of Column objects for the table specified by +table_name+
1876
- def columns(table_name, name = nil)
1877
- # to_s required because it may be a symbol.
2223
+ def columns(table_name)
2224
+ # to_s required because it may be a symbol.
1878
2225
  table_name = @servertype.set_case(table_name.to_s)
2226
+
1879
2227
  # Checks if a blank table name has been given.
1880
2228
  # If so it returns an empty array
1881
2229
  return [] if table_name.strip.empty?
@@ -1902,6 +2250,9 @@ module ActiveRecord
1902
2250
  # Assigns the column type
1903
2251
  column_type = col["type_name"].downcase
1904
2252
  # Assigns the field length (size) for the column
2253
+
2254
+ original_column_type = "#{column_type}"
2255
+
1905
2256
  column_length = col["column_size"]
1906
2257
  column_scale = col["decimal_digits"]
1907
2258
  # The initializer of the class Column, requires the +column_length+ to be declared
@@ -1926,12 +2277,30 @@ module ActiveRecord
1926
2277
  if !(column_name =~ /db2_generated_rowid_for_lobs/i)
1927
2278
  # Pushes into the array the *IBM_DBColumn* object, created by passing to the initializer
1928
2279
  # +column_name+, +default_value+, +column_type+ and +column_nullable+.
1929
- if(@arelVersion >= 6 )
1930
- cast_type = lookup_cast_type(column_type)
1931
- columns << IBM_DBColumn.new(column_name, column_default_value, cast_type, column_type, column_nullable)
1932
- else
1933
- columns << IBM_DBColumn.new(column_name, column_default_value, column_type, column_nullable)
1934
- end
2280
+ #if(@arelVersion >= 6 )
2281
+
2282
+ #cast_type = lookup_cast_type(column_type)
2283
+
2284
+ ruby_type = simplified_type2(column_type)
2285
+ precision = extract_precision(ruby_type)
2286
+
2287
+ #type = type_map.lookup(column_type)
2288
+ sql_type = type_to_sql(column_type, column_length, precision, column_scale)
2289
+
2290
+ sqltype_metadata = SqlTypeMetadata.new(
2291
+ #sql_type: sql_type,
2292
+ sql_type: original_column_type,
2293
+ type: ruby_type,
2294
+ limit: column_length,
2295
+ precision: precision,
2296
+ scale: column_scale,
2297
+ )
2298
+
2299
+ columns << Column.new(column_name, column_default_value, sqltype_metadata, column_nullable, table_name)
2300
+
2301
+ #else
2302
+ # columns << IBM_DBColumn.new(column_name, column_default_value, column_type, column_nullable)
2303
+ #end
1935
2304
  end
1936
2305
  end
1937
2306
  rescue StandardError => fetch_error # Handle driver fetch errors
@@ -1958,12 +2327,12 @@ module ActiveRecord
1958
2327
  return columns
1959
2328
  end
1960
2329
 
1961
- def foreign_keys(table_name)
2330
+ def foreign_keys(table_name)
1962
2331
  #fetch the foreign keys of the table using function foreign_keys
1963
2332
  #PKTABLE_NAME:: fk_row[2] Name of the table containing the primary key.
1964
2333
  #PKCOLUMN_NAME:: fk_row[3] Name of the column containing the primary key.
1965
2334
  #FKTABLE_NAME:: fk_row[6] Name of the table containing the foreign key.
1966
- #FKCOLUMN_NAME: fk_row[7] Name of the column containing the foreign key.
2335
+ #FKCOLUMN_NAME:: fk_row[7] Name of the column containing the foreign key.
1967
2336
  #FK_NAME:: fk_row[11] The name of the foreign key.
1968
2337
 
1969
2338
  table_name = @servertype.set_case(table_name.to_s)
@@ -1981,7 +2350,7 @@ module ActiveRecord
1981
2350
  primary_key: fk_row[3],
1982
2351
  }
1983
2352
  options[:on_update] = extract_foreign_key_action(fk_row[9])
1984
- options[:on_delete] = extract_foreign_key_action(fk_row[10])
2353
+ options[:on_delete] = extract_foreign_key_action(fk_row[10])
1985
2354
  foreignKeys << ForeignKeyDefinition.new(fk_row[6], table_name, options)
1986
2355
  end
1987
2356
 
@@ -2007,8 +2376,9 @@ module ActiveRecord
2007
2376
  end
2008
2377
  #Returns the foreignKeys array
2009
2378
  return foreignKeys
2010
- end
2011
- def extract_foreign_key_action(specifier) # :nodoc:
2379
+ end
2380
+
2381
+ def extract_foreign_key_action(specifier) # :nodoc:
2012
2382
  case specifier
2013
2383
  when 0; :cascade
2014
2384
  when 1; :restrict
@@ -2019,9 +2389,9 @@ module ActiveRecord
2019
2389
 
2020
2390
  def supports_disable_referential_integrity? #:nodoc:
2021
2391
  true
2022
- end
2392
+ end
2023
2393
 
2024
- def disable_referential_integrity #:nodoc:
2394
+ def disable_referential_integrity #:nodoc:
2025
2395
  if supports_disable_referential_integrity?
2026
2396
  alter_foreign_keys(tables, true)
2027
2397
  end
@@ -2032,7 +2402,7 @@ module ActiveRecord
2032
2402
  alter_foreign_keys(tables, false)
2033
2403
  end
2034
2404
 
2035
- end
2405
+ end
2036
2406
 
2037
2407
  def alter_foreign_keys(tables, not_enforced)
2038
2408
  enforced = not_enforced ? 'NOT ENFORCED' : 'ENFORCED'
@@ -2041,7 +2411,7 @@ module ActiveRecord
2041
2411
  execute("ALTER TABLE #{@servertype.set_case(fk.from_table)} ALTER FOREIGN KEY #{@servertype.set_case(fk.name)} #{enforced}")
2042
2412
  end
2043
2413
  end
2044
- end
2414
+ end
2045
2415
 
2046
2416
  # Renames a table.
2047
2417
  # ==== Example
@@ -2082,7 +2452,7 @@ module ActiveRecord
2082
2452
  #Add distinct clause to the sql if there is no order by specified
2083
2453
  def distinct(columns, order_by)
2084
2454
  if order_by.nil?
2085
- "DISTINCT #{columns}"
2455
+ "DISTINCT #{columns}"
2086
2456
  else
2087
2457
  "#{columns}"
2088
2458
  end
@@ -2129,7 +2499,7 @@ module ActiveRecord
2129
2499
  # remove_index :accounts, :username
2130
2500
  # Overriden to use the IBM data servers SQL syntax.
2131
2501
  def remove_index(table_name, options = {})
2132
- execute("DROP INDEX #{index_name(table_name, options)}")
2502
+ execute("DROP INDEX #{index_name(table_name, options)}")
2133
2503
  end
2134
2504
 
2135
2505
  protected
@@ -2143,14 +2513,15 @@ module ActiveRecord
2143
2513
  register_class_with_limit m, %r(datetime)i, Type::DateTime
2144
2514
  register_class_with_limit m, %r(float)i, Type::Float
2145
2515
  register_class_with_limit m, %r(int)i, Type::Integer
2146
-
2516
+
2517
+
2147
2518
  m.alias_type %r(blob)i, 'binary'
2148
2519
  m.alias_type %r(clob)i, 'text'
2149
2520
  m.alias_type %r(timestamp)i, 'datetime'
2150
2521
  m.alias_type %r(numeric)i, 'decimal'
2151
2522
  m.alias_type %r(number)i, 'decimal'
2152
2523
  m.alias_type %r(double)i, 'float'
2153
-
2524
+
2154
2525
  m.register_type(%r(decimal)i) do |sql_type|
2155
2526
  scale = extract_scale(sql_type)
2156
2527
  precision = extract_precision(sql_type)
@@ -2178,7 +2549,7 @@ module ActiveRecord
2178
2549
  class IBM_DataServer
2179
2550
  def initialize(adapter, ar3)
2180
2551
  @adapter = adapter
2181
- @isAr3 = ar3
2552
+ @isAr3 = ar3
2182
2553
  end
2183
2554
 
2184
2555
  def last_generated_id(stmt)
@@ -2285,7 +2656,9 @@ To remove the column, the table must be dropped and recreated without the #{colu
2285
2656
  end
2286
2657
  end
2287
2658
 
2659
+ # Akhil Tcheck for if_exits added so that it will try to drop even if the table does not exit.
2288
2660
  def execute(sql, name = nil)
2661
+ if name == nil || name.class == String
2289
2662
  begin
2290
2663
  if stmt = IBM_DB.exec(@adapter.connection, sql)
2291
2664
  stmt # Return the statement object
@@ -2299,6 +2672,25 @@ To remove the column, the table must be dropped and recreated without the #{colu
2299
2672
  raise
2300
2673
  end
2301
2674
  end
2675
+ else
2676
+ if name[:if_exists]
2677
+ IBM_DB.exec(@adapter.connection, sql)
2678
+ else
2679
+ begin
2680
+ if stmt = IBM_DB.exec(@adapter.connection, sql)
2681
+ stmt # Return the statement object
2682
+ else
2683
+ raise StatementInvalid, IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
2684
+ end
2685
+ rescue StandardError => exec_err
2686
+ if exec_err && !exec_err.message.empty?
2687
+ raise "Failed to execute statement due to: #{exec_err}"
2688
+ else
2689
+ raise
2690
+ end
2691
+ end
2692
+ end
2693
+ end
2302
2694
  end
2303
2695
 
2304
2696
  def set_schema(schema)
@@ -2357,7 +2749,7 @@ To remove the column, the table must be dropped and recreated without the #{colu
2357
2749
  end
2358
2750
 
2359
2751
  def primary_key_definition(start_id)
2360
- return "INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH #{start_id}) PRIMARY KEY"
2752
+ return "INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH #{start_id}) PRIMARY KEY NOT NULL"
2361
2753
  end
2362
2754
 
2363
2755
  # Returns the last automatically generated ID.
@@ -2407,6 +2799,9 @@ To remove the column, the table must be dropped and recreated without the #{colu
2407
2799
  end
2408
2800
 
2409
2801
  def change_column(table_name, column_name, type, options)
2802
+ if !options[:default].nil?
2803
+ change_column_default(table_name, column_name, options[:default])
2804
+ else
2410
2805
  data_type = @adapter.type_to_sql(type, options[:limit], options[:precision], options[:scale])
2411
2806
  begin
2412
2807
  execute "ALTER TABLE #{table_name} ALTER #{column_name} SET DATA TYPE #{data_type}"
@@ -2424,6 +2819,7 @@ The column datatype change to [#{data_type}] is not supported by this data serve
2424
2819
  change_column_default(table_name, column_name, options[:default])
2425
2820
  reorg_table(table_name)
2426
2821
  end
2822
+ end
2427
2823
 
2428
2824
  # DB2 specific ALTER TABLE statement to add a default clause
2429
2825
  def change_column_default(table_name, column_name, default)
@@ -2480,21 +2876,31 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
2480
2876
  return retHash
2481
2877
  end
2482
2878
 
2879
+
2483
2880
  if (offset.nil?)
2484
2881
  retHash["endSegment"] = " FETCH FIRST #{limit} ROWS ONLY"
2485
2882
  return retHash
2486
2883
  end
2487
2884
 
2488
- if(limit.nil?)
2489
- retHash["startSegment"] = "SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM ( SELECT "
2885
+ #if(limit.nil?)
2886
+ if(limit.nil?)
2887
+ #retHash["startSegment"] = "SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM ( SELECT "
2888
+ retHash["startSegment"] = "SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM ( "
2490
2889
  retHash["endSegment"] = " ) AS I) AS O WHERE sys_row_num > #{offset}"
2491
2890
  return retHash
2492
2891
  end
2493
2892
 
2494
2893
  # Defines what will be the last record
2495
2894
  last_record = offset.to_i + limit.to_i
2496
- retHash["startSegment"] = "SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM ( SELECT "
2497
- retHash["endSegment"] = " ) AS I) AS O WHERE sys_row_num BETWEEN #{offset+1} AND #{last_record}"
2895
+ #retHash["startSegment"] = "SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM ( SELECT "
2896
+ retHash["startSegment"] = "SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM ( "
2897
+
2898
+ if last_record < offset+1
2899
+ retHash["endSegment"] = " ) AS I) AS O WHERE sys_row_num BETWEEN #{last_record} AND #{offset+1}"
2900
+ else
2901
+ retHash["endSegment"] = " ) AS I) AS O WHERE sys_row_num BETWEEN #{offset+1} AND #{last_record}"
2902
+ end
2903
+
2498
2904
  return retHash
2499
2905
  end
2500
2906
 
@@ -2558,14 +2964,12 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
2558
2964
  # This method generates the default blob value specified for
2559
2965
  # DB2 Dataservers
2560
2966
  def set_binary_default(value)
2561
- #"BLOB('#{value}')"
2562
- "?"
2967
+ "BLOB('#{value}')"
2563
2968
  end
2564
2969
 
2565
2970
  # This method generates the blob value specified for DB2 Dataservers
2566
2971
  def set_binary_value
2567
- #"BLOB('?')"
2568
- "?"
2972
+ "BLOB('?')"
2569
2973
  end
2570
2974
 
2571
2975
  # This method generates the default clob value specified for
@@ -3016,7 +3420,7 @@ end
3016
3420
  rescue
3017
3421
  arelVersion = 0
3018
3422
  end
3019
- if(arelVersion >= 6)
3423
+ if(arelVersion >= 6 && arelVersion <= 9)
3020
3424
  class ToSql < Arel::Visitors::Reduce #opening and closing the class to ensure backward compatibility
3021
3425
  # In case when using Rails-2.3.x there is no arel used due to which the constructor has to be defined explicitly
3022
3426
  # to ensure the same code works on any version of Rails
@@ -3069,54 +3473,7 @@ end
3069
3473
  class IBM_DB < Arel::Visitors::ToSql
3070
3474
  private
3071
3475
 
3072
-
3073
- #Check Arel version
3074
- begin
3075
- @arelVersion = Arel::VERSION.to_i
3076
- rescue
3077
- @arelVersion = 0
3078
- end
3079
- if(@arelVersion < 6)
3080
-
3081
- def visit_Arel_Nodes_Limit o, a=nil
3082
- visit o.expr
3083
- end
3084
-
3085
- def visit_Arel_Nodes_Offset o, a=nil
3086
- visit o.expr
3087
- end
3088
- def visit_Arel_Nodes_SelectStatement o, a=nil
3089
- #Interim fix for backward compatibility [Arel 4.0.0 and below]
3090
- if self.method(:visit_Arel_Nodes_SelectCore).arity == 1
3091
- sql = [
3092
- (visit(o.with) if o.with),
3093
- o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
3094
- ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
3095
- ].compact.join ' '
3096
- else
3097
- sql = [
3098
- (visit(o.with) if o.with),
3099
- o.cores.map { |x| visit_Arel_Nodes_SelectCore x,a }.join,
3100
- ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
3101
- ].compact.join ' '
3102
- end
3103
-
3104
- if o.limit
3105
- limit = visit(o.limit)
3106
- else
3107
- limit = nil
3108
- end
3109
-
3110
- if o.offset
3111
- offset = visit(o.offset)
3112
- else
3113
- offset = nil
3114
- end
3115
- @connection.add_limit_offset!(sql, {:limit => limit, :offset => offset})
3116
- sql << " #{(visit(o.lock) if o.lock)}"
3117
- return sql
3118
- end
3119
- else
3476
+
3120
3477
  def visit_Arel_Nodes_Limit o,collector
3121
3478
  visit o.expr, collector
3122
3479
  end
@@ -3124,28 +3481,45 @@ else
3124
3481
  def visit_Arel_Nodes_Offset o,collector
3125
3482
  visit o.expr,collector
3126
3483
  end
3127
-
3484
+ def visit_Arel_Nodes_ValuesList(o, collector)
3485
+ collector << "VALUES "
3486
+ o.rows.each_with_index do |row, i|
3487
+ collector << ", " unless i == 0
3488
+ collector << "("
3489
+ row.each_with_index do |value, k|
3490
+ collector << ", " unless k == 0
3491
+ case value
3492
+ when Nodes::SqlLiteral, Nodes::BindParam
3493
+ collector = visit(value, collector)
3494
+ #collector << quote(value).to_s
3495
+ else
3496
+ collector << value.to_s
3497
+ end
3498
+ end
3499
+ collector << ")"
3500
+ end
3501
+ collector
3502
+ end
3128
3503
  def visit_Arel_Nodes_SelectStatement o, collector
3129
-
3130
3504
  if o.with
3131
3505
  collector = visit o.with, collector
3132
- collector << SPACE
3506
+ collector << " "
3133
3507
  end
3134
3508
 
3135
3509
  collector = o.cores.inject(collector) { |c,x|
3136
3510
  visit_Arel_Nodes_SelectCore(x, c)
3137
3511
  }
3138
3512
 
3139
- unless o.orders.empty?
3140
- collector << SPACE
3141
- collector << ORDER_BY
3513
+ unless o.orders.empty?
3514
+ collector << " ORDER BY "
3142
3515
  len = o.orders.length - 1
3143
3516
  o.orders.each_with_index { |x, i|
3144
3517
  collector = visit(x, collector)
3145
- collector << COMMA unless len == i
3518
+ collector << "," unless len == i
3146
3519
  }
3147
3520
  end
3148
3521
 
3522
+
3149
3523
  if o.limit
3150
3524
  limcoll = Arel::Collectors::SQLString.new
3151
3525
  visit(o.limit,limcoll)
@@ -3153,7 +3527,7 @@ else
3153
3527
  else
3154
3528
  limit = nil
3155
3529
  end
3156
-
3530
+
3157
3531
  if o.offset
3158
3532
  offcoll = Arel::Collectors::SQLString.new
3159
3533
  visit(o.offset,offcoll)
@@ -3161,25 +3535,26 @@ else
3161
3535
  else
3162
3536
  offset = nil
3163
3537
  end
3164
-
3538
+
3165
3539
  limOffClause = @connection.get_limit_offset_clauses(limit,offset)
3166
-
3540
+
3167
3541
  if( !limOffClause["startSegment"].empty? )
3168
- collector.changeFirstSegment(limOffClause["startSegment"])
3542
+ #collector.changeFirstSegment(limOffClause["startSegment"])
3543
+ collector.value.prepend(limOffClause["startSegment"])
3169
3544
  end
3170
3545
 
3171
3546
  if( !limOffClause["endSegment"].empty? )
3172
- collector.changeEndSegment(limOffClause["endSegment"])
3547
+ #collector.changeEndSegment(limOffClause["endSegment"])
3548
+ collector << " "
3549
+ collector << limOffClause["endSegment"]
3173
3550
  end
3174
3551
 
3175
3552
  #Initialize a new Collector and set its value to the sql string built so far with any limit and ofset modifications
3176
3553
  #collector.reset(sql)
3177
-
3554
+
3178
3555
  collector = maybe_visit o.lock, collector
3179
-
3180
- return collector
3556
+ return collector
3181
3557
  end
3182
- end
3183
3558
 
3184
3559
  end
3185
3560
  end