familia 1.0.0.pre.rc1 → 1.0.0.pre.rc3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+ require 'logger'
5
+
6
+ # Controls whether tracing is enabled via an environment variable
7
+ FAMILIA_TRACE = ENV.fetch('FAMILIA_TRACE', 'false').downcase
8
+
9
+ # FlexibleHashAccess
10
+ #
11
+ # This module provides a refinement for the Hash class to allow flexible access
12
+ # to hash keys using either strings or symbols interchangeably for reading values.
13
+ #
14
+ # Note: This refinement only affects reading from the hash. Writing to the hash
15
+ # maintains the original key type.
16
+ #
17
+ # @example Using the refinement
18
+ # using FlexibleHashAccess
19
+ #
20
+ # h = { name: "Alice", "age" => 30 }
21
+ # h[:name] # => "Alice"
22
+ # h["name"] # => "Alice"
23
+ # h[:age] # => 30
24
+ # h["age"] # => 30
25
+ #
26
+ # h["job"] = "Developer"
27
+ # h[:job] # => "Developer"
28
+ # h["job"] # => "Developer"
29
+ #
30
+ # h[:salary] = 75000
31
+ # h[:salary] # => 75000
32
+ # h["salary"] # => nil (original key type is preserved)
33
+ #
34
+ module FlexibleHashAccess
35
+ refine Hash do
36
+ ##
37
+ # Retrieves a value from the hash using either a string or symbol key.
38
+ #
39
+ # @param key [String, Symbol] The key to look up
40
+ # @return [Object, nil] The value associated with the key, or nil if not found
41
+ def [](key)
42
+ super(key.to_s) || super(key.to_sym)
43
+ end
44
+ end
45
+ end
46
+
47
+ # LoggerTraceRefinement
48
+ #
49
+ # This module adds a 'trace' log level to the Ruby Logger class.
50
+ # It is enabled when the FAMILIA_TRACE environment variable is set to
51
+ # '1', 'true', or 'yes' (case-insensitive).
52
+ #
53
+ # @example Enabling trace logging
54
+ # # Set environment variable
55
+ # ENV['FAMILIA_TRACE'] = 'true'
56
+ #
57
+ # # In your Ruby code
58
+ # require 'logger'
59
+ # using LoggerTraceRefinement
60
+ #
61
+ # logger = Logger.new(STDOUT)
62
+ # logger.trace("This is a trace message")
63
+ #
64
+ module LoggerTraceRefinement
65
+ # Indicates whether trace logging is enabled
66
+ ENABLED = %w[1 true yes].include?(FAMILIA_TRACE)
67
+
68
+ # The numeric level for trace logging (same as DEBUG)
69
+ TRACE = 0 unless defined?(TRACE)
70
+
71
+ refine Logger do
72
+ ##
73
+ # Logs a message at the TRACE level.
74
+ #
75
+ # @param progname [String] The program name to include in the log message
76
+ # @yield A block that evaluates to the message to log
77
+ # @return [true] Always returns true
78
+ #
79
+ # @example Logging a trace message
80
+ # logger.trace("MyApp") { "Detailed trace information" }
81
+ def trace(progname = nil, &block)
82
+ Thread.current[:severity_letter] = 'T'
83
+ add(LoggerTraceRefinement::TRACE, nil, progname, &block)
84
+ ensure
85
+ Thread.current[:severity_letter] = nil
86
+ end
87
+ end
88
+ end
@@ -53,19 +53,19 @@ module Familia
53
53
  multi_from_redis(*el)
54
54
  end
55
55
 
56
- def all
56
+ def hgetall
57
57
  # TODO: Use from_redis. Also name `all` is confusing with
58
58
  # Onetime::Customer.all which returns all customers.
59
59
  redis.hgetall rediskey
60
60
  end
61
- alias to_hash all
62
- alias clone all
61
+ alias all hgetall
63
62
 
64
- def has_key?(field)
63
+ def key?(field)
65
64
  redis.hexists rediskey, field
66
65
  end
67
- alias include? has_key?
68
- alias member? has_key?
66
+ alias has_key? key?
67
+ alias include? key?
68
+ alias member? key?
69
69
 
70
70
  def delete(field)
71
71
  redis.hdel rediskey, field
@@ -18,6 +18,7 @@ module Familia
18
18
  update_expiration
19
19
  self
20
20
  end
21
+ alias append push
21
22
 
22
23
  def <<(val)
23
24
  push val
@@ -31,6 +32,7 @@ module Familia
31
32
  update_expiration
32
33
  self
33
34
  end
35
+ alias prepend unshift
34
36
 
35
37
  def pop
36
38
  from_redis redis.rpop(rediskey)
data/lib/familia/utils.rb CHANGED
@@ -64,8 +64,8 @@ module Familia
64
64
  Time.at(rounded).utc.strftime(pattern)
65
65
  end
66
66
 
67
- def generate_sha_hash(elements)
68
- concatenated_string = Familia.join(elements)
67
+ def generate_sha_hash(*elements)
68
+ concatenated_string = Familia.join(*elements)
69
69
  DIGEST_CLASS.hexdigest(concatenated_string)
70
70
  end
71
71
 
@@ -113,10 +113,6 @@ module Familia
113
113
  Familia.trace :TOREDIS_DISTINGUISHER, redis, "isabase", caller(1..1) if Familia.debug?
114
114
  value_to_distinguish.identifier
115
115
 
116
- elsif dump_method && value_to_distinguish.respond_to?(dump_method)
117
- Familia.trace :TOREDIS_DISTINGUISHER, redis, "#{value_to_distinguish.class}##{dump_method}", caller(1..1) if Familia.debug?
118
- value_to_distinguish.send(dump_method)
119
-
120
116
  else
121
117
  Familia.trace :TOREDIS_DISTINGUISHER, redis, "else2 #{strict_values}", caller(1..1) if Familia.debug?
122
118
  raise Familia::HighRiskFactor, value_to_distinguish if strict_values
data/lib/familia.rb CHANGED
@@ -5,6 +5,7 @@ require 'redis'
5
5
  require 'uri/redis'
6
6
 
7
7
  require_relative 'familia/core_ext'
8
+ require_relative 'familia/refinements'
8
9
  require_relative 'familia/errors'
9
10
  require_relative 'familia/version'
10
11
 
@@ -38,3 +38,56 @@ Familia.debug = true
38
38
  ## Remove the key
39
39
  @hashkey.clear
40
40
  #=> 1
41
+
42
+ ## Horreum objects can update and save their fields (1 of 2)
43
+ @customer.name = 'John Doe'
44
+ #=> "John Doe"
45
+
46
+ ## Horreum objects can update and save their fields (2 of 2)
47
+ @customer.save
48
+ #=> true
49
+
50
+ ## Horreum object fields have a fast writer method (1 of 2)
51
+ Familia.trace :LOAD, @customer.redis, @customer.redisuri, caller if Familia.debug?
52
+ @customer.name! 'Jane Doe'
53
+ #=> 0
54
+
55
+ ## Horreum object fields have a fast writer method (2 of 2)
56
+ @customer.refresh!
57
+ @customer.name
58
+ #=> "Jane Doe"
59
+
60
+ ## Unsaved changes are lost when an object reloads
61
+ @customer.name = 'John Doe'
62
+ @customer.refresh!
63
+ @customer.name
64
+ #=> "Jane Doe"
65
+
66
+ ## Horreum objects can be destroyed
67
+ @customer.destroy!
68
+ #=> true
69
+
70
+ ## All horrerum objects have a key field
71
+ @customer.key
72
+ #=> @identifier
73
+
74
+ ## Even ones that didn't define it
75
+ @cd = CustomDomain.new "www.example.com", "@identifier"
76
+ @cd.key
77
+ #=> nil
78
+
79
+ ## We can call #identifier directly if we want to "lasy load" the unique identifier
80
+ @cd.identifier
81
+ #=> "7565befd"
82
+
83
+ ## The #key field will still be nil
84
+ @cd.key
85
+ #=> nil
86
+
87
+ ## But once we save
88
+ @cd.save
89
+ #=> true
90
+
91
+ ## The key will be set
92
+ @cd.key
93
+ #=> "7565befd"
data/try/test_helpers.rb CHANGED
@@ -70,6 +70,7 @@ class Customer < Familia::Horreum
70
70
  field :email
71
71
  field :role
72
72
  field :key
73
+ field :name
73
74
  field :passphrase_encryption
74
75
  field :passphrase
75
76
  field :verified
@@ -154,6 +155,7 @@ class CustomDomain < Familia::Horreum
154
155
  field :trd
155
156
  field :tld
156
157
  field :sld
158
+ # No :key field (so we can test hte behaviour in Horreum#initialize)
157
159
  field :txt_validation_host
158
160
  field :txt_validation_value
159
161
  field :status
@@ -167,7 +169,11 @@ class CustomDomain < Familia::Horreum
167
169
  # the customer ID. This is used to ensure that the same domain can't be
168
170
  # added twice by the same customer while avoiding collisions between customers.
169
171
  def derive_id
170
- Familia.generate_sha_hash(:display_domain, :custid).slice(0, 8)
172
+ elements = [
173
+ display_domain,
174
+ custid
175
+ ]
176
+ Familia.generate_sha_hash(*elements).slice(0, 8)
171
177
  end
172
178
  end
173
179
  @d = CustomDomain.new
@@ -178,6 +184,8 @@ class Limiter < Familia::Horreum
178
184
 
179
185
  identifier :name
180
186
  field :name
187
+ # No :key field (so we can test hte behaviour in Horreum#initialize)
188
+
181
189
  string :counter, :ttl => 1.hour, :quantize => [10.minutes, '%H:%M', 1302468980]
182
190
 
183
191
  def identifier
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: familia
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre.rc1
4
+ version: 1.0.0.pre.rc3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delano Mandelbaum
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-15 00:00:00.000000000 Z
11
+ date: 2024-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -97,6 +97,7 @@ files:
97
97
  - lib/familia/redistype.rb
98
98
  - lib/familia/redistype/commands.rb
99
99
  - lib/familia/redistype/serialization.rb
100
+ - lib/familia/refinements.rb
100
101
  - lib/familia/settings.rb
101
102
  - lib/familia/types/hashkey.rb
102
103
  - lib/familia/types/list.rb
@@ -141,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
142
  - !ruby/object:Gem::Version
142
143
  version: '0'
143
144
  requirements: []
144
- rubygems_version: 3.5.17
145
+ rubygems_version: 3.5.15
145
146
  signing_key:
146
147
  specification_version: 4
147
148
  summary: An ORM for Redis in Ruby.