familia 0.7.1 → 0.9.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e5c7b9afb9555b1223964ed3e93ac014df3c278e9c7467dfd26c5fced66e7298
4
+ data.tar.gz: 5ec4da06d0223bc8f27a2ba0689df6482dfbaf971028c3431bdc330cad332c13
5
+ SHA512:
6
+ metadata.gz: 7341bb23aa95bba387ab28377563d63d80933e99f3e5034ba65643c4806d7e7d7fc98308e9fc7ec7358d7c9775129bf0f02b198abd57b2b99bb1b28df0530a46
7
+ data.tar.gz: d4bbd6719f096d7f58ea00b0ae7a7ba2f5da71365b21b818863fc122b8a3856607248a803367ca9c87adc25b8d85b935331ce1413da4f803254baacf68cbb464
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ .DS_Store
2
+ .bundle
3
+ .byebug*
4
+ .history
5
+ .devcontainer
6
+ .vscode
7
+ *.env
8
+ *.log
9
+ *.md
10
+ *.txt
11
+ !LICENSE.txt
12
+ .ruby-version
13
+ appendonlydir
14
+ etc/config
15
+ log
16
+ tmp
17
+ vendor
18
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ ruby '>= 2.6.8'
4
+
5
+ gem 'redis', '~> 4.8'
6
+ gem 'uri-redis'
7
+ gem 'gibbler'
8
+ gem 'storable'
9
+ gem 'multi_json'
10
+
11
+ group :development, :test do
12
+ gem 'tryouts', '~> 2.2'
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ attic (1.0.0)
5
+ rake (~> 13.0.6)
6
+ drydock (0.6.9)
7
+ gibbler (1.0.0)
8
+ attic (~> 1.0)
9
+ rake (~> 13.0)
10
+ multi_json (1.15.0)
11
+ rake (13.0.6)
12
+ redis (4.8.1)
13
+ storable (0.10.0)
14
+ sysinfo (0.10.0)
15
+ drydock (< 1.0)
16
+ storable (~> 0.10)
17
+ tryouts (2.2.0)
18
+ sysinfo (~> 0.10)
19
+ uri-redis (0.4.2)
20
+
21
+ PLATFORMS
22
+ arm64-darwin-22
23
+
24
+ DEPENDENCIES
25
+ gibbler
26
+ multi_json
27
+ redis (~> 4.8)
28
+ storable
29
+ tryouts (~> 2.2)
30
+ uri-redis
31
+
32
+ RUBY VERSION
33
+ ruby 2.6.8p205
34
+
35
+ BUNDLED WITH
36
+ 2.4.12
@@ -1,29 +1,24 @@
1
- # Familia - 0.7 BETA
1
+ # Familia - 0.9 (2024-04-04)
2
2
 
3
3
  **Organize and store ruby objects in Redis**
4
4
 
5
5
 
6
6
  ## Basic Example
7
7
 
8
- class Bone < Storable
8
+ ```ruby
9
+ class Flower < Storable
9
10
  include Familia
10
11
  index [:token, :name]
11
- field :token
12
- field :name
12
+ field :token
13
+ field :name
13
14
  list :owners
14
15
  set :tags
15
16
  zset :metrics
16
17
  hash :props
17
18
  string :value, :default => "GREAT!"
18
19
  end
19
-
20
-
21
- ## More Information
22
-
23
- * [Codes](http://github.com/delano/familia)
24
- * [RDocs](http://delano.github.com/familia)
20
+ ```
25
21
 
22
+ ## More Information
26
23
 
27
- ## Credits
28
-
29
- * [Delano Mandelbaum](http://goldensword.ca)
24
+ * [Codes](https://github.com/delano/familia)
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
- ---
1
+ ---
2
2
  :MAJOR: 0
3
- :MINOR: 7
4
- :PATCH: 1
3
+ :MINOR: 9
4
+ :PATCH: 0
data/familia.gemspec CHANGED
@@ -1,74 +1,23 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
1
  Gem::Specification.new do |s|
7
- s.name = %q{familia}
8
- s.version = "0.7.1"
2
+ s.name = "familia"
3
+ s.version = "0.9.0"
4
+ s.summary = "Organize and store ruby objects in Redis"
5
+ s.description = "Familia: #{s.summary}"
6
+ s.authors = ["Delano Mandelbaum"]
7
+ s.email = "delano@solutious.com"
8
+ s.homepage = "https://github.com/delano/familia"
9
+ s.license = "MIT"
9
10
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Delano Mandelbaum"]
12
- s.date = %q{2011-04-11}
13
- s.description = %q{Organize and store ruby objects in Redis}
14
- s.email = %q{delano@solutious.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE.txt",
17
- "README.rdoc"
18
- ]
19
- s.files = [
20
- "CHANGES.txt",
21
- "LICENSE.txt",
22
- "README.rdoc",
23
- "Rakefile",
24
- "VERSION.yml",
25
- "familia.gemspec",
26
- "lib/familia.rb",
27
- "lib/familia/core_ext.rb",
28
- "lib/familia/helpers.rb",
29
- "lib/familia/object.rb",
30
- "lib/familia/redisobject.rb",
31
- "lib/familia/test_helpers.rb",
32
- "lib/familia/tools.rb",
33
- "try/00_familia.rb",
34
- "try/10_familia_try.rb",
35
- "try/20_redis_object_try.rb",
36
- "try/21_redis_object_zset_try.rb",
37
- "try/22_redis_object_set_try.rb",
38
- "try/23_redis_object_list_try.rb",
39
- "try/24_redis_object_string_try.rb",
40
- "try/25_redis_object_hash_try.rb",
41
- "try/30_familia_object_try.rb"
42
- ]
43
- s.homepage = %q{http://github.com/delano/familia}
44
- s.rdoc_options = ["--charset=UTF-8"]
11
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
12
+ s.bindir = "exe"
13
+ s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
45
14
  s.require_paths = ["lib"]
46
- s.rubyforge_project = %q{familia}
47
- s.rubygems_version = %q{1.5.2}
48
- s.summary = %q{Organize and store ruby objects in Redis}
49
15
 
50
- if s.respond_to? :specification_version then
51
- s.specification_version = 3
16
+ s.required_ruby_version = Gem::Requirement.new(">= 2.6.8")
52
17
 
53
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
54
- s.add_runtime_dependency(%q<redis>, [">= 2.1.0"])
55
- s.add_runtime_dependency(%q<uri-redis>, [">= 0.4.2"])
56
- s.add_runtime_dependency(%q<gibbler>, [">= 0.8.6"])
57
- s.add_runtime_dependency(%q<storable>, [">= 0.8.6"])
58
- s.add_runtime_dependency(%q<multi_json>, [">= 0.0.5"])
59
- else
60
- s.add_dependency(%q<redis>, [">= 2.1.0"])
61
- s.add_dependency(%q<uri-redis>, [">= 0.4.2"])
62
- s.add_dependency(%q<gibbler>, [">= 0.8.6"])
63
- s.add_dependency(%q<storable>, [">= 0.8.6"])
64
- s.add_dependency(%q<multi_json>, [">= 0.0.5"])
65
- end
66
- else
67
- s.add_dependency(%q<redis>, [">= 2.1.0"])
68
- s.add_dependency(%q<uri-redis>, [">= 0.4.2"])
69
- s.add_dependency(%q<gibbler>, [">= 0.8.6"])
70
- s.add_dependency(%q<storable>, [">= 0.8.6"])
71
- s.add_dependency(%q<multi_json>, [">= 0.0.5"])
72
- end
18
+ s.add_dependency "redis", "~> 4.8.0"
19
+ s.add_dependency "uri-redis", "~> 0.4", ">= 0.4.2"
20
+ s.add_dependency "gibbler", "~> 1.0.0"
21
+ s.add_dependency "storable", "~> 0.10.0"
22
+ s.add_dependency "multi_json", "~> 0.0", ">= 0.0.5"
73
23
  end
74
-
@@ -2,12 +2,12 @@ require 'ostruct'
2
2
 
3
3
  module Familia
4
4
  require 'familia/redisobject'
5
-
5
+
6
6
  # Auto-extended into a class that includes Familia
7
7
  module ClassMethods
8
-
8
+
9
9
  Familia::RedisObject.registration.each_pair do |kind, klass|
10
- # e.g.
10
+ # e.g.
11
11
  #
12
12
  # list(name, klass, opts)
13
13
  # list?(name)
@@ -22,12 +22,12 @@ module Familia
22
22
  obj = redis_objects[name.to_s.to_sym]
23
23
  !obj.nil? && klass == obj.klass
24
24
  end
25
- define_method :"#{kind}s" do
25
+ define_method :"#{kind}s" do
26
26
  names = redis_objects_order.select { |name| send(:"#{kind}?", name) }
27
27
  names.collect! { |name| redis_objects[name] }
28
28
  names
29
29
  end
30
- # e.g.
30
+ # e.g.
31
31
  #
32
32
  # class_list(name, klass, opts)
33
33
  # class_list?(name)
@@ -41,11 +41,11 @@ module Familia
41
41
  obj = class_redis_objects[name.to_s.to_sym]
42
42
  !obj.nil? && klass == obj.klass
43
43
  end
44
- define_method :"class_#{kind}s" do
44
+ define_method :"class_#{kind}s" do
45
45
  names = class_redis_objects_order.select { |name| ret = send(:"class_#{kind}?", name) }
46
46
  # TODO: This returns instances of the RedisObject class which
47
47
  # also contain the options. This is different from the instance
48
- # RedisObjects defined above which returns the OpenStruct of name, klass, and opts.
48
+ # RedisObjects defined above which returns the OpenStruct of name, klass, and opts.
49
49
  #names.collect! { |name| self.send name }
50
50
  # OR NOT:
51
51
  names.collect! { |name| class_redis_objects[name] }
@@ -69,9 +69,9 @@ module Familia
69
69
  obj.class_zset :instances, :class => obj, :reference => true
70
70
  Familia.classes << obj
71
71
  end
72
-
72
+
73
73
  # Creates an instance method called +name+ that
74
- # returns an instance of the RedisObject +klass+
74
+ # returns an instance of the RedisObject +klass+
75
75
  def install_redis_object name, klass, opts
76
76
  raise ArgumentError, "Name is blank" if name.to_s.empty?
77
77
  name = name.to_s.to_sym
@@ -90,34 +90,34 @@ module Familia
90
90
  end
91
91
  redis_objects[name]
92
92
  end
93
-
93
+
94
94
  def qstamp quantum=nil, pattern=nil, now=Familia.now
95
95
  quantum ||= ttl || 10.minutes
96
96
  pattern ||= '%H%M'
97
97
  rounded = now - (now % quantum)
98
98
  Time.at(rounded).utc.strftime(pattern)
99
99
  end
100
-
100
+
101
101
  # Creates a class method called +name+ that
102
- # returns an instance of the RedisObject +klass+
102
+ # returns an instance of the RedisObject +klass+
103
103
  def install_class_redis_object name, klass, opts
104
104
  raise ArgumentError, "Name is blank" if name.to_s.empty?
105
105
  name = name.to_s.to_sym
106
106
  opts = opts.nil? ? {} : opts.clone
107
107
  opts[:parent] = self unless opts.has_key?(:parent)
108
- # TODO: investigate using metaclass.redis_objects
108
+ # TODO: investigate using attic.redis_objects
109
109
  class_redis_objects_order << name
110
110
  class_redis_objects[name] = OpenStruct.new
111
111
  class_redis_objects[name].name = name
112
112
  class_redis_objects[name].klass = klass
113
- class_redis_objects[name].opts = opts
113
+ class_redis_objects[name].opts = opts
114
114
  # An accessor method created in the metclass will
115
- # access the instance variables for this class.
116
- metaclass.send :attr_reader, name
117
- metaclass.send :define_method, "#{name}=" do |v|
115
+ # access the instance variables for this class.
116
+ attic.send :attr_reader, name
117
+ attic.send :define_method, "#{name}=" do |v|
118
118
  send(name).replace v
119
119
  end
120
- metaclass.send :define_method, "#{name}?" do
120
+ attic.send :define_method, "#{name}?" do
121
121
  !send(name).empty?
122
122
  end
123
123
  redis_object = klass.new name, opts
@@ -125,7 +125,7 @@ module Familia
125
125
  self.instance_variable_set("@#{name}", redis_object)
126
126
  class_redis_objects[name]
127
127
  end
128
-
128
+
129
129
  def from_redisdump dump
130
130
  dump # todo
131
131
  end
@@ -146,9 +146,9 @@ module Familia
146
146
  def port=(port) @port = port end
147
147
  def uri=(uri)
148
148
  uri = URI.parse uri if String === uri
149
- @uri = uri
149
+ @uri = uri
150
150
  end
151
- def uri(uri=nil)
151
+ def uri(uri=nil)
152
152
  self.uri = uri if !uri.to_s.empty?
153
153
  @uri ||= (parent ? parent.uri : Familia.uri)
154
154
  @uri.db = @db if @db && @uri.db.to_s != @db.to_s
@@ -166,7 +166,7 @@ module Familia
166
166
  end
167
167
  def all(suffix=:object)
168
168
  # objects that could not be parsed will be nil
169
- keys(suffix).collect { |k| from_key(k) }.compact
169
+ keys(suffix).collect { |k| from_key(k) }.compact
170
170
  end
171
171
  def any?(filter='*')
172
172
  size(filter) > 0
@@ -174,7 +174,7 @@ module Familia
174
174
  def size(filter='*')
175
175
  self.redis.keys(rediskey(filter)).compact.size
176
176
  end
177
- def suffix(a=nil, &blk)
177
+ def suffix(a=nil, &blk)
178
178
  @suffix = a || blk if a || !blk.nil?
179
179
  val = @suffix || Familia.default_suffix
180
180
  val
@@ -184,7 +184,7 @@ module Familia
184
184
  # TODO: grab db, ttl, uri from parent
185
185
  #def parent=(a) @parent = a end
186
186
  #def parent(a=nil) @parent = a if a; @parent end
187
- def index(i=nil, &blk)
187
+ def index(i=nil, &blk)
188
188
  @index = i || blk if i || !blk.nil?
189
189
  @index ||= Familia.index
190
190
  @index
@@ -230,9 +230,9 @@ module Familia
230
230
  Familia.trace :MULTIGET, self.redis, "#{ids.size}: #{ids}", caller if Familia.debug?
231
231
  ids = self.redis.mget *ids
232
232
  end
233
-
233
+
234
234
  # Returns an instance based on +idx+ otherwise it
235
- # creates and saves a new instance base on +idx+.
235
+ # creates and saves a new instance base on +idx+.
236
236
  # See from_index
237
237
  def load_or_create idx
238
238
  return from_redis(idx) if exists?(idx)
@@ -240,17 +240,17 @@ module Familia
240
240
  obj.save
241
241
  obj
242
242
  end
243
- # Note +idx+ needs to be an appropriate index for
243
+ # Note +idx+ needs to be an appropriate index for
244
244
  # the given class. If the index is multi-value it
245
245
  # must be passed as an Array in the proper order.
246
246
  # Does not call save.
247
247
  def from_index idx
248
- obj = new
248
+ obj = new
249
249
  obj.index = idx
250
250
  obj
251
251
  end
252
252
  def from_key objkey
253
- raise ArgumentError, "Empty key" if objkey.to_s.empty?
253
+ raise ArgumentError, "Empty key" if objkey.to_s.empty?
254
254
  Familia.trace :LOAD, Familia.redis(self.uri), objkey, caller if Familia.debug?
255
255
  obj = Familia::String.new objkey, :class => self
256
256
  obj.value
@@ -293,18 +293,18 @@ module Familia
293
293
  case list.size
294
294
  when 0
295
295
  nil
296
- when 1
296
+ when 1
297
297
  matches = list.first.match(/\A#{Familia.rediskey(prefix)}\:(.+?)\:#{suffix}/) || []
298
298
  matches[1]
299
299
  else
300
- raise Familia::NonUniqueKey, "Short key returned more than 1 match"
300
+ raise Familia::NonUniqueKey, "Short key returned more than 1 match"
301
301
  end
302
302
  end
303
303
  end
304
304
 
305
-
305
+
306
306
  module InstanceMethods
307
-
307
+
308
308
  # A default initialize method. This will be replaced
309
309
  # if a class defines its own initialize method after
310
310
  # including Familia. In that case, the replacement
@@ -313,15 +313,15 @@ module Familia
313
313
  initialize_redis_objects
314
314
  init *args if respond_to? :init
315
315
  end
316
-
316
+
317
317
  # This needs to be called in the initialize method of
318
- # any class that includes Familia.
318
+ # any class that includes Familia.
319
319
  def initialize_redis_objects
320
320
  # Generate instances of each RedisObject. These need to be
321
321
  # unique for each instance of this class so they can refer
322
322
  # to the index of this specific instance.
323
323
  #
324
- # i.e.
324
+ # i.e.
325
325
  # familia_object.rediskey == v1:bone:INDEXVALUE:object
326
326
  # familia_object.redis_object.rediskey == v1:bone:INDEXVALUE:name
327
327
  #
@@ -335,19 +335,19 @@ module Familia
335
335
  self.instance_variable_set "@#{name}", redis_object
336
336
  end
337
337
  end
338
-
338
+
339
339
  def qstamp quantum=nil, pattern=nil, now=Familia.now
340
340
  self.class.qstamp ttl, pattern, now
341
341
  end
342
-
343
- def from_redis
342
+
343
+ def from_redis
344
344
  self.class.from_redis self.index
345
345
  end
346
-
346
+
347
347
  def redis
348
348
  self.class.redis
349
349
  end
350
-
350
+
351
351
  def redisinfo
352
352
  info = {
353
353
  :uri => self.class.uri,
@@ -359,32 +359,32 @@ module Familia
359
359
  end
360
360
  def exists?
361
361
  Familia.redis(self.class.uri).exists rediskey
362
- end
363
-
362
+ end
363
+
364
364
  #def rediskeys
365
365
  # self.class.redis_objects.each do |redis_object_definition|
366
- #
366
+ #
367
367
  # end
368
368
  #end
369
-
369
+
370
370
  def allkeys
371
371
  # TODO: Use redis_objects instead
372
372
  keynames = []
373
- self.class.suffixes.each do |sfx|
373
+ self.class.suffixes.each do |sfx|
374
374
  keynames << rediskey(sfx)
375
375
  end
376
376
  keynames
377
377
  end
378
378
  # +suffix+ is the value to be used at the end of the redis key
379
379
  # + ignored+ is literally ignored. It's around to maintain
380
- # consistency with the class version of this method.
380
+ # consistency with the class version of this method.
381
381
  # (RedisObject#rediskey may call against a class or instance).
382
382
  def rediskey(suffix=nil, ignored=nil)
383
383
  Familia.info "[#{self.class}] something was ignored" unless ignored.nil?
384
384
  raise Familia::NoIndex, self.class if index.to_s.empty?
385
385
  if suffix.nil?
386
- suffix = self.class.suffix.kind_of?(Proc) ?
387
- self.class.suffix.call(self) :
386
+ suffix = self.class.suffix.kind_of?(Proc) ?
387
+ self.class.suffix.call(self) :
388
388
  self.class.suffix
389
389
  end
390
390
  self.class.rediskey self.index, suffix
@@ -405,7 +405,7 @@ module Familia
405
405
  end
406
406
  ret == "OK" || ret == true || ret == 1
407
407
  end
408
- def savenx
408
+ def savenx
409
409
  save :setnx
410
410
  end
411
411
  def update! hsh=nil
@@ -416,10 +416,10 @@ module Familia
416
416
  ret = from_redis
417
417
  hsh = ret.to_hash if ret
418
418
  end
419
- hsh.keys.each { |field|
419
+ hsh.keys.each { |field|
420
420
  v = hsh[field.to_s] || hsh[field.to_s.to_sym]
421
421
  next if v.nil?
422
- self.send(:"#{field}=", v)
422
+ self.send(:"#{field}=", v)
423
423
  updated = true
424
424
  }
425
425
  updated
@@ -437,7 +437,7 @@ module Familia
437
437
  when Proc
438
438
  self.class.index.call(self)
439
439
  when Array
440
- parts = self.class.index.collect { |meth|
440
+ parts = self.class.index.collect { |meth|
441
441
  unless self.respond_to? meth
442
442
  raise NoIndex, "No such method: `#{meth}' for #{self.class}"
443
443
  end
@@ -469,11 +469,11 @@ module Familia
469
469
  unless Array === v && v.size == self.class.index.size
470
470
  raise ArgumentError, "Index mismatch (#{v.size} for #{self.class.index.size})"
471
471
  end
472
- parts = self.class.index.each_with_index { |meth,idx|
472
+ parts = self.class.index.each_with_index { |meth,idx|
473
473
  unless self.respond_to? "#{meth}="
474
474
  raise NoIndex, "No such method: `#{meth}=' for #{self.class}"
475
475
  end
476
- self.send("#{meth}=", v[idx])
476
+ self.send("#{meth}=", v[idx])
477
477
  }
478
478
  when Symbol, String
479
479
  if self.class.redis_object?(self.class.index.to_sym)
@@ -487,7 +487,7 @@ module Familia
487
487
  else
488
488
  raise Familia::NoIndex, self
489
489
  end
490
-
490
+
491
491
  end
492
492
  def expire(ttl=nil)
493
493
  ttl ||= self.class.ttl
@@ -526,8 +526,8 @@ module Familia
526
526
  len += 1
527
527
  end
528
528
  end
529
- @id.shorten(len)
529
+ @id.shorten(len)
530
530
  end
531
531
  end
532
-
533
- end
532
+
533
+ end