familia 2.0.0.pre19 → 2.0.0.pre22

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 (370) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/claude-code-review.yml +4 -9
  3. data/.github/workflows/code-smells.yml +64 -3
  4. data/.pre-commit-config.yaml +8 -6
  5. data/.reek.yml +10 -9
  6. data/.rubocop.yml +4 -0
  7. data/.talismanrc +5 -1
  8. data/CHANGELOG.rst +220 -112
  9. data/CLAUDE.md +28 -1
  10. data/Gemfile +1 -1
  11. data/Gemfile.lock +20 -17
  12. data/bin/try +16 -0
  13. data/bin/tryouts +16 -0
  14. data/docs/1106-participates_in-bidirectional-solution.md +129 -0
  15. data/docs/guides/encryption.md +486 -0
  16. data/docs/guides/feature-encrypted-fields.md +123 -7
  17. data/docs/guides/feature-expiration.md +161 -117
  18. data/docs/guides/feature-external-identifiers.md +415 -443
  19. data/docs/guides/feature-object-identifiers.md +400 -269
  20. data/docs/guides/feature-quantization.md +120 -6
  21. data/docs/guides/feature-relationships-indexing.md +318 -0
  22. data/docs/guides/feature-relationships-methods.md +146 -604
  23. data/docs/guides/feature-relationships-participation.md +263 -0
  24. data/docs/guides/feature-relationships.md +118 -136
  25. data/docs/guides/feature-system-devs.md +176 -693
  26. data/docs/guides/feature-system.md +119 -6
  27. data/docs/guides/feature-transient-fields.md +81 -0
  28. data/docs/guides/field-system.md +778 -0
  29. data/docs/guides/index.md +32 -15
  30. data/docs/guides/logging.md +187 -0
  31. data/docs/guides/optimized-loading.md +674 -0
  32. data/docs/guides/thread-safety-monitoring.md +61 -0
  33. data/docs/guides/{time-utilities.md → time-literals.md} +12 -12
  34. data/docs/migrating/v2.0.0-pre22.md +241 -0
  35. data/docs/overview.md +7 -9
  36. data/docs/reference/api-technical.md +267 -320
  37. data/examples/autoloader/mega_customer/features/deprecated_fields.rb +2 -0
  38. data/examples/autoloader/mega_customer/safe_dump_fields.rb +2 -0
  39. data/examples/autoloader/mega_customer.rb +2 -0
  40. data/examples/datatype_standalone.rb +4 -3
  41. data/examples/encrypted_fields.rb +2 -1
  42. data/examples/json_usage_patterns.rb +2 -0
  43. data/examples/relationships.rb +3 -0
  44. data/examples/safe_dump.rb +2 -1
  45. data/examples/sampling_demo.rb +53 -0
  46. data/examples/single_connection_transaction_confusions.rb +2 -1
  47. data/familia.gemspec +2 -1
  48. data/lib/familia/base.rb +2 -0
  49. data/lib/familia/connection/behavior.rb +2 -0
  50. data/lib/familia/connection/handlers.rb +2 -0
  51. data/lib/familia/connection/individual_command_proxy.rb +2 -0
  52. data/lib/familia/connection/middleware.rb +34 -24
  53. data/lib/familia/connection/operation_core.rb +3 -2
  54. data/lib/familia/connection/operations.rb +2 -0
  55. data/lib/familia/connection/pipelined_core.rb +3 -3
  56. data/lib/familia/connection/transaction_core.rb +69 -2
  57. data/lib/familia/connection.rb +18 -3
  58. data/lib/familia/data_type/class_methods.rb +3 -1
  59. data/lib/familia/data_type/connection.rb +2 -0
  60. data/lib/familia/data_type/database_commands.rb +2 -0
  61. data/lib/familia/data_type/serialization.rb +79 -52
  62. data/lib/familia/data_type/settings.rb +2 -0
  63. data/lib/familia/data_type/types/counter.rb +2 -0
  64. data/lib/familia/data_type/types/hashkey.rb +7 -5
  65. data/lib/familia/data_type/types/listkey.rb +2 -0
  66. data/lib/familia/data_type/types/lock.rb +2 -0
  67. data/lib/familia/data_type/types/sorted_set.rb +7 -10
  68. data/lib/familia/data_type/types/stringkey.rb +24 -0
  69. data/lib/familia/data_type/types/unsorted_set.rb +2 -0
  70. data/lib/familia/data_type.rb +2 -0
  71. data/lib/familia/encryption/encrypted_data.rb +4 -2
  72. data/lib/familia/encryption/manager.rb +2 -0
  73. data/lib/familia/encryption/provider.rb +2 -0
  74. data/lib/familia/encryption/providers/aes_gcm_provider.rb +2 -0
  75. data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +2 -0
  76. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +2 -0
  77. data/lib/familia/encryption/registry.rb +2 -0
  78. data/lib/familia/encryption/request_cache.rb +2 -0
  79. data/lib/familia/encryption.rb +9 -2
  80. data/lib/familia/errors.rb +2 -0
  81. data/lib/familia/features/autoloader.rb +2 -0
  82. data/lib/familia/features/encrypted_fields/concealed_string.rb +2 -0
  83. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +4 -0
  84. data/lib/familia/features/encrypted_fields.rb +2 -2
  85. data/lib/familia/features/expiration/extensions.rb +3 -1
  86. data/lib/familia/features/expiration.rb +12 -4
  87. data/lib/familia/features/external_identifier.rb +62 -7
  88. data/lib/familia/features/object_identifier.rb +49 -0
  89. data/lib/familia/features/quantization.rb +3 -1
  90. data/lib/familia/features/relationships/README.md +3 -1
  91. data/lib/familia/features/relationships/collection_operations.rb +2 -0
  92. data/lib/familia/features/relationships/indexing/multi_index_generators.rb +138 -9
  93. data/lib/familia/features/relationships/indexing/rebuild_strategies.rb +479 -0
  94. data/lib/familia/features/relationships/indexing/unique_index_generators.rb +97 -21
  95. data/lib/familia/features/relationships/indexing.rb +3 -0
  96. data/lib/familia/features/relationships/indexing_relationship.rb +3 -1
  97. data/lib/familia/features/relationships/participation/participant_methods.rb +131 -14
  98. data/lib/familia/features/relationships/participation/rebuild_strategies.md +41 -0
  99. data/lib/familia/features/relationships/participation/target_methods.rb +6 -6
  100. data/lib/familia/features/relationships/participation.rb +155 -69
  101. data/lib/familia/features/relationships/participation_membership.rb +69 -0
  102. data/lib/familia/features/relationships/participation_relationship.rb +34 -6
  103. data/lib/familia/features/relationships/score_encoding.rb +2 -0
  104. data/lib/familia/features/relationships.rb +5 -3
  105. data/lib/familia/features/safe_dump.rb +2 -0
  106. data/lib/familia/features/transient_fields/redacted_string.rb +2 -0
  107. data/lib/familia/features/transient_fields/single_use_redacted_string.rb +2 -0
  108. data/lib/familia/features/transient_fields/transient_field_type.rb +5 -3
  109. data/lib/familia/features/transient_fields.rb +2 -0
  110. data/lib/familia/features.rb +2 -0
  111. data/lib/familia/field_type.rb +3 -1
  112. data/lib/familia/horreum/connection.rb +17 -1
  113. data/lib/familia/horreum/database_commands.rb +8 -1
  114. data/lib/familia/horreum/definition.rb +16 -6
  115. data/lib/familia/horreum/management.rb +353 -52
  116. data/lib/familia/horreum/persistence.rb +179 -108
  117. data/lib/familia/horreum/related_fields.rb +2 -0
  118. data/lib/familia/horreum/serialization.rb +23 -4
  119. data/lib/familia/horreum/settings.rb +2 -0
  120. data/lib/familia/horreum/utils.rb +2 -0
  121. data/lib/familia/horreum.rb +15 -1
  122. data/lib/familia/identifier_extractor.rb +3 -1
  123. data/lib/familia/instrumentation.rb +156 -0
  124. data/lib/familia/json_serializer.rb +2 -0
  125. data/lib/familia/logging.rb +92 -32
  126. data/lib/familia/refinements/dear_json.rb +2 -0
  127. data/lib/familia/refinements/stylize_words.rb +2 -14
  128. data/lib/familia/refinements/time_literals.rb +2 -0
  129. data/lib/familia/refinements.rb +2 -0
  130. data/lib/familia/secure_identifier.rb +10 -2
  131. data/lib/familia/settings.rb +2 -0
  132. data/lib/familia/thread_safety/instrumented_mutex.rb +166 -0
  133. data/lib/familia/thread_safety/monitor.rb +328 -0
  134. data/lib/familia/utils.rb +13 -0
  135. data/lib/familia/verifiable_identifier.rb +3 -1
  136. data/lib/familia/version.rb +3 -1
  137. data/lib/familia.rb +31 -4
  138. data/lib/middleware/database_command_counter.rb +152 -0
  139. data/lib/middleware/database_logger.rb +295 -170
  140. data/lib/multi_result.rb +61 -31
  141. data/try/edge_cases/empty_identifiers_try.rb +2 -0
  142. data/try/edge_cases/hash_symbolization_try.rb +2 -0
  143. data/try/edge_cases/json_serialization_try.rb +2 -0
  144. data/try/edge_cases/legacy_data_detection/deserialization_edge_cases_try.rb +4 -0
  145. data/try/edge_cases/race_conditions_try.rb +4 -0
  146. data/try/edge_cases/reserved_keywords_try.rb +4 -0
  147. data/try/edge_cases/string_coercion_try.rb +2 -0
  148. data/try/edge_cases/ttl_side_effects_try.rb +4 -0
  149. data/try/features/count_any_edge_cases_try.rb +486 -0
  150. data/try/features/count_any_methods_try.rb +197 -0
  151. data/try/features/encrypted_fields/aad_protection_try.rb +4 -0
  152. data/try/features/encrypted_fields/concealed_string_core_try.rb +4 -0
  153. data/try/features/encrypted_fields/context_isolation_try.rb +4 -0
  154. data/try/features/encrypted_fields/encrypted_fields_core_try.rb +33 -0
  155. data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +4 -0
  156. data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +4 -0
  157. data/try/features/encrypted_fields/encrypted_fields_security_try.rb +4 -0
  158. data/try/features/encrypted_fields/error_conditions_try.rb +4 -0
  159. data/try/features/encrypted_fields/fresh_key_derivation_try.rb +4 -0
  160. data/try/features/encrypted_fields/fresh_key_try.rb +4 -0
  161. data/try/features/encrypted_fields/key_rotation_try.rb +4 -0
  162. data/try/features/encrypted_fields/memory_security_try.rb +4 -0
  163. data/try/features/encrypted_fields/missing_current_key_version_try.rb +4 -0
  164. data/try/features/encrypted_fields/nonce_uniqueness_try.rb +4 -0
  165. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +4 -0
  166. data/try/features/encrypted_fields/thread_safety_try.rb +4 -0
  167. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +4 -0
  168. data/try/features/encryption/config_persistence_try.rb +4 -0
  169. data/try/features/encryption/core_try.rb +4 -0
  170. data/try/features/encryption/instance_variable_scope_try.rb +4 -0
  171. data/try/features/encryption/module_loading_try.rb +4 -0
  172. data/try/features/encryption/providers/aes_gcm_provider_try.rb +4 -0
  173. data/try/features/encryption/providers/xchacha20_poly1305_provider_try.rb +4 -0
  174. data/try/features/encryption/roundtrip_validation_try.rb +4 -0
  175. data/try/features/encryption/secure_memory_handling_try.rb +4 -0
  176. data/try/features/expiration/expiration_try.rb +4 -0
  177. data/try/features/external_identifier/external_identifier_try.rb +305 -8
  178. data/try/features/feature_dependencies_try.rb +2 -0
  179. data/try/features/feature_improvements_try.rb +2 -0
  180. data/try/features/field_groups_try.rb +2 -0
  181. data/try/features/object_identifier/object_identifier_integration_try.rb +12 -9
  182. data/try/features/object_identifier/object_identifier_try.rb +140 -0
  183. data/try/features/quantization/quantization_try.rb +4 -0
  184. data/try/features/real_feature_integration_try.rb +2 -0
  185. data/try/features/relationships/indexing_commands_verification_try.rb +2 -0
  186. data/try/features/relationships/indexing_rebuild_try.rb +606 -0
  187. data/try/features/relationships/indexing_try.rb +2 -0
  188. data/try/features/relationships/participation_bidirectional_try.rb +242 -0
  189. data/try/features/relationships/participation_commands_verification_spec.rb +4 -0
  190. data/try/features/relationships/participation_commands_verification_try.rb +2 -0
  191. data/try/features/relationships/participation_performance_improvements_try.rb +11 -9
  192. data/try/features/relationships/participation_reverse_index_try.rb +15 -13
  193. data/try/features/relationships/participation_target_class_resolution_try.rb +209 -0
  194. data/try/features/relationships/participation_unresolved_target_try.rb +109 -0
  195. data/try/features/relationships/relationships_api_changes_try.rb +2 -0
  196. data/try/features/relationships/relationships_edge_cases_try.rb +4 -0
  197. data/try/features/relationships/relationships_performance_minimal_try.rb +4 -0
  198. data/try/features/relationships/relationships_performance_simple_try.rb +4 -0
  199. data/try/features/relationships/relationships_performance_try.rb +4 -0
  200. data/try/features/relationships/relationships_performance_working_try.rb +4 -0
  201. data/try/features/relationships/relationships_try.rb +6 -4
  202. data/try/features/safe_dump/safe_dump_advanced_try.rb +4 -0
  203. data/try/features/safe_dump/safe_dump_try.rb +4 -0
  204. data/try/features/transient_fields/redacted_string_try.rb +2 -0
  205. data/try/features/transient_fields/refresh_reset_try.rb +3 -0
  206. data/try/features/transient_fields/simple_refresh_test.rb +3 -0
  207. data/try/features/transient_fields/single_use_redacted_string_try.rb +2 -0
  208. data/try/features/transient_fields/transient_fields_core_try.rb +4 -0
  209. data/try/features/transient_fields/transient_fields_integration_try.rb +4 -0
  210. data/try/integration/connection/fiber_context_preservation_try.rb +4 -0
  211. data/try/integration/connection/handler_constraints_try.rb +4 -0
  212. data/try/integration/connection/isolated_dbclient_try.rb +4 -0
  213. data/try/integration/connection/middleware_reconnect_try.rb +2 -0
  214. data/try/integration/connection/operation_mode_guards_try.rb +4 -0
  215. data/try/integration/connection/pipeline_fallback_integration_try.rb +3 -0
  216. data/try/integration/connection/pools_try.rb +4 -0
  217. data/try/integration/connection/responsibility_chain_tracking_try.rb +4 -0
  218. data/try/integration/connection/transaction_fallback_integration_try.rb +4 -0
  219. data/try/integration/connection/transaction_mode_permissive_try.rb +4 -0
  220. data/try/integration/connection/transaction_mode_strict_try.rb +4 -0
  221. data/try/integration/connection/transaction_mode_warn_try.rb +4 -0
  222. data/try/integration/connection/transaction_modes_try.rb +4 -0
  223. data/try/integration/conventional_inheritance_try.rb +4 -0
  224. data/try/integration/create_method_try.rb +4 -0
  225. data/try/integration/cross_component_try.rb +4 -0
  226. data/try/integration/data_types/datatype_pipelines_try.rb +9 -3
  227. data/try/integration/data_types/datatype_transactions_try.rb +17 -7
  228. data/try/integration/database_consistency_try.rb +4 -0
  229. data/try/integration/familia_extended_try.rb +4 -0
  230. data/try/integration/familia_members_methods_try.rb +4 -0
  231. data/try/integration/models/customer_safe_dump_try.rb +4 -0
  232. data/try/integration/models/customer_try.rb +7 -3
  233. data/try/integration/models/datatype_base_try.rb +4 -0
  234. data/try/integration/models/familia_object_try.rb +4 -0
  235. data/try/integration/persistence_operations_try.rb +4 -0
  236. data/try/integration/relationships_persistence_round_trip_try.rb +17 -14
  237. data/try/integration/save_methods_consistency_try.rb +241 -0
  238. data/try/integration/scenarios_try.rb +4 -0
  239. data/try/integration/secure_identifier_try.rb +4 -0
  240. data/try/integration/transaction_safety_core_try.rb +176 -0
  241. data/try/integration/transaction_safety_workflow_try.rb +291 -0
  242. data/try/integration/verifiable_identifier_try.rb +4 -0
  243. data/try/investigation/pipeline_routing/README.md +228 -0
  244. data/try/performance/benchmarks_try.rb +4 -0
  245. data/try/performance/transaction_safety_benchmark_try.rb +238 -0
  246. data/try/support/benchmarks/deserialization_benchmark.rb +3 -1
  247. data/try/support/benchmarks/deserialization_correctness_test.rb +3 -1
  248. data/try/support/debugging/cache_behavior_tracer.rb +4 -0
  249. data/try/support/debugging/debug_aad_process.rb +3 -0
  250. data/try/support/debugging/debug_concealed_internal.rb +3 -0
  251. data/try/support/debugging/debug_concealed_reveal.rb +3 -0
  252. data/try/support/debugging/debug_context_aad.rb +3 -0
  253. data/try/support/debugging/debug_context_simple.rb +3 -0
  254. data/try/support/debugging/debug_cross_context.rb +3 -0
  255. data/try/support/debugging/debug_database_load.rb +3 -0
  256. data/try/support/debugging/debug_encrypted_json_check.rb +3 -0
  257. data/try/support/debugging/debug_encrypted_json_step_by_step.rb +3 -0
  258. data/try/support/debugging/debug_exists_lifecycle.rb +3 -0
  259. data/try/support/debugging/debug_field_decrypt.rb +3 -0
  260. data/try/support/debugging/debug_fresh_cross_context.rb +3 -0
  261. data/try/support/debugging/debug_load_path.rb +3 -0
  262. data/try/support/debugging/debug_method_definition.rb +3 -0
  263. data/try/support/debugging/debug_method_resolution.rb +3 -0
  264. data/try/support/debugging/debug_minimal.rb +3 -0
  265. data/try/support/debugging/debug_provider.rb +3 -0
  266. data/try/support/debugging/debug_secure_behavior.rb +3 -0
  267. data/try/support/debugging/debug_string_class.rb +3 -0
  268. data/try/support/debugging/debug_test.rb +3 -0
  269. data/try/support/debugging/debug_test_design.rb +3 -0
  270. data/try/support/debugging/encryption_method_tracer.rb +4 -0
  271. data/try/support/debugging/provider_diagnostics.rb +4 -0
  272. data/try/support/helpers/test_cleanup.rb +4 -0
  273. data/try/support/helpers/test_helpers.rb +5 -0
  274. data/try/support/memory/memory_basic_test.rb +4 -0
  275. data/try/support/memory/memory_detailed_test.rb +4 -0
  276. data/try/support/memory/memory_search_for_string.rb +4 -0
  277. data/try/support/memory/test_actual_redactedstring_protection.rb +4 -0
  278. data/try/support/prototypes/atomic_saves_v1_context_proxy.rb +4 -0
  279. data/try/support/prototypes/atomic_saves_v2_connection_switching.rb +4 -0
  280. data/try/support/prototypes/atomic_saves_v3_connection_pool.rb +4 -0
  281. data/try/support/prototypes/atomic_saves_v4.rb +4 -0
  282. data/try/support/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -0
  283. data/try/support/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
  284. data/try/support/prototypes/pooling/configurable_stress_test.rb +4 -0
  285. data/try/support/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
  286. data/try/support/prototypes/pooling/lib/connection_pool_metrics.rb +4 -0
  287. data/try/support/prototypes/pooling/lib/connection_pool_stress_test.rb +4 -0
  288. data/try/support/prototypes/pooling/lib/connection_pool_threading_models.rb +4 -0
  289. data/try/support/prototypes/pooling/lib/visualize_stress_results.rb +4 -2
  290. data/try/support/prototypes/pooling/pool_siege.rb +4 -2
  291. data/try/support/prototypes/pooling/run_stress_tests.rb +4 -2
  292. data/try/thread_safety/README.md +496 -0
  293. data/try/thread_safety/class_connection_chain_race_try.rb +265 -0
  294. data/try/thread_safety/connection_chain_race_try.rb +148 -0
  295. data/try/thread_safety/encryption_manager_cache_race_try.rb +166 -0
  296. data/try/thread_safety/feature_registry_race_try.rb +226 -0
  297. data/try/thread_safety/fiber_pipeline_isolation_try.rb +235 -0
  298. data/try/thread_safety/fiber_transaction_isolation_try.rb +208 -0
  299. data/try/thread_safety/field_registration_race_try.rb +222 -0
  300. data/try/thread_safety/logger_initialization_race_try.rb +170 -0
  301. data/try/thread_safety/middleware_registration_race_try.rb +154 -0
  302. data/try/thread_safety/module_config_race_try.rb +175 -0
  303. data/try/thread_safety/secure_identifier_cache_race_try.rb +226 -0
  304. data/try/unit/core/autoloader_try.rb +4 -0
  305. data/try/unit/core/base_enhancements_try.rb +4 -0
  306. data/try/unit/core/connection_try.rb +4 -0
  307. data/try/unit/core/errors_try.rb +4 -0
  308. data/try/unit/core/extensions_try.rb +4 -0
  309. data/try/unit/core/familia_logger_try.rb +2 -0
  310. data/try/unit/core/familia_try.rb +4 -0
  311. data/try/unit/core/middleware_sampling_try.rb +335 -0
  312. data/try/unit/core/middleware_test_helpers_bug_try.rb +58 -0
  313. data/try/unit/core/middleware_thread_safety_try.rb +245 -0
  314. data/try/unit/core/middleware_try.rb +4 -0
  315. data/try/unit/core/settings_try.rb +4 -0
  316. data/try/unit/core/time_utils_try.rb +4 -0
  317. data/try/unit/core/tools_try.rb +4 -0
  318. data/try/unit/core/utils_try.rb +37 -0
  319. data/try/unit/data_types/boolean_try.rb +39 -22
  320. data/try/unit/data_types/counter_try.rb +4 -0
  321. data/try/unit/data_types/datatype_base_try.rb +4 -0
  322. data/try/unit/data_types/hash_try.rb +6 -2
  323. data/try/unit/data_types/list_try.rb +4 -0
  324. data/try/unit/data_types/lock_try.rb +4 -0
  325. data/try/unit/data_types/serialization_try.rb +386 -0
  326. data/try/unit/data_types/sorted_set_try.rb +4 -0
  327. data/try/unit/data_types/sorted_set_zadd_options_try.rb +4 -0
  328. data/try/unit/data_types/string_try.rb +4 -0
  329. data/try/unit/data_types/unsortedset_try.rb +4 -0
  330. data/try/unit/familia_resolve_class_try.rb +116 -0
  331. data/try/unit/horreum/auto_indexing_on_save_try.rb +5 -1
  332. data/try/unit/horreum/automatic_index_validation_try.rb +2 -0
  333. data/try/unit/horreum/base_try.rb +4 -0
  334. data/try/unit/horreum/class_methods_try.rb +4 -0
  335. data/try/unit/horreum/commands_try.rb +4 -0
  336. data/try/unit/horreum/defensive_initialization_try.rb +4 -0
  337. data/try/unit/horreum/destroy_related_fields_cleanup_try.rb +6 -1
  338. data/try/unit/horreum/enhanced_conflict_handling_try.rb +4 -0
  339. data/try/unit/horreum/field_categories_try.rb +4 -0
  340. data/try/unit/horreum/field_definition_try.rb +4 -0
  341. data/try/unit/horreum/initialization_try.rb +4 -0
  342. data/try/unit/horreum/json_type_preservation_try.rb +2 -0
  343. data/try/unit/horreum/optimized_loading_try.rb +156 -0
  344. data/try/unit/horreum/relations_try.rb +4 -0
  345. data/try/unit/horreum/serialization_persistent_fields_try.rb +4 -0
  346. data/try/unit/horreum/serialization_try.rb +4 -0
  347. data/try/unit/horreum/settings_try.rb +4 -0
  348. data/try/unit/horreum/unique_index_edge_cases_try.rb +4 -0
  349. data/try/unit/horreum/unique_index_guard_validation_try.rb +2 -0
  350. data/try/unit/middleware/database_command_counter_methods_try.rb +139 -0
  351. data/try/unit/middleware/database_logger_methods_try.rb +251 -0
  352. data/try/unit/refinements/dear_json_array_methods_try.rb +4 -0
  353. data/try/unit/refinements/dear_json_hash_methods_try.rb +4 -0
  354. data/try/unit/refinements/time_literals_numeric_methods_try.rb +4 -0
  355. data/try/unit/refinements/time_literals_string_methods_try.rb +4 -0
  356. data/try/unit/thread_safety_monitor_try.rb +149 -0
  357. metadata +69 -17
  358. data/.github/workflows/code-quality.yml +0 -138
  359. data/changelog.d/20251011_012003_delano_159_datatype_transaction_pipeline_support.rst +0 -91
  360. data/changelog.d/20251011_203905_delano_next.rst +0 -30
  361. data/changelog.d/20251011_212633_delano_next.rst +0 -13
  362. data/changelog.d/20251011_221253_delano_next.rst +0 -26
  363. data/docs/archive/FAMILIA_RELATIONSHIPS.md +0 -210
  364. data/docs/archive/FAMILIA_TECHNICAL.md +0 -823
  365. data/docs/archive/FAMILIA_UPDATE.md +0 -226
  366. data/docs/archive/README.md +0 -64
  367. data/docs/archive/api-reference.md +0 -333
  368. data/docs/guides/core-field-system.md +0 -806
  369. data/docs/guides/implementation.md +0 -276
  370. data/docs/guides/security-model.md +0 -183
@@ -0,0 +1,386 @@
1
+ # try/unit/data_types/serialization_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
5
+ # Test coverage for DataType serialization/deserialization behavior
6
+ # Issue #190: Unify DataType and Horreum serialization for type preservation
7
+
8
+ require_relative '../../support/helpers/test_helpers'
9
+
10
+ Familia.debug = false
11
+
12
+ # Create test instances
13
+ @bone = Bone.new('serialize_test_token')
14
+
15
+ # ========================================
16
+ # DataType Serialization Behavior (Issue #190)
17
+ # Now uses JSON serialization for type preservation
18
+ # ========================================
19
+
20
+ ## HashKey stores string values correctly
21
+ @bone.props['string_field'] = 'hello'
22
+ @bone.props['string_field']
23
+ #=> 'hello'
24
+
25
+ ## HashKey stores integer with type preservation
26
+ @bone.props['int_field'] = 42
27
+ @bone.props['int_field']
28
+ #=> 42
29
+
30
+ ## HashKey stores float with type preservation
31
+ @bone.props['float_field'] = 3.14
32
+ @bone.props['float_field']
33
+ #=> 3.14
34
+
35
+ ## HashKey stores symbol as string (symbols serialize to strings in JSON)
36
+ @bone.props['symbol_field'] = :active
37
+ @bone.props['symbol_field']
38
+ #=> 'active'
39
+
40
+ ## HashKey stores boolean true with type preservation
41
+ @bone.props['bool_true'] = true
42
+ @bone.props['bool_true']
43
+ #=> true
44
+
45
+ ## HashKey stores boolean true as TrueClass
46
+ @bone.props['bool_true'].class
47
+ #=> TrueClass
48
+
49
+ ## HashKey stores boolean false with type preservation
50
+ @bone.props['bool_false'] = false
51
+ @bone.props['bool_false']
52
+ #=> false
53
+
54
+ ## HashKey stores boolean false as FalseClass
55
+ @bone.props['bool_false'].class
56
+ #=> FalseClass
57
+
58
+ ## HashKey stores nil with type preservation
59
+ @bone.props['nil_field'] = nil
60
+ @bone.props['nil_field']
61
+ #=> nil
62
+
63
+ ## HashKey stores hash with type preservation
64
+ @bone.props['hash_field'] = { 'key' => 'value' }
65
+ @bone.props['hash_field']
66
+ #=> {'key'=>'value'}
67
+
68
+ ## HashKey stores array with type preservation
69
+ @bone.props['array_field'] = [1, 2, 3]
70
+ @bone.props['array_field']
71
+ #=> [1, 2, 3]
72
+
73
+ # ========================================
74
+ # List Serialization Behavior
75
+ # ========================================
76
+
77
+ ## List stores string values correctly
78
+ @bone.owners.delete!
79
+ @bone.owners.push('owner1')
80
+ @bone.owners.first
81
+ #=> 'owner1'
82
+
83
+ ## List stores integer with type preservation
84
+ @bone.owners.delete!
85
+ @bone.owners.push(123)
86
+ @bone.owners.first
87
+ #=> 123
88
+
89
+ ## List stores boolean with type preservation
90
+ @bone.owners.delete!
91
+ @bone.owners.push(true)
92
+ @bone.owners.first
93
+ #=> true
94
+
95
+ ## List stores nil with type preservation
96
+ @bone.owners.delete!
97
+ @bone.owners.push(nil)
98
+ @bone.owners.first
99
+ #=> nil
100
+
101
+ # ========================================
102
+ # Set Serialization Behavior
103
+ # ========================================
104
+
105
+ ## Set stores string values correctly
106
+ @bone.tags.delete!
107
+ @bone.tags.add('tag1')
108
+ @bone.tags.members.include?('tag1')
109
+ #=> true
110
+
111
+ ## Set stores integer with type preservation
112
+ @bone.tags.delete!
113
+ @bone.tags.add(42)
114
+ @bone.tags.members.include?(42)
115
+ #=> true
116
+
117
+ ## Set stores boolean with type preservation
118
+ @bone.tags.delete!
119
+ @bone.tags.add(true)
120
+ @bone.tags.members.include?(true)
121
+ #=> true
122
+
123
+ # ========================================
124
+ # SortedSet Serialization Behavior
125
+ # ========================================
126
+
127
+ ## SortedSet stores string values correctly
128
+ @bone.metrics.delete!
129
+ @bone.metrics.add('metric1', 1.0)
130
+ @bone.metrics.members.include?('metric1')
131
+ #=> true
132
+
133
+ ## SortedSet stores integer member with type preservation
134
+ @bone.metrics.delete!
135
+ @bone.metrics.add(999, 1.0)
136
+ @bone.metrics.members.include?(999)
137
+ #=> true
138
+
139
+ ## SortedSet stores boolean member with type preservation
140
+ @bone.metrics.delete!
141
+ @bone.metrics.add(true, 1.0)
142
+ @bone.metrics.members.include?(true)
143
+ #=> true
144
+
145
+ # ========================================
146
+ # Horreum Field Serialization (for comparison)
147
+ # Uses JSON encoding - type preserved
148
+ # ========================================
149
+
150
+ ## Horreum field stores string with JSON encoding
151
+ @customer = Customer.new
152
+ @customer.custid = 'serialization_test'
153
+ @customer.role = 'admin'
154
+ @customer.save
155
+ loaded = Customer.find_by_id('serialization_test')
156
+ loaded.role
157
+ #=> 'admin'
158
+
159
+ ## Horreum field stores boolean true (JSON encoded)
160
+ @customer.verified = true
161
+ @customer.save
162
+ @loaded_customer = Customer.find_by_id('serialization_test')
163
+ @loaded_customer.verified
164
+ #=> true
165
+
166
+ ## Horreum verified field is actually boolean, not string
167
+ @loaded_customer.verified.class
168
+ #=> TrueClass
169
+
170
+ ## Horreum field stores boolean false (JSON encoded)
171
+ @customer.reset_requested = false
172
+ @customer.save
173
+ @loaded_customer2 = Customer.find_by_id('serialization_test')
174
+ @loaded_customer2.reset_requested
175
+ #=> false
176
+
177
+ ## Horreum reset_requested field is actually boolean, not string
178
+ @loaded_customer2.reset_requested.class
179
+ #=> FalseClass
180
+
181
+ # ========================================
182
+ # Type Round-Trip Comparison (Unified Behavior)
183
+ # ========================================
184
+
185
+ ## Integer round-trip in HashKey now preserves type (Issue #190)
186
+ @bone.props['roundtrip_int'] = 100
187
+ retrieved = @bone.props['roundtrip_int']
188
+ retrieved.class
189
+ #=> Integer
190
+
191
+ ## Boolean round-trip in HashKey preserves type
192
+ @bone.props['roundtrip_bool'] = true
193
+ @bone.props['roundtrip_bool'].class
194
+ #=> TrueClass
195
+
196
+ ## DataType and Horreum now use same JSON serialization
197
+ @session = Session.new
198
+ @session.sessid = 'roundtrip_test'
199
+ # Both DataType and Horreum fields now preserve types consistently
200
+
201
+ # ========================================
202
+ # Horreum serialize_value Comprehensive Tests
203
+ # (Issue #190: Document behavior for unification)
204
+ # ========================================
205
+
206
+ ## Horreum serialize_value: string gets JSON encoded with quotes
207
+ @customer.serialize_value('hello')
208
+ #=> '"hello"'
209
+
210
+ ## Horreum serialize_value: empty string gets JSON encoded
211
+ @customer.serialize_value('')
212
+ #=> '""'
213
+
214
+ ## Horreum serialize_value: integer becomes JSON number (no quotes)
215
+ @customer.serialize_value(42)
216
+ #=> '42'
217
+
218
+ ## Horreum serialize_value: zero becomes JSON number
219
+ @customer.serialize_value(0)
220
+ #=> '0'
221
+
222
+ ## Horreum serialize_value: negative integer
223
+ @customer.serialize_value(-99)
224
+ #=> '-99'
225
+
226
+ ## Horreum serialize_value: float becomes JSON number
227
+ @customer.serialize_value(3.14159)
228
+ #=> '3.14159'
229
+
230
+ ## Horreum serialize_value: boolean true becomes JSON true
231
+ @customer.serialize_value(true)
232
+ #=> 'true'
233
+
234
+ ## Horreum serialize_value: boolean false becomes JSON false
235
+ @customer.serialize_value(false)
236
+ #=> 'false'
237
+
238
+ ## Horreum serialize_value: nil becomes JSON null
239
+ @customer.serialize_value(nil)
240
+ #=> 'null'
241
+
242
+ ## Horreum serialize_value: symbol becomes JSON string
243
+ @customer.serialize_value(:active)
244
+ #=> '"active"'
245
+
246
+ ## Horreum serialize_value: hash becomes JSON object
247
+ @customer.serialize_value({ name: 'test', count: 5 })
248
+ #=> '{"name":"test","count":5}'
249
+
250
+ ## Horreum serialize_value: array becomes JSON array
251
+ @customer.serialize_value([1, 'two', true, nil])
252
+ #=> '[1,"two",true,null]'
253
+
254
+ ## Horreum serialize_value: nested structures work
255
+ @customer.serialize_value({ users: [{ id: 1 }, { id: 2 }] })
256
+ #=> '{"users":[{"id":1},{"id":2}]}'
257
+
258
+ # ========================================
259
+ # Horreum deserialize_value Comprehensive Tests
260
+ # ========================================
261
+
262
+ ## Horreum deserialize_value: JSON string becomes Ruby string
263
+ @customer.deserialize_value('"hello"')
264
+ #=> 'hello'
265
+
266
+ ## Horreum deserialize_value: JSON number becomes Ruby integer
267
+ @customer.deserialize_value('42')
268
+ #=> 42
269
+
270
+ ## Horreum deserialize_value: JSON number is actually Integer class
271
+ @customer.deserialize_value('42').class
272
+ #=> Integer
273
+
274
+ ## Horreum deserialize_value: JSON float becomes Ruby float
275
+ @customer.deserialize_value('3.14159')
276
+ #=> 3.14159
277
+
278
+ ## Horreum deserialize_value: JSON float is actually Float class
279
+ @customer.deserialize_value('3.14159').class
280
+ #=> Float
281
+
282
+ ## Horreum deserialize_value: JSON true becomes Ruby true
283
+ @customer.deserialize_value('true')
284
+ #=> true
285
+
286
+ ## Horreum deserialize_value: JSON true is TrueClass
287
+ @customer.deserialize_value('true').class
288
+ #=> TrueClass
289
+
290
+ ## Horreum deserialize_value: JSON false becomes Ruby false
291
+ @customer.deserialize_value('false')
292
+ #=> false
293
+
294
+ ## Horreum deserialize_value: JSON false is FalseClass
295
+ @customer.deserialize_value('false').class
296
+ #=> FalseClass
297
+
298
+ ## Horreum deserialize_value: JSON null becomes Ruby nil
299
+ @customer.deserialize_value('null')
300
+ #=> nil
301
+
302
+ ## Horreum deserialize_value: JSON object becomes Ruby hash
303
+ @customer.deserialize_value('{"name":"test","count":5}')
304
+ #=> {"name"=>"test", "count"=>5}
305
+
306
+ ## Horreum deserialize_value: JSON array becomes Ruby array
307
+ @customer.deserialize_value('[1,"two",true,null]')
308
+ #=> [1, "two", true, nil]
309
+
310
+ ## Horreum deserialize_value: nil input returns nil
311
+ @customer.deserialize_value(nil)
312
+ #=> nil
313
+
314
+ ## Horreum deserialize_value: empty string returns nil
315
+ @customer.deserialize_value('')
316
+ #=> nil
317
+
318
+ ## Horreum deserialize_value: plain unquoted string (legacy data) returns as-is
319
+ # This handles data stored before JSON encoding was used
320
+ @customer.deserialize_value('plain string without quotes')
321
+ #=> 'plain string without quotes'
322
+
323
+ # ========================================
324
+ # Familia Object Serialization (shared behavior)
325
+ # ========================================
326
+
327
+ ## Horreum serialize_value: string value gets JSON encoded
328
+ # When storing a value from another Familia object's field
329
+ @ref_customer = Customer.new('reference_test@example.com')
330
+ @ref_customer.custid = 'reference_test@example.com'
331
+ # Note: Horreum.serialize_value uses JsonSerializer.dump, which JSON-encodes
332
+ # all values, including strings. This is different from DataType#serialize_value,
333
+ # which has special handling for Familia objects.
334
+ @customer.serialize_value(@ref_customer.custid)
335
+ #=> '"reference_test@example.com"'
336
+
337
+ # ========================================
338
+ # Round-trip Type Preservation Tests
339
+ # ========================================
340
+
341
+ ## Round-trip: integer preserves type through Horreum serialization
342
+ serialized = @customer.serialize_value(42)
343
+ @customer.deserialize_value(serialized)
344
+ #=> 42
345
+
346
+ ## Round-trip: integer class preserved
347
+ serialized = @customer.serialize_value(42)
348
+ @customer.deserialize_value(serialized).class
349
+ #=> Integer
350
+
351
+ ## Round-trip: boolean true preserves type
352
+ serialized = @customer.serialize_value(true)
353
+ @customer.deserialize_value(serialized)
354
+ #=> true
355
+
356
+ ## Round-trip: boolean true class preserved
357
+ serialized = @customer.serialize_value(true)
358
+ @customer.deserialize_value(serialized).class
359
+ #=> TrueClass
360
+
361
+ ## Round-trip: boolean false preserves type
362
+ serialized = @customer.serialize_value(false)
363
+ @customer.deserialize_value(serialized)
364
+ #=> false
365
+
366
+ ## Round-trip: nil preserves type
367
+ serialized = @customer.serialize_value(nil)
368
+ @customer.deserialize_value(serialized)
369
+ #=> nil
370
+
371
+ ## Round-trip: hash preserves structure
372
+ serialized = @customer.serialize_value({ active: true, count: 10 })
373
+ @customer.deserialize_value(serialized)
374
+ #=> {"active"=>true, "count"=>10}
375
+
376
+ ## Round-trip: array preserves structure and types
377
+ serialized = @customer.serialize_value([1, 'two', true, nil, 3.5])
378
+ @customer.deserialize_value(serialized)
379
+ #=> [1, "two", true, nil, 3.5]
380
+
381
+ # Cleanup
382
+ @bone.props.delete!
383
+ @bone.owners.delete!
384
+ @bone.tags.delete!
385
+ @bone.metrics.delete!
386
+ @customer.destroy! rescue nil
@@ -1,3 +1,7 @@
1
+ # try/unit/data_types/sorted_set_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/data_types/sorted_set_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/unit/data_types/sorted_set_zadd_options_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/data_type/sorted_set_zadd_options_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/unit/data_types/string_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/data_types/string_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/unit/data_types/unsortedset_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/data_types/unsortedset_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -0,0 +1,116 @@
1
+ # try/unit/familia_resolve_class_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
5
+ # Unit tests for Familia.resolve_class method
6
+ #
7
+ # This test ensures the public API for resolving class references works
8
+ # correctly across different input types (Class, Symbol, String).
9
+ #
10
+ # Related to the fix for NoMethodError in participates_in where the private
11
+ # method member_by_config_name was being called directly instead of using
12
+ # the public resolve_class API.
13
+
14
+ require_relative '../support/helpers/test_helpers'
15
+
16
+ # Test class for resolution
17
+ class ResolveTestClass < Familia::Horreum
18
+ identifier_field :id
19
+ field :id
20
+ field :name
21
+ end
22
+
23
+ # Test class in module for modularized class resolution
24
+ module ResolveTestModule
25
+ class ModularClass < Familia::Horreum
26
+ identifier_field :id
27
+ field :id
28
+ end
29
+ end
30
+
31
+ ## Test resolve_class with Class object returns the class unchanged
32
+ @resolved_class = Familia.resolve_class(ResolveTestClass)
33
+ @resolved_class == ResolveTestClass
34
+ #=> true
35
+
36
+ ## Test resolve_class with Symbol returns the correct class
37
+ @resolved_symbol = Familia.resolve_class(:ResolveTestClass)
38
+ @resolved_symbol == ResolveTestClass
39
+ #=> true
40
+
41
+ ## Test resolve_class with String returns the correct class
42
+ @resolved_string = Familia.resolve_class('ResolveTestClass')
43
+ @resolved_string == ResolveTestClass
44
+ #=> true
45
+
46
+ ## Test resolve_class with PascalCase symbol works
47
+ @resolved_pascal_sym = Familia.resolve_class(:ResolveTestClass)
48
+ @resolved_pascal_sym == ResolveTestClass
49
+ #=> true
50
+
51
+ ## Test resolve_class with PascalCase string works
52
+ @resolved_pascal_str = Familia.resolve_class('ResolveTestClass')
53
+ @resolved_pascal_str == ResolveTestClass
54
+ #=> true
55
+
56
+ ## Test resolve_class with snake_case symbol works
57
+ @resolved_snake = Familia.resolve_class(:resolve_test_class)
58
+ @resolved_snake == ResolveTestClass
59
+ #=> true
60
+
61
+ ## Test resolve_class with snake_case string works
62
+ @resolved_snake_str = Familia.resolve_class('resolve_test_class')
63
+ @resolved_snake_str == ResolveTestClass
64
+ #=> true
65
+
66
+ ## Test resolve_class raises ArgumentError for invalid types
67
+ begin
68
+ Familia.resolve_class(123)
69
+ @raised = false
70
+ rescue ArgumentError => e
71
+ @raised = true
72
+ @error_message = e.message
73
+ end
74
+ @raised
75
+ #=> true
76
+
77
+ ## Test error message is descriptive
78
+ @error_message.include?('Expected Class, String, or Symbol')
79
+ #=> true
80
+
81
+ ## Test resolve_class returns nil for non-existent class
82
+ @nonexistent = Familia.resolve_class(:NonExistentClass)
83
+ @nonexistent.nil?
84
+ #=> true
85
+
86
+ ## Test resolve_class with variations of proper naming
87
+ # Note: All-caps or all-lowercase don't work because snake_case needs case boundaries
88
+ # Realistic usage: PascalCase, snake_case, or mixed-case with boundaries
89
+ @case_variant_snake = Familia.resolve_class('resolve_test_class')
90
+ @case_variant_snake == ResolveTestClass
91
+ #=> true
92
+
93
+ ## Test resolve_class handles already snake_cased symbols
94
+ @already_snake = Familia.resolve_class(:resolve_test_class)
95
+ @already_snake == ResolveTestClass
96
+ #=> true
97
+
98
+ ## Test resolve_class with modularized Symbol (without module prefix)
99
+ @modular_resolved = Familia.resolve_class(:ModularClass)
100
+ @modular_resolved == ResolveTestModule::ModularClass
101
+ #=> true
102
+
103
+ ## Test resolve_class with modularized String (without module prefix)
104
+ @modular_resolved_str = Familia.resolve_class('ModularClass')
105
+ @modular_resolved_str == ResolveTestModule::ModularClass
106
+ #=> true
107
+
108
+ ## Test resolve_class with snake_case modularized Symbol
109
+ @modular_snake = Familia.resolve_class(:modular_class)
110
+ @modular_snake == ResolveTestModule::ModularClass
111
+ #=> true
112
+
113
+ ## Test resolve_class with Class object for modularized class
114
+ @modular_class_obj = Familia.resolve_class(ResolveTestModule::ModularClass)
115
+ @modular_class_obj == ResolveTestModule::ModularClass
116
+ #=> true
@@ -1,3 +1,7 @@
1
+ # try/unit/horreum/auto_indexing_on_save_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/horreum/auto_indexing_on_save_try.rb
2
6
 
3
7
  #
@@ -182,7 +186,7 @@ AutoIndexWithTransient.find_by_email(@transient_email)&.id
182
186
  begin
183
187
  @transient_dup.save
184
188
  rescue Familia::RecordExistsError => ex
185
- Familia.ld ex.backtrace.join("\n")
189
+ Familia.debug ex.backtrace.join("\n")
186
190
  ex.message
187
191
  end
188
192
  #=:> String
@@ -1,4 +1,6 @@
1
1
  # try/unit/horreum/automatic_index_validation_try.rb
2
+ #
3
+ # frozen_string_literal: true
2
4
 
3
5
  #
4
6
  # Automatic index validation tests
@@ -1,3 +1,7 @@
1
+ # try/unit/horreum/base_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/horreum/base_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/unit/horreum/class_methods_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/horreum/class_methods_try.rb
2
6
 
3
7
  # Test Horreum class methods
@@ -1,3 +1,7 @@
1
+ # try/unit/horreum/commands_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/horreum/commands_try.rb
2
6
 
3
7
  # Test Horreum Valkey/Redis commands
@@ -1,3 +1,7 @@
1
+ # try/unit/horreum/defensive_initialization_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/horreum/defensive_initialization_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/unit/horreum/destroy_related_fields_cleanup_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/horreum/destroy_related_fields_cleanup_try.rb
2
6
 
3
7
  # Horreum destroy! Related Fields Cleanup Tryouts
@@ -255,8 +259,9 @@ destroy_result = model.destroy!
255
259
 
256
260
  # Should result in success and also complete in a reasonable amount of
257
261
  # time (under 100ms for this test). I acknowledge this is flaky.
262
+ # Note: 42 results = 40 related field DELs + 1 main object DEL + 1 instances ZREM
258
263
  [destroy_result.class, destroy_result.successful?, destroy_result.results.size]
259
- #=> [MultiResult, true, 41]
264
+ #=> [MultiResult, true, 42]
260
265
  #=%> 100
261
266
 
262
267
  ## Verify transaction_fallback_integration_try.rb bug is fixed
@@ -1,3 +1,7 @@
1
+ # try/unit/horreum/enhanced_conflict_handling_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/horreum/enhanced_conflict_handling_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/unit/horreum/field_categories_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/horreum/field_categories_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/unit/horreum/field_definition_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/horreum/field_definition_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/unit/horreum/initialization_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/horreum/initialization_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,5 @@
1
+ # try/unit/horreum/json_type_preservation_try.rb
2
+ #
1
3
  # frozen_string_literal: true
2
4
 
3
5
  require_relative '../../support/helpers/test_helpers'