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,493 +1,493 @@
1
- require 'thread'
2
- require "cases/helper"
3
- require 'models/person'
4
- require 'models/job'
5
- require 'models/reader'
6
- require 'models/ship'
7
- require 'models/legacy_thing'
8
- require 'models/personal_legacy_thing'
9
- require 'models/reference'
10
- require 'models/string_key_object'
11
- require 'models/car'
12
- require 'models/bulb'
13
- require 'models/engine'
14
- require 'models/wheel'
15
- require 'models/treasure'
16
-
17
- class LockWithoutDefault < ActiveRecord::Base; end
18
-
19
- class LockWithCustomColumnWithoutDefault < ActiveRecord::Base
20
- self.table_name = :lock_without_defaults_cust
21
- self.column_defaults # to test @column_defaults caching.
22
- self.locking_column = :custom_lock_version
23
- end
24
-
25
- class ReadonlyNameShip < Ship
26
- attr_readonly :name
27
- end
28
-
29
- class OptimisticLockingTest < ActiveRecord::TestCase
30
- fixtures :people, :legacy_things, :references, :string_key_objects, :peoples_treasures
31
-
32
- def test_quote_value_passed_lock_col
33
- p1 = Person.find(1)
34
- assert_equal 0, p1.lock_version
35
-
36
- p1.first_name = 'anika2'
37
- p1.save!
38
-
39
- assert_equal 1, p1.lock_version
40
- end
41
-
42
- def test_non_integer_lock_existing
43
- s1 = StringKeyObject.find("record1")
44
- s2 = StringKeyObject.find("record1")
45
- assert_equal 0, s1.lock_version
46
- assert_equal 0, s2.lock_version
47
-
48
- s1.name = 'updated record'
49
- s1.save!
50
- assert_equal 1, s1.lock_version
51
- assert_equal 0, s2.lock_version
52
-
53
- s2.name = 'doubly updated record'
54
- assert_raise(ActiveRecord::StaleObjectError) { s2.save! }
55
- end
56
-
57
- def test_non_integer_lock_destroy
58
- s1 = StringKeyObject.find("record1")
59
- s2 = StringKeyObject.find("record1")
60
- assert_equal 0, s1.lock_version
61
- assert_equal 0, s2.lock_version
62
-
63
- s1.name = 'updated record'
64
- s1.save!
65
- assert_equal 1, s1.lock_version
66
- assert_equal 0, s2.lock_version
67
- assert_raise(ActiveRecord::StaleObjectError) { s2.destroy }
68
-
69
- assert s1.destroy
70
- assert s1.frozen?
71
- assert s1.destroyed?
72
- assert_raises(ActiveRecord::RecordNotFound) { StringKeyObject.find("record1") }
73
- end
74
-
75
- def test_lock_existing
76
- p1 = Person.find(1)
77
- p2 = Person.find(1)
78
- assert_equal 0, p1.lock_version
79
- assert_equal 0, p2.lock_version
80
-
81
- p1.first_name = 'stu'
82
- p1.save!
83
- assert_equal 1, p1.lock_version
84
- assert_equal 0, p2.lock_version
85
-
86
- p2.first_name = 'sue'
87
- assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
88
- end
89
-
90
- # See Lighthouse ticket #1966
91
- def test_lock_destroy
92
- p1 = Person.find(1)
93
- p2 = Person.find(1)
94
- assert_equal 0, p1.lock_version
95
- assert_equal 0, p2.lock_version
96
-
97
- p1.first_name = 'stu'
98
- p1.save!
99
- assert_equal 1, p1.lock_version
100
- assert_equal 0, p2.lock_version
101
-
102
- assert_raises(ActiveRecord::StaleObjectError) { p2.destroy }
103
-
104
- assert p1.destroy
105
- assert p1.frozen?
106
- assert p1.destroyed?
107
- assert_raises(ActiveRecord::RecordNotFound) { Person.find(1) }
108
- end
109
-
110
- def test_lock_repeating
111
- p1 = Person.find(1)
112
- p2 = Person.find(1)
113
- assert_equal 0, p1.lock_version
114
- assert_equal 0, p2.lock_version
115
-
116
- p1.first_name = 'stu'
117
- p1.save!
118
- assert_equal 1, p1.lock_version
119
- assert_equal 0, p2.lock_version
120
-
121
- p2.first_name = 'sue'
122
- assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
123
- p2.first_name = 'sue2'
124
- assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
125
- end
126
-
127
- def test_lock_new
128
- p1 = Person.new(:first_name => 'anika')
129
- assert_equal 0, p1.lock_version
130
-
131
- p1.first_name = 'anika2'
132
- p1.save!
133
- p2 = Person.find(p1.id)
134
- assert_equal 0, p1.lock_version
135
- assert_equal 0, p2.lock_version
136
-
137
- p1.first_name = 'anika3'
138
- p1.save!
139
- assert_equal 1, p1.lock_version
140
- assert_equal 0, p2.lock_version
141
-
142
- p2.first_name = 'sue'
143
- assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
144
- end
145
-
146
- def test_lock_exception_record
147
- p1 = Person.new(:first_name => 'mira')
148
- assert_equal 0, p1.lock_version
149
-
150
- p1.first_name = 'mira2'
151
- p1.save!
152
- p2 = Person.find(p1.id)
153
- assert_equal 0, p1.lock_version
154
- assert_equal 0, p2.lock_version
155
-
156
- p1.first_name = 'mira3'
157
- p1.save!
158
-
159
- p2.first_name = 'sue'
160
- error = assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
161
- assert_equal(error.record.object_id, p2.object_id)
162
- end
163
-
164
- def test_lock_new_with_nil
165
- p1 = Person.new(:first_name => 'anika')
166
- p1.save!
167
- p1.lock_version = nil # simulate bad fixture or column with no default
168
- p1.save!
169
- assert_equal 1, p1.lock_version
170
- end
171
-
172
- def test_lock_new_when_explicitly_passing_nil
173
- p1 = Person.new(:first_name => 'anika', lock_version: nil)
174
- p1.save!
175
- assert_equal 0, p1.lock_version
176
- end
177
-
178
- def test_touch_existing_lock
179
- p1 = Person.find(1)
180
- assert_equal 0, p1.lock_version
181
-
182
- p1.touch
183
- assert_equal 1, p1.lock_version
184
- end
185
-
186
- def test_touch_stale_object
187
- person = Person.create!(first_name: 'Mehmet Emin')
188
- stale_person = Person.find(person.id)
189
- person.update_attribute(:gender, 'M')
190
-
191
- assert_raises(ActiveRecord::StaleObjectError) do
192
- stale_person.touch
193
- end
194
- end
195
-
196
- def test_lock_column_name_existing
197
- t1 = LegacyThing.find(1)
198
- t2 = LegacyThing.find(1)
199
- assert_equal 0, t1.version
200
- assert_equal 0, t2.version
201
-
202
- t1.tps_report_number = 700
203
- t1.save!
204
- assert_equal 1, t1.version
205
- assert_equal 0, t2.version
206
-
207
- t2.tps_report_number = 800
208
- assert_raise(ActiveRecord::StaleObjectError) { t2.save! }
209
- end
210
-
211
- def test_lock_column_is_mass_assignable
212
- p1 = Person.create(:first_name => 'bianca')
213
- assert_equal 0, p1.lock_version
214
- assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
215
-
216
- p1.first_name = 'bianca2'
217
- p1.save!
218
- assert_equal 1, p1.lock_version
219
- assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
220
- end
221
-
222
- def test_lock_without_default_sets_version_to_zero
223
- t1 = LockWithoutDefault.new
224
- assert_equal 0, t1.lock_version
225
-
226
- t1.save
227
- t1 = LockWithoutDefault.find(t1.id)
228
- assert_equal 0, t1.lock_version
229
- end
230
-
231
- def test_lock_with_custom_column_without_default_sets_version_to_zero
232
- t1 = LockWithCustomColumnWithoutDefault.new
233
- assert_equal 0, t1.custom_lock_version
234
- assert_nil t1.custom_lock_version_before_type_cast
235
-
236
- t1.save!
237
- t1.reload
238
- assert_equal 0, t1.custom_lock_version
239
- assert [0, "0"].include?(t1.custom_lock_version_before_type_cast)
240
- end
241
-
242
- def test_readonly_attributes
243
- assert_equal Set.new([ 'name' ]), ReadonlyNameShip.readonly_attributes
244
-
245
- s = ReadonlyNameShip.create(:name => "unchangeable name")
246
- s.reload
247
- assert_equal "unchangeable name", s.name
248
-
249
- s.update(name: "changed name")
250
- s.reload
251
- assert_equal "unchangeable name", s.name
252
- end
253
-
254
- def test_quote_table_name
255
- ref = references(:michael_magician)
256
- ref.favourite = !ref.favourite
257
- assert ref.save
258
- end
259
-
260
- # Useful for partial updates, don't only update the lock_version if there
261
- # is nothing else being updated.
262
- def test_update_without_attributes_does_not_only_update_lock_version
263
- assert_nothing_raised do
264
- p1 = Person.create!(:first_name => 'anika')
265
- lock_version = p1.lock_version
266
- p1.save
267
- p1.reload
268
- assert_equal lock_version, p1.lock_version
269
- end
270
- end
271
-
272
- def test_polymorphic_destroy_with_dependencies_and_lock_version
273
- car = Car.create!
274
-
275
- assert_difference 'car.wheels.count' do
276
- car.wheels << Wheel.create!
277
- end
278
- assert_difference 'car.wheels.count', -1 do
279
- car.reload.destroy
280
- end
281
- assert car.destroyed?
282
- end
283
-
284
- def test_removing_has_and_belongs_to_many_associations_upon_destroy
285
- p = RichPerson.create! first_name: 'Jon'
286
- p.treasures.create!
287
- assert !p.treasures.empty?
288
- p.destroy
289
- assert p.treasures.empty?
290
- assert RichPerson.connection.select_all("SELECT * FROM peoples_treasures WHERE rich_person_id = 1").empty?
291
- end
292
-
293
- def test_yaml_dumping_with_lock_column
294
- t1 = LockWithoutDefault.new
295
- t2 = YAML.load(YAML.dump(t1))
296
-
297
- assert_equal t1.attributes, t2.attributes
298
- end
299
- end
300
-
301
- class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
302
- fixtures :people, :legacy_things, :references
303
-
304
- # need to disable transactional tests, because otherwise the sqlite3
305
- # adapter (at least) chokes when we try and change the schema in the middle
306
- # of a test (see test_increment_counter_*).
307
- self.use_transactional_tests = false
308
-
309
- { :lock_version => Person, :custom_lock_version => LegacyThing }.each do |name, model|
310
- define_method("test_increment_counter_updates_#{name}") do
311
- counter_test model, 1 do |id|
312
- model.increment_counter :test_count, id
313
- end
314
- end
315
-
316
- define_method("test_decrement_counter_updates_#{name}") do
317
- counter_test model, -1 do |id|
318
- model.decrement_counter :test_count, id
319
- end
320
- end
321
-
322
- define_method("test_update_counters_updates_#{name}") do
323
- counter_test model, 1 do |id|
324
- model.update_counters id, :test_count => 1
325
- end
326
- end
327
- end
328
-
329
- # See Lighthouse ticket #1966
330
- def test_destroy_dependents
331
- # Establish dependent relationship between Person and PersonalLegacyThing
332
- add_counter_column_to(Person, 'personal_legacy_things_count')
333
- PersonalLegacyThing.reset_column_information
334
-
335
- # Make sure that counter incrementing doesn't cause problems
336
- p1 = Person.new(:first_name => 'fjord')
337
- p1.save!
338
- t = PersonalLegacyThing.new(:person => p1)
339
- t.save!
340
- p1.reload
341
- assert_equal 1, p1.personal_legacy_things_count
342
- assert p1.destroy
343
- assert_equal true, p1.frozen?
344
- assert_raises(ActiveRecord::RecordNotFound) { Person.find(p1.id) }
345
- assert_raises(ActiveRecord::RecordNotFound) { PersonalLegacyThing.find(t.id) }
346
- ensure
347
- remove_counter_column_from(Person, 'personal_legacy_things_count')
348
- PersonalLegacyThing.reset_column_information
349
- end
350
-
351
- private
352
-
353
- def add_counter_column_to(model, col='test_count')
354
- model.connection.add_column model.table_name, col, :integer, :null => false, :default => 0
355
- model.reset_column_information
356
- end
357
-
358
- def remove_counter_column_from(model, col = :test_count)
359
- model.connection.remove_column model.table_name, col
360
- model.reset_column_information
361
- end
362
-
363
- def counter_test(model, expected_count)
364
- add_counter_column_to(model)
365
- object = model.first
366
- assert_equal 0, object.test_count
367
- assert_equal 0, object.send(model.locking_column)
368
- yield object.id
369
- object.reload
370
- assert_equal expected_count, object.test_count
371
- assert_equal 1, object.send(model.locking_column)
372
- ensure
373
- remove_counter_column_from(model)
374
- end
375
- end
376
-
377
-
378
- # TODO: test against the generated SQL since testing locking behavior itself
379
- # is so cumbersome. Will deadlock Ruby threads if the underlying db.execute
380
- # blocks, so separate script called by Kernel#system is needed.
381
- # (See exec vs. async_exec in the PostgreSQL adapter.)
382
- unless in_memory_db?
383
- class PessimisticLockingTest < ActiveRecord::TestCase
384
- self.use_transactional_tests = false
385
- fixtures :people, :readers
386
-
387
- def setup
388
- Person.connection_pool.clear_reloadable_connections!
389
- # Avoid introspection queries during tests.
390
- Person.columns; Reader.columns
391
- end
392
-
393
- # Test typical find.
394
- def test_sane_find_with_lock
395
- assert_nothing_raised do
396
- Person.transaction do
397
- Person.lock.find(1)
398
- end
399
- end
400
- end
401
-
402
- # PostgreSQL protests SELECT ... FOR UPDATE on an outer join.
403
- unless current_adapter?(:PostgreSQLAdapter)
404
- # Test locked eager find.
405
- def test_eager_find_with_lock
406
- assert_nothing_raised do
407
- Person.transaction do
408
- Person.includes(:readers).lock.find(1)
409
- end
410
- end
411
- end
412
- end
413
-
414
- # Locking a record reloads it.
415
- def test_sane_lock_method
416
- assert_nothing_raised do
417
- Person.transaction do
418
- person = Person.find 1
419
- old, person.first_name = person.first_name, 'fooman'
420
- person.lock!
421
- assert_equal old, person.first_name
422
- end
423
- end
424
- end
425
-
426
- def test_with_lock_commits_transaction
427
- person = Person.find 1
428
- person.with_lock do
429
- person.first_name = 'fooman'
430
- person.save!
431
- end
432
- assert_equal 'fooman', person.reload.first_name
433
- end
434
-
435
- def test_with_lock_rolls_back_transaction
436
- person = Person.find 1
437
- old = person.first_name
438
- person.with_lock do
439
- person.first_name = 'fooman'
440
- person.save!
441
- raise 'oops'
442
- end rescue nil
443
- assert_equal old, person.reload.first_name
444
- end
445
-
446
- if current_adapter?(:PostgreSQLAdapter)
447
- def test_lock_sending_custom_lock_statement
448
- Person.transaction do
449
- person = Person.find(1)
450
- assert_sql(/LIMIT \$?\d FOR SHARE NOWAIT/) do
451
- person.lock!('FOR SHARE NOWAIT')
452
- end
453
- end
454
- end
455
- end
456
-
457
- if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
458
- def test_no_locks_no_wait
459
- first, second = duel { Person.find 1 }
460
- assert first.end > second.end
461
- end
462
-
463
- protected
464
- def duel(zzz = 5)
465
- t0, t1, t2, t3 = nil, nil, nil, nil
466
-
467
- a = Thread.new do
468
- t0 = Time.now
469
- Person.transaction do
470
- yield
471
- sleep zzz # block thread 2 for zzz seconds
472
- end
473
- t1 = Time.now
474
- end
475
-
476
- b = Thread.new do
477
- sleep zzz / 2.0 # ensure thread 1 tx starts first
478
- t2 = Time.now
479
- Person.transaction { yield }
480
- t3 = Time.now
481
- end
482
-
483
- a.join
484
- b.join
485
-
486
- assert t1 > t0 + zzz
487
- assert t2 > t0
488
- assert t3 > t2
489
- [t0.to_f..t1.to_f, t2.to_f..t3.to_f]
490
- end
491
- end
492
- end
493
- end
1
+ require 'thread'
2
+ require "cases/helper"
3
+ require 'models/person'
4
+ require 'models/job'
5
+ require 'models/reader'
6
+ require 'models/ship'
7
+ require 'models/legacy_thing'
8
+ require 'models/personal_legacy_thing'
9
+ require 'models/reference'
10
+ require 'models/string_key_object'
11
+ require 'models/car'
12
+ require 'models/bulb'
13
+ require 'models/engine'
14
+ require 'models/wheel'
15
+ require 'models/treasure'
16
+
17
+ class LockWithoutDefault < ActiveRecord::Base; end
18
+
19
+ class LockWithCustomColumnWithoutDefault < ActiveRecord::Base
20
+ self.table_name = :lock_without_defaults_cust
21
+ self.column_defaults # to test @column_defaults caching.
22
+ self.locking_column = :custom_lock_version
23
+ end
24
+
25
+ class ReadonlyNameShip < Ship
26
+ attr_readonly :name
27
+ end
28
+
29
+ class OptimisticLockingTest < ActiveRecord::TestCase
30
+ fixtures :people, :legacy_things, :references, :string_key_objects, :peoples_treasures
31
+
32
+ def test_quote_value_passed_lock_col
33
+ p1 = Person.find(1)
34
+ assert_equal 0, p1.lock_version
35
+
36
+ p1.first_name = 'anika2'
37
+ p1.save!
38
+
39
+ assert_equal 1, p1.lock_version
40
+ end
41
+
42
+ def test_non_integer_lock_existing
43
+ s1 = StringKeyObject.find("record1")
44
+ s2 = StringKeyObject.find("record1")
45
+ assert_equal 0, s1.lock_version
46
+ assert_equal 0, s2.lock_version
47
+
48
+ s1.name = 'updated record'
49
+ s1.save!
50
+ assert_equal 1, s1.lock_version
51
+ assert_equal 0, s2.lock_version
52
+
53
+ s2.name = 'doubly updated record'
54
+ assert_raise(ActiveRecord::StaleObjectError) { s2.save! }
55
+ end
56
+
57
+ def test_non_integer_lock_destroy
58
+ s1 = StringKeyObject.find("record1")
59
+ s2 = StringKeyObject.find("record1")
60
+ assert_equal 0, s1.lock_version
61
+ assert_equal 0, s2.lock_version
62
+
63
+ s1.name = 'updated record'
64
+ s1.save!
65
+ assert_equal 1, s1.lock_version
66
+ assert_equal 0, s2.lock_version
67
+ assert_raise(ActiveRecord::StaleObjectError) { s2.destroy }
68
+
69
+ assert s1.destroy
70
+ assert s1.frozen?
71
+ assert s1.destroyed?
72
+ assert_raises(ActiveRecord::RecordNotFound) { StringKeyObject.find("record1") }
73
+ end
74
+
75
+ def test_lock_existing
76
+ p1 = Person.find(1)
77
+ p2 = Person.find(1)
78
+ assert_equal 0, p1.lock_version
79
+ assert_equal 0, p2.lock_version
80
+
81
+ p1.first_name = 'stu'
82
+ p1.save!
83
+ assert_equal 1, p1.lock_version
84
+ assert_equal 0, p2.lock_version
85
+
86
+ p2.first_name = 'sue'
87
+ assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
88
+ end
89
+
90
+ # See Lighthouse ticket #1966
91
+ def test_lock_destroy
92
+ p1 = Person.find(1)
93
+ p2 = Person.find(1)
94
+ assert_equal 0, p1.lock_version
95
+ assert_equal 0, p2.lock_version
96
+
97
+ p1.first_name = 'stu'
98
+ p1.save!
99
+ assert_equal 1, p1.lock_version
100
+ assert_equal 0, p2.lock_version
101
+
102
+ assert_raises(ActiveRecord::StaleObjectError) { p2.destroy }
103
+
104
+ assert p1.destroy
105
+ assert p1.frozen?
106
+ assert p1.destroyed?
107
+ assert_raises(ActiveRecord::RecordNotFound) { Person.find(1) }
108
+ end
109
+
110
+ def test_lock_repeating
111
+ p1 = Person.find(1)
112
+ p2 = Person.find(1)
113
+ assert_equal 0, p1.lock_version
114
+ assert_equal 0, p2.lock_version
115
+
116
+ p1.first_name = 'stu'
117
+ p1.save!
118
+ assert_equal 1, p1.lock_version
119
+ assert_equal 0, p2.lock_version
120
+
121
+ p2.first_name = 'sue'
122
+ assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
123
+ p2.first_name = 'sue2'
124
+ assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
125
+ end
126
+
127
+ def test_lock_new
128
+ p1 = Person.new(:first_name => 'anika')
129
+ assert_equal 0, p1.lock_version
130
+
131
+ p1.first_name = 'anika2'
132
+ p1.save!
133
+ p2 = Person.find(p1.id)
134
+ assert_equal 0, p1.lock_version
135
+ assert_equal 0, p2.lock_version
136
+
137
+ p1.first_name = 'anika3'
138
+ p1.save!
139
+ assert_equal 1, p1.lock_version
140
+ assert_equal 0, p2.lock_version
141
+
142
+ p2.first_name = 'sue'
143
+ assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
144
+ end
145
+
146
+ def test_lock_exception_record
147
+ p1 = Person.new(:first_name => 'mira')
148
+ assert_equal 0, p1.lock_version
149
+
150
+ p1.first_name = 'mira2'
151
+ p1.save!
152
+ p2 = Person.find(p1.id)
153
+ assert_equal 0, p1.lock_version
154
+ assert_equal 0, p2.lock_version
155
+
156
+ p1.first_name = 'mira3'
157
+ p1.save!
158
+
159
+ p2.first_name = 'sue'
160
+ error = assert_raise(ActiveRecord::StaleObjectError) { p2.save! }
161
+ assert_equal(error.record.object_id, p2.object_id)
162
+ end
163
+
164
+ def test_lock_new_with_nil
165
+ p1 = Person.new(:first_name => 'anika')
166
+ p1.save!
167
+ p1.lock_version = nil # simulate bad fixture or column with no default
168
+ p1.save!
169
+ assert_equal 1, p1.lock_version
170
+ end
171
+
172
+ def test_lock_new_when_explicitly_passing_nil
173
+ p1 = Person.new(:first_name => 'anika', lock_version: nil)
174
+ p1.save!
175
+ assert_equal 0, p1.lock_version
176
+ end
177
+
178
+ def test_touch_existing_lock
179
+ p1 = Person.find(1)
180
+ assert_equal 0, p1.lock_version
181
+
182
+ p1.touch
183
+ assert_equal 1, p1.lock_version
184
+ end
185
+
186
+ def test_touch_stale_object
187
+ person = Person.create!(first_name: 'Mehmet Emin')
188
+ stale_person = Person.find(person.id)
189
+ person.update_attribute(:gender, 'M')
190
+
191
+ assert_raises(ActiveRecord::StaleObjectError) do
192
+ stale_person.touch
193
+ end
194
+ end
195
+
196
+ def test_lock_column_name_existing
197
+ t1 = LegacyThing.find(1)
198
+ t2 = LegacyThing.find(1)
199
+ assert_equal 0, t1.version
200
+ assert_equal 0, t2.version
201
+
202
+ t1.tps_report_number = 700
203
+ t1.save!
204
+ assert_equal 1, t1.version
205
+ assert_equal 0, t2.version
206
+
207
+ t2.tps_report_number = 800
208
+ assert_raise(ActiveRecord::StaleObjectError) { t2.save! }
209
+ end
210
+
211
+ def test_lock_column_is_mass_assignable
212
+ p1 = Person.create(:first_name => 'bianca')
213
+ assert_equal 0, p1.lock_version
214
+ assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
215
+
216
+ p1.first_name = 'bianca2'
217
+ p1.save!
218
+ assert_equal 1, p1.lock_version
219
+ assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
220
+ end
221
+
222
+ def test_lock_without_default_sets_version_to_zero
223
+ t1 = LockWithoutDefault.new
224
+ assert_equal 0, t1.lock_version
225
+
226
+ t1.save
227
+ t1 = LockWithoutDefault.find(t1.id)
228
+ assert_equal 0, t1.lock_version
229
+ end
230
+
231
+ def test_lock_with_custom_column_without_default_sets_version_to_zero
232
+ t1 = LockWithCustomColumnWithoutDefault.new
233
+ assert_equal 0, t1.custom_lock_version
234
+ assert_nil t1.custom_lock_version_before_type_cast
235
+
236
+ t1.save!
237
+ t1.reload
238
+ assert_equal 0, t1.custom_lock_version
239
+ assert [0, "0"].include?(t1.custom_lock_version_before_type_cast)
240
+ end
241
+
242
+ def test_readonly_attributes
243
+ assert_equal Set.new([ 'name' ]), ReadonlyNameShip.readonly_attributes
244
+
245
+ s = ReadonlyNameShip.create(:name => "unchangeable name")
246
+ s.reload
247
+ assert_equal "unchangeable name", s.name
248
+
249
+ s.update(name: "changed name")
250
+ s.reload
251
+ assert_equal "unchangeable name", s.name
252
+ end
253
+
254
+ def test_quote_table_name
255
+ ref = references(:michael_magician)
256
+ ref.favourite = !ref.favourite
257
+ assert ref.save
258
+ end
259
+
260
+ # Useful for partial updates, don't only update the lock_version if there
261
+ # is nothing else being updated.
262
+ def test_update_without_attributes_does_not_only_update_lock_version
263
+ assert_nothing_raised do
264
+ p1 = Person.create!(:first_name => 'anika')
265
+ lock_version = p1.lock_version
266
+ p1.save
267
+ p1.reload
268
+ assert_equal lock_version, p1.lock_version
269
+ end
270
+ end
271
+
272
+ def test_polymorphic_destroy_with_dependencies_and_lock_version
273
+ car = Car.create!
274
+
275
+ assert_difference 'car.wheels.count' do
276
+ car.wheels << Wheel.create!
277
+ end
278
+ assert_difference 'car.wheels.count', -1 do
279
+ car.reload.destroy
280
+ end
281
+ assert car.destroyed?
282
+ end
283
+
284
+ def test_removing_has_and_belongs_to_many_associations_upon_destroy
285
+ p = RichPerson.create! first_name: 'Jon'
286
+ p.treasures.create!
287
+ assert !p.treasures.empty?
288
+ p.destroy
289
+ assert p.treasures.empty?
290
+ assert RichPerson.connection.select_all("SELECT * FROM peoples_treasures WHERE rich_person_id = 1").empty?
291
+ end
292
+
293
+ def test_yaml_dumping_with_lock_column
294
+ t1 = LockWithoutDefault.new
295
+ t2 = YAML.load(YAML.dump(t1))
296
+
297
+ assert_equal t1.attributes, t2.attributes
298
+ end
299
+ end
300
+
301
+ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
302
+ fixtures :people, :legacy_things, :references
303
+
304
+ # need to disable transactional tests, because otherwise the sqlite3
305
+ # adapter (at least) chokes when we try and change the schema in the middle
306
+ # of a test (see test_increment_counter_*).
307
+ self.use_transactional_tests = false
308
+
309
+ { :lock_version => Person, :custom_lock_version => LegacyThing }.each do |name, model|
310
+ define_method("test_increment_counter_updates_#{name}") do
311
+ counter_test model, 1 do |id|
312
+ model.increment_counter :test_count, id
313
+ end
314
+ end
315
+
316
+ define_method("test_decrement_counter_updates_#{name}") do
317
+ counter_test model, -1 do |id|
318
+ model.decrement_counter :test_count, id
319
+ end
320
+ end
321
+
322
+ define_method("test_update_counters_updates_#{name}") do
323
+ counter_test model, 1 do |id|
324
+ model.update_counters id, :test_count => 1
325
+ end
326
+ end
327
+ end
328
+
329
+ # See Lighthouse ticket #1966
330
+ def test_destroy_dependents
331
+ # Establish dependent relationship between Person and PersonalLegacyThing
332
+ add_counter_column_to(Person, 'personal_legacy_things_count')
333
+ PersonalLegacyThing.reset_column_information
334
+
335
+ # Make sure that counter incrementing doesn't cause problems
336
+ p1 = Person.new(:first_name => 'fjord')
337
+ p1.save!
338
+ t = PersonalLegacyThing.new(:person => p1)
339
+ t.save!
340
+ p1.reload
341
+ assert_equal 1, p1.personal_legacy_things_count
342
+ assert p1.destroy
343
+ assert_equal true, p1.frozen?
344
+ assert_raises(ActiveRecord::RecordNotFound) { Person.find(p1.id) }
345
+ assert_raises(ActiveRecord::RecordNotFound) { PersonalLegacyThing.find(t.id) }
346
+ ensure
347
+ remove_counter_column_from(Person, 'personal_legacy_things_count')
348
+ PersonalLegacyThing.reset_column_information
349
+ end
350
+
351
+ private
352
+
353
+ def add_counter_column_to(model, col='test_count')
354
+ model.connection.add_column model.table_name, col, :integer, :null => false, :default => 0
355
+ model.reset_column_information
356
+ end
357
+
358
+ def remove_counter_column_from(model, col = :test_count)
359
+ model.connection.remove_column model.table_name, col
360
+ model.reset_column_information
361
+ end
362
+
363
+ def counter_test(model, expected_count)
364
+ add_counter_column_to(model)
365
+ object = model.first
366
+ assert_equal 0, object.test_count
367
+ assert_equal 0, object.send(model.locking_column)
368
+ yield object.id
369
+ object.reload
370
+ assert_equal expected_count, object.test_count
371
+ assert_equal 1, object.send(model.locking_column)
372
+ ensure
373
+ remove_counter_column_from(model)
374
+ end
375
+ end
376
+
377
+
378
+ # TODO: test against the generated SQL since testing locking behavior itself
379
+ # is so cumbersome. Will deadlock Ruby threads if the underlying db.execute
380
+ # blocks, so separate script called by Kernel#system is needed.
381
+ # (See exec vs. async_exec in the PostgreSQL adapter.)
382
+ unless in_memory_db?
383
+ class PessimisticLockingTest < ActiveRecord::TestCase
384
+ self.use_transactional_tests = false
385
+ fixtures :people, :readers
386
+
387
+ def setup
388
+ Person.connection_pool.clear_reloadable_connections!
389
+ # Avoid introspection queries during tests.
390
+ Person.columns; Reader.columns
391
+ end
392
+
393
+ # Test typical find.
394
+ def test_sane_find_with_lock
395
+ assert_nothing_raised do
396
+ Person.transaction do
397
+ Person.lock.find(1)
398
+ end
399
+ end
400
+ end
401
+
402
+ # PostgreSQL protests SELECT ... FOR UPDATE on an outer join.
403
+ unless current_adapter?(:PostgreSQLAdapter)
404
+ # Test locked eager find.
405
+ def test_eager_find_with_lock
406
+ assert_nothing_raised do
407
+ Person.transaction do
408
+ Person.includes(:readers).lock.find(1)
409
+ end
410
+ end
411
+ end
412
+ end
413
+
414
+ # Locking a record reloads it.
415
+ def test_sane_lock_method
416
+ assert_nothing_raised do
417
+ Person.transaction do
418
+ person = Person.find 1
419
+ old, person.first_name = person.first_name, 'fooman'
420
+ person.lock!
421
+ assert_equal old, person.first_name
422
+ end
423
+ end
424
+ end
425
+
426
+ def test_with_lock_commits_transaction
427
+ person = Person.find 1
428
+ person.with_lock do
429
+ person.first_name = 'fooman'
430
+ person.save!
431
+ end
432
+ assert_equal 'fooman', person.reload.first_name
433
+ end
434
+
435
+ def test_with_lock_rolls_back_transaction
436
+ person = Person.find 1
437
+ old = person.first_name
438
+ person.with_lock do
439
+ person.first_name = 'fooman'
440
+ person.save!
441
+ raise 'oops'
442
+ end rescue nil
443
+ assert_equal old, person.reload.first_name
444
+ end
445
+
446
+ if current_adapter?(:PostgreSQLAdapter)
447
+ def test_lock_sending_custom_lock_statement
448
+ Person.transaction do
449
+ person = Person.find(1)
450
+ assert_sql(/LIMIT \$?\d FOR SHARE NOWAIT/) do
451
+ person.lock!('FOR SHARE NOWAIT')
452
+ end
453
+ end
454
+ end
455
+ end
456
+
457
+ if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
458
+ def test_no_locks_no_wait
459
+ first, second = duel { Person.find 1 }
460
+ assert first.end > second.end
461
+ end
462
+
463
+ protected
464
+ def duel(zzz = 5)
465
+ t0, t1, t2, t3 = nil, nil, nil, nil
466
+
467
+ a = Thread.new do
468
+ t0 = Time.now
469
+ Person.transaction do
470
+ yield
471
+ sleep zzz # block thread 2 for zzz seconds
472
+ end
473
+ t1 = Time.now
474
+ end
475
+
476
+ b = Thread.new do
477
+ sleep zzz / 2.0 # ensure thread 1 tx starts first
478
+ t2 = Time.now
479
+ Person.transaction { yield }
480
+ t3 = Time.now
481
+ end
482
+
483
+ a.join
484
+ b.join
485
+
486
+ assert t1 > t0 + zzz
487
+ assert t2 > t0
488
+ assert t3 > t2
489
+ [t0.to_f..t1.to_f, t2.to_f..t3.to_f]
490
+ end
491
+ end
492
+ end
493
+ end