ibm_db 3.0.3-x86-mingw32 → 5.0.3-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (593) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +10 -0
  3. data/LICENSE +1 -1
  4. data/MANIFEST +14 -14
  5. data/ParameterizedQueries README +6 -6
  6. data/README +208 -225
  7. data/ext/Makefile +269 -0
  8. data/ext/Makefile.nt32 +181 -181
  9. data/ext/Makefile.nt32.191 +212 -212
  10. data/ext/extconf.rb +322 -291
  11. data/ext/gil_release_version +3 -0
  12. data/ext/ibm_db-i386-mingw32.def +2 -0
  13. data/ext/ibm_db.c +11879 -11884
  14. data/ext/ibm_db.o +0 -0
  15. data/ext/ibm_db.so +0 -0
  16. data/ext/mkmf.log +110 -0
  17. data/ext/ruby_ibm_db.h +241 -241
  18. data/ext/ruby_ibm_db_cli.c +866 -866
  19. data/ext/ruby_ibm_db_cli.h +500 -500
  20. data/ext/ruby_ibm_db_cli.o +0 -0
  21. data/ext/unicode_support_version +3 -0
  22. data/init.rb +41 -41
  23. data/lib/IBM_DB.rb +27 -27
  24. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3561 -3186
  25. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -2
  26. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  27. data/lib/mswin32/ibm_db.rb +91 -123
  28. data/lib/mswin32/rb2x/i386/ibm_db.so +0 -0
  29. data/test/active_record/connection_adapters/fake_adapter.rb +49 -46
  30. data/test/assets/example.log +1 -1
  31. data/test/assets/test.txt +1 -1
  32. data/test/cases/adapter_test.rb +351 -261
  33. data/test/cases/adapters/mysql2/active_schema_test.rb +193 -0
  34. data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -0
  35. data/test/cases/adapters/mysql2/boolean_test.rb +100 -0
  36. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -0
  37. data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -0
  38. data/test/cases/adapters/mysql2/connection_test.rb +210 -0
  39. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -0
  40. data/test/cases/adapters/mysql2/enum_test.rb +26 -0
  41. data/test/cases/adapters/mysql2/explain_test.rb +21 -0
  42. data/test/cases/adapters/mysql2/json_test.rb +195 -0
  43. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -0
  44. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
  45. data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -0
  46. data/test/cases/adapters/mysql2/schema_test.rb +126 -0
  47. data/test/cases/adapters/mysql2/sp_test.rb +36 -0
  48. data/test/cases/adapters/mysql2/sql_types_test.rb +14 -0
  49. data/test/cases/adapters/mysql2/table_options_test.rb +42 -0
  50. data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -0
  51. data/test/cases/adapters/postgresql/active_schema_test.rb +98 -0
  52. data/test/cases/adapters/postgresql/array_test.rb +339 -0
  53. data/test/cases/adapters/postgresql/bit_string_test.rb +82 -0
  54. data/test/cases/adapters/postgresql/bytea_test.rb +134 -0
  55. data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -0
  56. data/test/cases/adapters/postgresql/change_schema_test.rb +38 -0
  57. data/test/cases/adapters/postgresql/cidr_test.rb +25 -0
  58. data/test/cases/adapters/postgresql/citext_test.rb +78 -0
  59. data/test/cases/adapters/postgresql/collation_test.rb +53 -0
  60. data/test/cases/adapters/postgresql/composite_test.rb +132 -0
  61. data/test/cases/adapters/postgresql/connection_test.rb +257 -0
  62. data/test/cases/adapters/postgresql/datatype_test.rb +92 -0
  63. data/test/cases/adapters/postgresql/domain_test.rb +47 -0
  64. data/test/cases/adapters/postgresql/enum_test.rb +91 -0
  65. data/test/cases/adapters/postgresql/explain_test.rb +20 -0
  66. data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -0
  67. data/test/cases/adapters/postgresql/full_text_test.rb +44 -0
  68. data/test/cases/adapters/postgresql/geometric_test.rb +378 -0
  69. data/test/cases/adapters/postgresql/hstore_test.rb +382 -0
  70. data/test/cases/adapters/postgresql/infinity_test.rb +69 -0
  71. data/test/cases/adapters/postgresql/integer_test.rb +25 -0
  72. data/test/cases/adapters/postgresql/json_test.rb +237 -0
  73. data/test/cases/adapters/postgresql/ltree_test.rb +53 -0
  74. data/test/cases/adapters/postgresql/money_test.rb +96 -0
  75. data/test/cases/adapters/postgresql/network_test.rb +94 -0
  76. data/test/cases/adapters/postgresql/numbers_test.rb +49 -0
  77. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -0
  78. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
  79. data/test/cases/adapters/postgresql/quoting_test.rb +44 -0
  80. data/test/cases/adapters/postgresql/range_test.rb +343 -0
  81. data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -0
  82. data/test/cases/adapters/postgresql/rename_table_test.rb +34 -0
  83. data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -0
  84. data/test/cases/adapters/postgresql/schema_test.rb +597 -0
  85. data/test/cases/adapters/postgresql/serial_test.rb +154 -0
  86. data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -0
  87. data/test/cases/adapters/postgresql/timestamp_test.rb +90 -0
  88. data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -0
  89. data/test/cases/adapters/postgresql/utils_test.rb +62 -0
  90. data/test/cases/adapters/postgresql/uuid_test.rb +294 -0
  91. data/test/cases/adapters/postgresql/xml_test.rb +54 -0
  92. data/test/cases/adapters/sqlite3/collation_test.rb +53 -0
  93. data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -0
  94. data/test/cases/adapters/sqlite3/explain_test.rb +21 -0
  95. data/test/cases/adapters/sqlite3/quoting_test.rb +101 -0
  96. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -0
  97. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
  98. data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -0
  99. data/test/cases/aggregations_test.rb +168 -158
  100. data/test/cases/ar_schema_test.rb +146 -161
  101. data/test/cases/associations/association_scope_test.rb +16 -21
  102. data/test/cases/associations/belongs_to_associations_test.rb +1141 -1029
  103. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -0
  104. data/test/cases/associations/callbacks_test.rb +190 -192
  105. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  106. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  107. data/test/cases/associations/eager_load_nested_include_test.rb +126 -128
  108. data/test/cases/associations/eager_singularization_test.rb +148 -148
  109. data/test/cases/associations/eager_test.rb +1514 -1411
  110. data/test/cases/associations/extension_test.rb +87 -82
  111. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1004 -932
  112. data/test/cases/associations/has_many_associations_test.rb +2501 -2162
  113. data/test/cases/associations/has_many_through_associations_test.rb +1271 -1204
  114. data/test/cases/associations/has_one_associations_test.rb +707 -610
  115. data/test/cases/associations/has_one_through_associations_test.rb +383 -380
  116. data/test/cases/associations/inner_join_association_test.rb +139 -139
  117. data/test/cases/associations/inverse_associations_test.rb +733 -693
  118. data/test/cases/associations/join_model_test.rb +777 -754
  119. data/test/cases/associations/left_outer_join_association_test.rb +88 -0
  120. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  121. data/test/cases/associations/required_test.rb +102 -82
  122. data/test/cases/associations_test.rb +385 -380
  123. data/test/cases/attribute_decorators_test.rb +126 -125
  124. data/test/cases/attribute_methods/read_test.rb +60 -60
  125. data/test/cases/attribute_methods_test.rb +1009 -952
  126. data/test/cases/attribute_set_test.rb +270 -200
  127. data/test/cases/attribute_test.rb +246 -180
  128. data/test/cases/attributes_test.rb +253 -136
  129. data/test/cases/autosave_association_test.rb +1708 -1595
  130. data/test/cases/base_test.rb +1713 -1638
  131. data/test/cases/batches_test.rb +489 -212
  132. data/test/cases/binary_test.rb +44 -52
  133. data/test/cases/bind_parameter_test.rb +110 -100
  134. data/test/cases/cache_key_test.rb +26 -0
  135. data/test/cases/calculations_test.rb +798 -646
  136. data/test/cases/callbacks_test.rb +636 -543
  137. data/test/cases/clone_test.rb +40 -40
  138. data/test/cases/coders/json_test.rb +15 -0
  139. data/test/cases/coders/yaml_column_test.rb +63 -63
  140. data/test/cases/collection_cache_key_test.rb +115 -0
  141. data/test/cases/column_alias_test.rb +17 -17
  142. data/test/cases/column_definition_test.rb +92 -123
  143. data/test/cases/comment_test.rb +145 -0
  144. data/test/cases/connection_adapters/adapter_leasing_test.rb +56 -54
  145. data/test/cases/connection_adapters/connection_handler_test.rb +160 -53
  146. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  147. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +255 -293
  148. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +69 -65
  149. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  150. data/test/cases/connection_adapters/schema_cache_test.rb +61 -56
  151. data/test/cases/connection_adapters/type_lookup_test.rb +118 -110
  152. data/test/cases/connection_management_test.rb +112 -122
  153. data/test/cases/connection_pool_test.rb +521 -346
  154. data/test/cases/connection_specification/resolver_test.rb +131 -116
  155. data/test/cases/core_test.rb +112 -112
  156. data/test/cases/counter_cache_test.rb +214 -209
  157. data/test/cases/custom_locking_test.rb +17 -17
  158. data/test/cases/database_statements_test.rb +34 -19
  159. data/test/cases/{invalid_date_test.rb → date_test.rb} +44 -32
  160. data/test/cases/date_time_precision_test.rb +107 -0
  161. data/test/cases/date_time_test.rb +61 -61
  162. data/test/cases/defaults_test.rb +219 -223
  163. data/test/cases/dirty_test.rb +763 -775
  164. data/test/cases/disconnected_test.rb +30 -28
  165. data/test/cases/dup_test.rb +157 -157
  166. data/test/cases/enum_test.rb +444 -290
  167. data/test/cases/errors_test.rb +16 -0
  168. data/test/cases/explain_subscriber_test.rb +64 -64
  169. data/test/cases/explain_test.rb +87 -76
  170. data/test/cases/finder_respond_to_test.rb +60 -60
  171. data/test/cases/finder_test.rb +1294 -1166
  172. data/test/cases/fixture_set/file_test.rb +156 -138
  173. data/test/cases/fixtures_test.rb +988 -897
  174. data/test/cases/forbidden_attributes_protection_test.rb +165 -99
  175. data/test/cases/habtm_destroy_order_test.rb +61 -61
  176. data/test/cases/helper.rb +204 -210
  177. data/test/cases/hot_compatibility_test.rb +142 -54
  178. data/test/cases/i18n_test.rb +45 -45
  179. data/test/cases/inheritance_test.rb +606 -375
  180. data/test/cases/integration_test.rb +155 -139
  181. data/test/cases/invalid_connection_test.rb +24 -22
  182. data/test/cases/invertible_migration_test.rb +387 -295
  183. data/test/cases/json_serialization_test.rb +311 -302
  184. data/test/cases/locking_test.rb +493 -477
  185. data/test/cases/log_subscriber_test.rb +225 -136
  186. data/test/cases/migration/change_schema_test.rb +458 -472
  187. data/test/cases/migration/change_table_test.rb +256 -224
  188. data/test/cases/migration/column_attributes_test.rb +176 -192
  189. data/test/cases/migration/column_positioning_test.rb +56 -56
  190. data/test/cases/migration/columns_test.rb +310 -304
  191. data/test/cases/migration/command_recorder_test.rb +350 -305
  192. data/test/cases/migration/compatibility_test.rb +118 -0
  193. data/test/cases/migration/create_join_table_test.rb +157 -148
  194. data/test/cases/migration/foreign_key_test.rb +362 -360
  195. data/test/cases/migration/helper.rb +39 -39
  196. data/test/cases/migration/index_test.rb +218 -216
  197. data/test/cases/migration/logger_test.rb +36 -36
  198. data/test/cases/migration/pending_migrations_test.rb +52 -53
  199. data/test/cases/migration/references_foreign_key_test.rb +221 -214
  200. data/test/cases/migration/references_index_test.rb +101 -101
  201. data/test/cases/migration/references_statements_test.rb +136 -116
  202. data/test/cases/migration/rename_table_test.rb +93 -93
  203. data/test/cases/migration_test.rb +1157 -959
  204. data/test/cases/migrator_test.rb +471 -388
  205. data/test/cases/mixin_test.rb +68 -70
  206. data/test/cases/modules_test.rb +172 -173
  207. data/test/cases/multiparameter_attributes_test.rb +372 -350
  208. data/test/cases/multiple_db_test.rb +122 -115
  209. data/test/cases/nested_attributes_test.rb +1098 -1057
  210. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  211. data/test/cases/persistence_test.rb +1001 -909
  212. data/test/cases/pooled_connections_test.rb +81 -81
  213. data/test/cases/primary_keys_test.rb +376 -237
  214. data/test/cases/query_cache_test.rb +446 -326
  215. data/test/cases/quoting_test.rb +202 -156
  216. data/test/cases/readonly_test.rb +119 -118
  217. data/test/cases/reaper_test.rb +85 -85
  218. data/test/cases/reflection_test.rb +509 -454
  219. data/test/cases/relation/delegation_test.rb +63 -68
  220. data/test/cases/relation/merging_test.rb +157 -161
  221. data/test/cases/relation/mutation_test.rb +183 -165
  222. data/test/cases/relation/or_test.rb +92 -0
  223. data/test/cases/relation/predicate_builder_test.rb +16 -14
  224. data/test/cases/relation/record_fetch_warning_test.rb +40 -0
  225. data/test/cases/relation/where_chain_test.rb +105 -181
  226. data/test/cases/relation/where_clause_test.rb +182 -0
  227. data/test/cases/relation/where_test.rb +322 -300
  228. data/test/cases/relation_test.rb +328 -297
  229. data/test/cases/relations_test.rb +2026 -1815
  230. data/test/cases/reload_models_test.rb +22 -22
  231. data/test/cases/result_test.rb +90 -80
  232. data/test/cases/sanitize_test.rb +176 -83
  233. data/test/cases/schema_dumper_test.rb +457 -463
  234. data/test/cases/schema_loading_test.rb +52 -0
  235. data/test/cases/scoping/default_scoping_test.rb +528 -454
  236. data/test/cases/scoping/named_scoping_test.rb +561 -524
  237. data/test/cases/scoping/relation_scoping_test.rb +400 -357
  238. data/test/cases/secure_token_test.rb +32 -0
  239. data/test/cases/serialization_test.rb +104 -104
  240. data/test/cases/serialized_attribute_test.rb +364 -277
  241. data/test/cases/statement_cache_test.rb +136 -98
  242. data/test/cases/store_test.rb +195 -194
  243. data/test/cases/suppressor_test.rb +63 -0
  244. data/test/cases/tasks/database_tasks_test.rb +462 -396
  245. data/test/cases/tasks/mysql_rake_test.rb +345 -311
  246. data/test/cases/tasks/postgresql_rake_test.rb +304 -245
  247. data/test/cases/tasks/sqlite_rake_test.rb +220 -193
  248. data/test/cases/test_case.rb +131 -123
  249. data/test/cases/test_fixtures_test.rb +36 -0
  250. data/test/cases/time_precision_test.rb +103 -0
  251. data/test/cases/timestamp_test.rb +501 -468
  252. data/test/cases/touch_later_test.rb +121 -0
  253. data/test/cases/transaction_callbacks_test.rb +518 -452
  254. data/test/cases/transaction_isolation_test.rb +106 -106
  255. data/test/cases/transactions_test.rb +835 -817
  256. data/test/cases/type/adapter_specific_registry_test.rb +133 -0
  257. data/test/cases/type/date_time_test.rb +14 -0
  258. data/test/cases/type/integer_test.rb +27 -121
  259. data/test/cases/type/string_test.rb +22 -36
  260. data/test/cases/type/type_map_test.rb +177 -177
  261. data/test/cases/type_test.rb +39 -0
  262. data/test/cases/types_test.rb +24 -141
  263. data/test/cases/unconnected_test.rb +33 -33
  264. data/test/cases/validations/absence_validation_test.rb +73 -0
  265. data/test/cases/validations/association_validation_test.rb +97 -86
  266. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  267. data/test/cases/validations/i18n_validation_test.rb +86 -90
  268. data/test/cases/validations/length_validation_test.rb +79 -47
  269. data/test/cases/validations/presence_validation_test.rb +103 -68
  270. data/test/cases/validations/uniqueness_validation_test.rb +548 -434
  271. data/test/cases/validations_repair_helper.rb +19 -23
  272. data/test/cases/validations_test.rb +194 -165
  273. data/test/cases/view_test.rb +216 -113
  274. data/test/cases/yaml_serialization_test.rb +121 -86
  275. data/test/config.example.yml +97 -0
  276. data/test/config.rb +5 -5
  277. data/test/config.yml +154 -154
  278. data/test/connections/native_ibm_db/connection.rb +43 -43
  279. data/test/fixtures/accounts.yml +29 -29
  280. data/test/fixtures/admin/accounts.yml +2 -2
  281. data/test/fixtures/admin/randomly_named_a9.yml +7 -7
  282. data/test/fixtures/admin/randomly_named_b0.yml +7 -7
  283. data/test/fixtures/admin/users.yml +10 -10
  284. data/test/fixtures/author_addresses.yml +17 -17
  285. data/test/fixtures/author_favorites.yml +3 -3
  286. data/test/fixtures/authors.yml +23 -23
  287. data/test/fixtures/bad_posts.yml +9 -0
  288. data/test/fixtures/binaries.yml +133 -133
  289. data/test/fixtures/books.yml +31 -11
  290. data/test/fixtures/bulbs.yml +5 -5
  291. data/test/fixtures/cars.yml +9 -9
  292. data/test/fixtures/categories.yml +19 -19
  293. data/test/fixtures/categories/special_categories.yml +9 -9
  294. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  295. data/test/fixtures/categories_ordered.yml +7 -7
  296. data/test/fixtures/categories_posts.yml +31 -31
  297. data/test/fixtures/categorizations.yml +23 -23
  298. data/test/fixtures/clubs.yml +8 -8
  299. data/test/fixtures/collections.yml +3 -3
  300. data/test/fixtures/colleges.yml +3 -3
  301. data/test/fixtures/comments.yml +65 -65
  302. data/test/fixtures/companies.yml +67 -67
  303. data/test/fixtures/computers.yml +10 -10
  304. data/test/fixtures/content.yml +3 -0
  305. data/test/fixtures/content_positions.yml +3 -0
  306. data/test/fixtures/courses.yml +8 -8
  307. data/test/fixtures/customers.yml +25 -25
  308. data/test/fixtures/dashboards.yml +6 -6
  309. data/test/fixtures/dead_parrots.yml +5 -0
  310. data/test/fixtures/developers.yml +21 -21
  311. data/test/fixtures/developers_projects.yml +16 -16
  312. data/test/fixtures/dog_lovers.yml +7 -7
  313. data/test/fixtures/dogs.yml +4 -4
  314. data/test/fixtures/doubloons.yml +3 -3
  315. data/test/fixtures/edges.yml +5 -5
  316. data/test/fixtures/entrants.yml +14 -14
  317. data/test/fixtures/essays.yml +6 -6
  318. data/test/fixtures/faces.yml +11 -11
  319. data/test/fixtures/fk_test_has_fk.yml +3 -3
  320. data/test/fixtures/fk_test_has_pk.yml +1 -1
  321. data/test/fixtures/friendships.yml +4 -4
  322. data/test/fixtures/funny_jokes.yml +10 -10
  323. data/test/fixtures/interests.yml +33 -33
  324. data/test/fixtures/items.yml +3 -3
  325. data/test/fixtures/jobs.yml +7 -7
  326. data/test/fixtures/legacy_things.yml +3 -3
  327. data/test/fixtures/live_parrots.yml +4 -0
  328. data/test/fixtures/mateys.yml +4 -4
  329. data/test/fixtures/member_details.yml +8 -8
  330. data/test/fixtures/member_types.yml +6 -6
  331. data/test/fixtures/members.yml +11 -11
  332. data/test/fixtures/memberships.yml +34 -34
  333. data/test/fixtures/men.yml +5 -5
  334. data/test/fixtures/minimalistics.yml +2 -2
  335. data/test/fixtures/minivans.yml +5 -5
  336. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  337. data/test/fixtures/mixins.yml +29 -29
  338. data/test/fixtures/movies.yml +7 -7
  339. data/test/fixtures/naked/yml/accounts.yml +1 -1
  340. data/test/fixtures/naked/yml/companies.yml +1 -1
  341. data/test/fixtures/naked/yml/courses.yml +1 -1
  342. data/test/fixtures/naked/yml/parrots.yml +2 -0
  343. data/test/fixtures/naked/yml/trees.yml +3 -0
  344. data/test/fixtures/nodes.yml +29 -0
  345. data/test/fixtures/organizations.yml +5 -5
  346. data/test/fixtures/other_comments.yml +6 -0
  347. data/test/fixtures/other_dogs.yml +2 -0
  348. data/test/fixtures/other_posts.yml +7 -0
  349. data/test/fixtures/other_topics.yml +42 -42
  350. data/test/fixtures/owners.yml +9 -9
  351. data/test/fixtures/parrots.yml +27 -27
  352. data/test/fixtures/parrots_pirates.yml +7 -7
  353. data/test/fixtures/people.yml +24 -24
  354. data/test/fixtures/peoples_treasures.yml +3 -3
  355. data/test/fixtures/pets.yml +19 -19
  356. data/test/fixtures/pirates.yml +12 -12
  357. data/test/fixtures/posts.yml +80 -80
  358. data/test/fixtures/price_estimates.yml +16 -7
  359. data/test/fixtures/products.yml +4 -4
  360. data/test/fixtures/projects.yml +7 -7
  361. data/test/fixtures/randomly_named_a9.yml +7 -7
  362. data/test/fixtures/ratings.yml +14 -14
  363. data/test/fixtures/readers.yml +11 -11
  364. data/test/fixtures/references.yml +17 -17
  365. data/test/fixtures/reserved_words/distinct.yml +5 -5
  366. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  367. data/test/fixtures/reserved_words/group.yml +14 -14
  368. data/test/fixtures/reserved_words/select.yml +8 -8
  369. data/test/fixtures/reserved_words/values.yml +7 -7
  370. data/test/fixtures/ships.yml +6 -6
  371. data/test/fixtures/speedometers.yml +8 -8
  372. data/test/fixtures/sponsors.yml +12 -12
  373. data/test/fixtures/string_key_objects.yml +7 -7
  374. data/test/fixtures/subscribers.yml +10 -10
  375. data/test/fixtures/subscriptions.yml +12 -12
  376. data/test/fixtures/taggings.yml +78 -78
  377. data/test/fixtures/tags.yml +11 -11
  378. data/test/fixtures/tasks.yml +7 -7
  379. data/test/fixtures/teapots.yml +3 -3
  380. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  381. data/test/fixtures/to_be_linked/users.yml +10 -10
  382. data/test/fixtures/topics.yml +49 -49
  383. data/test/fixtures/toys.yml +14 -14
  384. data/test/fixtures/traffic_lights.yml +9 -9
  385. data/test/fixtures/treasures.yml +10 -10
  386. data/test/fixtures/trees.yml +3 -0
  387. data/test/fixtures/uuid_children.yml +3 -3
  388. data/test/fixtures/uuid_parents.yml +2 -2
  389. data/test/fixtures/variants.yml +4 -4
  390. data/test/fixtures/vegetables.yml +19 -19
  391. data/test/fixtures/vertices.yml +3 -3
  392. data/test/fixtures/warehouse_things.yml +2 -2
  393. data/test/fixtures/zines.yml +5 -5
  394. data/test/ibm_db_test.rb +24 -24
  395. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  396. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  397. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  398. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -9
  399. data/test/migrations/missing/1_people_have_last_names.rb +9 -9
  400. data/test/migrations/missing/3_we_need_reminders.rb +12 -12
  401. data/test/migrations/missing/4_innocent_jointable.rb +12 -12
  402. data/test/migrations/rename/1_we_need_things.rb +11 -11
  403. data/test/migrations/rename/2_rename_things.rb +9 -9
  404. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  405. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  406. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  407. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  408. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  409. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  410. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  411. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  412. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  413. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  414. data/test/migrations/valid/2_we_need_reminders.rb +12 -12
  415. data/test/migrations/valid/3_innocent_jointable.rb +12 -12
  416. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  417. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -12
  418. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -12
  419. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  420. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  421. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  422. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  423. data/test/models/admin.rb +4 -4
  424. data/test/models/admin/account.rb +2 -2
  425. data/test/models/admin/randomly_named_c1.rb +7 -3
  426. data/test/models/admin/user.rb +40 -40
  427. data/test/models/aircraft.rb +5 -4
  428. data/test/models/arunit2_model.rb +3 -3
  429. data/test/models/author.rb +209 -212
  430. data/test/models/auto_id.rb +4 -4
  431. data/test/models/autoloadable/extra_firm.rb +2 -2
  432. data/test/models/binary.rb +1 -1
  433. data/test/models/bird.rb +12 -12
  434. data/test/models/book.rb +23 -18
  435. data/test/models/boolean.rb +2 -2
  436. data/test/models/bulb.rb +52 -51
  437. data/test/models/cake_designer.rb +3 -3
  438. data/test/models/car.rb +29 -26
  439. data/test/models/carrier.rb +2 -2
  440. data/test/models/cat.rb +10 -0
  441. data/test/models/categorization.rb +19 -19
  442. data/test/models/category.rb +35 -35
  443. data/test/models/chef.rb +8 -3
  444. data/test/models/citation.rb +3 -3
  445. data/test/models/club.rb +25 -23
  446. data/test/models/college.rb +10 -10
  447. data/test/models/column.rb +3 -3
  448. data/test/models/column_name.rb +3 -3
  449. data/test/models/comment.rb +76 -64
  450. data/test/models/company.rb +230 -225
  451. data/test/models/company_in_module.rb +98 -98
  452. data/test/models/computer.rb +3 -3
  453. data/test/models/contact.rb +41 -41
  454. data/test/models/content.rb +40 -0
  455. data/test/models/contract.rb +20 -20
  456. data/test/models/country.rb +7 -7
  457. data/test/models/course.rb +6 -6
  458. data/test/models/customer.rb +83 -77
  459. data/test/models/customer_carrier.rb +14 -14
  460. data/test/models/dashboard.rb +3 -3
  461. data/test/models/default.rb +2 -2
  462. data/test/models/department.rb +4 -4
  463. data/test/models/developer.rb +274 -252
  464. data/test/models/dog.rb +5 -5
  465. data/test/models/dog_lover.rb +5 -5
  466. data/test/models/doubloon.rb +12 -12
  467. data/test/models/drink_designer.rb +3 -3
  468. data/test/models/edge.rb +5 -5
  469. data/test/models/electron.rb +5 -5
  470. data/test/models/engine.rb +4 -4
  471. data/test/models/entrant.rb +3 -3
  472. data/test/models/essay.rb +5 -5
  473. data/test/models/event.rb +2 -2
  474. data/test/models/eye.rb +37 -37
  475. data/test/models/face.rb +9 -9
  476. data/test/models/friendship.rb +6 -6
  477. data/test/models/guid.rb +1 -1
  478. data/test/models/guitar.rb +4 -0
  479. data/test/models/hotel.rb +11 -6
  480. data/test/models/image.rb +3 -3
  481. data/test/models/interest.rb +5 -5
  482. data/test/models/invoice.rb +4 -4
  483. data/test/models/item.rb +7 -7
  484. data/test/models/job.rb +7 -7
  485. data/test/models/joke.rb +7 -7
  486. data/test/models/keyboard.rb +3 -3
  487. data/test/models/legacy_thing.rb +3 -3
  488. data/test/models/lesson.rb +11 -11
  489. data/test/models/line_item.rb +3 -3
  490. data/test/models/liquid.rb +4 -4
  491. data/test/models/man.rb +11 -11
  492. data/test/models/matey.rb +4 -4
  493. data/test/models/member.rb +42 -41
  494. data/test/models/member_detail.rb +8 -7
  495. data/test/models/member_type.rb +3 -3
  496. data/test/models/membership.rb +35 -35
  497. data/test/models/mentor.rb +3 -0
  498. data/test/models/minimalistic.rb +2 -2
  499. data/test/models/minivan.rb +9 -9
  500. data/test/models/mixed_case_monkey.rb +3 -3
  501. data/test/models/mocktail_designer.rb +2 -0
  502. data/test/models/molecule.rb +6 -6
  503. data/test/models/movie.rb +5 -5
  504. data/test/models/node.rb +5 -0
  505. data/test/models/non_primary_key.rb +2 -0
  506. data/test/models/notification.rb +3 -0
  507. data/test/models/order.rb +4 -4
  508. data/test/models/organization.rb +14 -14
  509. data/test/models/other_dog.rb +5 -0
  510. data/test/models/owner.rb +37 -34
  511. data/test/models/parrot.rb +28 -29
  512. data/test/models/person.rb +142 -143
  513. data/test/models/personal_legacy_thing.rb +4 -4
  514. data/test/models/pet.rb +18 -15
  515. data/test/models/pet_treasure.rb +6 -0
  516. data/test/models/pirate.rb +92 -92
  517. data/test/models/possession.rb +3 -3
  518. data/test/models/post.rb +273 -264
  519. data/test/models/price_estimate.rb +4 -4
  520. data/test/models/professor.rb +5 -5
  521. data/test/models/project.rb +40 -29
  522. data/test/models/publisher.rb +2 -2
  523. data/test/models/publisher/article.rb +4 -4
  524. data/test/models/publisher/magazine.rb +3 -3
  525. data/test/models/randomly_named_c1.rb +3 -3
  526. data/test/models/rating.rb +4 -4
  527. data/test/models/reader.rb +23 -23
  528. data/test/models/recipe.rb +3 -0
  529. data/test/models/record.rb +2 -2
  530. data/test/models/reference.rb +22 -22
  531. data/test/models/reply.rb +61 -61
  532. data/test/models/ship.rb +39 -33
  533. data/test/models/ship_part.rb +7 -7
  534. data/test/models/shop.rb +17 -17
  535. data/test/models/shop_account.rb +6 -6
  536. data/test/models/speedometer.rb +6 -6
  537. data/test/models/sponsor.rb +7 -7
  538. data/test/models/string_key_object.rb +3 -3
  539. data/test/models/student.rb +4 -4
  540. data/test/models/subject.rb +16 -16
  541. data/test/models/subscriber.rb +8 -8
  542. data/test/models/subscription.rb +4 -4
  543. data/test/models/tag.rb +13 -7
  544. data/test/models/tagging.rb +13 -13
  545. data/test/models/task.rb +5 -5
  546. data/test/models/topic.rb +118 -124
  547. data/test/models/toy.rb +6 -6
  548. data/test/models/traffic_light.rb +4 -4
  549. data/test/models/treasure.rb +14 -14
  550. data/test/models/treaty.rb +7 -7
  551. data/test/models/tree.rb +3 -0
  552. data/test/models/tuning_peg.rb +4 -0
  553. data/test/models/tyre.rb +11 -11
  554. data/test/models/user.rb +14 -0
  555. data/test/models/uuid_child.rb +3 -3
  556. data/test/models/uuid_item.rb +6 -0
  557. data/test/models/uuid_parent.rb +3 -3
  558. data/test/models/vegetables.rb +24 -24
  559. data/test/models/vehicle.rb +6 -6
  560. data/test/models/vertex.rb +9 -9
  561. data/test/models/warehouse_thing.rb +5 -5
  562. data/test/models/wheel.rb +3 -3
  563. data/test/models/without_table.rb +3 -3
  564. data/test/models/zine.rb +3 -3
  565. data/test/schema/mysql2_specific_schema.rb +68 -58
  566. data/test/schema/oracle_specific_schema.rb +40 -43
  567. data/test/schema/postgresql_specific_schema.rb +114 -202
  568. data/test/schema/schema.rb +1057 -938
  569. data/test/schema/schema.rb.original +1057 -0
  570. data/test/schema/sqlite_specific_schema.rb +18 -22
  571. data/test/support/config.rb +43 -43
  572. data/test/support/connection.rb +23 -22
  573. data/test/support/connection_helper.rb +14 -14
  574. data/test/support/ddl_helper.rb +8 -8
  575. data/test/support/schema_dumping_helper.rb +20 -20
  576. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
  577. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
  578. metadata +146 -30
  579. data/lib/mswin32/rb19x/ibm_db.so +0 -0
  580. data/lib/mswin32/rb21x/i386/ibm_db.so +0 -0
  581. data/lib/mswin32/rb22x/i386/ibm_db.so +0 -0
  582. data/lib/mswin32/rb23x/i386/ibm_db.so +0 -0
  583. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +0 -26
  584. data/test/cases/attribute_methods/serialization_test.rb +0 -29
  585. data/test/cases/migration/change_schema_test - Copy.rb +0 -448
  586. data/test/cases/migration/foreign_key_test - Changed.rb +0 -325
  587. data/test/cases/migration/table_and_index_test.rb +0 -24
  588. data/test/cases/relation/where_test2.rb +0 -36
  589. data/test/cases/type/decimal_test.rb +0 -51
  590. data/test/cases/type/unsigned_integer_test.rb +0 -18
  591. data/test/cases/xml_serialization_test.rb +0 -457
  592. data/test/fixtures/naked/csv/accounts.csv +0 -1
  593. data/test/schema/mysql_specific_schema.rb +0 -70
@@ -1,136 +1,225 @@
1
- require "cases/helper"
2
- require "models/binary"
3
- require "models/developer"
4
- require "models/post"
5
- require "active_support/log_subscriber/test_helper"
6
-
7
- class LogSubscriberTest < ActiveRecord::TestCase
8
- include ActiveSupport::LogSubscriber::TestHelper
9
- include ActiveSupport::Logger::Severity
10
-
11
- class TestDebugLogSubscriber < ActiveRecord::LogSubscriber
12
- attr_reader :debugs
13
-
14
- def initialize
15
- @debugs = []
16
- super
17
- end
18
-
19
- def debug message
20
- @debugs << message
21
- end
22
- end
23
-
24
- fixtures :posts
25
-
26
- def setup
27
- @old_logger = ActiveRecord::Base.logger
28
- Developer.primary_key
29
- super
30
- ActiveRecord::LogSubscriber.attach_to(:active_record)
31
- end
32
-
33
- def teardown
34
- super
35
- ActiveRecord::LogSubscriber.log_subscribers.pop
36
- ActiveRecord::Base.logger = @old_logger
37
- end
38
-
39
- def set_logger(logger)
40
- ActiveRecord::Base.logger = logger
41
- end
42
-
43
- def test_schema_statements_are_ignored
44
- event = Struct.new(:duration, :payload)
45
-
46
- logger = TestDebugLogSubscriber.new
47
- assert_equal 0, logger.debugs.length
48
-
49
- logger.sql(event.new(0, sql: 'hi mom!'))
50
- assert_equal 1, logger.debugs.length
51
-
52
- logger.sql(event.new(0, sql: 'hi mom!', name: 'foo'))
53
- assert_equal 2, logger.debugs.length
54
-
55
- logger.sql(event.new(0, sql: 'hi mom!', name: 'SCHEMA'))
56
- assert_equal 2, logger.debugs.length
57
- end
58
-
59
- def test_sql_statements_are_not_squeezed
60
- event = Struct.new(:duration, :payload)
61
- logger = TestDebugLogSubscriber.new
62
- logger.sql(event.new(0, sql: 'ruby rails'))
63
- assert_match(/ruby rails/, logger.debugs.first)
64
- end
65
-
66
- def test_ignore_binds_payload_with_nil_column
67
- event = Struct.new(:duration, :payload)
68
-
69
- logger = TestDebugLogSubscriber.new
70
- logger.sql(event.new(0, sql: 'hi mom!', binds: [[nil, 1]]))
71
- assert_equal 1, logger.debugs.length
72
- end
73
-
74
- def test_basic_query_logging
75
- Developer.all.load
76
- wait
77
- assert_equal 1, @logger.logged(:debug).size
78
- assert_match(/Developer Load/, @logger.logged(:debug).last)
79
- assert_match(/SELECT .*?FROM .?developers.?/i, @logger.logged(:debug).last)
80
- end
81
-
82
- def test_exists_query_logging
83
- Developer.exists? 1
84
- wait
85
- assert_equal 1, @logger.logged(:debug).size
86
- assert_match(/Developer Exists/, @logger.logged(:debug).last)
87
- assert_match(/SELECT .*?FROM .?developers.?/i, @logger.logged(:debug).last)
88
- end
89
-
90
- def test_cached_queries
91
- ActiveRecord::Base.cache do
92
- Developer.all.load
93
- Developer.all.load
94
- end
95
- wait
96
- assert_equal 2, @logger.logged(:debug).size
97
- assert_match(/CACHE/, @logger.logged(:debug).last)
98
- assert_match(/SELECT .*?FROM .?developers.?/i, @logger.logged(:debug).last)
99
- end
100
-
101
- def test_basic_query_doesnt_log_when_level_is_not_debug
102
- @logger.level = INFO
103
- Developer.all.load
104
- wait
105
- assert_equal 0, @logger.logged(:debug).size
106
- end
107
-
108
- def test_cached_queries_doesnt_log_when_level_is_not_debug
109
- @logger.level = INFO
110
- ActiveRecord::Base.cache do
111
- Developer.all.load
112
- Developer.all.load
113
- end
114
- wait
115
- assert_equal 0, @logger.logged(:debug).size
116
- end
117
-
118
- def test_initializes_runtime
119
- Thread.new { assert_equal 0, ActiveRecord::LogSubscriber.runtime }.join
120
- end
121
-
122
- unless current_adapter?(:Mysql2Adapter)
123
- def test_binary_data_is_not_logged
124
- Binary.create(data: 'some binary data')
125
- wait
126
- assert_match(/<16 bytes of binary data>/, @logger.logged(:debug).join)
127
- end
128
-
129
- def test_nil_binary_data_is_logged
130
- binary = Binary.create(data: "")
131
- binary.update_attributes(data: nil)
132
- wait
133
- assert_match(/<NULL binary data>/, @logger.logged(:debug).join)
134
- end
135
- end
136
- end
1
+ require "cases/helper"
2
+ require "models/binary"
3
+ require "models/developer"
4
+ require "models/post"
5
+ require "active_support/log_subscriber/test_helper"
6
+
7
+ class LogSubscriberTest < ActiveRecord::TestCase
8
+ include ActiveSupport::LogSubscriber::TestHelper
9
+ include ActiveSupport::Logger::Severity
10
+ REGEXP_CLEAR = Regexp.escape(ActiveRecord::LogSubscriber::CLEAR)
11
+ REGEXP_BOLD = Regexp.escape(ActiveRecord::LogSubscriber::BOLD)
12
+ REGEXP_MAGENTA = Regexp.escape(ActiveRecord::LogSubscriber::MAGENTA)
13
+ REGEXP_CYAN = Regexp.escape(ActiveRecord::LogSubscriber::CYAN)
14
+ SQL_COLORINGS = {
15
+ SELECT: Regexp.escape(ActiveRecord::LogSubscriber::BLUE),
16
+ INSERT: Regexp.escape(ActiveRecord::LogSubscriber::GREEN),
17
+ UPDATE: Regexp.escape(ActiveRecord::LogSubscriber::YELLOW),
18
+ DELETE: Regexp.escape(ActiveRecord::LogSubscriber::RED),
19
+ LOCK: Regexp.escape(ActiveRecord::LogSubscriber::WHITE),
20
+ ROLLBACK: Regexp.escape(ActiveRecord::LogSubscriber::RED),
21
+ TRANSACTION: REGEXP_CYAN,
22
+ OTHER: REGEXP_MAGENTA
23
+ }
24
+
25
+ class TestDebugLogSubscriber < ActiveRecord::LogSubscriber
26
+ attr_reader :debugs
27
+
28
+ def initialize
29
+ @debugs = []
30
+ super
31
+ end
32
+
33
+ def debug message
34
+ @debugs << message
35
+ end
36
+ end
37
+
38
+ fixtures :posts
39
+
40
+ def setup
41
+ @old_logger = ActiveRecord::Base.logger
42
+ Developer.primary_key
43
+ super
44
+ ActiveRecord::LogSubscriber.attach_to(:active_record)
45
+ end
46
+
47
+ def teardown
48
+ super
49
+ ActiveRecord::LogSubscriber.log_subscribers.pop
50
+ ActiveRecord::Base.logger = @old_logger
51
+ end
52
+
53
+ def set_logger(logger)
54
+ ActiveRecord::Base.logger = logger
55
+ end
56
+
57
+ def test_schema_statements_are_ignored
58
+ event = Struct.new(:duration, :payload)
59
+
60
+ logger = TestDebugLogSubscriber.new
61
+ assert_equal 0, logger.debugs.length
62
+
63
+ logger.sql(event.new(0.9, sql: "hi mom!"))
64
+ assert_equal 1, logger.debugs.length
65
+
66
+ logger.sql(event.new(0.9, sql: "hi mom!", name: "foo"))
67
+ assert_equal 2, logger.debugs.length
68
+
69
+ logger.sql(event.new(0.9, sql: "hi mom!", name: "SCHEMA"))
70
+ assert_equal 2, logger.debugs.length
71
+ end
72
+
73
+ def test_sql_statements_are_not_squeezed
74
+ event = Struct.new(:duration, :payload)
75
+ logger = TestDebugLogSubscriber.new
76
+ logger.sql(event.new(0.9, sql: "ruby rails"))
77
+ assert_match(/ruby rails/, logger.debugs.first)
78
+ end
79
+
80
+ def test_basic_query_logging
81
+ Developer.all.load
82
+ wait
83
+ assert_equal 1, @logger.logged(:debug).size
84
+ assert_match(/Developer Load/, @logger.logged(:debug).last)
85
+ assert_match(/SELECT .*?FROM .?developers.?/i, @logger.logged(:debug).last)
86
+ end
87
+
88
+ def test_basic_query_logging_coloration
89
+ event = Struct.new(:duration, :payload)
90
+ logger = TestDebugLogSubscriber.new
91
+ logger.colorize_logging = true
92
+ SQL_COLORINGS.each do |verb, color_regex|
93
+ logger.sql(event.new(0.9, sql: verb.to_s))
94
+ assert_match(/#{REGEXP_BOLD}#{color_regex}#{verb}#{REGEXP_CLEAR}/i, logger.debugs.last)
95
+ end
96
+ end
97
+
98
+ def test_basic_payload_name_logging_coloration_generic_sql
99
+ event = Struct.new(:duration, :payload)
100
+ logger = TestDebugLogSubscriber.new
101
+ logger.colorize_logging = true
102
+ SQL_COLORINGS.each do |verb, _|
103
+ logger.sql(event.new(0.9, sql: verb.to_s))
104
+ assert_match(/#{REGEXP_BOLD}#{REGEXP_MAGENTA} \(0\.9ms\)#{REGEXP_CLEAR}/i, logger.debugs.last)
105
+
106
+ logger.sql(event.new(0.9, sql: verb.to_s, name: "SQL"))
107
+ assert_match(/#{REGEXP_BOLD}#{REGEXP_MAGENTA}SQL \(0\.9ms\)#{REGEXP_CLEAR}/i, logger.debugs.last)
108
+ end
109
+ end
110
+
111
+ def test_basic_payload_name_logging_coloration_named_sql
112
+ event = Struct.new(:duration, :payload)
113
+ logger = TestDebugLogSubscriber.new
114
+ logger.colorize_logging = true
115
+ SQL_COLORINGS.each do |verb, _|
116
+ logger.sql(event.new(0.9, sql: verb.to_s, name: "Model Load"))
117
+ assert_match(/#{REGEXP_BOLD}#{REGEXP_CYAN}Model Load \(0\.9ms\)#{REGEXP_CLEAR}/i, logger.debugs.last)
118
+
119
+ logger.sql(event.new(0.9, sql: verb.to_s, name: "Model Exists"))
120
+ assert_match(/#{REGEXP_BOLD}#{REGEXP_CYAN}Model Exists \(0\.9ms\)#{REGEXP_CLEAR}/i, logger.debugs.last)
121
+
122
+ logger.sql(event.new(0.9, sql: verb.to_s, name: "ANY SPECIFIC NAME"))
123
+ assert_match(/#{REGEXP_BOLD}#{REGEXP_CYAN}ANY SPECIFIC NAME \(0\.9ms\)#{REGEXP_CLEAR}/i, logger.debugs.last)
124
+ end
125
+ end
126
+
127
+ def test_query_logging_coloration_with_nested_select
128
+ event = Struct.new(:duration, :payload)
129
+ logger = TestDebugLogSubscriber.new
130
+ logger.colorize_logging = true
131
+ SQL_COLORINGS.slice(:SELECT, :INSERT, :UPDATE, :DELETE).each do |verb, color_regex|
132
+ logger.sql(event.new(0.9, sql: "#{verb} WHERE ID IN SELECT"))
133
+ assert_match(/#{REGEXP_BOLD}#{REGEXP_MAGENTA} \(0\.9ms\)#{REGEXP_CLEAR} #{REGEXP_BOLD}#{color_regex}#{verb} WHERE ID IN SELECT#{REGEXP_CLEAR}/i, logger.debugs.last)
134
+ end
135
+ end
136
+
137
+ def test_query_logging_coloration_with_multi_line_nested_select
138
+ event = Struct.new(:duration, :payload)
139
+ logger = TestDebugLogSubscriber.new
140
+ logger.colorize_logging = true
141
+ SQL_COLORINGS.slice(:SELECT, :INSERT, :UPDATE, :DELETE).each do |verb, color_regex|
142
+ sql = <<-EOS
143
+ #{verb}
144
+ WHERE ID IN (
145
+ SELECT ID FROM THINGS
146
+ )
147
+ EOS
148
+ logger.sql(event.new(0.9, sql: sql))
149
+ assert_match(/#{REGEXP_BOLD}#{REGEXP_MAGENTA} \(0\.9ms\)#{REGEXP_CLEAR} #{REGEXP_BOLD}#{color_regex}.*#{verb}.*#{REGEXP_CLEAR}/mi, logger.debugs.last)
150
+ end
151
+ end
152
+
153
+ def test_query_logging_coloration_with_lock
154
+ event = Struct.new(:duration, :payload)
155
+ logger = TestDebugLogSubscriber.new
156
+ logger.colorize_logging = true
157
+ sql = <<-EOS
158
+ SELECT * FROM
159
+ (SELECT * FROM mytable FOR UPDATE) ss
160
+ WHERE col1 = 5;
161
+ EOS
162
+ logger.sql(event.new(0.9, sql: sql))
163
+ assert_match(/#{REGEXP_BOLD}#{REGEXP_MAGENTA} \(0\.9ms\)#{REGEXP_CLEAR} #{REGEXP_BOLD}#{SQL_COLORINGS[:LOCK]}.*FOR UPDATE.*#{REGEXP_CLEAR}/mi, logger.debugs.last)
164
+
165
+ sql = <<-EOS
166
+ LOCK TABLE films IN SHARE MODE;
167
+ EOS
168
+ logger.sql(event.new(0.9, sql: sql))
169
+ assert_match(/#{REGEXP_BOLD}#{REGEXP_MAGENTA} \(0\.9ms\)#{REGEXP_CLEAR} #{REGEXP_BOLD}#{SQL_COLORINGS[:LOCK]}.*LOCK TABLE.*#{REGEXP_CLEAR}/mi, logger.debugs.last)
170
+ end
171
+
172
+ def test_exists_query_logging
173
+ Developer.exists? 1
174
+ wait
175
+ assert_equal 1, @logger.logged(:debug).size
176
+ assert_match(/Developer Exists/, @logger.logged(:debug).last)
177
+ assert_match(/SELECT .*?FROM .?developers.?/i, @logger.logged(:debug).last)
178
+ end
179
+
180
+ def test_cached_queries
181
+ ActiveRecord::Base.cache do
182
+ Developer.all.load
183
+ Developer.all.load
184
+ end
185
+ wait
186
+ assert_equal 2, @logger.logged(:debug).size
187
+ assert_match(/CACHE/, @logger.logged(:debug).last)
188
+ assert_match(/SELECT .*?FROM .?developers.?/i, @logger.logged(:debug).last)
189
+ end
190
+
191
+ def test_basic_query_doesnt_log_when_level_is_not_debug
192
+ @logger.level = INFO
193
+ Developer.all.load
194
+ wait
195
+ assert_equal 0, @logger.logged(:debug).size
196
+ end
197
+
198
+ def test_cached_queries_doesnt_log_when_level_is_not_debug
199
+ @logger.level = INFO
200
+ ActiveRecord::Base.cache do
201
+ Developer.all.load
202
+ Developer.all.load
203
+ end
204
+ wait
205
+ assert_equal 0, @logger.logged(:debug).size
206
+ end
207
+
208
+ def test_initializes_runtime
209
+ Thread.new { assert_equal 0, ActiveRecord::LogSubscriber.runtime }.join
210
+ end
211
+
212
+ if ActiveRecord::Base.connection.prepared_statements
213
+ def test_binary_data_is_not_logged
214
+ Binary.create(data: 'some binary data')
215
+ wait
216
+ assert_match(/<16 bytes of binary data>/, @logger.logged(:debug).join)
217
+ end
218
+
219
+ def test_binary_data_hash
220
+ Binary.create(data: { a: 1 })
221
+ wait
222
+ assert_match(/<7 bytes of binary data>/, @logger.logged(:debug).join)
223
+ end
224
+ end
225
+ end
@@ -1,472 +1,458 @@
1
- require 'cases/helper'
2
-
3
- module ActiveRecord
4
- class Migration
5
- class ChangeSchemaTest < ActiveRecord::TestCase
6
- attr_reader :connection, :table_name
7
-
8
- def setup
9
- super
10
- @connection = ActiveRecord::Base.connection
11
- @table_name = :testings
12
- end
13
-
14
- teardown do
15
- connection.drop_table :testings rescue nil
16
- ActiveRecord::Base.primary_key_prefix_type = nil
17
- ActiveRecord::Base.clear_cache!
18
- end
19
-
20
- def test_create_table_without_id
21
- testing_table_with_only_foo_attribute do
22
- assert_equal connection.columns(:testings).size, 1
23
- end
24
- end
25
-
26
- unless current_adapter?(:IBM_DBAdapter)
27
- # For DB2: Cannot add a primary key to a table with some rows already in it as it violates the unique constraint
28
- # Secondly GENERATED BY DEFAULT AS IDENTITY cannot be applied in a alter table command.
29
- # as this will be wrong sql syntax for DB
30
- def test_add_column_with_primary_key_attribute
31
- testing_table_with_only_foo_attribute do
32
- connection.add_column :testings, :id, :primary_key
33
- assert_equal connection.columns(:testings).size, 2
34
- end
35
- end
36
- end
37
-
38
- def test_create_table_adds_id
39
- connection.drop_table :testings rescue nil
40
- connection.create_table :testings do |t|
41
- t.column :foo, :string
42
- end
43
-
44
- assert_equal %w(id foo), connection.columns(:testings).map(&:name)
45
- end
46
-
47
- def test_create_table_with_not_null_column
48
- connection.drop_table :testings rescue nil
49
- connection.create_table :testings do |t|
50
- t.column :foo, :string, :null => false
51
- end
52
-
53
- assert_raises(ActiveRecord::StatementInvalid) do
54
- connection.execute "insert into testings (foo) values (NULL)"
55
- end
56
- end
57
-
58
- def test_create_table_with_defaults
59
- # MySQL doesn't allow defaults on TEXT or BLOB columns.
60
- mysql = current_adapter?(:MysqlAdapter, :Mysql2Adapter, :IBM_DBAdapter)
61
- connection.drop_table :testings rescue nil
62
- connection.create_table :testings do |t|
63
- t.column :one, :string, :default => "hello"
64
- t.column :two, :boolean, :default => true
65
- t.column :three, :boolean, :default => false
66
- t.column :four, :integer, :default => 1
67
- t.column :five, :text, :default => "hello" unless mysql
68
- end
69
-
70
- columns = connection.columns(:testings)
71
- one = columns.detect { |c| c.name == "one" }
72
- two = columns.detect { |c| c.name == "two" }
73
- three = columns.detect { |c| c.name == "three" }
74
- four = columns.detect { |c| c.name == "four" }
75
- five = columns.detect { |c| c.name == "five" } unless mysql
76
-
77
- assert_equal "hello", one.default
78
- assert_equal true, two.type_cast_from_database(two.default)
79
- assert_equal false, three.type_cast_from_database(three.default)
80
- assert_equal '1', four.default
81
- assert_equal "hello", five.default unless mysql
82
- end
83
-
84
- if current_adapter?(:PostgreSQLAdapter)
85
- def test_add_column_with_array
86
- connection.drop_table :testings rescue nil
87
- connection.create_table :testings
88
- connection.add_column :testings, :foo, :string, :array => true
89
-
90
- columns = connection.columns(:testings)
91
- array_column = columns.detect { |c| c.name == "foo" }
92
-
93
- assert array_column.array
94
- end
95
-
96
- def test_create_table_with_array_column
97
- connection.drop_table :testings rescue nil
98
- connection.create_table :testings do |t|
99
- t.string :foo, :array => true
100
- end
101
-
102
- columns = connection.columns(:testings)
103
- array_column = columns.detect { |c| c.name == "foo" }
104
-
105
- assert array_column.array
106
- end
107
- end
108
-
109
- def test_create_table_with_bigint
110
- connection.drop_table :testings rescue nil
111
- connection.create_table :testings do |t|
112
- t.bigint :eight_int
113
- end
114
- columns = connection.columns(:testings)
115
- eight = columns.detect { |c| c.name == "eight_int" }
116
-
117
- if current_adapter?(:OracleAdapter)
118
- assert_equal 'NUMBER(19)', eight.sql_type
119
- elsif current_adapter?(:SQLite3Adapter)
120
- assert_equal 'bigint', eight.sql_type
121
- else
122
- assert_equal :integer, eight.type
123
- assert_equal 8, eight.limit
124
- end
125
- ensure
126
- connection.drop_table :testings
127
- end
128
-
129
- def test_create_table_with_limits
130
- connection.drop_table :testings rescue nil
131
- connection.create_table :testings do |t|
132
- t.column :foo, :string, :limit => 255
133
-
134
- t.column :default_int, :integer
135
-
136
- t.column :one_int, :integer, :limit => 1
137
- t.column :four_int, :integer, :limit => 4
138
- t.column :eight_int, :integer, :limit => 8
139
- end
140
-
141
- columns = connection.columns(:testings)
142
- foo = columns.detect { |c| c.name == "foo" }
143
- assert_equal 255, foo.limit
144
-
145
- default = columns.detect { |c| c.name == "default_int" }
146
- one = columns.detect { |c| c.name == "one_int" }
147
- four = columns.detect { |c| c.name == "four_int" }
148
- eight = columns.detect { |c| c.name == "eight_int" }
149
-
150
- if current_adapter?(:PostgreSQLAdapter)
151
- assert_equal 'integer', default.sql_type
152
- assert_equal 'smallint', one.sql_type
153
- assert_equal 'integer', four.sql_type
154
- assert_equal 'bigint', eight.sql_type
155
- elsif current_adapter?(:MysqlAdapter, :Mysql2Adapter)
156
- assert_match 'int(11)', default.sql_type
157
- assert_match 'tinyint', one.sql_type
158
- assert_match 'int', four.sql_type
159
- assert_match 'bigint', eight.sql_type
160
- elsif current_adapter?(:OracleAdapter)
161
- assert_equal 'NUMBER(38)', default.sql_type
162
- assert_equal 'NUMBER(1)', one.sql_type
163
- assert_equal 'NUMBER(4)', four.sql_type
164
- assert_equal 'NUMBER(8)', eight.sql_type
165
- end
166
- end
167
-
168
- def test_create_table_with_primary_key_prefix_as_table_name_with_underscore
169
- ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore
170
- connection.drop_table :testings rescue nil
171
- connection.create_table :testings do |t|
172
- t.column :foo, :string
173
- end
174
-
175
- assert_equal %w(testing_id foo), connection.columns(:testings).map(&:name)
176
- end
177
-
178
- def test_create_table_with_primary_key_prefix_as_table_name
179
- ActiveRecord::Base.primary_key_prefix_type = :table_name
180
- connection.drop_table :testings rescue nil
181
- connection.create_table :testings do |t|
182
- t.column :foo, :string
183
- end
184
-
185
- assert_equal %w(testingid foo), connection.columns(:testings).map(&:name)
186
- end
187
-
188
- def test_create_table_raises_when_redefining_primary_key_column
189
-
190
- unless current_adapter?(:IBM_DBAdapter)
191
- #DB2 instead of ArgumentError exception, thorws Class: <ActiveRecord::StatementInvalid> Message: <"RuntimeError: Failed to execute statement due to: [IBM][CLI Driver][DB2/NT64] SQL0612N \"ID\" is a duplicate name. SQLSTATE=42711\r SQLCODE=-612: CREATE TABLE testings (id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 10000) PRIMARY KEY, id varchar(255)) ">
192
- error = assert_raise(ArgumentError) do
193
- connection.drop_table :testings rescue nil
194
- connection.create_table :testings do |t|
195
- t.column :id, :string
196
- end
197
- end
198
- assert_equal "you can't redefine the primary key column 'id'. To define a custom primary key, pass { id: false } to create_table.", error.message
199
- end
200
- end
201
-
202
- def test_create_table_raises_when_redefining_custom_primary_key_column
203
- connection.drop_table :testings rescue nil
204
- error = assert_raise(ArgumentError) do
205
- connection.create_table :testings, primary_key: :testing_id do |t|
206
- t.column :testing_id, :string
207
- end
208
- end
209
-
210
- assert_equal "you can't redefine the primary key column 'testing_id'. To define a custom primary key, pass { id: false } to create_table.", error.message
211
- end
212
-
213
- def test_create_table_with_timestamps_should_create_datetime_columns
214
- # FIXME: Remove the silence when we change the default `null` behavior
215
- ActiveSupport::Deprecation.silence do
216
- connection.drop_table :testings rescue nil
217
- connection.create_table table_name do |t|
218
- t.timestamps
219
- end
220
- end
221
- created_columns = connection.columns(table_name)
222
-
223
- created_at_column = created_columns.detect {|c| c.name == 'created_at' }
224
- updated_at_column = created_columns.detect {|c| c.name == 'updated_at' }
225
-
226
- assert created_at_column.null
227
- assert updated_at_column.null
228
- end
229
-
230
- def test_create_table_with_timestamps_should_create_datetime_columns_with_options
231
- connection.drop_table :testings rescue nil
232
- connection.create_table table_name do |t|
233
- t.timestamps :null => false
234
- end
235
- created_columns = connection.columns(table_name)
236
-
237
- created_at_column = created_columns.detect {|c| c.name == 'created_at' }
238
- updated_at_column = created_columns.detect {|c| c.name == 'updated_at' }
239
-
240
- assert !created_at_column.null
241
- assert !updated_at_column.null
242
- end
243
-
244
- def test_create_table_without_a_block
245
- connection.drop_table :testings rescue nil
246
- connection.create_table table_name
247
- end
248
-
249
- # Sybase, and SQLite3 will not allow you to add a NOT NULL
250
- # column to a table without a default value.
251
- unless current_adapter?(:SybaseAdapter, :SQLite3Adapter, :IBM_DBAdapter)
252
- def test_add_column_not_null_without_default
253
- connection.drop_table :testings rescue nil
254
- connection.create_table :testings do |t|
255
- t.column :foo, :string
256
- end
257
- connection.add_column :testings, :bar, :string, :null => false
258
-
259
- assert_raise(ActiveRecord::StatementInvalid) do
260
- connection.execute "insert into testings (foo, bar) values ('hello', NULL)"
261
- end
262
- end
263
- end
264
-
265
- def test_add_column_not_null_with_default
266
- connection.drop_table :testings rescue nil
267
- connection.create_table :testings do |t|
268
- t.column :foo, :string
269
- end
270
-
271
- con = connection
272
- connection.enable_identity_insert("testings", true) if current_adapter?(:SybaseAdapter)
273
- connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}) values (1, 'hello')"
274
- connection.enable_identity_insert("testings", false) if current_adapter?(:SybaseAdapter)
275
- assert_nothing_raised {connection.add_column :testings, :bar, :string, :null => false, :default => "default" }
276
-
277
- assert_raises(ActiveRecord::StatementInvalid) do
278
- unless current_adapter?(:OpenBaseAdapter)
279
- connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}, #{con.quote_column_name('bar')}) values (2, 'hello', NULL)"
280
- else
281
- connection.insert("INSERT INTO testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}, #{con.quote_column_name('bar')}) VALUES (2, 'hello', NULL)",
282
- "Testing Insert","id",2)
283
- end
284
- end
285
- end
286
-
287
- def test_change_column_quotes_column_names
288
- connection.drop_table :testings rescue nil
289
- connection.create_table :testings do |t|
290
- unless current_adapter?(:IBM_DBAdapter)
291
- t.column :select, :string
292
- else
293
- # If no limit specified by default column of length 255 is created, which later cannot be scaled down to 10
294
- t.column :select, :string, :limit => 5
295
- end
296
- end
297
-
298
- connection.change_column :testings, :select, :string, :limit => 10
299
-
300
- # Oracle needs primary key value from sequence
301
- if current_adapter?(:OracleAdapter)
302
- connection.execute "insert into testings (id, #{connection.quote_column_name('select')}) values (testings_seq.nextval, '7 chars')"
303
- else
304
- connection.execute "insert into testings (#{connection.quote_column_name('select')}) values ('7 chars')"
305
- end
306
- end
307
-
308
- def test_keeping_default_and_notnull_constraints_on_change
309
- connection.drop_table :testings rescue nil
310
- connection.create_table :testings do |t|
311
- t.column :title, :string
312
- end
313
- person_klass = Class.new(ActiveRecord::Base)
314
- person_klass.table_name = 'testings'
315
-
316
- person_klass.connection.add_column "testings", "wealth", :integer, :null => false, :default => 99
317
- person_klass.reset_column_information
318
- assert_equal "99", person_klass.columns_hash["wealth"].default
319
- assert_equal false, person_klass.columns_hash["wealth"].null
320
- # Oracle needs primary key value from sequence
321
- if current_adapter?(:OracleAdapter)
322
- assert_nothing_raised {person_klass.connection.execute("insert into testings (id, title) values (testings_seq.nextval, 'tester')")}
323
- else
324
- assert_nothing_raised {person_klass.connection.execute("insert into testings (title) values ('tester')")}
325
- end
326
-
327
- # change column default to see that column doesn't lose its not null definition
328
- person_klass.connection.change_column_default "testings", "wealth", 100
329
- person_klass.reset_column_information
330
- assert_equal "100", person_klass.columns_hash["wealth"].default
331
- assert_equal false, person_klass.columns_hash["wealth"].null
332
-
333
- if (!current_adapter?(:IBM_DBAdapter))
334
- # rename column to see that column doesn't lose its not null and/or default definition
335
- person_klass.connection.rename_column "testings", "wealth", "money"
336
- person_klass.reset_column_information
337
- assert_nil person_klass.columns_hash["wealth"]
338
- assert_equal 100, person_klass.columns_hash["money"].default
339
- assert_equal false, person_klass.columns_hash["money"].null
340
- end
341
-
342
- # change column
343
- unless current_adapter?(:IBM_DBAdapter)
344
- person_klass.connection.change_column "testings", "money", :integer, :null => false, :default => 1000
345
- person_klass.reset_column_information
346
- assert_equal 1000, person_klass.columns_hash["money"].default
347
- assert_equal false, person_klass.columns_hash["money"].null
348
- else
349
- person_klass.connection.change_column "testings", "wealth", :decimal, :precision => 15, :scale => 1,:null => false, :default => 1000
350
- person_klass.reset_column_information
351
- assert_equal "1000", person_klass.columns_hash["wealth"].default
352
- assert_equal false, person_klass.columns_hash["wealth"].null
353
- end
354
-
355
- # change column, make it nullable and clear default
356
- unless current_adapter?(:IBM_DBAdapter)
357
- person_klass.connection.change_column "testings", "money", :integer, :null => true, :default => nil
358
- person_klass.reset_column_information
359
- assert_nil person_klass.columns_hash["money"].default
360
- assert_equal true, person_klass.columns_hash["money"].null
361
- else
362
- person_klass.connection.change_column "testings", "wealth", :decimal, :precision => 20, :scale => 2, :null => true, :default => nil
363
- person_klass.reset_column_information
364
- assert_nil person_klass.columns_hash["wealth"].default
365
- assert_equal true, person_klass.columns_hash["wealth"].null
366
- end
367
-
368
- # change_column_null, make it not nullable and set null values to a default value
369
- unless current_adapter?(:IBM_DBAdapter)
370
- person_klass.connection.execute('UPDATE testings SET money = NULL')
371
- person_klass.connection.change_column_null "testings", "money", false, 2000
372
- person_klass.reset_column_information
373
- assert_nil person_klass.columns_hash["money"].default
374
- assert_equal false, person_klass.columns_hash["money"].null
375
- assert_equal [2000], Person.connection.select_values("SELECT money FROM testings").map { |s| s.to_i }.sort
376
- else
377
- # Trying to set the value of the column wealth to NULL and
378
- # in the next statement a not null constraint is being applied which is wrong
379
- #person_klass.connection.execute('UPDATE testings SET money = NULL')
380
- person_klass.connection.change_column_null "testings", "wealth", false, 2000
381
- person_klass.reset_column_information
382
- #assert_nil person_klass.columns_hash["wealth"].default #Setting default to 2000 and expecting nil is nor correct
383
- assert_not_nil person_klass.columns_hash["wealth"].default
384
- assert_equal false, person_klass.columns_hash["wealth"].null
385
- #Changing default does not change the already inserted value. Hence expecting 2000 is wrong.
386
- #assert_equal [99], Person.connection.select_values("SELECT wealth FROM testings").map { |s| s.to_i }.sort
387
- assert_equal [99], person_klass.connection.select_values("SELECT wealth FROM testings").map { |s| s.to_i }.sort
388
- end
389
- end
390
-
391
- def test_change_column_null
392
- testing_table_with_only_foo_attribute do
393
- notnull_migration = Class.new(ActiveRecord::Migration) do
394
- def change
395
- change_column_null :testings, :foo, false
396
- end
397
- end
398
- notnull_migration.new.suppress_messages do
399
- notnull_migration.migrate(:up)
400
- assert_equal false, connection.columns(:testings).find{ |c| c.name == "foo"}.null
401
- notnull_migration.migrate(:down)
402
- assert connection.columns(:testings).find{ |c| c.name == "foo"}.null
403
- end
404
- end
405
- end
406
-
407
- def test_column_exists
408
- connection.drop_table :testings rescue nil
409
- connection.create_table :testings do |t|
410
- t.column :foo, :string
411
- end
412
-
413
- assert connection.column_exists?(:testings, :foo)
414
- assert_not connection.column_exists?(:testings, :bar)
415
- end
416
-
417
- def test_column_exists_with_type
418
- connection.drop_table :testings rescue nil
419
- connection.create_table :testings do |t|
420
- t.column :foo, :string
421
- t.column :bar, :decimal, :precision => 8, :scale => 2
422
- end
423
-
424
- assert connection.column_exists?(:testings, :foo, :string)
425
- assert_not connection.column_exists?(:testings, :foo, :integer)
426
-
427
- assert connection.column_exists?(:testings, :bar, :decimal)
428
- assert_not connection.column_exists?(:testings, :bar, :integer)
429
- end
430
-
431
- def test_column_exists_with_definition
432
- connection.drop_table :testings rescue nil
433
- connection.create_table :testings do |t|
434
- t.column :foo, :string, limit: 100
435
- t.column :bar, :decimal, precision: 8, scale: 2
436
- t.column :taggable_id, :integer, null: false
437
- t.column :taggable_type, :string, default: 'Photo'
438
- end
439
-
440
- assert connection.column_exists?(:testings, :foo, :string, limit: 100)
441
- assert_not connection.column_exists?(:testings, :foo, :string, limit: nil)
442
- assert connection.column_exists?(:testings, :bar, :decimal, precision: 8, scale: 2)
443
- assert_not connection.column_exists?(:testings, :bar, :decimal, precision: nil, scale: nil)
444
- assert connection.column_exists?(:testings, :taggable_id, :integer, null: false)
445
- assert_not connection.column_exists?(:testings, :taggable_id, :integer, null: true)
446
- assert connection.column_exists?(:testings, :taggable_type, :string, default: 'Photo')
447
- assert_not connection.column_exists?(:testings, :taggable_type, :string, default: nil)
448
- end
449
-
450
- def test_column_exists_on_table_with_no_options_parameter_supplied
451
- connection.drop_table :testings rescue nil
452
- connection.create_table :testings do |t|
453
- t.string :foo
454
- end
455
- connection.change_table :testings do |t|
456
- assert t.column_exists?(:foo)
457
- assert !(t.column_exists?(:bar))
458
- end
459
- end
460
-
461
- private
462
- def testing_table_with_only_foo_attribute
463
- connection.drop_table :testings rescue nil
464
- connection.create_table :testings, :id => false do |t|
465
- t.column :foo, :string
466
- end
467
-
468
- yield
469
- end
470
- end
471
- end
472
- end
1
+ require 'cases/helper'
2
+
3
+ module ActiveRecord
4
+ class Migration
5
+ class ChangeSchemaTest < ActiveRecord::TestCase
6
+ attr_reader :connection, :table_name
7
+
8
+ def setup
9
+ super
10
+ @connection = ActiveRecord::Base.connection
11
+ @table_name = :testings
12
+ end
13
+
14
+ teardown do
15
+ connection.drop_table :testings rescue nil
16
+ ActiveRecord::Base.primary_key_prefix_type = nil
17
+ ActiveRecord::Base.clear_cache!
18
+ end
19
+
20
+ def test_create_table_without_id
21
+ testing_table_with_only_foo_attribute do
22
+ assert_equal connection.columns(:testings).size, 1
23
+ end
24
+ end
25
+
26
+ def test_add_column_with_primary_key_attribute
27
+ testing_table_with_only_foo_attribute do
28
+ connection.add_column :testings, :id, :primary_key
29
+ assert_equal connection.columns(:testings).size, 2
30
+ end
31
+ end
32
+
33
+ def test_create_table_adds_id
34
+ connection.create_table :testings do |t|
35
+ t.column :foo, :string
36
+ end
37
+
38
+ assert_equal %w(id foo), connection.columns(:testings).map(&:name)
39
+ end
40
+
41
+ def test_create_table_with_not_null_column
42
+ connection.create_table :testings do |t|
43
+ t.column :foo, :string, :null => false
44
+ end
45
+
46
+ assert_raises(ActiveRecord::StatementInvalid) do
47
+ connection.execute "insert into testings (foo) values (NULL)"
48
+ end
49
+ end
50
+
51
+ def test_create_table_with_defaults
52
+ # MySQL doesn't allow defaults on TEXT or BLOB columns.
53
+ mysql = current_adapter?(:Mysql2Adapter)
54
+
55
+ connection.create_table :testings do |t|
56
+ t.column :one, :string, :default => "hello"
57
+ t.column :two, :boolean, :default => true
58
+ t.column :three, :boolean, :default => false
59
+ t.column :four, :integer, :default => 1
60
+ t.column :five, :text, :default => "hello" unless mysql
61
+ end
62
+
63
+ columns = connection.columns(:testings)
64
+ one = columns.detect { |c| c.name == "one" }
65
+ two = columns.detect { |c| c.name == "two" }
66
+ three = columns.detect { |c| c.name == "three" }
67
+ four = columns.detect { |c| c.name == "four" }
68
+ five = columns.detect { |c| c.name == "five" } unless mysql
69
+
70
+ assert_equal "hello", one.default
71
+ assert_equal true, connection.lookup_cast_type_from_column(two).deserialize(two.default)
72
+ assert_equal false, connection.lookup_cast_type_from_column(three).deserialize(three.default)
73
+ assert_equal '1', four.default
74
+ assert_equal "hello", five.default unless mysql
75
+ end
76
+
77
+ if current_adapter?(:PostgreSQLAdapter)
78
+ def test_add_column_with_array
79
+ connection.create_table :testings
80
+ connection.add_column :testings, :foo, :string, :array => true
81
+
82
+ columns = connection.columns(:testings)
83
+ array_column = columns.detect { |c| c.name == "foo" }
84
+
85
+ assert array_column.array?
86
+ end
87
+
88
+ def test_create_table_with_array_column
89
+ connection.create_table :testings do |t|
90
+ t.string :foo, :array => true
91
+ end
92
+
93
+ columns = connection.columns(:testings)
94
+ array_column = columns.detect { |c| c.name == "foo" }
95
+
96
+ assert array_column.array?
97
+ end
98
+ end
99
+
100
+ def test_create_table_with_bigint
101
+ connection.create_table :testings do |t|
102
+ t.bigint :eight_int
103
+ end
104
+ columns = connection.columns(:testings)
105
+ eight = columns.detect { |c| c.name == "eight_int" }
106
+
107
+ if current_adapter?(:OracleAdapter)
108
+ assert_equal 'NUMBER(19)', eight.sql_type
109
+ elsif current_adapter?(:SQLite3Adapter)
110
+ assert_equal 'bigint', eight.sql_type
111
+ else
112
+ assert_equal :integer, eight.type
113
+ assert_equal 8, eight.limit
114
+ end
115
+ ensure
116
+ connection.drop_table :testings
117
+ end
118
+
119
+ def test_create_table_with_limits
120
+ connection.create_table :testings do |t|
121
+ t.column :foo, :string, :limit => 255
122
+
123
+ t.column :default_int, :integer
124
+
125
+ t.column :one_int, :integer, :limit => 1
126
+ t.column :four_int, :integer, :limit => 4
127
+ t.column :eight_int, :integer, :limit => 8
128
+ end
129
+
130
+ columns = connection.columns(:testings)
131
+ foo = columns.detect { |c| c.name == "foo" }
132
+ assert_equal 255, foo.limit
133
+
134
+ default = columns.detect { |c| c.name == "default_int" }
135
+ one = columns.detect { |c| c.name == "one_int" }
136
+ four = columns.detect { |c| c.name == "four_int" }
137
+ eight = columns.detect { |c| c.name == "eight_int" }
138
+
139
+ if current_adapter?(:PostgreSQLAdapter)
140
+ assert_equal 'integer', default.sql_type
141
+ assert_equal 'smallint', one.sql_type
142
+ assert_equal 'integer', four.sql_type
143
+ assert_equal 'bigint', eight.sql_type
144
+ elsif current_adapter?(:Mysql2Adapter)
145
+ assert_match 'int(11)', default.sql_type
146
+ assert_match 'tinyint', one.sql_type
147
+ assert_match 'int', four.sql_type
148
+ assert_match 'bigint', eight.sql_type
149
+ elsif current_adapter?(:OracleAdapter)
150
+ assert_equal 'NUMBER(38)', default.sql_type
151
+ assert_equal 'NUMBER(1)', one.sql_type
152
+ assert_equal 'NUMBER(4)', four.sql_type
153
+ assert_equal 'NUMBER(8)', eight.sql_type
154
+ end
155
+ end
156
+
157
+ def test_create_table_with_primary_key_prefix_as_table_name_with_underscore
158
+ ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore
159
+
160
+ connection.create_table :testings do |t|
161
+ t.column :foo, :string
162
+ end
163
+
164
+ assert_equal %w(testing_id foo), connection.columns(:testings).map(&:name)
165
+ end
166
+
167
+ def test_create_table_with_primary_key_prefix_as_table_name
168
+ ActiveRecord::Base.primary_key_prefix_type = :table_name
169
+
170
+ connection.create_table :testings do |t|
171
+ t.column :foo, :string
172
+ end
173
+
174
+ assert_equal %w(testingid foo), connection.columns(:testings).map(&:name)
175
+ end
176
+
177
+ def test_create_table_raises_when_redefining_primary_key_column
178
+ error = assert_raise(ArgumentError) do
179
+ connection.create_table :testings do |t|
180
+ t.column :id, :string
181
+ end
182
+ end
183
+
184
+ assert_equal "you can't redefine the primary key column 'id'. To define a custom primary key, pass { id: false } to create_table.", error.message
185
+ end
186
+
187
+ def test_create_table_raises_when_redefining_custom_primary_key_column
188
+ error = assert_raise(ArgumentError) do
189
+ connection.create_table :testings, primary_key: :testing_id do |t|
190
+ t.column :testing_id, :string
191
+ end
192
+ end
193
+
194
+ assert_equal "you can't redefine the primary key column 'testing_id'. To define a custom primary key, pass { id: false } to create_table.", error.message
195
+ end
196
+
197
+ def test_create_table_with_timestamps_should_create_datetime_columns
198
+ connection.create_table table_name do |t|
199
+ t.timestamps
200
+ end
201
+ created_columns = connection.columns(table_name)
202
+
203
+ created_at_column = created_columns.detect {|c| c.name == 'created_at' }
204
+ updated_at_column = created_columns.detect {|c| c.name == 'updated_at' }
205
+
206
+ assert !created_at_column.null
207
+ assert !updated_at_column.null
208
+ end
209
+
210
+ def test_create_table_with_timestamps_should_create_datetime_columns_with_options
211
+ connection.create_table table_name do |t|
212
+ t.timestamps null: true
213
+ end
214
+ created_columns = connection.columns(table_name)
215
+
216
+ created_at_column = created_columns.detect {|c| c.name == 'created_at' }
217
+ updated_at_column = created_columns.detect {|c| c.name == 'updated_at' }
218
+
219
+ assert created_at_column.null
220
+ assert updated_at_column.null
221
+ end
222
+
223
+ def test_create_table_without_a_block
224
+ connection.create_table table_name
225
+ end
226
+
227
+ # SQLite3 will not allow you to add a NOT NULL
228
+ # column to a table without a default value.
229
+ unless current_adapter?(:SQLite3Adapter)
230
+ def test_add_column_not_null_without_default
231
+ connection.create_table :testings do |t|
232
+ t.column :foo, :string
233
+ end
234
+ connection.add_column :testings, :bar, :string, :null => false
235
+
236
+ assert_raise(ActiveRecord::StatementInvalid) do
237
+ connection.execute "insert into testings (foo, bar) values ('hello', NULL)"
238
+ end
239
+ end
240
+ end
241
+
242
+ def test_add_column_not_null_with_default
243
+ connection.create_table :testings do |t|
244
+ t.column :foo, :string
245
+ end
246
+
247
+ con = connection
248
+ connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}) values (1, 'hello')"
249
+ assert_nothing_raised {connection.add_column :testings, :bar, :string, :null => false, :default => "default" }
250
+
251
+ assert_raises(ActiveRecord::StatementInvalid) do
252
+ connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}, #{con.quote_column_name('bar')}) values (2, 'hello', NULL)"
253
+ end
254
+ end
255
+
256
+ def test_add_column_with_timestamp_type
257
+ connection.create_table :testings do |t|
258
+ t.column :foo, :timestamp
259
+ end
260
+
261
+ klass = Class.new(ActiveRecord::Base)
262
+ klass.table_name = 'testings'
263
+
264
+ assert_equal :datetime, klass.columns_hash['foo'].type
265
+
266
+ if current_adapter?(:PostgreSQLAdapter)
267
+ assert_equal 'timestamp without time zone', klass.columns_hash['foo'].sql_type
268
+ else
269
+ assert_equal klass.connection.type_to_sql('datetime'), klass.columns_hash['foo'].sql_type
270
+ end
271
+ end
272
+
273
+ def test_change_column_quotes_column_names
274
+ connection.create_table :testings do |t|
275
+ t.column :select, :string
276
+ end
277
+
278
+ connection.change_column :testings, :select, :string, :limit => 10
279
+
280
+ # Oracle needs primary key value from sequence
281
+ if current_adapter?(:OracleAdapter)
282
+ connection.execute "insert into testings (id, #{connection.quote_column_name('select')}) values (testings_seq.nextval, '7 chars')"
283
+ else
284
+ connection.execute "insert into testings (#{connection.quote_column_name('select')}) values ('7 chars')"
285
+ end
286
+ end
287
+
288
+ def test_keeping_default_and_notnull_constraints_on_change
289
+ connection.create_table :testings do |t|
290
+ t.column :title, :string
291
+ end
292
+ person_klass = Class.new(ActiveRecord::Base)
293
+ person_klass.table_name = 'testings'
294
+
295
+ person_klass.connection.add_column "testings", "wealth", :integer, :null => false, :default => 99
296
+ person_klass.reset_column_information
297
+ assert_equal 99, person_klass.column_defaults["wealth"]
298
+ assert_equal false, person_klass.columns_hash["wealth"].null
299
+ # Oracle needs primary key value from sequence
300
+ if current_adapter?(:OracleAdapter)
301
+ assert_nothing_raised {person_klass.connection.execute("insert into testings (id, title) values (testings_seq.nextval, 'tester')")}
302
+ else
303
+ assert_nothing_raised {person_klass.connection.execute("insert into testings (title) values ('tester')")}
304
+ end
305
+
306
+ # change column default to see that column doesn't lose its not null definition
307
+ person_klass.connection.change_column_default "testings", "wealth", 100
308
+ person_klass.reset_column_information
309
+ assert_equal 100, person_klass.column_defaults["wealth"]
310
+ assert_equal false, person_klass.columns_hash["wealth"].null
311
+
312
+ # rename column to see that column doesn't lose its not null and/or default definition
313
+ person_klass.connection.rename_column "testings", "wealth", "money"
314
+ person_klass.reset_column_information
315
+ assert_nil person_klass.columns_hash["wealth"]
316
+ assert_equal 100, person_klass.column_defaults["money"]
317
+ assert_equal false, person_klass.columns_hash["money"].null
318
+
319
+ # change column
320
+ person_klass.connection.change_column "testings", "money", :integer, :null => false, :default => 1000
321
+ person_klass.reset_column_information
322
+ assert_equal 1000, person_klass.column_defaults["money"]
323
+ assert_equal false, person_klass.columns_hash["money"].null
324
+
325
+ # change column, make it nullable and clear default
326
+ person_klass.connection.change_column "testings", "money", :integer, :null => true, :default => nil
327
+ person_klass.reset_column_information
328
+ assert_nil person_klass.columns_hash["money"].default
329
+ assert_equal true, person_klass.columns_hash["money"].null
330
+
331
+ # change_column_null, make it not nullable and set null values to a default value
332
+ person_klass.connection.execute('UPDATE testings SET money = NULL')
333
+ person_klass.connection.change_column_null "testings", "money", false, 2000
334
+ person_klass.reset_column_information
335
+ assert_nil person_klass.columns_hash["money"].default
336
+ assert_equal false, person_klass.columns_hash["money"].null
337
+ assert_equal 2000, connection.select_values("SELECT money FROM testings").first.to_i
338
+ end
339
+
340
+ def test_change_column_null
341
+ testing_table_with_only_foo_attribute do
342
+ notnull_migration = Class.new(ActiveRecord::Migration::Current) do
343
+ def change
344
+ change_column_null :testings, :foo, false
345
+ end
346
+ end
347
+ notnull_migration.new.suppress_messages do
348
+ notnull_migration.migrate(:up)
349
+ assert_equal false, connection.columns(:testings).find{ |c| c.name == "foo"}.null
350
+ notnull_migration.migrate(:down)
351
+ assert connection.columns(:testings).find{ |c| c.name == "foo"}.null
352
+ end
353
+ end
354
+ end
355
+
356
+ def test_column_exists
357
+ connection.create_table :testings do |t|
358
+ t.column :foo, :string
359
+ end
360
+
361
+ assert connection.column_exists?(:testings, :foo)
362
+ assert_not connection.column_exists?(:testings, :bar)
363
+ end
364
+
365
+ def test_column_exists_with_type
366
+ connection.create_table :testings do |t|
367
+ t.column :foo, :string
368
+ t.column :bar, :decimal, :precision => 8, :scale => 2
369
+ end
370
+
371
+ assert connection.column_exists?(:testings, :foo, :string)
372
+ assert_not connection.column_exists?(:testings, :foo, :integer)
373
+
374
+ assert connection.column_exists?(:testings, :bar, :decimal)
375
+ assert_not connection.column_exists?(:testings, :bar, :integer)
376
+ end
377
+
378
+ def test_column_exists_with_definition
379
+ connection.create_table :testings do |t|
380
+ t.column :foo, :string, limit: 100
381
+ t.column :bar, :decimal, precision: 8, scale: 2
382
+ t.column :taggable_id, :integer, null: false
383
+ t.column :taggable_type, :string, default: 'Photo'
384
+ end
385
+
386
+ assert connection.column_exists?(:testings, :foo, :string, limit: 100)
387
+ assert_not connection.column_exists?(:testings, :foo, :string, limit: nil)
388
+ assert connection.column_exists?(:testings, :bar, :decimal, precision: 8, scale: 2)
389
+ assert_not connection.column_exists?(:testings, :bar, :decimal, precision: nil, scale: nil)
390
+ assert connection.column_exists?(:testings, :taggable_id, :integer, null: false)
391
+ assert_not connection.column_exists?(:testings, :taggable_id, :integer, null: true)
392
+ assert connection.column_exists?(:testings, :taggable_type, :string, default: 'Photo')
393
+ assert_not connection.column_exists?(:testings, :taggable_type, :string, default: nil)
394
+ end
395
+
396
+ def test_column_exists_on_table_with_no_options_parameter_supplied
397
+ connection.create_table :testings do |t|
398
+ t.string :foo
399
+ end
400
+ connection.change_table :testings do |t|
401
+ assert t.column_exists?(:foo)
402
+ assert !(t.column_exists?(:bar))
403
+ end
404
+ end
405
+
406
+ def test_drop_table_if_exists
407
+ connection.create_table(:testings)
408
+ ActiveSupport::Deprecation.silence { assert connection.table_exists?(:testings) }
409
+ connection.drop_table(:testings, if_exists: true)
410
+ ActiveSupport::Deprecation.silence { assert_not connection.table_exists?(:testings) }
411
+ end
412
+
413
+ def test_drop_table_if_exists_nothing_raised
414
+ assert_nothing_raised { connection.drop_table(:nonexistent, if_exists: true) }
415
+ end
416
+
417
+ private
418
+ def testing_table_with_only_foo_attribute
419
+ connection.create_table :testings, :id => false do |t|
420
+ t.column :foo, :string
421
+ end
422
+
423
+ yield
424
+ end
425
+ end
426
+
427
+ if ActiveRecord::Base.connection.supports_foreign_keys?
428
+ class ChangeSchemaWithDependentObjectsTest < ActiveRecord::TestCase
429
+ self.use_transactional_tests = false
430
+
431
+ setup do
432
+ @connection = ActiveRecord::Base.connection
433
+ @connection.create_table :trains
434
+ @connection.create_table(:wagons) { |t| t.references :train }
435
+ @connection.add_foreign_key :wagons, :trains
436
+ end
437
+
438
+ teardown do
439
+ [:wagons, :trains].each do |table|
440
+ @connection.drop_table table, if_exists: true
441
+ end
442
+ end
443
+
444
+ def test_create_table_with_force_cascade_drops_dependent_objects
445
+ skip "MySQL > 5.5 does not drop dependent objects with DROP TABLE CASCADE" if current_adapter?(:Mysql2Adapter)
446
+ # can't re-create table referenced by foreign key
447
+ assert_raises(ActiveRecord::StatementInvalid) do
448
+ @connection.create_table :trains, force: true
449
+ end
450
+
451
+ # can recreate referenced table with force: :cascade
452
+ @connection.create_table :trains, force: :cascade
453
+ assert_equal [], @connection.foreign_keys(:wagons)
454
+ end
455
+ end
456
+ end
457
+ end
458
+ end