rom 5.3.0 → 6.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -33
  3. data/LICENSE +1 -1
  4. data/README.md +6 -6
  5. data/lib/rom/array_dataset.rb +46 -0
  6. data/lib/rom/associations/abstract.rb +217 -0
  7. data/lib/rom/associations/definitions/abstract.rb +150 -0
  8. data/lib/rom/associations/definitions/many_to_many.rb +29 -0
  9. data/lib/rom/associations/definitions/many_to_one.rb +14 -0
  10. data/lib/rom/associations/definitions/one_to_many.rb +14 -0
  11. data/lib/rom/associations/definitions/one_to_one.rb +14 -0
  12. data/lib/rom/associations/definitions/one_to_one_through.rb +14 -0
  13. data/lib/rom/associations/definitions.rb +7 -0
  14. data/lib/rom/associations/many_to_many.rb +128 -0
  15. data/lib/rom/associations/many_to_one.rb +65 -0
  16. data/lib/rom/associations/one_to_many.rb +65 -0
  17. data/lib/rom/associations/one_to_one.rb +13 -0
  18. data/lib/rom/associations/one_to_one_through.rb +13 -0
  19. data/lib/rom/associations/through_identifier.rb +41 -0
  20. data/lib/rom/attribute.rb +425 -0
  21. data/lib/rom/auto_curry.rb +70 -0
  22. data/lib/rom/cache.rb +87 -0
  23. data/lib/rom/changeset/associated.rb +110 -0
  24. data/lib/rom/changeset/create.rb +18 -0
  25. data/lib/rom/changeset/delete.rb +15 -0
  26. data/lib/rom/changeset/extensions/relation.rb +26 -0
  27. data/lib/rom/changeset/pipe.rb +81 -0
  28. data/lib/rom/changeset/pipe_registry.rb +27 -0
  29. data/lib/rom/changeset/stateful.rb +285 -0
  30. data/lib/rom/changeset/update.rb +81 -0
  31. data/lib/rom/changeset.rb +185 -0
  32. data/lib/rom/command.rb +351 -0
  33. data/lib/rom/command_compiler.rb +201 -0
  34. data/lib/rom/command_proxy.rb +36 -0
  35. data/lib/rom/commands/class_interface.rb +236 -0
  36. data/lib/rom/commands/composite.rb +55 -0
  37. data/lib/rom/commands/create.rb +15 -0
  38. data/lib/rom/commands/delete.rb +16 -0
  39. data/lib/rom/commands/graph/class_interface.rb +64 -0
  40. data/lib/rom/commands/graph/input_evaluator.rb +94 -0
  41. data/lib/rom/commands/graph.rb +88 -0
  42. data/lib/rom/commands/lazy/create.rb +35 -0
  43. data/lib/rom/commands/lazy/delete.rb +39 -0
  44. data/lib/rom/commands/lazy/update.rb +46 -0
  45. data/lib/rom/commands/lazy.rb +106 -0
  46. data/lib/rom/commands/update.rb +16 -0
  47. data/lib/rom/commands.rb +5 -0
  48. data/lib/rom/compat/auto_registration.rb +115 -0
  49. data/lib/rom/compat/auto_registration_strategies/base.rb +29 -0
  50. data/lib/rom/compat/auto_registration_strategies/custom_namespace.rb +84 -0
  51. data/lib/rom/compat/auto_registration_strategies/no_namespace.rb +33 -0
  52. data/lib/rom/compat/auto_registration_strategies/with_namespace.rb +29 -0
  53. data/lib/rom/compat/command.rb +74 -0
  54. data/lib/rom/compat/components/dsl/schema.rb +130 -0
  55. data/lib/rom/compat/components.rb +91 -0
  56. data/lib/rom/compat/global.rb +17 -0
  57. data/lib/rom/compat/mapper.rb +22 -0
  58. data/lib/rom/compat/registries.rb +47 -0
  59. data/lib/rom/compat/relation.rb +40 -0
  60. data/lib/rom/compat/schema/dsl.rb +260 -0
  61. data/lib/rom/compat/setting_proxy.rb +44 -0
  62. data/lib/rom/compat/setup.rb +151 -0
  63. data/lib/rom/compat/transformer.rb +49 -0
  64. data/lib/rom/compat.rb +22 -0
  65. data/lib/rom/components/association.rb +26 -0
  66. data/lib/rom/components/command.rb +24 -0
  67. data/lib/rom/components/core.rb +148 -0
  68. data/lib/rom/components/dataset.rb +60 -0
  69. data/lib/rom/components/dsl/association.rb +47 -0
  70. data/lib/rom/components/dsl/command.rb +60 -0
  71. data/lib/rom/components/dsl/core.rb +126 -0
  72. data/lib/rom/components/dsl/dataset.rb +33 -0
  73. data/lib/rom/components/dsl/gateway.rb +14 -0
  74. data/lib/rom/components/dsl/mapper.rb +70 -0
  75. data/lib/rom/components/dsl/relation.rb +49 -0
  76. data/lib/rom/components/dsl/schema.rb +150 -0
  77. data/lib/rom/components/dsl/view.rb +82 -0
  78. data/lib/rom/components/dsl.rb +255 -0
  79. data/lib/rom/components/gateway.rb +50 -0
  80. data/lib/rom/components/mapper.rb +29 -0
  81. data/lib/rom/components/provider.rb +160 -0
  82. data/lib/rom/components/registry.rb +154 -0
  83. data/lib/rom/components/relation.rb +41 -0
  84. data/lib/rom/components/schema.rb +61 -0
  85. data/lib/rom/components/view.rb +55 -0
  86. data/lib/rom/components.rb +55 -0
  87. data/lib/rom/configuration_dsl.rb +4 -0
  88. data/lib/rom/constants.rb +135 -0
  89. data/lib/rom/container.rb +182 -0
  90. data/lib/rom/core.rb +125 -0
  91. data/lib/rom/data_proxy.rb +97 -0
  92. data/lib/rom/enumerable_dataset.rb +70 -0
  93. data/lib/rom/gateway.rb +232 -0
  94. data/lib/rom/global.rb +56 -0
  95. data/lib/rom/header/attribute.rb +190 -0
  96. data/lib/rom/header.rb +198 -0
  97. data/lib/rom/inferrer.rb +55 -0
  98. data/lib/rom/initializer.rb +80 -0
  99. data/lib/rom/lint/enumerable_dataset.rb +56 -0
  100. data/lib/rom/lint/gateway.rb +120 -0
  101. data/lib/rom/lint/linter.rb +79 -0
  102. data/lib/rom/lint/spec.rb +22 -0
  103. data/lib/rom/lint/test.rb +98 -0
  104. data/lib/rom/loader.rb +161 -0
  105. data/lib/rom/mapper/attribute_dsl.rb +480 -0
  106. data/lib/rom/mapper/dsl.rb +107 -0
  107. data/lib/rom/mapper/model_dsl.rb +61 -0
  108. data/lib/rom/mapper.rb +99 -0
  109. data/lib/rom/mapper_compiler.rb +84 -0
  110. data/lib/rom/memory/associations/many_to_many.rb +12 -0
  111. data/lib/rom/memory/associations/many_to_one.rb +12 -0
  112. data/lib/rom/memory/associations/one_to_many.rb +12 -0
  113. data/lib/rom/memory/associations/one_to_one.rb +12 -0
  114. data/lib/rom/memory/associations.rb +6 -0
  115. data/lib/rom/memory/commands.rb +60 -0
  116. data/lib/rom/memory/dataset.rb +127 -0
  117. data/lib/rom/memory/gateway.rb +66 -0
  118. data/lib/rom/memory/mapper_compiler.rb +10 -0
  119. data/lib/rom/memory/relation.rb +91 -0
  120. data/lib/rom/memory/schema.rb +32 -0
  121. data/lib/rom/memory/storage.rb +61 -0
  122. data/lib/rom/memory/types.rb +11 -0
  123. data/lib/rom/memory.rb +7 -0
  124. data/lib/rom/model_builder.rb +103 -0
  125. data/lib/rom/open_struct.rb +112 -0
  126. data/lib/rom/pipeline.rb +111 -0
  127. data/lib/rom/plugin.rb +130 -0
  128. data/lib/rom/plugins/class_methods.rb +37 -0
  129. data/lib/rom/plugins/command/schema.rb +45 -0
  130. data/lib/rom/plugins/command/timestamps.rb +149 -0
  131. data/lib/rom/plugins/dsl.rb +53 -0
  132. data/lib/rom/plugins/relation/changeset.rb +97 -0
  133. data/lib/rom/plugins/relation/instrumentation.rb +66 -0
  134. data/lib/rom/plugins/relation/registry_reader.rb +36 -0
  135. data/lib/rom/plugins/schema/timestamps.rb +59 -0
  136. data/lib/rom/plugins.rb +100 -0
  137. data/lib/rom/processor/composer.rb +37 -0
  138. data/lib/rom/processor/transformer.rb +415 -0
  139. data/lib/rom/processor.rb +30 -0
  140. data/lib/rom/registries/associations.rb +26 -0
  141. data/lib/rom/registries/commands.rb +11 -0
  142. data/lib/rom/registries/container.rb +12 -0
  143. data/lib/rom/registries/datasets.rb +21 -0
  144. data/lib/rom/registries/gateways.rb +8 -0
  145. data/lib/rom/registries/mappers.rb +21 -0
  146. data/lib/rom/registries/nestable.rb +32 -0
  147. data/lib/rom/registries/relations.rb +8 -0
  148. data/lib/rom/registries/root.rb +203 -0
  149. data/lib/rom/registries/schemas.rb +44 -0
  150. data/lib/rom/registries/views.rb +11 -0
  151. data/lib/rom/relation/class_interface.rb +61 -0
  152. data/lib/rom/relation/combined.rb +160 -0
  153. data/lib/rom/relation/commands.rb +65 -0
  154. data/lib/rom/relation/composite.rb +53 -0
  155. data/lib/rom/relation/curried.rb +129 -0
  156. data/lib/rom/relation/graph.rb +107 -0
  157. data/lib/rom/relation/loaded.rb +136 -0
  158. data/lib/rom/relation/materializable.rb +62 -0
  159. data/lib/rom/relation/name.rb +122 -0
  160. data/lib/rom/relation/wrap.rb +64 -0
  161. data/lib/rom/relation.rb +625 -0
  162. data/lib/rom/repository/class_interface.rb +162 -0
  163. data/lib/rom/repository/relation_reader.rb +48 -0
  164. data/lib/rom/repository/root.rb +75 -0
  165. data/lib/rom/repository/session.rb +60 -0
  166. data/lib/rom/repository.rb +179 -0
  167. data/lib/rom/schema/associations_dsl.rb +222 -0
  168. data/lib/rom/schema/inferrer.rb +106 -0
  169. data/lib/rom/schema.rb +471 -0
  170. data/lib/rom/settings.rb +141 -0
  171. data/lib/rom/setup.rb +297 -0
  172. data/lib/rom/struct.rb +99 -0
  173. data/lib/rom/struct_compiler.rb +114 -0
  174. data/lib/rom/support/configurable.rb +213 -0
  175. data/lib/rom/support/inflector.rb +31 -0
  176. data/lib/rom/support/memoizable.rb +61 -0
  177. data/lib/rom/support/notifications.rb +238 -0
  178. data/lib/rom/transaction.rb +26 -0
  179. data/lib/rom/transformer.rb +46 -0
  180. data/lib/rom/types.rb +74 -0
  181. data/lib/rom/version.rb +1 -1
  182. data/lib/rom-changeset.rb +4 -0
  183. data/lib/rom-core.rb +3 -0
  184. data/lib/rom-repository.rb +4 -0
  185. data/lib/rom.rb +3 -3
  186. metadata +272 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19e154168ffd887dd4d1ff82b078fb5549d357762cfe4414b4e445f53532ee56
4
- data.tar.gz: 17fea031391e985b38848fa9e79b3551da26f41641309be08bbb6dcdd0b2ff27
3
+ metadata.gz: 3dd988f906dce6d2688a81ef514a35dcf5661708a02381bcc929950b9ffee9ee
4
+ data.tar.gz: 63cf0036ba18ce38385b915bb9ac44b6a022cb6066575a596f675fe15a485dac
5
5
  SHA512:
6
- metadata.gz: f827125bc85724c74e14fc060c9badc1fbc31a57ac1ddf71acec24e9061373363a647fdde5889c580e77c24eb829f6f323752a0066da0225b07f80888debd8cf
7
- data.tar.gz: 74e0a8a96c478ad1dcc30c9b0b41a4a4e591a532626dfcf46f8758e69dab7d9c1d0eb48136c7cd91fb88707988f990a0fa76a5fefba4acf414afa31a49a378c7
6
+ metadata.gz: 7dccbadae0c2c95428bb7303a7afca7f878d72ce6ac0824dc8002bf4d6d9bba950d0e50ea3d74e53ec2b8edf157c58315e3b584180009c9b2f0d1e3e423fed13
7
+ data.tar.gz: bb9a618db56d1d3f803b17f8390261f50e4c0a381fc8b8e7090ed6efce288daa5adaeddd6c01c8900f0117cdb86276d2d3c73335956f88a141c62268a25f1431
data/CHANGELOG.md CHANGED
@@ -1,58 +1,85 @@
1
- ## 5.3.0
1
+ <!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
2
2
 
3
- ### Changed
4
-
5
- - [rom] Upgraded to the latest versions of dry-* (@flash-gordon)
6
-
7
- ### Fixed
8
-
9
- - [rom-core] warning about using `lambda` without a literal block (@flash-gordon)
10
-
11
- [Compare v5.2.6...release-5.3](https://github.com/rom-rb/rom/compare/v5.2.6...v5.3.0)
12
-
13
- ## 5.2.6 2021-01-16
14
-
15
- ### Changed
16
-
17
- - [rom] Dependency on `rom-core` was bumped to `>= 5.2.5` (@solnic)
3
+ ## 6.0.0.alpha1 2022-04-15
18
4
 
19
- ### Fixed
5
+ This is a major release but it's backward compatible. Please see [the upgrade guide](https://github.com/rom-rb/rom/wiki/6.0-Upgrade-Guide) as there are
6
+ a couple of extra steps required for the upgrade.
20
7
 
21
- - [rom-core] Setup works under MRI 3.0.0 (issue #622 fixed via #623) (@v-kolesnikov)
22
8
 
23
- [Compare v5.2.5...v5.2.6](https://github.com/rom-rb/rom/compare/v5.2.5...v5.2.6)
9
+ ### Added
24
10
 
25
- ## 5.2.5 2020-12-30
11
+ - New settings API for components using dry-configurable (via #651) (@solnic)
12
+ - ROM(...) shortcut method for setting up rom, ie `ROM(:sql, "sqlite::memory")` (@solnic)
13
+ - You can now configure a custom inflector via configuration (PR #591) (@flash-gordon)
14
+ - New component API that replaces internal implementation of the finalization code and makes it possible to extend ROM with arbitrary component types (see #637) (@solnic)
15
+ - Generic Component API which allows you to turn any class or object into a DSL that can define rom components (via #650) (@solnic)
16
+ - Support for defining abstract components via `config.component.abstract` in which case they won't be initialized for runtime usage (via #651) (@solnic)
17
+ - Ability to provide top-level component configuration ie default gateway, adapter, inflector etc. (via #653) (@solnic)
18
+ - Ability to configure gateways using configuration DSL (via #653) (@solnic)
19
+ - Ability to define schemas without relations (via #653) (@solnic)
20
+ - Relation view schemas that are defined via `Relation.view` DSL are now registered too, which makes them more accessible/reusable (via #653) (@solnic)
21
+ - Global configuration that can provide default settings for all your components. ie a default adapter, gateway etc. (via #654) (@solnic)
22
+ - Support for custom namespaces under which commands and mappers can be registered (via #654) (@solnic)
23
+ - Top-level `associations` DSL (via #656) (@solnic)
24
+ - Support for configuring plugins on a per-component *instance* basis, which means that implementing plugins is now simpler and more powerful (via #656) (@solnic)
25
+ - New relation setting: `component.infer_id_from_class` (via #661) (@solnic)
26
+ - [experimental] New `ROM.components` API for registering custom component types (via #654) (@solnic)
27
+ - .transaction methods now accept keyword arguments. `Repository#transaction` accepts gateway to use. `Repository::Root#transaction` uses a gateway of the root relation by default (#620 closed by #621) (@flash-gordon)
28
+ - Backward-compatibility extension that you can load via `require "rom/compat"` (via #634 refs #607) (@solnic)
26
29
 
27
30
  ### Fixed
28
31
 
29
- - [rom-core] auto-registration sorts files now which fixes some (rare) issues with file loading (@v-kolesnikov)
30
- - [rom-core] configuration values are no longer being frozen during finalization of the setup (@v-kolesnikov)
32
+ - Setup works under MRI 3.0.0 (issue #622 fixed via #623) (@v-kolesnikov)
31
33
 
32
34
  ### Changed
33
35
 
34
- - [rom] Dependency on `rom-core` was bumped to `>= 5.2.4` (@solnic)
35
-
36
- [Compare v5.2.4...v5.2.5](https://github.com/rom-rb/rom/compare/v5.2.4...v5.2.5)
36
+ - [BREAKING] `rom-core`, `rom-changeset` and `rom-repository` have been merged into `rom` gem (@solnic)
37
+ - [BREAKING] `Setup#auto_registration` was renamed to `Setup#auto_register`. You can restore the original method via rom/compat extension (via #634 refs #607) (@solnic)
38
+ - [BREAKING] `Configuration#method_missing` no longer resolves gateways by default. This functionality was moved to rom/compat (@solnic)
39
+ - [BREAKING] `ROM::Configuration` is deprecated and it was replaced by `ROM::Setup`. It can be restored via rom/compat (via #653) (@solnic)
40
+ - `ROM.container` is deprecated and it was replaced by `ROM.runtime` (via #653) (@solnic)
41
+ - `Schema#[]` and `Relation#[]` now raise an error if a given attribute is not unique (issue #529 fixed via #543) (@waiting-for-dev)
42
+ - Configuration values are no longer being frozen during setup process (issue #616 fixed via #617) (@v-kolesnikov)
43
+ - Custom commands are now lazily-resolved at runtime, which simplifies and speeds up setup and finalization (via #641) (@solnic)
44
+ - Mappers are now lazy-resolved at runtime which speeds up setup and finalization (via #642) (@solnic)
45
+ - Schemas are now 1st class components accessible via runtime container and decoupled from relations (via #644) (@solnic)
46
+ - `Relation.dataset` receives canonical schema object now, rather than relation class (via #644) (@solnic)
47
+ - Relation classes no holder hold their schemas as class variables (via #644) (@solnic)
48
+ - Gateways are now lazy-loadable (via #645) (@solnic)
49
+ - Associations are now decoupled from schemas and lazy-loaded (via #646) (@solnic)
50
+ - Plugin API is now internally simplified which resulted in faster runtime. It's also no longer required to register plugin types upfront (via #648) (@solnic)
51
+ - Configuring auto_register stores its config under `config.auto_register` (via #650) (@solnic)
52
+ - [internal] auto registration is now powered by Zeitwerk (via #634 refs #607) (@solnic)
53
+ - Plugin event listeners are no longer global which makes it possible to have plugin with different configs in a single process (via #639) (@solnic)
54
+ - [internal] Command compiler is no longer coupled to gateway and notifications (via #640) (@solnic)
55
+ - Plugin configurations **are no longer global** which means that you can configure the same plugin with different default settings for different component groups or different runtimes in the same Ruby process (via #654) (@solnic)
56
+ - `Schema::DSL` is now deprecated. Adapters that need customized schema DSL behavior can provide plugins instead (via #656) (@solnic)
57
+ - `ROM.plugins` returns global plugin registry when called without a block (via #660) (@solnic)
58
+ - [internal] `ROM::Container` is deprecated and it was replaced by `ROM::Registries::Root`. It can be restored via rom/compat (via #653) (@solnic)
59
+ - [internal] Commands that are compiled at runtime are now cached in the runtime registry (via #653) (@solnic)
60
+ - [internal] `ROM.plugin_registry` is deprecated, use `ROM.plugins` instead (via #660) (@solnic)
61
+ - [REVISIT] configuring custom gateway for a relation via DSL requires passing it as an option rather than specifying it within the block. It kinda-worked previously because the adapter was defaulting to the first one found. I'm quite sure this was more like a bug than a feature. This behavior could be restored in rom/compat though - it's a matter of defaulting to the first adapter found when gateway was not explicitly specified, meaning the new default should be set to `Undefined` rather than `:default` so that we can detect when it was not specified and act accordingly. This will only make sense when there's just *one adapter available* (via bedb330f0ec195d9acacf4481dad3a705e8a36af) (@solnic)
62
+
63
+ [Compare v5.2.4...v6.0.0.alpha1](https://github.com/rom-rb/rom/compare/v5.2.4...v6.0.0.alpha1)
37
64
 
38
65
  ## 5.2.4 2020-05-08
39
66
 
40
- ### Changed
41
67
 
42
- - [rom] Dependency on `rom-changeset` was bumped to `>= 5.2.3` (@flash-gordon)
68
+ ### Fixed
69
+
70
+ - [rom] Bumped rom-changeset version (@flash-gordon)
71
+
43
72
 
44
73
  [Compare v5.2.3...v5.2.4](https://github.com/rom-rb/rom/compare/v5.2.3...v5.2.4)
45
74
 
46
75
  ## 5.2.3 2020-05-07
47
76
 
48
- ### Fixed
49
77
 
50
- - [rom-core] Fix duplicated input processing in update commands (see #594) (@flash-gordon)
51
- - [rom-changeset] fix binding mapping functions in `Update` changesets (@timriley & @flash-gordon)
78
+ ### Fixed
52
79
 
53
- ### Changed
80
+ - [rom-core] Constructor types were fired twice when updating data (@flash-gordon)
81
+ - [rom-changeset] fixed a regression where a map function in `Update` changesets was not evaluated in the context of a changeset object (fixed via #592) (@timriley + @solnic)
54
82
 
55
- - [rom] Dependency on `rom-core` was bumped to `>= 5.2.3` (@solnic)
56
83
 
57
84
  [Compare v5.2.2...v5.2.3](https://github.com/rom-rb/rom/compare/v5.2.2...v5.2.3)
58
85
 
@@ -277,4 +304,4 @@ Yanked and republished as 5.2.1
277
304
 
278
305
  ## 4.0.0 2017-10-18
279
306
 
280
- This release turns `rom` gem into a meta gem which depends on `rom-core`, `rom-mapper`, `rom-repository` and `rom-changeset'`. See [CHANGELOG](https://github.com/rom-rb/rom/blob/master/core/CHANGELOG.md#v400-2017-10-18) in core for more information.
307
+ This release turns `rom` gem into a meta gem which depends on `rom-core`, `rom-mapper`, `rom-repository` and `rom-changeset'`. See [CHANGELOG](https://github.com/rom-rb/rom/blob/main/core/CHANGELOG.md#v400-2017-10-18) in core for more information.
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2019 rom-rb team
3
+ Copyright (c) 2015-2021 rom-rb team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  [![CI Status](https://github.com/rom-rb/rom/workflows/ci/badge.svg)][actions]
11
11
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/f473a2496d6e41ed94d3fc1e96c4a486)][codacy]
12
12
  [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/f473a2496d6e41ed94d3fc1e96c4a486)][codacy]
13
- [![Inline docs](http://inch-ci.org/github/rom-rb/rom.svg?branch=master&style=flat)][inchpages]
13
+ [![Inline docs](http://inch-ci.org/github/rom-rb/rom.svg?branch=main&style=flat)][inchpages]
14
14
  [![OpenCollective](https://opencollective.com/rom/backers/badge.svg)](#backers)
15
15
  [![OpenCollective](https://opencollective.com/rom/sponsors/badge.svg)](#sponsors)
16
16
 
@@ -20,14 +20,14 @@ the full power of your database.
20
20
 
21
21
  Main rom gem provides following components:
22
22
 
23
- * [core](https://github.com/rom-rb/rom/blob/master/core/README.md) - Core and Adapter APIs
24
- * [changeset](https://github.com/rom-rb/rom/blob/master/changeset/README.md) - Changeset objects integrated with rom-core
25
- * [repository](https://github.com/rom-rb/rom/blob/master/repository/README.md) - Additional repository abstraction integrated with rom-core
23
+ * [core](https://github.com/rom-rb/rom/blob/main/core/README.md) - Core and Adapter APIs
24
+ * [changeset](https://github.com/rom-rb/rom/blob/main/changeset/README.md) - Changeset objects integrated with rom-core
25
+ * [repository](https://github.com/rom-rb/rom/blob/main/repository/README.md) - Additional repository abstraction integrated with rom-core
26
26
 
27
27
  Learn more:
28
28
 
29
- * [Introduction](http://rom-rb.org/learn/introduction)
30
- * [Quick Start](http://rom-rb.org/learn/repositories/quick-start)
29
+ * [Introduction](https://rom-rb.org/learn/introduction)
30
+ * [Quick Start](https://rom-rb.org/learn/repository/5.2/quick-start/)
31
31
 
32
32
  ## Backers
33
33
 
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/initializer"
4
+ require "rom/enumerable_dataset"
5
+
6
+ module ROM
7
+ # A helper module that adds data-proxy behavior to an array-like object
8
+ #
9
+ # @see EnumerableDataset
10
+ #
11
+ # @api public
12
+ module ArrayDataset
13
+ extend DataProxy::ClassMethods
14
+ include EnumerableDataset
15
+
16
+ # Extends the class with data-proxy behavior
17
+ #
18
+ # @api private
19
+ def self.included(klass)
20
+ klass.class_eval do
21
+ extend Initializer
22
+ include DataProxy
23
+
24
+ param :data
25
+ end
26
+ end
27
+
28
+ forward(
29
+ :*, :+, :-, :compact, :compact!, :flatten, :flatten!, :length, :pop,
30
+ :reverse, :reverse!, :sample, :size, :shift, :shuffle, :shuffle!,
31
+ :slice, :slice!, :sort!, :uniq, :uniq!, :unshift, :values_at
32
+ )
33
+
34
+ %i[
35
+ map! combination cycle delete_if keep_if permutation reject!
36
+ select! sort_by!
37
+ ].each do |method|
38
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
39
+ def #{method}(*args, &block)
40
+ return to_enum unless block
41
+ self.class.new(data.send(:#{method}, *args, &block), **options)
42
+ end
43
+ RUBY
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/core/constants"
4
+ require "dry/core/class_attributes"
5
+
6
+ require "rom/types"
7
+ require "rom/initializer"
8
+ require "rom/support/memoizable"
9
+
10
+ module ROM
11
+ module Associations
12
+ # Abstract association class
13
+ #
14
+ # @api public
15
+ class Abstract
16
+ extend Initializer
17
+
18
+ include Memoizable
19
+ include Dry::Equalizer(:definition, :source, :target)
20
+
21
+ # @!attribute [r] definition
22
+ # @return [ROM::Associations::Definition] Association configuration object
23
+ param :definition
24
+
25
+ # @!attribute [r] relations
26
+ # @return [ROM::RelationRegistry] Relation registry
27
+ option :relations, reader: true
28
+
29
+ # @!attribute [r] source
30
+ # @return [ROM::Relation] The source relation
31
+ option :source, reader: false, optional: true
32
+
33
+ # @!attribute [r] target
34
+ # @return [ROM::Relation] The target relation
35
+ option :target, reader: false, optional: true
36
+
37
+ # Create an association object
38
+ #
39
+ # @param [Definition] definition The association definition object
40
+ # @param [RelationRegistry] relations The relation registry
41
+ #
42
+ # @api public
43
+ def self.new(definition, relations)
44
+ super(definition, relations: relations)
45
+ end
46
+
47
+ # @return [ROM::Relation] The source relation
48
+ #
49
+ # @api public
50
+ def source
51
+ options[:source] || relations[definition.source.relation]
52
+ end
53
+
54
+ # @return [ROM::Relation] The target relation
55
+ #
56
+ # @api public
57
+ def target
58
+ options[:target] || relations[definition.target.relation]
59
+ end
60
+
61
+ # Return if an association has an alias
62
+ #
63
+ # @return [Boolean]
64
+ #
65
+ # @api public
66
+ def aliased?
67
+ definition.aliased?
68
+ end
69
+
70
+ # Return association alias
71
+ #
72
+ # @return [Symbol]
73
+ #
74
+ # @api public
75
+ def as
76
+ definition.as
77
+ end
78
+
79
+ # Return association canonical name
80
+ #
81
+ # @return [Symbol]
82
+ #
83
+ # @api public
84
+ def name
85
+ definition.name
86
+ end
87
+
88
+ # Return the name of a custom relation view that should be use to
89
+ # extend or override default association view
90
+ #
91
+ # @return [Symbol]
92
+ #
93
+ # @api public
94
+ def view
95
+ definition.view
96
+ end
97
+
98
+ # Return association foreign key name
99
+ #
100
+ # @return [Symbol]
101
+ #
102
+ # @api public
103
+ def foreign_key
104
+ definition.foreign_key
105
+ end
106
+
107
+ # Return result type
108
+ #
109
+ # This can be either :one or :many
110
+ #
111
+ # @return [Symbol]
112
+ #
113
+ # @api public
114
+ def result
115
+ definition.result
116
+ end
117
+
118
+ # Return if a custom view should override default association view
119
+ #
120
+ # @return [Boolean]
121
+ #
122
+ # @api public
123
+ def override?
124
+ definition.override
125
+ end
126
+
127
+ # Return the name of a key in tuples under which loaded association data are returned
128
+ #
129
+ # @return [Symbol]
130
+ #
131
+ # @api public
132
+ def key
133
+ as || name
134
+ end
135
+
136
+ # Applies custom view to the default association view
137
+ #
138
+ # @return [Relation]
139
+ #
140
+ # @api protected
141
+ def apply_view(schema, relation)
142
+ view_rel = relation.public_send(view)
143
+ schema.merge(view_rel.schema).uniq(&:key).(view_rel)
144
+ end
145
+
146
+ # Return combine keys hash
147
+ #
148
+ # Combine keys are used for merging associated data together, typically these
149
+ # are the same as fk<=>pk mapping
150
+ #
151
+ # @return [Hash<Symbol=>Symbol>]
152
+ #
153
+ # @api public
154
+ def combine_keys
155
+ definition.combine_keys || {source_key => target_key}
156
+ end
157
+
158
+ # Return names of source PKs and target FKs
159
+ #
160
+ # @return [Array<Symbol>]
161
+ #
162
+ # @api private
163
+ def join_key_map
164
+ join_keys.to_a.flatten(1).map(&:key)
165
+ end
166
+
167
+ # Return target relation configured as a combine node
168
+ #
169
+ # @return [Relation]
170
+ #
171
+ # @api private
172
+ def node
173
+ target.with(
174
+ name: target.name.as(key),
175
+ meta: {keys: combine_keys, combine_type: result, combine_name: key}
176
+ )
177
+ end
178
+
179
+ # Return target relation as a wrap node
180
+ #
181
+ # @return [Relation]
182
+ #
183
+ # @api private
184
+ def wrap
185
+ target.with(
186
+ name: target.name.as(key),
187
+ schema: target.schema.wrap,
188
+ meta: {wrap: true, combine_name: key}
189
+ )
190
+ end
191
+
192
+ # Prepare association's target relation for composition
193
+ #
194
+ # @return [Relation]
195
+ #
196
+ # @api private
197
+ def prepare(target)
198
+ if override?
199
+ target.public_send(view)
200
+ else
201
+ call(target: target)
202
+ end
203
+ end
204
+
205
+ # Return if this association's source relation is the same as the target
206
+ #
207
+ # @return [Boolean]
208
+ #
209
+ # @api private
210
+ def self_ref?
211
+ source.name.dataset == target.name.dataset
212
+ end
213
+
214
+ memoize :combine_keys, :join_key_map
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/core/class_attributes"
4
+
5
+ require "rom/constants"
6
+ require "rom/types"
7
+ require "rom/initializer"
8
+ require "rom/relation/name"
9
+ require "rom/associations/through_identifier"
10
+ require "rom/support/inflector"
11
+
12
+ module ROM
13
+ module Associations
14
+ module Definitions
15
+ # Abstract association definition object
16
+ #
17
+ # @api public
18
+ class Abstract
19
+ include Dry::Equalizer(:source, :target, :result)
20
+ extend Initializer
21
+ extend Dry::Core::ClassAttributes
22
+
23
+ defines :result
24
+
25
+ # @!attribute [r] source
26
+ # @return [Relation::Name] the source relation name
27
+ param :source
28
+
29
+ # @!attribute [r] target
30
+ # @return [Relation::Name] the target relation name
31
+ param :target
32
+
33
+ # @!attribute [r] name
34
+ # @return [Symbol] The name of an association
35
+ option :name, Types::Strict::Symbol, default: -> { target.to_sym }
36
+
37
+ # @!attribute [r] relation
38
+ # @return [Symbol] an optional relation identifier for the target
39
+ option :relation, Types::Strict::Symbol, default: -> { name }
40
+
41
+ # @!attribute [r] alias
42
+ # @return [Symbol] An optional association alias
43
+ option :as, Types::Strict::Symbol.optional, optional: true
44
+
45
+ # @!attribute [r] foreign_key
46
+ # @return [Symbol] an optional association alias name
47
+ option :foreign_key, Types::Optional::Strict::Symbol, optional: true
48
+
49
+ # @!attribute [r] result
50
+ # @return [Symbol] either :one or :many
51
+ option :result, Types::Strict::Symbol, default: -> { self.class.result }
52
+
53
+ # @!attribute [r] view
54
+ # @return [Symbol] An optional view that should be used to extend assoc relation
55
+ option :view, optional: true
56
+
57
+ # @!attribute [r] override
58
+ # @return [TrueClass,FalseClass] Whether custom view should override default one or not
59
+ option :override, default: -> { false }
60
+
61
+ # @!attribute [r] combine_keys
62
+ # @return [Hash<Symbol=>Symbol>] Override inferred combine keys
63
+ option :combine_keys, optional: true
64
+
65
+ # Instantiate a new association definition
66
+ #
67
+ # @param [Symbol] source The name of the source dataset
68
+ # @param [Symbol] target The name of the target dataset
69
+ # @param [Hash] opts The option hash
70
+ # @option opts [Symbol] :as The name of the association (defaults to target)
71
+ # @option opts [Symbol] :relation The name of the target relation (defaults to target)
72
+ # @option opts [Symbol] :foreign_key The name of a custom foreign key
73
+ # @option opts [Symbol] :view The name of a custom relation view on the target's relation side
74
+ # @option opts [TrueClass,FalseClass] :override Whether provided :view should override association's default view
75
+ #
76
+ # @api public
77
+ def self.new(source, target, **opts)
78
+ source_name = Relation::Name[source]
79
+ target_name = resolve_target_name(target, opts)
80
+ options = process_options(target_name, opts.to_h)
81
+
82
+ super(source_name, target_name, **options)
83
+ end
84
+
85
+ # @api private
86
+ def self.resolve_target_name(target, options)
87
+ dataset = target
88
+ relation = options.fetch(:relation, target)
89
+
90
+ Relation::Name[relation, dataset, options[:as]]
91
+ end
92
+
93
+ # @api private
94
+ def self.process_options(target, options)
95
+ through = options[:through]
96
+
97
+ if through
98
+ options[:through] = ThroughIdentifier[
99
+ through,
100
+ target.relation,
101
+ options[:assoc],
102
+ inflector: options.fetch(:inflector, Inflector)
103
+ ]
104
+ end
105
+
106
+ options[:name] = target.relation
107
+
108
+ options
109
+ end
110
+
111
+ # @api public
112
+ def id
113
+ aliased? ? as : name
114
+ end
115
+
116
+ # @api public
117
+ def to_h
118
+ {id: id, **options}
119
+ end
120
+
121
+ # Return true if association's default relation view should be overridden by a custom one
122
+ #
123
+ # @return [Boolean]
124
+ #
125
+ # @api public
126
+ def override?
127
+ options[:override].equal?(true)
128
+ end
129
+
130
+ # Return true if association is aliased
131
+ #
132
+ # @return [Boolean]
133
+ #
134
+ # @api public
135
+ def aliased?
136
+ !options[:as].nil?
137
+ end
138
+
139
+ # Return association class for a given definition object
140
+ #
141
+ # @return [Class]
142
+ #
143
+ # @api public
144
+ def type
145
+ Inflector.demodulize(self.class.name).to_sym
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/types"
4
+ require "rom/associations/definitions/abstract"
5
+
6
+ module ROM
7
+ module Associations
8
+ module Definitions
9
+ # @api private
10
+ class ManyToMany < Abstract
11
+ result :many
12
+
13
+ # @!attribute [r] through
14
+ # @return [ThroughIdentifier] The name of the "through" relation
15
+ option :through, reader: true
16
+
17
+ # @api private
18
+ def through_relation
19
+ through.relation
20
+ end
21
+
22
+ # @api private
23
+ def through_assoc_name
24
+ through.assoc_name
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/associations/definitions/abstract"
4
+
5
+ module ROM
6
+ module Associations
7
+ module Definitions
8
+ # @api private
9
+ class ManyToOne < Abstract
10
+ result :one
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/associations/definitions/abstract"
4
+
5
+ module ROM
6
+ module Associations
7
+ module Definitions
8
+ # @api private
9
+ class OneToMany < Abstract
10
+ result :many
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/associations/definitions/abstract"
4
+
5
+ module ROM
6
+ module Associations
7
+ module Definitions
8
+ # @api private
9
+ class OneToOne < Abstract
10
+ result :one
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/associations/definitions/abstract"
4
+
5
+ module ROM
6
+ module Associations
7
+ module Definitions
8
+ # @api private
9
+ class OneToOneThrough < ManyToMany
10
+ result :one
11
+ end
12
+ end
13
+ end
14
+ end