familia 2.0.0.pre18 → 2.0.0.pre21
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/claude-code-review.yml +4 -9
- data/.github/workflows/code-smells.yml +64 -3
- data/.pre-commit-config.yaml +8 -6
- data/.reek.yml +10 -9
- data/.rubocop.yml +4 -0
- data/CHANGELOG.rst +205 -88
- data/CLAUDE.md +62 -10
- data/Gemfile +3 -3
- data/Gemfile.lock +27 -62
- data/README.md +39 -0
- data/bin/try +16 -0
- data/bin/tryouts +16 -0
- data/changelog.d/20251105_flexible_external_identifier_format.rst +66 -0
- data/changelog.d/20251107_112554_delano_179_participation_asymmetry.rst +44 -0
- data/changelog.d/20251107_213121_delano_fix_thread_safety_races_011CUumCP492Twxm4NLt2FvL.rst +20 -0
- data/changelog.d/20251107_fix_participates_in_symbol_resolution.rst +91 -0
- data/changelog.d/20251107_optimized_redis_exists_checks.rst +94 -0
- data/changelog.d/20251108_frozen_string_literal_pragma.rst +44 -0
- data/docs/1106-participates_in-bidirectional-solution.md +129 -0
- data/docs/guides/encryption.md +486 -0
- data/docs/guides/feature-encrypted-fields.md +123 -7
- data/docs/guides/feature-expiration.md +177 -133
- data/docs/guides/feature-external-identifiers.md +415 -443
- data/docs/guides/feature-object-identifiers.md +400 -269
- data/docs/guides/feature-quantization.md +120 -6
- data/docs/guides/feature-relationships-indexing.md +318 -0
- data/docs/guides/feature-relationships-methods.md +146 -604
- data/docs/guides/feature-relationships-participation.md +263 -0
- data/docs/guides/feature-relationships.md +118 -136
- data/docs/guides/feature-system-devs.md +176 -693
- data/docs/guides/feature-system.md +119 -6
- data/docs/guides/feature-transient-fields.md +81 -0
- data/docs/guides/field-system.md +778 -0
- data/docs/guides/index.md +32 -15
- data/docs/guides/logging.md +187 -0
- data/docs/guides/optimized-loading.md +674 -0
- data/docs/guides/thread-safety-monitoring.md +61 -0
- data/docs/guides/{time-utilities.md → time-literals.md} +12 -12
- data/docs/migrating/v2.0.0-pre19.md +197 -0
- data/docs/migrating/v2.0.0-pre22.md +241 -0
- data/docs/overview.md +7 -9
- data/docs/reference/api-technical.md +267 -320
- data/examples/autoloader/mega_customer/features/deprecated_fields.rb +2 -0
- data/examples/autoloader/mega_customer/safe_dump_fields.rb +2 -0
- data/examples/autoloader/mega_customer.rb +2 -0
- data/examples/datatype_standalone.rb +282 -0
- data/examples/encrypted_fields.rb +2 -1
- data/examples/json_usage_patterns.rb +2 -0
- data/examples/relationships.rb +3 -0
- data/examples/safe_dump.rb +2 -1
- data/examples/sampling_demo.rb +53 -0
- data/examples/single_connection_transaction_confusions.rb +2 -1
- data/familia.gemspec +2 -1
- data/lib/familia/base.rb +2 -0
- data/lib/familia/connection/behavior.rb +254 -0
- data/lib/familia/connection/handlers.rb +97 -0
- data/lib/familia/connection/individual_command_proxy.rb +2 -0
- data/lib/familia/connection/middleware.rb +34 -24
- data/lib/familia/connection/operation_core.rb +3 -1
- data/lib/familia/connection/operations.rb +2 -0
- data/lib/familia/connection/{pipeline_core.rb → pipelined_core.rb} +4 -2
- data/lib/familia/connection/transaction_core.rb +75 -9
- data/lib/familia/connection.rb +21 -5
- data/lib/familia/data_type/class_methods.rb +3 -1
- data/lib/familia/data_type/connection.rb +153 -7
- data/lib/familia/data_type/database_commands.rb +9 -4
- data/lib/familia/data_type/serialization.rb +10 -4
- data/lib/familia/data_type/settings.rb +2 -0
- data/lib/familia/data_type/types/counter.rb +2 -0
- data/lib/familia/data_type/types/hashkey.rb +8 -6
- data/lib/familia/data_type/types/listkey.rb +2 -0
- data/lib/familia/data_type/types/lock.rb +2 -0
- data/lib/familia/data_type/types/sorted_set.rb +2 -0
- data/lib/familia/data_type/types/stringkey.rb +2 -0
- data/lib/familia/data_type/types/unsorted_set.rb +2 -0
- data/lib/familia/data_type.rb +2 -0
- data/lib/familia/encryption/encrypted_data.rb +4 -2
- data/lib/familia/encryption/manager.rb +2 -0
- data/lib/familia/encryption/provider.rb +2 -0
- data/lib/familia/encryption/providers/aes_gcm_provider.rb +2 -0
- data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +2 -0
- data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +2 -0
- data/lib/familia/encryption/registry.rb +2 -0
- data/lib/familia/encryption/request_cache.rb +2 -0
- data/lib/familia/encryption.rb +9 -2
- data/lib/familia/errors.rb +53 -14
- data/lib/familia/features/autoloader.rb +2 -0
- data/lib/familia/features/encrypted_fields/concealed_string.rb +2 -0
- data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +4 -0
- data/lib/familia/features/encrypted_fields.rb +2 -2
- data/lib/familia/features/expiration/extensions.rb +11 -11
- data/lib/familia/features/expiration.rb +29 -21
- data/lib/familia/features/external_identifier.rb +33 -7
- data/lib/familia/features/object_identifier.rb +2 -0
- data/lib/familia/features/quantization.rb +3 -1
- data/lib/familia/features/relationships/README.md +3 -1
- data/lib/familia/features/relationships/collection_operations.rb +2 -0
- data/lib/familia/features/relationships/indexing/multi_index_generators.rb +177 -47
- data/lib/familia/features/relationships/indexing/rebuild_strategies.rb +479 -0
- data/lib/familia/features/relationships/indexing/unique_index_generators.rb +203 -63
- data/lib/familia/features/relationships/indexing.rb +40 -42
- data/lib/familia/features/relationships/indexing_relationship.rb +17 -5
- data/lib/familia/features/relationships/participation/participant_methods.rb +131 -14
- data/lib/familia/features/relationships/participation/rebuild_strategies.md +41 -0
- data/lib/familia/features/relationships/participation/target_methods.rb +6 -6
- data/lib/familia/features/relationships/participation.rb +155 -69
- data/lib/familia/features/relationships/participation_membership.rb +69 -0
- data/lib/familia/features/relationships/participation_relationship.rb +34 -6
- data/lib/familia/features/relationships/score_encoding.rb +2 -0
- data/lib/familia/features/relationships.rb +5 -3
- data/lib/familia/features/safe_dump.rb +2 -0
- data/lib/familia/features/transient_fields/redacted_string.rb +2 -0
- data/lib/familia/features/transient_fields/single_use_redacted_string.rb +2 -0
- data/lib/familia/features/transient_fields/transient_field_type.rb +5 -3
- data/lib/familia/features/transient_fields.rb +2 -0
- data/lib/familia/features.rb +2 -0
- data/lib/familia/field_type.rb +5 -2
- data/lib/familia/horreum/connection.rb +28 -36
- data/lib/familia/horreum/database_commands.rb +131 -10
- data/lib/familia/horreum/definition.rb +18 -7
- data/lib/familia/horreum/management.rb +233 -57
- data/lib/familia/horreum/persistence.rb +314 -122
- data/lib/familia/horreum/related_fields.rb +2 -0
- data/lib/familia/horreum/serialization.rb +26 -4
- data/lib/familia/horreum/settings.rb +2 -0
- data/lib/familia/horreum/utils.rb +2 -8
- data/lib/familia/horreum.rb +46 -13
- data/lib/familia/identifier_extractor.rb +2 -0
- data/lib/familia/instrumentation.rb +156 -0
- data/lib/familia/json_serializer.rb +2 -0
- data/lib/familia/logging.rb +94 -37
- data/lib/familia/refinements/dear_json.rb +2 -0
- data/lib/familia/refinements/stylize_words.rb +2 -14
- data/lib/familia/refinements/time_literals.rb +2 -0
- data/lib/familia/refinements.rb +2 -0
- data/lib/familia/secure_identifier.rb +10 -2
- data/lib/familia/settings.rb +9 -7
- data/lib/familia/thread_safety/instrumented_mutex.rb +166 -0
- data/lib/familia/thread_safety/monitor.rb +328 -0
- data/lib/familia/utils.rb +13 -0
- data/lib/familia/verifiable_identifier.rb +3 -1
- data/lib/familia/version.rb +3 -1
- data/lib/familia.rb +31 -4
- data/lib/middleware/database_command_counter.rb +152 -0
- data/lib/middleware/database_logger.rb +325 -129
- data/lib/multi_result.rb +2 -0
- data/try/edge_cases/empty_identifiers_try.rb +2 -0
- data/try/edge_cases/hash_symbolization_try.rb +2 -0
- data/try/edge_cases/json_serialization_try.rb +2 -0
- data/try/edge_cases/legacy_data_detection/deserialization_edge_cases_try.rb +4 -0
- data/try/edge_cases/race_conditions_try.rb +4 -0
- data/try/edge_cases/reserved_keywords_try.rb +4 -0
- data/try/edge_cases/string_coercion_try.rb +6 -4
- data/try/edge_cases/ttl_side_effects_try.rb +4 -0
- data/try/features/encrypted_fields/aad_protection_try.rb +4 -0
- data/try/features/encrypted_fields/concealed_string_core_try.rb +4 -0
- data/try/features/encrypted_fields/context_isolation_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_core_try.rb +33 -0
- data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_security_try.rb +4 -0
- data/try/features/encrypted_fields/error_conditions_try.rb +4 -0
- data/try/features/encrypted_fields/fresh_key_derivation_try.rb +4 -0
- data/try/features/encrypted_fields/fresh_key_try.rb +4 -0
- data/try/features/encrypted_fields/key_rotation_try.rb +4 -0
- data/try/features/encrypted_fields/memory_security_try.rb +4 -0
- data/try/features/encrypted_fields/missing_current_key_version_try.rb +4 -0
- data/try/features/encrypted_fields/nonce_uniqueness_try.rb +4 -0
- data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +4 -0
- data/try/features/encrypted_fields/thread_safety_try.rb +4 -0
- data/try/features/encrypted_fields/universal_serialization_safety_try.rb +4 -0
- data/try/features/encryption/config_persistence_try.rb +4 -0
- data/try/features/encryption/core_try.rb +4 -0
- data/try/features/encryption/instance_variable_scope_try.rb +4 -0
- data/try/features/encryption/module_loading_try.rb +4 -0
- data/try/features/encryption/providers/aes_gcm_provider_try.rb +4 -0
- data/try/features/encryption/providers/xchacha20_poly1305_provider_try.rb +4 -0
- data/try/features/encryption/roundtrip_validation_try.rb +4 -0
- data/try/features/encryption/secure_memory_handling_try.rb +4 -0
- data/try/features/expiration/expiration_try.rb +5 -1
- data/try/features/external_identifier/external_identifier_try.rb +171 -8
- data/try/features/feature_dependencies_try.rb +2 -0
- data/try/features/feature_improvements_try.rb +2 -0
- data/try/features/field_groups_try.rb +2 -0
- data/try/features/object_identifier/object_identifier_integration_try.rb +12 -9
- data/try/features/object_identifier/object_identifier_try.rb +2 -0
- data/try/features/quantization/quantization_try.rb +4 -0
- data/try/features/real_feature_integration_try.rb +2 -0
- data/try/features/relationships/indexing_commands_verification_try.rb +2 -0
- data/try/features/relationships/indexing_rebuild_try.rb +600 -0
- data/try/features/relationships/indexing_try.rb +30 -4
- data/try/features/relationships/participation_bidirectional_try.rb +242 -0
- data/try/features/relationships/participation_commands_verification_spec.rb +4 -0
- data/try/features/relationships/participation_commands_verification_try.rb +2 -0
- data/try/features/relationships/participation_performance_improvements_try.rb +11 -9
- data/try/features/relationships/participation_reverse_index_try.rb +15 -13
- data/try/features/relationships/participation_target_class_resolution_try.rb +209 -0
- data/try/features/relationships/participation_unresolved_target_try.rb +109 -0
- data/try/features/relationships/relationships_api_changes_try.rb +6 -4
- data/try/features/relationships/relationships_edge_cases_try.rb +4 -0
- data/try/features/relationships/relationships_performance_minimal_try.rb +4 -0
- data/try/features/relationships/relationships_performance_simple_try.rb +4 -0
- data/try/features/relationships/relationships_performance_try.rb +4 -0
- data/try/features/relationships/relationships_performance_working_try.rb +4 -0
- data/try/features/relationships/relationships_try.rb +6 -4
- data/try/features/safe_dump/safe_dump_advanced_try.rb +4 -0
- data/try/features/safe_dump/safe_dump_try.rb +4 -0
- data/try/features/transient_fields/redacted_string_try.rb +2 -0
- data/try/features/transient_fields/refresh_reset_try.rb +3 -0
- data/try/features/transient_fields/simple_refresh_test.rb +3 -0
- data/try/features/transient_fields/single_use_redacted_string_try.rb +2 -0
- data/try/features/transient_fields/transient_fields_core_try.rb +4 -0
- data/try/features/transient_fields/transient_fields_integration_try.rb +4 -0
- data/try/integration/connection/fiber_context_preservation_try.rb +7 -3
- data/try/integration/connection/handler_constraints_try.rb +4 -0
- data/try/integration/connection/isolated_dbclient_try.rb +4 -0
- data/try/integration/connection/middleware_reconnect_try.rb +2 -0
- data/try/integration/connection/operation_mode_guards_try.rb +5 -1
- data/try/integration/connection/pipeline_fallback_integration_try.rb +15 -12
- data/try/integration/connection/pools_try.rb +4 -0
- data/try/integration/connection/responsibility_chain_tracking_try.rb +4 -0
- data/try/integration/connection/transaction_fallback_integration_try.rb +4 -0
- data/try/integration/connection/transaction_mode_permissive_try.rb +4 -0
- data/try/integration/connection/transaction_mode_strict_try.rb +4 -0
- data/try/integration/connection/transaction_mode_warn_try.rb +4 -0
- data/try/integration/connection/transaction_modes_try.rb +4 -0
- data/try/integration/conventional_inheritance_try.rb +4 -0
- data/try/integration/create_method_try.rb +26 -22
- data/try/integration/cross_component_try.rb +4 -0
- data/try/integration/data_types/datatype_pipelines_try.rb +108 -0
- data/try/integration/data_types/datatype_transactions_try.rb +251 -0
- data/try/integration/database_consistency_try.rb +4 -0
- data/try/integration/familia_extended_try.rb +4 -0
- data/try/integration/familia_members_methods_try.rb +4 -0
- data/try/integration/models/customer_safe_dump_try.rb +9 -1
- data/try/integration/models/customer_try.rb +4 -0
- data/try/integration/models/datatype_base_try.rb +4 -0
- data/try/integration/models/familia_object_try.rb +5 -1
- data/try/integration/persistence_operations_try.rb +166 -10
- data/try/integration/relationships_persistence_round_trip_try.rb +17 -14
- data/try/integration/save_methods_consistency_try.rb +241 -0
- data/try/integration/scenarios_try.rb +4 -0
- data/try/integration/secure_identifier_try.rb +4 -0
- data/try/integration/transaction_safety_core_try.rb +176 -0
- data/try/integration/transaction_safety_workflow_try.rb +291 -0
- data/try/integration/verifiable_identifier_try.rb +4 -0
- data/try/investigation/pipeline_routing/README.md +228 -0
- data/try/performance/benchmarks_try.rb +4 -0
- data/try/performance/transaction_safety_benchmark_try.rb +238 -0
- data/try/support/benchmarks/deserialization_benchmark.rb +3 -1
- data/try/support/benchmarks/deserialization_correctness_test.rb +3 -1
- data/try/support/debugging/cache_behavior_tracer.rb +4 -0
- data/try/support/debugging/debug_aad_process.rb +3 -0
- data/try/support/debugging/debug_concealed_internal.rb +3 -0
- data/try/support/debugging/debug_concealed_reveal.rb +3 -0
- data/try/support/debugging/debug_context_aad.rb +3 -0
- data/try/support/debugging/debug_context_simple.rb +3 -0
- data/try/support/debugging/debug_cross_context.rb +3 -0
- data/try/support/debugging/debug_database_load.rb +3 -0
- data/try/support/debugging/debug_encrypted_json_check.rb +3 -0
- data/try/support/debugging/debug_encrypted_json_step_by_step.rb +3 -0
- data/try/support/debugging/debug_exists_lifecycle.rb +3 -0
- data/try/support/debugging/debug_field_decrypt.rb +3 -0
- data/try/support/debugging/debug_fresh_cross_context.rb +3 -0
- data/try/support/debugging/debug_load_path.rb +3 -0
- data/try/support/debugging/debug_method_definition.rb +3 -0
- data/try/support/debugging/debug_method_resolution.rb +3 -0
- data/try/support/debugging/debug_minimal.rb +3 -0
- data/try/support/debugging/debug_provider.rb +3 -0
- data/try/support/debugging/debug_secure_behavior.rb +3 -0
- data/try/support/debugging/debug_string_class.rb +3 -0
- data/try/support/debugging/debug_test.rb +3 -0
- data/try/support/debugging/debug_test_design.rb +3 -0
- data/try/support/debugging/encryption_method_tracer.rb +4 -0
- data/try/support/debugging/provider_diagnostics.rb +4 -0
- data/try/support/helpers/test_cleanup.rb +4 -0
- data/try/support/helpers/test_helpers.rb +5 -0
- data/try/support/memory/memory_basic_test.rb +4 -0
- data/try/support/memory/memory_detailed_test.rb +4 -0
- data/try/support/memory/memory_search_for_string.rb +4 -0
- data/try/support/memory/test_actual_redactedstring_protection.rb +4 -0
- data/try/support/prototypes/atomic_saves_v1_context_proxy.rb +4 -0
- data/try/support/prototypes/atomic_saves_v2_connection_switching.rb +4 -0
- data/try/support/prototypes/atomic_saves_v3_connection_pool.rb +4 -0
- data/try/support/prototypes/atomic_saves_v4.rb +4 -0
- data/try/support/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -0
- data/try/support/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
- data/try/support/prototypes/pooling/configurable_stress_test.rb +4 -0
- data/try/support/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_metrics.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_stress_test.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_threading_models.rb +4 -0
- data/try/support/prototypes/pooling/lib/visualize_stress_results.rb +4 -2
- data/try/support/prototypes/pooling/pool_siege.rb +4 -2
- data/try/support/prototypes/pooling/run_stress_tests.rb +4 -2
- data/try/thread_safety/README.md +496 -0
- data/try/thread_safety/class_connection_chain_race_try.rb +265 -0
- data/try/thread_safety/connection_chain_race_try.rb +148 -0
- data/try/thread_safety/encryption_manager_cache_race_try.rb +166 -0
- data/try/thread_safety/feature_registry_race_try.rb +226 -0
- data/try/thread_safety/fiber_pipeline_isolation_try.rb +235 -0
- data/try/thread_safety/fiber_transaction_isolation_try.rb +208 -0
- data/try/thread_safety/field_registration_race_try.rb +222 -0
- data/try/thread_safety/logger_initialization_race_try.rb +170 -0
- data/try/thread_safety/middleware_registration_race_try.rb +154 -0
- data/try/thread_safety/module_config_race_try.rb +175 -0
- data/try/thread_safety/secure_identifier_cache_race_try.rb +226 -0
- data/try/unit/core/autoloader_try.rb +4 -0
- data/try/unit/core/base_enhancements_try.rb +4 -0
- data/try/unit/core/connection_try.rb +4 -0
- data/try/unit/core/errors_try.rb +4 -0
- data/try/unit/core/extensions_try.rb +4 -0
- data/try/unit/core/familia_logger_try.rb +2 -0
- data/try/unit/core/familia_try.rb +4 -0
- data/try/unit/core/middleware_sampling_try.rb +335 -0
- data/try/unit/core/middleware_test_helpers_bug_try.rb +58 -0
- data/try/unit/core/middleware_thread_safety_try.rb +245 -0
- data/try/unit/core/middleware_try.rb +4 -0
- data/try/unit/core/settings_try.rb +4 -0
- data/try/unit/core/time_utils_try.rb +4 -0
- data/try/unit/core/tools_try.rb +4 -0
- data/try/unit/core/utils_try.rb +37 -0
- data/try/unit/data_types/boolean_try.rb +5 -1
- data/try/unit/data_types/counter_try.rb +4 -0
- data/try/unit/data_types/datatype_base_try.rb +4 -0
- data/try/unit/data_types/hash_try.rb +4 -0
- data/try/unit/data_types/list_try.rb +4 -0
- data/try/unit/data_types/lock_try.rb +4 -0
- data/try/unit/data_types/sorted_set_try.rb +4 -0
- data/try/unit/data_types/sorted_set_zadd_options_try.rb +4 -0
- data/try/unit/data_types/string_try.rb +5 -1
- data/try/unit/data_types/unsortedset_try.rb +4 -0
- data/try/unit/familia_resolve_class_try.rb +116 -0
- data/try/unit/horreum/auto_indexing_on_save_try.rb +36 -16
- data/try/unit/horreum/automatic_index_validation_try.rb +255 -0
- data/try/unit/horreum/base_try.rb +5 -1
- data/try/unit/horreum/class_methods_try.rb +6 -2
- data/try/unit/horreum/commands_try.rb +4 -0
- data/try/unit/horreum/defensive_initialization_try.rb +4 -0
- data/try/unit/horreum/destroy_related_fields_cleanup_try.rb +4 -0
- data/try/unit/horreum/enhanced_conflict_handling_try.rb +4 -0
- data/try/unit/horreum/field_categories_try.rb +4 -0
- data/try/unit/horreum/field_definition_try.rb +4 -0
- data/try/unit/horreum/initialization_try.rb +5 -1
- data/try/unit/horreum/json_type_preservation_try.rb +2 -0
- data/try/unit/horreum/optimized_loading_try.rb +156 -0
- data/try/unit/horreum/relations_try.rb +8 -4
- data/try/unit/horreum/serialization_persistent_fields_try.rb +4 -0
- data/try/unit/horreum/serialization_try.rb +6 -2
- data/try/unit/horreum/settings_try.rb +4 -0
- data/try/unit/horreum/unique_index_edge_cases_try.rb +380 -0
- data/try/unit/horreum/unique_index_guard_validation_try.rb +283 -0
- data/try/unit/middleware/database_command_counter_methods_try.rb +139 -0
- data/try/unit/middleware/database_logger_methods_try.rb +251 -0
- data/try/unit/refinements/dear_json_array_methods_try.rb +4 -0
- data/try/unit/refinements/dear_json_hash_methods_try.rb +4 -0
- data/try/unit/refinements/time_literals_numeric_methods_try.rb +4 -0
- data/try/unit/refinements/time_literals_string_methods_try.rb +4 -0
- data/try/unit/thread_safety_monitor_try.rb +149 -0
- metadata +81 -14
- data/.github/workflows/code-quality.yml +0 -138
- data/docs/archive/FAMILIA_RELATIONSHIPS.md +0 -210
- data/docs/archive/FAMILIA_TECHNICAL.md +0 -823
- data/docs/archive/FAMILIA_UPDATE.md +0 -226
- data/docs/archive/README.md +0 -64
- data/docs/archive/api-reference.md +0 -333
- data/docs/guides/core-field-system.md +0 -806
- data/docs/guides/implementation.md +0 -276
- data/docs/guides/security-model.md +0 -183
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: familia
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.0.
|
|
4
|
+
version: 2.0.0.pre21
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Delano Mandelbaum
|
|
@@ -23,6 +23,20 @@ dependencies:
|
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '0.4'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: concurrent-ruby
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '1.3'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '1.3'
|
|
26
40
|
- !ruby/object:Gem::Dependency
|
|
27
41
|
name: connection_pool
|
|
28
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -137,7 +151,6 @@ files:
|
|
|
137
151
|
- ".github/workflows/ci.yml"
|
|
138
152
|
- ".github/workflows/claude-code-review.yml"
|
|
139
153
|
- ".github/workflows/claude.yml"
|
|
140
|
-
- ".github/workflows/code-quality.yml"
|
|
141
154
|
- ".github/workflows/code-smells.yml"
|
|
142
155
|
- ".github/workflows/docs.yml"
|
|
143
156
|
- ".gitignore"
|
|
@@ -153,31 +166,39 @@ files:
|
|
|
153
166
|
- LICENSE.txt
|
|
154
167
|
- README.md
|
|
155
168
|
- bin/irb
|
|
169
|
+
- bin/try
|
|
170
|
+
- bin/tryouts
|
|
171
|
+
- changelog.d/20251105_flexible_external_identifier_format.rst
|
|
172
|
+
- changelog.d/20251107_112554_delano_179_participation_asymmetry.rst
|
|
173
|
+
- changelog.d/20251107_213121_delano_fix_thread_safety_races_011CUumCP492Twxm4NLt2FvL.rst
|
|
174
|
+
- changelog.d/20251107_fix_participates_in_symbol_resolution.rst
|
|
175
|
+
- changelog.d/20251107_optimized_redis_exists_checks.rst
|
|
176
|
+
- changelog.d/20251108_frozen_string_literal_pragma.rst
|
|
156
177
|
- changelog.d/README.md
|
|
157
178
|
- changelog.d/scriv.ini
|
|
179
|
+
- docs/1106-participates_in-bidirectional-solution.md
|
|
158
180
|
- docs/archive/.gitignore
|
|
159
|
-
- docs/archive/FAMILIA_RELATIONSHIPS.md
|
|
160
|
-
- docs/archive/FAMILIA_TECHNICAL.md
|
|
161
|
-
- docs/archive/FAMILIA_UPDATE.md
|
|
162
|
-
- docs/archive/README.md
|
|
163
|
-
- docs/archive/api-reference.md
|
|
164
181
|
- docs/conf.py
|
|
165
182
|
- docs/guides/.gitignore
|
|
166
|
-
- docs/guides/
|
|
183
|
+
- docs/guides/encryption.md
|
|
167
184
|
- docs/guides/feature-encrypted-fields.md
|
|
168
185
|
- docs/guides/feature-expiration.md
|
|
169
186
|
- docs/guides/feature-external-identifiers.md
|
|
170
187
|
- docs/guides/feature-object-identifiers.md
|
|
171
188
|
- docs/guides/feature-quantization.md
|
|
189
|
+
- docs/guides/feature-relationships-indexing.md
|
|
172
190
|
- docs/guides/feature-relationships-methods.md
|
|
191
|
+
- docs/guides/feature-relationships-participation.md
|
|
173
192
|
- docs/guides/feature-relationships.md
|
|
174
193
|
- docs/guides/feature-system-devs.md
|
|
175
194
|
- docs/guides/feature-system.md
|
|
176
195
|
- docs/guides/feature-transient-fields.md
|
|
177
|
-
- docs/guides/
|
|
196
|
+
- docs/guides/field-system.md
|
|
178
197
|
- docs/guides/index.md
|
|
179
|
-
- docs/guides/
|
|
180
|
-
- docs/guides/
|
|
198
|
+
- docs/guides/logging.md
|
|
199
|
+
- docs/guides/optimized-loading.md
|
|
200
|
+
- docs/guides/thread-safety-monitoring.md
|
|
201
|
+
- docs/guides/time-literals.md
|
|
181
202
|
- docs/migrating/.gitignore
|
|
182
203
|
- docs/migrating/v2.0.0-pre.md
|
|
183
204
|
- docs/migrating/v2.0.0-pre11.md
|
|
@@ -185,6 +206,8 @@ files:
|
|
|
185
206
|
- docs/migrating/v2.0.0-pre13.md
|
|
186
207
|
- docs/migrating/v2.0.0-pre14.md
|
|
187
208
|
- docs/migrating/v2.0.0-pre18.md
|
|
209
|
+
- docs/migrating/v2.0.0-pre19.md
|
|
210
|
+
- docs/migrating/v2.0.0-pre22.md
|
|
188
211
|
- docs/migrating/v2.0.0-pre5.md
|
|
189
212
|
- docs/migrating/v2.0.0-pre6.md
|
|
190
213
|
- docs/migrating/v2.0.0-pre7.md
|
|
@@ -194,21 +217,24 @@ files:
|
|
|
194
217
|
- examples/autoloader/mega_customer.rb
|
|
195
218
|
- examples/autoloader/mega_customer/features/deprecated_fields.rb
|
|
196
219
|
- examples/autoloader/mega_customer/safe_dump_fields.rb
|
|
220
|
+
- examples/datatype_standalone.rb
|
|
197
221
|
- examples/encrypted_fields.rb
|
|
198
222
|
- examples/json_usage_patterns.rb
|
|
199
223
|
- examples/relationships.rb
|
|
200
224
|
- examples/safe_dump.rb
|
|
225
|
+
- examples/sampling_demo.rb
|
|
201
226
|
- examples/single_connection_transaction_confusions.rb
|
|
202
227
|
- familia.gemspec
|
|
203
228
|
- lib/familia.rb
|
|
204
229
|
- lib/familia/base.rb
|
|
205
230
|
- lib/familia/connection.rb
|
|
231
|
+
- lib/familia/connection/behavior.rb
|
|
206
232
|
- lib/familia/connection/handlers.rb
|
|
207
233
|
- lib/familia/connection/individual_command_proxy.rb
|
|
208
234
|
- lib/familia/connection/middleware.rb
|
|
209
235
|
- lib/familia/connection/operation_core.rb
|
|
210
236
|
- lib/familia/connection/operations.rb
|
|
211
|
-
- lib/familia/connection/
|
|
237
|
+
- lib/familia/connection/pipelined_core.rb
|
|
212
238
|
- lib/familia/connection/transaction_core.rb
|
|
213
239
|
- lib/familia/data_type.rb
|
|
214
240
|
- lib/familia/data_type/class_methods.rb
|
|
@@ -248,11 +274,14 @@ files:
|
|
|
248
274
|
- lib/familia/features/relationships/collection_operations.rb
|
|
249
275
|
- lib/familia/features/relationships/indexing.rb
|
|
250
276
|
- lib/familia/features/relationships/indexing/multi_index_generators.rb
|
|
277
|
+
- lib/familia/features/relationships/indexing/rebuild_strategies.rb
|
|
251
278
|
- lib/familia/features/relationships/indexing/unique_index_generators.rb
|
|
252
279
|
- lib/familia/features/relationships/indexing_relationship.rb
|
|
253
280
|
- lib/familia/features/relationships/participation.rb
|
|
254
281
|
- lib/familia/features/relationships/participation/participant_methods.rb
|
|
282
|
+
- lib/familia/features/relationships/participation/rebuild_strategies.md
|
|
255
283
|
- lib/familia/features/relationships/participation/target_methods.rb
|
|
284
|
+
- lib/familia/features/relationships/participation_membership.rb
|
|
256
285
|
- lib/familia/features/relationships/participation_relationship.rb
|
|
257
286
|
- lib/familia/features/relationships/score_encoding.rb
|
|
258
287
|
- lib/familia/features/safe_dump.rb
|
|
@@ -272,6 +301,7 @@ files:
|
|
|
272
301
|
- lib/familia/horreum/settings.rb
|
|
273
302
|
- lib/familia/horreum/utils.rb
|
|
274
303
|
- lib/familia/identifier_extractor.rb
|
|
304
|
+
- lib/familia/instrumentation.rb
|
|
275
305
|
- lib/familia/json_serializer.rb
|
|
276
306
|
- lib/familia/logging.rb
|
|
277
307
|
- lib/familia/refinements.rb
|
|
@@ -280,9 +310,12 @@ files:
|
|
|
280
310
|
- lib/familia/refinements/time_literals.rb
|
|
281
311
|
- lib/familia/secure_identifier.rb
|
|
282
312
|
- lib/familia/settings.rb
|
|
313
|
+
- lib/familia/thread_safety/instrumented_mutex.rb
|
|
314
|
+
- lib/familia/thread_safety/monitor.rb
|
|
283
315
|
- lib/familia/utils.rb
|
|
284
316
|
- lib/familia/verifiable_identifier.rb
|
|
285
317
|
- lib/familia/version.rb
|
|
318
|
+
- lib/middleware/database_command_counter.rb
|
|
286
319
|
- lib/middleware/database_logger.rb
|
|
287
320
|
- lib/multi_result.rb
|
|
288
321
|
- pr_agent.toml
|
|
@@ -330,11 +363,15 @@ files:
|
|
|
330
363
|
- try/features/quantization/quantization_try.rb
|
|
331
364
|
- try/features/real_feature_integration_try.rb
|
|
332
365
|
- try/features/relationships/indexing_commands_verification_try.rb
|
|
366
|
+
- try/features/relationships/indexing_rebuild_try.rb
|
|
333
367
|
- try/features/relationships/indexing_try.rb
|
|
368
|
+
- try/features/relationships/participation_bidirectional_try.rb
|
|
334
369
|
- try/features/relationships/participation_commands_verification_spec.rb
|
|
335
370
|
- try/features/relationships/participation_commands_verification_try.rb
|
|
336
371
|
- try/features/relationships/participation_performance_improvements_try.rb
|
|
337
372
|
- try/features/relationships/participation_reverse_index_try.rb
|
|
373
|
+
- try/features/relationships/participation_target_class_resolution_try.rb
|
|
374
|
+
- try/features/relationships/participation_unresolved_target_try.rb
|
|
338
375
|
- try/features/relationships/relationships_api_changes_try.rb
|
|
339
376
|
- try/features/relationships/relationships_edge_cases_try.rb
|
|
340
377
|
- try/features/relationships/relationships_performance_minimal_try.rb
|
|
@@ -366,6 +403,8 @@ files:
|
|
|
366
403
|
- try/integration/conventional_inheritance_try.rb
|
|
367
404
|
- try/integration/create_method_try.rb
|
|
368
405
|
- try/integration/cross_component_try.rb
|
|
406
|
+
- try/integration/data_types/datatype_pipelines_try.rb
|
|
407
|
+
- try/integration/data_types/datatype_transactions_try.rb
|
|
369
408
|
- try/integration/database_consistency_try.rb
|
|
370
409
|
- try/integration/familia_extended_try.rb
|
|
371
410
|
- try/integration/familia_members_methods_try.rb
|
|
@@ -375,10 +414,15 @@ files:
|
|
|
375
414
|
- try/integration/models/familia_object_try.rb
|
|
376
415
|
- try/integration/persistence_operations_try.rb
|
|
377
416
|
- try/integration/relationships_persistence_round_trip_try.rb
|
|
417
|
+
- try/integration/save_methods_consistency_try.rb
|
|
378
418
|
- try/integration/scenarios_try.rb
|
|
379
419
|
- try/integration/secure_identifier_try.rb
|
|
420
|
+
- try/integration/transaction_safety_core_try.rb
|
|
421
|
+
- try/integration/transaction_safety_workflow_try.rb
|
|
380
422
|
- try/integration/verifiable_identifier_try.rb
|
|
423
|
+
- try/investigation/pipeline_routing/README.md
|
|
381
424
|
- try/performance/benchmarks_try.rb
|
|
425
|
+
- try/performance/transaction_safety_benchmark_try.rb
|
|
382
426
|
- try/support/benchmarks/deserialization_benchmark.rb
|
|
383
427
|
- try/support/benchmarks/deserialization_correctness_test.rb
|
|
384
428
|
- try/support/debugging/README.md
|
|
@@ -428,6 +472,18 @@ files:
|
|
|
428
472
|
- try/support/prototypes/pooling/lib/visualize_stress_results.rb
|
|
429
473
|
- try/support/prototypes/pooling/pool_siege.rb
|
|
430
474
|
- try/support/prototypes/pooling/run_stress_tests.rb
|
|
475
|
+
- try/thread_safety/README.md
|
|
476
|
+
- try/thread_safety/class_connection_chain_race_try.rb
|
|
477
|
+
- try/thread_safety/connection_chain_race_try.rb
|
|
478
|
+
- try/thread_safety/encryption_manager_cache_race_try.rb
|
|
479
|
+
- try/thread_safety/feature_registry_race_try.rb
|
|
480
|
+
- try/thread_safety/fiber_pipeline_isolation_try.rb
|
|
481
|
+
- try/thread_safety/fiber_transaction_isolation_try.rb
|
|
482
|
+
- try/thread_safety/field_registration_race_try.rb
|
|
483
|
+
- try/thread_safety/logger_initialization_race_try.rb
|
|
484
|
+
- try/thread_safety/middleware_registration_race_try.rb
|
|
485
|
+
- try/thread_safety/module_config_race_try.rb
|
|
486
|
+
- try/thread_safety/secure_identifier_cache_race_try.rb
|
|
431
487
|
- try/unit/core/autoloader_try.rb
|
|
432
488
|
- try/unit/core/base_enhancements_try.rb
|
|
433
489
|
- try/unit/core/connection_try.rb
|
|
@@ -435,6 +491,9 @@ files:
|
|
|
435
491
|
- try/unit/core/extensions_try.rb
|
|
436
492
|
- try/unit/core/familia_logger_try.rb
|
|
437
493
|
- try/unit/core/familia_try.rb
|
|
494
|
+
- try/unit/core/middleware_sampling_try.rb
|
|
495
|
+
- try/unit/core/middleware_test_helpers_bug_try.rb
|
|
496
|
+
- try/unit/core/middleware_thread_safety_try.rb
|
|
438
497
|
- try/unit/core/middleware_try.rb
|
|
439
498
|
- try/unit/core/settings_try.rb
|
|
440
499
|
- try/unit/core/time_utils_try.rb
|
|
@@ -450,7 +509,9 @@ files:
|
|
|
450
509
|
- try/unit/data_types/sorted_set_zadd_options_try.rb
|
|
451
510
|
- try/unit/data_types/string_try.rb
|
|
452
511
|
- try/unit/data_types/unsortedset_try.rb
|
|
512
|
+
- try/unit/familia_resolve_class_try.rb
|
|
453
513
|
- try/unit/horreum/auto_indexing_on_save_try.rb
|
|
514
|
+
- try/unit/horreum/automatic_index_validation_try.rb
|
|
454
515
|
- try/unit/horreum/base_try.rb
|
|
455
516
|
- try/unit/horreum/class_methods_try.rb
|
|
456
517
|
- try/unit/horreum/commands_try.rb
|
|
@@ -461,14 +522,20 @@ files:
|
|
|
461
522
|
- try/unit/horreum/field_definition_try.rb
|
|
462
523
|
- try/unit/horreum/initialization_try.rb
|
|
463
524
|
- try/unit/horreum/json_type_preservation_try.rb
|
|
525
|
+
- try/unit/horreum/optimized_loading_try.rb
|
|
464
526
|
- try/unit/horreum/relations_try.rb
|
|
465
527
|
- try/unit/horreum/serialization_persistent_fields_try.rb
|
|
466
528
|
- try/unit/horreum/serialization_try.rb
|
|
467
529
|
- try/unit/horreum/settings_try.rb
|
|
530
|
+
- try/unit/horreum/unique_index_edge_cases_try.rb
|
|
531
|
+
- try/unit/horreum/unique_index_guard_validation_try.rb
|
|
532
|
+
- try/unit/middleware/database_command_counter_methods_try.rb
|
|
533
|
+
- try/unit/middleware/database_logger_methods_try.rb
|
|
468
534
|
- try/unit/refinements/dear_json_array_methods_try.rb
|
|
469
535
|
- try/unit/refinements/dear_json_hash_methods_try.rb
|
|
470
536
|
- try/unit/refinements/time_literals_numeric_methods_try.rb
|
|
471
537
|
- try/unit/refinements/time_literals_string_methods_try.rb
|
|
538
|
+
- try/unit/thread_safety_monitor_try.rb
|
|
472
539
|
- try/valkey.conf
|
|
473
540
|
homepage: https://github.com/delano/familia
|
|
474
541
|
licenses:
|
|
@@ -482,14 +549,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
482
549
|
requirements:
|
|
483
550
|
- - ">="
|
|
484
551
|
- !ruby/object:Gem::Version
|
|
485
|
-
version:
|
|
552
|
+
version: 3.3.6
|
|
486
553
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
487
554
|
requirements:
|
|
488
555
|
- - ">="
|
|
489
556
|
- !ruby/object:Gem::Version
|
|
490
557
|
version: '0'
|
|
491
558
|
requirements: []
|
|
492
|
-
rubygems_version: 3.
|
|
559
|
+
rubygems_version: 3.7.2
|
|
493
560
|
specification_version: 4
|
|
494
561
|
summary: An ORM for Valkey-compatible databases in Ruby.
|
|
495
562
|
test_files: []
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
name: Code Quality
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
branches: [ main ]
|
|
6
|
-
push:
|
|
7
|
-
branches: [ main ]
|
|
8
|
-
workflow_dispatch:
|
|
9
|
-
|
|
10
|
-
permissions:
|
|
11
|
-
contents: read
|
|
12
|
-
pull-requests: write # Needed to post comments on PRs
|
|
13
|
-
|
|
14
|
-
jobs:
|
|
15
|
-
reek:
|
|
16
|
-
name: Reek Code Analysis
|
|
17
|
-
runs-on: ubuntu-24.04
|
|
18
|
-
timeout-minutes: 5
|
|
19
|
-
|
|
20
|
-
steps:
|
|
21
|
-
- name: Checkout code
|
|
22
|
-
uses: actions/checkout@v4
|
|
23
|
-
|
|
24
|
-
- name: Set up Ruby
|
|
25
|
-
uses: ruby/setup-ruby@v1
|
|
26
|
-
with:
|
|
27
|
-
ruby-version: 3.4
|
|
28
|
-
bundler-cache: true
|
|
29
|
-
|
|
30
|
-
- name: Configure Bundler for secure gem installation
|
|
31
|
-
run: |
|
|
32
|
-
bundle config set --local path 'vendor/bundle'
|
|
33
|
-
bundle config set --local deployment 'false'
|
|
34
|
-
|
|
35
|
-
- name: Install dependencies
|
|
36
|
-
run: bundle install
|
|
37
|
-
|
|
38
|
-
- name: Run Reek analysis
|
|
39
|
-
run: |
|
|
40
|
-
echo "=== Running Reek code analysis ==="
|
|
41
|
-
echo "This analysis identifies code smells and potential improvements."
|
|
42
|
-
echo "Results are informational and won't fail the build."
|
|
43
|
-
echo ""
|
|
44
|
-
|
|
45
|
-
# Run reek and capture output (don't fail on warnings)
|
|
46
|
-
# Use success-exit-code to prevent failures from stopping the analysis
|
|
47
|
-
bundle exec reek --format=text --success-exit-code 0 --failure-exit-code 0 || true
|
|
48
|
-
|
|
49
|
-
echo ""
|
|
50
|
-
echo "=== Reek analysis complete ==="
|
|
51
|
-
continue-on-error: true # Don't fail the build on code smells
|
|
52
|
-
|
|
53
|
-
- name: Generate Reek report (if analysis available)
|
|
54
|
-
run: |
|
|
55
|
-
echo "=== Generating detailed Reek report ==="
|
|
56
|
-
|
|
57
|
-
# Generate JSON report for potential future processing
|
|
58
|
-
bundle exec reek --format=json --success-exit-code 0 --failure-exit-code 0 > reek-report.json || true
|
|
59
|
-
|
|
60
|
-
# Display summary
|
|
61
|
-
if [ -s reek-report.json ]; then
|
|
62
|
-
echo "Reek JSON report generated: $(wc -l < reek-report.json) lines"
|
|
63
|
-
echo "Top code smell types found:"
|
|
64
|
-
jq -r '.[].smells[].smell_type' reek-report.json 2>/dev/null | sort | uniq -c | sort -rn | head -10 || echo "Unable to parse JSON report"
|
|
65
|
-
else
|
|
66
|
-
echo "No code smells detected or analysis failed"
|
|
67
|
-
fi
|
|
68
|
-
continue-on-error: true
|
|
69
|
-
|
|
70
|
-
- name: Upload Reek report as artifact
|
|
71
|
-
uses: actions/upload-artifact@v4
|
|
72
|
-
if: always()
|
|
73
|
-
with:
|
|
74
|
-
name: reek-report
|
|
75
|
-
path: reek-report.json
|
|
76
|
-
retention-days: 30
|
|
77
|
-
|
|
78
|
-
# Add other code quality checks here
|
|
79
|
-
additional-quality-checks:
|
|
80
|
-
name: Additional Quality Checks
|
|
81
|
-
runs-on: ubuntu-24.04
|
|
82
|
-
timeout-minutes: 5
|
|
83
|
-
|
|
84
|
-
steps:
|
|
85
|
-
- name: Checkout code
|
|
86
|
-
uses: actions/checkout@v4
|
|
87
|
-
|
|
88
|
-
- name: Set up Ruby
|
|
89
|
-
uses: ruby/setup-ruby@v1
|
|
90
|
-
with:
|
|
91
|
-
ruby-version: 3.4
|
|
92
|
-
bundler-cache: true
|
|
93
|
-
|
|
94
|
-
- name: Configure Bundler for secure gem installation
|
|
95
|
-
run: |
|
|
96
|
-
bundle config set --local path 'vendor/bundle'
|
|
97
|
-
bundle config set --local deployment 'false'
|
|
98
|
-
|
|
99
|
-
- name: Install dependencies
|
|
100
|
-
run: bundle install
|
|
101
|
-
|
|
102
|
-
- name: Check for TODO/FIXME comments
|
|
103
|
-
run: |
|
|
104
|
-
echo "=== Scanning for TODO/FIXME comments ==="
|
|
105
|
-
echo "This helps track technical debt and action items."
|
|
106
|
-
echo ""
|
|
107
|
-
|
|
108
|
-
# Find TODO/FIXME comments (excluding this workflow file)
|
|
109
|
-
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
110
|
-
xargs grep -Hn -i -E "(TODO|FIXME|HACK|XXX|NOTE):" 2>/dev/null | \
|
|
111
|
-
head -20 || echo "No TODO/FIXME comments found"
|
|
112
|
-
continue-on-error: true
|
|
113
|
-
|
|
114
|
-
- name: Check Ruby file syntax
|
|
115
|
-
run: |
|
|
116
|
-
echo "=== Checking Ruby syntax ==="
|
|
117
|
-
echo "Validates that all Ruby files have correct syntax."
|
|
118
|
-
echo ""
|
|
119
|
-
|
|
120
|
-
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
121
|
-
while read -r file; do
|
|
122
|
-
if ! ruby -c "$file" > /dev/null 2>&1; then
|
|
123
|
-
echo "Syntax error in: $file"
|
|
124
|
-
ruby -c "$file"
|
|
125
|
-
fi
|
|
126
|
-
done
|
|
127
|
-
continue-on-error: true
|
|
128
|
-
|
|
129
|
-
- name: Check for long lines
|
|
130
|
-
run: |
|
|
131
|
-
echo "=== Checking for long lines (>120 characters) ==="
|
|
132
|
-
echo "Identifies potentially hard-to-read code lines."
|
|
133
|
-
echo ""
|
|
134
|
-
|
|
135
|
-
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
136
|
-
xargs grep -Hn "^.\{121,\}$" | \
|
|
137
|
-
head -10 || echo "No overly long lines found"
|
|
138
|
-
continue-on-error: true
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
# Relationship methods
|
|
2
|
-
|
|
3
|
-
here are the methods automatically generated for each relationship type:
|
|
4
|
-
|
|
5
|
-
member_of Relationships
|
|
6
|
-
|
|
7
|
-
When you declare:
|
|
8
|
-
class Domain < Familia::Horreum
|
|
9
|
-
member_of Customer, :domains, type: :set
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
Generated methods on Domain instances:
|
|
13
|
-
- add_to_customer_domains(customer_id) - Add this domain to customer's domains collection
|
|
14
|
-
- remove_from_customer_domains(customer_id) - Remove this domain from customer's domains collection
|
|
15
|
-
- in_customer_domains?(customer_id) - Check if this domain is in customer's domains collection
|
|
16
|
-
|
|
17
|
-
The method names follow the pattern: {action}_to_{lowercase_class_name}_{collection_name}
|
|
18
|
-
|
|
19
|
-
participates_in Relationships
|
|
20
|
-
|
|
21
|
-
When you declare:
|
|
22
|
-
class Customer < Familia::Horreum
|
|
23
|
-
participates_in :all_customers, type: :sorted_set, score: :created_at
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
Generated class methods:
|
|
27
|
-
- Customer.add_to_all_customers(customer) - Add customer to global tracking
|
|
28
|
-
- Customer.remove_from_all_customers(customer) - Remove customer from global tracking
|
|
29
|
-
- Customer.all_customers - Access the sorted set collection directly
|
|
30
|
-
|
|
31
|
-
For scoped tracking (with class prefix):
|
|
32
|
-
participates_in :global, :active_users, score: :last_seen
|
|
33
|
-
Generates: Customer.add_to_active_users(customer) and Customer.active_users
|
|
34
|
-
|
|
35
|
-
indexed_by Relationships
|
|
36
|
-
|
|
37
|
-
The `indexed_by` method creates Valkey/Redis hash-based indexes for O(1) field lookups. The `context` parameter determines index ownership and scope.
|
|
38
|
-
|
|
39
|
-
**Global Context (Shared Index)**
|
|
40
|
-
When you declare:
|
|
41
|
-
```ruby
|
|
42
|
-
class Customer < Familia::Horreum
|
|
43
|
-
indexed_by :email, :email_lookup, target: :global
|
|
44
|
-
end
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Generated class methods:
|
|
48
|
-
- Customer.add_to_email_lookup(customer) - Add customer to global email index
|
|
49
|
-
- Customer.remove_from_email_lookup(customer) - Remove customer from global email index
|
|
50
|
-
- Customer.email_lookup - Access the global hash index directly (supports .get(email))
|
|
51
|
-
|
|
52
|
-
Valkey/Redis key pattern: `global:email_lookup`
|
|
53
|
-
|
|
54
|
-
**Class Context (Per-Instance Index)**
|
|
55
|
-
When you declare:
|
|
56
|
-
```ruby
|
|
57
|
-
class Domain < Familia::Horreum
|
|
58
|
-
indexed_by :name, :domain_index, target: Customer
|
|
59
|
-
end
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Generated class methods on Customer:
|
|
63
|
-
- Customer.find_by_name(domain_name) - Find domain by name within this customer
|
|
64
|
-
- Customer.find_all_by_name(domain_names) - Find multiple domains by names
|
|
65
|
-
|
|
66
|
-
Valkey/Redis key pattern: `customer:123:domain_index` (per customer instance)
|
|
67
|
-
|
|
68
|
-
**When to Use Each Context**
|
|
69
|
-
- **Global context (`:global`)**: Use for system-wide lookups where the field value should be unique across all instances
|
|
70
|
-
- Examples: email addresses, usernames, API keys
|
|
71
|
-
- **Class context (e.g., `Customer`)**: Use for scoped lookups where the field value is unique within a specific parent object
|
|
72
|
-
- Examples: domain names per customer, project names per team
|
|
73
|
-
|
|
74
|
-
Example from the Codebase
|
|
75
|
-
|
|
76
|
-
From the relationships example file, you can see this in action:
|
|
77
|
-
|
|
78
|
-
# Domain declares membership in Customer collections
|
|
79
|
-
class Domain < Familia::Horreum
|
|
80
|
-
member_of Customer, :domains, type: :set
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# This generates these methods on Domain instances:
|
|
84
|
-
domain.add_to_customer_domains(customer.custid) # Add to relationship
|
|
85
|
-
domain.remove_from_customer_domains(customer.custid) # Remove from relationship
|
|
86
|
-
domain.in_customer_domains?(customer.custid) # Query membership
|
|
87
|
-
|
|
88
|
-
# For participates_in relationships:
|
|
89
|
-
Customer.add_to_all_customers(customer) # Class method
|
|
90
|
-
Customer.all_customers.range(0, -1) # Direct collection access
|
|
91
|
-
|
|
92
|
-
# For indexed_by relationships:
|
|
93
|
-
Customer.add_to_email_lookup(customer) # Class method
|
|
94
|
-
Customer.email_lookup.get("user@example.com") # O(1) lookup
|
|
95
|
-
|
|
96
|
-
Method Naming Conventions
|
|
97
|
-
|
|
98
|
-
The relationship system uses consistent naming patterns:
|
|
99
|
-
- member_of: {add_to|remove_from|in}_#{parent_class.downcase}_#{collection_name}
|
|
100
|
-
- participates_in: {add_to|remove_from}_#{collection_name} (class methods)
|
|
101
|
-
- indexed_by: {add_to|remove_from}_#{index_name} (class methods)
|
|
102
|
-
|
|
103
|
-
This automatic method generation creates a clean, predictable API that handles both the db operations and maintains referential consistency
|
|
104
|
-
across related objects.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
## Context Parameter Usage Patterns
|
|
108
|
-
|
|
109
|
-
The `context` parameter in `indexed_by` is a fundamental architectural decision that determines index scope and ownership. Here are practical patterns for when to use each approach:
|
|
110
|
-
|
|
111
|
-
### Global Context Pattern
|
|
112
|
-
Use `context: :global` when field values should be unique system-wide:
|
|
113
|
-
|
|
114
|
-
```ruby
|
|
115
|
-
class User < Familia::Horreum
|
|
116
|
-
feature :relationships
|
|
117
|
-
|
|
118
|
-
identifier_field :user_id
|
|
119
|
-
field :user_id, :email, :username
|
|
120
|
-
|
|
121
|
-
# System-wide unique email lookup
|
|
122
|
-
indexed_by :email, :email_lookup, target: :global
|
|
123
|
-
indexed_by :username, :username_lookup, target: :global
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# Usage:
|
|
127
|
-
User.add_to_email_lookup(user)
|
|
128
|
-
found_user_id = User.email_lookup.get("john@example.com")
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
**Valkey/Redis keys generated**: `global:email_lookup`, `global:username_lookup`
|
|
132
|
-
|
|
133
|
-
### Class Context Pattern
|
|
134
|
-
Use `context: SomeClass` when field values are unique within a specific parent context:
|
|
135
|
-
|
|
136
|
-
```ruby
|
|
137
|
-
class Customer < Familia::Horreum
|
|
138
|
-
feature :relationships
|
|
139
|
-
|
|
140
|
-
identifier_field :custid
|
|
141
|
-
field :custid, :name
|
|
142
|
-
sorted_set :domains
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
class Domain < Familia::Horreum
|
|
146
|
-
feature :relationships
|
|
147
|
-
|
|
148
|
-
identifier_field :domain_id
|
|
149
|
-
field :domain_id, :name, :subdomain
|
|
150
|
-
|
|
151
|
-
# Domains are unique per customer (customer can't have duplicate domain names)
|
|
152
|
-
indexed_by :name, :domain_index, target: Customer
|
|
153
|
-
indexed_by :subdomain, :subdomain_index, target: Customer
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
# Usage:
|
|
157
|
-
customer = Customer.new(custid: "cust_123")
|
|
158
|
-
customer.find_by_name("example.com") # Find domain within this customer
|
|
159
|
-
customer.find_all_by_subdomain(["www", "api"]) # Find multiple subdomains
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
**Valkey/Redis keys generated**: `customer:cust_123:domain_index`, `customer:cust_123:subdomain_index`
|
|
163
|
-
|
|
164
|
-
### Mixed Pattern Example
|
|
165
|
-
A real-world example showing both patterns:
|
|
166
|
-
|
|
167
|
-
```ruby
|
|
168
|
-
class ApiKey < Familia::Horreum
|
|
169
|
-
feature :relationships
|
|
170
|
-
|
|
171
|
-
identifier_field :key_id
|
|
172
|
-
field :key_id, :key_hash, :name, :scope
|
|
173
|
-
|
|
174
|
-
# API key hashes must be globally unique
|
|
175
|
-
indexed_by :key_hash, :global_key_lookup, target: :global
|
|
176
|
-
|
|
177
|
-
# But key names can be reused across different customers
|
|
178
|
-
indexed_by :name, :customer_key_lookup, target: Customer
|
|
179
|
-
indexed_by :scope, :scope_lookup, target: Customer
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
# Usage examples:
|
|
183
|
-
# Global lookup (system-wide unique)
|
|
184
|
-
ApiKey.key_lookup.get("sha256:abc123...")
|
|
185
|
-
|
|
186
|
-
# Scoped lookup (unique per customer)
|
|
187
|
-
customer = Customer.new(custid: "cust_456")
|
|
188
|
-
customer.find_by_name("production-api-key")
|
|
189
|
-
customer.find_all_by_scope(["read", "write"])
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### Migrating Guide
|
|
193
|
-
If you have existing code with incorrect syntax, here's how to fix it:
|
|
194
|
-
|
|
195
|
-
```ruby
|
|
196
|
-
# ❌ Old incorrect syntax
|
|
197
|
-
indexed_by :email_lookup, field: :email
|
|
198
|
-
|
|
199
|
-
# ✅ New correct syntax - Global scope
|
|
200
|
-
indexed_by :email, :email_lookup, target: :global
|
|
201
|
-
|
|
202
|
-
# ✅ New correct syntax - Class scope
|
|
203
|
-
indexed_by :email, :customer_email_lookup, target: Customer
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
**Key Differences**:
|
|
207
|
-
1. Parameter order: `indexed_by(field, index_name, context:)`
|
|
208
|
-
2. The `field:` named parameter is now positional
|
|
209
|
-
3. The `context:` parameter is required and determines scope
|
|
210
|
-
4. Index name comes second (allows same field to have multiple indexes)
|