lutaml-store 0.2.0 → 0.2.1

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +11 -175
  3. data/README.adoc +233 -1124
  4. data/lib/lutaml/store/adapter/base.rb +4 -0
  5. data/lib/lutaml/store/adapter/memory.rb +8 -0
  6. data/lib/lutaml/store/cache_store.rb +9 -6
  7. data/lib/lutaml/store/format.rb +19 -0
  8. data/lib/lutaml/store/http_cache.rb +3 -13
  9. data/lib/lutaml/store/model_registration.rb +5 -2
  10. data/lib/lutaml/store/model_registry.rb +22 -20
  11. data/lib/lutaml/store/package_store.rb +2 -18
  12. data/lib/lutaml/store/package_transport/base.rb +48 -0
  13. data/lib/lutaml/store/package_transport/directory_transport.rb +196 -0
  14. data/lib/lutaml/store/package_transport/zip_transport.rb +178 -0
  15. data/lib/lutaml/store/package_transport.rb +11 -438
  16. data/lib/lutaml/store/version.rb +1 -1
  17. metadata +12 -77
  18. data/.github/workflows/main.yml +0 -27
  19. data/.gitignore +0 -12
  20. data/CORRECTED_HTTP_CACHE_IMPLEMENTATION.md +0 -209
  21. data/CORRECTED_HTTP_CACHE_PLAN.md +0 -164
  22. data/Gemfile +0 -15
  23. data/Gemfile.lock +0 -227
  24. data/TODO.impl/0-lutaml-store-self-quality.md +0 -112
  25. data/TODO.impl/1-lutaml-hal-migration.md +0 -96
  26. data/TODO.impl/2-glossarist-migration.md +0 -359
  27. data/TODO.impl/3-lutaml-jsonschema-migration.md +0 -273
  28. data/bin/console +0 -11
  29. data/bin/setup +0 -8
  30. data/demo/Gemfile +0 -15
  31. data/demo/Gemfile.lock +0 -61
  32. data/demo/README.adoc +0 -301
  33. data/demo/data/vcards/co/contact_10_thompson.data +0 -1
  34. data/demo/data/vcards/co/contact_10_thompson.meta +0 -1
  35. data/demo/data/vcards/co/contact_1_doe.data +0 -1
  36. data/demo/data/vcards/co/contact_1_doe.meta +0 -1
  37. data/demo/data/vcards/co/contact_2_smith.data +0 -1
  38. data/demo/data/vcards/co/contact_2_smith.meta +0 -1
  39. data/demo/data/vcards/co/contact_3_johnson.data +0 -1
  40. data/demo/data/vcards/co/contact_3_johnson.meta +0 -1
  41. data/demo/data/vcards/co/contact_4_garcia.data +0 -1
  42. data/demo/data/vcards/co/contact_4_garcia.meta +0 -1
  43. data/demo/data/vcards/co/contact_5_wilson.data +0 -1
  44. data/demo/data/vcards/co/contact_5_wilson.meta +0 -1
  45. data/demo/data/vcards/co/contact_6_brown.data +0 -1
  46. data/demo/data/vcards/co/contact_6_brown.meta +0 -1
  47. data/demo/data/vcards/co/contact_7_davis.data +0 -1
  48. data/demo/data/vcards/co/contact_7_davis.meta +0 -1
  49. data/demo/data/vcards/co/contact_8_anderson.data +0 -1
  50. data/demo/data/vcards/co/contact_8_anderson.meta +0 -1
  51. data/demo/data/vcards/co/contact_9_taylor.data +0 -1
  52. data/demo/data/vcards/co/contact_9_taylor.meta +0 -1
  53. data/demo/data/vcards.db +0 -0
  54. data/demo/pottery_class_demo.rb +0 -164
  55. data/demo/vcard_models.rb +0 -140
  56. data/demo/vcard_store_demo.rb +0 -526
  57. data/lutaml-store.gemspec +0 -36
  58. data/plan.adoc +0 -606
  59. data/spec/lutaml/store/adapter_interface_spec.rb +0 -89
  60. data/spec/lutaml/store/anti_pattern_guard_spec.rb +0 -35
  61. data/spec/lutaml/store/anti_pattern_spec.rb +0 -78
  62. data/spec/lutaml/store/autoload_spec.rb +0 -34
  63. data/spec/lutaml/store/cache_store_spec.rb +0 -271
  64. data/spec/lutaml/store/compression_spec.rb +0 -78
  65. data/spec/lutaml/store/config_enhanced_spec.rb +0 -158
  66. data/spec/lutaml/store/corrected_http_cache_integration_spec.rb +0 -336
  67. data/spec/lutaml/store/custom_serializer_spec.rb +0 -108
  68. data/spec/lutaml/store/database_store_spec.rb +0 -279
  69. data/spec/lutaml/store/file_io_spec.rb +0 -220
  70. data/spec/lutaml/store/format/yamls_spec.rb +0 -80
  71. data/spec/lutaml/store/format_round_trip_spec.rb +0 -110
  72. data/spec/lutaml/store/format_spec.rb +0 -70
  73. data/spec/lutaml/store/http_cache_entry_spec.rb +0 -203
  74. data/spec/lutaml/store/http_cache_hal_integration_spec.rb +0 -404
  75. data/spec/lutaml/store/http_cache_spec.rb +0 -422
  76. data/spec/lutaml/store/http_header_processor_spec.rb +0 -290
  77. data/spec/lutaml/store/import_spec.rb +0 -90
  78. data/spec/lutaml/store/integrity_spec.rb +0 -157
  79. data/spec/lutaml/store/key_collision_serializer_spec.rb +0 -98
  80. data/spec/lutaml/store/load_save_spec.rb +0 -107
  81. data/spec/lutaml/store/lutaml_model_integration_spec.rb +0 -291
  82. data/spec/lutaml/store/model_serializer_spec.rb +0 -140
  83. data/spec/lutaml/store/package_definition_spec.rb +0 -89
  84. data/spec/lutaml/store/package_store_spec.rb +0 -153
  85. data/spec/lutaml/store/package_transport/directory_transport_spec.rb +0 -139
  86. data/spec/lutaml/store/package_transport/zip_transport_spec.rb +0 -85
  87. data/spec/lutaml/store/store_spec.rb +0 -182
  88. data/spec/lutaml/store_spec.rb +0 -21
  89. data/spec/spec_helper.rb +0 -16
  90. data/spec/support/simple_test_model.rb +0 -15
  91. data/spec/support/yamls_test_model.rb +0 -35
@@ -1,526 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "bundler/setup"
5
- require "lutaml/store"
6
- require "securerandom"
7
- require "date"
8
- require "paint"
9
- require "table_tennis"
10
- require_relative "vcard_models"
11
-
12
- # VCard Store Demo
13
- # This demo showcases the lutaml-store functionality using vCard models
14
- class VCardStoreDemo
15
- include VCardDemo
16
-
17
- def initialize
18
- @stores = {}
19
- setup_stores
20
- puts "šŸŽÆ VCard Store Demo Initialized"
21
- puts "=" * 50
22
- end
23
-
24
- def run
25
- puts "\nšŸ“‹ Running VCard Store Demo..."
26
-
27
- # Create sample vCards
28
- create_sample_vcards
29
-
30
- # Demonstrate different storage backends
31
- demonstrate_memory_store
32
- demonstrate_filesystem_store
33
- demonstrate_sqlite_store
34
- demonstrate_cache_store
35
-
36
- # Demonstrate search and retrieval
37
- demonstrate_search_capabilities
38
-
39
- # Demonstrate data integrity
40
- demonstrate_integrity_features
41
-
42
- puts "\nāœ… Demo completed successfully!"
43
- puts "Check the demo/data/ directory for persisted files."
44
- end
45
-
46
- private
47
-
48
- def setup_stores
49
- # Memory store for fast operations
50
- @stores[:memory] = Lutaml::Store::Store.new(
51
- adapter: { type: :memory }
52
- )
53
-
54
- # Filesystem store for persistence
55
- @stores[:filesystem] = Lutaml::Store::Store.new(
56
- adapter: {
57
- type: :filesystem,
58
- options: { path: "demo/data/vcards" }
59
- }
60
- )
61
-
62
- # SQLite store for structured queries
63
- @stores[:sqlite] = Lutaml::Store::Store.new(
64
- adapter: {
65
- type: :sqlite,
66
- options: { path: "demo/data/vcards.db" }
67
- }
68
- )
69
-
70
- # Cache store for performance
71
- @stores[:cache] = Lutaml::Store::CacheStore.new(
72
- adapter: { type: :memory },
73
- default_ttl: 300, # 5 minutes
74
- max_size: 100
75
- )
76
- end
77
-
78
- def create_sample_vcards
79
- puts "\nšŸ“ Creating 10 sample vCards..."
80
-
81
- @sample_vcards = [
82
- create_vcard(
83
- fn: "John Doe",
84
- given: "John", family: "Doe",
85
- email: ["john.doe@example.com", "j.doe@work.com"],
86
- phone: ["+1-555-0101", "work"],
87
- org: "Tech Corp",
88
- birthday: "1985-03-15"
89
- ),
90
- create_vcard(
91
- fn: "Jane Smith",
92
- given: "Jane", family: "Smith",
93
- email: ["jane.smith@example.com"],
94
- phone: ["+1-555-0102", "mobile"],
95
- org: "Design Studio",
96
- birthday: "1990-07-22"
97
- ),
98
- create_vcard(
99
- fn: "Dr. Robert Johnson",
100
- prefix: "Dr.", given: "Robert", family: "Johnson",
101
- email: ["r.johnson@hospital.com", "robert@personal.com"],
102
- phone: ["+1-555-0103", "work"],
103
- org: "City Hospital",
104
- birthday: "1975-11-08"
105
- ),
106
- create_vcard(
107
- fn: "Maria Garcia",
108
- given: "Maria", family: "Garcia",
109
- email: ["maria.garcia@startup.com"],
110
- phone: ["+1-555-0104", "mobile"],
111
- org: "Innovation Labs",
112
- birthday: "1988-02-14"
113
- ),
114
- create_vcard(
115
- fn: "David Wilson",
116
- given: "David", family: "Wilson",
117
- email: ["david.wilson@consulting.com"],
118
- phone: ["+1-555-0105", "work"],
119
- org: "Wilson Consulting",
120
- birthday: "1982-09-30"
121
- ),
122
- create_vcard(
123
- fn: "Sarah Brown",
124
- given: "Sarah", family: "Brown",
125
- email: ["sarah.brown@university.edu", "s.brown@research.org"],
126
- phone: ["+1-555-0106", "work"],
127
- org: "State University",
128
- birthday: "1979-12-03"
129
- ),
130
- create_vcard(
131
- fn: "Michael Davis",
132
- given: "Michael", family: "Davis",
133
- email: ["mike.davis@agency.com"],
134
- phone: ["+1-555-0107", "mobile"],
135
- org: "Creative Agency",
136
- birthday: "1992-05-18"
137
- ),
138
- create_vcard(
139
- fn: "Lisa Anderson",
140
- given: "Lisa", family: "Anderson",
141
- email: ["lisa.anderson@finance.com"],
142
- phone: ["+1-555-0108", "work"],
143
- org: "Financial Services Inc",
144
- birthday: "1986-08-25"
145
- ),
146
- create_vcard(
147
- fn: "James Taylor",
148
- given: "James", family: "Taylor",
149
- email: ["james.taylor@music.com", "jtaylor@personal.net"],
150
- phone: ["+1-555-0109", "mobile"],
151
- org: "Music Production",
152
- birthday: "1983-01-12"
153
- ),
154
- create_vcard(
155
- fn: "Emma Thompson",
156
- given: "Emma", family: "Thompson",
157
- email: ["emma.thompson@law.com"],
158
- phone: ["+1-555-0110", "work"],
159
- org: "Thompson & Associates",
160
- birthday: "1977-04-07"
161
- )
162
- ]
163
-
164
- puts "āœ… Created #{@sample_vcards.length} vCards"
165
- end
166
-
167
- def create_vcard(fn:, given:, family:, email:, phone:, org:, birthday:, prefix: nil)
168
- name = VcardName.new(
169
- given: given,
170
- family: family,
171
- prefix: prefix
172
- )
173
-
174
- tel = VcardTel.new(
175
- value: phone[0],
176
- type: phone[1]
177
- )
178
-
179
- bday = VcardBday.new(
180
- value: birthday
181
- )
182
-
183
- Vcard.new(
184
- fn: fn,
185
- n: name,
186
- email: email,
187
- tel: [tel],
188
- org: org,
189
- bday: bday
190
- )
191
- end
192
-
193
- def demonstrate_memory_store
194
- puts "\n🧠 Memory Store Demo"
195
- puts "-" * 30
196
-
197
- store = @stores[:memory]
198
-
199
- # Store all vCards
200
- @sample_vcards.each do |vcard|
201
- store.set(vcard.uid, vcard.to_h)
202
- puts "šŸ’¾ Stored: #{vcard.fn}"
203
- end
204
-
205
- puts "šŸ“Š Total stored: #{store.size} vCards"
206
-
207
- # Retrieve a specific vCard
208
- first_uid = @sample_vcards.first.uid
209
- retrieved = store.get(first_uid)
210
- puts "šŸ” Retrieved: #{retrieved["fn"]} by UID"
211
-
212
- # List all keys
213
- puts "šŸ—‚ļø All UIDs: #{store.keys.length} entries"
214
- end
215
-
216
- def demonstrate_filesystem_store
217
- puts "\nšŸ’¾ Filesystem Store Demo"
218
- puts "-" * 30
219
-
220
- store = @stores[:filesystem]
221
-
222
- # Store vCards with organized keys
223
- @sample_vcards.each_with_index do |vcard, index|
224
- key = "contact_#{index + 1}_#{vcard.n.family.downcase}"
225
- store.set(key, vcard.to_h)
226
- puts "šŸ“ Saved to file: #{key}"
227
- end
228
-
229
- puts "šŸ“Š Total files: #{store.size}"
230
-
231
- # Demonstrate file persistence
232
- puts "šŸ’½ Files are persisted in: demo/data/vcards/"
233
-
234
- # Retrieve by organized key
235
- key = "contact_1_doe"
236
- return unless store.exists?(key)
237
-
238
- retrieved = store.get(key)
239
- puts "šŸ” Retrieved from file: #{retrieved["fn"]}"
240
- end
241
-
242
- def demonstrate_sqlite_store
243
- puts "\nšŸ—„ļø SQLite Store Demo"
244
- puts "-" * 30
245
-
246
- store = @stores[:sqlite]
247
-
248
- # Store with email-based keys for easy lookup
249
- @sample_vcards.each do |vcard|
250
- email_key = vcard.primary_email.split("@").first
251
- store.set(email_key, vcard.to_h)
252
- puts "šŸ—ƒļø Stored in DB: #{email_key} -> #{vcard.fn}"
253
- end
254
-
255
- puts "šŸ“Š Total DB records: #{store.size}"
256
-
257
- # Demonstrate database persistence
258
- puts "šŸ’¾ Data persisted in: demo/data/vcards.db"
259
-
260
- # Retrieve by email key
261
- retrieved = store.get("john.doe")
262
- puts "šŸ” Retrieved from DB: #{retrieved["fn"]}" if retrieved
263
- end
264
-
265
- def demonstrate_cache_store
266
- puts "\n⚔ Cache Store Demo"
267
- puts "-" * 30
268
-
269
- cache = @stores[:cache]
270
-
271
- # Cache frequently accessed vCards
272
- @sample_vcards.first(5).each do |vcard|
273
- cache.set(vcard.uid, vcard.to_h, ttl: 60) # 1 minute TTL
274
- puts "⚔ Cached: #{vcard.fn} (TTL: 60s)"
275
- end
276
-
277
- # Demonstrate cache operations
278
- first_uid = @sample_vcards.first.uid
279
- puts "šŸ” Cache hit: #{cache.get(first_uid)["fn"]}"
280
- puts "ā±ļø TTL remaining: #{cache.ttl(first_uid).round(2)}s"
281
-
282
- # Cache statistics
283
- info = cache.cache_info
284
- puts "šŸ“Š Cache stats: #{info[:valid_entries]} valid, #{info[:expired_entries]} expired"
285
- end
286
-
287
- def demonstrate_search_capabilities
288
- puts "\nšŸ” Search & Retrieval Demo"
289
- puts "-" * 30
290
-
291
- # Search across different stores
292
- puts "šŸ¢ Finding contacts by organization:"
293
- find_by_organization("Tech Corp")
294
-
295
- puts "\nšŸ“§ Finding contacts by email domain:"
296
- find_by_email_domain("example.com")
297
-
298
- puts "\nšŸŽ‚ Finding contacts by birth year:"
299
- find_by_birth_year(1985)
300
-
301
- # Display contacts in a formatted table
302
- puts "\nšŸ“‹ Contact Directory (Table View)"
303
- puts "-" * 40
304
- display_contacts_table
305
-
306
- # Demonstrate ID-based search
307
- puts "\nšŸ†” Search by ID Demo"
308
- puts "-" * 25
309
- first_uid = @sample_vcards.first.uid
310
- colored_search_by_id(first_uid)
311
- end
312
-
313
- def find_by_organization(org_name)
314
- found = 0
315
- @stores[:memory].each_key do |key|
316
- vcard_data = @stores[:memory].get(key)
317
- if vcard_data["org"] == org_name
318
- puts " šŸ‘¤ #{vcard_data["fn"]} - #{vcard_data["org"]}"
319
- found += 1
320
- end
321
- end
322
- puts " šŸ“Š Found #{found} contacts in #{org_name}" if found.positive?
323
- end
324
-
325
- def find_by_email_domain(domain)
326
- @stores[:filesystem].each_key do |key|
327
- vcard_data = @stores[:filesystem].get(key)
328
- emails = vcard_data["email"] || []
329
- puts " šŸ“§ #{vcard_data["fn"]} - #{emails.first}" if emails.any? { |email| email.include?(domain) }
330
- end
331
- end
332
-
333
- def find_by_birth_year(year)
334
- @stores[:sqlite].each_key do |key|
335
- vcard_data = @stores[:sqlite].get(key)
336
- puts " šŸŽ‚ #{vcard_data["fn"]} - born in #{year}" if vcard_data.dig("bday", "value")&.start_with?(year.to_s)
337
- end
338
- end
339
-
340
- def demonstrate_integrity_features
341
- puts "\nšŸ”’ Data Integrity Demo"
342
- puts "-" * 30
343
-
344
- # Create a store with integrity checking
345
- integrity_store = Lutaml::Store::Store.new(
346
- adapter: { type: :memory },
347
- integrity: { enabled: true, algorithm: :sha256 }
348
- )
349
-
350
- # Store a vCard with integrity checking
351
- vcard = @sample_vcards.first
352
- integrity_store.set(vcard.uid, vcard.to_h)
353
- puts "šŸ” Stored with integrity check: #{vcard.fn}"
354
-
355
- # Verify integrity
356
- puts "āœ… Integrity verified for: #{vcard.fn}" if integrity_store.exists?(vcard.uid)
357
-
358
- # Demonstrate compression
359
- compressed_store = Lutaml::Store::Store.new(
360
- adapter: { type: :memory },
361
- compression: { enabled: true, algorithm: :gzip }
362
- )
363
-
364
- compressed_store.set(vcard.uid, vcard.to_h)
365
- puts "šŸ—œļø Stored with compression: #{vcard.fn}"
366
- end
367
-
368
- # Display contacts in a formatted table using table_tennis
369
- def display_contacts_table
370
- # Prepare data for the table (without colors for table_tennis)
371
- table_data = []
372
-
373
- # Header row (plain text for table_tennis)
374
- table_data << %w[Name Organization Email Phone Birthday]
375
-
376
- # Data rows from memory store
377
- @stores[:memory].keys.first(5).each do |key|
378
- vcard_data = @stores[:memory].get(key)
379
- emails = vcard_data["email"] || []
380
- tel_data = vcard_data["tel"] || []
381
- phone = tel_data.first&.dig("value") || "N/A"
382
- birthday = vcard_data.dig("bday", "value") || "N/A"
383
-
384
- table_data << [
385
- vcard_data["fn"],
386
- vcard_data["org"] || "N/A",
387
- emails.first || "N/A",
388
- phone,
389
- birthday
390
- ]
391
- end
392
-
393
- # Create and display the table
394
- table = TableTennis::Table.new(table_data)
395
- puts table
396
-
397
- # Show the saved files
398
- puts "\nšŸ“ Saved Files in Filesystem Store"
399
- puts "-" * 40
400
- show_saved_files
401
-
402
- # Display individual contact cards
403
- puts "\nšŸŽØ Individual Contact Cards"
404
- puts "-" * 40
405
- @sample_vcards.first(3).each do |vcard|
406
- display_colored_vcard(vcard)
407
- puts
408
- end
409
- end
410
-
411
- # Show the actual saved files and their contents
412
- def show_saved_files
413
- data_dir = "demo/data/vcards"
414
- puts "šŸ“‚ Directory: #{File.expand_path(data_dir)}"
415
-
416
- if Dir.exist?(data_dir)
417
- # Look for .data files specifically
418
- files = Dir.glob("#{data_dir}/**/*.data").first(3)
419
- files.each do |file|
420
- puts "\nšŸ“„ File: #{File.basename(file)}"
421
- puts " Path: #{file}"
422
- puts " Content preview:"
423
- if File.file?(file)
424
- content = File.read(file)
425
- # Show first few lines of YAML content
426
- lines = content.lines.first(8)
427
- lines.each { |line| puts " #{line.chomp}" }
428
- puts " ..." if content.lines.length > 8
429
- else
430
- puts " āŒ Not a regular file"
431
- end
432
- end
433
-
434
- # Also show directory structure
435
- puts "\nšŸ“ Directory Structure:"
436
- Dir.glob("#{data_dir}/**/*").first(10).each do |path|
437
- relative_path = path.sub("#{data_dir}/", "")
438
- if File.directory?(path)
439
- puts " šŸ“ #{relative_path}/"
440
- else
441
- puts " šŸ“„ #{relative_path}"
442
- end
443
- end
444
- else
445
- puts "āŒ Directory not found: #{data_dir}"
446
- end
447
- end
448
-
449
- # Display a single vCard with colors and formatting
450
- def display_colored_vcard(vcard)
451
- puts Paint["ā•”#{"═" * 50}ā•—", :blue, :bold]
452
- puts Paint["ā•‘", :blue, :bold] + Paint[" #{vcard.fn.center(48)} ", :white, :bold] + Paint["ā•‘", :blue, :bold]
453
- puts Paint["ā• #{"═" * 50}ā•£", :blue, :bold]
454
-
455
- # Name details
456
- if vcard.n.prefix
457
- puts Paint["ā•‘", :blue,
458
- :bold] + Paint[" Title: ", :cyan,
459
- :bold] + Paint["#{vcard.n.prefix.ljust(41)} ", :white] + Paint["ā•‘", :blue, :bold]
460
- end
461
-
462
- puts Paint["ā•‘", :blue,
463
- :bold] + Paint[" Given: ", :cyan,
464
- :bold] + Paint["#{vcard.n.given.ljust(40)} ", :white] + Paint["ā•‘", :blue, :bold]
465
- puts Paint["ā•‘", :blue,
466
- :bold] + Paint[" Family: ", :cyan,
467
- :bold] + Paint["#{vcard.n.family.ljust(39)} ", :white] + Paint["ā•‘", :blue, :bold]
468
-
469
- # Organization
470
- puts Paint["ā•‘", :blue,
471
- :bold] + Paint[" Organization: ", :green,
472
- :bold] + Paint["#{vcard.org.ljust(33)} ", :green] + Paint["ā•‘", :blue, :bold]
473
-
474
- # Contact info
475
- puts Paint["ā•‘", :blue,
476
- :bold] + Paint[" Email: ", :yellow,
477
- :bold] + Paint["#{vcard.primary_email.ljust(39)} ",
478
- :yellow] + Paint["ā•‘", :blue, :bold]
479
-
480
- if vcard.tel && !vcard.tel.empty?
481
- tel = vcard.tel.first
482
- phone_info = "#{tel.value} (#{tel.type})"
483
- puts Paint["ā•‘", :blue,
484
- :bold] + Paint[" Phone: ", :magenta,
485
- :bold] + Paint["#{phone_info.ljust(39)} ", :magenta] + Paint["ā•‘", :blue, :bold]
486
- end
487
-
488
- # Birthday
489
- if vcard.bday
490
- puts Paint["ā•‘", :blue,
491
- :bold] + Paint[" Birthday: ", :cyan,
492
- :bold] + Paint["#{vcard.bday.value.ljust(37)} ", :cyan] + Paint["ā•‘", :blue, :bold]
493
- end
494
-
495
- # UID
496
- puts Paint["ā•‘", :blue,
497
- :bold] + Paint[" UID: ", :red,
498
- :bold] + Paint["#{vcard.uid[0..41]}... ", :red] + Paint["ā•‘", :blue, :bold]
499
-
500
- puts Paint["ā•š#{"═" * 50}ā•", :blue, :bold]
501
- end
502
-
503
- # Enhanced search with colored output
504
- def colored_search_by_id(uid)
505
- puts Paint["\nšŸ” Searching for UID: #{uid}", :yellow, :bold]
506
-
507
- @stores.each do |store_name, store|
508
- next unless store.exists?(uid)
509
-
510
- vcard_data = store.get(uid)
511
- puts Paint["āœ… Found in #{store_name} store:", :green, :bold]
512
- puts Paint[" Name: #{vcard_data["fn"]}", :white]
513
- puts Paint[" Organization: #{vcard_data["org"]}", :green]
514
- return vcard_data
515
- end
516
-
517
- puts Paint["āŒ Not found in any store", :red, :bold]
518
- nil
519
- end
520
- end
521
-
522
- # Run the demo
523
- if __FILE__ == $PROGRAM_NAME
524
- demo = VCardStoreDemo.new
525
- demo.run
526
- end
data/lutaml-store.gemspec DELETED
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/lutaml/store/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "lutaml-store"
7
- spec.version = Lutaml::Store::VERSION
8
- spec.authors = ["Ronald Tse"]
9
- spec.email = ["ronald.tse@ribose.com"]
10
-
11
- spec.summary = "Store-centric database-style API for Lutaml::Model with multi-backend persistence."
12
- spec.description = <<~DESCRIPTION
13
- Provides a unified store interface for Lutaml::Model objects with model registry,
14
- polymorphic support, composite relationships, and multiple storage backends
15
- (memory, filesystem, SQLite).
16
- DESCRIPTION
17
-
18
- spec.homepage = "https://github.com/lutaml/lutaml-store"
19
- spec.license = "BSD-2-Clause"
20
-
21
- spec.bindir = "exe"
22
- spec.require_paths = ["lib"]
23
- spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
24
-
25
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
- `git ls-files -z`.split("\x0").reject do |f|
27
- f.match(%r{^(test|features)/})
28
- end
29
- end
30
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
-
32
- spec.add_dependency "lutaml-model", "~> 0.8.15"
33
- spec.add_dependency "rubyzip", "~> 2.3"
34
-
35
- spec.metadata["rubygems_mfa_required"] = "true"
36
- end