ibm_db 3.0.4-x86-mingw32 → 3.0.5-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 (463) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +4 -1
  3. data/LICENSE +1 -1
  4. data/MANIFEST +14 -14
  5. data/README +225 -225
  6. data/ext/Makefile.nt32 +181 -181
  7. data/ext/Makefile.nt32.191 +212 -212
  8. data/ext/extconf.rb +291 -291
  9. data/ext/ibm_db.c +11887 -11884
  10. data/ext/ruby_ibm_db.h +241 -241
  11. data/ext/ruby_ibm_db_cli.c +866 -866
  12. data/ext/ruby_ibm_db_cli.h +500 -500
  13. data/init.rb +41 -41
  14. data/lib/IBM_DB.rb +27 -27
  15. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3177 -3177
  16. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +1 -1
  17. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  18. data/lib/mswin32/ibm_db.rb +122 -122
  19. data/lib/mswin32/rb21x/i386/ibm_db.so +0 -0
  20. data/lib/mswin32/rb22x/i386/ibm_db.so +0 -0
  21. data/lib/mswin32/rb23x/i386/ibm_db.so +0 -0
  22. data/test/active_record/connection_adapters/fake_adapter.rb +46 -46
  23. data/test/assets/example.log +1 -1
  24. data/test/assets/test.txt +1 -1
  25. data/test/cases/adapter_test.rb +276 -261
  26. data/test/cases/aggregations_test.rb +158 -158
  27. data/test/cases/ar_schema_test.rb +161 -161
  28. data/test/cases/associations/association_scope_test.rb +21 -21
  29. data/test/cases/associations/belongs_to_associations_test.rb +1029 -1029
  30. data/test/cases/associations/callbacks_test.rb +192 -192
  31. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  32. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +26 -26
  33. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  34. data/test/cases/associations/eager_load_nested_include_test.rb +128 -128
  35. data/test/cases/associations/eager_singularization_test.rb +148 -148
  36. data/test/cases/associations/eager_test.rb +1429 -1411
  37. data/test/cases/associations/extension_test.rb +82 -82
  38. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +972 -932
  39. data/test/cases/associations/has_many_associations_test.rb +2182 -2162
  40. data/test/cases/associations/has_many_through_associations_test.rb +1204 -1204
  41. data/test/cases/associations/has_one_associations_test.rb +610 -610
  42. data/test/cases/associations/has_one_through_associations_test.rb +380 -380
  43. data/test/cases/associations/inner_join_association_test.rb +139 -139
  44. data/test/cases/associations/inverse_associations_test.rb +706 -693
  45. data/test/cases/associations/join_model_test.rb +754 -754
  46. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  47. data/test/cases/associations/required_test.rb +82 -82
  48. data/test/cases/associations_test.rb +380 -380
  49. data/test/cases/attribute_decorators_test.rb +125 -125
  50. data/test/cases/attribute_methods/read_test.rb +60 -60
  51. data/test/cases/attribute_methods/serialization_test.rb +29 -29
  52. data/test/cases/attribute_methods_test.rb +952 -952
  53. data/test/cases/attribute_set_test.rb +210 -200
  54. data/test/cases/attribute_test.rb +180 -180
  55. data/test/cases/attributes_test.rb +136 -136
  56. data/test/cases/autosave_association_test.rb +1595 -1595
  57. data/test/cases/base_test.rb +1664 -1638
  58. data/test/cases/batches_test.rb +212 -212
  59. data/test/cases/binary_test.rb +52 -52
  60. data/test/cases/bind_parameter_test.rb +100 -100
  61. data/test/cases/calculations_test.rb +646 -646
  62. data/test/cases/callbacks_test.rb +543 -543
  63. data/test/cases/clone_test.rb +40 -40
  64. data/test/cases/coders/yaml_column_test.rb +63 -63
  65. data/test/cases/column_alias_test.rb +17 -17
  66. data/test/cases/column_definition_test.rb +123 -123
  67. data/test/cases/connection_adapters/adapter_leasing_test.rb +54 -54
  68. data/test/cases/connection_adapters/connection_handler_test.rb +53 -53
  69. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  70. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +293 -293
  71. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +65 -65
  72. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  73. data/test/cases/connection_adapters/schema_cache_test.rb +56 -56
  74. data/test/cases/connection_adapters/type_lookup_test.rb +110 -110
  75. data/test/cases/connection_management_test.rb +122 -122
  76. data/test/cases/connection_pool_test.rb +346 -346
  77. data/test/cases/connection_specification/resolver_test.rb +116 -116
  78. data/test/cases/core_test.rb +112 -112
  79. data/test/cases/counter_cache_test.rb +209 -209
  80. data/test/cases/custom_locking_test.rb +17 -17
  81. data/test/cases/database_statements_test.rb +19 -19
  82. data/test/cases/date_time_test.rb +61 -61
  83. data/test/cases/defaults_test.rb +223 -223
  84. data/test/cases/dirty_test.rb +785 -775
  85. data/test/cases/disconnected_test.rb +28 -28
  86. data/test/cases/dup_test.rb +157 -157
  87. data/test/cases/enum_test.rb +290 -290
  88. data/test/cases/explain_subscriber_test.rb +64 -64
  89. data/test/cases/explain_test.rb +76 -76
  90. data/test/cases/finder_respond_to_test.rb +60 -60
  91. data/test/cases/finder_test.rb +1169 -1166
  92. data/test/cases/fixture_set/file_test.rb +138 -138
  93. data/test/cases/fixtures_test.rb +908 -897
  94. data/test/cases/forbidden_attributes_protection_test.rb +99 -99
  95. data/test/cases/habtm_destroy_order_test.rb +61 -61
  96. data/test/cases/helper.rb +210 -210
  97. data/test/cases/hot_compatibility_test.rb +54 -54
  98. data/test/cases/i18n_test.rb +45 -45
  99. data/test/cases/inheritance_test.rb +375 -375
  100. data/test/cases/integration_test.rb +139 -139
  101. data/test/cases/invalid_connection_test.rb +22 -22
  102. data/test/cases/invalid_date_test.rb +32 -32
  103. data/test/cases/invertible_migration_test.rb +295 -295
  104. data/test/cases/json_serialization_test.rb +302 -302
  105. data/test/cases/locking_test.rb +477 -477
  106. data/test/cases/log_subscriber_test.rb +136 -136
  107. data/test/cases/migration/change_schema_test - Copy.rb +448 -448
  108. data/test/cases/migration/change_schema_test.rb +512 -472
  109. data/test/cases/migration/change_table_test.rb +224 -224
  110. data/test/cases/migration/column_attributes_test.rb +192 -192
  111. data/test/cases/migration/column_positioning_test.rb +56 -56
  112. data/test/cases/migration/columns_test.rb +304 -304
  113. data/test/cases/migration/command_recorder_test.rb +305 -305
  114. data/test/cases/migration/create_join_table_test.rb +148 -148
  115. data/test/cases/migration/foreign_key_test - Changed.rb +325 -325
  116. data/test/cases/migration/foreign_key_test.rb +328 -360
  117. data/test/cases/migration/helper.rb +39 -39
  118. data/test/cases/migration/index_test.rb +216 -216
  119. data/test/cases/migration/logger_test.rb +36 -36
  120. data/test/cases/migration/pending_migrations_test.rb +53 -53
  121. data/test/cases/migration/references_foreign_key_test.rb +169 -214
  122. data/test/cases/migration/references_index_test.rb +101 -101
  123. data/test/cases/migration/references_statements_test.rb +116 -116
  124. data/test/cases/migration/rename_table_test.rb +93 -93
  125. data/test/cases/migration/table_and_index_test.rb +24 -24
  126. data/test/cases/migration_test.rb +959 -959
  127. data/test/cases/migrator_test.rb +388 -388
  128. data/test/cases/mixin_test.rb +70 -70
  129. data/test/cases/modules_test.rb +173 -173
  130. data/test/cases/multiparameter_attributes_test.rb +350 -350
  131. data/test/cases/multiple_db_test.rb +115 -115
  132. data/test/cases/nested_attributes_test.rb +1070 -1057
  133. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  134. data/test/cases/persistence_test.rb +909 -909
  135. data/test/cases/pooled_connections_test.rb +81 -81
  136. data/test/cases/primary_keys_test.rb +237 -237
  137. data/test/cases/query_cache_test.rb +326 -326
  138. data/test/cases/quoting_test.rb +156 -156
  139. data/test/cases/readonly_test.rb +118 -118
  140. data/test/cases/reaper_test.rb +85 -85
  141. data/test/cases/reflection_test.rb +463 -454
  142. data/test/cases/relation/delegation_test.rb +68 -68
  143. data/test/cases/relation/merging_test.rb +161 -161
  144. data/test/cases/relation/mutation_test.rb +165 -165
  145. data/test/cases/relation/predicate_builder_test.rb +14 -14
  146. data/test/cases/relation/where_chain_test.rb +181 -181
  147. data/test/cases/relation/where_test.rb +300 -300
  148. data/test/cases/relation/where_test2.rb +36 -36
  149. data/test/cases/relation_test.rb +319 -297
  150. data/test/cases/relations_test.rb +1815 -1815
  151. data/test/cases/reload_models_test.rb +22 -22
  152. data/test/cases/result_test.rb +80 -80
  153. data/test/cases/sanitize_test.rb +83 -83
  154. data/test/cases/schema_dumper_test.rb +463 -463
  155. data/test/cases/scoping/default_scoping_test.rb +454 -454
  156. data/test/cases/scoping/named_scoping_test.rb +524 -524
  157. data/test/cases/scoping/relation_scoping_test.rb +357 -357
  158. data/test/cases/serialization_test.rb +104 -104
  159. data/test/cases/serialized_attribute_test.rb +277 -277
  160. data/test/cases/statement_cache_test.rb +98 -98
  161. data/test/cases/store_test.rb +194 -194
  162. data/test/cases/tasks/database_tasks_test.rb +398 -396
  163. data/test/cases/tasks/mysql_rake_test.rb +324 -311
  164. data/test/cases/tasks/postgresql_rake_test.rb +250 -245
  165. data/test/cases/tasks/sqlite_rake_test.rb +193 -193
  166. data/test/cases/test_case.rb +123 -123
  167. data/test/cases/timestamp_test.rb +467 -468
  168. data/test/cases/transaction_callbacks_test.rb +452 -452
  169. data/test/cases/transaction_isolation_test.rb +106 -106
  170. data/test/cases/transactions_test.rb +817 -817
  171. data/test/cases/type/decimal_test.rb +56 -51
  172. data/test/cases/type/integer_test.rb +121 -121
  173. data/test/cases/type/string_test.rb +36 -36
  174. data/test/cases/type/type_map_test.rb +177 -177
  175. data/test/cases/type/unsigned_integer_test.rb +18 -18
  176. data/test/cases/types_test.rb +141 -141
  177. data/test/cases/unconnected_test.rb +33 -33
  178. data/test/cases/validations/association_validation_test.rb +86 -86
  179. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  180. data/test/cases/validations/i18n_validation_test.rb +90 -90
  181. data/test/cases/validations/length_validation_test.rb +47 -47
  182. data/test/cases/validations/presence_validation_test.rb +68 -68
  183. data/test/cases/validations/uniqueness_validation_test.rb +457 -434
  184. data/test/cases/validations_repair_helper.rb +23 -23
  185. data/test/cases/validations_test.rb +165 -165
  186. data/test/cases/view_test.rb +119 -113
  187. data/test/cases/xml_serialization_test.rb +457 -457
  188. data/test/cases/yaml_serialization_test.rb +126 -86
  189. data/test/config.rb +5 -5
  190. data/test/config.yml +154 -154
  191. data/test/connections/native_ibm_db/connection.rb +43 -43
  192. data/test/fixtures/accounts.yml +29 -29
  193. data/test/fixtures/admin/accounts.yml +2 -2
  194. data/test/fixtures/admin/randomly_named_a9.yml +7 -7
  195. data/test/fixtures/admin/randomly_named_b0.yml +7 -7
  196. data/test/fixtures/admin/users.yml +10 -10
  197. data/test/fixtures/author_addresses.yml +17 -17
  198. data/test/fixtures/author_favorites.yml +3 -3
  199. data/test/fixtures/authors.yml +23 -23
  200. data/test/fixtures/binaries.yml +133 -133
  201. data/test/fixtures/books.yml +11 -11
  202. data/test/fixtures/bulbs.yml +5 -5
  203. data/test/fixtures/cars.yml +9 -9
  204. data/test/fixtures/categories.yml +19 -19
  205. data/test/fixtures/categories/special_categories.yml +9 -9
  206. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  207. data/test/fixtures/categories_ordered.yml +7 -7
  208. data/test/fixtures/categories_posts.yml +31 -31
  209. data/test/fixtures/categorizations.yml +23 -23
  210. data/test/fixtures/clubs.yml +8 -8
  211. data/test/fixtures/collections.yml +3 -3
  212. data/test/fixtures/colleges.yml +3 -3
  213. data/test/fixtures/comments.yml +65 -65
  214. data/test/fixtures/companies.yml +67 -67
  215. data/test/fixtures/computers.yml +10 -10
  216. data/test/fixtures/courses.yml +8 -8
  217. data/test/fixtures/customers.yml +25 -25
  218. data/test/fixtures/dashboards.yml +6 -6
  219. data/test/fixtures/developers.yml +21 -21
  220. data/test/fixtures/developers_projects.yml +16 -16
  221. data/test/fixtures/dog_lovers.yml +7 -7
  222. data/test/fixtures/dogs.yml +4 -4
  223. data/test/fixtures/doubloons.yml +3 -3
  224. data/test/fixtures/edges.yml +5 -5
  225. data/test/fixtures/entrants.yml +14 -14
  226. data/test/fixtures/essays.yml +6 -6
  227. data/test/fixtures/faces.yml +11 -11
  228. data/test/fixtures/fk_test_has_fk.yml +3 -3
  229. data/test/fixtures/fk_test_has_pk.yml +1 -1
  230. data/test/fixtures/friendships.yml +4 -4
  231. data/test/fixtures/funny_jokes.yml +10 -10
  232. data/test/fixtures/interests.yml +33 -33
  233. data/test/fixtures/items.yml +3 -3
  234. data/test/fixtures/jobs.yml +7 -7
  235. data/test/fixtures/legacy_things.yml +3 -3
  236. data/test/fixtures/mateys.yml +4 -4
  237. data/test/fixtures/member_details.yml +8 -8
  238. data/test/fixtures/member_types.yml +6 -6
  239. data/test/fixtures/members.yml +11 -11
  240. data/test/fixtures/memberships.yml +34 -34
  241. data/test/fixtures/men.yml +5 -5
  242. data/test/fixtures/minimalistics.yml +2 -2
  243. data/test/fixtures/minivans.yml +5 -5
  244. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  245. data/test/fixtures/mixins.yml +29 -29
  246. data/test/fixtures/movies.yml +7 -7
  247. data/test/fixtures/naked/csv/accounts.csv +1 -1
  248. data/test/fixtures/naked/yml/accounts.yml +1 -1
  249. data/test/fixtures/naked/yml/companies.yml +1 -1
  250. data/test/fixtures/naked/yml/courses.yml +1 -1
  251. data/test/fixtures/organizations.yml +5 -5
  252. data/test/fixtures/other_topics.yml +42 -42
  253. data/test/fixtures/owners.yml +9 -9
  254. data/test/fixtures/parrots.yml +27 -27
  255. data/test/fixtures/parrots_pirates.yml +7 -7
  256. data/test/fixtures/people.yml +24 -24
  257. data/test/fixtures/peoples_treasures.yml +3 -3
  258. data/test/fixtures/pets.yml +19 -19
  259. data/test/fixtures/pirates.yml +12 -12
  260. data/test/fixtures/posts.yml +80 -80
  261. data/test/fixtures/price_estimates.yml +7 -7
  262. data/test/fixtures/products.yml +4 -4
  263. data/test/fixtures/projects.yml +7 -7
  264. data/test/fixtures/randomly_named_a9.yml +7 -7
  265. data/test/fixtures/ratings.yml +14 -14
  266. data/test/fixtures/readers.yml +11 -11
  267. data/test/fixtures/references.yml +17 -17
  268. data/test/fixtures/reserved_words/distinct.yml +5 -5
  269. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  270. data/test/fixtures/reserved_words/group.yml +14 -14
  271. data/test/fixtures/reserved_words/select.yml +8 -8
  272. data/test/fixtures/reserved_words/values.yml +7 -7
  273. data/test/fixtures/ships.yml +6 -6
  274. data/test/fixtures/speedometers.yml +8 -8
  275. data/test/fixtures/sponsors.yml +12 -12
  276. data/test/fixtures/string_key_objects.yml +7 -7
  277. data/test/fixtures/subscribers.yml +10 -10
  278. data/test/fixtures/subscriptions.yml +12 -12
  279. data/test/fixtures/taggings.yml +78 -78
  280. data/test/fixtures/tags.yml +11 -11
  281. data/test/fixtures/tasks.yml +7 -7
  282. data/test/fixtures/teapots.yml +3 -3
  283. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  284. data/test/fixtures/to_be_linked/users.yml +10 -10
  285. data/test/fixtures/topics.yml +49 -49
  286. data/test/fixtures/toys.yml +14 -14
  287. data/test/fixtures/traffic_lights.yml +9 -9
  288. data/test/fixtures/treasures.yml +10 -10
  289. data/test/fixtures/uuid_children.yml +3 -3
  290. data/test/fixtures/uuid_parents.yml +2 -2
  291. data/test/fixtures/variants.yml +4 -4
  292. data/test/fixtures/vegetables.yml +19 -19
  293. data/test/fixtures/vertices.yml +3 -3
  294. data/test/fixtures/warehouse_things.yml +2 -2
  295. data/test/fixtures/zines.yml +5 -5
  296. data/test/ibm_db_test.rb +24 -24
  297. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  298. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  299. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  300. data/test/migrations/missing/1000_people_have_middle_names.rb +8 -8
  301. data/test/migrations/missing/1_people_have_last_names.rb +8 -8
  302. data/test/migrations/missing/3_we_need_reminders.rb +11 -11
  303. data/test/migrations/missing/4_innocent_jointable.rb +11 -11
  304. data/test/migrations/rename/1_we_need_things.rb +10 -10
  305. data/test/migrations/rename/2_rename_things.rb +8 -8
  306. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  307. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  308. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  309. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  310. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  311. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  312. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  313. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  314. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  315. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  316. data/test/migrations/valid/2_we_need_reminders.rb +11 -11
  317. data/test/migrations/valid/3_innocent_jointable.rb +11 -11
  318. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  319. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +11 -11
  320. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +11 -11
  321. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  322. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  323. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  324. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  325. data/test/models/admin.rb +4 -4
  326. data/test/models/admin/account.rb +2 -2
  327. data/test/models/admin/randomly_named_c1.rb +3 -3
  328. data/test/models/admin/user.rb +40 -40
  329. data/test/models/aircraft.rb +4 -4
  330. data/test/models/arunit2_model.rb +3 -3
  331. data/test/models/author.rb +212 -212
  332. data/test/models/auto_id.rb +4 -4
  333. data/test/models/autoloadable/extra_firm.rb +2 -2
  334. data/test/models/binary.rb +1 -1
  335. data/test/models/bird.rb +12 -12
  336. data/test/models/book.rb +18 -18
  337. data/test/models/boolean.rb +2 -2
  338. data/test/models/bulb.rb +51 -51
  339. data/test/models/cake_designer.rb +3 -3
  340. data/test/models/car.rb +26 -26
  341. data/test/models/carrier.rb +2 -2
  342. data/test/models/categorization.rb +19 -19
  343. data/test/models/category.rb +35 -35
  344. data/test/models/chef.rb +7 -3
  345. data/test/models/citation.rb +3 -3
  346. data/test/models/club.rb +23 -23
  347. data/test/models/college.rb +10 -10
  348. data/test/models/column.rb +3 -3
  349. data/test/models/column_name.rb +3 -3
  350. data/test/models/comment.rb +64 -64
  351. data/test/models/company.rb +228 -225
  352. data/test/models/company_in_module.rb +98 -98
  353. data/test/models/computer.rb +3 -3
  354. data/test/models/contact.rb +41 -41
  355. data/test/models/contract.rb +20 -20
  356. data/test/models/country.rb +7 -7
  357. data/test/models/course.rb +6 -6
  358. data/test/models/customer.rb +77 -77
  359. data/test/models/customer_carrier.rb +14 -14
  360. data/test/models/dashboard.rb +3 -3
  361. data/test/models/default.rb +2 -2
  362. data/test/models/department.rb +4 -4
  363. data/test/models/developer.rb +255 -252
  364. data/test/models/dog.rb +5 -5
  365. data/test/models/dog_lover.rb +5 -5
  366. data/test/models/doubloon.rb +12 -12
  367. data/test/models/drink_designer.rb +3 -3
  368. data/test/models/edge.rb +5 -5
  369. data/test/models/electron.rb +5 -5
  370. data/test/models/engine.rb +4 -4
  371. data/test/models/entrant.rb +3 -3
  372. data/test/models/essay.rb +5 -5
  373. data/test/models/event.rb +2 -2
  374. data/test/models/eye.rb +37 -37
  375. data/test/models/face.rb +9 -9
  376. data/test/models/friendship.rb +6 -6
  377. data/test/models/guid.rb +1 -1
  378. data/test/models/hotel.rb +9 -6
  379. data/test/models/image.rb +3 -3
  380. data/test/models/interest.rb +5 -5
  381. data/test/models/invoice.rb +4 -4
  382. data/test/models/item.rb +7 -7
  383. data/test/models/job.rb +7 -7
  384. data/test/models/joke.rb +7 -7
  385. data/test/models/keyboard.rb +3 -3
  386. data/test/models/legacy_thing.rb +3 -3
  387. data/test/models/lesson.rb +11 -11
  388. data/test/models/line_item.rb +3 -3
  389. data/test/models/liquid.rb +4 -4
  390. data/test/models/man.rb +11 -11
  391. data/test/models/matey.rb +4 -4
  392. data/test/models/member.rb +41 -41
  393. data/test/models/member_detail.rb +7 -7
  394. data/test/models/member_type.rb +3 -3
  395. data/test/models/membership.rb +35 -35
  396. data/test/models/minimalistic.rb +2 -2
  397. data/test/models/minivan.rb +9 -9
  398. data/test/models/mixed_case_monkey.rb +3 -3
  399. data/test/models/molecule.rb +6 -6
  400. data/test/models/movie.rb +5 -5
  401. data/test/models/order.rb +4 -4
  402. data/test/models/organization.rb +14 -14
  403. data/test/models/owner.rb +34 -34
  404. data/test/models/parrot.rb +29 -29
  405. data/test/models/person.rb +143 -143
  406. data/test/models/personal_legacy_thing.rb +4 -4
  407. data/test/models/pet.rb +15 -15
  408. data/test/models/pirate.rb +92 -92
  409. data/test/models/possession.rb +3 -3
  410. data/test/models/post.rb +264 -264
  411. data/test/models/price_estimate.rb +4 -4
  412. data/test/models/professor.rb +5 -5
  413. data/test/models/project.rb +31 -29
  414. data/test/models/publisher.rb +2 -2
  415. data/test/models/publisher/article.rb +4 -4
  416. data/test/models/publisher/magazine.rb +3 -3
  417. data/test/models/randomly_named_c1.rb +3 -3
  418. data/test/models/rating.rb +4 -4
  419. data/test/models/reader.rb +23 -23
  420. data/test/models/record.rb +2 -2
  421. data/test/models/reference.rb +22 -22
  422. data/test/models/reply.rb +61 -61
  423. data/test/models/ship.rb +33 -33
  424. data/test/models/ship_part.rb +7 -7
  425. data/test/models/shop.rb +17 -17
  426. data/test/models/shop_account.rb +6 -6
  427. data/test/models/speedometer.rb +6 -6
  428. data/test/models/sponsor.rb +7 -7
  429. data/test/models/string_key_object.rb +3 -3
  430. data/test/models/student.rb +4 -4
  431. data/test/models/subject.rb +16 -16
  432. data/test/models/subscriber.rb +8 -8
  433. data/test/models/subscription.rb +4 -4
  434. data/test/models/tag.rb +7 -7
  435. data/test/models/tagging.rb +13 -13
  436. data/test/models/task.rb +5 -5
  437. data/test/models/topic.rb +124 -124
  438. data/test/models/toy.rb +6 -6
  439. data/test/models/traffic_light.rb +4 -4
  440. data/test/models/treasure.rb +14 -14
  441. data/test/models/treaty.rb +7 -7
  442. data/test/models/tyre.rb +11 -11
  443. data/test/models/uuid_child.rb +3 -3
  444. data/test/models/uuid_parent.rb +3 -3
  445. data/test/models/vegetables.rb +24 -24
  446. data/test/models/vehicle.rb +6 -6
  447. data/test/models/vertex.rb +9 -9
  448. data/test/models/warehouse_thing.rb +5 -5
  449. data/test/models/wheel.rb +3 -3
  450. data/test/models/without_table.rb +3 -3
  451. data/test/models/zine.rb +3 -3
  452. data/test/schema/mysql2_specific_schema.rb +58 -58
  453. data/test/schema/mysql_specific_schema.rb +70 -70
  454. data/test/schema/oracle_specific_schema.rb +43 -43
  455. data/test/schema/postgresql_specific_schema.rb +202 -202
  456. data/test/schema/schema.rb +952 -938
  457. data/test/schema/sqlite_specific_schema.rb +21 -21
  458. data/test/support/config.rb +43 -43
  459. data/test/support/connection.rb +22 -22
  460. data/test/support/connection_helper.rb +14 -14
  461. data/test/support/ddl_helper.rb +8 -8
  462. data/test/support/schema_dumping_helper.rb +20 -20
  463. metadata +2 -2
@@ -1,100 +1,100 @@
1
- require 'cases/helper'
2
- require 'models/topic'
3
- require 'models/author'
4
- require 'models/post'
5
-
6
- module ActiveRecord
7
- class BindParameterTest < ActiveRecord::TestCase
8
- fixtures :topics, :authors, :posts
9
-
10
- class LogListener
11
- attr_accessor :calls
12
-
13
- def initialize
14
- @calls = []
15
- end
16
-
17
- def call(*args)
18
- calls << args
19
- end
20
- end
21
-
22
- def setup
23
- super
24
- @connection = ActiveRecord::Base.connection
25
- @subscriber = LogListener.new
26
- @pk = Topic.columns_hash[Topic.primary_key]
27
- @subscription = ActiveSupport::Notifications.subscribe('sql.active_record', @subscriber)
28
- end
29
-
30
- teardown do
31
- ActiveSupport::Notifications.unsubscribe(@subscription)
32
- end
33
-
34
- if ActiveRecord::Base.connection.supports_statement_cache?
35
- def test_bind_from_join_in_subquery
36
- subquery = Author.joins(:thinking_posts).where(name: 'David')
37
- scope = Author.from(subquery, 'authors').where(id: 1)
38
- assert_equal 1, scope.count
39
- end
40
-
41
- def test_binds_are_logged
42
- sub = @connection.substitute_at(@pk)
43
- binds = [[@pk, 1]]
44
- sql = "select * from topics where id = #{sub.to_sql}"
45
-
46
- @connection.exec_query(sql, 'SQL', binds)
47
-
48
- message = @subscriber.calls.find { |args| args[4][:sql] == sql }
49
- assert_equal binds, message[4][:binds]
50
- end
51
-
52
- def test_binds_are_logged_after_type_cast
53
- sub = @connection.substitute_at(@pk)
54
- binds = [[@pk, "3"]]
55
- sql = "select * from topics where id = #{sub.to_sql}"
56
-
57
- @connection.exec_query(sql, 'SQL', binds)
58
-
59
- message = @subscriber.calls.find { |args| args[4][:sql] == sql }
60
- assert_equal [[@pk, 3]], message[4][:binds]
61
- end
62
-
63
- def test_find_one_uses_binds
64
- Topic.find(1)
65
- binds = [[@pk, 1]]
66
- message = @subscriber.calls.find { |args| args[4][:binds] == binds }
67
- assert message, 'expected a message with binds'
68
- end
69
-
70
- def test_logs_bind_vars
71
- payload = {
72
- :name => 'SQL',
73
- :sql => 'select * from topics where id = ?',
74
- :binds => [[@pk, 10]]
75
- }
76
- event = ActiveSupport::Notifications::Event.new(
77
- 'foo',
78
- Time.now,
79
- Time.now,
80
- 123,
81
- payload)
82
-
83
- logger = Class.new(ActiveRecord::LogSubscriber) {
84
- attr_reader :debugs
85
- def initialize
86
- super
87
- @debugs = []
88
- end
89
-
90
- def debug str
91
- @debugs << str
92
- end
93
- }.new
94
-
95
- logger.sql event
96
- assert_match([[@pk.name, 10]].inspect, logger.debugs.first)
97
- end
98
- end
99
- end
100
- end
1
+ require 'cases/helper'
2
+ require 'models/topic'
3
+ require 'models/author'
4
+ require 'models/post'
5
+
6
+ module ActiveRecord
7
+ class BindParameterTest < ActiveRecord::TestCase
8
+ fixtures :topics, :authors, :posts
9
+
10
+ class LogListener
11
+ attr_accessor :calls
12
+
13
+ def initialize
14
+ @calls = []
15
+ end
16
+
17
+ def call(*args)
18
+ calls << args
19
+ end
20
+ end
21
+
22
+ def setup
23
+ super
24
+ @connection = ActiveRecord::Base.connection
25
+ @subscriber = LogListener.new
26
+ @pk = Topic.columns_hash[Topic.primary_key]
27
+ @subscription = ActiveSupport::Notifications.subscribe('sql.active_record', @subscriber)
28
+ end
29
+
30
+ teardown do
31
+ ActiveSupport::Notifications.unsubscribe(@subscription)
32
+ end
33
+
34
+ if ActiveRecord::Base.connection.supports_statement_cache?
35
+ def test_bind_from_join_in_subquery
36
+ subquery = Author.joins(:thinking_posts).where(name: 'David')
37
+ scope = Author.from(subquery, 'authors').where(id: 1)
38
+ assert_equal 1, scope.count
39
+ end
40
+
41
+ def test_binds_are_logged
42
+ sub = @connection.substitute_at(@pk)
43
+ binds = [[@pk, 1]]
44
+ sql = "select * from topics where id = #{sub.to_sql}"
45
+
46
+ @connection.exec_query(sql, 'SQL', binds)
47
+
48
+ message = @subscriber.calls.find { |args| args[4][:sql] == sql }
49
+ assert_equal binds, message[4][:binds]
50
+ end
51
+
52
+ def test_binds_are_logged_after_type_cast
53
+ sub = @connection.substitute_at(@pk)
54
+ binds = [[@pk, "3"]]
55
+ sql = "select * from topics where id = #{sub.to_sql}"
56
+
57
+ @connection.exec_query(sql, 'SQL', binds)
58
+
59
+ message = @subscriber.calls.find { |args| args[4][:sql] == sql }
60
+ assert_equal [[@pk, 3]], message[4][:binds]
61
+ end
62
+
63
+ def test_find_one_uses_binds
64
+ Topic.find(1)
65
+ binds = [[@pk, 1]]
66
+ message = @subscriber.calls.find { |args| args[4][:binds] == binds }
67
+ assert message, 'expected a message with binds'
68
+ end
69
+
70
+ def test_logs_bind_vars
71
+ payload = {
72
+ :name => 'SQL',
73
+ :sql => 'select * from topics where id = ?',
74
+ :binds => [[@pk, 10]]
75
+ }
76
+ event = ActiveSupport::Notifications::Event.new(
77
+ 'foo',
78
+ Time.now,
79
+ Time.now,
80
+ 123,
81
+ payload)
82
+
83
+ logger = Class.new(ActiveRecord::LogSubscriber) {
84
+ attr_reader :debugs
85
+ def initialize
86
+ super
87
+ @debugs = []
88
+ end
89
+
90
+ def debug str
91
+ @debugs << str
92
+ end
93
+ }.new
94
+
95
+ logger.sql event
96
+ assert_match([[@pk.name, 10]].inspect, logger.debugs.first)
97
+ end
98
+ end
99
+ end
100
+ end
@@ -1,646 +1,646 @@
1
- require "cases/helper"
2
- require 'models/club'
3
- require 'models/company'
4
- require "models/contract"
5
- require 'models/edge'
6
- require 'models/organization'
7
- require 'models/possession'
8
- require 'models/topic'
9
- require 'models/reply'
10
- require 'models/minivan'
11
- require 'models/speedometer'
12
- require 'models/ship_part'
13
- require 'models/treasure'
14
- require 'models/developer'
15
- require 'models/comment'
16
- require 'models/rating'
17
- require 'models/post'
18
-
19
- class NumericData < ActiveRecord::Base
20
- self.table_name = 'numeric_data'
21
-
22
- attribute :world_population, Type::Integer.new
23
- attribute :my_house_population, Type::Integer.new
24
- attribute :atoms_in_universe, Type::Integer.new
25
- end
26
-
27
- class CalculationsTest < ActiveRecord::TestCase
28
- fixtures :companies, :accounts, :topics, :speedometers, :minivans
29
-
30
- def test_should_sum_field
31
- assert_equal 318, Account.sum(:credit_limit)
32
- end
33
-
34
- def test_should_average_field
35
- value = Account.average(:credit_limit)
36
- assert_equal 53.0, value
37
- end
38
-
39
- def test_should_resolve_aliased_attributes
40
- assert_equal 318, Account.sum(:available_credit)
41
- end
42
-
43
- def test_should_return_decimal_average_of_integer_field
44
- return if current_adapter?(:IBM_DBAdapter) #average cannot be a decimal value when applied on integer field
45
- value = Account.average(:id)
46
- assert_equal 3.5, value
47
- end
48
-
49
- def test_should_return_integer_average_if_db_returns_such
50
- ShipPart.delete_all
51
- ShipPart.create!(:id => 3, :name => 'foo')
52
- value = ShipPart.average(:id)
53
- assert_equal 3, value
54
- end
55
-
56
- def test_should_return_nil_as_average
57
- assert_nil NumericData.average(:bank_balance)
58
- end
59
-
60
- def test_should_get_maximum_of_field
61
- assert_equal 60, Account.maximum(:credit_limit)
62
- end
63
-
64
- def test_should_get_maximum_of_field_with_include
65
- assert_equal 55, Account.where("companies.name != 'Summit'").references(:companies).includes(:firm).maximum(:credit_limit)
66
- end
67
-
68
- def test_should_get_minimum_of_field
69
- assert_equal 50, Account.minimum(:credit_limit)
70
- end
71
-
72
- def test_should_group_by_field
73
- c = Account.group(:firm_id).sum(:credit_limit)
74
- [1,6,2].each do |firm_id|
75
- assert c.keys.include?(firm_id), "Group #{c.inspect} does not contain firm_id #{firm_id}"
76
- end
77
- end
78
-
79
- def test_should_group_by_arel_attribute
80
- c = Account.group(Account.arel_table[:firm_id]).sum(:credit_limit)
81
- [1,6,2].each do |firm_id|
82
- assert c.keys.include?(firm_id), "Group #{c.inspect} does not contain firm_id #{firm_id}"
83
- end
84
- end
85
-
86
- def test_should_group_by_multiple_fields
87
- c = Account.group('firm_id', :credit_limit).count(:all)
88
- [ [nil, 50], [1, 50], [6, 50], [6, 55], [9, 53], [2, 60] ].each { |firm_and_limit| assert c.keys.include?(firm_and_limit) }
89
- end
90
-
91
- def test_should_group_by_multiple_fields_having_functions
92
- c = Topic.group(:author_name, 'COALESCE(type, title)').count(:all)
93
- assert_equal 1, c[["Carl", "The Third Topic of the day"]]
94
- assert_equal 1, c[["Mary", "Reply"]]
95
- assert_equal 1, c[["David", "The First Topic"]]
96
- assert_equal 1, c[["Carl", "Reply"]]
97
- end
98
-
99
- def test_should_group_by_summed_field
100
- c = Account.group(:firm_id).sum(:credit_limit)
101
- assert_equal 50, c[1]
102
- assert_equal 105, c[6]
103
- assert_equal 60, c[2]
104
- end
105
-
106
- def test_should_order_by_grouped_field
107
- c = Account.group(:firm_id).order("firm_id").sum(:credit_limit)
108
- assert_equal [1, 2, 6, 9], c.keys.compact
109
- end
110
-
111
- def test_should_order_by_calculation
112
- c = Account.group(:firm_id).order("sum_credit_limit desc, firm_id").sum(:credit_limit)
113
- assert_equal [105, 60, 53, 50, 50], c.keys.collect { |k| c[k] }
114
- assert_equal [6, 2, 9, 1], c.keys.compact
115
- end
116
-
117
- def test_should_limit_calculation
118
- c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id").limit(2).sum(:credit_limit)
119
- assert_equal [1, 2], c.keys.compact
120
- end
121
-
122
- def test_should_limit_calculation_with_offset
123
- c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id").
124
- limit(2).offset(1).sum(:credit_limit)
125
- assert_equal [2, 6], c.keys.compact
126
- end
127
-
128
- def test_limit_should_apply_before_count
129
- accounts = Account.limit(3).where('firm_id IS NOT NULL')
130
-
131
- assert_equal 3, accounts.count(:firm_id)
132
- assert_equal 3, accounts.select(:firm_id).count
133
- end
134
-
135
- def test_count_should_shortcut_with_limit_zero
136
- accounts = Account.limit(0)
137
-
138
- assert_no_queries { assert_equal 0, accounts.count }
139
- end
140
-
141
- def test_limit_is_kept
142
- return if current_adapter?(:OracleAdapter) || current_adapter?(:IBM_DBAdapter)
143
-
144
- queries = assert_sql { Account.limit(1).count }
145
- assert_equal 1, queries.length
146
- assert_match(/LIMIT/, queries.first)
147
- end
148
-
149
- def test_offset_is_kept
150
- return if current_adapter?(:OracleAdapter) || current_adapter?(:IBM_DBAdapter)
151
-
152
- queries = assert_sql { Account.offset(1).count }
153
- assert_equal 1, queries.length
154
- assert_match(/OFFSET/, queries.first)
155
- end
156
-
157
- def test_limit_with_offset_is_kept
158
- return if current_adapter?(:OracleAdapter) || current_adapter?(:IBM_DBAdapter)
159
-
160
- queries = assert_sql { Account.limit(1).offset(1).count }
161
- assert_equal 1, queries.length
162
- assert_match(/LIMIT/, queries.first)
163
- assert_match(/OFFSET/, queries.first)
164
- end
165
-
166
- def test_no_limit_no_offset
167
- queries = assert_sql { Account.count }
168
- assert_equal 1, queries.length
169
- assert_no_match(/LIMIT/, queries.first)
170
- assert_no_match(/OFFSET/, queries.first)
171
- end
172
-
173
- def test_count_on_invalid_columns_raises
174
- e = assert_raises(ActiveRecord::StatementInvalid) {
175
- Account.select("credit_limit, firm_name").count
176
- }
177
-
178
- assert_match %r{accounts}i, e.message
179
- assert_match "credit_limit, firm_name", e.message
180
- end
181
-
182
- def test_should_group_by_summed_field_having_condition
183
- c = Account.group(:firm_id).having('sum(credit_limit) > 50').sum(:credit_limit)
184
- assert_nil c[1]
185
- assert_equal 105, c[6]
186
- assert_equal 60, c[2]
187
- end
188
-
189
- def test_should_group_by_summed_field_having_condition_from_select
190
- c = Account.select("MIN(credit_limit) AS min_credit_limit").group(:firm_id).having("MIN(credit_limit) > 50").sum(:credit_limit)
191
- assert_nil c[1]
192
- assert_equal 60, c[2]
193
- assert_equal 53, c[9]
194
- end
195
-
196
- def test_should_group_by_summed_association
197
- c = Account.group(:firm).sum(:credit_limit)
198
- assert_equal 50, c[companies(:first_firm)]
199
- assert_equal 105, c[companies(:rails_core)]
200
- assert_equal 60, c[companies(:first_client)]
201
- end
202
-
203
- def test_should_sum_field_with_conditions
204
- assert_equal 105, Account.where('firm_id = 6').sum(:credit_limit)
205
- end
206
-
207
- def test_should_return_zero_if_sum_conditions_return_nothing
208
- assert_equal 0, Account.where('1 = 2').sum(:credit_limit)
209
- assert_equal 0, companies(:rails_core).companies.where('1 = 2').sum(:id)
210
- end
211
-
212
- def test_sum_should_return_valid_values_for_decimals
213
- NumericData.create(:bank_balance => 19.83)
214
- assert_equal 19.83, NumericData.sum(:bank_balance)
215
- end
216
-
217
- def test_should_return_type_casted_values_with_group_and_expression
218
- assert_equal 0.5, Account.group(:firm_name).sum('0.01 * credit_limit')['37signals']
219
- end
220
-
221
- def test_should_group_by_summed_field_with_conditions
222
- c = Account.where('firm_id > 1').group(:firm_id).sum(:credit_limit)
223
- assert_nil c[1]
224
- assert_equal 105, c[6]
225
- assert_equal 60, c[2]
226
- end
227
-
228
- def test_should_group_by_summed_field_with_conditions_and_having
229
- c = Account.where('firm_id > 1').group(:firm_id).
230
- having('sum(credit_limit) > 60').sum(:credit_limit)
231
- assert_nil c[1]
232
- assert_equal 105, c[6]
233
- assert_nil c[2]
234
- end
235
-
236
- def test_should_group_by_fields_with_table_alias
237
- c = Account.group('accounts.firm_id').sum(:credit_limit)
238
- assert_equal 50, c[1]
239
- assert_equal 105, c[6]
240
- assert_equal 60, c[2]
241
- end
242
-
243
- def test_should_calculate_with_invalid_field
244
- assert_equal 6, Account.calculate(:count, '*')
245
- assert_equal 6, Account.calculate(:count, :all)
246
- end
247
-
248
- def test_should_calculate_grouped_with_invalid_field
249
- c = Account.group('accounts.firm_id').count(:all)
250
- assert_equal 1, c[1]
251
- assert_equal 2, c[6]
252
- assert_equal 1, c[2]
253
- end
254
-
255
- def test_should_calculate_grouped_association_with_invalid_field
256
- c = Account.group(:firm).count(:all)
257
- assert_equal 1, c[companies(:first_firm)]
258
- assert_equal 2, c[companies(:rails_core)]
259
- assert_equal 1, c[companies(:first_client)]
260
- end
261
-
262
- def test_should_group_by_association_with_non_numeric_foreign_key
263
- Speedometer.create! id: 'ABC'
264
- Minivan.create! id: 'OMG', speedometer_id: 'ABC'
265
-
266
- c = Minivan.group(:speedometer).count(:all)
267
- first_key = c.keys.first
268
- assert_equal Speedometer, first_key.class
269
- assert_equal 1, c[first_key]
270
- end
271
-
272
- def test_should_calculate_grouped_association_with_foreign_key_option
273
- Account.belongs_to :another_firm, :class_name => 'Firm', :foreign_key => 'firm_id'
274
- c = Account.group(:another_firm).count(:all)
275
- assert_equal 1, c[companies(:first_firm)]
276
- assert_equal 2, c[companies(:rails_core)]
277
- assert_equal 1, c[companies(:first_client)]
278
- end
279
-
280
- def test_should_calculate_grouped_by_function
281
- c = Company.group("UPPER(#{QUOTED_TYPE})").count(:all)
282
- assert_equal 2, c[nil]
283
- assert_equal 1, c['DEPENDENTFIRM']
284
- assert_equal 5, c['CLIENT']
285
- assert_equal 2, c['FIRM']
286
- end
287
-
288
- def test_should_calculate_grouped_by_function_with_table_alias
289
- c = Company.group("UPPER(companies.#{QUOTED_TYPE})").count(:all)
290
- assert_equal 2, c[nil]
291
- assert_equal 1, c['DEPENDENTFIRM']
292
- assert_equal 5, c['CLIENT']
293
- assert_equal 2, c['FIRM']
294
- end
295
-
296
- def test_should_not_overshadow_enumerable_sum
297
- assert_equal 6, [1, 2, 3].sum(&:abs)
298
- end
299
-
300
- def test_should_sum_scoped_field
301
- assert_equal 15, companies(:rails_core).companies.sum(:id)
302
- end
303
-
304
- def test_should_sum_scoped_field_with_from
305
- assert_equal Club.count, Organization.clubs.count
306
- end
307
-
308
- def test_should_sum_scoped_field_with_conditions
309
- assert_equal 8, companies(:rails_core).companies.where('id > 7').sum(:id)
310
- end
311
-
312
- def test_should_group_by_scoped_field
313
- c = companies(:rails_core).companies.group(:name).sum(:id)
314
- assert_equal 7, c['Leetsoft']
315
- assert_equal 8, c['Jadedpixel']
316
- end
317
-
318
- def test_should_group_by_summed_field_through_association_and_having
319
- c = companies(:rails_core).companies.group(:name).having('sum(id) > 7').sum(:id)
320
- assert_nil c['Leetsoft']
321
- assert_equal 8, c['Jadedpixel']
322
- end
323
-
324
- def test_should_count_selected_field_with_include
325
- assert_equal 6, Account.includes(:firm).distinct.count
326
- assert_equal 4, Account.includes(:firm).distinct.select(:credit_limit).count
327
- end
328
-
329
- def test_should_not_perform_joined_include_by_default
330
- assert_equal Account.count, Account.includes(:firm).count
331
- queries = assert_sql { Account.includes(:firm).count }
332
- assert_no_match(/join/i, queries.last)
333
- end
334
-
335
- def test_should_perform_joined_include_when_referencing_included_tables
336
- joined_count = Account.includes(:firm).where(:companies => {:name => '37signals'}).count
337
- assert_equal 1, joined_count
338
- end
339
-
340
- def test_should_count_scoped_select
341
- Account.update_all("credit_limit = NULL")
342
- assert_equal 0, Account.select("credit_limit").count
343
- end
344
-
345
- def test_should_count_scoped_select_with_options
346
- Account.update_all("credit_limit = NULL")
347
- Account.last.update_columns('credit_limit' => 49)
348
- Account.first.update_columns('credit_limit' => 51)
349
-
350
- assert_equal 1, Account.select("credit_limit").where('credit_limit >= 50').count
351
- end
352
-
353
- def test_should_count_manual_select_with_include
354
- assert_equal 6, Account.select("DISTINCT accounts.id").includes(:firm).count
355
- end
356
-
357
- def test_count_with_column_parameter
358
- assert_equal 5, Account.count(:firm_id)
359
- end
360
-
361
- def test_count_with_distinct
362
- assert_equal 4, Account.select(:credit_limit).distinct.count
363
- assert_equal 4, Account.select(:credit_limit).uniq.count
364
- end
365
-
366
- def test_count_with_aliased_attribute
367
- assert_equal 6, Account.count(:available_credit)
368
- end
369
-
370
- def test_count_with_column_and_options_parameter
371
- assert_equal 2, Account.where("credit_limit = 50 AND firm_id IS NOT NULL").count(:firm_id)
372
- end
373
-
374
- def test_should_count_field_in_joined_table
375
- assert_equal 5, Account.joins(:firm).count('companies.id')
376
- assert_equal 4, Account.joins(:firm).distinct.count('companies.id')
377
- end
378
-
379
- def test_should_count_field_in_joined_table_with_group_by
380
- c = Account.group('accounts.firm_id').joins(:firm).count('companies.id')
381
-
382
- [1,6,2,9].each { |firm_id| assert c.keys.include?(firm_id) }
383
- end
384
-
385
- def test_count_with_no_parameters_isnt_deprecated
386
- assert_not_deprecated { Account.count }
387
- end
388
-
389
- def test_count_with_too_many_parameters_raises
390
- assert_raise(ArgumentError) { Account.count(1, 2, 3) }
391
- end
392
-
393
- def test_count_with_order
394
- assert_equal 6, Account.order(:credit_limit).count
395
- end
396
-
397
- def test_count_with_reverse_order
398
- assert_equal 6, Account.order(:credit_limit).reverse_order.count
399
- end
400
-
401
- def test_count_with_where_and_order
402
- assert_equal 1, Account.where(firm_name: '37signals').count
403
- assert_equal 1, Account.where(firm_name: '37signals').order(:firm_name).count
404
- assert_equal 1, Account.where(firm_name: '37signals').order(:firm_name).reverse_order.count
405
- end
406
-
407
- def test_should_sum_expression
408
- # Oracle adapter returns floating point value 636.0 after SUM
409
- if current_adapter?(:OracleAdapter)
410
- assert_equal 636, Account.sum("2 * credit_limit")
411
- else
412
- assert_equal 636, Account.sum("2 * credit_limit").to_i
413
- end
414
- end
415
-
416
- def test_sum_expression_returns_zero_when_no_records_to_sum
417
- assert_equal 0, Account.where('1 = 2').sum("2 * credit_limit")
418
- end
419
-
420
- def test_count_with_from_option
421
- assert_equal Company.count(:all), Company.from('companies').count(:all)
422
- assert_equal Account.where("credit_limit = 50").count(:all),
423
- Account.from('accounts').where("credit_limit = 50").count(:all)
424
- assert_equal Company.where(:type => "Firm").count(:type),
425
- Company.where(:type => "Firm").from('companies').count(:type)
426
- end
427
-
428
- def test_sum_with_from_option
429
- assert_equal Account.sum(:credit_limit), Account.from('accounts').sum(:credit_limit)
430
- assert_equal Account.where("credit_limit > 50").sum(:credit_limit),
431
- Account.where("credit_limit > 50").from('accounts').sum(:credit_limit)
432
- end
433
-
434
- def test_average_with_from_option
435
- assert_equal Account.average(:credit_limit), Account.from('accounts').average(:credit_limit)
436
- assert_equal Account.where("credit_limit > 50").average(:credit_limit),
437
- Account.where("credit_limit > 50").from('accounts').average(:credit_limit)
438
- end
439
-
440
- def test_minimum_with_from_option
441
- assert_equal Account.minimum(:credit_limit), Account.from('accounts').minimum(:credit_limit)
442
- assert_equal Account.where("credit_limit > 50").minimum(:credit_limit),
443
- Account.where("credit_limit > 50").from('accounts').minimum(:credit_limit)
444
- end
445
-
446
- def test_maximum_with_from_option
447
- assert_equal Account.maximum(:credit_limit), Account.from('accounts').maximum(:credit_limit)
448
- assert_equal Account.where("credit_limit > 50").maximum(:credit_limit),
449
- Account.where("credit_limit > 50").from('accounts').maximum(:credit_limit)
450
- end
451
-
452
- def test_maximum_with_not_auto_table_name_prefix_if_column_included
453
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
454
-
455
- assert_equal 7, Company.includes(:contracts).maximum(:developer_id)
456
- end
457
-
458
- def test_minimum_with_not_auto_table_name_prefix_if_column_included
459
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
460
-
461
- assert_equal 7, Company.includes(:contracts).minimum(:developer_id)
462
- end
463
-
464
- def test_sum_with_not_auto_table_name_prefix_if_column_included
465
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
466
-
467
- assert_equal 7, Company.includes(:contracts).sum(:developer_id)
468
- end
469
-
470
- def test_from_option_with_specified_index
471
- if Edge.connection.adapter_name == 'MySQL' or Edge.connection.adapter_name == 'Mysql2'
472
- assert_equal Edge.count(:all), Edge.from('edges USE INDEX(unique_edge_index)').count(:all)
473
- assert_equal Edge.where('sink_id < 5').count(:all),
474
- Edge.from('edges USE INDEX(unique_edge_index)').where('sink_id < 5').count(:all)
475
- end
476
- end
477
-
478
- def test_from_option_with_table_different_than_class
479
- assert_equal Account.count(:all), Company.from('accounts').count(:all)
480
- end
481
-
482
- def test_distinct_is_honored_when_used_with_count_operation_after_group
483
- # Count the number of authors for approved topics
484
- approved_topics_count = Topic.group(:approved).count(:author_name)[true]
485
- assert_equal approved_topics_count, 4
486
- # Count the number of distinct authors for approved Topics
487
- distinct_authors_for_approved_count = Topic.group(:approved).distinct.count(:author_name)[true]
488
- assert_equal distinct_authors_for_approved_count, 3
489
- end
490
-
491
- def test_pluck
492
- assert_equal [1,2,3,4,5], Topic.order(:id).pluck(:id)
493
- end
494
-
495
- def test_pluck_without_column_names
496
- assert_equal [[1, "Firm", 1, nil, "37signals", nil, 1, nil, ""]],
497
- Company.order(:id).limit(1).pluck
498
- end
499
-
500
- def test_pluck_type_cast
501
- topic = topics(:first)
502
- relation = Topic.where(:id => topic.id)
503
- assert_equal [ topic.approved ], relation.pluck(:approved)
504
- assert_equal [ topic.last_read ], relation.pluck(:last_read)
505
- assert_equal [ topic.written_on ], relation.pluck(:written_on)
506
- end
507
-
508
- def test_pluck_and_uniq
509
- assert_equal [50, 53, 55, 60], Account.order(:credit_limit).uniq.pluck(:credit_limit)
510
- end
511
-
512
- def test_pluck_in_relation
513
- company = Company.first
514
- contract = company.contracts.create!
515
- assert_equal [contract.id], company.contracts.pluck(:id)
516
- end
517
-
518
- def test_pluck_on_aliased_attribute
519
- assert_equal 'The First Topic', Topic.order(:id).pluck(:heading).first
520
- end
521
-
522
- def test_pluck_with_serialization
523
- t = Topic.create!(:content => { :foo => :bar })
524
- assert_equal [{:foo => :bar}], Topic.where(:id => t.id).pluck(:content)
525
- end
526
-
527
- def test_pluck_with_qualified_column_name
528
- assert_equal [1,2,3,4,5], Topic.order(:id).pluck("topics.id")
529
- end
530
-
531
- def test_pluck_auto_table_name_prefix
532
- c = Company.create!(:name => "test", :contracts => [Contract.new])
533
- assert_equal [c.id], Company.joins(:contracts).pluck(:id)
534
- end
535
-
536
- def test_pluck_if_table_included
537
- c = Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
538
- assert_equal [c.id], Company.includes(:contracts).where("contracts.id" => c.contracts.first).pluck(:id)
539
- end
540
-
541
- def test_pluck_not_auto_table_name_prefix_if_column_joined
542
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
543
- assert_equal [7], Company.joins(:contracts).pluck(:developer_id)
544
- end
545
-
546
- def test_pluck_with_selection_clause
547
- assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT credit_limit').sort
548
- assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT accounts.credit_limit').sort
549
- assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT(credit_limit)').sort
550
-
551
- # MySQL returns "SUM(DISTINCT(credit_limit))" as the column name unless
552
- # an alias is provided. Without the alias, the column cannot be found
553
- # and properly typecast.
554
- assert_equal [50 + 53 + 55 + 60], Account.pluck('SUM(DISTINCT(credit_limit)) as credit_limit')
555
- end
556
-
557
- def test_plucks_with_ids
558
- assert_equal Company.all.map(&:id).sort, Company.ids.sort
559
- end
560
-
561
- def test_pluck_with_includes_limit_and_empty_result
562
- assert_equal [], Topic.includes(:replies).limit(0).pluck(:id)
563
- assert_equal [], Topic.includes(:replies).limit(1).where('0 = 1').pluck(:id)
564
- end
565
-
566
- def test_pluck_not_auto_table_name_prefix_if_column_included
567
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
568
- ids = Company.includes(:contracts).pluck(:developer_id)
569
- assert_equal Company.count, ids.length
570
- assert_equal [7], ids.compact
571
- end
572
-
573
- def test_pluck_multiple_columns
574
- assert_equal [
575
- [1, "The First Topic"], [2, "The Second Topic of the day"],
576
- [3, "The Third Topic of the day"], [4, "The Fourth Topic of the day"],
577
- [5, "The Fifth Topic of the day"]
578
- ], Topic.order(:id).pluck(:id, :title)
579
- assert_equal [
580
- [1, "The First Topic", "David"], [2, "The Second Topic of the day", "Mary"],
581
- [3, "The Third Topic of the day", "Carl"], [4, "The Fourth Topic of the day", "Carl"],
582
- [5, "The Fifth Topic of the day", "Jason"]
583
- ], Topic.order(:id).pluck(:id, :title, :author_name)
584
- end
585
-
586
- def test_pluck_with_multiple_columns_and_selection_clause
587
- assert_equal [[1, 50], [2, 50], [3, 50], [4, 60], [5, 55], [6, 53]],
588
- Account.pluck('id, credit_limit')
589
- end
590
-
591
- def test_pluck_with_multiple_columns_and_includes
592
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
593
- companies_and_developers = Company.order('companies.id').includes(:contracts).pluck(:name, :developer_id)
594
-
595
- assert_equal Company.count, companies_and_developers.length
596
- assert_equal ["37signals", nil], companies_and_developers.first
597
- assert_equal ["test", 7], companies_and_developers.last
598
- end
599
-
600
- def test_pluck_with_reserved_words
601
- Possession.create!(:where => "Over There")
602
-
603
- assert_equal ["Over There"], Possession.pluck(:where)
604
- end
605
-
606
- def test_pluck_replaces_select_clause
607
- taks_relation = Topic.select(:approved, :id).order(:id)
608
- assert_equal [1,2,3,4,5], taks_relation.pluck(:id)
609
- assert_equal [false, true, true, true, true], taks_relation.pluck(:approved)
610
- end
611
-
612
- def test_pluck_columns_with_same_name
613
- expected = [["The First Topic", "The Second Topic of the day"], ["The Third Topic of the day", "The Fourth Topic of the day"]]
614
- actual = Topic.joins(:replies)
615
- .pluck('topics.title', 'replies_topics.title')
616
- assert_equal expected, actual
617
- end
618
-
619
- def test_calculation_with_polymorphic_relation
620
- part = ShipPart.create!(name: "has trinket")
621
- part.trinkets.create!
622
-
623
- assert_equal part.id, ShipPart.joins(:trinkets).sum(:id)
624
- end
625
-
626
- def test_pluck_joined_with_polymorphic_relation
627
- part = ShipPart.create!(name: "has trinket")
628
- part.trinkets.create!
629
-
630
- assert_equal [part.id], ShipPart.joins(:trinkets).pluck(:id)
631
- end
632
-
633
- def test_grouped_calculation_with_polymorphic_relation
634
- part = ShipPart.create!(name: "has trinket")
635
- part.trinkets.create!
636
-
637
- assert_equal({ "has trinket" => part.id }, ShipPart.joins(:trinkets).group("ship_parts.name").sum(:id))
638
- end
639
-
640
- def test_should_reference_correct_aliases_while_joining_tables_of_has_many_through_association
641
- assert_nothing_raised ActiveRecord::StatementInvalid do
642
- developer = Developer.create!(name: 'developer')
643
- developer.ratings.includes(comment: :post).where(posts: { id: 1 }).count
644
- end
645
- end
646
- end
1
+ require "cases/helper"
2
+ require 'models/club'
3
+ require 'models/company'
4
+ require "models/contract"
5
+ require 'models/edge'
6
+ require 'models/organization'
7
+ require 'models/possession'
8
+ require 'models/topic'
9
+ require 'models/reply'
10
+ require 'models/minivan'
11
+ require 'models/speedometer'
12
+ require 'models/ship_part'
13
+ require 'models/treasure'
14
+ require 'models/developer'
15
+ require 'models/comment'
16
+ require 'models/rating'
17
+ require 'models/post'
18
+
19
+ class NumericData < ActiveRecord::Base
20
+ self.table_name = 'numeric_data'
21
+
22
+ attribute :world_population, Type::Integer.new
23
+ attribute :my_house_population, Type::Integer.new
24
+ attribute :atoms_in_universe, Type::Integer.new
25
+ end
26
+
27
+ class CalculationsTest < ActiveRecord::TestCase
28
+ fixtures :companies, :accounts, :topics, :speedometers, :minivans
29
+
30
+ def test_should_sum_field
31
+ assert_equal 318, Account.sum(:credit_limit)
32
+ end
33
+
34
+ def test_should_average_field
35
+ value = Account.average(:credit_limit)
36
+ assert_equal 53.0, value
37
+ end
38
+
39
+ def test_should_resolve_aliased_attributes
40
+ assert_equal 318, Account.sum(:available_credit)
41
+ end
42
+
43
+ def test_should_return_decimal_average_of_integer_field
44
+ return if current_adapter?(:IBM_DBAdapter) #average cannot be a decimal value when applied on integer field
45
+ value = Account.average(:id)
46
+ assert_equal 3.5, value
47
+ end
48
+
49
+ def test_should_return_integer_average_if_db_returns_such
50
+ ShipPart.delete_all
51
+ ShipPart.create!(:id => 3, :name => 'foo')
52
+ value = ShipPart.average(:id)
53
+ assert_equal 3, value
54
+ end
55
+
56
+ def test_should_return_nil_as_average
57
+ assert_nil NumericData.average(:bank_balance)
58
+ end
59
+
60
+ def test_should_get_maximum_of_field
61
+ assert_equal 60, Account.maximum(:credit_limit)
62
+ end
63
+
64
+ def test_should_get_maximum_of_field_with_include
65
+ assert_equal 55, Account.where("companies.name != 'Summit'").references(:companies).includes(:firm).maximum(:credit_limit)
66
+ end
67
+
68
+ def test_should_get_minimum_of_field
69
+ assert_equal 50, Account.minimum(:credit_limit)
70
+ end
71
+
72
+ def test_should_group_by_field
73
+ c = Account.group(:firm_id).sum(:credit_limit)
74
+ [1,6,2].each do |firm_id|
75
+ assert c.keys.include?(firm_id), "Group #{c.inspect} does not contain firm_id #{firm_id}"
76
+ end
77
+ end
78
+
79
+ def test_should_group_by_arel_attribute
80
+ c = Account.group(Account.arel_table[:firm_id]).sum(:credit_limit)
81
+ [1,6,2].each do |firm_id|
82
+ assert c.keys.include?(firm_id), "Group #{c.inspect} does not contain firm_id #{firm_id}"
83
+ end
84
+ end
85
+
86
+ def test_should_group_by_multiple_fields
87
+ c = Account.group('firm_id', :credit_limit).count(:all)
88
+ [ [nil, 50], [1, 50], [6, 50], [6, 55], [9, 53], [2, 60] ].each { |firm_and_limit| assert c.keys.include?(firm_and_limit) }
89
+ end
90
+
91
+ def test_should_group_by_multiple_fields_having_functions
92
+ c = Topic.group(:author_name, 'COALESCE(type, title)').count(:all)
93
+ assert_equal 1, c[["Carl", "The Third Topic of the day"]]
94
+ assert_equal 1, c[["Mary", "Reply"]]
95
+ assert_equal 1, c[["David", "The First Topic"]]
96
+ assert_equal 1, c[["Carl", "Reply"]]
97
+ end
98
+
99
+ def test_should_group_by_summed_field
100
+ c = Account.group(:firm_id).sum(:credit_limit)
101
+ assert_equal 50, c[1]
102
+ assert_equal 105, c[6]
103
+ assert_equal 60, c[2]
104
+ end
105
+
106
+ def test_should_order_by_grouped_field
107
+ c = Account.group(:firm_id).order("firm_id").sum(:credit_limit)
108
+ assert_equal [1, 2, 6, 9], c.keys.compact
109
+ end
110
+
111
+ def test_should_order_by_calculation
112
+ c = Account.group(:firm_id).order("sum_credit_limit desc, firm_id").sum(:credit_limit)
113
+ assert_equal [105, 60, 53, 50, 50], c.keys.collect { |k| c[k] }
114
+ assert_equal [6, 2, 9, 1], c.keys.compact
115
+ end
116
+
117
+ def test_should_limit_calculation
118
+ c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id").limit(2).sum(:credit_limit)
119
+ assert_equal [1, 2], c.keys.compact
120
+ end
121
+
122
+ def test_should_limit_calculation_with_offset
123
+ c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id").
124
+ limit(2).offset(1).sum(:credit_limit)
125
+ assert_equal [2, 6], c.keys.compact
126
+ end
127
+
128
+ def test_limit_should_apply_before_count
129
+ accounts = Account.limit(3).where('firm_id IS NOT NULL')
130
+
131
+ assert_equal 3, accounts.count(:firm_id)
132
+ assert_equal 3, accounts.select(:firm_id).count
133
+ end
134
+
135
+ def test_count_should_shortcut_with_limit_zero
136
+ accounts = Account.limit(0)
137
+
138
+ assert_no_queries { assert_equal 0, accounts.count }
139
+ end
140
+
141
+ def test_limit_is_kept
142
+ return if current_adapter?(:OracleAdapter) || current_adapter?(:IBM_DBAdapter)
143
+
144
+ queries = assert_sql { Account.limit(1).count }
145
+ assert_equal 1, queries.length
146
+ assert_match(/LIMIT/, queries.first)
147
+ end
148
+
149
+ def test_offset_is_kept
150
+ return if current_adapter?(:OracleAdapter) || current_adapter?(:IBM_DBAdapter)
151
+
152
+ queries = assert_sql { Account.offset(1).count }
153
+ assert_equal 1, queries.length
154
+ assert_match(/OFFSET/, queries.first)
155
+ end
156
+
157
+ def test_limit_with_offset_is_kept
158
+ return if current_adapter?(:OracleAdapter) || current_adapter?(:IBM_DBAdapter)
159
+
160
+ queries = assert_sql { Account.limit(1).offset(1).count }
161
+ assert_equal 1, queries.length
162
+ assert_match(/LIMIT/, queries.first)
163
+ assert_match(/OFFSET/, queries.first)
164
+ end
165
+
166
+ def test_no_limit_no_offset
167
+ queries = assert_sql { Account.count }
168
+ assert_equal 1, queries.length
169
+ assert_no_match(/LIMIT/, queries.first)
170
+ assert_no_match(/OFFSET/, queries.first)
171
+ end
172
+
173
+ def test_count_on_invalid_columns_raises
174
+ e = assert_raises(ActiveRecord::StatementInvalid) {
175
+ Account.select("credit_limit, firm_name").count
176
+ }
177
+
178
+ assert_match %r{accounts}i, e.message
179
+ assert_match "credit_limit, firm_name", e.message
180
+ end
181
+
182
+ def test_should_group_by_summed_field_having_condition
183
+ c = Account.group(:firm_id).having('sum(credit_limit) > 50').sum(:credit_limit)
184
+ assert_nil c[1]
185
+ assert_equal 105, c[6]
186
+ assert_equal 60, c[2]
187
+ end
188
+
189
+ def test_should_group_by_summed_field_having_condition_from_select
190
+ c = Account.select("MIN(credit_limit) AS min_credit_limit").group(:firm_id).having("MIN(credit_limit) > 50").sum(:credit_limit)
191
+ assert_nil c[1]
192
+ assert_equal 60, c[2]
193
+ assert_equal 53, c[9]
194
+ end
195
+
196
+ def test_should_group_by_summed_association
197
+ c = Account.group(:firm).sum(:credit_limit)
198
+ assert_equal 50, c[companies(:first_firm)]
199
+ assert_equal 105, c[companies(:rails_core)]
200
+ assert_equal 60, c[companies(:first_client)]
201
+ end
202
+
203
+ def test_should_sum_field_with_conditions
204
+ assert_equal 105, Account.where('firm_id = 6').sum(:credit_limit)
205
+ end
206
+
207
+ def test_should_return_zero_if_sum_conditions_return_nothing
208
+ assert_equal 0, Account.where('1 = 2').sum(:credit_limit)
209
+ assert_equal 0, companies(:rails_core).companies.where('1 = 2').sum(:id)
210
+ end
211
+
212
+ def test_sum_should_return_valid_values_for_decimals
213
+ NumericData.create(:bank_balance => 19.83)
214
+ assert_equal 19.83, NumericData.sum(:bank_balance)
215
+ end
216
+
217
+ def test_should_return_type_casted_values_with_group_and_expression
218
+ assert_equal 0.5, Account.group(:firm_name).sum('0.01 * credit_limit')['37signals']
219
+ end
220
+
221
+ def test_should_group_by_summed_field_with_conditions
222
+ c = Account.where('firm_id > 1').group(:firm_id).sum(:credit_limit)
223
+ assert_nil c[1]
224
+ assert_equal 105, c[6]
225
+ assert_equal 60, c[2]
226
+ end
227
+
228
+ def test_should_group_by_summed_field_with_conditions_and_having
229
+ c = Account.where('firm_id > 1').group(:firm_id).
230
+ having('sum(credit_limit) > 60').sum(:credit_limit)
231
+ assert_nil c[1]
232
+ assert_equal 105, c[6]
233
+ assert_nil c[2]
234
+ end
235
+
236
+ def test_should_group_by_fields_with_table_alias
237
+ c = Account.group('accounts.firm_id').sum(:credit_limit)
238
+ assert_equal 50, c[1]
239
+ assert_equal 105, c[6]
240
+ assert_equal 60, c[2]
241
+ end
242
+
243
+ def test_should_calculate_with_invalid_field
244
+ assert_equal 6, Account.calculate(:count, '*')
245
+ assert_equal 6, Account.calculate(:count, :all)
246
+ end
247
+
248
+ def test_should_calculate_grouped_with_invalid_field
249
+ c = Account.group('accounts.firm_id').count(:all)
250
+ assert_equal 1, c[1]
251
+ assert_equal 2, c[6]
252
+ assert_equal 1, c[2]
253
+ end
254
+
255
+ def test_should_calculate_grouped_association_with_invalid_field
256
+ c = Account.group(:firm).count(:all)
257
+ assert_equal 1, c[companies(:first_firm)]
258
+ assert_equal 2, c[companies(:rails_core)]
259
+ assert_equal 1, c[companies(:first_client)]
260
+ end
261
+
262
+ def test_should_group_by_association_with_non_numeric_foreign_key
263
+ Speedometer.create! id: 'ABC'
264
+ Minivan.create! id: 'OMG', speedometer_id: 'ABC'
265
+
266
+ c = Minivan.group(:speedometer).count(:all)
267
+ first_key = c.keys.first
268
+ assert_equal Speedometer, first_key.class
269
+ assert_equal 1, c[first_key]
270
+ end
271
+
272
+ def test_should_calculate_grouped_association_with_foreign_key_option
273
+ Account.belongs_to :another_firm, :class_name => 'Firm', :foreign_key => 'firm_id'
274
+ c = Account.group(:another_firm).count(:all)
275
+ assert_equal 1, c[companies(:first_firm)]
276
+ assert_equal 2, c[companies(:rails_core)]
277
+ assert_equal 1, c[companies(:first_client)]
278
+ end
279
+
280
+ def test_should_calculate_grouped_by_function
281
+ c = Company.group("UPPER(#{QUOTED_TYPE})").count(:all)
282
+ assert_equal 2, c[nil]
283
+ assert_equal 1, c['DEPENDENTFIRM']
284
+ assert_equal 5, c['CLIENT']
285
+ assert_equal 2, c['FIRM']
286
+ end
287
+
288
+ def test_should_calculate_grouped_by_function_with_table_alias
289
+ c = Company.group("UPPER(companies.#{QUOTED_TYPE})").count(:all)
290
+ assert_equal 2, c[nil]
291
+ assert_equal 1, c['DEPENDENTFIRM']
292
+ assert_equal 5, c['CLIENT']
293
+ assert_equal 2, c['FIRM']
294
+ end
295
+
296
+ def test_should_not_overshadow_enumerable_sum
297
+ assert_equal 6, [1, 2, 3].sum(&:abs)
298
+ end
299
+
300
+ def test_should_sum_scoped_field
301
+ assert_equal 15, companies(:rails_core).companies.sum(:id)
302
+ end
303
+
304
+ def test_should_sum_scoped_field_with_from
305
+ assert_equal Club.count, Organization.clubs.count
306
+ end
307
+
308
+ def test_should_sum_scoped_field_with_conditions
309
+ assert_equal 8, companies(:rails_core).companies.where('id > 7').sum(:id)
310
+ end
311
+
312
+ def test_should_group_by_scoped_field
313
+ c = companies(:rails_core).companies.group(:name).sum(:id)
314
+ assert_equal 7, c['Leetsoft']
315
+ assert_equal 8, c['Jadedpixel']
316
+ end
317
+
318
+ def test_should_group_by_summed_field_through_association_and_having
319
+ c = companies(:rails_core).companies.group(:name).having('sum(id) > 7').sum(:id)
320
+ assert_nil c['Leetsoft']
321
+ assert_equal 8, c['Jadedpixel']
322
+ end
323
+
324
+ def test_should_count_selected_field_with_include
325
+ assert_equal 6, Account.includes(:firm).distinct.count
326
+ assert_equal 4, Account.includes(:firm).distinct.select(:credit_limit).count
327
+ end
328
+
329
+ def test_should_not_perform_joined_include_by_default
330
+ assert_equal Account.count, Account.includes(:firm).count
331
+ queries = assert_sql { Account.includes(:firm).count }
332
+ assert_no_match(/join/i, queries.last)
333
+ end
334
+
335
+ def test_should_perform_joined_include_when_referencing_included_tables
336
+ joined_count = Account.includes(:firm).where(:companies => {:name => '37signals'}).count
337
+ assert_equal 1, joined_count
338
+ end
339
+
340
+ def test_should_count_scoped_select
341
+ Account.update_all("credit_limit = NULL")
342
+ assert_equal 0, Account.select("credit_limit").count
343
+ end
344
+
345
+ def test_should_count_scoped_select_with_options
346
+ Account.update_all("credit_limit = NULL")
347
+ Account.last.update_columns('credit_limit' => 49)
348
+ Account.first.update_columns('credit_limit' => 51)
349
+
350
+ assert_equal 1, Account.select("credit_limit").where('credit_limit >= 50').count
351
+ end
352
+
353
+ def test_should_count_manual_select_with_include
354
+ assert_equal 6, Account.select("DISTINCT accounts.id").includes(:firm).count
355
+ end
356
+
357
+ def test_count_with_column_parameter
358
+ assert_equal 5, Account.count(:firm_id)
359
+ end
360
+
361
+ def test_count_with_distinct
362
+ assert_equal 4, Account.select(:credit_limit).distinct.count
363
+ assert_equal 4, Account.select(:credit_limit).uniq.count
364
+ end
365
+
366
+ def test_count_with_aliased_attribute
367
+ assert_equal 6, Account.count(:available_credit)
368
+ end
369
+
370
+ def test_count_with_column_and_options_parameter
371
+ assert_equal 2, Account.where("credit_limit = 50 AND firm_id IS NOT NULL").count(:firm_id)
372
+ end
373
+
374
+ def test_should_count_field_in_joined_table
375
+ assert_equal 5, Account.joins(:firm).count('companies.id')
376
+ assert_equal 4, Account.joins(:firm).distinct.count('companies.id')
377
+ end
378
+
379
+ def test_should_count_field_in_joined_table_with_group_by
380
+ c = Account.group('accounts.firm_id').joins(:firm).count('companies.id')
381
+
382
+ [1,6,2,9].each { |firm_id| assert c.keys.include?(firm_id) }
383
+ end
384
+
385
+ def test_count_with_no_parameters_isnt_deprecated
386
+ assert_not_deprecated { Account.count }
387
+ end
388
+
389
+ def test_count_with_too_many_parameters_raises
390
+ assert_raise(ArgumentError) { Account.count(1, 2, 3) }
391
+ end
392
+
393
+ def test_count_with_order
394
+ assert_equal 6, Account.order(:credit_limit).count
395
+ end
396
+
397
+ def test_count_with_reverse_order
398
+ assert_equal 6, Account.order(:credit_limit).reverse_order.count
399
+ end
400
+
401
+ def test_count_with_where_and_order
402
+ assert_equal 1, Account.where(firm_name: '37signals').count
403
+ assert_equal 1, Account.where(firm_name: '37signals').order(:firm_name).count
404
+ assert_equal 1, Account.where(firm_name: '37signals').order(:firm_name).reverse_order.count
405
+ end
406
+
407
+ def test_should_sum_expression
408
+ # Oracle adapter returns floating point value 636.0 after SUM
409
+ if current_adapter?(:OracleAdapter)
410
+ assert_equal 636, Account.sum("2 * credit_limit")
411
+ else
412
+ assert_equal 636, Account.sum("2 * credit_limit").to_i
413
+ end
414
+ end
415
+
416
+ def test_sum_expression_returns_zero_when_no_records_to_sum
417
+ assert_equal 0, Account.where('1 = 2').sum("2 * credit_limit")
418
+ end
419
+
420
+ def test_count_with_from_option
421
+ assert_equal Company.count(:all), Company.from('companies').count(:all)
422
+ assert_equal Account.where("credit_limit = 50").count(:all),
423
+ Account.from('accounts').where("credit_limit = 50").count(:all)
424
+ assert_equal Company.where(:type => "Firm").count(:type),
425
+ Company.where(:type => "Firm").from('companies').count(:type)
426
+ end
427
+
428
+ def test_sum_with_from_option
429
+ assert_equal Account.sum(:credit_limit), Account.from('accounts').sum(:credit_limit)
430
+ assert_equal Account.where("credit_limit > 50").sum(:credit_limit),
431
+ Account.where("credit_limit > 50").from('accounts').sum(:credit_limit)
432
+ end
433
+
434
+ def test_average_with_from_option
435
+ assert_equal Account.average(:credit_limit), Account.from('accounts').average(:credit_limit)
436
+ assert_equal Account.where("credit_limit > 50").average(:credit_limit),
437
+ Account.where("credit_limit > 50").from('accounts').average(:credit_limit)
438
+ end
439
+
440
+ def test_minimum_with_from_option
441
+ assert_equal Account.minimum(:credit_limit), Account.from('accounts').minimum(:credit_limit)
442
+ assert_equal Account.where("credit_limit > 50").minimum(:credit_limit),
443
+ Account.where("credit_limit > 50").from('accounts').minimum(:credit_limit)
444
+ end
445
+
446
+ def test_maximum_with_from_option
447
+ assert_equal Account.maximum(:credit_limit), Account.from('accounts').maximum(:credit_limit)
448
+ assert_equal Account.where("credit_limit > 50").maximum(:credit_limit),
449
+ Account.where("credit_limit > 50").from('accounts').maximum(:credit_limit)
450
+ end
451
+
452
+ def test_maximum_with_not_auto_table_name_prefix_if_column_included
453
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
454
+
455
+ assert_equal 7, Company.includes(:contracts).maximum(:developer_id)
456
+ end
457
+
458
+ def test_minimum_with_not_auto_table_name_prefix_if_column_included
459
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
460
+
461
+ assert_equal 7, Company.includes(:contracts).minimum(:developer_id)
462
+ end
463
+
464
+ def test_sum_with_not_auto_table_name_prefix_if_column_included
465
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
466
+
467
+ assert_equal 7, Company.includes(:contracts).sum(:developer_id)
468
+ end
469
+
470
+ def test_from_option_with_specified_index
471
+ if Edge.connection.adapter_name == 'MySQL' or Edge.connection.adapter_name == 'Mysql2'
472
+ assert_equal Edge.count(:all), Edge.from('edges USE INDEX(unique_edge_index)').count(:all)
473
+ assert_equal Edge.where('sink_id < 5').count(:all),
474
+ Edge.from('edges USE INDEX(unique_edge_index)').where('sink_id < 5').count(:all)
475
+ end
476
+ end
477
+
478
+ def test_from_option_with_table_different_than_class
479
+ assert_equal Account.count(:all), Company.from('accounts').count(:all)
480
+ end
481
+
482
+ def test_distinct_is_honored_when_used_with_count_operation_after_group
483
+ # Count the number of authors for approved topics
484
+ approved_topics_count = Topic.group(:approved).count(:author_name)[true]
485
+ assert_equal approved_topics_count, 4
486
+ # Count the number of distinct authors for approved Topics
487
+ distinct_authors_for_approved_count = Topic.group(:approved).distinct.count(:author_name)[true]
488
+ assert_equal distinct_authors_for_approved_count, 3
489
+ end
490
+
491
+ def test_pluck
492
+ assert_equal [1,2,3,4,5], Topic.order(:id).pluck(:id)
493
+ end
494
+
495
+ def test_pluck_without_column_names
496
+ assert_equal [[1, "Firm", 1, nil, "37signals", nil, 1, nil, ""]],
497
+ Company.order(:id).limit(1).pluck
498
+ end
499
+
500
+ def test_pluck_type_cast
501
+ topic = topics(:first)
502
+ relation = Topic.where(:id => topic.id)
503
+ assert_equal [ topic.approved ], relation.pluck(:approved)
504
+ assert_equal [ topic.last_read ], relation.pluck(:last_read)
505
+ assert_equal [ topic.written_on ], relation.pluck(:written_on)
506
+ end
507
+
508
+ def test_pluck_and_uniq
509
+ assert_equal [50, 53, 55, 60], Account.order(:credit_limit).uniq.pluck(:credit_limit)
510
+ end
511
+
512
+ def test_pluck_in_relation
513
+ company = Company.first
514
+ contract = company.contracts.create!
515
+ assert_equal [contract.id], company.contracts.pluck(:id)
516
+ end
517
+
518
+ def test_pluck_on_aliased_attribute
519
+ assert_equal 'The First Topic', Topic.order(:id).pluck(:heading).first
520
+ end
521
+
522
+ def test_pluck_with_serialization
523
+ t = Topic.create!(:content => { :foo => :bar })
524
+ assert_equal [{:foo => :bar}], Topic.where(:id => t.id).pluck(:content)
525
+ end
526
+
527
+ def test_pluck_with_qualified_column_name
528
+ assert_equal [1,2,3,4,5], Topic.order(:id).pluck("topics.id")
529
+ end
530
+
531
+ def test_pluck_auto_table_name_prefix
532
+ c = Company.create!(:name => "test", :contracts => [Contract.new])
533
+ assert_equal [c.id], Company.joins(:contracts).pluck(:id)
534
+ end
535
+
536
+ def test_pluck_if_table_included
537
+ c = Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
538
+ assert_equal [c.id], Company.includes(:contracts).where("contracts.id" => c.contracts.first).pluck(:id)
539
+ end
540
+
541
+ def test_pluck_not_auto_table_name_prefix_if_column_joined
542
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
543
+ assert_equal [7], Company.joins(:contracts).pluck(:developer_id)
544
+ end
545
+
546
+ def test_pluck_with_selection_clause
547
+ assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT credit_limit').sort
548
+ assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT accounts.credit_limit').sort
549
+ assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT(credit_limit)').sort
550
+
551
+ # MySQL returns "SUM(DISTINCT(credit_limit))" as the column name unless
552
+ # an alias is provided. Without the alias, the column cannot be found
553
+ # and properly typecast.
554
+ assert_equal [50 + 53 + 55 + 60], Account.pluck('SUM(DISTINCT(credit_limit)) as credit_limit')
555
+ end
556
+
557
+ def test_plucks_with_ids
558
+ assert_equal Company.all.map(&:id).sort, Company.ids.sort
559
+ end
560
+
561
+ def test_pluck_with_includes_limit_and_empty_result
562
+ assert_equal [], Topic.includes(:replies).limit(0).pluck(:id)
563
+ assert_equal [], Topic.includes(:replies).limit(1).where('0 = 1').pluck(:id)
564
+ end
565
+
566
+ def test_pluck_not_auto_table_name_prefix_if_column_included
567
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
568
+ ids = Company.includes(:contracts).pluck(:developer_id)
569
+ assert_equal Company.count, ids.length
570
+ assert_equal [7], ids.compact
571
+ end
572
+
573
+ def test_pluck_multiple_columns
574
+ assert_equal [
575
+ [1, "The First Topic"], [2, "The Second Topic of the day"],
576
+ [3, "The Third Topic of the day"], [4, "The Fourth Topic of the day"],
577
+ [5, "The Fifth Topic of the day"]
578
+ ], Topic.order(:id).pluck(:id, :title)
579
+ assert_equal [
580
+ [1, "The First Topic", "David"], [2, "The Second Topic of the day", "Mary"],
581
+ [3, "The Third Topic of the day", "Carl"], [4, "The Fourth Topic of the day", "Carl"],
582
+ [5, "The Fifth Topic of the day", "Jason"]
583
+ ], Topic.order(:id).pluck(:id, :title, :author_name)
584
+ end
585
+
586
+ def test_pluck_with_multiple_columns_and_selection_clause
587
+ assert_equal [[1, 50], [2, 50], [3, 50], [4, 60], [5, 55], [6, 53]],
588
+ Account.pluck('id, credit_limit')
589
+ end
590
+
591
+ def test_pluck_with_multiple_columns_and_includes
592
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
593
+ companies_and_developers = Company.order('companies.id').includes(:contracts).pluck(:name, :developer_id)
594
+
595
+ assert_equal Company.count, companies_and_developers.length
596
+ assert_equal ["37signals", nil], companies_and_developers.first
597
+ assert_equal ["test", 7], companies_and_developers.last
598
+ end
599
+
600
+ def test_pluck_with_reserved_words
601
+ Possession.create!(:where => "Over There")
602
+
603
+ assert_equal ["Over There"], Possession.pluck(:where)
604
+ end
605
+
606
+ def test_pluck_replaces_select_clause
607
+ taks_relation = Topic.select(:approved, :id).order(:id)
608
+ assert_equal [1,2,3,4,5], taks_relation.pluck(:id)
609
+ assert_equal [false, true, true, true, true], taks_relation.pluck(:approved)
610
+ end
611
+
612
+ def test_pluck_columns_with_same_name
613
+ expected = [["The First Topic", "The Second Topic of the day"], ["The Third Topic of the day", "The Fourth Topic of the day"]]
614
+ actual = Topic.joins(:replies)
615
+ .pluck('topics.title', 'replies_topics.title')
616
+ assert_equal expected, actual
617
+ end
618
+
619
+ def test_calculation_with_polymorphic_relation
620
+ part = ShipPart.create!(name: "has trinket")
621
+ part.trinkets.create!
622
+
623
+ assert_equal part.id, ShipPart.joins(:trinkets).sum(:id)
624
+ end
625
+
626
+ def test_pluck_joined_with_polymorphic_relation
627
+ part = ShipPart.create!(name: "has trinket")
628
+ part.trinkets.create!
629
+
630
+ assert_equal [part.id], ShipPart.joins(:trinkets).pluck(:id)
631
+ end
632
+
633
+ def test_grouped_calculation_with_polymorphic_relation
634
+ part = ShipPart.create!(name: "has trinket")
635
+ part.trinkets.create!
636
+
637
+ assert_equal({ "has trinket" => part.id }, ShipPart.joins(:trinkets).group("ship_parts.name").sum(:id))
638
+ end
639
+
640
+ def test_should_reference_correct_aliases_while_joining_tables_of_has_many_through_association
641
+ assert_nothing_raised ActiveRecord::StatementInvalid do
642
+ developer = Developer.create!(name: 'developer')
643
+ developer.ratings.includes(comment: :post).where(posts: { id: 1 }).count
644
+ end
645
+ end
646
+ end