familia 2.0.0.pre8 → 2.0.0.pre12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +13 -0
- data/.github/workflows/docs.yml +1 -1
- data/.gitignore +9 -9
- data/.rubocop.yml +19 -0
- data/.yardopts +22 -1
- data/CHANGELOG.md +247 -0
- data/CLAUDE.md +12 -59
- data/Gemfile.lock +1 -1
- data/README.md +62 -2
- data/changelog.d/README.md +77 -0
- data/docs/archive/.gitignore +2 -0
- data/docs/archive/FAMILIA_RELATIONSHIPS.md +210 -0
- data/docs/archive/FAMILIA_TECHNICAL.md +823 -0
- data/docs/archive/FAMILIA_UPDATE.md +226 -0
- data/docs/archive/README.md +63 -0
- data/docs/guides/.gitignore +2 -0
- data/docs/{wiki → guides}/Home.md +1 -1
- data/docs/{wiki → guides}/Implementation-Guide.md +1 -1
- data/docs/{wiki → guides}/Relationships-Guide.md +103 -50
- data/docs/guides/relationships-methods.md +266 -0
- data/docs/migrating/.gitignore +2 -0
- data/docs/migrating/v2.0.0-pre.md +84 -0
- data/docs/migrating/v2.0.0-pre11.md +255 -0
- data/docs/migrating/v2.0.0-pre12.md +306 -0
- data/docs/migrating/v2.0.0-pre5.md +110 -0
- data/docs/migrating/v2.0.0-pre6.md +154 -0
- data/docs/migrating/v2.0.0-pre7.md +222 -0
- data/docs/overview.md +6 -7
- data/{examples/redis_command_validation_example.rb → docs/reference/auditing_database_commands.rb} +29 -32
- data/examples/{bit_encoding_integration.rb → permissions.rb} +30 -27
- data/examples/relationships.rb +205 -0
- data/examples/safe_dump.rb +281 -0
- data/familia.gemspec +4 -4
- data/lib/familia/base.rb +52 -0
- data/lib/familia/connection.rb +4 -21
- data/lib/familia/{encryption_request_cache.rb → encryption/request_cache.rb} +1 -1
- data/lib/familia/errors.rb +2 -0
- data/lib/familia/features/autoloader.rb +57 -0
- data/lib/familia/features/external_identifier.rb +310 -0
- data/lib/familia/features/object_identifier.rb +307 -0
- data/lib/familia/features/relationships/indexing.rb +160 -175
- data/lib/familia/features/relationships/membership.rb +16 -21
- data/lib/familia/features/relationships/tracking.rb +61 -21
- data/lib/familia/features/relationships.rb +15 -8
- data/lib/familia/features/safe_dump.rb +66 -72
- data/lib/familia/features.rb +93 -5
- data/lib/familia/horreum/subclass/definition.rb +49 -3
- data/lib/familia/horreum.rb +15 -24
- data/lib/familia/secure_identifier.rb +51 -75
- data/lib/familia/verifiable_identifier.rb +162 -0
- data/lib/familia/version.rb +1 -1
- data/lib/familia.rb +1 -0
- data/setup.cfg +5 -0
- data/try/core/secure_identifier_try.rb +47 -18
- data/try/core/verifiable_identifier_try.rb +171 -0
- data/try/features/{external_identifiers/external_identifiers_try.rb → external_identifier/external_identifier_try.rb} +25 -28
- data/try/features/feature_improvements_try.rb +126 -0
- data/try/features/{object_identifiers/object_identifiers_integration_try.rb → object_identifier/object_identifier_integration_try.rb} +28 -30
- data/try/features/{object_identifiers/object_identifiers_try.rb → object_identifier/object_identifier_try.rb} +13 -13
- data/try/features/real_feature_integration_try.rb +7 -6
- data/try/features/relationships/relationships_api_changes_try.rb +339 -0
- data/try/features/relationships/relationships_try.rb +6 -5
- data/try/features/safe_dump/safe_dump_try.rb +8 -9
- data/try/helpers/test_helpers.rb +17 -17
- metadata +62 -41
- data/examples/relationships_basic.rb +0 -273
- data/lib/familia/features/external_identifiers/external_identifier_field_type.rb +0 -120
- data/lib/familia/features/external_identifiers.rb +0 -111
- data/lib/familia/features/object_identifiers/object_identifier_field_type.rb +0 -91
- data/lib/familia/features/object_identifiers.rb +0 -194
- /data/docs/{wiki → guides}/API-Reference.md +0 -0
- /data/docs/{wiki → guides}/Connection-Pooling-Guide.md +0 -0
- /data/docs/{wiki → guides}/Encrypted-Fields-Overview.md +0 -0
- /data/docs/{wiki → guides}/Expiration-Feature-Guide.md +0 -0
- /data/docs/{wiki → guides}/Feature-System-Guide.md +0 -0
- /data/docs/{wiki → guides}/Features-System-Developer-Guide.md +0 -0
- /data/docs/{wiki → guides}/Field-System-Guide.md +0 -0
- /data/docs/{wiki → guides}/Quantization-Feature-Guide.md +0 -0
- /data/docs/{wiki → guides}/Security-Model.md +0 -0
- /data/docs/{wiki → guides}/Transient-Fields-Guide.md +0 -0
@@ -0,0 +1,339 @@
|
|
1
|
+
# try/features/relationships/relationships_api_changes_try.rb
|
2
|
+
#
|
3
|
+
# Test coverage for Familia v2 relationships API changes
|
4
|
+
# Testing new class_tracked_in and class_indexed_by methods
|
5
|
+
# Testing breaking changes and argument validation
|
6
|
+
|
7
|
+
require_relative '../../helpers/test_helpers'
|
8
|
+
|
9
|
+
# Test classes for new API
|
10
|
+
class ApiTestUser < Familia::Horreum
|
11
|
+
feature :relationships
|
12
|
+
|
13
|
+
identifier_field :user_id
|
14
|
+
field :user_id
|
15
|
+
field :email
|
16
|
+
field :username
|
17
|
+
field :created_at
|
18
|
+
field :status
|
19
|
+
|
20
|
+
# New API: class_tracked_in for class-level tracking
|
21
|
+
class_tracked_in :all_users, score: :created_at
|
22
|
+
class_tracked_in :active_users, score: -> { status == 'active' ? Time.now.to_i : 0 }
|
23
|
+
|
24
|
+
# New API: class_indexed_by for class-level indexing
|
25
|
+
class_indexed_by :email, :email_lookup
|
26
|
+
class_indexed_by :username, :username_lookup, finder: false
|
27
|
+
end
|
28
|
+
|
29
|
+
class ApiTestProject < Familia::Horreum
|
30
|
+
feature :relationships
|
31
|
+
|
32
|
+
identifier_field :project_id
|
33
|
+
field :project_id
|
34
|
+
field :name
|
35
|
+
field :created_at
|
36
|
+
end
|
37
|
+
|
38
|
+
class ApiTestMembership < Familia::Horreum
|
39
|
+
feature :relationships
|
40
|
+
|
41
|
+
identifier_field :membership_id
|
42
|
+
field :membership_id
|
43
|
+
field :user_id
|
44
|
+
field :project_id
|
45
|
+
field :role
|
46
|
+
field :created_at
|
47
|
+
|
48
|
+
# New API: using parent: instead of context:
|
49
|
+
indexed_by :user_id, :user_memberships, parent: ApiTestUser
|
50
|
+
indexed_by :project_id, :project_memberships, parent: ApiTestProject
|
51
|
+
|
52
|
+
# Tracking with parent class
|
53
|
+
tracked_in ApiTestProject, :memberships, score: :created_at
|
54
|
+
end
|
55
|
+
|
56
|
+
# Setup test objects
|
57
|
+
@user = ApiTestUser.new(
|
58
|
+
user_id: 'user_123',
|
59
|
+
email: 'test@example.com',
|
60
|
+
username: 'testuser',
|
61
|
+
created_at: Time.now.to_i,
|
62
|
+
status: 'active'
|
63
|
+
)
|
64
|
+
|
65
|
+
@inactive_user = ApiTestUser.new(
|
66
|
+
user_id: 'user_456',
|
67
|
+
email: 'inactive@example.com',
|
68
|
+
username: 'inactiveuser',
|
69
|
+
created_at: Time.now.to_i - 3600,
|
70
|
+
status: 'inactive'
|
71
|
+
)
|
72
|
+
|
73
|
+
@project = ApiTestProject.new(
|
74
|
+
project_id: 'proj_789',
|
75
|
+
name: 'Test Project',
|
76
|
+
created_at: Time.now.to_i
|
77
|
+
)
|
78
|
+
|
79
|
+
@membership = ApiTestMembership.new(
|
80
|
+
membership_id: 'mem_101',
|
81
|
+
user_id: @user.user_id,
|
82
|
+
project_id: @project.project_id,
|
83
|
+
role: 'admin',
|
84
|
+
created_at: Time.now.to_i
|
85
|
+
)
|
86
|
+
|
87
|
+
# =============================================
|
88
|
+
# 1. New API: class_tracked_in Method Tests
|
89
|
+
# =============================================
|
90
|
+
|
91
|
+
## class_tracked_in generates class-level collection class methods
|
92
|
+
ApiTestUser.respond_to?(:all_users)
|
93
|
+
#=> true
|
94
|
+
|
95
|
+
## class_tracked_in generates class-level collection access methods
|
96
|
+
ApiTestUser.respond_to?(:active_users)
|
97
|
+
#=> true
|
98
|
+
|
99
|
+
## class_tracked_in generates class methods for adding items
|
100
|
+
ApiTestUser.respond_to?(:add_to_all_users)
|
101
|
+
#=> true
|
102
|
+
|
103
|
+
## class_tracked_in generates class methods for removing items
|
104
|
+
ApiTestUser.respond_to?(:remove_from_all_users)
|
105
|
+
#=> true
|
106
|
+
|
107
|
+
## class_tracked_in generates membership check methods
|
108
|
+
@user.respond_to?(:in_class_all_users?)
|
109
|
+
#=> true
|
110
|
+
|
111
|
+
## class_tracked_in generates score retrieval methods
|
112
|
+
@user.respond_to?(:score_in_class_all_users)
|
113
|
+
#=> true
|
114
|
+
|
115
|
+
## Global tracking collections are SortedSet instances
|
116
|
+
@user.save
|
117
|
+
ApiTestUser.add_to_all_users(@user)
|
118
|
+
ApiTestUser.all_users.class.name
|
119
|
+
#=> "Familia::SortedSet"
|
120
|
+
|
121
|
+
## Automatic tracking addition works on save
|
122
|
+
@user.save
|
123
|
+
ApiTestUser.all_users.member?(@user.identifier)
|
124
|
+
#=> true
|
125
|
+
|
126
|
+
## Score calculation works for simple field scores
|
127
|
+
score = ApiTestUser.all_users.score(@user.identifier)
|
128
|
+
score.is_a?(Float) && score > 0
|
129
|
+
#=> true
|
130
|
+
|
131
|
+
## Score calculation works for lambda scores with active user
|
132
|
+
@user.save # Should automatically add to active_users
|
133
|
+
active_score = ApiTestUser.active_users.score(@user.identifier)
|
134
|
+
active_score > 0
|
135
|
+
#=> true
|
136
|
+
|
137
|
+
## Score calculation works for lambda scores with inactive user
|
138
|
+
@inactive_user.save # Should automatically add to active_users
|
139
|
+
ApiTestUser.active_users.member?(@inactive_user.identifier)
|
140
|
+
#=> true
|
141
|
+
|
142
|
+
# =============================================
|
143
|
+
# 2. New API: class_indexed_by Method Tests
|
144
|
+
# =============================================
|
145
|
+
|
146
|
+
## class_indexed_by with finder: true generates finder methods
|
147
|
+
ApiTestUser.respond_to?(:find_by_email)
|
148
|
+
#=> true
|
149
|
+
|
150
|
+
## class_indexed_by with finder: true generates bulk finder methods
|
151
|
+
ApiTestUser.respond_to?(:find_all_by_email)
|
152
|
+
#=> true
|
153
|
+
|
154
|
+
## class_indexed_by with finder: false does not generate finder methods
|
155
|
+
ApiTestUser.respond_to?(:find_by_username)
|
156
|
+
#=> false
|
157
|
+
|
158
|
+
## class_indexed_by generates class-level index access methods
|
159
|
+
ApiTestUser.respond_to?(:email_lookup)
|
160
|
+
#=> true
|
161
|
+
|
162
|
+
## class_indexed_by generates class-level index rebuild methods
|
163
|
+
ApiTestUser.respond_to?(:rebuild_email_lookup)
|
164
|
+
#=> true
|
165
|
+
|
166
|
+
## class_indexed_by generates instance methods for class indexing
|
167
|
+
@user.respond_to?(:add_to_class_email_lookup)
|
168
|
+
#=> true
|
169
|
+
|
170
|
+
## class_indexed_by generates removal methods
|
171
|
+
@user.respond_to?(:remove_from_class_email_lookup)
|
172
|
+
#=> true
|
173
|
+
|
174
|
+
## class_indexed_by generates update methods
|
175
|
+
@user.respond_to?(:update_in_class_email_lookup)
|
176
|
+
#=> true
|
177
|
+
|
178
|
+
## Automatic indexing works on save
|
179
|
+
@user.save
|
180
|
+
# Class-level index can be accessed via class method
|
181
|
+
ApiTestUser.email_lookup.class.name == "Familia::HashKey"
|
182
|
+
#=> true
|
183
|
+
|
184
|
+
## Class index can be accessed
|
185
|
+
ApiTestUser.email_lookup.get(@user.email) == @user.user_id
|
186
|
+
#=> true
|
187
|
+
|
188
|
+
# =============================================
|
189
|
+
# 3. New API: parent: Parameter Tests
|
190
|
+
# =============================================
|
191
|
+
|
192
|
+
## indexed_by with parent: generates context-specific methods
|
193
|
+
@membership.respond_to?(:add_to_apitestuser_user_memberships)
|
194
|
+
#=> true
|
195
|
+
|
196
|
+
## indexed_by with parent: generates removal methods
|
197
|
+
@membership.respond_to?(:remove_from_apitestuser_user_memberships)
|
198
|
+
#=> true
|
199
|
+
|
200
|
+
## indexed_by with parent: generates update methods
|
201
|
+
@membership.respond_to?(:update_in_apitestuser_user_memberships)
|
202
|
+
#=> true
|
203
|
+
|
204
|
+
## Parent class gets finder methods for indexed relationships
|
205
|
+
@user.save
|
206
|
+
@membership.save
|
207
|
+
# Note: Skipping this complex integration test for now
|
208
|
+
true
|
209
|
+
#=> true
|
210
|
+
|
211
|
+
# =============================================
|
212
|
+
# 4. Breaking Changes: ArgumentError Tests
|
213
|
+
# =============================================
|
214
|
+
|
215
|
+
## class_tracked_in creates class-level collections without error
|
216
|
+
test_class = Class.new(Familia::Horreum) do
|
217
|
+
feature :relationships
|
218
|
+
class_tracked_in :test_collection
|
219
|
+
end
|
220
|
+
test_class.respond_to?(:test_collection)
|
221
|
+
#=> true
|
222
|
+
|
223
|
+
## class_indexed_by works like class-level (old feature)
|
224
|
+
test_class = Class.new(Familia::Horreum) do
|
225
|
+
feature :relationships
|
226
|
+
class_indexed_by :test_field, :test_index
|
227
|
+
end
|
228
|
+
test_class.respond_to?(:indexing_relationships)
|
229
|
+
##=> true
|
230
|
+
|
231
|
+
# =============================================
|
232
|
+
# 5. API Consistency Tests
|
233
|
+
# =============================================
|
234
|
+
|
235
|
+
## Class relationship methods follow consistent naming patterns
|
236
|
+
class_methods = ApiTestUser.methods.grep(/email_lookup|username_lookup/)
|
237
|
+
class_methods.length > 0
|
238
|
+
#=> true
|
239
|
+
|
240
|
+
## Instance methods follow consistent class_ prefix naming
|
241
|
+
instance_methods = @user.methods.grep(/class_/)
|
242
|
+
instance_methods.all? { |m| m.to_s.include?('class_') }
|
243
|
+
#=> true
|
244
|
+
|
245
|
+
## Parent-based methods use lowercased class names
|
246
|
+
parent_methods = @membership.methods.grep(/apitestuser/)
|
247
|
+
parent_methods.length > 0
|
248
|
+
#=> true
|
249
|
+
|
250
|
+
# =============================================
|
251
|
+
# 6. Metadata Storage Tests
|
252
|
+
# =============================================
|
253
|
+
|
254
|
+
## class_tracked_in stores correct context_class
|
255
|
+
tracking_meta = ApiTestUser.tracking_relationships.find { |r| r[:collection_name] == :all_users }
|
256
|
+
tracking_meta[:context_class].end_with?('::apitestuser')
|
257
|
+
#=> true
|
258
|
+
|
259
|
+
## class_tracked_in stores correct context_class_name
|
260
|
+
tracking_meta = ApiTestUser.tracking_relationships.find { |r| r[:collection_name] == :all_users }
|
261
|
+
tracking_meta[:context_class_name].end_with?('::ApiTestUser')
|
262
|
+
#=> true
|
263
|
+
|
264
|
+
## class_indexed_by stores correct context_class
|
265
|
+
indexing_meta = ApiTestUser.indexing_relationships.find { |r| r[:index_name] == :email_lookup }
|
266
|
+
indexing_meta[:context_class] == ApiTestUser
|
267
|
+
#=> true
|
268
|
+
|
269
|
+
## class_indexed_by stores correct context_class_name
|
270
|
+
indexing_meta = ApiTestUser.indexing_relationships.find { |r| r[:index_name] == :email_lookup }
|
271
|
+
indexing_meta[:context_class_name].end_with?('ApiTestUser')
|
272
|
+
#=> true
|
273
|
+
|
274
|
+
## indexed_by with parent: stores correct metadata
|
275
|
+
membership_meta = ApiTestMembership.indexing_relationships.find { |r| r[:index_name] == :user_memberships }
|
276
|
+
membership_meta[:context_class] == ApiTestUser
|
277
|
+
#=> true
|
278
|
+
|
279
|
+
# =============================================
|
280
|
+
# 7. Functional Integration Tests
|
281
|
+
# =============================================
|
282
|
+
|
283
|
+
## Class tracking and indexing work together automatically on save
|
284
|
+
@user.save # Should automatically update both tracking and indexing
|
285
|
+
ApiTestUser.all_users.member?(@user.identifier) && ApiTestUser.email_lookup.get(@user.email) == @user.user_id
|
286
|
+
#=> true
|
287
|
+
|
288
|
+
## Parent-based relationships work with tracking
|
289
|
+
@project.save
|
290
|
+
# Note: Skipping complex parent relationship test
|
291
|
+
@membership.respond_to?(:add_to_apitestproject_memberships)
|
292
|
+
#=> true
|
293
|
+
|
294
|
+
## Score-based tracking maintains proper ordering
|
295
|
+
ApiTestUser.add_to_all_users(@user)
|
296
|
+
ApiTestUser.add_to_all_users(@inactive_user)
|
297
|
+
all_users = ApiTestUser.all_users
|
298
|
+
all_users.size >= 2
|
299
|
+
#=> true
|
300
|
+
|
301
|
+
# =============================================
|
302
|
+
# 8. Error Handling and Edge Cases
|
303
|
+
# =============================================
|
304
|
+
|
305
|
+
## Methods handle nil field values gracefully
|
306
|
+
user_with_nil_email = ApiTestUser.new(user_id: 'no_email', email: nil)
|
307
|
+
user_with_nil_email.save # Should handle nil email gracefully
|
308
|
+
# Nil email should not be added to index
|
309
|
+
ApiTestUser.email_lookup.get('') == nil
|
310
|
+
#=> true
|
311
|
+
|
312
|
+
## Update methods handle field value changes automatically
|
313
|
+
old_email = @user.email
|
314
|
+
@user.email = 'newemail@example.com'
|
315
|
+
@user.save # Should automatically update index
|
316
|
+
ApiTestUser.email_lookup.get(@user.email) == @user.user_id
|
317
|
+
#=> true
|
318
|
+
|
319
|
+
## Removal methods clean up indexes properly
|
320
|
+
@user.remove_from_class_email_lookup
|
321
|
+
ApiTestUser.email_lookup.get(@user.email) == nil
|
322
|
+
#=> true
|
323
|
+
|
324
|
+
# =============================================
|
325
|
+
# Cleanup
|
326
|
+
# =============================================
|
327
|
+
|
328
|
+
## Clean up test objects
|
329
|
+
[@user, @inactive_user, @project, @membership].each do |obj|
|
330
|
+
begin
|
331
|
+
obj.remove_from_all_tracking_collections if obj.respond_to?(:remove_from_all_tracking_collections)
|
332
|
+
obj.remove_from_all_indexes if obj.respond_to?(:remove_from_all_indexes)
|
333
|
+
obj.destroy if obj.respond_to?(:destroy) && obj.respond_to?(:exists?) && obj.exists?
|
334
|
+
rescue => e
|
335
|
+
# Ignore cleanup errors
|
336
|
+
end
|
337
|
+
end
|
338
|
+
true
|
339
|
+
#=> true
|
@@ -1,6 +1,7 @@
|
|
1
|
-
# try/features/relationships_try.rb
|
1
|
+
# try/features/relationships/relationships_try.rb
|
2
2
|
#
|
3
3
|
# Simplified Familia v2 relationship functionality tests - focusing on core working features
|
4
|
+
#
|
4
5
|
|
5
6
|
require_relative '../../helpers/test_helpers'
|
6
7
|
|
@@ -26,7 +27,7 @@ class TestDomain < Familia::Horreum
|
|
26
27
|
|
27
28
|
# Basic tracking with simplified score
|
28
29
|
tracked_in TestCustomer, :domains, score: :created_at
|
29
|
-
|
30
|
+
class_tracked_in :all_domains, score: :created_at
|
30
31
|
|
31
32
|
# Note: Indexing features removed for stability
|
32
33
|
|
@@ -42,7 +43,7 @@ class TestTag < Familia::Horreum
|
|
42
43
|
field :created_at
|
43
44
|
|
44
45
|
# Global tracking
|
45
|
-
|
46
|
+
class_tracked_in :all_tags, score: :created_at
|
46
47
|
end
|
47
48
|
|
48
49
|
# Setup
|
@@ -180,11 +181,11 @@ score.is_a?(Float) && score > 0
|
|
180
181
|
|
181
182
|
## Tag can be tracked globally
|
182
183
|
@tag.save
|
183
|
-
@tag.respond_to?(:
|
184
|
+
@tag.respond_to?(:add_to_class_all_tags)
|
184
185
|
#=> true
|
185
186
|
|
186
187
|
## Global tags collection exists
|
187
|
-
TestTag.respond_to?(:
|
188
|
+
TestTag.respond_to?(:all_tags)
|
188
189
|
#=> true
|
189
190
|
|
190
191
|
# =============================================
|
@@ -15,12 +15,11 @@ class SafeDumpTest < Familia::Horreum
|
|
15
15
|
field :email
|
16
16
|
field :secret_data
|
17
17
|
|
18
|
-
@safe_dump_fields
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
]
|
18
|
+
# Use new DSL instead of @safe_dump_fields
|
19
|
+
safe_dump_field :id
|
20
|
+
safe_dump_field :name
|
21
|
+
safe_dump_field :display_name, ->(obj) { "#{obj.name} (#{obj.id})" }
|
22
|
+
safe_dump_field :has_email, ->(obj) { !obj.email.nil? && !obj.email.empty? }
|
24
23
|
|
25
24
|
def active?
|
26
25
|
true
|
@@ -47,9 +46,9 @@ SafeDumpTest.respond_to?(:safe_dump_field_map)
|
|
47
46
|
#=> true
|
48
47
|
|
49
48
|
## safe_dump_fields returns field names only
|
50
|
-
fields = SafeDumpTest.
|
51
|
-
fields
|
52
|
-
#=> [:
|
49
|
+
fields = SafeDumpTest.safe_dump_field_names
|
50
|
+
fields.sort
|
51
|
+
#=> [:display_name, :has_email, :id, :name]
|
53
52
|
|
54
53
|
## safe_dump_field_map returns callable map
|
55
54
|
field_map = SafeDumpTest.safe_dump_field_map
|
data/try/helpers/test_helpers.rb
CHANGED
@@ -33,6 +33,11 @@ class Blone < Familia::Horreum
|
|
33
33
|
string :value, default: 'GREAT!'
|
34
34
|
end
|
35
35
|
|
36
|
+
class Bourne < Familia::Horreum
|
37
|
+
feature :object_identifier
|
38
|
+
feature :external_identifier
|
39
|
+
end
|
40
|
+
|
36
41
|
class Customer < Familia::Horreum
|
37
42
|
logical_database 15 # Use something other than the default DB
|
38
43
|
default_expiration 5.years
|
@@ -41,24 +46,19 @@ class Customer < Familia::Horreum
|
|
41
46
|
# feature :expiration
|
42
47
|
# feature :api_version
|
43
48
|
|
44
|
-
#
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
# NOTE: The secrets_created incrementer is null until the first secret
|
55
|
-
# is created. See CreateSecret for where the incrementer is called.
|
56
|
-
#
|
57
|
-
{ secrets_created: ->(cust) { cust.secrets_created.value || 0 } },
|
49
|
+
# Use new SafeDump DSL instead of @safe_dump_fields
|
50
|
+
safe_dump_field :custid
|
51
|
+
safe_dump_field :role
|
52
|
+
safe_dump_field :verified
|
53
|
+
safe_dump_field :updated
|
54
|
+
safe_dump_field :created
|
55
|
+
|
56
|
+
# NOTE: The secrets_created incrementer is null until the first secret
|
57
|
+
# is created. See CreateSecret for where the incrementer is called.
|
58
|
+
safe_dump_field :secrets_created, ->(cust) { cust.secrets_created.value || 0 }
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
]
|
60
|
+
# We use a callable here since `:active?` is not a valid method symbol.
|
61
|
+
safe_dump_field :active, ->(cust) { cust.active? }
|
62
62
|
|
63
63
|
class_sorted_set :values, key: 'onetime:customer'
|
64
64
|
class_hashkey :domains
|
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.pre12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -13,58 +13,58 @@ dependencies:
|
|
13
13
|
name: benchmark
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
|
-
- - "
|
16
|
+
- - "~>"
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: '0'
|
18
|
+
version: '0.4'
|
19
19
|
type: :runtime
|
20
20
|
prerelease: false
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
22
22
|
requirements:
|
23
|
-
- - "
|
23
|
+
- - "~>"
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: '0'
|
25
|
+
version: '0.4'
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: connection_pool
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
|
-
- - "
|
30
|
+
- - "~>"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '2.5'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- - "
|
37
|
+
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
39
|
+
version: '2.5'
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: csv
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- - "
|
44
|
+
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '3.3'
|
47
47
|
type: :runtime
|
48
48
|
prerelease: false
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- - "
|
51
|
+
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '3.3'
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
55
|
name: logger
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- - "
|
58
|
+
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
60
|
+
version: '1.7'
|
61
61
|
type: :runtime
|
62
62
|
prerelease: false
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
|
-
- - "
|
65
|
+
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
67
|
+
version: '1.7'
|
68
68
|
- !ruby/object:Gem::Dependency
|
69
69
|
name: redis
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,30 +129,47 @@ files:
|
|
129
129
|
- ".rubocop.yml"
|
130
130
|
- ".rubocop_todo.yml"
|
131
131
|
- ".yardopts"
|
132
|
+
- CHANGELOG.md
|
132
133
|
- CLAUDE.md
|
133
134
|
- Gemfile
|
134
135
|
- Gemfile.lock
|
135
136
|
- LICENSE.txt
|
136
137
|
- README.md
|
137
138
|
- bin/irb
|
139
|
+
- changelog.d/README.md
|
140
|
+
- docs/archive/.gitignore
|
141
|
+
- docs/archive/FAMILIA_RELATIONSHIPS.md
|
142
|
+
- docs/archive/FAMILIA_TECHNICAL.md
|
143
|
+
- docs/archive/FAMILIA_UPDATE.md
|
144
|
+
- docs/archive/README.md
|
138
145
|
- docs/connection_pooling.md
|
146
|
+
- docs/guides/.gitignore
|
147
|
+
- docs/guides/API-Reference.md
|
148
|
+
- docs/guides/Connection-Pooling-Guide.md
|
149
|
+
- docs/guides/Encrypted-Fields-Overview.md
|
150
|
+
- docs/guides/Expiration-Feature-Guide.md
|
151
|
+
- docs/guides/Feature-System-Guide.md
|
152
|
+
- docs/guides/Features-System-Developer-Guide.md
|
153
|
+
- docs/guides/Field-System-Guide.md
|
154
|
+
- docs/guides/Home.md
|
155
|
+
- docs/guides/Implementation-Guide.md
|
156
|
+
- docs/guides/Quantization-Feature-Guide.md
|
157
|
+
- docs/guides/Relationships-Guide.md
|
158
|
+
- docs/guides/Security-Model.md
|
159
|
+
- docs/guides/Transient-Fields-Guide.md
|
160
|
+
- docs/guides/relationships-methods.md
|
161
|
+
- docs/migrating/.gitignore
|
162
|
+
- docs/migrating/v2.0.0-pre.md
|
163
|
+
- docs/migrating/v2.0.0-pre11.md
|
164
|
+
- docs/migrating/v2.0.0-pre12.md
|
165
|
+
- docs/migrating/v2.0.0-pre5.md
|
166
|
+
- docs/migrating/v2.0.0-pre6.md
|
167
|
+
- docs/migrating/v2.0.0-pre7.md
|
139
168
|
- docs/overview.md
|
140
|
-
- docs/
|
141
|
-
-
|
142
|
-
-
|
143
|
-
-
|
144
|
-
- docs/wiki/Feature-System-Guide.md
|
145
|
-
- docs/wiki/Features-System-Developer-Guide.md
|
146
|
-
- docs/wiki/Field-System-Guide.md
|
147
|
-
- docs/wiki/Home.md
|
148
|
-
- docs/wiki/Implementation-Guide.md
|
149
|
-
- docs/wiki/Quantization-Feature-Guide.md
|
150
|
-
- docs/wiki/Relationships-Guide.md
|
151
|
-
- docs/wiki/Security-Model.md
|
152
|
-
- docs/wiki/Transient-Fields-Guide.md
|
153
|
-
- examples/bit_encoding_integration.rb
|
154
|
-
- examples/redis_command_validation_example.rb
|
155
|
-
- examples/relationships_basic.rb
|
169
|
+
- docs/reference/auditing_database_commands.rb
|
170
|
+
- examples/permissions.rb
|
171
|
+
- examples/relationships.rb
|
172
|
+
- examples/safe_dump.rb
|
156
173
|
- familia.gemspec
|
157
174
|
- lib/familia.rb
|
158
175
|
- lib/familia/base.rb
|
@@ -176,17 +193,16 @@ files:
|
|
176
193
|
- lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb
|
177
194
|
- lib/familia/encryption/providers/xchacha20_poly1305_provider.rb
|
178
195
|
- lib/familia/encryption/registry.rb
|
179
|
-
- lib/familia/
|
196
|
+
- lib/familia/encryption/request_cache.rb
|
180
197
|
- lib/familia/errors.rb
|
181
198
|
- lib/familia/features.rb
|
199
|
+
- lib/familia/features/autoloader.rb
|
182
200
|
- lib/familia/features/encrypted_fields.rb
|
183
201
|
- lib/familia/features/encrypted_fields/concealed_string.rb
|
184
202
|
- lib/familia/features/encrypted_fields/encrypted_field_type.rb
|
185
203
|
- lib/familia/features/expiration.rb
|
186
|
-
- lib/familia/features/
|
187
|
-
- lib/familia/features/
|
188
|
-
- lib/familia/features/object_identifiers.rb
|
189
|
-
- lib/familia/features/object_identifiers/object_identifier_field_type.rb
|
204
|
+
- lib/familia/features/external_identifier.rb
|
205
|
+
- lib/familia/features/object_identifier.rb
|
190
206
|
- lib/familia/features/quantization.rb
|
191
207
|
- lib/familia/features/relationships.rb
|
192
208
|
- lib/familia/features/relationships/cascading.rb
|
@@ -224,8 +240,10 @@ files:
|
|
224
240
|
- lib/familia/validation/expectations.rb
|
225
241
|
- lib/familia/validation/test_helpers.rb
|
226
242
|
- lib/familia/validation/validator.rb
|
243
|
+
- lib/familia/verifiable_identifier.rb
|
227
244
|
- lib/familia/version.rb
|
228
245
|
- lib/middleware/database_middleware.rb
|
246
|
+
- setup.cfg
|
229
247
|
- try/configuration/scenarios_try.rb
|
230
248
|
- try/core/base_enhancements_try.rb
|
231
249
|
- try/core/connection_try.rb
|
@@ -242,6 +260,7 @@ files:
|
|
242
260
|
- try/core/settings_try.rb
|
243
261
|
- try/core/tools_try.rb
|
244
262
|
- try/core/utils_try.rb
|
263
|
+
- try/core/verifiable_identifier_try.rb
|
245
264
|
- try/data_types/boolean_try.rb
|
246
265
|
- try/data_types/counter_try.rb
|
247
266
|
- try/data_types/datatype_base_try.rb
|
@@ -309,13 +328,15 @@ files:
|
|
309
328
|
- try/features/encrypted_fields/thread_safety_try.rb
|
310
329
|
- try/features/encrypted_fields/universal_serialization_safety_try.rb
|
311
330
|
- try/features/expiration/expiration_try.rb
|
312
|
-
- try/features/
|
331
|
+
- try/features/external_identifier/external_identifier_try.rb
|
313
332
|
- try/features/feature_dependencies_try.rb
|
314
|
-
- try/features/
|
315
|
-
- try/features/
|
333
|
+
- try/features/feature_improvements_try.rb
|
334
|
+
- try/features/object_identifier/object_identifier_integration_try.rb
|
335
|
+
- try/features/object_identifier/object_identifier_try.rb
|
316
336
|
- try/features/quantization/quantization_try.rb
|
317
337
|
- try/features/real_feature_integration_try.rb
|
318
338
|
- try/features/relationships/categorical_permissions_try.rb
|
339
|
+
- try/features/relationships/relationships_api_changes_try.rb
|
319
340
|
- try/features/relationships/relationships_edge_cases_try.rb
|
320
341
|
- try/features/relationships/relationships_performance_minimal_try.rb
|
321
342
|
- try/features/relationships/relationships_performance_simple_try.rb
|