activerecord 2.3.18 → 3.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (378) hide show
  1. data/CHANGELOG +105 -34
  2. data/examples/performance.rb +3 -39
  3. data/examples/simple.rb +14 -0
  4. data/lib/active_record.rb +81 -47
  5. data/lib/active_record/aggregations.rb +1 -3
  6. data/lib/active_record/association_preload.rb +39 -54
  7. data/lib/active_record/associations.rb +262 -419
  8. data/lib/active_record/associations/association_collection.rb +85 -100
  9. data/lib/active_record/associations/association_proxy.rb +20 -18
  10. data/lib/active_record/associations/belongs_to_association.rb +8 -8
  11. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +13 -35
  12. data/lib/active_record/associations/has_many_association.rb +11 -19
  13. data/lib/active_record/associations/has_many_through_association.rb +30 -183
  14. data/lib/active_record/associations/has_one_association.rb +10 -10
  15. data/lib/active_record/associations/has_one_through_association.rb +13 -11
  16. data/lib/active_record/associations/through_association_scope.rb +153 -0
  17. data/lib/active_record/attribute_methods.rb +17 -370
  18. data/lib/active_record/attribute_methods/before_type_cast.rb +33 -0
  19. data/lib/active_record/attribute_methods/dirty.rb +87 -0
  20. data/lib/active_record/attribute_methods/primary_key.rb +44 -0
  21. data/lib/active_record/attribute_methods/query.rb +37 -0
  22. data/lib/active_record/attribute_methods/read.rb +116 -0
  23. data/lib/active_record/attribute_methods/time_zone_conversion.rb +60 -0
  24. data/lib/active_record/attribute_methods/write.rb +37 -0
  25. data/lib/active_record/autosave_association.rb +20 -41
  26. data/lib/active_record/base.rb +357 -1180
  27. data/lib/active_record/batches.rb +10 -16
  28. data/lib/active_record/callbacks.rb +66 -126
  29. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +17 -13
  30. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +5 -25
  31. data/lib/active_record/connection_adapters/abstract/database_statements.rb +4 -43
  32. data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -2
  33. data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -4
  34. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
  35. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +18 -72
  36. data/lib/active_record/connection_adapters/abstract_adapter.rb +16 -49
  37. data/lib/active_record/connection_adapters/mysql_adapter.rb +15 -27
  38. data/lib/active_record/connection_adapters/postgresql_adapter.rb +84 -46
  39. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +9 -3
  40. data/lib/active_record/connection_adapters/sqlite_adapter.rb +34 -65
  41. data/lib/active_record/fixtures.rb +21 -25
  42. data/lib/active_record/locale/en.yml +9 -27
  43. data/lib/active_record/locking/optimistic.rb +16 -48
  44. data/lib/active_record/migration.rb +59 -46
  45. data/lib/active_record/named_scope.rb +85 -92
  46. data/lib/active_record/nested_attributes.rb +18 -24
  47. data/lib/active_record/observer.rb +18 -94
  48. data/lib/active_record/railtie.rb +83 -0
  49. data/lib/active_record/railties/controller_runtime.rb +38 -0
  50. data/lib/active_record/railties/databases.rake +477 -0
  51. data/lib/active_record/railties/subscriber.rb +27 -0
  52. data/lib/active_record/reflection.rb +2 -15
  53. data/lib/active_record/relation.rb +339 -0
  54. data/lib/active_record/relation/calculations.rb +259 -0
  55. data/lib/active_record/relation/finder_methods.rb +315 -0
  56. data/lib/active_record/relation/predicate_builder.rb +46 -0
  57. data/lib/active_record/relation/query_methods.rb +218 -0
  58. data/lib/active_record/relation/spawn_methods.rb +102 -0
  59. data/lib/active_record/schema_dumper.rb +10 -6
  60. data/lib/active_record/serialization.rb +31 -74
  61. data/lib/active_record/serializers/xml_serializer.rb +33 -121
  62. data/lib/active_record/session_store.rb +1 -9
  63. data/lib/active_record/test_case.rb +1 -3
  64. data/lib/active_record/timestamp.rb +7 -5
  65. data/lib/active_record/transactions.rb +9 -9
  66. data/lib/active_record/validations.rb +51 -1100
  67. data/lib/active_record/validations/associated.rb +47 -0
  68. data/lib/active_record/validations/uniqueness.rb +181 -0
  69. data/lib/active_record/version.rb +3 -3
  70. data/lib/generators/active_record.rb +30 -0
  71. data/lib/generators/active_record/migration/migration_generator.rb +25 -0
  72. data/lib/generators/active_record/migration/templates/migration.rb +11 -0
  73. data/lib/generators/active_record/model/model_generator.rb +33 -0
  74. data/lib/generators/active_record/model/templates/migration.rb +16 -0
  75. data/lib/generators/active_record/model/templates/model.rb +5 -0
  76. data/lib/generators/active_record/observer/observer_generator.rb +15 -0
  77. data/lib/generators/active_record/observer/templates/observer.rb +2 -0
  78. data/lib/generators/active_record/session_migration/session_migration_generator.rb +24 -0
  79. data/lib/generators/active_record/session_migration/templates/migration.rb +16 -0
  80. metadata +67 -325
  81. data/RUNNING_UNIT_TESTS +0 -36
  82. data/Rakefile +0 -268
  83. data/install.rb +0 -30
  84. data/lib/active_record/calculations.rb +0 -321
  85. data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -57
  86. data/lib/active_record/dirty.rb +0 -183
  87. data/lib/active_record/serializers/json_serializer.rb +0 -91
  88. data/lib/activerecord.rb +0 -2
  89. data/test/assets/example.log +0 -1
  90. data/test/assets/flowers.jpg +0 -0
  91. data/test/cases/aaa_create_tables_test.rb +0 -24
  92. data/test/cases/active_schema_test_mysql.rb +0 -122
  93. data/test/cases/active_schema_test_postgresql.rb +0 -24
  94. data/test/cases/adapter_test.rb +0 -144
  95. data/test/cases/aggregations_test.rb +0 -167
  96. data/test/cases/ar_schema_test.rb +0 -32
  97. data/test/cases/associations/belongs_to_associations_test.rb +0 -438
  98. data/test/cases/associations/callbacks_test.rb +0 -161
  99. data/test/cases/associations/cascaded_eager_loading_test.rb +0 -131
  100. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +0 -36
  101. data/test/cases/associations/eager_load_nested_include_test.rb +0 -131
  102. data/test/cases/associations/eager_load_nested_polymorphic_include.rb +0 -19
  103. data/test/cases/associations/eager_singularization_test.rb +0 -145
  104. data/test/cases/associations/eager_test.rb +0 -852
  105. data/test/cases/associations/extension_test.rb +0 -62
  106. data/test/cases/associations/habtm_join_table_test.rb +0 -56
  107. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +0 -827
  108. data/test/cases/associations/has_many_associations_test.rb +0 -1273
  109. data/test/cases/associations/has_many_through_associations_test.rb +0 -360
  110. data/test/cases/associations/has_one_associations_test.rb +0 -330
  111. data/test/cases/associations/has_one_through_associations_test.rb +0 -209
  112. data/test/cases/associations/inner_join_association_test.rb +0 -93
  113. data/test/cases/associations/inverse_associations_test.rb +0 -566
  114. data/test/cases/associations/join_model_test.rb +0 -712
  115. data/test/cases/associations_test.rb +0 -282
  116. data/test/cases/attribute_methods_test.rb +0 -305
  117. data/test/cases/autosave_association_test.rb +0 -1218
  118. data/test/cases/base_test.rb +0 -2166
  119. data/test/cases/batches_test.rb +0 -81
  120. data/test/cases/binary_test.rb +0 -30
  121. data/test/cases/calculations_test.rb +0 -360
  122. data/test/cases/callbacks_observers_test.rb +0 -38
  123. data/test/cases/callbacks_test.rb +0 -438
  124. data/test/cases/class_inheritable_attributes_test.rb +0 -32
  125. data/test/cases/column_alias_test.rb +0 -17
  126. data/test/cases/column_definition_test.rb +0 -70
  127. data/test/cases/connection_pool_test.rb +0 -25
  128. data/test/cases/connection_test_firebird.rb +0 -8
  129. data/test/cases/connection_test_mysql.rb +0 -65
  130. data/test/cases/copy_table_test_sqlite.rb +0 -80
  131. data/test/cases/counter_cache_test.rb +0 -84
  132. data/test/cases/database_statements_test.rb +0 -12
  133. data/test/cases/datatype_test_postgresql.rb +0 -204
  134. data/test/cases/date_time_test.rb +0 -37
  135. data/test/cases/default_test_firebird.rb +0 -16
  136. data/test/cases/defaults_test.rb +0 -111
  137. data/test/cases/deprecated_finder_test.rb +0 -30
  138. data/test/cases/dirty_test.rb +0 -316
  139. data/test/cases/finder_respond_to_test.rb +0 -76
  140. data/test/cases/finder_test.rb +0 -1098
  141. data/test/cases/fixtures_test.rb +0 -661
  142. data/test/cases/helper.rb +0 -68
  143. data/test/cases/i18n_test.rb +0 -46
  144. data/test/cases/inheritance_test.rb +0 -262
  145. data/test/cases/invalid_date_test.rb +0 -24
  146. data/test/cases/json_serialization_test.rb +0 -219
  147. data/test/cases/lifecycle_test.rb +0 -193
  148. data/test/cases/locking_test.rb +0 -350
  149. data/test/cases/method_scoping_test.rb +0 -704
  150. data/test/cases/migration_test.rb +0 -1649
  151. data/test/cases/migration_test_firebird.rb +0 -124
  152. data/test/cases/mixin_test.rb +0 -96
  153. data/test/cases/modules_test.rb +0 -109
  154. data/test/cases/multiple_db_test.rb +0 -85
  155. data/test/cases/named_scope_test.rb +0 -372
  156. data/test/cases/nested_attributes_test.rb +0 -840
  157. data/test/cases/pk_test.rb +0 -119
  158. data/test/cases/pooled_connections_test.rb +0 -103
  159. data/test/cases/query_cache_test.rb +0 -129
  160. data/test/cases/readonly_test.rb +0 -107
  161. data/test/cases/reflection_test.rb +0 -234
  162. data/test/cases/reload_models_test.rb +0 -22
  163. data/test/cases/repair_helper.rb +0 -50
  164. data/test/cases/reserved_word_test_mysql.rb +0 -176
  165. data/test/cases/sanitize_test.rb +0 -25
  166. data/test/cases/schema_authorization_test_postgresql.rb +0 -75
  167. data/test/cases/schema_dumper_test.rb +0 -211
  168. data/test/cases/schema_test_postgresql.rb +0 -178
  169. data/test/cases/serialization_test.rb +0 -47
  170. data/test/cases/sp_test_mysql.rb +0 -16
  171. data/test/cases/synonym_test_oracle.rb +0 -17
  172. data/test/cases/timestamp_test.rb +0 -75
  173. data/test/cases/transactions_test.rb +0 -543
  174. data/test/cases/unconnected_test.rb +0 -32
  175. data/test/cases/validations_i18n_test.rb +0 -925
  176. data/test/cases/validations_test.rb +0 -1684
  177. data/test/cases/xml_serialization_test.rb +0 -240
  178. data/test/cases/yaml_serialization_test.rb +0 -11
  179. data/test/config.rb +0 -5
  180. data/test/connections/jdbc_jdbcderby/connection.rb +0 -18
  181. data/test/connections/jdbc_jdbch2/connection.rb +0 -18
  182. data/test/connections/jdbc_jdbchsqldb/connection.rb +0 -18
  183. data/test/connections/jdbc_jdbcmysql/connection.rb +0 -26
  184. data/test/connections/jdbc_jdbcpostgresql/connection.rb +0 -26
  185. data/test/connections/jdbc_jdbcsqlite3/connection.rb +0 -25
  186. data/test/connections/native_db2/connection.rb +0 -25
  187. data/test/connections/native_firebird/connection.rb +0 -26
  188. data/test/connections/native_frontbase/connection.rb +0 -27
  189. data/test/connections/native_mysql/connection.rb +0 -25
  190. data/test/connections/native_openbase/connection.rb +0 -21
  191. data/test/connections/native_oracle/connection.rb +0 -27
  192. data/test/connections/native_postgresql/connection.rb +0 -21
  193. data/test/connections/native_sqlite/connection.rb +0 -25
  194. data/test/connections/native_sqlite3/connection.rb +0 -25
  195. data/test/connections/native_sqlite3/in_memory_connection.rb +0 -18
  196. data/test/connections/native_sybase/connection.rb +0 -23
  197. data/test/fixtures/accounts.yml +0 -29
  198. data/test/fixtures/all/developers.yml +0 -0
  199. data/test/fixtures/all/people.csv +0 -0
  200. data/test/fixtures/all/tasks.yml +0 -0
  201. data/test/fixtures/author_addresses.yml +0 -5
  202. data/test/fixtures/author_favorites.yml +0 -4
  203. data/test/fixtures/authors.yml +0 -9
  204. data/test/fixtures/binaries.yml +0 -132
  205. data/test/fixtures/books.yml +0 -7
  206. data/test/fixtures/categories.yml +0 -14
  207. data/test/fixtures/categories/special_categories.yml +0 -9
  208. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +0 -4
  209. data/test/fixtures/categories_ordered.yml +0 -7
  210. data/test/fixtures/categories_posts.yml +0 -23
  211. data/test/fixtures/categorizations.yml +0 -17
  212. data/test/fixtures/clubs.yml +0 -6
  213. data/test/fixtures/comments.yml +0 -59
  214. data/test/fixtures/companies.yml +0 -56
  215. data/test/fixtures/computers.yml +0 -4
  216. data/test/fixtures/courses.yml +0 -7
  217. data/test/fixtures/customers.yml +0 -26
  218. data/test/fixtures/developers.yml +0 -21
  219. data/test/fixtures/developers_projects.yml +0 -17
  220. data/test/fixtures/edges.yml +0 -6
  221. data/test/fixtures/entrants.yml +0 -14
  222. data/test/fixtures/faces.yml +0 -11
  223. data/test/fixtures/fk_test_has_fk.yml +0 -3
  224. data/test/fixtures/fk_test_has_pk.yml +0 -2
  225. data/test/fixtures/funny_jokes.yml +0 -10
  226. data/test/fixtures/interests.yml +0 -33
  227. data/test/fixtures/items.yml +0 -4
  228. data/test/fixtures/jobs.yml +0 -7
  229. data/test/fixtures/legacy_things.yml +0 -3
  230. data/test/fixtures/mateys.yml +0 -4
  231. data/test/fixtures/member_types.yml +0 -6
  232. data/test/fixtures/members.yml +0 -6
  233. data/test/fixtures/memberships.yml +0 -20
  234. data/test/fixtures/men.yml +0 -5
  235. data/test/fixtures/minimalistics.yml +0 -2
  236. data/test/fixtures/mixed_case_monkeys.yml +0 -6
  237. data/test/fixtures/mixins.yml +0 -29
  238. data/test/fixtures/movies.yml +0 -7
  239. data/test/fixtures/naked/csv/accounts.csv +0 -1
  240. data/test/fixtures/naked/yml/accounts.yml +0 -1
  241. data/test/fixtures/naked/yml/companies.yml +0 -1
  242. data/test/fixtures/naked/yml/courses.yml +0 -1
  243. data/test/fixtures/organizations.yml +0 -5
  244. data/test/fixtures/owners.yml +0 -7
  245. data/test/fixtures/parrots.yml +0 -27
  246. data/test/fixtures/parrots_pirates.yml +0 -7
  247. data/test/fixtures/people.yml +0 -15
  248. data/test/fixtures/pets.yml +0 -14
  249. data/test/fixtures/pirates.yml +0 -9
  250. data/test/fixtures/polymorphic_designs.yml +0 -19
  251. data/test/fixtures/polymorphic_prices.yml +0 -19
  252. data/test/fixtures/posts.yml +0 -52
  253. data/test/fixtures/price_estimates.yml +0 -7
  254. data/test/fixtures/projects.yml +0 -7
  255. data/test/fixtures/readers.yml +0 -9
  256. data/test/fixtures/references.yml +0 -17
  257. data/test/fixtures/reserved_words/distinct.yml +0 -5
  258. data/test/fixtures/reserved_words/distincts_selects.yml +0 -11
  259. data/test/fixtures/reserved_words/group.yml +0 -14
  260. data/test/fixtures/reserved_words/select.yml +0 -8
  261. data/test/fixtures/reserved_words/values.yml +0 -7
  262. data/test/fixtures/ships.yml +0 -5
  263. data/test/fixtures/sponsors.yml +0 -9
  264. data/test/fixtures/subscribers.yml +0 -7
  265. data/test/fixtures/subscriptions.yml +0 -12
  266. data/test/fixtures/taggings.yml +0 -28
  267. data/test/fixtures/tags.yml +0 -7
  268. data/test/fixtures/tasks.yml +0 -7
  269. data/test/fixtures/tees.yml +0 -4
  270. data/test/fixtures/ties.yml +0 -4
  271. data/test/fixtures/topics.yml +0 -42
  272. data/test/fixtures/toys.yml +0 -4
  273. data/test/fixtures/treasures.yml +0 -10
  274. data/test/fixtures/vertices.yml +0 -4
  275. data/test/fixtures/warehouse-things.yml +0 -3
  276. data/test/fixtures/zines.yml +0 -5
  277. data/test/migrations/broken/100_migration_that_raises_exception.rb +0 -10
  278. data/test/migrations/decimal/1_give_me_big_numbers.rb +0 -15
  279. data/test/migrations/duplicate/1_people_have_last_names.rb +0 -9
  280. data/test/migrations/duplicate/2_we_need_reminders.rb +0 -12
  281. data/test/migrations/duplicate/3_foo.rb +0 -7
  282. data/test/migrations/duplicate/3_innocent_jointable.rb +0 -12
  283. data/test/migrations/duplicate_names/20080507052938_chunky.rb +0 -7
  284. data/test/migrations/duplicate_names/20080507053028_chunky.rb +0 -7
  285. data/test/migrations/interleaved/pass_1/3_innocent_jointable.rb +0 -12
  286. data/test/migrations/interleaved/pass_2/1_people_have_last_names.rb +0 -9
  287. data/test/migrations/interleaved/pass_2/3_innocent_jointable.rb +0 -12
  288. data/test/migrations/interleaved/pass_3/1_people_have_last_names.rb +0 -9
  289. data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +0 -8
  290. data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +0 -12
  291. data/test/migrations/missing/1000_people_have_middle_names.rb +0 -9
  292. data/test/migrations/missing/1_people_have_last_names.rb +0 -9
  293. data/test/migrations/missing/3_we_need_reminders.rb +0 -12
  294. data/test/migrations/missing/4_innocent_jointable.rb +0 -12
  295. data/test/migrations/valid/1_people_have_last_names.rb +0 -9
  296. data/test/migrations/valid/2_we_need_reminders.rb +0 -12
  297. data/test/migrations/valid/3_innocent_jointable.rb +0 -12
  298. data/test/models/author.rb +0 -151
  299. data/test/models/auto_id.rb +0 -4
  300. data/test/models/binary.rb +0 -2
  301. data/test/models/bird.rb +0 -9
  302. data/test/models/book.rb +0 -4
  303. data/test/models/categorization.rb +0 -5
  304. data/test/models/category.rb +0 -34
  305. data/test/models/citation.rb +0 -6
  306. data/test/models/club.rb +0 -13
  307. data/test/models/column_name.rb +0 -3
  308. data/test/models/comment.rb +0 -29
  309. data/test/models/company.rb +0 -173
  310. data/test/models/company_in_module.rb +0 -78
  311. data/test/models/computer.rb +0 -3
  312. data/test/models/contact.rb +0 -16
  313. data/test/models/contract.rb +0 -5
  314. data/test/models/course.rb +0 -3
  315. data/test/models/customer.rb +0 -73
  316. data/test/models/default.rb +0 -2
  317. data/test/models/developer.rb +0 -101
  318. data/test/models/edge.rb +0 -5
  319. data/test/models/entrant.rb +0 -3
  320. data/test/models/essay.rb +0 -3
  321. data/test/models/event.rb +0 -3
  322. data/test/models/event_author.rb +0 -8
  323. data/test/models/face.rb +0 -7
  324. data/test/models/guid.rb +0 -2
  325. data/test/models/interest.rb +0 -5
  326. data/test/models/invoice.rb +0 -4
  327. data/test/models/item.rb +0 -7
  328. data/test/models/job.rb +0 -5
  329. data/test/models/joke.rb +0 -3
  330. data/test/models/keyboard.rb +0 -3
  331. data/test/models/legacy_thing.rb +0 -3
  332. data/test/models/line_item.rb +0 -3
  333. data/test/models/man.rb +0 -9
  334. data/test/models/matey.rb +0 -4
  335. data/test/models/member.rb +0 -12
  336. data/test/models/member_detail.rb +0 -5
  337. data/test/models/member_type.rb +0 -3
  338. data/test/models/membership.rb +0 -9
  339. data/test/models/minimalistic.rb +0 -2
  340. data/test/models/mixed_case_monkey.rb +0 -3
  341. data/test/models/movie.rb +0 -5
  342. data/test/models/order.rb +0 -4
  343. data/test/models/organization.rb +0 -6
  344. data/test/models/owner.rb +0 -5
  345. data/test/models/parrot.rb +0 -22
  346. data/test/models/person.rb +0 -16
  347. data/test/models/pet.rb +0 -5
  348. data/test/models/pirate.rb +0 -80
  349. data/test/models/polymorphic_design.rb +0 -3
  350. data/test/models/polymorphic_price.rb +0 -3
  351. data/test/models/post.rb +0 -102
  352. data/test/models/price_estimate.rb +0 -3
  353. data/test/models/project.rb +0 -30
  354. data/test/models/reader.rb +0 -4
  355. data/test/models/reference.rb +0 -4
  356. data/test/models/reply.rb +0 -46
  357. data/test/models/ship.rb +0 -19
  358. data/test/models/ship_part.rb +0 -7
  359. data/test/models/sponsor.rb +0 -4
  360. data/test/models/subject.rb +0 -4
  361. data/test/models/subscriber.rb +0 -8
  362. data/test/models/subscription.rb +0 -4
  363. data/test/models/tag.rb +0 -7
  364. data/test/models/tagging.rb +0 -10
  365. data/test/models/task.rb +0 -3
  366. data/test/models/tee.rb +0 -4
  367. data/test/models/tie.rb +0 -4
  368. data/test/models/topic.rb +0 -80
  369. data/test/models/toy.rb +0 -6
  370. data/test/models/treasure.rb +0 -8
  371. data/test/models/vertex.rb +0 -9
  372. data/test/models/warehouse_thing.rb +0 -5
  373. data/test/models/zine.rb +0 -3
  374. data/test/schema/mysql_specific_schema.rb +0 -31
  375. data/test/schema/postgresql_specific_schema.rb +0 -114
  376. data/test/schema/schema.rb +0 -550
  377. data/test/schema/schema2.rb +0 -6
  378. data/test/schema/sqlite_specific_schema.rb +0 -25
@@ -1,25 +0,0 @@
1
- require "cases/helper"
2
- require 'models/binary'
3
-
4
- class SanitizeTest < ActiveRecord::TestCase
5
- def setup
6
- end
7
-
8
- def test_sanitize_sql_array_handles_string_interpolation
9
- quoted_bambi = ActiveRecord::Base.connection.quote_string("Bambi")
10
- assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=%s", "Bambi"])
11
- assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=%s", "Bambi".mb_chars])
12
- quoted_bambi_and_thumper = ActiveRecord::Base.connection.quote_string("Bambi\nand\nThumper")
13
- assert_equal "name=#{quoted_bambi_and_thumper}",Binary.send(:sanitize_sql_array, ["name=%s", "Bambi\nand\nThumper"])
14
- assert_equal "name=#{quoted_bambi_and_thumper}",Binary.send(:sanitize_sql_array, ["name=%s", "Bambi\nand\nThumper".mb_chars])
15
- end
16
-
17
- def test_sanitize_sql_array_handles_bind_variables
18
- quoted_bambi = ActiveRecord::Base.connection.quote("Bambi")
19
- assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi"])
20
- assert_equal "name=#{quoted_bambi}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi".mb_chars])
21
- quoted_bambi_and_thumper = ActiveRecord::Base.connection.quote("Bambi\nand\nThumper")
22
- assert_equal "name=#{quoted_bambi_and_thumper}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi\nand\nThumper"])
23
- assert_equal "name=#{quoted_bambi_and_thumper}", Binary.send(:sanitize_sql_array, ["name=?", "Bambi\nand\nThumper".mb_chars])
24
- end
25
- end
@@ -1,75 +0,0 @@
1
- require "cases/helper"
2
-
3
- class SchemaThing < ActiveRecord::Base
4
- end
5
-
6
- class SchemaAuthorizationTest < ActiveRecord::TestCase
7
- self.use_transactional_fixtures = false
8
-
9
- TABLE_NAME = 'schema_things'
10
- COLUMNS = [
11
- 'id serial primary key',
12
- 'name character varying(50)'
13
- ]
14
- USERS = ['rails_pg_schema_user1', 'rails_pg_schema_user2']
15
-
16
- def setup
17
- @connection = ActiveRecord::Base.connection
18
- @connection.execute "SET search_path TO '$user',public"
19
- set_session_auth
20
- USERS.each do |u|
21
- @connection.execute "CREATE USER #{u}" rescue nil
22
- @connection.execute "CREATE SCHEMA AUTHORIZATION #{u}" rescue nil
23
- set_session_auth u
24
- @connection.execute "CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
25
- @connection.execute "INSERT INTO #{TABLE_NAME} (name) VALUES ('#{u}')"
26
- set_session_auth
27
- end
28
- end
29
-
30
- def teardown
31
- set_session_auth
32
- @connection.execute "RESET search_path"
33
- USERS.each do |u|
34
- @connection.execute "DROP SCHEMA #{u} CASCADE"
35
- @connection.execute "DROP USER #{u}"
36
- end
37
- end
38
-
39
- def test_schema_invisible
40
- assert_raise(ActiveRecord::StatementInvalid) do
41
- set_session_auth
42
- @connection.execute "SELECT * FROM #{TABLE_NAME}"
43
- end
44
- end
45
-
46
- def test_schema_uniqueness
47
- assert_nothing_raised do
48
- set_session_auth
49
- USERS.each do |u|
50
- set_session_auth u
51
- assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = 1")
52
- set_session_auth
53
- end
54
- end
55
- end
56
-
57
- def test_sequence_schema_caching
58
- assert_nothing_raised do
59
- USERS.each do |u|
60
- set_session_auth u
61
- st = SchemaThing.new :name => 'TEST1'
62
- st.save!
63
- st = SchemaThing.new :id => 5, :name => 'TEST2'
64
- st.save!
65
- set_session_auth
66
- end
67
- end
68
- end
69
-
70
- private
71
- def set_session_auth auth = nil
72
- @connection.execute "SET SESSION AUTHORIZATION #{auth || 'default'}"
73
- end
74
-
75
- end
@@ -1,211 +0,0 @@
1
- require "cases/helper"
2
- require 'stringio'
3
-
4
-
5
- class SchemaDumperTest < ActiveRecord::TestCase
6
- def standard_dump
7
- stream = StringIO.new
8
- ActiveRecord::SchemaDumper.ignore_tables = []
9
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
10
- stream.string
11
- end
12
-
13
- def test_schema_dump
14
- output = standard_dump
15
- assert_match %r{create_table "accounts"}, output
16
- assert_match %r{create_table "authors"}, output
17
- assert_no_match %r{create_table "schema_migrations"}, output
18
- end
19
-
20
- def test_schema_dump_excludes_sqlite_sequence
21
- output = standard_dump
22
- assert_no_match %r{create_table "sqlite_sequence"}, output
23
- end
24
-
25
- def test_schema_dump_includes_camelcase_table_name
26
- output = standard_dump
27
- assert_match %r{create_table "CamelCase"}, output
28
- end
29
-
30
- def assert_line_up(lines, pattern, required = false)
31
- return assert(true) if lines.empty?
32
- matches = lines.map { |line| line.match(pattern) }
33
- assert matches.all? if required
34
- matches.compact!
35
- return assert(true) if matches.empty?
36
- assert_equal 1, matches.map{ |match| match.offset(0).first }.uniq.length
37
- end
38
-
39
- def column_definition_lines(output = standard_dump)
40
- output.scan(/^( *)create_table.*?\n(.*?)^\1end/m).map{ |m| m.last.split(/\n/) }
41
- end
42
-
43
- def test_types_line_up
44
- column_definition_lines.each do |column_set|
45
- next if column_set.empty?
46
-
47
- lengths = column_set.map do |column|
48
- if match = column.match(/t\.(?:integer|decimal|float|datetime|timestamp|time|date|text|binary|string|boolean)\s+"/)
49
- match[0].length
50
- end
51
- end
52
-
53
- assert_equal 1, lengths.uniq.length
54
- end
55
- end
56
-
57
- def test_arguments_line_up
58
- column_definition_lines.each do |column_set|
59
- assert_line_up(column_set, /:default => /)
60
- assert_line_up(column_set, /:limit => /)
61
- assert_line_up(column_set, /:null => /)
62
- end
63
- end
64
-
65
- def test_no_dump_errors
66
- output = standard_dump
67
- assert_no_match %r{\# Could not dump table}, output
68
- end
69
-
70
- def test_schema_dump_includes_not_null_columns
71
- stream = StringIO.new
72
-
73
- ActiveRecord::SchemaDumper.ignore_tables = [/^[^r]/]
74
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
75
- output = stream.string
76
- assert_match %r{:null => false}, output
77
- end
78
-
79
- def test_schema_dump_includes_limit_constraint_for_integer_columns
80
- stream = StringIO.new
81
-
82
- ActiveRecord::SchemaDumper.ignore_tables = [/^(?!integer_limits)/]
83
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
84
- output = stream.string
85
-
86
- if current_adapter?(:PostgreSQLAdapter)
87
- assert_match %r{c_int_1.*:limit => 2}, output
88
- assert_match %r{c_int_2.*:limit => 2}, output
89
-
90
- # int 3 is 4 bytes in postgresql
91
- assert_match %r{c_int_3.*}, output
92
- assert_no_match %r{c_int_3.*:limit}, output
93
-
94
- assert_match %r{c_int_4.*}, output
95
- assert_no_match %r{c_int_4.*:limit}, output
96
- elsif current_adapter?(:MysqlAdapter)
97
- assert_match %r{c_int_1.*:limit => 1}, output
98
- assert_match %r{c_int_2.*:limit => 2}, output
99
- assert_match %r{c_int_3.*:limit => 3}, output
100
-
101
- assert_match %r{c_int_4.*}, output
102
- assert_no_match %r{c_int_4.*:limit}, output
103
- elsif current_adapter?(:SQLiteAdapter)
104
- assert_match %r{c_int_1.*:limit => 1}, output
105
- assert_match %r{c_int_2.*:limit => 2}, output
106
- assert_match %r{c_int_3.*:limit => 3}, output
107
- assert_match %r{c_int_4.*:limit => 4}, output
108
- end
109
- assert_match %r{c_int_without_limit.*}, output
110
- assert_no_match %r{c_int_without_limit.*:limit}, output
111
-
112
- if current_adapter?(:SQLiteAdapter)
113
- assert_match %r{c_int_5.*:limit => 5}, output
114
- assert_match %r{c_int_6.*:limit => 6}, output
115
- assert_match %r{c_int_7.*:limit => 7}, output
116
- assert_match %r{c_int_8.*:limit => 8}, output
117
- else
118
- assert_match %r{c_int_5.*:limit => 8}, output
119
- assert_match %r{c_int_6.*:limit => 8}, output
120
- assert_match %r{c_int_7.*:limit => 8}, output
121
- assert_match %r{c_int_8.*:limit => 8}, output
122
- end
123
- end
124
-
125
- def test_schema_dump_with_string_ignored_table
126
- stream = StringIO.new
127
-
128
- ActiveRecord::SchemaDumper.ignore_tables = ['accounts']
129
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
130
- output = stream.string
131
- assert_no_match %r{create_table "accounts"}, output
132
- assert_match %r{create_table "authors"}, output
133
- assert_no_match %r{create_table "schema_migrations"}, output
134
- end
135
-
136
- def test_schema_dump_with_regexp_ignored_table
137
- stream = StringIO.new
138
-
139
- ActiveRecord::SchemaDumper.ignore_tables = [/^account/]
140
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
141
- output = stream.string
142
- assert_no_match %r{create_table "accounts"}, output
143
- assert_match %r{create_table "authors"}, output
144
- assert_no_match %r{create_table "schema_migrations"}, output
145
- end
146
-
147
- def test_schema_dump_illegal_ignored_table_value
148
- stream = StringIO.new
149
- ActiveRecord::SchemaDumper.ignore_tables = [5]
150
- assert_raise(StandardError) do
151
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
152
- end
153
- end
154
-
155
- def test_schema_dumps_index_columns_in_right_order
156
- index_definition = standard_dump.split(/\n/).grep(/add_index.*companies/).first.strip
157
- assert_equal 'add_index "companies", ["firm_id", "type", "rating", "ruby_type"], :name => "company_index"', index_definition
158
- end
159
-
160
- def test_schema_dump_should_honor_nonstandard_primary_keys
161
- output = standard_dump
162
- match = output.match(%r{create_table "movies"(.*)do})
163
- assert_not_nil(match, "nonstandardpk table not found")
164
- assert_match %r(:primary_key => "movieid"), match[1], "non-standard primary key not preserved"
165
- end
166
-
167
- if current_adapter?(:MysqlAdapter)
168
- def test_schema_dump_should_not_add_default_value_for_mysql_text_field
169
- output = standard_dump
170
- assert_match %r{t.text\s+"body",\s+:null => false$}, output
171
- end
172
-
173
- def test_schema_dump_includes_length_for_mysql_blob_and_text_fields
174
- output = standard_dump
175
- assert_match %r{t.binary\s+"tiny_blob",\s+:limit => 255$}, output
176
- assert_match %r{t.binary\s+"normal_blob"$}, output
177
- assert_match %r{t.binary\s+"medium_blob",\s+:limit => 16777215$}, output
178
- assert_match %r{t.binary\s+"long_blob",\s+:limit => 2147483647$}, output
179
- assert_match %r{t.text\s+"tiny_text",\s+:limit => 255$}, output
180
- assert_match %r{t.text\s+"normal_text"$}, output
181
- assert_match %r{t.text\s+"medium_text",\s+:limit => 16777215$}, output
182
- assert_match %r{t.text\s+"long_text",\s+:limit => 2147483647$}, output
183
- end
184
- end
185
-
186
- def test_schema_dump_includes_decimal_options
187
- stream = StringIO.new
188
- ActiveRecord::SchemaDumper.ignore_tables = [/^[^n]/]
189
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
190
- output = stream.string
191
- assert_match %r{:precision => 3,[[:space:]]+:scale => 2,[[:space:]]+:default => 2.78}, output
192
- end
193
-
194
- if current_adapter?(:PostgreSQLAdapter)
195
- def test_schema_dump_includes_xml_shorthand_definition
196
- output = standard_dump
197
- if %r{create_table "postgresql_xml_data_type"} =~ output
198
- assert_match %r{t.xml "data"}, output
199
- end
200
- end
201
- end
202
-
203
- def test_schema_dump_keeps_id_column_when_id_is_false_and_id_column_added
204
- output = standard_dump
205
- match = output.match(%r{create_table "goofy_string_id"(.*)do.*\n(.*)\n})
206
- assert_not_nil(match, "goofy_string_id table not found")
207
- assert_match %r(:id => false), match[1], "no table id not preserved"
208
- assert_match %r{t.string[[:space:]]+"id",[[:space:]]+:null => false$}, match[2], "non-primary key id column not preserved"
209
- end
210
- end
211
-
@@ -1,178 +0,0 @@
1
- require "cases/helper"
2
-
3
- class SchemaTest < ActiveRecord::TestCase
4
- self.use_transactional_fixtures = false
5
-
6
- SCHEMA_NAME = 'test_schema'
7
- SCHEMA2_NAME = 'test_schema2'
8
- TABLE_NAME = 'things'
9
- CAPITALIZED_TABLE_NAME = 'Things'
10
- INDEX_A_NAME = 'a_index_things_on_name'
11
- INDEX_B_NAME = 'b_index_things_on_different_columns_in_each_schema'
12
- INDEX_A_COLUMN = 'name'
13
- INDEX_B_COLUMN_S1 = 'email'
14
- INDEX_B_COLUMN_S2 = 'moment'
15
- COLUMNS = [
16
- 'id integer',
17
- 'name character varying(50)',
18
- 'email character varying(50)',
19
- 'moment timestamp without time zone default now()'
20
- ]
21
-
22
- class Thing1 < ActiveRecord::Base
23
- set_table_name "test_schema.things"
24
- end
25
-
26
- class Thing2 < ActiveRecord::Base
27
- set_table_name "test_schema2.things"
28
- end
29
-
30
- class Thing3 < ActiveRecord::Base
31
- set_table_name 'test_schema."things.table"'
32
- end
33
-
34
- class Thing4 < ActiveRecord::Base
35
- set_table_name 'test_schema."Things"'
36
- end
37
-
38
- def setup
39
- @connection = ActiveRecord::Base.connection
40
- @connection.execute "CREATE SCHEMA #{SCHEMA_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
41
- @connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{TABLE_NAME}.table\" (#{COLUMNS.join(',')})"
42
- @connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{CAPITALIZED_TABLE_NAME}\" (#{COLUMNS.join(',')})"
43
- @connection.execute "CREATE SCHEMA #{SCHEMA2_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
44
- @connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
45
- @connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
46
- @connection.execute "CREATE INDEX #{INDEX_B_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_B_COLUMN_S1});"
47
- @connection.execute "CREATE INDEX #{INDEX_B_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_B_COLUMN_S2});"
48
- end
49
-
50
- def teardown
51
- @connection.execute "DROP SCHEMA #{SCHEMA2_NAME} CASCADE"
52
- @connection.execute "DROP SCHEMA #{SCHEMA_NAME} CASCADE"
53
- end
54
-
55
- def test_with_schema_prefixed_table_name
56
- assert_nothing_raised do
57
- assert_equal COLUMNS, columns("#{SCHEMA_NAME}.#{TABLE_NAME}")
58
- end
59
- end
60
-
61
- def test_with_schema_prefixed_capitalized_table_name
62
- assert_nothing_raised do
63
- assert_equal COLUMNS, columns("#{SCHEMA_NAME}.#{CAPITALIZED_TABLE_NAME}")
64
- end
65
- end
66
-
67
- def test_with_schema_search_path
68
- assert_nothing_raised do
69
- with_schema_search_path(SCHEMA_NAME) do
70
- assert_equal COLUMNS, columns(TABLE_NAME)
71
- end
72
- end
73
- end
74
-
75
-
76
- def test_proper_encoding_of_table_name
77
- assert_equal '"table_name"', @connection.quote_table_name('table_name')
78
- assert_equal '"table.name"', @connection.quote_table_name('"table.name"')
79
- assert_equal '"schema_name"."table_name"', @connection.quote_table_name('schema_name.table_name')
80
- assert_equal '"schema_name"."table.name"', @connection.quote_table_name('schema_name."table.name"')
81
- assert_equal '"schema.name"."table_name"', @connection.quote_table_name('"schema.name".table_name')
82
- assert_equal '"schema.name"."table.name"', @connection.quote_table_name('"schema.name"."table.name"')
83
- end
84
-
85
- def test_classes_with_qualified_schema_name
86
- assert_equal 0, Thing1.count
87
- assert_equal 0, Thing2.count
88
- assert_equal 0, Thing3.count
89
- assert_equal 0, Thing4.count
90
-
91
- Thing1.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
92
- assert_equal 1, Thing1.count
93
- assert_equal 0, Thing2.count
94
- assert_equal 0, Thing3.count
95
- assert_equal 0, Thing4.count
96
-
97
- Thing2.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
98
- assert_equal 1, Thing1.count
99
- assert_equal 1, Thing2.count
100
- assert_equal 0, Thing3.count
101
- assert_equal 0, Thing4.count
102
-
103
- Thing3.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
104
- assert_equal 1, Thing1.count
105
- assert_equal 1, Thing2.count
106
- assert_equal 1, Thing3.count
107
- assert_equal 0, Thing4.count
108
-
109
- Thing4.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
110
- assert_equal 1, Thing1.count
111
- assert_equal 1, Thing2.count
112
- assert_equal 1, Thing3.count
113
- assert_equal 1, Thing4.count
114
- end
115
-
116
- def test_raise_on_unquoted_schema_name
117
- assert_raise(ActiveRecord::StatementInvalid) do
118
- with_schema_search_path '$user,public'
119
- end
120
- end
121
-
122
- def test_without_schema_search_path
123
- assert_raise(ActiveRecord::StatementInvalid) { columns(TABLE_NAME) }
124
- end
125
-
126
- def test_ignore_nil_schema_search_path
127
- assert_nothing_raised { with_schema_search_path nil }
128
- end
129
-
130
- def test_dump_indexes_for_schema_one
131
- do_dump_index_tests_for_schema(SCHEMA_NAME, INDEX_A_COLUMN, INDEX_B_COLUMN_S1)
132
- end
133
-
134
- def test_dump_indexes_for_schema_two
135
- do_dump_index_tests_for_schema(SCHEMA2_NAME, INDEX_A_COLUMN, INDEX_B_COLUMN_S2)
136
- end
137
-
138
- def test_with_uppercase_index_name
139
- ActiveRecord::Base.connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
140
- assert_nothing_raised { ActiveRecord::Base.connection.remove_index! "things", "#{SCHEMA_NAME}.things_Index"}
141
-
142
- ActiveRecord::Base.connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
143
- ActiveRecord::Base.connection.schema_search_path = SCHEMA_NAME
144
- assert_nothing_raised { ActiveRecord::Base.connection.remove_index! "things", "things_Index"}
145
- ActiveRecord::Base.connection.schema_search_path = "public"
146
- end
147
-
148
- private
149
- def columns(table_name)
150
- @connection.send(:column_definitions, table_name).map do |name, type, default|
151
- "#{name} #{type}" + (default ? " default #{default}" : '')
152
- end
153
- end
154
-
155
- def with_schema_search_path(schema_search_path)
156
- @connection.schema_search_path = schema_search_path
157
- yield if block_given?
158
- ensure
159
- @connection.schema_search_path = "'$user', public"
160
- end
161
-
162
- def do_dump_index_tests_for_schema(this_schema_name, first_index_column_name, second_index_column_name)
163
- with_schema_search_path(this_schema_name) do
164
- indexes = @connection.indexes(TABLE_NAME).sort_by {|i| i.name}
165
- assert_equal 2,indexes.size
166
-
167
- do_dump_index_assertions_for_one_index(indexes[0], INDEX_A_NAME, first_index_column_name)
168
- do_dump_index_assertions_for_one_index(indexes[1], INDEX_B_NAME, second_index_column_name)
169
- end
170
- end
171
-
172
- def do_dump_index_assertions_for_one_index(this_index, this_index_name, this_index_column)
173
- assert_equal TABLE_NAME, this_index.table
174
- assert_equal 1, this_index.columns.size
175
- assert_equal this_index_column, this_index.columns[0]
176
- assert_equal this_index_name, this_index.name
177
- end
178
- end