foobara 0.0.1

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 (359) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +5 -0
  3. data/.rubocop.yml +20 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +10 -0
  6. data/DECISION_LOG.md +220 -0
  7. data/Guardfile +9 -0
  8. data/LICENSE-AGPL.txt +666 -0
  9. data/LICENSE.txt +4 -0
  10. data/README.md +50 -0
  11. data/Rakefile +10 -0
  12. data/concepts.md +153 -0
  13. data/projects/builtin_types/lib/foobara/builtin_types.rb +67 -0
  14. data/projects/builtin_types/src/README.md +140 -0
  15. data/projects/builtin_types/src/array/casters/arrayable.rb +22 -0
  16. data/projects/builtin_types/src/array/supported_processors/element_type_declaration.rb +41 -0
  17. data/projects/builtin_types/src/array/supported_validators/size.rb +43 -0
  18. data/projects/builtin_types/src/associative_array/casters/array.rb +22 -0
  19. data/projects/builtin_types/src/associative_array/supported_processors/key_type_declaration.rb +44 -0
  20. data/projects/builtin_types/src/associative_array/supported_processors/value_type_declaration.rb +44 -0
  21. data/projects/builtin_types/src/atomic_duck.rb +6 -0
  22. data/projects/builtin_types/src/attributes/casters/array.rb +33 -0
  23. data/projects/builtin_types/src/attributes/casters/hash.rb +28 -0
  24. data/projects/builtin_types/src/attributes/supported_processors/element_type_declarations.rb +89 -0
  25. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_defaults_from_element_types_to_root.rb +40 -0
  26. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/desugarizers/symbolize_defaults.rb +31 -0
  27. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/hash_with_symbolic_keys.rb +37 -0
  28. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/valid_attribute_names.rb +60 -0
  29. data/projects/builtin_types/src/attributes/supported_transformers/defaults.rb +41 -0
  30. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_required_from_element_types_to_root.rb +55 -0
  31. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/array_of_symbols.rb +47 -0
  32. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/array_with_valid_attribute_names.rb +54 -0
  33. data/projects/builtin_types/src/attributes/supported_validators/required.rb +51 -0
  34. data/projects/builtin_types/src/big_decimal/casters/integer.rb +21 -0
  35. data/projects/builtin_types/src/big_decimal/casters/string.rb +24 -0
  36. data/projects/builtin_types/src/boolean/casters/numeric.rb +21 -0
  37. data/projects/builtin_types/src/boolean/casters/string_or_symbol.rb +27 -0
  38. data/projects/builtin_types/src/builtin_types.rb +189 -0
  39. data/projects/builtin_types/src/date/casters/hash.rb +23 -0
  40. data/projects/builtin_types/src/date/casters/string.rb +40 -0
  41. data/projects/builtin_types/src/datetime/casters/date.rb +21 -0
  42. data/projects/builtin_types/src/datetime/casters/hash.rb +77 -0
  43. data/projects/builtin_types/src/datetime/casters/seconds_since_epoch.rb +21 -0
  44. data/projects/builtin_types/src/datetime/casters/string.rb +31 -0
  45. data/projects/builtin_types/src/duck/supported_casters/allow_nil.rb +38 -0
  46. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/class_desugarizer.rb +29 -0
  47. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_class_desugarizer.rb +31 -0
  48. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_symbol_desugarizer.rb +31 -0
  49. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/type_declaration_validators/is_valid_class.rb +43 -0
  50. data/projects/builtin_types/src/duck/supported_validators/instance_of.rb +42 -0
  51. data/projects/builtin_types/src/duck/supported_validators/one_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/cast_one_of.rb +37 -0
  52. data/projects/builtin_types/src/duck/supported_validators/one_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/module_desugarizer.rb +41 -0
  53. data/projects/builtin_types/src/duck/supported_validators/one_of.rb +41 -0
  54. data/projects/builtin_types/src/duck.rb +6 -0
  55. data/projects/builtin_types/src/duckture.rb +6 -0
  56. data/projects/builtin_types/src/email/transformers/downcase.rb +15 -0
  57. data/projects/builtin_types/src/email/validator_base.rb +94 -0
  58. data/projects/builtin_types/src/float/casters/integer.rb +21 -0
  59. data/projects/builtin_types/src/float/casters/string.rb +24 -0
  60. data/projects/builtin_types/src/integer/casters/string.rb +23 -0
  61. data/projects/builtin_types/src/number/supported_validators/max.rb +41 -0
  62. data/projects/builtin_types/src/number/supported_validators/min.rb +41 -0
  63. data/projects/builtin_types/src/string/casters/numeric.rb +21 -0
  64. data/projects/builtin_types/src/string/casters/symbol.rb +21 -0
  65. data/projects/builtin_types/src/string/supported_transformers/downcase.rb +11 -0
  66. data/projects/builtin_types/src/string/supported_validators/matches.rb +41 -0
  67. data/projects/builtin_types/src/string/supported_validators/max_length.rb +37 -0
  68. data/projects/builtin_types/src/symbol/casters/string.rb +21 -0
  69. data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations/type_declaration_extension/extend_tuple_type_declaration/desugarizers/set_size.rb +32 -0
  70. data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations/type_declaration_extension/extend_tuple_type_declaration/type_declaration_validators/size_matches.rb +50 -0
  71. data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations.rb +59 -0
  72. data/projects/callback/lib/foobara/callback.rb +1 -0
  73. data/projects/callback/src/block/after.rb +10 -0
  74. data/projects/callback/src/block/around.rb +10 -0
  75. data/projects/callback/src/block/before.rb +10 -0
  76. data/projects/callback/src/block/concerns/block_parameter_not_allowed.rb +21 -0
  77. data/projects/callback/src/block/concerns/block_parameter_required.rb +21 -0
  78. data/projects/callback/src/block/concerns/keyword_argumentable_block.rb +31 -0
  79. data/projects/callback/src/block/concerns/single_argument_block.rb +22 -0
  80. data/projects/callback/src/block/concerns/type.rb +17 -0
  81. data/projects/callback/src/block/error.rb +10 -0
  82. data/projects/callback/src/block.rb +83 -0
  83. data/projects/callback/src/registry/base.rb +90 -0
  84. data/projects/callback/src/registry/chained_conditioned.rb +24 -0
  85. data/projects/callback/src/registry/chained_multiple_action.rb +24 -0
  86. data/projects/callback/src/registry/conditioned.rb +101 -0
  87. data/projects/callback/src/registry/multiple_action.rb +110 -0
  88. data/projects/callback/src/registry/single_action.rb +15 -0
  89. data/projects/callback/src/runner.rb +89 -0
  90. data/projects/callback/src/set.rb +56 -0
  91. data/projects/command/lib/foobara/command.rb +9 -0
  92. data/projects/command/src/command/entity_helpers.rb +145 -0
  93. data/projects/command/src/command.rb +36 -0
  94. data/projects/command/src/concerns/callbacks.rb +93 -0
  95. data/projects/command/src/concerns/description.rb +23 -0
  96. data/projects/command/src/concerns/domain_mappers.rb +35 -0
  97. data/projects/command/src/concerns/entities.rb +88 -0
  98. data/projects/command/src/concerns/errors.rb +181 -0
  99. data/projects/command/src/concerns/errors_type.rb +124 -0
  100. data/projects/command/src/concerns/inputs.rb +59 -0
  101. data/projects/command/src/concerns/inputs_type.rb +58 -0
  102. data/projects/command/src/concerns/namespace.rb +49 -0
  103. data/projects/command/src/concerns/reflection.rb +137 -0
  104. data/projects/command/src/concerns/result.rb +25 -0
  105. data/projects/command/src/concerns/result_type.rb +29 -0
  106. data/projects/command/src/concerns/runtime.rb +119 -0
  107. data/projects/command/src/concerns/state_machine.rb +12 -0
  108. data/projects/command/src/concerns/subcommands.rb +102 -0
  109. data/projects/command/src/concerns/transactions.rb +81 -0
  110. data/projects/command/src/state_machine.rb +57 -0
  111. data/projects/command/src/transformed_command.rb +459 -0
  112. data/projects/command_connectors/lib/foobara/command_connectors.rb +12 -0
  113. data/projects/command_connectors/src/command_connector.rb +401 -0
  114. data/projects/command_connectors/src/command_registry/allowed_rule.rb +29 -0
  115. data/projects/command_connectors/src/command_registry/exposed_command.rb +140 -0
  116. data/projects/command_connectors/src/command_registry/exposed_domain.rb +30 -0
  117. data/projects/command_connectors/src/command_registry/exposed_organization.rb +30 -0
  118. data/projects/command_connectors/src/command_registry.rb +257 -0
  119. data/projects/command_connectors/src/commands/describe.rb +36 -0
  120. data/projects/command_connectors/src/commands/list_commands.rb +51 -0
  121. data/projects/command_connectors/src/commands/ping.rb +21 -0
  122. data/projects/command_connectors/src/commands/query_git_commit_info.rb +81 -0
  123. data/projects/command_connectors/src/request.rb +99 -0
  124. data/projects/command_connectors/src/response.rb +17 -0
  125. data/projects/command_connectors/src/serializer.rb +25 -0
  126. data/projects/command_connectors/src/serializers/aggregate_serializer.rb +32 -0
  127. data/projects/command_connectors/src/serializers/atomic_serializer.rb +25 -0
  128. data/projects/command_connectors/src/serializers/entities_to_primary_keys_serializer.rb +28 -0
  129. data/projects/command_connectors/src/serializers/errors_serializer.rb +18 -0
  130. data/projects/command_connectors/src/serializers/json_serializer.rb +20 -0
  131. data/projects/command_connectors/src/serializers/noop_serializer.rb +20 -0
  132. data/projects/command_connectors/src/serializers/record_store_serializer.rb +31 -0
  133. data/projects/command_connectors/src/serializers/success_serializer.rb +14 -0
  134. data/projects/command_connectors/src/serializers/yaml_serializer.rb +20 -0
  135. data/projects/command_connectors/src/transformers/auth_errors_transformer.rb +35 -0
  136. data/projects/command_connectors/src/transformers/load_aggregates_pre_commit_transformer.rb +36 -0
  137. data/projects/command_connectors_http/lib/foobara/command_connectors_http.rb +6 -0
  138. data/projects/command_connectors_http/src/http/commands/get_options.rb +16 -0
  139. data/projects/command_connectors_http/src/http/commands/help/presenter/command.rb +14 -0
  140. data/projects/command_connectors_http/src/http/commands/help/presenter/domain.rb +14 -0
  141. data/projects/command_connectors_http/src/http/commands/help/presenter/entity.rb +14 -0
  142. data/projects/command_connectors_http/src/http/commands/help/presenter/error.rb +14 -0
  143. data/projects/command_connectors_http/src/http/commands/help/presenter/model.rb +14 -0
  144. data/projects/command_connectors_http/src/http/commands/help/presenter/organization.rb +14 -0
  145. data/projects/command_connectors_http/src/http/commands/help/presenter/processor.rb +14 -0
  146. data/projects/command_connectors_http/src/http/commands/help/presenter/processor_class.rb +14 -0
  147. data/projects/command_connectors_http/src/http/commands/help/presenter/root.rb +14 -0
  148. data/projects/command_connectors_http/src/http/commands/help/presenter/type.rb +14 -0
  149. data/projects/command_connectors_http/src/http/commands/help/presenter.rb +162 -0
  150. data/projects/command_connectors_http/src/http/commands/help/templates/command.html.erb +11 -0
  151. data/projects/command_connectors_http/src/http/commands/help/templates/domain.html.erb +1 -0
  152. data/projects/command_connectors_http/src/http/commands/help/templates/entity.html.erb +1 -0
  153. data/projects/command_connectors_http/src/http/commands/help/templates/error.html.erb +1 -0
  154. data/projects/command_connectors_http/src/http/commands/help/templates/model.html.erb +1 -0
  155. data/projects/command_connectors_http/src/http/commands/help/templates/organization.html.erb +1 -0
  156. data/projects/command_connectors_http/src/http/commands/help/templates/processor.html.erb +1 -0
  157. data/projects/command_connectors_http/src/http/commands/help/templates/processor_class.html.erb +1 -0
  158. data/projects/command_connectors_http/src/http/commands/help/templates/root.html.erb +3 -0
  159. data/projects/command_connectors_http/src/http/commands/help/templates/type.html.erb +1 -0
  160. data/projects/command_connectors_http/src/http/commands/help.rb +98 -0
  161. data/projects/command_connectors_http/src/http/request.rb +98 -0
  162. data/projects/command_connectors_http/src/http/response.rb +14 -0
  163. data/projects/command_connectors_http/src/http.rb +84 -0
  164. data/projects/common/lib/foobara/common.rb +11 -0
  165. data/projects/common/src/data_path.rb +272 -0
  166. data/projects/common/src/error.rb +215 -0
  167. data/projects/common/src/error_collection.rb +97 -0
  168. data/projects/common/src/error_key.rb +168 -0
  169. data/projects/common/src/outcome.rb +101 -0
  170. data/projects/common/src/possible_error.rb +80 -0
  171. data/projects/common/src/runtime_error.rb +24 -0
  172. data/projects/concerns/lib/foobara/concerns.rb +1 -0
  173. data/projects/concerns/src/concern.rb +93 -0
  174. data/projects/delegate/lib/foobara/delegate.rb +1 -0
  175. data/projects/delegate/src/extensions/module.rb +12 -0
  176. data/projects/domain/lib/foobara/domain.rb +25 -0
  177. data/projects/domain/src/domain.rb +65 -0
  178. data/projects/domain/src/domain_mapper/registry.rb +47 -0
  179. data/projects/domain/src/domain_mapper.rb +162 -0
  180. data/projects/domain/src/domain_module_extension.rb +510 -0
  181. data/projects/domain/src/extensions/foobara.rb +69 -0
  182. data/projects/domain/src/global_domain.rb +14 -0
  183. data/projects/domain/src/global_organization.rb +12 -0
  184. data/projects/domain/src/is_manifestable.rb +68 -0
  185. data/projects/domain/src/manifestable.rb +12 -0
  186. data/projects/domain/src/module_extension.rb +122 -0
  187. data/projects/domain/src/organization.rb +52 -0
  188. data/projects/domain/src/organization_module_extension.rb +50 -0
  189. data/projects/entity/lib/foobara/entity.rb +27 -0
  190. data/projects/entity/src/concerns/associations.rb +241 -0
  191. data/projects/entity/src/concerns/attributes.rb +170 -0
  192. data/projects/entity/src/concerns/callbacks.rb +97 -0
  193. data/projects/entity/src/concerns/initialization.rb +127 -0
  194. data/projects/entity/src/concerns/persistence.rb +142 -0
  195. data/projects/entity/src/concerns/primary_key.rb +43 -0
  196. data/projects/entity/src/concerns/queries.rb +96 -0
  197. data/projects/entity/src/concerns/reflection.rb +51 -0
  198. data/projects/entity/src/concerns/transactions.rb +31 -0
  199. data/projects/entity/src/concerns/types.rb +31 -0
  200. data/projects/entity/src/entity.rb +61 -0
  201. data/projects/entity/src/extensions/builtin_types/entity/casters/hash.rb +33 -0
  202. data/projects/entity/src/extensions/builtin_types/entity/validators/attributes_declaration.rb +32 -0
  203. data/projects/entity/src/extensions/builtin_types/entity.rb +6 -0
  204. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/attributes_handler_desugarizer.rb +14 -0
  205. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/hash_desugarizer.rb +43 -0
  206. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/model_class_desugarizer.rb +21 -0
  207. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/primary_key_desugarizer.rb +19 -0
  208. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/to_type_transformer.rb +64 -0
  209. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/validate_primary_key_is_symbol.rb +35 -0
  210. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/validate_primary_key_present.rb +27 -0
  211. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/validate_primary_key_references_attribute.rb +36 -0
  212. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration.rb +11 -0
  213. data/projects/entity/src/new_prepend.rb +21 -0
  214. data/projects/entity/src/not_found_error.rb +72 -0
  215. data/projects/enumerated/lib/foobara/enumerated.rb +1 -0
  216. data/projects/enumerated/src/accessors.rb +61 -0
  217. data/projects/enumerated/src/values.rb +121 -0
  218. data/projects/foobara/lib/foobara/all.rb +44 -0
  219. data/projects/in_memory_crud_driver/lib/foobara/in_memory_crud_driver.rb +3 -0
  220. data/projects/in_memory_crud_driver/src/in_memory.rb +10 -0
  221. data/projects/in_memory_crud_driver_minimal/lib/foobara/in_memory_crud_driver_minimal.rb +1 -0
  222. data/projects/in_memory_crud_driver_minimal/src/in_memory_minimal.rb +113 -0
  223. data/projects/manifest/lib/foobara/manifest.rb +4 -0
  224. data/projects/manifest/src/foobara/manifest/array.rb +13 -0
  225. data/projects/manifest/src/foobara/manifest/attributes.rb +40 -0
  226. data/projects/manifest/src/foobara/manifest/base_manifest.rb +161 -0
  227. data/projects/manifest/src/foobara/manifest/command.rb +59 -0
  228. data/projects/manifest/src/foobara/manifest/domain.rb +43 -0
  229. data/projects/manifest/src/foobara/manifest/entity.rb +35 -0
  230. data/projects/manifest/src/foobara/manifest/error.rb +33 -0
  231. data/projects/manifest/src/foobara/manifest/model.rb +43 -0
  232. data/projects/manifest/src/foobara/manifest/organization.rb +45 -0
  233. data/projects/manifest/src/foobara/manifest/possible_error.rb +30 -0
  234. data/projects/manifest/src/foobara/manifest/processor.rb +11 -0
  235. data/projects/manifest/src/foobara/manifest/processor_class.rb +11 -0
  236. data/projects/manifest/src/foobara/manifest/root_manifest.rb +112 -0
  237. data/projects/manifest/src/foobara/manifest/type.rb +86 -0
  238. data/projects/manifest/src/foobara/manifest/type_declaration.rb +117 -0
  239. data/projects/model/lib/foobara/model.rb +23 -0
  240. data/projects/model/src/concerns/reflection.rb +22 -0
  241. data/projects/model/src/concerns/types.rb +104 -0
  242. data/projects/model/src/extensions/builtin_types/model/casters/hash.rb +23 -0
  243. data/projects/model/src/extensions/builtin_types/model/transformers/mutable.rb +26 -0
  244. data/projects/model/src/extensions/builtin_types/model/validators/attributes_declaration.rb +33 -0
  245. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/attributes_handler_desugarizer.rb +24 -0
  246. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/hash_desugarizer.rb +32 -0
  247. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/model_class_desugarizer.rb +119 -0
  248. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/to_type_transformer.rb +57 -0
  249. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration.rb +21 -0
  250. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/hash_desugarizer.rb +37 -0
  251. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/model_class_type_desugarizer.rb +25 -0
  252. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/mutable_validator.rb +46 -0
  253. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/normalize_mutable_attributes_desugarizer.rb +28 -0
  254. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/to_type_transformer.rb +27 -0
  255. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration.rb +31 -0
  256. data/projects/model/src/extensions/type_declarations/handlers/registered_type_declaration/model_class_desugarizer.rb +23 -0
  257. data/projects/model/src/model.rb +320 -0
  258. data/projects/monorepo/lib/foobara/monorepo/project.rb +52 -0
  259. data/projects/monorepo/lib/foobara/monorepo.rb +63 -0
  260. data/projects/namespace/lib/foobara/namespace.rb +4 -0
  261. data/projects/namespace/src/ambiguous_registry.rb +104 -0
  262. data/projects/namespace/src/base_registry.rb +66 -0
  263. data/projects/namespace/src/extensions/module.rb +5 -0
  264. data/projects/namespace/src/is_namespace.rb +352 -0
  265. data/projects/namespace/src/namespace/lookup_mode.rb +41 -0
  266. data/projects/namespace/src/namespace.rb +61 -0
  267. data/projects/namespace/src/namespace_helpers.rb +273 -0
  268. data/projects/namespace/src/prefixless_registry.rb +54 -0
  269. data/projects/namespace/src/scoped.rb +113 -0
  270. data/projects/namespace/src/unambiguous_registry.rb +65 -0
  271. data/projects/persistence/lib/foobara/persistence.rb +22 -0
  272. data/projects/persistence/src/entity_attributes_crud_driver.rb +241 -0
  273. data/projects/persistence/src/entity_base/table.rb +14 -0
  274. data/projects/persistence/src/entity_base/transaction/concerns/entity_callback_handling.rb +157 -0
  275. data/projects/persistence/src/entity_base/transaction/concerns/state_transitions.rb +83 -0
  276. data/projects/persistence/src/entity_base/transaction/concerns/transaction_tracking.rb +53 -0
  277. data/projects/persistence/src/entity_base/transaction/state_machine.rb +27 -0
  278. data/projects/persistence/src/entity_base/transaction.rb +163 -0
  279. data/projects/persistence/src/entity_base/transaction_table/concerns/queries.rb +42 -0
  280. data/projects/persistence/src/entity_base/transaction_table/concerns/record_tracking.rb +134 -0
  281. data/projects/persistence/src/entity_base/transaction_table.rb +620 -0
  282. data/projects/persistence/src/entity_base.rb +114 -0
  283. data/projects/persistence/src/persistence.rb +172 -0
  284. data/projects/state_machine/lib/foobara/state_machine.rb +1 -0
  285. data/projects/state_machine/src/callbacks.rb +158 -0
  286. data/projects/state_machine/src/log_entry.rb +13 -0
  287. data/projects/state_machine/src/state_machine.rb +91 -0
  288. data/projects/state_machine/src/sugar.rb +125 -0
  289. data/projects/state_machine/src/transition_log.rb +19 -0
  290. data/projects/state_machine/src/validations.rb +69 -0
  291. data/projects/thread_parent/lib/foobara/thread_parent.rb +1 -0
  292. data/projects/thread_parent/src/thread_parent.rb +38 -0
  293. data/projects/type_declarations/lib/foobara/type_declarations.rb +131 -0
  294. data/projects/type_declarations/src/attributes.rb +34 -0
  295. data/projects/type_declarations/src/caster.rb +7 -0
  296. data/projects/type_declarations/src/desugarizer.rb +25 -0
  297. data/projects/type_declarations/src/dsl/attributes.rb +199 -0
  298. data/projects/type_declarations/src/element_processor.rb +7 -0
  299. data/projects/type_declarations/src/error_extension.rb +73 -0
  300. data/projects/type_declarations/src/handlers/extend_array_type_declaration/array_desugarizer.rb +31 -0
  301. data/projects/type_declarations/src/handlers/extend_array_type_declaration/element_type_declaration_desugarizer.rb +37 -0
  302. data/projects/type_declarations/src/handlers/extend_array_type_declaration/to_type_transformer.rb +22 -0
  303. data/projects/type_declarations/src/handlers/extend_array_type_declaration/type_set_to_array_desugarizer.rb +36 -0
  304. data/projects/type_declarations/src/handlers/extend_array_type_declaration.rb +14 -0
  305. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/to_type_transformer.rb +28 -0
  306. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration.rb +20 -0
  307. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/dsl_desugarizer.rb +25 -0
  308. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/element_type_declarations_desugarizer.rb +34 -0
  309. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/hash_desugarizer.rb +60 -0
  310. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/to_type_transformer.rb +21 -0
  311. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration.rb +16 -0
  312. data/projects/type_declarations/src/handlers/extend_registered_type_declaration/to_type_transformer.rb +75 -0
  313. data/projects/type_declarations/src/handlers/extend_registered_type_declaration.rb +23 -0
  314. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/array_desugarizer.rb +30 -0
  315. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/to_type_transformer.rb +24 -0
  316. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration.rb +13 -0
  317. data/projects/type_declarations/src/handlers/registered_type_declaration/desugarizer_metadata_cleanup_desugarizer.rb +29 -0
  318. data/projects/type_declarations/src/handlers/registered_type_declaration/short_type_name_desugarizer.rb +65 -0
  319. data/projects/type_declarations/src/handlers/registered_type_declaration/strict_desugarizer.rb +32 -0
  320. data/projects/type_declarations/src/handlers/registered_type_declaration/strict_stringified_desugarizer.rb +39 -0
  321. data/projects/type_declarations/src/handlers/registered_type_declaration/symbol_desugarizer.rb +26 -0
  322. data/projects/type_declarations/src/handlers/registered_type_declaration/to_type_transformer.rb +28 -0
  323. data/projects/type_declarations/src/handlers/registered_type_declaration/type_desugarizer.rb +24 -0
  324. data/projects/type_declarations/src/handlers/registered_type_declaration.rb +26 -0
  325. data/projects/type_declarations/src/processor.rb +7 -0
  326. data/projects/type_declarations/src/to_type_transformer.rb +11 -0
  327. data/projects/type_declarations/src/transformer.rb +7 -0
  328. data/projects/type_declarations/src/type_builder.rb +112 -0
  329. data/projects/type_declarations/src/type_declaration_error.rb +9 -0
  330. data/projects/type_declarations/src/type_declaration_handler.rb +120 -0
  331. data/projects/type_declarations/src/type_declaration_handler_registry.rb +27 -0
  332. data/projects/type_declarations/src/type_declaration_validator.rb +19 -0
  333. data/projects/type_declarations/src/type_declarations.rb +128 -0
  334. data/projects/type_declarations/src/typed_transformer.rb +89 -0
  335. data/projects/type_declarations/src/validator.rb +7 -0
  336. data/projects/type_declarations/src/with_registries.rb +41 -0
  337. data/projects/types/lib/foobara/types.rb +11 -0
  338. data/projects/types/src/element_processor.rb +7 -0
  339. data/projects/types/src/extensions/error.rb +32 -0
  340. data/projects/types/src/type/concerns/reflection.rb +79 -0
  341. data/projects/types/src/type/concerns/supported_processor_registration.rb +56 -0
  342. data/projects/types/src/type.rb +375 -0
  343. data/projects/types/src/types.rb +4 -0
  344. data/projects/value/lib/foobara/value.rb +7 -0
  345. data/projects/value/src/caster.rb +84 -0
  346. data/projects/value/src/data_error.rb +27 -0
  347. data/projects/value/src/processor/casting.rb +123 -0
  348. data/projects/value/src/processor/multi.rb +63 -0
  349. data/projects/value/src/processor/pipeline.rb +27 -0
  350. data/projects/value/src/processor/runner.rb +38 -0
  351. data/projects/value/src/processor/selection.rb +90 -0
  352. data/projects/value/src/processor.rb +358 -0
  353. data/projects/value/src/transformer.rb +84 -0
  354. data/projects/value/src/validator.rb +53 -0
  355. data/projects/version/lib/foobara/version.rb +4 -0
  356. data/projects/version/src/version.rb +5 -0
  357. data/projects/weak_object_set/lib/foobara/weak_object_set.rb +3 -0
  358. data/projects/weak_object_set/src/weak_object_set.rb +163 -0
  359. metadata +445 -0
@@ -0,0 +1,241 @@
1
+ module Foobara
2
+ module Persistence
3
+ class EntityAttributesCrudDriver
4
+ attr_accessor :raw_connection, :tables
5
+
6
+ def initialize(connection_or_credentials = nil)
7
+ self.raw_connection = open_connection(connection_or_credentials)
8
+ self.tables = {}
9
+ end
10
+
11
+ # TODO: audit that this interface is correct
12
+ def open_connection(_connection_or_credentials)
13
+ # :nocov:
14
+ raise "subclass responsibility"
15
+ # :nocov:
16
+ end
17
+
18
+ def open_transaction
19
+ # :nocov:
20
+ raise "subclass responsibility"
21
+ # :nocov:
22
+ end
23
+
24
+ def flush_transaction(_raw_tx)
25
+ # :nocov:
26
+ raise "subclass responsibility"
27
+ # :nocov:
28
+ end
29
+
30
+ def revert_transaction(_raw_tx)
31
+ # :nocov:
32
+ raise "subclass responsibility"
33
+ # :nocov:
34
+ end
35
+
36
+ def rollback_transaction(_raw_tx)
37
+ # :nocov:
38
+ raise "subclass responsibility"
39
+ # :nocov:
40
+ end
41
+
42
+ def close_transaction(_raw_tx)
43
+ # :nocov:
44
+ raise "subclass responsibility"
45
+ # :nocov:
46
+ end
47
+
48
+ def table_for(entity_class)
49
+ key = entity_class.full_entity_name
50
+
51
+ tables[key] ||= self.class::Table.new(entity_class, self)
52
+ end
53
+
54
+ # TODO: relocate this to another file?
55
+ class Table
56
+ class CannotCrudError < StandardError
57
+ attr_accessor :record_id
58
+
59
+ def verb
60
+ match = /^Cannot(\w+)Error$/.match(Util.non_full_name(self.class))
61
+
62
+ unless match
63
+ # :nocov:
64
+ raise "Bad error name for #{self.class.name}"
65
+ # :nocov:
66
+ end
67
+
68
+ Util.underscore(match[1])
69
+ end
70
+
71
+ def initialize(record_id, submessage = nil)
72
+ self.record_id = record_id
73
+ message = "Could not #{verb} for id #{record_id.inspect}"
74
+
75
+ if submessage
76
+ message = "#{message}: #{submessage}"
77
+ end
78
+
79
+ super(message)
80
+ end
81
+ end
82
+
83
+ class CannotFindError < CannotCrudError; end
84
+ class CannotInsertError < CannotCrudError; end
85
+ class CannotUpdateError < CannotCrudError; end
86
+ class CannotDeleteError < CannotCrudError; end
87
+
88
+ attr_accessor :table_name, :entity_class, :raw_connection, :crud_driver
89
+
90
+ def initialize(entity_class, crud_driver, table_name = Util.underscore(entity_class.entity_name))
91
+ self.crud_driver = crud_driver
92
+ self.entity_class = entity_class
93
+ # what is this used for?
94
+ self.raw_connection = crud_driver.raw_connection
95
+ self.table_name = table_name
96
+ end
97
+
98
+ # CRUD
99
+ def select(_query_declaration)
100
+ # :nocov:
101
+ raise "subclass responsibility"
102
+ # :nocov:
103
+ end
104
+
105
+ def all
106
+ # :nocov:
107
+ raise "subclass responsibility"
108
+ # :nocov:
109
+ end
110
+
111
+ def first
112
+ all.first
113
+ end
114
+
115
+ def find(_record_id)
116
+ # :nocov:
117
+ raise "subclass responsibility"
118
+ # :nocov:
119
+ end
120
+
121
+ def find!(_record_id)
122
+ # :nocov:
123
+ raise "subclass responsibility"
124
+ # :nocov:
125
+ end
126
+
127
+ def find_many!(record_ids)
128
+ record_ids.each.lazy.map do |record_id|
129
+ find!(record_id)
130
+ end
131
+ end
132
+
133
+ def find_by_attribute_containing(attribute_name, value)
134
+ all.find do |found_attributes|
135
+ found_attributes[attribute_name]&.include?(value)
136
+ end
137
+ end
138
+
139
+ def find_all_by_attribute_any_of(attribute_name, values)
140
+ all.select do |attributes|
141
+ values.include?(attributes[attribute_name])
142
+ end
143
+ end
144
+
145
+ def find_all_by_attribute_containing_any_of(attribute_name, values)
146
+ all.select do |attributes|
147
+ attributes[attribute_name]&.any? do |attribute_value|
148
+ values.include?(attribute_value)
149
+ end
150
+ end
151
+ end
152
+
153
+ def find_by(attributes_filter)
154
+ all.find do |found_attributes|
155
+ matches_attributes_filter?(found_attributes, attributes_filter)
156
+ end
157
+ end
158
+
159
+ def find_many_by(attributes_filter)
160
+ Enumerator.new do |yielder|
161
+ all.each do |found_attributes|
162
+ if matches_attributes_filter?(found_attributes, attributes_filter)
163
+ yielder << found_attributes
164
+ end
165
+ end
166
+ end
167
+ end
168
+
169
+ def matches_attributes_filter?(attributes, attributes_filter)
170
+ attributes_filter.all? { |attribute_name, value| attributes[attribute_name] == value }
171
+ end
172
+
173
+ def insert(_attributes)
174
+ # :nocov:
175
+ raise "subclass responsibility"
176
+ # :nocov:
177
+ end
178
+
179
+ def insert_many(attributes_array)
180
+ # TODO: add a test for a driver that doesn't override this and remove these :nocov: comments
181
+ # :nocov:
182
+ attributes_array.each.lazy.map do |attributes|
183
+ insert(attributes)
184
+ end
185
+ # :nocov:
186
+ end
187
+
188
+ def update(_record)
189
+ # :nocov:
190
+ raise "subclass responsibility"
191
+ # :nocov:
192
+ end
193
+
194
+ def hard_delete(_record_id)
195
+ # :nocov:
196
+ raise "subclass responsibility"
197
+ # :nocov:
198
+ end
199
+
200
+ def hard_delete_many(record_ids)
201
+ # TODO: add a test for a driver that doesn't override this and remove these :nocov: comments
202
+ # :nocov:
203
+ record_ids.each.lazy.map do |record_id|
204
+ delete(record_id)
205
+ end
206
+ # :nocov:
207
+ end
208
+
209
+ def hard_delete_all!
210
+ # :nocov:
211
+ raise "subclass responsibility"
212
+ # :nocov:
213
+ end
214
+
215
+ def count
216
+ # :nocov:
217
+ raise "subclass responsibility"
218
+ # :nocov:
219
+ end
220
+
221
+ def exists?(record_id)
222
+ !!find(record_id)
223
+ end
224
+
225
+ def all_exist?(record_ids)
226
+ record_ids.all? do |record_id|
227
+ exists?(record_id)
228
+ end
229
+ end
230
+
231
+ def record_id_for(attributes)
232
+ attributes&.[](primary_key_attribute)
233
+ end
234
+
235
+ def primary_key_attribute
236
+ entity_class.primary_key_attribute
237
+ end
238
+ end
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,14 @@
1
+ module Foobara
2
+ module Persistence
3
+ class EntityBase
4
+ class Table
5
+ attr_accessor :table_name, :entity_base
6
+
7
+ def initialize(table_name, entity_base)
8
+ self.entity_base = entity_base
9
+ self.table_name = table_name
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,157 @@
1
+ module Foobara
2
+ module Persistence
3
+ class EntityBase
4
+ class Transaction
5
+ class CurrentTransactionIsClosedError < StandardError; end
6
+ class NoCurrentTransactionError < StandardError; end
7
+
8
+ module Concerns
9
+ # NOTE: not really a concern...
10
+ module EntityCallbackHandling
11
+ class << self
12
+ def reset_all
13
+ install!
14
+ end
15
+
16
+ def install!
17
+ # TODO: do all this in an install! method and make sure Entity.reset_all clears it.
18
+ Entity.after_dirtied do |record:, **|
19
+ transaction = Transaction.open_transaction_for(record)
20
+
21
+ unless transaction
22
+ raise NoCurrentTransactionError,
23
+ "Cannot modify #{record} because there's no current transaction"
24
+ end
25
+
26
+ unless transaction.open?
27
+ # :nocov:
28
+ raise CurrentTransactionIsClosedError,
29
+ "Cannot modify #{record} because current transaction is not open"
30
+ # :nocov:
31
+ end
32
+
33
+ transaction.updated(record)
34
+ end
35
+
36
+ Entity.after_undirtied do |record:, **|
37
+ transaction = Transaction.open_transaction_for(record)
38
+
39
+ unless transaction
40
+ # :nocov:
41
+ raise NoCurrentTransactionError,
42
+ "Cannot modify #{record} because there's no current transaction"
43
+ # :nocov:
44
+ end
45
+
46
+ unless transaction.open?
47
+ # :nocov:
48
+ raise CurrentTransactionIsClosedError,
49
+ "Cannot modify #{record} because current transaction is not open"
50
+ # :nocov:
51
+ end
52
+
53
+ transaction.updated(record)
54
+ end
55
+
56
+ Entity.after_hard_deleted do |record:, **|
57
+ transaction = Transaction.open_transaction_for(record)
58
+
59
+ unless transaction
60
+ # :nocov:
61
+ raise NoCurrentTransactionError,
62
+ "Cannot modify #{record} because there's no current transaction"
63
+ # :nocov:
64
+ end
65
+
66
+ unless transaction.open?
67
+ # :nocov:
68
+ raise CurrentTransactionIsClosedError,
69
+ "Cannot modify #{record} because current transaction is not open"
70
+ # :nocov:
71
+ end
72
+
73
+ transaction.hard_deleted(record)
74
+ end
75
+
76
+ Entity.after_unhard_deleted do |record:, **|
77
+ transaction = Transaction.open_transaction_for(record)
78
+
79
+ unless transaction
80
+ # :nocov:
81
+ raise NoCurrentTransactionError,
82
+ "Cannot modify #{record} because there's no current transaction"
83
+ # :nocov:
84
+ end
85
+
86
+ unless transaction.open?
87
+ # :nocov:
88
+ raise CurrentTransactionIsClosedError,
89
+ "Cannot modify #{record} because current transaction is not open"
90
+ # :nocov:
91
+ end
92
+
93
+ transaction.unhard_deleted(record)
94
+ end
95
+
96
+ Entity.after_initialized_loaded do |record:, **|
97
+ transaction = Persistence.current_transaction(record)
98
+ unless transaction
99
+ # :nocov:
100
+ raise NoCurrentTransactionError,
101
+ "Cannot initialize #{record} because there's no current transaction"
102
+ # :nocov:
103
+ end
104
+
105
+ unless transaction.open?
106
+ # :nocov:
107
+ raise CurrentTransactionIsClosedError,
108
+ "Cannot initialize #{record} because current transaction is not open"
109
+ # :nocov:
110
+ end
111
+ # TODO: we need a way to not blow up here in case of non-block form of transaction
112
+ transaction.track_loaded(record)
113
+ end
114
+
115
+ Entity.after_initialized_created do |record:, **|
116
+ transaction = Persistence.current_transaction(record)
117
+ unless transaction
118
+ raise NoCurrentTransactionError,
119
+ "Cannot initialize #{record} because there's no current transaction"
120
+ end
121
+
122
+ unless transaction.open?
123
+ # :nocov:
124
+ raise CurrentTransactionIsClosedError,
125
+ "Cannot initialize #{record} because current transaction is not open"
126
+ # :nocov:
127
+ end
128
+ # TODO: we need a way to not blow up here in case of non-block form of transaction
129
+ transaction.track_created(record)
130
+ end
131
+
132
+ Entity.after_initialized_thunk do |record:, **|
133
+ transaction = Persistence.current_transaction(record)
134
+ unless transaction
135
+ # :nocov:
136
+ raise NoCurrentTransactionError,
137
+ "Cannot initialize #{record} because there's no current transaction"
138
+ # :nocov:
139
+ end
140
+
141
+ unless transaction.open?
142
+ # :nocov:
143
+ raise CurrentTransactionIsClosedError,
144
+ "Cannot initialize #{record} because current transaction is not open"
145
+ # :nocov:
146
+ end
147
+ # TODO: we need a way to not blow up here in case of non-block form of transaction
148
+ transaction.track_unloaded_thunk(record)
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,83 @@
1
+ module Foobara
2
+ module Persistence
3
+ class EntityBase
4
+ class Transaction
5
+ # Used to communicate to enclosing transaction that execution has terminated and the transaction is borked
6
+ class RolledBack < StandardError; end
7
+
8
+ module Concerns
9
+ module StateTransitions
10
+ foobara_delegate :close!, :currently_open?, to: :state_machine
11
+
12
+ def open!
13
+ state_machine.open! do
14
+ self.raw_tx = entity_attributes_crud_driver.open_transaction
15
+ end
16
+ end
17
+
18
+ def flush!
19
+ state_machine.flush! do
20
+ each_table(&:validate!)
21
+ each_table(&:flush_created!)
22
+ each_table(&:flush_updated_and_hard_deleted!)
23
+ end
24
+ rescue => e
25
+ # :nocov:
26
+ rollback!(e)
27
+ raise
28
+ # :nocov:
29
+ end
30
+
31
+ # Should communicate somehow that this is only in-memory.
32
+ # TODO: support multiple-reverts for databases that support checkpoints
33
+ def revert!
34
+ state_machine.revert! do
35
+ each_table(&:revert!)
36
+ end
37
+ rescue => e
38
+ # :nocov:
39
+ rollback!(e)
40
+ raise
41
+ # :nocov:
42
+ end
43
+
44
+ def commit!
45
+ state_machine.commit! do
46
+ each_table(&:validate!)
47
+ each_table(&:flush_created!)
48
+ each_table(&:flush_updated_and_hard_deleted!)
49
+ entity_attributes_crud_driver.close_transaction(raw_tx)
50
+ end
51
+ rescue => e
52
+ # :nocov:
53
+ rollback!(e)
54
+ raise
55
+ # :nocov:
56
+ end
57
+
58
+ # TODO: this belongs elsewhere
59
+ def each_table(&)
60
+ tables.values.each(&)
61
+ end
62
+
63
+ def rollback!(because_of = nil)
64
+ state_machine.rollback! do
65
+ # TODO: raise error if already flushed and if crud_driver doesn't support true transactions
66
+ entity_attributes_crud_driver.rollback_transaction(raw_tx)
67
+ each_table(&:rollback!)
68
+ entity_attributes_crud_driver.close_transaction(raw_tx)
69
+ end
70
+
71
+ if !because_of && (self == entity_base.current_transaction)
72
+ raise RolledBack, "intentionally rolled back"
73
+ end
74
+ rescue
75
+ state_machine.error! if state_machine.currently_open?
76
+ raise
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,53 @@
1
+ module Foobara
2
+ module Persistence
3
+ class EntityBase
4
+ class Transaction
5
+ module Concerns
6
+ module TransactionTracking
7
+ include Concern
8
+
9
+ module ClassMethods
10
+ def install!
11
+ Transaction::StateMachine.register_transition_callback(:after,
12
+ transition: :open) do |state_machine:, **|
13
+ transaction = state_machine.owner
14
+ Transaction.open_transactions << transaction
15
+ end
16
+
17
+ Transaction::StateMachine.register_transition_callback(:after, to: :closed) do |state_machine:, **|
18
+ transaction = state_machine.owner
19
+ Transaction.open_transactions.delete(transaction)
20
+ end
21
+ end
22
+
23
+ def reset_all
24
+ @open_transactions = nil
25
+ end
26
+
27
+ def open_transactions
28
+ @open_transactions ||= Set.new
29
+ end
30
+
31
+ def open_transaction_for(record)
32
+ # let's check the current_transaction first since that usually will match
33
+ tx = Persistence.current_transaction(record)
34
+
35
+ if tx&.tracking?(record)
36
+ return tx
37
+ else
38
+ entity_base = record.class.entity_base
39
+
40
+ tx = open_transactions.find do |transaction|
41
+ transaction.entity_base == entity_base && transaction.tracking?(record)
42
+ end
43
+ end
44
+
45
+ tx
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ module Foobara
2
+ module Persistence
3
+ class EntityBase
4
+ class Transaction
5
+ class StateMachine < Foobara::StateMachine
6
+ # TODO: make these outer braces optional somehow
7
+ set_transition_map({
8
+ unopened: {
9
+ open: :open,
10
+ close: :closed
11
+ },
12
+ open: {
13
+ # TODO: maybe call this something involving "checkpoint"?
14
+ flush: :open,
15
+ revert: :open,
16
+ close: :closed,
17
+ # TODO: should we have intermediate states to quickly get out of the open state?
18
+ rollback: :closed,
19
+ commit: :closed,
20
+ error: :closed
21
+ }
22
+ })
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end