familia 2.0.0.pre15 → 2.0.0.pre16

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 (274) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/code-quality.yml +138 -0
  3. data/.github/workflows/code-smellage.yml +145 -0
  4. data/.github/workflows/docs.yml +31 -8
  5. data/.gitignore +1 -1
  6. data/.pre-commit-config.yaml +7 -1
  7. data/.reek.yml +98 -0
  8. data/.rubocop.yml +48 -10
  9. data/.talismanrc +9 -0
  10. data/.yardopts +18 -13
  11. data/CHANGELOG.rst +64 -4
  12. data/CLAUDE.md +1 -1
  13. data/Gemfile +6 -5
  14. data/Gemfile.lock +99 -23
  15. data/LICENSE.txt +1 -1
  16. data/README.md +285 -85
  17. data/changelog.d/README.md +2 -2
  18. data/docs/archive/FAMILIA_RELATIONSHIPS.md +22 -22
  19. data/docs/archive/FAMILIA_TECHNICAL.md +41 -41
  20. data/docs/archive/FAMILIA_UPDATE.md +3 -3
  21. data/docs/archive/README.md +3 -2
  22. data/docs/{guides/API-Reference.md → archive/api-reference.md} +87 -101
  23. data/docs/conf.py +29 -0
  24. data/docs/guides/{Field-System-Guide.md → core-field-system.md} +9 -9
  25. data/docs/guides/feature-encrypted-fields.md +785 -0
  26. data/docs/guides/{Expiration-Feature-Guide.md → feature-expiration.md} +11 -2
  27. data/docs/guides/feature-external-identifiers.md +637 -0
  28. data/docs/guides/feature-object-identifiers.md +435 -0
  29. data/docs/guides/{Quantization-Feature-Guide.md → feature-quantization.md} +94 -29
  30. data/docs/guides/feature-relationships-methods.md +684 -0
  31. data/docs/guides/feature-relationships.md +200 -0
  32. data/docs/guides/{Features-System-Developer-Guide.md → feature-system-devs.md} +4 -4
  33. data/docs/guides/{Feature-System-Guide.md → feature-system.md} +5 -5
  34. data/docs/guides/{Transient-Fields-Guide.md → feature-transient-fields.md} +2 -2
  35. data/docs/guides/{Implementation-Guide.md → implementation.md} +3 -3
  36. data/docs/guides/index.md +176 -0
  37. data/docs/guides/{Security-Model.md → security-model.md} +1 -1
  38. data/docs/migrating/v2.0.0-pre.md +1 -1
  39. data/docs/migrating/v2.0.0-pre11.md +2 -2
  40. data/docs/migrating/v2.0.0-pre12.md +2 -2
  41. data/docs/migrating/v2.0.0-pre5.md +33 -12
  42. data/docs/migrating/v2.0.0-pre6.md +2 -2
  43. data/docs/migrating/v2.0.0-pre7.md +8 -8
  44. data/docs/overview.md +623 -19
  45. data/docs/reference/api-technical.md +1365 -0
  46. data/examples/autoloader/mega_customer/features/deprecated_fields.rb +7 -0
  47. data/examples/autoloader/mega_customer/safe_dump_fields.rb +1 -1
  48. data/examples/autoloader/mega_customer.rb +3 -1
  49. data/examples/encrypted_fields.rb +378 -0
  50. data/examples/json_usage_patterns.rb +144 -0
  51. data/examples/relationships.rb +13 -13
  52. data/examples/safe_dump.rb +6 -6
  53. data/examples/single_connection_transaction_confusions.rb +379 -0
  54. data/lib/familia/base.rb +49 -10
  55. data/lib/familia/connection/handlers.rb +223 -0
  56. data/lib/familia/connection/individual_command_proxy.rb +64 -0
  57. data/lib/familia/connection/middleware.rb +75 -0
  58. data/lib/familia/connection/operation_core.rb +93 -0
  59. data/lib/familia/connection/operations.rb +277 -0
  60. data/lib/familia/connection/pipeline_core.rb +87 -0
  61. data/lib/familia/connection/transaction_core.rb +100 -0
  62. data/lib/familia/connection.rb +60 -186
  63. data/lib/familia/data_type/commands.rb +53 -51
  64. data/lib/familia/data_type/serialization.rb +108 -107
  65. data/lib/familia/data_type/types/counter.rb +1 -1
  66. data/lib/familia/data_type/types/hashkey.rb +13 -10
  67. data/lib/familia/data_type/types/{list.rb → listkey.rb} +13 -5
  68. data/lib/familia/data_type/types/lock.rb +3 -2
  69. data/lib/familia/data_type/types/sorted_set.rb +26 -15
  70. data/lib/familia/data_type/types/{string.rb → stringkey.rb} +7 -5
  71. data/lib/familia/data_type/types/unsorted_set.rb +20 -27
  72. data/lib/familia/data_type.rb +75 -47
  73. data/lib/familia/distinguisher.rb +85 -0
  74. data/lib/familia/encryption/encrypted_data.rb +15 -24
  75. data/lib/familia/encryption/manager.rb +6 -4
  76. data/lib/familia/encryption/providers/aes_gcm_provider.rb +1 -1
  77. data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +7 -9
  78. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +4 -5
  79. data/lib/familia/encryption/request_cache.rb +7 -7
  80. data/lib/familia/encryption.rb +2 -3
  81. data/lib/familia/errors.rb +9 -3
  82. data/lib/familia/features/autoloader.rb +30 -12
  83. data/lib/familia/features/encrypted_fields/concealed_string.rb +3 -4
  84. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +13 -14
  85. data/lib/familia/features/encrypted_fields.rb +66 -64
  86. data/lib/familia/features/expiration/extensions.rb +1 -1
  87. data/lib/familia/features/expiration.rb +31 -26
  88. data/lib/familia/features/external_identifier.rb +9 -12
  89. data/lib/familia/features/object_identifier.rb +56 -19
  90. data/lib/familia/features/quantization.rb +16 -21
  91. data/lib/familia/features/relationships/README.md +97 -0
  92. data/lib/familia/features/relationships/collection_operations.rb +104 -0
  93. data/lib/familia/features/relationships/indexing/multi_index_generators.rb +202 -0
  94. data/lib/familia/features/relationships/indexing/unique_index_generators.rb +301 -0
  95. data/lib/familia/features/relationships/indexing.rb +176 -256
  96. data/lib/familia/features/relationships/indexing_relationship.rb +35 -0
  97. data/lib/familia/features/relationships/participation/participant_methods.rb +160 -0
  98. data/lib/familia/features/relationships/participation/target_methods.rb +225 -0
  99. data/lib/familia/features/relationships/participation.rb +656 -0
  100. data/lib/familia/features/relationships/participation_relationship.rb +31 -0
  101. data/lib/familia/features/relationships/score_encoding.rb +20 -20
  102. data/lib/familia/features/relationships.rb +65 -266
  103. data/lib/familia/features/safe_dump.rb +127 -130
  104. data/lib/familia/features/transient_fields/redacted_string.rb +6 -6
  105. data/lib/familia/features/transient_fields/transient_field_type.rb +5 -5
  106. data/lib/familia/features/transient_fields.rb +3 -5
  107. data/lib/familia/features.rb +4 -13
  108. data/lib/familia/field_type.rb +24 -4
  109. data/lib/familia/horreum/core/connection.rb +229 -26
  110. data/lib/familia/horreum/core/database_commands.rb +27 -17
  111. data/lib/familia/horreum/core/serialization.rb +40 -20
  112. data/lib/familia/horreum/core/utils.rb +2 -1
  113. data/lib/familia/horreum/shared/settings.rb +2 -1
  114. data/lib/familia/horreum/subclass/definition.rb +33 -45
  115. data/lib/familia/horreum/subclass/management.rb +72 -24
  116. data/lib/familia/horreum/subclass/related_fields_management.rb +82 -21
  117. data/lib/familia/horreum.rb +196 -114
  118. data/lib/familia/json_serializer.rb +0 -1
  119. data/lib/familia/logging.rb +11 -114
  120. data/lib/familia/refinements/dear_json.rb +122 -0
  121. data/lib/familia/refinements/logger_trace.rb +20 -17
  122. data/lib/familia/refinements/stylize_words.rb +65 -0
  123. data/lib/familia/refinements/time_literals.rb +60 -52
  124. data/lib/familia/refinements.rb +2 -1
  125. data/lib/familia/secure_identifier.rb +60 -28
  126. data/lib/familia/settings.rb +83 -7
  127. data/lib/familia/utils.rb +5 -87
  128. data/lib/familia/verifiable_identifier.rb +4 -4
  129. data/lib/familia/version.rb +1 -1
  130. data/lib/familia.rb +72 -14
  131. data/lib/middleware/database_middleware.rb +56 -14
  132. data/lib/{familia/multi_result.rb → multi_result.rb} +23 -16
  133. data/try/configuration/scenarios_try.rb +1 -1
  134. data/try/connection/fiber_context_preservation_try.rb +250 -0
  135. data/try/connection/handler_constraints_try.rb +59 -0
  136. data/try/connection/operation_mode_guards_try.rb +208 -0
  137. data/try/connection/pipeline_fallback_integration_try.rb +128 -0
  138. data/try/connection/responsibility_chain_tracking_try.rb +72 -0
  139. data/try/connection/transaction_fallback_integration_try.rb +288 -0
  140. data/try/connection/transaction_mode_permissive_try.rb +153 -0
  141. data/try/connection/transaction_mode_strict_try.rb +98 -0
  142. data/try/connection/transaction_mode_warn_try.rb +131 -0
  143. data/try/connection/transaction_modes_try.rb +249 -0
  144. data/try/core/autoloader_try.rb +120 -2
  145. data/try/core/connection_try.rb +7 -7
  146. data/try/core/conventional_inheritance_try.rb +130 -0
  147. data/try/core/create_method_try.rb +15 -23
  148. data/try/core/database_consistency_try.rb +10 -10
  149. data/try/core/errors_try.rb +8 -11
  150. data/try/core/familia_extended_try.rb +2 -2
  151. data/try/core/familia_members_methods_try.rb +76 -0
  152. data/try/core/isolated_dbclient_try.rb +165 -0
  153. data/try/core/middleware_try.rb +16 -16
  154. data/try/core/persistence_operations_try.rb +4 -4
  155. data/try/core/pools_try.rb +42 -26
  156. data/try/core/secure_identifier_try.rb +28 -24
  157. data/try/core/time_utils_try.rb +10 -10
  158. data/try/core/tools_try.rb +1 -1
  159. data/try/core/utils_try.rb +2 -2
  160. data/try/data_types/boolean_try.rb +4 -4
  161. data/try/data_types/datatype_base_try.rb +0 -2
  162. data/try/data_types/list_try.rb +10 -10
  163. data/try/data_types/sorted_set_try.rb +5 -5
  164. data/try/data_types/string_try.rb +12 -12
  165. data/try/data_types/unsortedset_try.rb +33 -0
  166. data/try/debugging/cache_behavior_tracer.rb +7 -7
  167. data/try/debugging/debug_aad_process.rb +1 -1
  168. data/try/debugging/debug_concealed_internal.rb +1 -1
  169. data/try/debugging/debug_cross_context.rb +1 -1
  170. data/try/debugging/debug_fresh_cross_context.rb +1 -1
  171. data/try/debugging/encryption_method_tracer.rb +10 -10
  172. data/try/edge_cases/hash_symbolization_try.rb +1 -1
  173. data/try/edge_cases/ttl_side_effects_try.rb +1 -1
  174. data/try/encryption/config_persistence_try.rb +2 -2
  175. data/try/encryption/encryption_core_try.rb +19 -19
  176. data/try/encryption/instance_variable_scope_try.rb +1 -1
  177. data/try/encryption/module_loading_try.rb +2 -2
  178. data/try/encryption/providers/aes_gcm_provider_try.rb +1 -1
  179. data/try/encryption/providers/xchacha20_poly1305_provider_try.rb +1 -1
  180. data/try/encryption/secure_memory_handling_try.rb +1 -1
  181. data/try/features/encrypted_fields/concealed_string_core_try.rb +11 -7
  182. data/try/features/encrypted_fields/encrypted_fields_core_try.rb +1 -1
  183. data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +3 -3
  184. data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +10 -10
  185. data/try/features/encrypted_fields/encrypted_fields_security_try.rb +14 -14
  186. data/try/features/encrypted_fields/error_conditions_try.rb +7 -7
  187. data/try/features/encrypted_fields/fresh_key_try.rb +1 -1
  188. data/try/features/encrypted_fields/nonce_uniqueness_try.rb +1 -1
  189. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +7 -7
  190. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +13 -20
  191. data/try/features/external_identifier/external_identifier_try.rb +1 -1
  192. data/try/features/feature_dependencies_try.rb +3 -3
  193. data/try/features/object_identifier/object_identifier_integration_try.rb +28 -34
  194. data/try/features/object_identifier/object_identifier_try.rb +10 -0
  195. data/try/features/quantization/quantization_try.rb +1 -1
  196. data/try/features/relationships/indexing_commands_verification_try.rb +136 -0
  197. data/try/features/relationships/indexing_try.rb +433 -0
  198. data/try/features/relationships/participation_commands_verification_spec.rb +102 -0
  199. data/try/features/relationships/participation_commands_verification_try.rb +105 -0
  200. data/try/features/relationships/participation_performance_improvements_try.rb +124 -0
  201. data/try/features/relationships/participation_reverse_index_try.rb +196 -0
  202. data/try/features/relationships/relationships_api_changes_try.rb +72 -71
  203. data/try/features/relationships/relationships_edge_cases_try.rb +15 -18
  204. data/try/features/relationships/relationships_performance_minimal_try.rb +2 -2
  205. data/try/features/relationships/relationships_performance_simple_try.rb +8 -8
  206. data/try/features/relationships/relationships_performance_try.rb +20 -20
  207. data/try/features/relationships/relationships_try.rb +27 -38
  208. data/try/features/safe_dump/safe_dump_advanced_try.rb +2 -2
  209. data/try/features/transient_fields/refresh_reset_try.rb +1 -1
  210. data/try/features/transient_fields/simple_refresh_test.rb +1 -1
  211. data/try/helpers/test_cleanup.rb +86 -0
  212. data/try/helpers/test_helpers.rb +3 -3
  213. data/try/horreum/base_try.rb +3 -2
  214. data/try/horreum/commands_try.rb +1 -1
  215. data/try/horreum/destroy_related_fields_cleanup_try.rb +330 -0
  216. data/try/horreum/initialization_try.rb +11 -7
  217. data/try/horreum/relations_try.rb +21 -13
  218. data/try/horreum/serialization_try.rb +12 -11
  219. data/try/integration/cross_component_try.rb +3 -3
  220. data/try/memory/memory_basic_test.rb +1 -1
  221. data/try/memory/memory_docker_ruby_dump.sh +1 -1
  222. data/try/models/customer_safe_dump_try.rb +1 -1
  223. data/try/models/customer_try.rb +8 -10
  224. data/try/models/datatype_base_try.rb +3 -3
  225. data/try/models/familia_object_try.rb +9 -8
  226. data/try/performance/benchmarks_try.rb +2 -2
  227. data/try/prototypes/atomic_saves_v1_context_proxy.rb +2 -2
  228. data/try/prototypes/atomic_saves_v3_connection_pool.rb +3 -3
  229. data/try/prototypes/atomic_saves_v4.rb +1 -1
  230. data/try/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -4
  231. data/try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  232. data/try/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  233. data/try/prototypes/pooling/lib/connection_pool_metrics.rb +5 -5
  234. data/try/prototypes/pooling/lib/connection_pool_stress_test.rb +26 -26
  235. data/try/prototypes/pooling/lib/connection_pool_threading_models.rb +7 -7
  236. data/try/prototypes/pooling/lib/visualize_stress_results.rb +1 -1
  237. data/try/prototypes/pooling/pool_siege.rb +11 -11
  238. data/try/prototypes/pooling/run_stress_tests.rb +7 -7
  239. data/try/refinements/dear_json_array_methods_try.rb +53 -0
  240. data/try/refinements/dear_json_hash_methods_try.rb +54 -0
  241. data/try/refinements/logger_trace_methods_try.rb +44 -0
  242. data/try/refinements/time_literals_numeric_methods_try.rb +141 -0
  243. data/try/refinements/time_literals_string_methods_try.rb +80 -0
  244. metadata +75 -43
  245. data/.rubocop_todo.yml +0 -208
  246. data/docs/connection_pooling.md +0 -192
  247. data/docs/guides/Connection-Pooling-Guide.md +0 -437
  248. data/docs/guides/Encrypted-Fields-Overview.md +0 -101
  249. data/docs/guides/Feature-System-Autoloading.md +0 -198
  250. data/docs/guides/Home.md +0 -116
  251. data/docs/guides/Relationships-Guide.md +0 -737
  252. data/docs/guides/relationships-methods.md +0 -266
  253. data/docs/reference/auditing_database_commands.rb +0 -228
  254. data/examples/permissions.rb +0 -240
  255. data/lib/familia/features/relationships/cascading.rb +0 -437
  256. data/lib/familia/features/relationships/membership.rb +0 -497
  257. data/lib/familia/features/relationships/permission_management.rb +0 -264
  258. data/lib/familia/features/relationships/querying.rb +0 -615
  259. data/lib/familia/features/relationships/redis_operations.rb +0 -274
  260. data/lib/familia/features/relationships/tracking.rb +0 -418
  261. data/lib/familia/refinements/snake_case.rb +0 -40
  262. data/lib/familia/validation/command_recorder.rb +0 -336
  263. data/lib/familia/validation/expectations.rb +0 -519
  264. data/lib/familia/validation/validation_helpers.rb +0 -443
  265. data/lib/familia/validation/validator.rb +0 -412
  266. data/lib/familia/validation.rb +0 -140
  267. data/try/data_types/set_try.rb +0 -33
  268. data/try/features/relationships/categorical_permissions_try.rb +0 -515
  269. data/try/features/safe_dump/module_based_extensions_try.rb +0 -100
  270. data/try/features/safe_dump/safe_dump_autoloading_try.rb +0 -107
  271. data/try/validation/atomic_operations_try.rb.disabled +0 -320
  272. data/try/validation/command_validation_try.rb.disabled +0 -207
  273. data/try/validation/performance_validation_try.rb.disabled +0 -324
  274. data/try/validation/real_world_scenarios_try.rb.disabled +0 -390
@@ -0,0 +1,54 @@
1
+ # try/refinements/dear_json_hash_methods_try.rb
2
+
3
+ require_relative '../helpers/test_helpers'
4
+
5
+ class TestHashWithDearJson < Hash
6
+ include Familia::Refinements::DearJsonHashMethods
7
+ end
8
+
9
+ class TestObjectWithAsJson
10
+ def initialize(name)
11
+ @name = name
12
+ end
13
+
14
+ def as_json(options = nil)
15
+ { name: @name, type: 'test_object' }
16
+ end
17
+ end
18
+
19
+ ## Can create a hash with DearJson methods
20
+ test_hash = TestHashWithDearJson.new
21
+ test_hash[:key] = 'value'
22
+ test_hash.respond_to?(:to_json)
23
+ #=> true
24
+
25
+ ## to_json converts hash to JSON string using JsonSerializer
26
+ test_hash = TestHashWithDearJson.new
27
+ test_hash[:simple] = 'value'
28
+ test_hash[:number] = 42
29
+ json_result = test_hash.to_json
30
+ json_result
31
+ #=:> String
32
+
33
+ ## to_json handles objects with as_json methods
34
+ test_hash = TestHashWithDearJson.new
35
+ test_obj = TestObjectWithAsJson.new('test')
36
+ test_hash[:object] = test_obj
37
+ test_hash[:simple] = 'value'
38
+ json_result = test_hash.to_json
39
+ json_result
40
+ #=~> /test_object/
41
+
42
+ ## as_json returns the hash itself
43
+ test_hash = TestHashWithDearJson.new
44
+ test_hash[:key] = 'value'
45
+ result = test_hash.as_json
46
+ result == test_hash
47
+ #=> true
48
+
49
+ ## as_json accepts options parameter
50
+ test_hash = TestHashWithDearJson.new
51
+ test_hash[:key] = 'value'
52
+ result = test_hash.as_json(some_option: true)
53
+ result == test_hash
54
+ #=> true
@@ -0,0 +1,44 @@
1
+ # try/refinements/logger_trace_methods_try.rb
2
+
3
+ require_relative '../helpers/test_helpers'
4
+ require 'logger'
5
+ require 'stringio'
6
+
7
+ class TestLoggerWithTrace < Logger
8
+ include Familia::Refinements::LoggerTraceMethods
9
+ end
10
+
11
+ ## Can create a logger with trace methods
12
+ output = StringIO.new
13
+ logger = TestLoggerWithTrace.new(output)
14
+ logger.respond_to?(:trace)
15
+ #=> true
16
+
17
+ ## trace method logs with TRACE level
18
+ output = StringIO.new
19
+ logger = TestLoggerWithTrace.new(output)
20
+ logger.trace('Test message')
21
+ output.string
22
+ #=~> /Test message/
23
+
24
+ ## trace method sets and clears severity letter
25
+ output = StringIO.new
26
+ logger = TestLoggerWithTrace.new(output)
27
+ logger.trace('Test message')
28
+ Fiber[:severity_letter]
29
+ #=> nil
30
+
31
+ ## trace method accepts progname parameter
32
+ output = StringIO.new
33
+ logger = TestLoggerWithTrace.new(output)
34
+ logger.trace('MyApp') { 'Test message' }
35
+ output.string
36
+ #=~> /MyApp/
37
+ #=~> /Test message/
38
+
39
+ ## trace method accepts block for message
40
+ output = StringIO.new
41
+ logger = TestLoggerWithTrace.new(output)
42
+ logger.trace { 'Block message' }
43
+ output.string
44
+ #=~> /Block message/
@@ -0,0 +1,141 @@
1
+ # try/refinements/time_literals_numeric_methods_try.rb
2
+
3
+ require_relative '../helpers/test_helpers'
4
+
5
+ class TestNumericWithTimeLiterals
6
+ include Familia::Refinements::TimeLiterals::NumericMethods
7
+
8
+ def initialize(value)
9
+ @value = value
10
+ end
11
+
12
+ def to_f
13
+ @value.to_f
14
+ end
15
+
16
+ def to_i
17
+ @value.to_i
18
+ end
19
+
20
+ def positive?
21
+ @value.positive?
22
+ end
23
+
24
+ def zero?
25
+ @value.zero?
26
+ end
27
+
28
+ def abs
29
+ @value.abs
30
+ end
31
+
32
+ def <(other)
33
+ @value < other
34
+ end
35
+
36
+ def >(other)
37
+ @value > other
38
+ end
39
+
40
+ def -(other)
41
+ @value - other
42
+ end
43
+
44
+ def +(other)
45
+ @value + other
46
+ end
47
+
48
+ def *(other)
49
+ @value * other
50
+ end
51
+
52
+ def /(other)
53
+ @value / other
54
+ end
55
+ end
56
+
57
+ ## Can create numeric with time literal methods
58
+ test_num = TestNumericWithTimeLiterals.new(5)
59
+ test_num.respond_to?(:minutes)
60
+ #=> true
61
+ #=:> TrueClass
62
+
63
+ ## Basic time unit conversions work
64
+ test_num = TestNumericWithTimeLiterals.new(5)
65
+ test_num.minutes
66
+ #=> 300.0
67
+ #=:> Float
68
+
69
+ ## Minutes conversion
70
+ test_num = TestNumericWithTimeLiterals.new(2)
71
+ test_num.minutes
72
+ #=> 120.0
73
+ #=:> Float
74
+
75
+ ## Hours conversion
76
+ test_num = TestNumericWithTimeLiterals.new(2)
77
+ test_num.hours
78
+ #=> 7200.0
79
+ #=:> Float
80
+
81
+ ## Days conversion
82
+ test_num = TestNumericWithTimeLiterals.new(1)
83
+ test_num.days
84
+ #=> 86400.0
85
+ #=:> Float
86
+
87
+ ## Conversion from seconds to other units
88
+ test_num = TestNumericWithTimeLiterals.new(3600)
89
+ test_num.in_hours
90
+ #=> 1.0
91
+ #=:> Float
92
+
93
+ ## Conversion from seconds to days
94
+ test_num = TestNumericWithTimeLiterals.new(86400)
95
+ test_num.in_days
96
+ #=> 1.0
97
+ #=:> Float
98
+
99
+ ## to_ms conversion
100
+ test_num = TestNumericWithTimeLiterals.new(5)
101
+ test_num.to_ms
102
+ #=> 5000.0
103
+ #=:> Float
104
+
105
+ ## humanize for seconds
106
+ test_num = TestNumericWithTimeLiterals.new(30)
107
+ test_num.humanize
108
+ #=> "30 seconds"
109
+ #=:> String
110
+
111
+ ## humanize for minutes
112
+ test_num = TestNumericWithTimeLiterals.new(120)
113
+ test_num.humanize
114
+ #=> "2 minutes"
115
+ #=:> String
116
+
117
+ ## to_bytes conversion
118
+ test_num = TestNumericWithTimeLiterals.new(1024)
119
+ test_num.to_bytes
120
+ #=> "1.00 KiB"
121
+ #=:> String
122
+
123
+ ## age_in with days
124
+ old_time = Familia.now.to_f - 86400
125
+ test_num = TestNumericWithTimeLiterals.new(old_time)
126
+ age = test_num.age_in(:days)
127
+ age.round
128
+ #=> 1
129
+ #=:> Integer
130
+
131
+ ## older_than? check
132
+ old_timestamp = TestNumericWithTimeLiterals.new(Familia.now.to_f - 7200) # 2 hours ago
133
+ old_timestamp.older_than?(3600) # 1 hour
134
+ #=> true
135
+ #=:> TrueClass
136
+
137
+ ## within? check for recent timestamp
138
+ recent_timestamp = TestNumericWithTimeLiterals.new(Familia.now.to_f - 30) # 30 seconds ago
139
+ recent_timestamp.within?(60) # within 1 minute
140
+ #=> true
141
+ #=:> TrueClass
@@ -0,0 +1,80 @@
1
+ # try/refinements/time_literals_string_methods_try.rb
2
+
3
+ require_relative '../helpers/test_helpers'
4
+
5
+ class TestStringWithTimeLiterals < String
6
+ include Familia::Refinements::TimeLiterals::StringMethods
7
+ end
8
+
9
+ ## Can create string with time literal methods
10
+ test_str = TestStringWithTimeLiterals.new("5m")
11
+ test_str.respond_to?(:in_seconds)
12
+ #=> true
13
+ #=:> TrueClass
14
+
15
+ ## Parse minutes to seconds
16
+ test_str = TestStringWithTimeLiterals.new("5m")
17
+ test_str.in_seconds
18
+ #=> 300.0
19
+ #=:> Float
20
+
21
+ ## Parse hours to seconds
22
+ test_str = TestStringWithTimeLiterals.new("2h")
23
+ test_str.in_seconds
24
+ #=> 7200.0
25
+ #=:> Float
26
+
27
+ ## Parse days to seconds
28
+ test_str = TestStringWithTimeLiterals.new("1d")
29
+ test_str.in_seconds
30
+ #=> 86400.0
31
+ #=:> Float
32
+
33
+ ## Parse decimal values
34
+ test_str = TestStringWithTimeLiterals.new("2.5h")
35
+ test_str.in_seconds
36
+ #=> 9000.0
37
+ #=:> Float
38
+
39
+ ## Parse years to seconds
40
+ test_str = TestStringWithTimeLiterals.new("1y")
41
+ result = test_str.in_seconds
42
+ result > 31_000_000 && result < 32_000_000
43
+ #=> true
44
+ #=:> TrueClass
45
+
46
+ ## Parse microseconds
47
+ test_str = TestStringWithTimeLiterals.new("500μs")
48
+ test_str.in_seconds
49
+ #=> 0.0005
50
+ #=:> Float
51
+
52
+ ## Parse milliseconds
53
+ test_str = TestStringWithTimeLiterals.new("500ms")
54
+ test_str.in_seconds
55
+ #=> 0.5
56
+ #=:> Float
57
+
58
+ ## Parse weeks
59
+ test_str = TestStringWithTimeLiterals.new("2w")
60
+ test_str.in_seconds
61
+ #=> 1209600.0
62
+ #=:> Float
63
+
64
+ ## Default unit is seconds when no unit specified
65
+ test_str = TestStringWithTimeLiterals.new("30")
66
+ test_str.in_seconds
67
+ #=> 30.0
68
+ #=:> Float
69
+
70
+ ## Invalid format returns nil
71
+ test_str = TestStringWithTimeLiterals.new("invalid")
72
+ test_str.in_seconds
73
+ #=> nil
74
+ #=:> NilClass
75
+
76
+ ## Empty string returns nil
77
+ test_str = TestStringWithTimeLiterals.new("")
78
+ test_str.in_seconds
79
+ #=> nil
80
+ #=:> NilClass
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.pre15
4
+ version: 2.0.0.pre16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delano Mandelbaum
@@ -137,11 +137,14 @@ files:
137
137
  - ".github/workflows/ci.yml"
138
138
  - ".github/workflows/claude-code-review.yml"
139
139
  - ".github/workflows/claude.yml"
140
+ - ".github/workflows/code-quality.yml"
141
+ - ".github/workflows/code-smellage.yml"
140
142
  - ".github/workflows/docs.yml"
141
143
  - ".gitignore"
142
144
  - ".pre-commit-config.yaml"
145
+ - ".reek.yml"
143
146
  - ".rubocop.yml"
144
- - ".rubocop_todo.yml"
147
+ - ".talismanrc"
145
148
  - ".yardopts"
146
149
  - CHANGELOG.rst
147
150
  - CLAUDE.md
@@ -157,23 +160,23 @@ files:
157
160
  - docs/archive/FAMILIA_TECHNICAL.md
158
161
  - docs/archive/FAMILIA_UPDATE.md
159
162
  - docs/archive/README.md
160
- - docs/connection_pooling.md
163
+ - docs/archive/api-reference.md
164
+ - docs/conf.py
161
165
  - docs/guides/.gitignore
162
- - docs/guides/API-Reference.md
163
- - docs/guides/Connection-Pooling-Guide.md
164
- - docs/guides/Encrypted-Fields-Overview.md
165
- - docs/guides/Expiration-Feature-Guide.md
166
- - docs/guides/Feature-System-Autoloading.md
167
- - docs/guides/Feature-System-Guide.md
168
- - docs/guides/Features-System-Developer-Guide.md
169
- - docs/guides/Field-System-Guide.md
170
- - docs/guides/Home.md
171
- - docs/guides/Implementation-Guide.md
172
- - docs/guides/Quantization-Feature-Guide.md
173
- - docs/guides/Relationships-Guide.md
174
- - docs/guides/Security-Model.md
175
- - docs/guides/Transient-Fields-Guide.md
176
- - docs/guides/relationships-methods.md
166
+ - docs/guides/core-field-system.md
167
+ - docs/guides/feature-encrypted-fields.md
168
+ - docs/guides/feature-expiration.md
169
+ - docs/guides/feature-external-identifiers.md
170
+ - docs/guides/feature-object-identifiers.md
171
+ - docs/guides/feature-quantization.md
172
+ - docs/guides/feature-relationships-methods.md
173
+ - docs/guides/feature-relationships.md
174
+ - docs/guides/feature-system-devs.md
175
+ - docs/guides/feature-system.md
176
+ - docs/guides/feature-transient-fields.md
177
+ - docs/guides/implementation.md
178
+ - docs/guides/index.md
179
+ - docs/guides/security-model.md
177
180
  - docs/guides/time-utilities.md
178
181
  - docs/migrating/.gitignore
179
182
  - docs/migrating/v2.0.0-pre.md
@@ -185,26 +188,37 @@ files:
185
188
  - docs/migrating/v2.0.0-pre6.md
186
189
  - docs/migrating/v2.0.0-pre7.md
187
190
  - docs/overview.md
188
- - docs/reference/auditing_database_commands.rb
191
+ - docs/reference/api-technical.md
189
192
  - examples/autoloader/mega_customer.rb
193
+ - examples/autoloader/mega_customer/features/deprecated_fields.rb
190
194
  - examples/autoloader/mega_customer/safe_dump_fields.rb
191
- - examples/permissions.rb
195
+ - examples/encrypted_fields.rb
196
+ - examples/json_usage_patterns.rb
192
197
  - examples/relationships.rb
193
198
  - examples/safe_dump.rb
199
+ - examples/single_connection_transaction_confusions.rb
194
200
  - familia.gemspec
195
201
  - lib/familia.rb
196
202
  - lib/familia/base.rb
197
203
  - lib/familia/connection.rb
204
+ - lib/familia/connection/handlers.rb
205
+ - lib/familia/connection/individual_command_proxy.rb
206
+ - lib/familia/connection/middleware.rb
207
+ - lib/familia/connection/operation_core.rb
208
+ - lib/familia/connection/operations.rb
209
+ - lib/familia/connection/pipeline_core.rb
210
+ - lib/familia/connection/transaction_core.rb
198
211
  - lib/familia/data_type.rb
199
212
  - lib/familia/data_type/commands.rb
200
213
  - lib/familia/data_type/serialization.rb
201
214
  - lib/familia/data_type/types/counter.rb
202
215
  - lib/familia/data_type/types/hashkey.rb
203
- - lib/familia/data_type/types/list.rb
216
+ - lib/familia/data_type/types/listkey.rb
204
217
  - lib/familia/data_type/types/lock.rb
205
218
  - lib/familia/data_type/types/sorted_set.rb
206
- - lib/familia/data_type/types/string.rb
219
+ - lib/familia/data_type/types/stringkey.rb
207
220
  - lib/familia/data_type/types/unsorted_set.rb
221
+ - lib/familia/distinguisher.rb
208
222
  - lib/familia/encryption.rb
209
223
  - lib/familia/encryption/encrypted_data.rb
210
224
  - lib/familia/encryption/manager.rb
@@ -226,14 +240,17 @@ files:
226
240
  - lib/familia/features/object_identifier.rb
227
241
  - lib/familia/features/quantization.rb
228
242
  - lib/familia/features/relationships.rb
229
- - lib/familia/features/relationships/cascading.rb
243
+ - lib/familia/features/relationships/README.md
244
+ - lib/familia/features/relationships/collection_operations.rb
230
245
  - lib/familia/features/relationships/indexing.rb
231
- - lib/familia/features/relationships/membership.rb
232
- - lib/familia/features/relationships/permission_management.rb
233
- - lib/familia/features/relationships/querying.rb
234
- - lib/familia/features/relationships/redis_operations.rb
246
+ - lib/familia/features/relationships/indexing/multi_index_generators.rb
247
+ - lib/familia/features/relationships/indexing/unique_index_generators.rb
248
+ - lib/familia/features/relationships/indexing_relationship.rb
249
+ - lib/familia/features/relationships/participation.rb
250
+ - lib/familia/features/relationships/participation/participant_methods.rb
251
+ - lib/familia/features/relationships/participation/target_methods.rb
252
+ - lib/familia/features/relationships/participation_relationship.rb
235
253
  - lib/familia/features/relationships/score_encoding.rb
236
- - lib/familia/features/relationships/tracking.rb
237
254
  - lib/familia/features/safe_dump.rb
238
255
  - lib/familia/features/transient_fields.rb
239
256
  - lib/familia/features/transient_fields/redacted_string.rb
@@ -252,32 +269,41 @@ files:
252
269
  - lib/familia/horreum/subclass/related_fields_management.rb
253
270
  - lib/familia/json_serializer.rb
254
271
  - lib/familia/logging.rb
255
- - lib/familia/multi_result.rb
256
272
  - lib/familia/refinements.rb
273
+ - lib/familia/refinements/dear_json.rb
257
274
  - lib/familia/refinements/logger_trace.rb
258
- - lib/familia/refinements/snake_case.rb
275
+ - lib/familia/refinements/stylize_words.rb
259
276
  - lib/familia/refinements/time_literals.rb
260
277
  - lib/familia/secure_identifier.rb
261
278
  - lib/familia/settings.rb
262
279
  - lib/familia/utils.rb
263
- - lib/familia/validation.rb
264
- - lib/familia/validation/command_recorder.rb
265
- - lib/familia/validation/expectations.rb
266
- - lib/familia/validation/validation_helpers.rb
267
- - lib/familia/validation/validator.rb
268
280
  - lib/familia/verifiable_identifier.rb
269
281
  - lib/familia/version.rb
270
282
  - lib/middleware/database_middleware.rb
283
+ - lib/multi_result.rb
271
284
  - try/configuration/scenarios_try.rb
285
+ - try/connection/fiber_context_preservation_try.rb
286
+ - try/connection/handler_constraints_try.rb
287
+ - try/connection/operation_mode_guards_try.rb
288
+ - try/connection/pipeline_fallback_integration_try.rb
289
+ - try/connection/responsibility_chain_tracking_try.rb
290
+ - try/connection/transaction_fallback_integration_try.rb
291
+ - try/connection/transaction_mode_permissive_try.rb
292
+ - try/connection/transaction_mode_strict_try.rb
293
+ - try/connection/transaction_mode_warn_try.rb
294
+ - try/connection/transaction_modes_try.rb
272
295
  - try/core/autoloader_try.rb
273
296
  - try/core/base_enhancements_try.rb
274
297
  - try/core/connection_try.rb
298
+ - try/core/conventional_inheritance_try.rb
275
299
  - try/core/create_method_try.rb
276
300
  - try/core/database_consistency_try.rb
277
301
  - try/core/errors_try.rb
278
302
  - try/core/extensions_try.rb
279
303
  - try/core/familia_extended_try.rb
304
+ - try/core/familia_members_methods_try.rb
280
305
  - try/core/familia_try.rb
306
+ - try/core/isolated_dbclient_try.rb
281
307
  - try/core/middleware_try.rb
282
308
  - try/core/persistence_operations_try.rb
283
309
  - try/core/pools_try.rb
@@ -293,9 +319,9 @@ files:
293
319
  - try/data_types/hash_try.rb
294
320
  - try/data_types/list_try.rb
295
321
  - try/data_types/lock_try.rb
296
- - try/data_types/set_try.rb
297
322
  - try/data_types/sorted_set_try.rb
298
323
  - try/data_types/string_try.rb
324
+ - try/data_types/unsortedset_try.rb
299
325
  - try/debugging/README.md
300
326
  - try/debugging/cache_behavior_tracer.rb
301
327
  - try/debugging/debug_aad_process.rb
@@ -361,7 +387,12 @@ files:
361
387
  - try/features/object_identifier/object_identifier_try.rb
362
388
  - try/features/quantization/quantization_try.rb
363
389
  - try/features/real_feature_integration_try.rb
364
- - try/features/relationships/categorical_permissions_try.rb
390
+ - try/features/relationships/indexing_commands_verification_try.rb
391
+ - try/features/relationships/indexing_try.rb
392
+ - try/features/relationships/participation_commands_verification_spec.rb
393
+ - try/features/relationships/participation_commands_verification_try.rb
394
+ - try/features/relationships/participation_performance_improvements_try.rb
395
+ - try/features/relationships/participation_reverse_index_try.rb
365
396
  - try/features/relationships/relationships_api_changes_try.rb
366
397
  - try/features/relationships/relationships_edge_cases_try.rb
367
398
  - try/features/relationships/relationships_performance_minimal_try.rb
@@ -369,9 +400,7 @@ files:
369
400
  - try/features/relationships/relationships_performance_try.rb
370
401
  - try/features/relationships/relationships_performance_working_try.rb
371
402
  - try/features/relationships/relationships_try.rb
372
- - try/features/safe_dump/module_based_extensions_try.rb
373
403
  - try/features/safe_dump/safe_dump_advanced_try.rb
374
- - try/features/safe_dump/safe_dump_autoloading_try.rb
375
404
  - try/features/safe_dump/safe_dump_try.rb
376
405
  - try/features/transient_fields/redacted_string_try.rb
377
406
  - try/features/transient_fields/refresh_reset_try.rb
@@ -379,10 +408,12 @@ files:
379
408
  - try/features/transient_fields/single_use_redacted_string_try.rb
380
409
  - try/features/transient_fields/transient_fields_core_try.rb
381
410
  - try/features/transient_fields/transient_fields_integration_try.rb
411
+ - try/helpers/test_cleanup.rb
382
412
  - try/helpers/test_helpers.rb
383
413
  - try/horreum/base_try.rb
384
414
  - try/horreum/class_methods_try.rb
385
415
  - try/horreum/commands_try.rb
416
+ - try/horreum/destroy_related_fields_cleanup_try.rb
386
417
  - try/horreum/enhanced_conflict_handling_try.rb
387
418
  - try/horreum/field_categories_try.rb
388
419
  - try/horreum/field_definition_try.rb
@@ -417,10 +448,11 @@ files:
417
448
  - try/prototypes/pooling/lib/visualize_stress_results.rb
418
449
  - try/prototypes/pooling/pool_siege.rb
419
450
  - try/prototypes/pooling/run_stress_tests.rb
420
- - try/validation/atomic_operations_try.rb.disabled
421
- - try/validation/command_validation_try.rb.disabled
422
- - try/validation/performance_validation_try.rb.disabled
423
- - try/validation/real_world_scenarios_try.rb.disabled
451
+ - try/refinements/dear_json_array_methods_try.rb
452
+ - try/refinements/dear_json_hash_methods_try.rb
453
+ - try/refinements/logger_trace_methods_try.rb
454
+ - try/refinements/time_literals_numeric_methods_try.rb
455
+ - try/refinements/time_literals_string_methods_try.rb
424
456
  homepage: https://github.com/delano/familia
425
457
  licenses:
426
458
  - MIT