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