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
@@ -0,0 +1,34 @@
1
+ require "cases/helper"
2
+
3
+ class PostgresqlRenameTableTest < ActiveRecord::PostgreSQLTestCase
4
+ def setup
5
+ @connection = ActiveRecord::Base.connection
6
+ @connection.create_table :before_rename, force: true
7
+ end
8
+
9
+ def teardown
10
+ @connection.drop_table "before_rename", if_exists: true
11
+ @connection.drop_table "after_rename", if_exists: true
12
+ end
13
+
14
+ test "renaming a table also renames the primary key index" do
15
+ # sanity check
16
+ assert_equal 1, num_indices_named("before_rename_pkey")
17
+ assert_equal 0, num_indices_named("after_rename_pkey")
18
+
19
+ @connection.rename_table :before_rename, :after_rename
20
+
21
+ assert_equal 0, num_indices_named("before_rename_pkey")
22
+ assert_equal 1, num_indices_named("after_rename_pkey")
23
+ end
24
+
25
+ private
26
+
27
+ def num_indices_named(name)
28
+ @connection.execute(<<-SQL).values.length
29
+ SELECT 1 FROM "pg_index"
30
+ JOIN "pg_class" ON "pg_index"."indexrelid" = "pg_class"."oid"
31
+ WHERE "pg_class"."relname" = '#{name}'
32
+ SQL
33
+ end
34
+ end
@@ -0,0 +1,119 @@
1
+ require "cases/helper"
2
+
3
+ class SchemaThing < ActiveRecord::Base
4
+ end
5
+
6
+ class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase
7
+ self.use_transactional_tests = false
8
+
9
+ TABLE_NAME = 'schema_things'
10
+ COLUMNS = [
11
+ 'id serial primary key',
12
+ 'name character varying(50)'
13
+ ]
14
+ USERS = ['rails_pg_schema_user1', 'rails_pg_schema_user2']
15
+
16
+ def setup
17
+ @connection = ActiveRecord::Base.connection
18
+ @connection.execute "SET search_path TO '$user',public"
19
+ set_session_auth
20
+ USERS.each do |u|
21
+ @connection.execute "CREATE USER #{u}" rescue nil
22
+ @connection.execute "CREATE SCHEMA AUTHORIZATION #{u}" rescue nil
23
+ set_session_auth u
24
+ @connection.execute "CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
25
+ @connection.execute "INSERT INTO #{TABLE_NAME} (name) VALUES ('#{u}')"
26
+ set_session_auth
27
+ end
28
+ end
29
+
30
+ teardown do
31
+ set_session_auth
32
+ @connection.execute "RESET search_path"
33
+ USERS.each do |u|
34
+ @connection.drop_schema u
35
+ @connection.execute "DROP USER #{u}"
36
+ end
37
+ end
38
+
39
+ def test_schema_invisible
40
+ assert_raise(ActiveRecord::StatementInvalid) do
41
+ set_session_auth
42
+ @connection.execute "SELECT * FROM #{TABLE_NAME}"
43
+ end
44
+ end
45
+
46
+ def test_session_auth=
47
+ assert_raise(ActiveRecord::StatementInvalid) do
48
+ @connection.session_auth = 'DEFAULT'
49
+ @connection.execute "SELECT * FROM #{TABLE_NAME}"
50
+ end
51
+ end
52
+
53
+ def test_setting_auth_clears_stmt_cache
54
+ assert_nothing_raised do
55
+ set_session_auth
56
+ USERS.each do |u|
57
+ set_session_auth u
58
+ assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = 1")
59
+ set_session_auth
60
+ end
61
+ end
62
+ end
63
+
64
+ if ActiveRecord::Base.connection.prepared_statements
65
+ def test_auth_with_bind
66
+ assert_nothing_raised do
67
+ set_session_auth
68
+ USERS.each do |u|
69
+ @connection.clear_cache!
70
+ set_session_auth u
71
+ assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [bind_param(1)])
72
+ set_session_auth
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ def test_schema_uniqueness
79
+ assert_nothing_raised do
80
+ set_session_auth
81
+ USERS.each do |u|
82
+ set_session_auth u
83
+ assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = 1")
84
+ set_session_auth
85
+ end
86
+ end
87
+ end
88
+
89
+ def test_sequence_schema_caching
90
+ assert_nothing_raised do
91
+ USERS.each do |u|
92
+ set_session_auth u
93
+ st = SchemaThing.new :name => 'TEST1'
94
+ st.save!
95
+ st = SchemaThing.new :id => 5, :name => 'TEST2'
96
+ st.save!
97
+ set_session_auth
98
+ end
99
+ end
100
+ end
101
+
102
+ def test_tables_in_current_schemas
103
+ assert !@connection.tables.include?(TABLE_NAME)
104
+ USERS.each do |u|
105
+ set_session_auth u
106
+ assert @connection.tables.include?(TABLE_NAME)
107
+ set_session_auth
108
+ end
109
+ end
110
+
111
+ private
112
+ def set_session_auth auth = nil
113
+ @connection.session_auth = auth || 'default'
114
+ end
115
+
116
+ def bind_param(value)
117
+ ActiveRecord::Relation::QueryAttribute.new(nil, value, ActiveRecord::Type::Value.new)
118
+ end
119
+ end
@@ -0,0 +1,597 @@
1
+ require "cases/helper"
2
+ require 'models/default'
3
+ require 'support/schema_dumping_helper'
4
+
5
+ module PGSchemaHelper
6
+ def with_schema_search_path(schema_search_path)
7
+ @connection.schema_search_path = schema_search_path
8
+ @connection.schema_cache.clear!
9
+ yield if block_given?
10
+ ensure
11
+ @connection.schema_search_path = "'$user', public"
12
+ @connection.schema_cache.clear!
13
+ end
14
+ end
15
+
16
+ class SchemaTest < ActiveRecord::PostgreSQLTestCase
17
+ include PGSchemaHelper
18
+ self.use_transactional_tests = false
19
+
20
+ SCHEMA_NAME = 'test_schema'
21
+ SCHEMA2_NAME = 'test_schema2'
22
+ TABLE_NAME = 'things'
23
+ CAPITALIZED_TABLE_NAME = 'Things'
24
+ INDEX_A_NAME = 'a_index_things_on_name'
25
+ INDEX_B_NAME = 'b_index_things_on_different_columns_in_each_schema'
26
+ INDEX_C_NAME = 'c_index_full_text_search'
27
+ INDEX_D_NAME = 'd_index_things_on_description_desc'
28
+ INDEX_E_NAME = 'e_index_things_on_name_vector'
29
+ INDEX_A_COLUMN = 'name'
30
+ INDEX_B_COLUMN_S1 = 'email'
31
+ INDEX_B_COLUMN_S2 = 'moment'
32
+ INDEX_C_COLUMN = %q{(to_tsvector('english', coalesce(things.name, '')))}
33
+ INDEX_D_COLUMN = 'description'
34
+ INDEX_E_COLUMN = 'name_vector'
35
+ COLUMNS = [
36
+ 'id integer',
37
+ 'name character varying(50)',
38
+ 'email character varying(50)',
39
+ 'description character varying(100)',
40
+ 'name_vector tsvector',
41
+ 'moment timestamp without time zone default now()'
42
+ ]
43
+ PK_TABLE_NAME = 'table_with_pk'
44
+ UNMATCHED_SEQUENCE_NAME = 'unmatched_primary_key_default_value_seq'
45
+ UNMATCHED_PK_TABLE_NAME = 'table_with_unmatched_sequence_for_pk'
46
+
47
+ class Thing1 < ActiveRecord::Base
48
+ self.table_name = "test_schema.things"
49
+ end
50
+
51
+ class Thing2 < ActiveRecord::Base
52
+ self.table_name = "test_schema2.things"
53
+ end
54
+
55
+ class Thing3 < ActiveRecord::Base
56
+ self.table_name = 'test_schema."things.table"'
57
+ end
58
+
59
+ class Thing4 < ActiveRecord::Base
60
+ self.table_name = 'test_schema."Things"'
61
+ end
62
+
63
+ class Thing5 < ActiveRecord::Base
64
+ self.table_name = 'things'
65
+ end
66
+
67
+ class Song < ActiveRecord::Base
68
+ self.table_name = "music.songs"
69
+ has_and_belongs_to_many :albums
70
+ end
71
+
72
+ class Album < ActiveRecord::Base
73
+ self.table_name = "music.albums"
74
+ has_and_belongs_to_many :songs
75
+ end
76
+
77
+ def setup
78
+ @connection = ActiveRecord::Base.connection
79
+ @connection.execute "CREATE SCHEMA #{SCHEMA_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
80
+ @connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{TABLE_NAME}.table\" (#{COLUMNS.join(',')})"
81
+ @connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{CAPITALIZED_TABLE_NAME}\" (#{COLUMNS.join(',')})"
82
+ @connection.execute "CREATE SCHEMA #{SCHEMA2_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
83
+ @connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
84
+ @connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
85
+ @connection.execute "CREATE INDEX #{INDEX_B_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_B_COLUMN_S1});"
86
+ @connection.execute "CREATE INDEX #{INDEX_B_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_B_COLUMN_S2});"
87
+ @connection.execute "CREATE INDEX #{INDEX_C_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING gin (#{INDEX_C_COLUMN});"
88
+ @connection.execute "CREATE INDEX #{INDEX_C_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING gin (#{INDEX_C_COLUMN});"
89
+ @connection.execute "CREATE INDEX #{INDEX_D_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_D_COLUMN} DESC);"
90
+ @connection.execute "CREATE INDEX #{INDEX_D_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_D_COLUMN} DESC);"
91
+ @connection.execute "CREATE INDEX #{INDEX_E_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING gin (#{INDEX_E_COLUMN});"
92
+ @connection.execute "CREATE INDEX #{INDEX_E_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING gin (#{INDEX_E_COLUMN});"
93
+ @connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{PK_TABLE_NAME} (id serial primary key)"
94
+ @connection.execute "CREATE SEQUENCE #{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}"
95
+ @connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{UNMATCHED_PK_TABLE_NAME} (id integer NOT NULL DEFAULT nextval('#{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}'::regclass), CONSTRAINT unmatched_pkey PRIMARY KEY (id))"
96
+ end
97
+
98
+ teardown do
99
+ @connection.drop_schema SCHEMA2_NAME, if_exists: true
100
+ @connection.drop_schema SCHEMA_NAME, if_exists: true
101
+ end
102
+
103
+ def test_schema_names
104
+ assert_equal ["public", "test_schema", "test_schema2"], @connection.schema_names
105
+ end
106
+
107
+ def test_create_schema
108
+ begin
109
+ @connection.create_schema "test_schema3"
110
+ assert @connection.schema_names.include? "test_schema3"
111
+ ensure
112
+ @connection.drop_schema "test_schema3"
113
+ end
114
+ end
115
+
116
+ def test_raise_create_schema_with_existing_schema
117
+ begin
118
+ @connection.create_schema "test_schema3"
119
+ assert_raises(ActiveRecord::StatementInvalid) do
120
+ @connection.create_schema "test_schema3"
121
+ end
122
+ ensure
123
+ @connection.drop_schema "test_schema3"
124
+ end
125
+ end
126
+
127
+ def test_drop_schema
128
+ begin
129
+ @connection.create_schema "test_schema3"
130
+ ensure
131
+ @connection.drop_schema "test_schema3"
132
+ end
133
+ assert !@connection.schema_names.include?("test_schema3")
134
+ end
135
+
136
+ def test_drop_schema_if_exists
137
+ @connection.create_schema "some_schema"
138
+ assert_includes @connection.schema_names, "some_schema"
139
+ @connection.drop_schema "some_schema", if_exists: true
140
+ assert_not_includes @connection.schema_names, "some_schema"
141
+ end
142
+
143
+ def test_habtm_table_name_with_schema
144
+ ActiveRecord::Base.connection.drop_schema "music", if_exists: true
145
+ ActiveRecord::Base.connection.create_schema "music"
146
+ ActiveRecord::Base.connection.execute <<-SQL
147
+ CREATE TABLE music.albums (id serial primary key);
148
+ CREATE TABLE music.songs (id serial primary key);
149
+ CREATE TABLE music.albums_songs (album_id integer, song_id integer);
150
+ SQL
151
+
152
+ song = Song.create
153
+ Album.create
154
+ assert_equal song, Song.includes(:albums).references(:albums).first
155
+ ensure
156
+ ActiveRecord::Base.connection.drop_schema "music", if_exists: true
157
+ end
158
+
159
+ def test_drop_schema_with_nonexisting_schema
160
+ assert_raises(ActiveRecord::StatementInvalid) do
161
+ @connection.drop_schema "idontexist"
162
+ end
163
+
164
+ assert_nothing_raised do
165
+ @connection.drop_schema "idontexist", if_exists: true
166
+ end
167
+ end
168
+
169
+ def test_raise_wrapped_exception_on_bad_prepare
170
+ assert_raises(ActiveRecord::StatementInvalid) do
171
+ @connection.exec_query "select * from developers where id = ?", 'sql', [bind_param(1)]
172
+ end
173
+ end
174
+
175
+ if ActiveRecord::Base.connection.prepared_statements
176
+ def test_schema_change_with_prepared_stmt
177
+ altered = false
178
+ @connection.exec_query "select * from developers where id = $1", 'sql', [bind_param(1)]
179
+ @connection.exec_query "alter table developers add column zomg int", 'sql', []
180
+ altered = true
181
+ @connection.exec_query "select * from developers where id = $1", 'sql', [bind_param(1)]
182
+ ensure
183
+ # We are not using DROP COLUMN IF EXISTS because that syntax is only
184
+ # supported by pg 9.X
185
+ @connection.exec_query("alter table developers drop column zomg", 'sql', []) if altered
186
+ end
187
+ end
188
+
189
+ def test_data_source_exists?
190
+ [Thing1, Thing2, Thing3, Thing4].each do |klass|
191
+ name = klass.table_name
192
+ assert @connection.data_source_exists?(name), "'#{name}' data_source should exist"
193
+ end
194
+ end
195
+
196
+ def test_data_source_exists_when_on_schema_search_path
197
+ with_schema_search_path(SCHEMA_NAME) do
198
+ assert(@connection.data_source_exists?(TABLE_NAME), "data_source should exist and be found")
199
+ end
200
+ end
201
+
202
+ def test_data_source_exists_when_not_on_schema_search_path
203
+ with_schema_search_path('PUBLIC') do
204
+ assert(!@connection.data_source_exists?(TABLE_NAME), "data_source exists but should not be found")
205
+ end
206
+ end
207
+
208
+ def test_data_source_exists_wrong_schema
209
+ assert(!@connection.data_source_exists?("foo.things"), "data_source should not exist")
210
+ end
211
+
212
+ def test_data_source_exists_quoted_names
213
+ [ %("#{SCHEMA_NAME}"."#{TABLE_NAME}"), %(#{SCHEMA_NAME}."#{TABLE_NAME}"), %(#{SCHEMA_NAME}."#{TABLE_NAME}")].each do |given|
214
+ assert(@connection.data_source_exists?(given), "data_source should exist when specified as #{given}")
215
+ end
216
+ with_schema_search_path(SCHEMA_NAME) do
217
+ given = %("#{TABLE_NAME}")
218
+ assert(@connection.data_source_exists?(given), "data_source should exist when specified as #{given}")
219
+ end
220
+ end
221
+
222
+ def test_data_source_exists_quoted_table
223
+ with_schema_search_path(SCHEMA_NAME) do
224
+ assert(@connection.data_source_exists?('"things.table"'), "data_source should exist")
225
+ end
226
+ end
227
+
228
+ def test_with_schema_prefixed_table_name
229
+ assert_nothing_raised do
230
+ assert_equal COLUMNS, columns("#{SCHEMA_NAME}.#{TABLE_NAME}")
231
+ end
232
+ end
233
+
234
+ def test_with_schema_prefixed_capitalized_table_name
235
+ assert_nothing_raised do
236
+ assert_equal COLUMNS, columns("#{SCHEMA_NAME}.#{CAPITALIZED_TABLE_NAME}")
237
+ end
238
+ end
239
+
240
+ def test_with_schema_search_path
241
+ assert_nothing_raised do
242
+ with_schema_search_path(SCHEMA_NAME) do
243
+ assert_equal COLUMNS, columns(TABLE_NAME)
244
+ end
245
+ end
246
+ end
247
+
248
+ def test_proper_encoding_of_table_name
249
+ assert_equal '"table_name"', @connection.quote_table_name('table_name')
250
+ assert_equal '"table.name"', @connection.quote_table_name('"table.name"')
251
+ assert_equal '"schema_name"."table_name"', @connection.quote_table_name('schema_name.table_name')
252
+ assert_equal '"schema_name"."table.name"', @connection.quote_table_name('schema_name."table.name"')
253
+ assert_equal '"schema.name"."table_name"', @connection.quote_table_name('"schema.name".table_name')
254
+ assert_equal '"schema.name"."table.name"', @connection.quote_table_name('"schema.name"."table.name"')
255
+ end
256
+
257
+ def test_classes_with_qualified_schema_name
258
+ assert_equal 0, Thing1.count
259
+ assert_equal 0, Thing2.count
260
+ assert_equal 0, Thing3.count
261
+ assert_equal 0, Thing4.count
262
+
263
+ Thing1.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
264
+ assert_equal 1, Thing1.count
265
+ assert_equal 0, Thing2.count
266
+ assert_equal 0, Thing3.count
267
+ assert_equal 0, Thing4.count
268
+
269
+ Thing2.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
270
+ assert_equal 1, Thing1.count
271
+ assert_equal 1, Thing2.count
272
+ assert_equal 0, Thing3.count
273
+ assert_equal 0, Thing4.count
274
+
275
+ Thing3.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
276
+ assert_equal 1, Thing1.count
277
+ assert_equal 1, Thing2.count
278
+ assert_equal 1, Thing3.count
279
+ assert_equal 0, Thing4.count
280
+
281
+ Thing4.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
282
+ assert_equal 1, Thing1.count
283
+ assert_equal 1, Thing2.count
284
+ assert_equal 1, Thing3.count
285
+ assert_equal 1, Thing4.count
286
+ end
287
+
288
+ def test_raise_on_unquoted_schema_name
289
+ assert_raises(ActiveRecord::StatementInvalid) do
290
+ with_schema_search_path '$user,public'
291
+ end
292
+ end
293
+
294
+ def test_without_schema_search_path
295
+ assert_raises(ActiveRecord::StatementInvalid) { columns(TABLE_NAME) }
296
+ end
297
+
298
+ def test_ignore_nil_schema_search_path
299
+ assert_nothing_raised { with_schema_search_path nil }
300
+ end
301
+
302
+ def test_index_name_exists
303
+ with_schema_search_path(SCHEMA_NAME) do
304
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_A_NAME, true)
305
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_B_NAME, true)
306
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_C_NAME, true)
307
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_D_NAME, true)
308
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME, true)
309
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME, true)
310
+ assert_not @connection.index_name_exists?(TABLE_NAME, 'missing_index', true)
311
+ end
312
+ end
313
+
314
+ def test_dump_indexes_for_schema_one
315
+ do_dump_index_tests_for_schema(SCHEMA_NAME, INDEX_A_COLUMN, INDEX_B_COLUMN_S1, INDEX_D_COLUMN, INDEX_E_COLUMN)
316
+ end
317
+
318
+ def test_dump_indexes_for_schema_two
319
+ do_dump_index_tests_for_schema(SCHEMA2_NAME, INDEX_A_COLUMN, INDEX_B_COLUMN_S2, INDEX_D_COLUMN, INDEX_E_COLUMN)
320
+ end
321
+
322
+ def test_dump_indexes_for_schema_multiple_schemas_in_search_path
323
+ do_dump_index_tests_for_schema("public, #{SCHEMA_NAME}", INDEX_A_COLUMN, INDEX_B_COLUMN_S1, INDEX_D_COLUMN, INDEX_E_COLUMN)
324
+ end
325
+
326
+ def test_dump_indexes_for_table_with_scheme_specified_in_name
327
+ indexes = @connection.indexes("#{SCHEMA_NAME}.#{TABLE_NAME}")
328
+ assert_equal 5, indexes.size
329
+ end
330
+
331
+ def test_with_uppercase_index_name
332
+ @connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
333
+
334
+ with_schema_search_path SCHEMA_NAME do
335
+ assert_nothing_raised { @connection.remove_index "things", name: "things_Index"}
336
+ end
337
+ end
338
+
339
+ def test_remove_index_when_schema_specified
340
+ @connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
341
+ assert_nothing_raised { @connection.remove_index "things", name: "#{SCHEMA_NAME}.things_Index" }
342
+
343
+ @connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
344
+ assert_nothing_raised { @connection.remove_index "#{SCHEMA_NAME}.things", name: "things_Index" }
345
+
346
+ @connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
347
+ assert_nothing_raised { @connection.remove_index "#{SCHEMA_NAME}.things", name: "#{SCHEMA_NAME}.things_Index" }
348
+
349
+ @connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
350
+ assert_raises(ArgumentError) { @connection.remove_index "#{SCHEMA2_NAME}.things", name: "#{SCHEMA_NAME}.things_Index" }
351
+ end
352
+
353
+ def test_primary_key_with_schema_specified
354
+ [
355
+ %("#{SCHEMA_NAME}"."#{PK_TABLE_NAME}"),
356
+ %(#{SCHEMA_NAME}."#{PK_TABLE_NAME}"),
357
+ %(#{SCHEMA_NAME}.#{PK_TABLE_NAME})
358
+ ].each do |given|
359
+ assert_equal 'id', @connection.primary_key(given), "primary key should be found when table referenced as #{given}"
360
+ end
361
+ end
362
+
363
+ def test_primary_key_assuming_schema_search_path
364
+ with_schema_search_path(SCHEMA_NAME) do
365
+ assert_equal 'id', @connection.primary_key(PK_TABLE_NAME), "primary key should be found"
366
+ end
367
+ end
368
+
369
+ def test_primary_key_raises_error_if_table_not_found_on_schema_search_path
370
+ with_schema_search_path(SCHEMA2_NAME) do
371
+ assert_raises(ActiveRecord::StatementInvalid) do
372
+ @connection.primary_key(PK_TABLE_NAME)
373
+ end
374
+ end
375
+ end
376
+
377
+ def test_pk_and_sequence_for_with_schema_specified
378
+ pg_name = ActiveRecord::ConnectionAdapters::PostgreSQL::Name
379
+ [
380
+ %("#{SCHEMA_NAME}"."#{PK_TABLE_NAME}"),
381
+ %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}")
382
+ ].each do |given|
383
+ pk, seq = @connection.pk_and_sequence_for(given)
384
+ assert_equal 'id', pk, "primary key should be found when table referenced as #{given}"
385
+ assert_equal pg_name.new(SCHEMA_NAME, "#{PK_TABLE_NAME}_id_seq"), seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{PK_TABLE_NAME}")
386
+ assert_equal pg_name.new(SCHEMA_NAME, UNMATCHED_SEQUENCE_NAME), seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}")
387
+ end
388
+ end
389
+
390
+ def test_current_schema
391
+ {
392
+ %('$user',public) => 'public',
393
+ SCHEMA_NAME => SCHEMA_NAME,
394
+ %(#{SCHEMA2_NAME},#{SCHEMA_NAME},public) => SCHEMA2_NAME,
395
+ %(public,#{SCHEMA2_NAME},#{SCHEMA_NAME}) => 'public'
396
+ }.each do |given,expect|
397
+ with_schema_search_path(given) { assert_equal expect, @connection.current_schema }
398
+ end
399
+ end
400
+
401
+ def test_prepared_statements_with_multiple_schemas
402
+ [SCHEMA_NAME, SCHEMA2_NAME].each do |schema_name|
403
+ with_schema_search_path schema_name do
404
+ Thing5.create(:id => 1, :name => "thing inside #{SCHEMA_NAME}", :email => "thing1@localhost", :moment => Time.now)
405
+ end
406
+ end
407
+
408
+ [SCHEMA_NAME, SCHEMA2_NAME].each do |schema_name|
409
+ with_schema_search_path schema_name do
410
+ assert_equal 1, Thing5.count
411
+ end
412
+ end
413
+ end
414
+
415
+ def test_schema_exists?
416
+ {
417
+ 'public' => true,
418
+ SCHEMA_NAME => true,
419
+ SCHEMA2_NAME => true,
420
+ 'darkside' => false
421
+ }.each do |given,expect|
422
+ assert_equal expect, @connection.schema_exists?(given)
423
+ end
424
+ end
425
+
426
+ def test_reset_pk_sequence
427
+ sequence_name = "#{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}"
428
+ @connection.execute "SELECT setval('#{sequence_name}', 123)"
429
+ assert_equal 124, @connection.select_value("SELECT nextval('#{sequence_name}')")
430
+ @connection.reset_pk_sequence!("#{SCHEMA_NAME}.#{UNMATCHED_PK_TABLE_NAME}")
431
+ assert_equal 1, @connection.select_value("SELECT nextval('#{sequence_name}')")
432
+ end
433
+
434
+ def test_set_pk_sequence
435
+ table_name = "#{SCHEMA_NAME}.#{PK_TABLE_NAME}"
436
+ _, sequence_name = @connection.pk_and_sequence_for table_name
437
+ @connection.set_pk_sequence! table_name, 123
438
+ assert_equal 124, @connection.select_value("SELECT nextval('#{sequence_name}')")
439
+ @connection.reset_pk_sequence! table_name
440
+ end
441
+
442
+ private
443
+ def columns(table_name)
444
+ @connection.send(:column_definitions, table_name).map do |name, type, default|
445
+ "#{name} #{type}" + (default ? " default #{default}" : '')
446
+ end
447
+ end
448
+
449
+ def do_dump_index_tests_for_schema(this_schema_name, first_index_column_name, second_index_column_name, third_index_column_name, fourth_index_column_name)
450
+ with_schema_search_path(this_schema_name) do
451
+ indexes = @connection.indexes(TABLE_NAME).sort_by(&:name)
452
+ assert_equal 5, indexes.size
453
+
454
+ index_a, index_b, index_c, index_d, index_e = indexes
455
+
456
+ do_dump_index_assertions_for_one_index(index_a, INDEX_A_NAME, first_index_column_name)
457
+ do_dump_index_assertions_for_one_index(index_b, INDEX_B_NAME, second_index_column_name)
458
+ do_dump_index_assertions_for_one_index(index_d, INDEX_D_NAME, third_index_column_name)
459
+ do_dump_index_assertions_for_one_index(index_e, INDEX_E_NAME, fourth_index_column_name)
460
+
461
+ assert_equal :btree, index_a.using
462
+ assert_equal :btree, index_b.using
463
+ assert_equal :gin, index_c.using
464
+ assert_equal :btree, index_d.using
465
+ assert_equal :gin, index_e.using
466
+
467
+ assert_equal :desc, index_d.orders[INDEX_D_COLUMN]
468
+ end
469
+ end
470
+
471
+ def do_dump_index_assertions_for_one_index(this_index, this_index_name, this_index_column)
472
+ assert_equal TABLE_NAME, this_index.table
473
+ assert_equal 1, this_index.columns.size
474
+ assert_equal this_index_column, this_index.columns[0]
475
+ assert_equal this_index_name, this_index.name
476
+ end
477
+
478
+ def bind_param(value)
479
+ ActiveRecord::Relation::QueryAttribute.new(nil, value, ActiveRecord::Type::Value.new)
480
+ end
481
+ end
482
+
483
+ class SchemaForeignKeyTest < ActiveRecord::PostgreSQLTestCase
484
+ include SchemaDumpingHelper
485
+
486
+ setup do
487
+ @connection = ActiveRecord::Base.connection
488
+ end
489
+
490
+ def test_dump_foreign_key_targeting_different_schema
491
+ @connection.create_schema "my_schema"
492
+ @connection.create_table "my_schema.trains" do |t|
493
+ t.string :name
494
+ end
495
+ @connection.create_table "wagons" do |t|
496
+ t.integer :train_id
497
+ end
498
+ @connection.add_foreign_key "wagons", "my_schema.trains", column: "train_id"
499
+ output = dump_table_schema "wagons"
500
+ assert_match %r{\s+add_foreign_key "wagons", "my_schema\.trains", column: "train_id"$}, output
501
+ ensure
502
+ @connection.drop_table "wagons", if_exists: true
503
+ @connection.drop_table "my_schema.trains", if_exists: true
504
+ @connection.drop_schema "my_schema", if_exists: true
505
+ end
506
+ end
507
+
508
+ class DefaultsUsingMultipleSchemasAndDomainTest < ActiveRecord::PostgreSQLTestCase
509
+ setup do
510
+ @connection = ActiveRecord::Base.connection
511
+ @connection.drop_schema "schema_1", if_exists: true
512
+ @connection.execute "CREATE SCHEMA schema_1"
513
+ @connection.execute "CREATE DOMAIN schema_1.text AS text"
514
+ @connection.execute "CREATE DOMAIN schema_1.varchar AS varchar"
515
+ @connection.execute "CREATE DOMAIN schema_1.bpchar AS bpchar"
516
+
517
+ @old_search_path = @connection.schema_search_path
518
+ @connection.schema_search_path = "schema_1, pg_catalog"
519
+ @connection.create_table "defaults" do |t|
520
+ t.text "text_col", default: "some value"
521
+ t.string "string_col", default: "some value"
522
+ t.decimal "decimal_col", default: "3.14159265358979323846"
523
+ end
524
+ Default.reset_column_information
525
+ end
526
+
527
+ teardown do
528
+ @connection.schema_search_path = @old_search_path
529
+ @connection.drop_schema "schema_1", if_exists: true
530
+ Default.reset_column_information
531
+ end
532
+
533
+ def test_text_defaults_in_new_schema_when_overriding_domain
534
+ assert_equal "some value", Default.new.text_col, "Default of text column was not correctly parsed"
535
+ end
536
+
537
+ def test_string_defaults_in_new_schema_when_overriding_domain
538
+ assert_equal "some value", Default.new.string_col, "Default of string column was not correctly parsed"
539
+ end
540
+
541
+ def test_decimal_defaults_in_new_schema_when_overriding_domain
542
+ assert_equal BigDecimal.new("3.14159265358979323846"), Default.new.decimal_col, "Default of decimal column was not correctly parsed"
543
+ end
544
+
545
+ def test_bpchar_defaults_in_new_schema_when_overriding_domain
546
+ @connection.execute "ALTER TABLE defaults ADD bpchar_col bpchar DEFAULT 'some value'"
547
+ Default.reset_column_information
548
+ assert_equal "some value", Default.new.bpchar_col, "Default of bpchar column was not correctly parsed"
549
+ end
550
+
551
+ def test_text_defaults_after_updating_column_default
552
+ @connection.execute "ALTER TABLE defaults ALTER COLUMN text_col SET DEFAULT 'some text'::schema_1.text"
553
+ assert_equal "some text", Default.new.text_col, "Default of text column was not correctly parsed after updating default using '::text' since postgreSQL will add parens to the default in db"
554
+ end
555
+
556
+ def test_default_containing_quote_and_colons
557
+ @connection.execute "ALTER TABLE defaults ALTER COLUMN string_col SET DEFAULT 'foo''::bar'"
558
+ assert_equal "foo'::bar", Default.new.string_col
559
+ end
560
+ end
561
+
562
+ class SchemaWithDotsTest < ActiveRecord::PostgreSQLTestCase
563
+ include PGSchemaHelper
564
+ self.use_transactional_tests = false
565
+
566
+ setup do
567
+ @connection = ActiveRecord::Base.connection
568
+ @connection.create_schema "my.schema"
569
+ end
570
+
571
+ teardown do
572
+ @connection.drop_schema "my.schema", if_exists: true
573
+ end
574
+
575
+ test "rename_table" do
576
+ with_schema_search_path('"my.schema"') do
577
+ @connection.create_table :posts
578
+ @connection.rename_table :posts, :articles
579
+ assert_equal ["articles"], @connection.tables
580
+ end
581
+ end
582
+
583
+ test "Active Record basics" do
584
+ with_schema_search_path('"my.schema"') do
585
+ @connection.create_table :articles do |t|
586
+ t.string :title
587
+ end
588
+ article_class = Class.new(ActiveRecord::Base) do
589
+ self.table_name = '"my.schema".articles'
590
+ end
591
+
592
+ article_class.create!(title: "zOMG, welcome to my blorgh!")
593
+ welcome_article = article_class.last
594
+ assert_equal "zOMG, welcome to my blorgh!", welcome_article.title
595
+ end
596
+ end
597
+ end