ohm-sorted 0.2.1 → 0.3.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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NTdhZWUxZTMxMjI1Y2E4OTliM2MzYjI2OTRmMDkxYjNlMzA1OTgzNg==
4
+ YmEwYzFiOTIwOGU3OWZhMGM2OTMzY2M4OTM1NTdmZTQ5Yzc4ZmUxMQ==
5
5
  data.tar.gz: !binary |-
6
- NDMzNzZhMzZhMTIyMTRlODc0Njc1ZmQwNzg4NWY5YjY4NGE1NDVkMQ==
6
+ MGQ3YzdhZjUwYTQwNzJkZjJjOWEyOTQzYzQxNmJmYjFhNWI3YTc5Ng==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MDMyM2E5NjgxODMxNjI1MmZmMDRjZjU1YzFhNDJkNWRjMzliOTZjMjc2ZWY4
10
- MTlkZDY5NmZhZjZmNjVlNGNmMTU2ZTRkM2Q1MTM5ODA1NjA0MWVmZjgyNzli
11
- NWRlZjQzNjAyODFlNzQzNmY4MTM5NWYwMGI2M2ZhODA2NzA4Y2Q=
9
+ MzE1Y2VjYzZiYjFkZjU2ZDExZWI5ZDYxMTllZmYyYWQ1ZWUzNDVmYTk5YmVi
10
+ NGFmMDExNmU4OTc0ZThjNzE3ZDRiZGZmNDBjYzk3NWQxZGY1MDRhZjNmYWEx
11
+ M2Y1YTJjNzBhYjc4Mjk3ZjgxMTVjOWY1ODg1Y2I0ZDkxZDdhN2Y=
12
12
  data.tar.gz: !binary |-
13
- NzBjNmIwYTdhYmJjNDM3NTAwOTFhZDhhZDM5YTYyOTRhMGIzNDU5Y2ZlMWMx
14
- Y2VmNmIzZGZlNGZkZmE1YWZmMDIzMmQ5NTczNzViYWRhMGVjN2ViMDJjNjU4
15
- YTc5YmFhOTdmYWE1MTA1MzRlN2U3MWQ4M2I0NWMzN2Q2YmZmZjM=
13
+ NjEzNTQ1M2JkYzk4MmQ3YmVjZmNkZjE0ZTc5NWQwYThiZDUzMDJjNjdmZTI3
14
+ Nzg1NDVmNzc2YTRhZGEwMjE0NTM0YjM5ZTEzZGEzMmZiN2FkOWY0ZjczYjZm
15
+ YjQ1MDM5ZTVmOWU1ZTQwMjg5MzEzMjY1ZjNlZGIzOTZjZDE4ZTc=
data/README.md CHANGED
@@ -5,7 +5,7 @@ ohm-sorted
5
5
  [![Build Status](https://travis-ci.org/educabilia/ohm-sorted.png?branch=master)](https://travis-ci.org/educabilia/ohm-sorted)
6
6
  [![Code Climate](https://codeclimate.com/github/educabilia/ohm-sorted.png)](https://codeclimate.com/github/educabilia/ohm-sorted)
7
7
 
8
- Sorted indexes for Ohm
8
+ Sorted indices for Ohm
9
9
 
10
10
 
11
11
  Setup
@@ -16,22 +16,46 @@ Setup
16
16
  include Ohm::Callbacks
17
17
  include Ohm::Sorted
18
18
 
19
- 2. Add a sorted index to your model with the following line:
19
+ 2. Add the sorted indices you want to your model:
20
20
 
21
- sorted :ranking, group_by: :status
21
+ - If you want a complete index:
22
+
23
+ sorted :created_at
24
+
25
+ - If you want to partition the index based on an attribute:
26
+
27
+ sorted :created_at, :group_by => :site_id
28
+
29
+
30
+ You can use both indices for the same attribute, as the partition keys are
31
+ namespaced by the `group_by` attribute.
32
+
33
+ You will need to resave every model if they already exist for the index to get
34
+ built.
35
+
36
+ The ranking attribute must be of a type that responds to `to_f`.
22
37
 
23
- You will need to resave every model if they already exist.
24
38
 
25
39
  Usage
26
40
  -----
27
41
 
28
42
  To query the sorted index, use the `sorted_find` class method.
29
43
 
30
- >> Post.sorted_find(:ranking, status: "draft")
44
+ >> Post.sorted_find(:created_at, site_id: "ar")
45
+
46
+ This returns an `Ohm::SortedSet`, similiar to an `Ohm::Set` but backed by a sorted
47
+ set.
48
+
49
+ To limit the results to a certain score range, use the `between` method.
50
+ This and the following methods return a new copy of the set object, but data
51
+ is not read until it is necessary.
52
+
53
+ >> Post.sorted_find(:created_at, site_id: "ar").between(start_time, end_time)
31
54
 
55
+ To take a slice of the results, use the `slice` method. This returns a new copy
56
+ of the set which will pass its `offset` and `count` parameters to Redis.
32
57
 
33
- This returns an Ohm::SortedSet, which is just a subclass of Ohm::BasicSet
34
- backed by a sorted set.
58
+ >> Post.sorted_find(:created_at, site_id: "ar").slice(2, 4)
35
59
 
36
60
 
37
61
  Requirements
data/lib/ohm/sorted.rb CHANGED
@@ -4,49 +4,52 @@ require 'ohm/contrib'
4
4
  module Ohm
5
5
 
6
6
  module SortedMethods
7
- attr_accessor :limit
8
- attr_accessor :offset
9
- attr_accessor :range
10
-
11
- def limit(n)
12
- set = dup
13
- set.limit = n
14
- set
7
+ attr :key
8
+ attr :namespace
9
+ attr :model
10
+
11
+ def initialize(key, namespace, model, options={})
12
+ @key = key
13
+ @namespace = namespace
14
+ @model = model
15
+ @options = options
15
16
  end
16
17
 
17
- def offset(n)
18
- set = dup
19
- set.offset = n
20
- set
18
+ def range
19
+ @options.fetch(:range, "-inf".."inf")
21
20
  end
22
21
 
23
- def start
24
- @start ||= (@offset || 0)
22
+ def offset
23
+ @options.fetch(:offset, 0)
25
24
  end
26
25
 
27
- def stop
28
- @stop ||= (@limit.nil? ? -1 : start + @limit - 1)
26
+ def count
27
+ @options.fetch(:count, -1)
29
28
  end
30
29
 
31
- def range(range)
32
- set = dup
33
- set.range = range
34
- set
30
+ def between(first, last)
31
+ range = first.to_f..last.to_f
32
+ opts = @options.merge(range: range)
33
+ SortedSet.new(key, namespace, model, opts)
35
34
  end
36
35
 
37
- def ids
38
- if @range.nil?
39
- execute { |key| db.zrange(key, start, stop) }
36
+ def slice(*args)
37
+ if args.count == 1
38
+ self[args.first]
39
+ elsif args.count == 2
40
+ offset, count = *args
41
+ opts = @options.merge(offset: offset, count: count)
42
+ SortedSet.new(key, namespace, model, opts)
40
43
  else
41
- execute { |key| db.zrangebyscore(key, @range.begin.to_f, @range.end.to_f, offset: [start, stop]) }
44
+ raise ArgumentError
42
45
  end
43
46
  end
44
47
 
45
- unless instance_methods.include?(:execute)
46
- def execute
47
- yield key
48
+ def ids
49
+ execute do |key|
50
+ db.zrangebyscore(key, range.begin, range.end,
51
+ limit: [offset, count])
48
52
  end
49
- private :execute
50
53
  end
51
54
  end
52
55
 
@@ -54,16 +57,6 @@ module Ohm
54
57
  class SortedSet < BasicSet
55
58
  include SortedMethods
56
59
 
57
- attr :key
58
- attr :namespace
59
- attr :model
60
-
61
- def initialize(key, namespace, model)
62
- @key = key
63
- @namespace = namespace
64
- @model = model
65
- end
66
-
67
60
  def size
68
61
  execute { |key| db.zcard(key) }
69
62
  end
@@ -90,11 +83,14 @@ module Ohm
90
83
  include Ohm::SortedMethods
91
84
 
92
85
  attr :key
86
+ attr :namespace
93
87
  attr :model
94
88
 
95
- def initialize(key, _, model)
89
+ def initialize(key, namespace, model, options={})
96
90
  @key = key
97
91
  @model = model
92
+ @namespace = namespace
93
+ @options = options
98
94
  end
99
95
 
100
96
  def db
@@ -122,12 +118,8 @@ module Ohm
122
118
  end
123
119
 
124
120
  def first
125
- if @range.nil?
126
- ids = db.zrange(key, start, 1)
127
- else
128
- ids = db.zrangebyscore(key, @range.begin.to_f, @range.end.to_f, offset: [start, 1])
129
- end
130
- ids.map(&model).first
121
+ id = db.zrange(key, 0, 1).first
122
+ model[id] unless id.empty?
131
123
  end
132
124
 
133
125
  def include?(model)
@@ -137,6 +129,11 @@ module Ohm
137
129
  def inspect
138
130
  "#<SortedSet (#{model}): #{db.zrange(key, 0, -1).inspect}>"
139
131
  end
132
+
133
+ private
134
+ def execute
135
+ yield key
136
+ end
140
137
  end
141
138
  end
142
139
 
@@ -201,6 +198,7 @@ module Ohm
201
198
 
202
199
  def before_update
203
200
  prune_sorted_indices
201
+ super
204
202
  end
205
203
 
206
204
  def after_update
data/ohm-sorted.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'ohm-sorted'
3
- s.version = '0.2.1'
3
+ s.version = '0.3.0'
4
4
  s.summary = "Sorted indices for Ohm."
5
5
  s.description = "An plugin for Ohm that lets you create sorted indices."
6
6
  s.author = "Federico Bond"
data/test/sorted_test.rb CHANGED
@@ -48,20 +48,14 @@ class SortedTest < Test::Unit::TestCase
48
48
  assert_equal [post_3, post_1, post_2], sorted_set.to_a
49
49
  end
50
50
 
51
- def test_sorted_find_with_limit
51
+ def test_sorted_find_with_slice
52
52
  posts = []
53
53
  posts << Post.create(order: 1)
54
54
  posts << Post.create(order: 2)
55
55
  Post.create(status: "draft", order: 3)
56
- assert_equal posts, Post.sorted_find(:order).limit(2).to_a
57
- end
58
-
59
- def test_sorted_find_with_offset
60
- Post.create(order: 1)
61
- posts = []
62
- posts << Post.create(order: 2)
63
- posts << Post.create(order: 3)
64
- assert_equal posts, Post.sorted_find(:order).offset(1).to_a
56
+ assert_equal posts, Post.sorted_find(:order).slice(0, 2).to_a
57
+ assert_equal posts[0, 1], Post.sorted_find(:order).slice(0, 1).to_a
58
+ assert_equal posts[1, 1], Post.sorted_find(:order).slice(1, 1).to_a
65
59
  end
66
60
 
67
61
  def test_sorted_find_with_range
@@ -71,8 +65,8 @@ class SortedTest < Test::Unit::TestCase
71
65
  posts << Post.create(status: "draft", order: 3)
72
66
  posts << Post.create(status: "published", order: 4)
73
67
  posts << Post.create(status: "draft", order: 5)
74
- assert_equal posts.slice(1, 2), Post.sorted_find(:order).range(2..3).to_a
75
- assert_equal [posts[3]], Post.sorted_find(:order, status: "published").range(2..4).to_a
68
+ assert_equal posts[1, 2], Post.sorted_find(:order).between(2, 3).to_a
69
+ assert_equal posts[3, 1], Post.sorted_find(:order, status: "published").between(2, 4).to_a
76
70
  end
77
71
 
78
72
  def test_sorted_find_first
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ohm-sorted
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Federico Bond
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-09 00:00:00.000000000 Z
11
+ date: 2013-09-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: An plugin for Ohm that lets you create sorted indices.
14
14
  email: federico@educabilia.com