familia 2.0.0.pre15 → 2.0.0.pre17
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +2 -2
- data/.github/workflows/code-quality.yml +138 -0
- data/.github/workflows/code-smells.yml +85 -0
- data/.github/workflows/docs.yml +31 -8
- data/.gitignore +3 -1
- data/.pre-commit-config.yaml +7 -1
- data/.reek.yml +98 -0
- data/.rubocop.yml +54 -10
- data/.talismanrc +9 -0
- data/.yardopts +18 -13
- data/CHANGELOG.rst +86 -4
- data/CLAUDE.md +39 -1
- data/Gemfile +6 -5
- data/Gemfile.lock +99 -23
- data/LICENSE.txt +1 -1
- data/README.md +285 -85
- data/changelog.d/README.md +2 -2
- data/docs/archive/FAMILIA_RELATIONSHIPS.md +22 -22
- data/docs/archive/FAMILIA_TECHNICAL.md +42 -42
- data/docs/archive/FAMILIA_UPDATE.md +3 -3
- data/docs/archive/README.md +3 -2
- data/docs/{guides/API-Reference.md → archive/api-reference.md} +87 -101
- data/docs/conf.py +29 -0
- data/docs/guides/{Field-System-Guide.md → core-field-system.md} +9 -9
- data/docs/guides/feature-encrypted-fields.md +785 -0
- data/docs/guides/{Expiration-Feature-Guide.md → feature-expiration.md} +11 -2
- data/docs/guides/feature-external-identifiers.md +637 -0
- data/docs/guides/feature-object-identifiers.md +435 -0
- data/docs/guides/{Quantization-Feature-Guide.md → feature-quantization.md} +94 -29
- data/docs/guides/feature-relationships-methods.md +684 -0
- data/docs/guides/feature-relationships.md +200 -0
- data/docs/guides/{Features-System-Developer-Guide.md → feature-system-devs.md} +4 -4
- data/docs/guides/{Feature-System-Guide.md → feature-system.md} +5 -5
- data/docs/guides/{Transient-Fields-Guide.md → feature-transient-fields.md} +2 -2
- data/docs/guides/{Implementation-Guide.md → implementation.md} +3 -3
- data/docs/guides/index.md +176 -0
- data/docs/guides/{Security-Model.md → security-model.md} +1 -1
- data/docs/migrating/v2.0.0-pre.md +1 -1
- data/docs/migrating/v2.0.0-pre11.md +2 -2
- data/docs/migrating/v2.0.0-pre12.md +2 -2
- data/docs/migrating/v2.0.0-pre5.md +33 -12
- data/docs/migrating/v2.0.0-pre6.md +2 -2
- data/docs/migrating/v2.0.0-pre7.md +8 -8
- data/docs/overview.md +624 -20
- data/docs/reference/api-technical.md +1365 -0
- data/examples/autoloader/mega_customer/features/deprecated_fields.rb +7 -0
- data/examples/autoloader/mega_customer/safe_dump_fields.rb +1 -1
- data/examples/autoloader/mega_customer.rb +3 -1
- data/examples/encrypted_fields.rb +378 -0
- data/examples/json_usage_patterns.rb +144 -0
- data/examples/relationships.rb +13 -13
- data/examples/safe_dump.rb +7 -7
- data/examples/single_connection_transaction_confusions.rb +379 -0
- data/lib/familia/base.rb +51 -10
- data/lib/familia/connection/handlers.rb +223 -0
- data/lib/familia/connection/individual_command_proxy.rb +64 -0
- data/lib/familia/connection/middleware.rb +75 -0
- data/lib/familia/connection/operation_core.rb +93 -0
- data/lib/familia/connection/operations.rb +277 -0
- data/lib/familia/connection/pipeline_core.rb +87 -0
- data/lib/familia/connection/transaction_core.rb +100 -0
- data/lib/familia/connection.rb +60 -186
- data/lib/familia/data_type/class_methods.rb +63 -0
- data/lib/familia/data_type/commands.rb +53 -51
- data/lib/familia/data_type/connection.rb +83 -0
- data/lib/familia/data_type/serialization.rb +108 -107
- data/lib/familia/data_type/settings.rb +96 -0
- data/lib/familia/data_type/types/counter.rb +1 -1
- data/lib/familia/data_type/types/hashkey.rb +15 -11
- data/lib/familia/data_type/types/{list.rb → listkey.rb} +13 -5
- data/lib/familia/data_type/types/lock.rb +3 -2
- data/lib/familia/data_type/types/sorted_set.rb +128 -14
- data/lib/familia/data_type/types/{string.rb → stringkey.rb} +7 -9
- data/lib/familia/data_type/types/unsorted_set.rb +20 -27
- data/lib/familia/data_type.rb +12 -171
- data/lib/familia/distinguisher.rb +85 -0
- data/lib/familia/encryption/encrypted_data.rb +15 -24
- data/lib/familia/encryption/manager.rb +6 -4
- data/lib/familia/encryption/providers/aes_gcm_provider.rb +1 -1
- data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +7 -9
- data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +4 -5
- data/lib/familia/encryption/request_cache.rb +7 -7
- data/lib/familia/encryption.rb +2 -3
- data/lib/familia/errors.rb +9 -3
- data/lib/familia/features/autoloader.rb +30 -12
- data/lib/familia/features/encrypted_fields/concealed_string.rb +3 -4
- data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +13 -14
- data/lib/familia/features/encrypted_fields.rb +71 -66
- data/lib/familia/features/expiration/extensions.rb +1 -1
- data/lib/familia/features/expiration.rb +31 -26
- data/lib/familia/features/external_identifier.rb +57 -19
- data/lib/familia/features/object_identifier.rb +134 -25
- data/lib/familia/features/quantization.rb +16 -21
- data/lib/familia/features/relationships/README.md +97 -0
- data/lib/familia/features/relationships/collection_operations.rb +104 -0
- data/lib/familia/features/relationships/indexing/multi_index_generators.rb +202 -0
- data/lib/familia/features/relationships/indexing/unique_index_generators.rb +306 -0
- data/lib/familia/features/relationships/indexing.rb +182 -256
- data/lib/familia/features/relationships/indexing_relationship.rb +35 -0
- data/lib/familia/features/relationships/participation/participant_methods.rb +164 -0
- data/lib/familia/features/relationships/participation/target_methods.rb +225 -0
- data/lib/familia/features/relationships/participation.rb +656 -0
- data/lib/familia/features/relationships/participation_relationship.rb +31 -0
- data/lib/familia/features/relationships/score_encoding.rb +20 -20
- data/lib/familia/features/relationships.rb +65 -266
- data/lib/familia/features/safe_dump.rb +127 -130
- data/lib/familia/features/transient_fields/redacted_string.rb +6 -6
- data/lib/familia/features/transient_fields/transient_field_type.rb +5 -5
- data/lib/familia/features/transient_fields.rb +10 -7
- data/lib/familia/features.rb +10 -14
- data/lib/familia/field_type.rb +6 -4
- data/lib/familia/horreum/connection.rb +297 -0
- data/lib/familia/horreum/{core/database_commands.rb → database_commands.rb} +27 -17
- data/lib/familia/horreum/{subclass/definition.rb → definition.rb} +139 -74
- data/lib/familia/horreum/{subclass/management.rb → management.rb} +73 -27
- data/lib/familia/horreum/{core/serialization.rb → persistence.rb} +108 -185
- data/lib/familia/horreum/{subclass/related_fields_management.rb → related_fields.rb} +104 -23
- data/lib/familia/horreum/serialization.rb +172 -0
- data/lib/familia/horreum/{shared/settings.rb → settings.rb} +2 -1
- data/lib/familia/horreum/{core/utils.rb → utils.rb} +2 -1
- data/lib/familia/horreum.rb +222 -119
- data/lib/familia/json_serializer.rb +0 -1
- data/lib/familia/logging.rb +11 -114
- data/lib/familia/refinements/dear_json.rb +122 -0
- data/lib/familia/refinements/logger_trace.rb +20 -17
- data/lib/familia/refinements/stylize_words.rb +65 -0
- data/lib/familia/refinements/time_literals.rb +60 -52
- data/lib/familia/refinements.rb +2 -1
- data/lib/familia/secure_identifier.rb +60 -28
- data/lib/familia/settings.rb +83 -7
- data/lib/familia/utils.rb +5 -87
- data/lib/familia/verifiable_identifier.rb +4 -4
- data/lib/familia/version.rb +1 -1
- data/lib/familia.rb +72 -14
- data/lib/middleware/database_middleware.rb +56 -14
- data/lib/{familia/multi_result.rb → multi_result.rb} +23 -16
- data/try/configuration/scenarios_try.rb +2 -2
- data/try/connection/fiber_context_preservation_try.rb +250 -0
- data/try/connection/handler_constraints_try.rb +59 -0
- data/try/connection/operation_mode_guards_try.rb +208 -0
- data/try/connection/pipeline_fallback_integration_try.rb +128 -0
- data/try/connection/responsibility_chain_tracking_try.rb +72 -0
- data/try/connection/transaction_fallback_integration_try.rb +288 -0
- data/try/connection/transaction_mode_permissive_try.rb +153 -0
- data/try/connection/transaction_mode_strict_try.rb +98 -0
- data/try/connection/transaction_mode_warn_try.rb +131 -0
- data/try/connection/transaction_modes_try.rb +249 -0
- data/try/core/autoloader_try.rb +120 -2
- data/try/core/connection_try.rb +10 -10
- data/try/core/conventional_inheritance_try.rb +130 -0
- data/try/core/create_method_try.rb +15 -23
- data/try/core/database_consistency_try.rb +11 -10
- data/try/core/errors_try.rb +11 -14
- data/try/core/familia_extended_try.rb +2 -2
- data/try/core/familia_members_methods_try.rb +76 -0
- data/try/core/familia_try.rb +1 -1
- data/try/core/isolated_dbclient_try.rb +165 -0
- data/try/core/middleware_try.rb +16 -16
- data/try/core/persistence_operations_try.rb +4 -4
- data/try/core/pools_try.rb +42 -26
- data/try/core/secure_identifier_try.rb +28 -24
- data/try/core/time_utils_try.rb +10 -10
- data/try/core/tools_try.rb +3 -3
- data/try/core/utils_try.rb +2 -2
- data/try/data_types/boolean_try.rb +4 -4
- data/try/data_types/datatype_base_try.rb +0 -2
- data/try/data_types/list_try.rb +10 -10
- data/try/data_types/sorted_set_try.rb +5 -5
- data/try/data_types/sorted_set_zadd_options_try.rb +625 -0
- data/try/data_types/string_try.rb +12 -12
- data/try/data_types/unsortedset_try.rb +33 -0
- data/try/debugging/cache_behavior_tracer.rb +7 -7
- data/try/debugging/debug_aad_process.rb +1 -1
- data/try/debugging/debug_concealed_internal.rb +1 -1
- data/try/debugging/debug_cross_context.rb +1 -1
- data/try/debugging/debug_fresh_cross_context.rb +1 -1
- data/try/debugging/encryption_method_tracer.rb +10 -10
- data/try/edge_cases/hash_symbolization_try.rb +1 -1
- data/try/edge_cases/ttl_side_effects_try.rb +1 -1
- data/try/encryption/config_persistence_try.rb +2 -2
- data/try/encryption/encryption_core_try.rb +19 -19
- data/try/encryption/instance_variable_scope_try.rb +1 -1
- data/try/encryption/module_loading_try.rb +2 -2
- data/try/encryption/providers/aes_gcm_provider_try.rb +1 -1
- data/try/encryption/providers/xchacha20_poly1305_provider_try.rb +1 -1
- data/try/encryption/secure_memory_handling_try.rb +1 -1
- data/try/features/encrypted_fields/concealed_string_core_try.rb +11 -7
- data/try/features/encrypted_fields/encrypted_fields_core_try.rb +1 -1
- data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +3 -3
- data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +10 -10
- data/try/features/encrypted_fields/encrypted_fields_security_try.rb +14 -14
- data/try/features/encrypted_fields/error_conditions_try.rb +7 -7
- data/try/features/encrypted_fields/fresh_key_try.rb +1 -1
- data/try/features/encrypted_fields/nonce_uniqueness_try.rb +1 -1
- data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +7 -7
- data/try/features/encrypted_fields/universal_serialization_safety_try.rb +13 -20
- data/try/features/external_identifier/external_identifier_try.rb +1 -1
- data/try/features/feature_dependencies_try.rb +3 -3
- data/try/features/field_groups_try.rb +244 -0
- data/try/features/object_identifier/object_identifier_integration_try.rb +28 -34
- data/try/features/object_identifier/object_identifier_try.rb +10 -0
- data/try/features/quantization/quantization_try.rb +1 -1
- data/try/features/relationships/indexing_commands_verification_try.rb +136 -0
- data/try/features/relationships/indexing_try.rb +443 -0
- data/try/features/relationships/participation_commands_verification_spec.rb +102 -0
- data/try/features/relationships/participation_commands_verification_try.rb +105 -0
- data/try/features/relationships/participation_performance_improvements_try.rb +124 -0
- data/try/features/relationships/participation_reverse_index_try.rb +196 -0
- data/try/features/relationships/relationships_api_changes_try.rb +72 -71
- data/try/features/relationships/relationships_edge_cases_try.rb +15 -18
- data/try/features/relationships/relationships_performance_minimal_try.rb +2 -2
- data/try/features/relationships/relationships_performance_simple_try.rb +8 -8
- data/try/features/relationships/relationships_performance_try.rb +20 -20
- data/try/features/relationships/relationships_try.rb +27 -38
- data/try/features/safe_dump/safe_dump_advanced_try.rb +2 -2
- data/try/features/transient_fields/refresh_reset_try.rb +3 -1
- data/try/features/transient_fields/simple_refresh_test.rb +1 -1
- data/try/helpers/test_cleanup.rb +86 -0
- data/try/helpers/test_helpers.rb +6 -7
- data/try/horreum/auto_indexing_on_save_try.rb +212 -0
- data/try/horreum/base_try.rb +3 -2
- data/try/horreum/commands_try.rb +3 -1
- data/try/horreum/defensive_initialization_try.rb +86 -0
- data/try/horreum/destroy_related_fields_cleanup_try.rb +332 -0
- data/try/horreum/initialization_try.rb +11 -7
- data/try/horreum/relations_try.rb +21 -13
- data/try/horreum/serialization_try.rb +12 -11
- data/try/horreum/settings_try.rb +2 -0
- data/try/integration/cross_component_try.rb +3 -3
- data/try/memory/memory_basic_test.rb +1 -1
- data/try/memory/memory_docker_ruby_dump.sh +2 -2
- data/try/models/customer_safe_dump_try.rb +1 -1
- data/try/models/customer_try.rb +13 -15
- data/try/models/datatype_base_try.rb +3 -3
- data/try/models/familia_object_try.rb +9 -8
- data/try/performance/benchmarks_try.rb +2 -2
- data/try/prototypes/atomic_saves_v1_context_proxy.rb +2 -2
- data/try/prototypes/atomic_saves_v3_connection_pool.rb +3 -3
- data/try/prototypes/atomic_saves_v4.rb +1 -1
- data/try/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -4
- data/try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
- data/try/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
- data/try/prototypes/pooling/lib/connection_pool_metrics.rb +5 -5
- data/try/prototypes/pooling/lib/connection_pool_stress_test.rb +26 -26
- data/try/prototypes/pooling/lib/connection_pool_threading_models.rb +7 -7
- data/try/prototypes/pooling/lib/visualize_stress_results.rb +1 -1
- data/try/prototypes/pooling/pool_siege.rb +11 -11
- data/try/prototypes/pooling/run_stress_tests.rb +7 -7
- data/try/refinements/dear_json_array_methods_try.rb +53 -0
- data/try/refinements/dear_json_hash_methods_try.rb +54 -0
- data/try/refinements/logger_trace_methods_try.rb +44 -0
- data/try/refinements/time_literals_numeric_methods_try.rb +141 -0
- data/try/refinements/time_literals_string_methods_try.rb +80 -0
- data/try/valkey.conf +26 -0
- metadata +92 -52
- data/.rubocop_todo.yml +0 -208
- data/docs/connection_pooling.md +0 -192
- data/docs/guides/Connection-Pooling-Guide.md +0 -437
- data/docs/guides/Encrypted-Fields-Overview.md +0 -101
- data/docs/guides/Feature-System-Autoloading.md +0 -198
- data/docs/guides/Home.md +0 -116
- data/docs/guides/Relationships-Guide.md +0 -737
- data/docs/guides/relationships-methods.md +0 -266
- data/docs/reference/auditing_database_commands.rb +0 -228
- data/examples/permissions.rb +0 -240
- data/lib/familia/features/relationships/cascading.rb +0 -437
- data/lib/familia/features/relationships/membership.rb +0 -497
- data/lib/familia/features/relationships/permission_management.rb +0 -264
- data/lib/familia/features/relationships/querying.rb +0 -615
- data/lib/familia/features/relationships/redis_operations.rb +0 -274
- data/lib/familia/features/relationships/tracking.rb +0 -418
- data/lib/familia/horreum/core/connection.rb +0 -73
- data/lib/familia/horreum/core.rb +0 -21
- data/lib/familia/refinements/snake_case.rb +0 -40
- data/lib/familia/validation/command_recorder.rb +0 -336
- data/lib/familia/validation/expectations.rb +0 -519
- data/lib/familia/validation/validation_helpers.rb +0 -443
- data/lib/familia/validation/validator.rb +0 -412
- data/lib/familia/validation.rb +0 -140
- data/try/data_types/set_try.rb +0 -33
- data/try/features/relationships/categorical_permissions_try.rb +0 -515
- data/try/features/safe_dump/module_based_extensions_try.rb +0 -100
- data/try/features/safe_dump/safe_dump_autoloading_try.rb +0 -107
- data/try/validation/atomic_operations_try.rb.disabled +0 -320
- data/try/validation/command_validation_try.rb.disabled +0 -207
- data/try/validation/performance_validation_try.rb.disabled +0 -324
- data/try/validation/real_world_scenarios_try.rb.disabled +0 -390
data/CHANGELOG.rst
CHANGED
@@ -12,6 +12,88 @@ Versioning <https://semver.org/spec/v2.0.0.html>`__.
|
|
12
12
|
|
13
13
|
<!--scriv-insert-here-->
|
14
14
|
|
15
|
+
.. _changelog-2.0.0.pre17:
|
16
|
+
|
17
|
+
2.0.0.pre17 — 2025-10-03
|
18
|
+
========================
|
19
|
+
|
20
|
+
Added
|
21
|
+
-----
|
22
|
+
|
23
|
+
- **SortedSet#add**: Full ZADD option support (NX, XX, GT, LT, CH) for atomic conditional operations and accurate change tracking. This enables proper index management with timestamp preservation, update-only operations, conditional score updates, and analytics tracking. Closes issue #135.
|
24
|
+
|
25
|
+
Fixed
|
26
|
+
-----
|
27
|
+
|
28
|
+
- Restored objid provenance tracking when loading objects from Redis. The ``ObjectIdentifier`` feature now infers the generator type (:uuid_v7, :uuid_v4, :hex) from the objid format, enabling dependent features like ``ExternalIdentifier`` to derive external identifiers from loaded objects. PR #131
|
29
|
+
|
30
|
+
AI Assistance
|
31
|
+
-------------
|
32
|
+
|
33
|
+
- Claude Code assisted with implementing the ``infer_objid_generator`` method and updating the setter logic in ``lib/familia/features/object_identifier.rb``.
|
34
|
+
|
35
|
+
- Claude Code assisted with Redis ZADD option semantics research, mutual exclusivity validation design, comprehensive test case matrix creation (50+ test cases), and YAML documentation examples.
|
36
|
+
|
37
|
+
.. _changelog-2.0.0.pre16:
|
38
|
+
|
39
|
+
2.0.0.pre16 — 2025-09-30
|
40
|
+
========================
|
41
|
+
|
42
|
+
Added
|
43
|
+
-----
|
44
|
+
|
45
|
+
- Added support for instance-scoped unique indexes via ``unique_index`` with ``within:`` parameter. Issue #128
|
46
|
+
|
47
|
+
Example: ``unique_index :badge_number, :badge_index, within: Company`` creates per-company unique badge lookups using HashKey DataType.
|
48
|
+
|
49
|
+
Changed
|
50
|
+
-------
|
51
|
+
|
52
|
+
- **BREAKING**: Consolidated relationships API by replacing ``tracked_in`` and ``member_of`` with unified ``participates_in`` method. PR #110
|
53
|
+
- **BREAKING**: Renamed ``context_class`` terminology to ``target_class`` throughout relationships module for clarity
|
54
|
+
- **BREAKING**: Removed ``tracking.rb`` and ``membership.rb`` modules, merged functionality into ``participation.rb``
|
55
|
+
- **BREAKING**: Updated method names and configuration keys to use ``target`` instead of ``context`` terminology
|
56
|
+
- Added ``bidirectional`` parameter to ``participates_in`` to control generation of convenience methods (default: true)
|
57
|
+
- Added support for different collection types (sorted_set, set, list) in unified ``participates_in`` API
|
58
|
+
- Renamed ``class_tracked_in`` to ``class_participates_in`` for consistency
|
59
|
+
|
60
|
+
- Renamed DataType classes to avoid Ruby namespace confusion: ``Familia::String`` → ``Familia::StringKey``, ``Familia::List`` → ``Familia::ListKey``
|
61
|
+
- Added dual registration for both traditional and explicit method names (``string``/``stringkey``, ``list``/``listkey``)
|
62
|
+
- Updated ``Counter`` and ``Lock`` to inherit from ``StringKey`` instead of ``String``
|
63
|
+
|
64
|
+
- **BREAKING:** Renamed indexing API methods for clarity. Issue #128
|
65
|
+
|
66
|
+
- ``class_indexed_by`` → ``unique_index`` (1:1 field-to-object mapping via HashKey)
|
67
|
+
- ``indexed_by`` → ``multi_index`` (1:many field-to-objects mapping via UnsortedSet)
|
68
|
+
- Parameter ``target:`` → ``within:`` for consistency across both index types
|
69
|
+
|
70
|
+
- **BREAKING:** Changed ``multi_index`` to use ``UnsortedSet`` instead of ``SortedSet``. Issue #128
|
71
|
+
|
72
|
+
Multi-value indexes no longer include temporal scoring. This aligns with the design philosophy that indexing is for finding objects by attribute, not ordering them. Sort results in Ruby when needed: ``employees.sort_by(&:hire_date)``
|
73
|
+
|
74
|
+
Documentation
|
75
|
+
-------------
|
76
|
+
|
77
|
+
- Updated overview documentation to explain dual naming system and namespace safety benefits
|
78
|
+
- Enhanced examples to demonstrate both traditional and explicit DataType method naming
|
79
|
+
|
80
|
+
- Updated inline module documentation
|
81
|
+
- ``Familia::Features::Relationships::Indexing`` with comprehensive examples, terminology guide, and design philosophy.
|
82
|
+
- ``Familia::Features::Relationships::Participation`` to clarify differences from indexing module.
|
83
|
+
|
84
|
+
AI Assistance
|
85
|
+
-------------
|
86
|
+
|
87
|
+
- Comprehensive analysis of existing ``tracked_in`` and ``member_of`` implementations
|
88
|
+
- Design and implementation of unified ``participates_in`` API integrating both functionalities
|
89
|
+
- Systematic refactoring of codebase terminology from context to target
|
90
|
+
- Complete test suite updates to verify API consolidation and new functionality
|
91
|
+
|
92
|
+
- DataType class renaming and dual registration system implementation designed and developed with Claude Code assistance
|
93
|
+
- All test updates and documentation enhancements created with AI support
|
94
|
+
|
95
|
+
- Architecture design, implementation, test updates, and documentation for indexing API refactoring completed with Claude Code assistance. Issue #128
|
96
|
+
|
15
97
|
.. _changelog-2.0.0.pre14:
|
16
98
|
|
17
99
|
2.0.0.pre14 — 2025-09-08
|
@@ -293,7 +375,7 @@ Fixed
|
|
293
375
|
(e.g., ``find_by_email``) would fail to correctly instantiate objects
|
294
376
|
from the index, returning partially-formed objects.
|
295
377
|
|
296
|
-
- Refactored connection handling to properly cache and reuse Redis
|
378
|
+
- Refactored connection handling to properly cache and reuse Valkey/Redis
|
297
379
|
connections. This eliminates repetitive “Overriding existing
|
298
380
|
connection” warnings and improves performance.
|
299
381
|
|
@@ -342,9 +424,9 @@ Changed
|
|
342
424
|
|
343
425
|
- **BREAKING**: ``tracked_in :global, collection`` syntax now raises
|
344
426
|
ArgumentError - use ``class_tracked_in collection`` instead
|
345
|
-
- **BREAKING**: ``indexed_by field, index,
|
427
|
+
- **BREAKING**: ``indexed_by field, index, target: :global`` syntax
|
346
428
|
replaced with ``class_indexed_by field, index``
|
347
|
-
- **BREAKING**: ``indexed_by field, index,
|
429
|
+
- **BREAKING**: ``indexed_by field, index, target: SomeClass`` syntax
|
348
430
|
replaced with ``indexed_by field, index, parent: SomeClass``
|
349
431
|
- Relationships API now provides consistent parameter naming across all
|
350
432
|
relationship types
|
@@ -498,7 +580,7 @@ Added
|
|
498
580
|
~~~~~
|
499
581
|
|
500
582
|
- Complete API redesign for clarity and modern Ruby conventions
|
501
|
-
- Valkey compatibility alongside traditional Redis support
|
583
|
+
- Valkey compatibility alongside traditional Valkey/Redis support
|
502
584
|
- Ruby 3.4+ modernization with fiber and thread safety improvements
|
503
585
|
- Connection pooling foundation with provider pattern architecture
|
504
586
|
|
data/CLAUDE.md
CHANGED
@@ -75,7 +75,7 @@ Add changelog fragment with each user-facing or documented change (optional but
|
|
75
75
|
|
76
76
|
2. **`Familia::DataType`** - Base class for Valkey data type wrappers
|
77
77
|
- Located in `lib/familia/data_type.rb`
|
78
|
-
- Provides String, List,
|
78
|
+
- Provides String, List, UnsortedSet, SortedSet, HashKey implementations
|
79
79
|
- Each type has its own class in `lib/familia/data_type/types/`
|
80
80
|
|
81
81
|
3. **`Familia::Base`** - Common module for both Horreum and DataType
|
@@ -92,6 +92,44 @@ Familia uses a modular feature system where features are mixed into classes:
|
|
92
92
|
|
93
93
|
**Inheritance Chain**: `MyClass < Familia::Horreum` automatically extends `ClassMethods` and `Features`
|
94
94
|
|
95
|
+
**Common Pitfall: Overriding initialize**
|
96
|
+
|
97
|
+
⚠️ **Do NOT override `initialize` without calling `super`** - this breaks related field initialization.
|
98
|
+
|
99
|
+
**Bad - will cause crashes:**
|
100
|
+
```ruby
|
101
|
+
class User < Familia::Horreum
|
102
|
+
def initialize(email)
|
103
|
+
@email = email # Missing super! Related fields won't work
|
104
|
+
end
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
**Good - use the `init` hook instead:**
|
109
|
+
```ruby
|
110
|
+
class User < Familia::Horreum
|
111
|
+
def init(email = nil)
|
112
|
+
@email = email # Called after super, related fields work
|
113
|
+
end
|
114
|
+
end
|
115
|
+
```
|
116
|
+
|
117
|
+
**Good - call super explicitly:**
|
118
|
+
```ruby
|
119
|
+
class User < Familia::Horreum
|
120
|
+
def initialize(email = nil, **kwargs)
|
121
|
+
super(**kwargs) # ✓ Related fields initialized
|
122
|
+
@email = email
|
123
|
+
end
|
124
|
+
end
|
125
|
+
```
|
126
|
+
|
127
|
+
**Why this matters**: Familia's `initialize` method calls `initialize_relatives` to set up DataType objects (lists, sets, etc.). Without calling `super`, these objects remain nil and you'll get helpful errors pointing to the missing super call.
|
128
|
+
|
129
|
+
**When to use each approach:**
|
130
|
+
- **Use `init` hook** (preferred): For simple initialization logic that doesn't need to intercept constructor arguments. The `init` method is called automatically after `super` with the same arguments passed to `new`.
|
131
|
+
- **Use explicit `super`**: When you need full control over initialization order or need to transform arguments before passing to parent. Remember to pass `**kwargs` to preserve keyword argument handling.
|
132
|
+
|
95
133
|
**DataType Definition**: Use class methods to define keystore database-backed attributes:
|
96
134
|
```ruby
|
97
135
|
class User < Familia::Horreum
|
data/Gemfile
CHANGED
@@ -5,21 +5,22 @@ source 'https://rubygems.org'
|
|
5
5
|
gemspec
|
6
6
|
|
7
7
|
group :test do
|
8
|
-
gem 'tryouts', '~> 3.6.0', require: false
|
9
8
|
gem 'concurrent-ruby', '~> 1.3.5', require: false
|
10
9
|
gem 'ruby-prof'
|
11
10
|
gem 'stackprof'
|
11
|
+
gem 'timecop', require: false
|
12
|
+
gem 'tryouts', '~> 3.6.0', require: false
|
12
13
|
end
|
13
14
|
|
14
15
|
group :development, :test do
|
15
|
-
|
16
|
-
gem 'byebug', '~> 11.0', require: false if RUBY_ENGINE == 'ruby'
|
16
|
+
gem 'debug', require: false
|
17
17
|
gem 'irb', '~> 1.15.2', require: false
|
18
|
-
gem '
|
19
|
-
gem '
|
18
|
+
gem 'redcarpet', require: false
|
19
|
+
gem 'reek', require: false
|
20
20
|
gem 'rubocop', require: false
|
21
21
|
gem 'rubocop-performance', require: false
|
22
22
|
gem 'rubocop-thread_safety', require: false
|
23
|
+
gem 'solargraph', require: false
|
23
24
|
gem 'yard', '~> 0.9', require: false
|
24
25
|
end
|
25
26
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
familia (2.0.0.
|
4
|
+
familia (2.0.0.pre17)
|
5
5
|
benchmark (~> 0.4)
|
6
6
|
connection_pool (~> 2.5)
|
7
7
|
csv (~> 3.3)
|
@@ -15,16 +15,47 @@ GEM
|
|
15
15
|
remote: https://rubygems.org/
|
16
16
|
specs:
|
17
17
|
ast (2.4.3)
|
18
|
+
backport (1.2.0)
|
18
19
|
base64 (0.3.0)
|
19
20
|
benchmark (0.4.1)
|
20
21
|
bigdecimal (3.2.3)
|
21
|
-
byebug (11.1.3)
|
22
|
-
coderay (1.1.3)
|
23
22
|
concurrent-ruby (1.3.5)
|
24
23
|
connection_pool (2.5.3)
|
25
24
|
csv (3.3.5)
|
26
25
|
date (3.4.1)
|
26
|
+
debug (1.11.0)
|
27
|
+
irb (~> 1.10)
|
28
|
+
reline (>= 0.3.8)
|
27
29
|
diff-lcs (1.6.2)
|
30
|
+
dry-configurable (1.3.0)
|
31
|
+
dry-core (~> 1.1)
|
32
|
+
zeitwerk (~> 2.6)
|
33
|
+
dry-core (1.1.0)
|
34
|
+
concurrent-ruby (~> 1.0)
|
35
|
+
logger
|
36
|
+
zeitwerk (~> 2.6)
|
37
|
+
dry-inflector (1.2.0)
|
38
|
+
dry-initializer (3.2.0)
|
39
|
+
dry-logic (1.6.0)
|
40
|
+
bigdecimal
|
41
|
+
concurrent-ruby (~> 1.0)
|
42
|
+
dry-core (~> 1.1)
|
43
|
+
zeitwerk (~> 2.6)
|
44
|
+
dry-schema (1.14.1)
|
45
|
+
concurrent-ruby (~> 1.0)
|
46
|
+
dry-configurable (~> 1.0, >= 1.0.1)
|
47
|
+
dry-core (~> 1.1)
|
48
|
+
dry-initializer (~> 3.2)
|
49
|
+
dry-logic (~> 1.5)
|
50
|
+
dry-types (~> 1.8)
|
51
|
+
zeitwerk (~> 2.6)
|
52
|
+
dry-types (1.8.3)
|
53
|
+
bigdecimal (~> 3.0)
|
54
|
+
concurrent-ruby (~> 1.0)
|
55
|
+
dry-core (~> 1.0)
|
56
|
+
dry-inflector (~> 1.0)
|
57
|
+
dry-logic (~> 1.4)
|
58
|
+
zeitwerk (~> 2.6)
|
28
59
|
erb (5.0.2)
|
29
60
|
ffi (1.17.2)
|
30
61
|
ffi (1.17.2-arm64-darwin)
|
@@ -33,20 +64,29 @@ GEM
|
|
33
64
|
pp (>= 0.6.0)
|
34
65
|
rdoc (>= 4.0.0)
|
35
66
|
reline (>= 0.4.2)
|
36
|
-
|
67
|
+
jaro_winkler (1.6.1)
|
68
|
+
json (2.15.0)
|
37
69
|
kramdown (2.5.1)
|
38
70
|
rexml (>= 3.3.9)
|
71
|
+
kramdown-parser-gfm (1.1.0)
|
72
|
+
kramdown (~> 2.0)
|
39
73
|
language_server-protocol (3.17.0.5)
|
40
74
|
lint_roller (1.1.0)
|
41
75
|
logger (1.7.0)
|
42
|
-
|
76
|
+
mini_portile2 (2.8.9)
|
43
77
|
minitest (5.25.5)
|
78
|
+
nokogiri (1.18.10)
|
79
|
+
mini_portile2 (~> 2.8.2)
|
80
|
+
racc (~> 1.4)
|
81
|
+
nokogiri (1.18.10-arm64-darwin)
|
82
|
+
racc (~> 1.4)
|
83
|
+
observer (0.1.2)
|
44
84
|
oj (3.16.11)
|
45
85
|
bigdecimal (>= 3.0)
|
46
86
|
ostruct (>= 0.2)
|
47
87
|
ostruct (0.6.3)
|
48
88
|
parallel (1.27.0)
|
49
|
-
parser (3.3.
|
89
|
+
parser (3.3.9.0)
|
50
90
|
ast (~> 2.4.1)
|
51
91
|
racc
|
52
92
|
pastel (0.8.0)
|
@@ -54,13 +94,7 @@ GEM
|
|
54
94
|
pp (0.6.2)
|
55
95
|
prettyprint
|
56
96
|
prettyprint (0.2.0)
|
57
|
-
prism (1.
|
58
|
-
pry (0.14.2)
|
59
|
-
coderay (~> 1.1)
|
60
|
-
method_source (~> 1.0)
|
61
|
-
pry-byebug (3.10.1)
|
62
|
-
byebug (~> 11.0)
|
63
|
-
pry (>= 0.13, < 0.15)
|
97
|
+
prism (1.5.1)
|
64
98
|
psych (5.2.6)
|
65
99
|
date
|
66
100
|
stringio
|
@@ -68,16 +102,27 @@ GEM
|
|
68
102
|
rainbow (3.1.1)
|
69
103
|
rbnacl (7.1.2)
|
70
104
|
ffi (~> 1)
|
105
|
+
rbs (3.9.5)
|
106
|
+
logger
|
71
107
|
rdoc (6.14.2)
|
72
108
|
erb
|
73
109
|
psych (>= 4.0.0)
|
110
|
+
redcarpet (3.6.1)
|
74
111
|
redis (5.4.1)
|
75
112
|
redis-client (>= 0.22.0)
|
76
113
|
redis-client (0.25.1)
|
77
114
|
connection_pool
|
78
|
-
|
115
|
+
reek (6.5.0)
|
116
|
+
dry-schema (~> 1.13)
|
117
|
+
logger (~> 1.6)
|
118
|
+
parser (~> 3.3.0)
|
119
|
+
rainbow (>= 2.0, < 4.0)
|
120
|
+
rexml (~> 3.1)
|
121
|
+
regexp_parser (2.11.3)
|
79
122
|
reline (0.6.2)
|
80
123
|
io-console (~> 0.5)
|
124
|
+
reverse_markdown (3.0.0)
|
125
|
+
nokogiri
|
81
126
|
rexml (3.4.1)
|
82
127
|
rspec (3.13.1)
|
83
128
|
rspec-core (~> 3.13.0)
|
@@ -92,7 +137,7 @@ GEM
|
|
92
137
|
diff-lcs (>= 1.2.0, < 2.0)
|
93
138
|
rspec-support (~> 3.13.0)
|
94
139
|
rspec-support (3.13.4)
|
95
|
-
rubocop (1.
|
140
|
+
rubocop (1.81.1)
|
96
141
|
json (~> 2.3)
|
97
142
|
language_server-protocol (~> 3.17.0.2)
|
98
143
|
lint_roller (~> 1.1.0)
|
@@ -100,10 +145,10 @@ GEM
|
|
100
145
|
parser (>= 3.3.0.2)
|
101
146
|
rainbow (>= 2.2.2, < 4.0)
|
102
147
|
regexp_parser (>= 2.9.3, < 3.0)
|
103
|
-
rubocop-ast (>= 1.
|
148
|
+
rubocop-ast (>= 1.47.1, < 2.0)
|
104
149
|
ruby-progressbar (~> 1.7)
|
105
150
|
unicode-display_width (>= 2.4.0, < 4.0)
|
106
|
-
rubocop-ast (1.
|
151
|
+
rubocop-ast (1.47.1)
|
107
152
|
parser (>= 3.3.7.2)
|
108
153
|
prism (~> 1.4)
|
109
154
|
rubocop-performance (1.25.0)
|
@@ -117,8 +162,32 @@ GEM
|
|
117
162
|
ruby-prof (1.7.2)
|
118
163
|
base64
|
119
164
|
ruby-progressbar (1.13.0)
|
165
|
+
solargraph (0.57.0)
|
166
|
+
backport (~> 1.2)
|
167
|
+
benchmark (~> 0.4)
|
168
|
+
bundler (~> 2.0)
|
169
|
+
diff-lcs (~> 1.4)
|
170
|
+
jaro_winkler (~> 1.6, >= 1.6.1)
|
171
|
+
kramdown (~> 2.3)
|
172
|
+
kramdown-parser-gfm (~> 1.1)
|
173
|
+
logger (~> 1.6)
|
174
|
+
observer (~> 0.1)
|
175
|
+
ostruct (~> 0.6)
|
176
|
+
parser (~> 3.0)
|
177
|
+
prism (~> 1.4)
|
178
|
+
rbs (>= 3.6.1, <= 4.0.0.dev.4)
|
179
|
+
reverse_markdown (~> 3.0)
|
180
|
+
rubocop (~> 1.76)
|
181
|
+
thor (~> 1.0)
|
182
|
+
tilt (~> 2.0)
|
183
|
+
yard (~> 0.9, >= 0.9.24)
|
184
|
+
yard-activesupport-concern (~> 0.0)
|
185
|
+
yard-solargraph (~> 0.1)
|
120
186
|
stackprof (0.2.27)
|
121
187
|
stringio (3.1.7)
|
188
|
+
thor (1.4.0)
|
189
|
+
tilt (2.6.1)
|
190
|
+
timecop (0.9.10)
|
122
191
|
tryouts (3.6.0)
|
123
192
|
concurrent-ruby (~> 1.0)
|
124
193
|
irb
|
@@ -131,29 +200,36 @@ GEM
|
|
131
200
|
tty-color (0.6.0)
|
132
201
|
tty-cursor (0.7.1)
|
133
202
|
tty-screen (0.8.2)
|
134
|
-
unicode-display_width (3.
|
135
|
-
unicode-emoji (~> 4.
|
136
|
-
unicode-emoji (4.0
|
203
|
+
unicode-display_width (3.2.0)
|
204
|
+
unicode-emoji (~> 4.1)
|
205
|
+
unicode-emoji (4.1.0)
|
137
206
|
uri-valkey (1.4.0)
|
138
207
|
yard (0.9.37)
|
208
|
+
yard-activesupport-concern (0.0.1)
|
209
|
+
yard (>= 0.8)
|
210
|
+
yard-solargraph (0.1.0)
|
211
|
+
yard (~> 0.9)
|
212
|
+
zeitwerk (2.7.3)
|
139
213
|
|
140
214
|
PLATFORMS
|
141
215
|
arm64-darwin-24
|
142
216
|
ruby
|
143
217
|
|
144
218
|
DEPENDENCIES
|
145
|
-
byebug (~> 11.0)
|
146
219
|
concurrent-ruby (~> 1.3.5)
|
220
|
+
debug
|
147
221
|
familia!
|
148
222
|
irb (~> 1.15.2)
|
149
|
-
kramdown
|
150
|
-
pry-byebug (~> 3.10.1)
|
151
223
|
rbnacl (~> 7.1, >= 7.1.1)
|
224
|
+
redcarpet
|
225
|
+
reek
|
152
226
|
rubocop
|
153
227
|
rubocop-performance
|
154
228
|
rubocop-thread_safety
|
155
229
|
ruby-prof
|
230
|
+
solargraph
|
156
231
|
stackprof
|
232
|
+
timecop
|
157
233
|
tryouts (~> 3.6.0)
|
158
234
|
yard (~> 0.9)
|
159
235
|
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
MIT License
|
2
2
|
|
3
|
-
Copyright (c) 2010-
|
3
|
+
Copyright (c) 2010-ongoing delano, contributors
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|