ibm_db 4.0.0-x86-mingw32 → 5.0.2-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 (570) hide show
  1. checksums.yaml +5 -5
  2. data/MANIFEST +14 -14
  3. data/README +208 -208
  4. data/ext/Makefile +269 -0
  5. data/ext/Makefile.nt32 +181 -181
  6. data/ext/Makefile.nt32.191 +212 -212
  7. data/ext/extconf.rb +322 -291
  8. data/ext/gil_release_version +3 -0
  9. data/ext/ibm_db.c +11879 -11887
  10. data/ext/mkmf.log +110 -0
  11. data/ext/ruby_ibm_db.h +241 -241
  12. data/ext/ruby_ibm_db_cli.c +866 -866
  13. data/ext/ruby_ibm_db_cli.h +500 -500
  14. data/ext/unicode_support_version +3 -0
  15. data/init.rb +41 -41
  16. data/lib/IBM_DB.rb +27 -27
  17. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3533 -3452
  18. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -5
  19. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  20. data/lib/mswin32/ibm_db.rb +90 -90
  21. data/lib/mswin32/rb2x/i386/ibm_db.so +0 -0
  22. data/test/active_record/connection_adapters/fake_adapter.rb +49 -49
  23. data/test/assets/example.log +1 -1
  24. data/test/assets/test.txt +1 -1
  25. data/test/cases/adapter_test.rb +351 -351
  26. data/test/cases/adapters/mysql2/active_schema_test.rb +193 -193
  27. data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -50
  28. data/test/cases/adapters/mysql2/boolean_test.rb +100 -100
  29. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -63
  30. data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -54
  31. data/test/cases/adapters/mysql2/connection_test.rb +210 -210
  32. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -45
  33. data/test/cases/adapters/mysql2/enum_test.rb +26 -26
  34. data/test/cases/adapters/mysql2/explain_test.rb +21 -21
  35. data/test/cases/adapters/mysql2/json_test.rb +195 -195
  36. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -83
  37. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -152
  38. data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -59
  39. data/test/cases/adapters/mysql2/schema_test.rb +126 -126
  40. data/test/cases/adapters/mysql2/sp_test.rb +36 -36
  41. data/test/cases/adapters/mysql2/sql_types_test.rb +14 -14
  42. data/test/cases/adapters/mysql2/table_options_test.rb +42 -42
  43. data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -66
  44. data/test/cases/adapters/postgresql/active_schema_test.rb +98 -98
  45. data/test/cases/adapters/postgresql/array_test.rb +339 -339
  46. data/test/cases/adapters/postgresql/bit_string_test.rb +82 -82
  47. data/test/cases/adapters/postgresql/bytea_test.rb +134 -134
  48. data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -26
  49. data/test/cases/adapters/postgresql/change_schema_test.rb +38 -38
  50. data/test/cases/adapters/postgresql/cidr_test.rb +25 -25
  51. data/test/cases/adapters/postgresql/citext_test.rb +78 -78
  52. data/test/cases/adapters/postgresql/collation_test.rb +53 -53
  53. data/test/cases/adapters/postgresql/composite_test.rb +132 -132
  54. data/test/cases/adapters/postgresql/connection_test.rb +257 -257
  55. data/test/cases/adapters/postgresql/datatype_test.rb +92 -92
  56. data/test/cases/adapters/postgresql/domain_test.rb +47 -47
  57. data/test/cases/adapters/postgresql/enum_test.rb +91 -91
  58. data/test/cases/adapters/postgresql/explain_test.rb +20 -20
  59. data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -63
  60. data/test/cases/adapters/postgresql/full_text_test.rb +44 -44
  61. data/test/cases/adapters/postgresql/geometric_test.rb +378 -378
  62. data/test/cases/adapters/postgresql/hstore_test.rb +382 -382
  63. data/test/cases/adapters/postgresql/infinity_test.rb +69 -69
  64. data/test/cases/adapters/postgresql/integer_test.rb +25 -25
  65. data/test/cases/adapters/postgresql/json_test.rb +237 -237
  66. data/test/cases/adapters/postgresql/ltree_test.rb +53 -53
  67. data/test/cases/adapters/postgresql/money_test.rb +96 -96
  68. data/test/cases/adapters/postgresql/network_test.rb +94 -94
  69. data/test/cases/adapters/postgresql/numbers_test.rb +49 -49
  70. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -405
  71. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -22
  72. data/test/cases/adapters/postgresql/quoting_test.rb +44 -44
  73. data/test/cases/adapters/postgresql/range_test.rb +343 -343
  74. data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -111
  75. data/test/cases/adapters/postgresql/rename_table_test.rb +34 -34
  76. data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -119
  77. data/test/cases/adapters/postgresql/schema_test.rb +597 -597
  78. data/test/cases/adapters/postgresql/serial_test.rb +154 -154
  79. data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -41
  80. data/test/cases/adapters/postgresql/timestamp_test.rb +90 -90
  81. data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -33
  82. data/test/cases/adapters/postgresql/utils_test.rb +62 -62
  83. data/test/cases/adapters/postgresql/uuid_test.rb +294 -294
  84. data/test/cases/adapters/postgresql/xml_test.rb +54 -54
  85. data/test/cases/adapters/sqlite3/collation_test.rb +53 -53
  86. data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -98
  87. data/test/cases/adapters/sqlite3/explain_test.rb +21 -21
  88. data/test/cases/adapters/sqlite3/quoting_test.rb +101 -101
  89. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -441
  90. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -24
  91. data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -20
  92. data/test/cases/aggregations_test.rb +168 -168
  93. data/test/cases/ar_schema_test.rb +146 -146
  94. data/test/cases/associations/association_scope_test.rb +16 -16
  95. data/test/cases/associations/belongs_to_associations_test.rb +1141 -1141
  96. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -41
  97. data/test/cases/associations/callbacks_test.rb +190 -190
  98. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  99. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  100. data/test/cases/associations/eager_load_nested_include_test.rb +126 -126
  101. data/test/cases/associations/eager_singularization_test.rb +148 -148
  102. data/test/cases/associations/eager_test.rb +1514 -1514
  103. data/test/cases/associations/extension_test.rb +87 -87
  104. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1004 -1004
  105. data/test/cases/associations/has_many_associations_test.rb +2501 -2501
  106. data/test/cases/associations/has_many_through_associations_test.rb +1271 -1271
  107. data/test/cases/associations/has_one_associations_test.rb +707 -707
  108. data/test/cases/associations/has_one_through_associations_test.rb +383 -383
  109. data/test/cases/associations/inner_join_association_test.rb +139 -139
  110. data/test/cases/associations/inverse_associations_test.rb +733 -733
  111. data/test/cases/associations/join_model_test.rb +777 -777
  112. data/test/cases/associations/left_outer_join_association_test.rb +88 -88
  113. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  114. data/test/cases/associations/required_test.rb +102 -102
  115. data/test/cases/associations_test.rb +385 -385
  116. data/test/cases/attribute_decorators_test.rb +126 -125
  117. data/test/cases/attribute_methods/read_test.rb +60 -60
  118. data/test/cases/attribute_methods_test.rb +1009 -1009
  119. data/test/cases/attribute_set_test.rb +270 -270
  120. data/test/cases/attribute_test.rb +246 -246
  121. data/test/cases/attributes_test.rb +253 -253
  122. data/test/cases/autosave_association_test.rb +1708 -1708
  123. data/test/cases/base_test.rb +1713 -1713
  124. data/test/cases/batches_test.rb +489 -489
  125. data/test/cases/binary_test.rb +44 -44
  126. data/test/cases/bind_parameter_test.rb +110 -110
  127. data/test/cases/cache_key_test.rb +26 -25
  128. data/test/cases/calculations_test.rb +798 -798
  129. data/test/cases/callbacks_test.rb +636 -636
  130. data/test/cases/clone_test.rb +40 -40
  131. data/test/cases/coders/json_test.rb +15 -15
  132. data/test/cases/coders/yaml_column_test.rb +63 -63
  133. data/test/cases/collection_cache_key_test.rb +115 -115
  134. data/test/cases/column_alias_test.rb +17 -17
  135. data/test/cases/column_definition_test.rb +92 -92
  136. data/test/cases/comment_test.rb +145 -143
  137. data/test/cases/connection_adapters/adapter_leasing_test.rb +56 -56
  138. data/test/cases/connection_adapters/connection_handler_test.rb +160 -160
  139. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  140. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +255 -255
  141. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +69 -69
  142. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  143. data/test/cases/connection_adapters/schema_cache_test.rb +61 -61
  144. data/test/cases/connection_adapters/type_lookup_test.rb +118 -118
  145. data/test/cases/connection_management_test.rb +112 -112
  146. data/test/cases/connection_pool_test.rb +521 -521
  147. data/test/cases/connection_specification/resolver_test.rb +131 -131
  148. data/test/cases/core_test.rb +112 -112
  149. data/test/cases/counter_cache_test.rb +214 -214
  150. data/test/cases/custom_locking_test.rb +17 -17
  151. data/test/cases/database_statements_test.rb +34 -34
  152. data/test/cases/date_test.rb +44 -44
  153. data/test/cases/date_time_precision_test.rb +107 -106
  154. data/test/cases/date_time_test.rb +61 -61
  155. data/test/cases/defaults_test.rb +219 -218
  156. data/test/cases/dirty_test.rb +763 -763
  157. data/test/cases/disconnected_test.rb +30 -30
  158. data/test/cases/dup_test.rb +157 -157
  159. data/test/cases/enum_test.rb +444 -444
  160. data/test/cases/errors_test.rb +16 -16
  161. data/test/cases/explain_subscriber_test.rb +64 -64
  162. data/test/cases/explain_test.rb +87 -87
  163. data/test/cases/finder_respond_to_test.rb +60 -60
  164. data/test/cases/finder_test.rb +1294 -1294
  165. data/test/cases/fixture_set/file_test.rb +156 -156
  166. data/test/cases/fixtures_test.rb +988 -988
  167. data/test/cases/forbidden_attributes_protection_test.rb +165 -165
  168. data/test/cases/habtm_destroy_order_test.rb +61 -61
  169. data/test/cases/helper.rb +204 -204
  170. data/test/cases/hot_compatibility_test.rb +142 -142
  171. data/test/cases/i18n_test.rb +45 -45
  172. data/test/cases/inheritance_test.rb +606 -606
  173. data/test/cases/integration_test.rb +155 -155
  174. data/test/cases/invalid_connection_test.rb +24 -24
  175. data/test/cases/invertible_migration_test.rb +387 -387
  176. data/test/cases/json_serialization_test.rb +311 -311
  177. data/test/cases/locking_test.rb +493 -493
  178. data/test/cases/log_subscriber_test.rb +225 -225
  179. data/test/cases/migration/change_schema_test.rb +458 -458
  180. data/test/cases/migration/change_table_test.rb +256 -256
  181. data/test/cases/migration/column_attributes_test.rb +176 -176
  182. data/test/cases/migration/column_positioning_test.rb +56 -56
  183. data/test/cases/migration/columns_test.rb +310 -310
  184. data/test/cases/migration/command_recorder_test.rb +350 -350
  185. data/test/cases/migration/compatibility_test.rb +118 -118
  186. data/test/cases/migration/create_join_table_test.rb +157 -157
  187. data/test/cases/migration/foreign_key_test.rb +362 -360
  188. data/test/cases/migration/helper.rb +39 -39
  189. data/test/cases/migration/index_test.rb +218 -218
  190. data/test/cases/migration/logger_test.rb +36 -36
  191. data/test/cases/migration/pending_migrations_test.rb +52 -52
  192. data/test/cases/migration/references_foreign_key_test.rb +221 -216
  193. data/test/cases/migration/references_index_test.rb +101 -101
  194. data/test/cases/migration/references_statements_test.rb +136 -136
  195. data/test/cases/migration/rename_table_test.rb +93 -93
  196. data/test/cases/migration_test.rb +1157 -1157
  197. data/test/cases/migrator_test.rb +471 -470
  198. data/test/cases/mixin_test.rb +68 -68
  199. data/test/cases/modules_test.rb +172 -172
  200. data/test/cases/multiparameter_attributes_test.rb +372 -372
  201. data/test/cases/multiple_db_test.rb +122 -122
  202. data/test/cases/nested_attributes_test.rb +1098 -1098
  203. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  204. data/test/cases/persistence_test.rb +1001 -1001
  205. data/test/cases/pooled_connections_test.rb +81 -81
  206. data/test/cases/primary_keys_test.rb +376 -376
  207. data/test/cases/query_cache_test.rb +446 -446
  208. data/test/cases/quoting_test.rb +202 -202
  209. data/test/cases/readonly_test.rb +119 -119
  210. data/test/cases/reaper_test.rb +85 -85
  211. data/test/cases/reflection_test.rb +509 -509
  212. data/test/cases/relation/delegation_test.rb +63 -63
  213. data/test/cases/relation/merging_test.rb +157 -157
  214. data/test/cases/relation/mutation_test.rb +183 -183
  215. data/test/cases/relation/or_test.rb +92 -92
  216. data/test/cases/relation/predicate_builder_test.rb +16 -16
  217. data/test/cases/relation/record_fetch_warning_test.rb +40 -40
  218. data/test/cases/relation/where_chain_test.rb +105 -105
  219. data/test/cases/relation/where_clause_test.rb +182 -182
  220. data/test/cases/relation/where_test.rb +322 -322
  221. data/test/cases/relation_test.rb +328 -328
  222. data/test/cases/relations_test.rb +2026 -2026
  223. data/test/cases/reload_models_test.rb +22 -22
  224. data/test/cases/result_test.rb +90 -90
  225. data/test/cases/sanitize_test.rb +176 -176
  226. data/test/cases/schema_dumper_test.rb +457 -457
  227. data/test/cases/schema_loading_test.rb +52 -52
  228. data/test/cases/scoping/default_scoping_test.rb +528 -528
  229. data/test/cases/scoping/named_scoping_test.rb +561 -561
  230. data/test/cases/scoping/relation_scoping_test.rb +400 -400
  231. data/test/cases/secure_token_test.rb +32 -32
  232. data/test/cases/serialization_test.rb +104 -104
  233. data/test/cases/serialized_attribute_test.rb +364 -364
  234. data/test/cases/statement_cache_test.rb +136 -136
  235. data/test/cases/store_test.rb +195 -195
  236. data/test/cases/suppressor_test.rb +63 -63
  237. data/test/cases/tasks/database_tasks_test.rb +462 -462
  238. data/test/cases/tasks/mysql_rake_test.rb +345 -345
  239. data/test/cases/tasks/postgresql_rake_test.rb +304 -304
  240. data/test/cases/tasks/sqlite_rake_test.rb +220 -220
  241. data/test/cases/test_case.rb +131 -131
  242. data/test/cases/test_fixtures_test.rb +36 -36
  243. data/test/cases/time_precision_test.rb +103 -102
  244. data/test/cases/timestamp_test.rb +501 -501
  245. data/test/cases/touch_later_test.rb +121 -121
  246. data/test/cases/transaction_callbacks_test.rb +518 -518
  247. data/test/cases/transaction_isolation_test.rb +106 -106
  248. data/test/cases/transactions_test.rb +835 -834
  249. data/test/cases/type/adapter_specific_registry_test.rb +133 -133
  250. data/test/cases/type/date_time_test.rb +14 -14
  251. data/test/cases/type/integer_test.rb +27 -27
  252. data/test/cases/type/string_test.rb +22 -22
  253. data/test/cases/type/type_map_test.rb +177 -177
  254. data/test/cases/type_test.rb +39 -39
  255. data/test/cases/types_test.rb +24 -24
  256. data/test/cases/unconnected_test.rb +33 -33
  257. data/test/cases/validations/absence_validation_test.rb +73 -73
  258. data/test/cases/validations/association_validation_test.rb +97 -97
  259. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  260. data/test/cases/validations/i18n_validation_test.rb +86 -86
  261. data/test/cases/validations/length_validation_test.rb +79 -79
  262. data/test/cases/validations/presence_validation_test.rb +103 -103
  263. data/test/cases/validations/uniqueness_validation_test.rb +548 -548
  264. data/test/cases/validations_repair_helper.rb +19 -19
  265. data/test/cases/validations_test.rb +194 -194
  266. data/test/cases/view_test.rb +216 -216
  267. data/test/cases/yaml_serialization_test.rb +121 -121
  268. data/test/config.example.yml +97 -97
  269. data/test/config.rb +5 -5
  270. data/test/connections/native_ibm_db/connection.rb +44 -0
  271. data/test/fixtures/accounts.yml +29 -29
  272. data/test/fixtures/admin/accounts.yml +2 -2
  273. data/test/fixtures/admin/users.yml +10 -10
  274. data/test/fixtures/author_addresses.yml +17 -17
  275. data/test/fixtures/author_favorites.yml +3 -3
  276. data/test/fixtures/authors.yml +23 -23
  277. data/test/fixtures/bad_posts.yml +9 -9
  278. data/test/fixtures/binaries.yml +133 -133
  279. data/test/fixtures/books.yml +31 -31
  280. data/test/fixtures/bulbs.yml +5 -5
  281. data/test/fixtures/cars.yml +9 -9
  282. data/test/fixtures/categories.yml +19 -19
  283. data/test/fixtures/categories/special_categories.yml +9 -9
  284. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  285. data/test/fixtures/categories_ordered.yml +7 -7
  286. data/test/fixtures/categories_posts.yml +31 -31
  287. data/test/fixtures/categorizations.yml +23 -23
  288. data/test/fixtures/clubs.yml +8 -8
  289. data/test/fixtures/collections.yml +3 -3
  290. data/test/fixtures/colleges.yml +3 -3
  291. data/test/fixtures/comments.yml +65 -65
  292. data/test/fixtures/companies.yml +67 -67
  293. data/test/fixtures/computers.yml +10 -10
  294. data/test/fixtures/content.yml +3 -3
  295. data/test/fixtures/content_positions.yml +3 -3
  296. data/test/fixtures/courses.yml +8 -8
  297. data/test/fixtures/customers.yml +25 -25
  298. data/test/fixtures/dashboards.yml +6 -6
  299. data/test/fixtures/dead_parrots.yml +5 -5
  300. data/test/fixtures/developers.yml +22 -22
  301. data/test/fixtures/developers_projects.yml +16 -16
  302. data/test/fixtures/dog_lovers.yml +7 -7
  303. data/test/fixtures/dogs.yml +4 -4
  304. data/test/fixtures/doubloons.yml +3 -3
  305. data/test/fixtures/edges.yml +5 -5
  306. data/test/fixtures/entrants.yml +14 -14
  307. data/test/fixtures/essays.yml +6 -6
  308. data/test/fixtures/faces.yml +11 -11
  309. data/test/fixtures/fk_test_has_fk.yml +3 -3
  310. data/test/fixtures/fk_test_has_pk.yml +1 -1
  311. data/test/fixtures/friendships.yml +4 -4
  312. data/test/fixtures/funny_jokes.yml +10 -10
  313. data/test/fixtures/interests.yml +33 -33
  314. data/test/fixtures/items.yml +3 -3
  315. data/test/fixtures/jobs.yml +7 -7
  316. data/test/fixtures/legacy_things.yml +3 -3
  317. data/test/fixtures/live_parrots.yml +4 -4
  318. data/test/fixtures/mateys.yml +4 -4
  319. data/test/fixtures/member_details.yml +8 -8
  320. data/test/fixtures/member_types.yml +6 -6
  321. data/test/fixtures/members.yml +11 -11
  322. data/test/fixtures/memberships.yml +34 -34
  323. data/test/fixtures/men.yml +5 -5
  324. data/test/fixtures/minimalistics.yml +2 -2
  325. data/test/fixtures/minivans.yml +5 -5
  326. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  327. data/test/fixtures/mixins.yml +29 -29
  328. data/test/fixtures/movies.yml +7 -7
  329. data/test/fixtures/naked/yml/accounts.yml +1 -1
  330. data/test/fixtures/naked/yml/companies.yml +1 -1
  331. data/test/fixtures/naked/yml/courses.yml +1 -1
  332. data/test/fixtures/naked/yml/parrots.yml +2 -2
  333. data/test/fixtures/naked/yml/trees.yml +3 -3
  334. data/test/fixtures/nodes.yml +29 -29
  335. data/test/fixtures/organizations.yml +5 -5
  336. data/test/fixtures/other_comments.yml +6 -6
  337. data/test/fixtures/other_dogs.yml +2 -2
  338. data/test/fixtures/other_posts.yml +7 -7
  339. data/test/fixtures/other_topics.yml +42 -42
  340. data/test/fixtures/owners.yml +9 -9
  341. data/test/fixtures/parrots.yml +27 -27
  342. data/test/fixtures/parrots_pirates.yml +7 -7
  343. data/test/fixtures/people.yml +24 -24
  344. data/test/fixtures/peoples_treasures.yml +3 -3
  345. data/test/fixtures/pets.yml +19 -19
  346. data/test/fixtures/pirates.yml +12 -15
  347. data/test/fixtures/posts.yml +80 -80
  348. data/test/fixtures/price_estimates.yml +16 -16
  349. data/test/fixtures/products.yml +4 -4
  350. data/test/fixtures/projects.yml +7 -7
  351. data/test/fixtures/ratings.yml +14 -14
  352. data/test/fixtures/readers.yml +11 -11
  353. data/test/fixtures/references.yml +17 -17
  354. data/test/fixtures/reserved_words/distinct.yml +5 -5
  355. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  356. data/test/fixtures/reserved_words/group.yml +14 -14
  357. data/test/fixtures/reserved_words/select.yml +8 -8
  358. data/test/fixtures/reserved_words/values.yml +7 -7
  359. data/test/fixtures/ships.yml +6 -6
  360. data/test/fixtures/speedometers.yml +8 -8
  361. data/test/fixtures/sponsors.yml +12 -12
  362. data/test/fixtures/string_key_objects.yml +7 -7
  363. data/test/fixtures/subscribers.yml +10 -10
  364. data/test/fixtures/subscriptions.yml +12 -12
  365. data/test/fixtures/taggings.yml +78 -78
  366. data/test/fixtures/tags.yml +11 -11
  367. data/test/fixtures/tasks.yml +7 -7
  368. data/test/fixtures/teapots.yml +3 -3
  369. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  370. data/test/fixtures/to_be_linked/users.yml +10 -10
  371. data/test/fixtures/topics.yml +49 -49
  372. data/test/fixtures/toys.yml +14 -14
  373. data/test/fixtures/traffic_lights.yml +9 -9
  374. data/test/fixtures/treasures.yml +10 -10
  375. data/test/fixtures/trees.yml +3 -3
  376. data/test/fixtures/uuid_children.yml +3 -3
  377. data/test/fixtures/uuid_parents.yml +2 -2
  378. data/test/fixtures/variants.yml +4 -4
  379. data/test/fixtures/vegetables.yml +19 -19
  380. data/test/fixtures/vertices.yml +3 -3
  381. data/test/fixtures/warehouse_things.yml +2 -2
  382. data/test/fixtures/zines.yml +5 -5
  383. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  384. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  385. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  386. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -9
  387. data/test/migrations/missing/1_people_have_last_names.rb +9 -9
  388. data/test/migrations/missing/3_we_need_reminders.rb +12 -12
  389. data/test/migrations/missing/4_innocent_jointable.rb +12 -12
  390. data/test/migrations/rename/1_we_need_things.rb +11 -11
  391. data/test/migrations/rename/2_rename_things.rb +9 -9
  392. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  393. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  394. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  395. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  396. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  397. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  398. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  399. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  400. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  401. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  402. data/test/migrations/valid/2_we_need_reminders.rb +12 -12
  403. data/test/migrations/valid/3_innocent_jointable.rb +12 -12
  404. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  405. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -12
  406. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -12
  407. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  408. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  409. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  410. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  411. data/test/models/admin.rb +5 -5
  412. data/test/models/admin/account.rb +3 -3
  413. data/test/models/admin/user.rb +40 -40
  414. data/test/models/aircraft.rb +5 -5
  415. data/test/models/arunit2_model.rb +3 -3
  416. data/test/models/author.rb +209 -209
  417. data/test/models/auto_id.rb +4 -4
  418. data/test/models/autoloadable/extra_firm.rb +2 -2
  419. data/test/models/binary.rb +2 -2
  420. data/test/models/bird.rb +12 -12
  421. data/test/models/book.rb +23 -23
  422. data/test/models/boolean.rb +2 -2
  423. data/test/models/bulb.rb +52 -52
  424. data/test/models/cake_designer.rb +3 -3
  425. data/test/models/car.rb +29 -29
  426. data/test/models/carrier.rb +2 -2
  427. data/test/models/cat.rb +10 -10
  428. data/test/models/categorization.rb +19 -19
  429. data/test/models/category.rb +35 -35
  430. data/test/models/chef.rb +8 -8
  431. data/test/models/citation.rb +3 -3
  432. data/test/models/club.rb +25 -25
  433. data/test/models/college.rb +10 -10
  434. data/test/models/column.rb +3 -3
  435. data/test/models/column_name.rb +3 -3
  436. data/test/models/comment.rb +76 -76
  437. data/test/models/company.rb +230 -230
  438. data/test/models/company_in_module.rb +98 -98
  439. data/test/models/computer.rb +3 -3
  440. data/test/models/contact.rb +41 -41
  441. data/test/models/content.rb +40 -40
  442. data/test/models/contract.rb +20 -20
  443. data/test/models/country.rb +7 -7
  444. data/test/models/course.rb +6 -6
  445. data/test/models/customer.rb +83 -83
  446. data/test/models/customer_carrier.rb +14 -14
  447. data/test/models/dashboard.rb +3 -3
  448. data/test/models/default.rb +2 -2
  449. data/test/models/department.rb +4 -4
  450. data/test/models/developer.rb +274 -274
  451. data/test/models/dog.rb +5 -5
  452. data/test/models/dog_lover.rb +5 -5
  453. data/test/models/doubloon.rb +12 -12
  454. data/test/models/drink_designer.rb +3 -3
  455. data/test/models/edge.rb +5 -5
  456. data/test/models/electron.rb +5 -5
  457. data/test/models/engine.rb +4 -4
  458. data/test/models/entrant.rb +3 -3
  459. data/test/models/essay.rb +5 -5
  460. data/test/models/event.rb +3 -3
  461. data/test/models/eye.rb +37 -37
  462. data/test/models/face.rb +9 -9
  463. data/test/models/friendship.rb +6 -6
  464. data/test/models/guid.rb +2 -2
  465. data/test/models/guitar.rb +4 -4
  466. data/test/models/hotel.rb +11 -11
  467. data/test/models/image.rb +3 -3
  468. data/test/models/interest.rb +5 -5
  469. data/test/models/invoice.rb +4 -4
  470. data/test/models/item.rb +7 -7
  471. data/test/models/job.rb +7 -7
  472. data/test/models/joke.rb +7 -7
  473. data/test/models/keyboard.rb +3 -3
  474. data/test/models/legacy_thing.rb +3 -3
  475. data/test/models/lesson.rb +11 -11
  476. data/test/models/line_item.rb +3 -3
  477. data/test/models/liquid.rb +4 -4
  478. data/test/models/man.rb +11 -11
  479. data/test/models/matey.rb +4 -4
  480. data/test/models/member.rb +42 -42
  481. data/test/models/member_detail.rb +8 -8
  482. data/test/models/member_type.rb +3 -3
  483. data/test/models/membership.rb +35 -35
  484. data/test/models/mentor.rb +2 -2
  485. data/test/models/minimalistic.rb +2 -2
  486. data/test/models/minivan.rb +9 -9
  487. data/test/models/mixed_case_monkey.rb +3 -3
  488. data/test/models/mocktail_designer.rb +2 -2
  489. data/test/models/molecule.rb +6 -6
  490. data/test/models/movie.rb +5 -5
  491. data/test/models/node.rb +5 -5
  492. data/test/models/non_primary_key.rb +2 -2
  493. data/test/models/notification.rb +3 -3
  494. data/test/models/order.rb +4 -4
  495. data/test/models/organization.rb +14 -14
  496. data/test/models/other_dog.rb +5 -5
  497. data/test/models/owner.rb +37 -37
  498. data/test/models/parrot.rb +28 -28
  499. data/test/models/person.rb +142 -142
  500. data/test/models/personal_legacy_thing.rb +4 -4
  501. data/test/models/pet.rb +18 -18
  502. data/test/models/pet_treasure.rb +6 -6
  503. data/test/models/pirate.rb +92 -92
  504. data/test/models/possession.rb +3 -3
  505. data/test/models/post.rb +273 -273
  506. data/test/models/price_estimate.rb +4 -4
  507. data/test/models/professor.rb +5 -5
  508. data/test/models/project.rb +40 -40
  509. data/test/models/publisher.rb +2 -2
  510. data/test/models/publisher/article.rb +4 -4
  511. data/test/models/publisher/magazine.rb +3 -3
  512. data/test/models/rating.rb +4 -4
  513. data/test/models/reader.rb +23 -23
  514. data/test/models/recipe.rb +3 -3
  515. data/test/models/record.rb +2 -2
  516. data/test/models/reference.rb +22 -22
  517. data/test/models/reply.rb +61 -61
  518. data/test/models/ship.rb +39 -39
  519. data/test/models/ship_part.rb +8 -8
  520. data/test/models/shop.rb +17 -17
  521. data/test/models/shop_account.rb +6 -6
  522. data/test/models/speedometer.rb +6 -6
  523. data/test/models/sponsor.rb +7 -7
  524. data/test/models/string_key_object.rb +3 -3
  525. data/test/models/student.rb +4 -4
  526. data/test/models/subject.rb +16 -16
  527. data/test/models/subscriber.rb +8 -8
  528. data/test/models/subscription.rb +4 -4
  529. data/test/models/tag.rb +13 -13
  530. data/test/models/tagging.rb +13 -13
  531. data/test/models/task.rb +5 -5
  532. data/test/models/topic.rb +118 -118
  533. data/test/models/toy.rb +6 -6
  534. data/test/models/traffic_light.rb +4 -4
  535. data/test/models/treasure.rb +14 -14
  536. data/test/models/treaty.rb +7 -7
  537. data/test/models/tree.rb +3 -3
  538. data/test/models/tuning_peg.rb +4 -4
  539. data/test/models/tyre.rb +11 -11
  540. data/test/models/user.rb +14 -14
  541. data/test/models/uuid_child.rb +3 -3
  542. data/test/models/uuid_item.rb +6 -6
  543. data/test/models/uuid_parent.rb +3 -3
  544. data/test/models/vegetables.rb +24 -24
  545. data/test/models/vehicle.rb +6 -6
  546. data/test/models/vertex.rb +9 -9
  547. data/test/models/warehouse_thing.rb +5 -5
  548. data/test/models/wheel.rb +3 -3
  549. data/test/models/without_table.rb +3 -3
  550. data/test/models/zine.rb +3 -3
  551. data/test/schema/i5/ibm_db_specific_schema.rb +137 -0
  552. data/test/schema/ids/ibm_db_specific_schema.rb +140 -0
  553. data/test/schema/luw/ibm_db_specific_schema.rb +137 -0
  554. data/test/schema/mysql2_specific_schema.rb +68 -68
  555. data/test/schema/oracle_specific_schema.rb +40 -40
  556. data/test/schema/postgresql_specific_schema.rb +114 -114
  557. data/test/schema/schema.rb +1057 -1057
  558. data/test/schema/schema.rb.original +1057 -1057
  559. data/test/schema/sqlite_specific_schema.rb +18 -18
  560. data/test/schema/zOS/ibm_db_specific_schema.rb +208 -0
  561. data/test/support/config.rb +43 -43
  562. data/test/support/connection.rb +23 -23
  563. data/test/support/connection_helper.rb +14 -14
  564. data/test/support/ddl_helper.rb +8 -8
  565. data/test/support/schema_dumping_helper.rb +20 -20
  566. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -22
  567. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -182
  568. metadata +24 -13
  569. data/test/fixtures/author_addresses.original +0 -11
  570. data/test/fixtures/authors.original +0 -17
@@ -1,597 +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
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