mementus 0.2.6 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a03cb6779f6872174442d561581c14c8048597c7
4
- data.tar.gz: e0b0e81f172b9b699a94a2da9ca65da1899823ee
3
+ metadata.gz: 2ae7a8b89d3a35849ea26912ff75d5b2491e7c87
4
+ data.tar.gz: 0d4bdcb9bede0c28548e2f1565126864e98683ff
5
5
  SHA512:
6
- metadata.gz: 5c45ef7529f95d104b97a4e92dd7ee0b922250f689e63f713f2b05c3794811cac69abb5b2d6b78c41cb058cf943a508c99d7af30eac6f65e84f82abe7b1c4992
7
- data.tar.gz: 8e62108ba5e92626ffea76a45d1222e7fe4c6cd3769e3af6ebf66b182d37d73d49ea67ef0d6bd4c9b9c22f98bd5ddade73e836bbd062a0d79fef072e96cbb481
6
+ metadata.gz: 8eff9fc722af1259cd66415632281d52f5e237da5f9914b05416d5ae6f84e662290a2072674f5d2a659de6f297d45c1539c4000eea2327ae6dd4dfb4d2616384
7
+ data.tar.gz: cffc400f5e932176b9dcd8a0bc06d0506964ed8a2268acc818205b6c82bf9fb761997c85711e28600e85d954b6521d1eeac6c552a03882be0dee26607882369b
data/README.md CHANGED
@@ -1,99 +1,3 @@
1
1
  # Mementus
2
2
 
3
3
  [![Build Status](https://travis-ci.org/maetl/mementus.svg?branch=master)](https://travis-ci.org/maetl/mementus)
4
-
5
- Mementus is a transient ORM for creating and querying in-memory object models.
6
-
7
- ## Installation
8
-
9
- Add this line to your application's Gemfile and `bundle` or `bundle update`:
10
-
11
- gem 'mementus'
12
-
13
- Or install with your local Rubygems:
14
-
15
- $ gem install mementus
16
-
17
- ## Usage
18
-
19
- ### Defining model classes
20
-
21
- To define model classes, inherit from the `Mementus::Model` base class and add attributes using the [Virtus API](https://github.com/solnic/virtus):
22
-
23
- ```ruby
24
- class Book < Mementus::Model
25
- attribute :title, String
26
- attribute :author, String
27
- end
28
- ```
29
-
30
- ### Creating objects
31
-
32
- Create new instances by passing data through the constructor or assigning attributes directly:
33
-
34
- ```ruby
35
- book1 = Book.new(
36
- :title => "Gravity's Rainbow",
37
- :author => "Thomas Pynchon"
38
- )
39
-
40
- book2 = Book.new
41
- book2.title = "The Golden Notebook"
42
- book2.author = "Doris Lessing"
43
- ```
44
-
45
- To write objects to the in-memory index, call their `create` method:
46
-
47
- ```ruby
48
- book3 = Book.new(
49
- :title => "Crash",
50
- :author => "J.G. Ballard"
51
- )
52
-
53
- book3.create
54
- ```
55
-
56
- ### Matching queries
57
-
58
- Basic match queries can be constructed by passing a predicate hash to the `where` method:
59
-
60
- ```ruby
61
- Book.where(author: "Doris Lessing")
62
-
63
- Book.where(title: "Crash")
64
- ```
65
-
66
- ### Scoped queries
67
-
68
- Reusable query shortcuts can be constructed on the model class by defining a `scope`:
69
-
70
- ```ruby
71
- class Book < Mementus::Model
72
- attribute :title, String
73
- attribute :author, String
74
- attribute :genre, String
75
- scope :scifi, genre: 'scifi'
76
- scope :romance, genre: 'romance'
77
- end
78
- ```
79
-
80
- These defined scopes become class methods on the model:
81
-
82
- ```ruby
83
- scifi_books = Book.scifi
84
- romance_books = Book.romance
85
- ```
86
-
87
- ## Roadmap
88
-
89
- - 0.2: Query API
90
- - 0.3: Relationships API
91
- - 0.4: Value objects
92
-
93
- ## Contributing
94
-
95
- 1. Fork it
96
- 2. Create your feature branch (`git checkout -b my-new-feature`)
97
- 3. Commit your changes (`git commit -am 'Add some feature'`)
98
- 4. Push to the branch (`git push origin my-new-feature`)
99
- 5. Create new Pull Request
@@ -0,0 +1,39 @@
1
+ module Mementus
2
+ class EdgeBuilder
3
+ attr_reader :from, :to, :label
4
+
5
+ def initialize(from=nil, to=nil, label=:edge)
6
+ @from = from
7
+ @to = to
8
+ @label = label
9
+ end
10
+
11
+ def from=(node, label=:node)
12
+ if node.is_a?(Node)
13
+ @from = node
14
+ else
15
+ @from = Node.new(node, label)
16
+ end
17
+ end
18
+
19
+ def to=(node)
20
+ if node.is_a?(Node)
21
+ @to = node
22
+ else
23
+ @to = Node.new(node, label)
24
+ end
25
+ end
26
+
27
+ def label=(label)
28
+ @label = label
29
+ end
30
+
31
+ def nodes
32
+ [@from, @to]
33
+ end
34
+
35
+ def other(node)
36
+ @from == node ? @to : @from
37
+ end
38
+ end
39
+ end
@@ -2,8 +2,12 @@ require 'set'
2
2
 
3
3
  module Mementus
4
4
  class Graph
5
- def initialize(is_directed=true)
6
- @structure = Structure.new(is_directed)
5
+ def initialize(is_directed=true, &block)
6
+ builder = GraphBuilder.new(is_directed)
7
+
8
+ builder.instance_eval(&block) if block_given?
9
+
10
+ @structure = builder.graph
7
11
  end
8
12
 
9
13
  def query
@@ -22,22 +26,6 @@ module Mementus
22
26
  @structure.directed?
23
27
  end
24
28
 
25
- def add_node(node)
26
- @structure.add_node(node)
27
- end
28
-
29
- def create_edge(&block)
30
- @structure.create_edge(&block)
31
- end
32
-
33
- def create_node(&block)
34
- @structure.create_node(&block)
35
- end
36
-
37
- def add_edge(edge)
38
- @structure.add_edge(edge)
39
- end
40
-
41
29
  def has_node?(node)
42
30
  @structure.has_node?(node)
43
31
  end
@@ -0,0 +1,27 @@
1
+ module Mementus
2
+ class GraphBuilder
3
+ def initialize(is_directed)
4
+ @structure = Structure.new(is_directed)
5
+ end
6
+
7
+ def add_node(node)
8
+ @structure.add_node(node)
9
+ end
10
+
11
+ def create_edge(&block)
12
+ @structure.create_edge(&block)
13
+ end
14
+
15
+ def create_node(&block)
16
+ @structure.create_node(&block)
17
+ end
18
+
19
+ def add_edge(edge)
20
+ @structure.add_edge(edge)
21
+ end
22
+
23
+ def graph
24
+ @structure
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ require 'thread'
2
+
3
+ module Mementus
4
+ class IntegerId
5
+ def initialize(start_value=1)
6
+ @current_value = start_value
7
+ @mutex = Mutex.new
8
+ end
9
+
10
+ def next_id
11
+ @mutex.lock
12
+ allocated = @current_value
13
+ @current_value += 1
14
+ @mutex.unlock
15
+ allocated
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Mementus
2
+ class NodeBuilder
3
+ attr_reader :id, :label
4
+
5
+ def initialize(id=nil, label=:node)
6
+ @id = id
7
+ @label = label
8
+ end
9
+
10
+ def id=(id)
11
+ @id = id
12
+ end
13
+
14
+ def label=(label)
15
+ @label = label
16
+ end
17
+ end
18
+ end
@@ -1,6 +1,6 @@
1
1
  module Mementus
2
2
  class Structure
3
- def initialize(is_directed)
3
+ def initialize(is_directed=true)
4
4
  @index = {}
5
5
  @is_directed = is_directed
6
6
  end
@@ -36,8 +36,8 @@ module Mementus
36
36
  end
37
37
 
38
38
  def add_edge(edge)
39
- add_node(edge.from)
40
- add_node(edge.to)
39
+ add_node(edge.from) unless has_node?(edge.from)
40
+ add_node(edge.to) unless has_node?(edge.to)
41
41
 
42
42
  @index[edge.from].add(edge.to)
43
43
  @index[edge.to].add(edge.from) unless directed?
@@ -1,3 +1,3 @@
1
1
  module Mementus
2
- VERSION = '0.2.6'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
data/lib/mementus.rb CHANGED
@@ -9,3 +9,7 @@ require_relative 'mementus/query/traversal'
9
9
  require_relative 'mementus/query/source'
10
10
  require_relative 'mementus/query/step'
11
11
  require_relative 'mementus/query/traversal'
12
+ require_relative 'mementus/integer_id'
13
+ require_relative 'mementus/graph_builder'
14
+ require_relative 'mementus/node_builder'
15
+ require_relative 'mementus/edge_builder'
data/spec/graph_spec.rb CHANGED
@@ -1,6 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Mementus::Graph do
4
+ let(:graph) do
5
+
6
+ end
7
+
4
8
  specify '#new' do
5
9
  graph = Mementus::Graph.new
6
10
 
@@ -9,18 +13,20 @@ describe Mementus::Graph do
9
13
  end
10
14
 
11
15
  specify '#add_node' do
12
- graph = Mementus::Graph.new
13
- graph.add_node(Mementus::Node.new(1, :node))
16
+ graph = Mementus::Graph.new do
17
+ add_node(Mementus::Node.new(1, :node))
18
+ end
14
19
 
15
20
  expect(graph.nodes_count).to eq(1)
16
21
  expect(graph.edges_count).to eq(0)
17
22
  end
18
23
 
19
24
  specify '#create_node' do
20
- graph = Mementus::Graph.new
21
- graph.create_node do |node|
22
- node.id = 1
23
- node.label = :vertex
25
+ graph = Mementus::Graph.new do
26
+ create_node do |node|
27
+ node.id = 1
28
+ node.label = :vertex
29
+ end
24
30
  end
25
31
 
26
32
  expect(graph.nodes_count).to eq(1)
@@ -28,19 +34,21 @@ describe Mementus::Graph do
28
34
  end
29
35
 
30
36
  specify '#add_edge' do
31
- graph = Mementus::Graph.new
32
- graph.add_edge(Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node)))
37
+ graph = Mementus::Graph.new do
38
+ add_edge(Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node)))
39
+ end
33
40
 
34
41
  expect(graph.nodes_count).to eq(2)
35
42
  expect(graph.edges_count).to eq(1)
36
43
  end
37
44
 
38
45
  specify '#create_edge' do
39
- graph = Mementus::Graph.new
40
- graph.create_edge do |edge|
41
- edge.label = :relationship
42
- edge.from = "A"
43
- edge.to = "B"
46
+ graph = Mementus::Graph.new do
47
+ create_edge do |edge|
48
+ edge.label = :relationship
49
+ edge.from = "A"
50
+ edge.to = "B"
51
+ end
44
52
  end
45
53
 
46
54
  expect(graph.nodes_count).to eq(2)
@@ -48,36 +56,41 @@ describe Mementus::Graph do
48
56
  end
49
57
 
50
58
  specify '#has_node?' do
51
- graph = Mementus::Graph.new
52
59
  node = Mementus::Node.new(1, :node)
53
- graph.add_node(node)
60
+ graph = Mementus::Graph.new do
61
+ add_node(node)
62
+ end
54
63
 
55
64
  expect(graph.has_node?(node)).to be true
56
65
  expect(graph.has_node?(node.dup)).to be false
57
66
  end
58
67
 
59
68
  specify '#has_edge?' do
60
- graph = Mementus::Graph.new
61
69
  edge = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
62
70
  edge2 = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
63
- graph.add_edge(edge)
71
+
72
+ graph = Mementus::Graph.new do
73
+ add_edge(edge)
74
+ end
64
75
 
65
76
  expect(graph.has_edge?(edge)).to be true
66
77
  expect(graph.has_edge?(edge2)).to be false
67
78
  end
68
79
 
69
80
  specify '#node(id)' do
70
- graph = Mementus::Graph.new
71
81
  edge = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
72
- graph.add_edge(edge)
82
+ graph = Mementus::Graph.new do
83
+ add_edge(edge)
84
+ end
73
85
 
74
86
  expect(graph.node(1)).to eq(edge.from)
75
87
  end
76
88
 
77
89
  specify '#nodes(filter)' do
78
- graph = Mementus::Graph.new
79
90
  edge = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
80
- graph.add_edge(edge)
91
+ graph = Mementus::Graph.new do
92
+ add_edge(edge)
93
+ end
81
94
 
82
95
  expect(graph.nodes).to eq([edge.from, edge.to])
83
96
  end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mementus::IntegerId do
4
+ it 'counts upwards from 1 by default' do
5
+ generator = Mementus::IntegerId.new
6
+ expect(generator.next_id).to eq(1)
7
+ expect(generator.next_id).to eq(2)
8
+ expect(generator.next_id).to eq(3)
9
+ end
10
+
11
+ it 'counts upwards from given start value' do
12
+ generator = Mementus::IntegerId.new(100)
13
+ expect(generator.next_id).to eq(100)
14
+ expect(generator.next_id).to eq(101)
15
+ expect(generator.next_id).to eq(102)
16
+ end
17
+ end
@@ -2,12 +2,13 @@ require 'spec_helper'
2
2
 
3
3
  describe Mementus::NodeProxy do
4
4
  specify '#new' do
5
- graph = Mementus::Graph.new
6
5
  node1 = Mementus::Node.new(1, :node)
7
6
  node2 = Mementus::Node.new(2, :node)
8
7
  node3 = Mementus::Node.new(3, :node)
9
- graph.add_edge(Mementus::Edge.new(node1, node2))
10
- graph.add_edge(Mementus::Edge.new(node1, node3))
8
+ graph = Mementus::Graph.new do
9
+ add_edge(Mementus::Edge.new(node1, node2))
10
+ add_edge(Mementus::Edge.new(node1, node3))
11
+ end
11
12
 
12
13
  node_proxy = Mementus::NodeProxy.new(node1, graph)
13
14
  expect(node_proxy.adjacent.map { |node| node.id}).to eq([node2.id, node3.id])
data/spec/query_spec.rb CHANGED
@@ -2,9 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  describe Mementus::Query do
4
4
  let(:graph) do
5
- graph = Mementus::Graph.new
6
- graph.add_edge(Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node)))
7
- graph
5
+ Mementus::Graph.new do
6
+ add_edge(Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node)))
7
+ end
8
8
  end
9
9
 
10
10
  specify '#node' do
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,2 @@
1
1
  require 'rspec'
2
2
  require 'mementus'
3
-
4
- RSpec.configure do |config|
5
- config.formatter = 'documentation'
6
- end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mementus::Structure do
4
+ let(:structure) do
5
+ Mementus::Structure.new
6
+ end
7
+
8
+ specify '#new' do
9
+ expect(structure.nodes_count).to eq(0)
10
+ expect(structure.edges_count).to eq(0)
11
+ end
12
+
13
+ specify '#add_node' do
14
+ structure.add_node(Mementus::Node.new(1, :node))
15
+
16
+ expect(structure.nodes_count).to eq(1)
17
+ expect(structure.edges_count).to eq(0)
18
+ end
19
+
20
+ specify '#create_node' do
21
+ structure.create_node do |node|
22
+ node.id = 1
23
+ node.label = :vertex
24
+ end
25
+
26
+ expect(structure.nodes_count).to eq(1)
27
+ expect(structure.edges_count).to eq(0)
28
+ end
29
+
30
+ specify '#add_edge' do
31
+ structure.add_edge(Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node)))
32
+
33
+ expect(structure.nodes_count).to eq(2)
34
+ expect(structure.edges_count).to eq(1)
35
+ end
36
+
37
+ specify '#create_edge' do
38
+ structure.create_edge do |edge|
39
+ edge.label = :relationship
40
+ edge.from = "A"
41
+ edge.to = "B"
42
+ end
43
+
44
+ expect(structure.nodes_count).to eq(2)
45
+ expect(structure.edges_count).to eq(1)
46
+ end
47
+
48
+ specify '#has_node?' do
49
+ node = Mementus::Node.new(1, :node)
50
+ structure.add_node(node)
51
+
52
+ expect(structure.has_node?(node)).to be true
53
+ expect(structure.has_node?(node.dup)).to be false
54
+ end
55
+
56
+ specify '#has_edge?' do
57
+ edge = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
58
+ edge2 = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
59
+ structure.add_edge(edge)
60
+
61
+ expect(structure.has_edge?(edge)).to be true
62
+ expect(structure.has_edge?(edge2)).to be false
63
+ end
64
+
65
+ specify '#node(id)' do
66
+ edge = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
67
+ structure.add_edge(edge)
68
+
69
+ expect(structure.node(1)).to eq(edge.from)
70
+ end
71
+
72
+ specify '#nodes(filter)' do
73
+ edge = Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(2, :node))
74
+ structure.add_edge(edge)
75
+
76
+ expect(structure.nodes).to eq([edge.from, edge.to])
77
+ end
78
+ end
@@ -6,15 +6,16 @@ describe 'Basic graph traversals' do
6
6
  end
7
7
 
8
8
  let(:graph) do
9
- graph = Mementus::Graph.new
10
- graph.add_edge(Mementus::Edge.new(start, Mementus::Node.new(2, :node)))
11
- graph.add_edge(Mementus::Edge.new(Mementus::Node.new(2, :node), Mementus::Node.new(3, :node)))
12
- graph.add_edge(Mementus::Edge.new(Mementus::Node.new(2, :node), Mementus::Node.new(5, :node)))
13
- graph.add_edge(Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(6, :node)))
14
- graph.add_edge(Mementus::Edge.new(Mementus::Node.new(2, :node), Mementus::Node.new(7, :node)))
15
- graph.add_edge(Mementus::Edge.new(Mementus::Node.new(7, :node), Mementus::Node.new(8, :node)))
16
- graph.add_edge(Mementus::Edge.new(Mementus::Node.new(5, :node), Mementus::Node.new(9, :node)))
17
- graph
9
+ start_node = start
10
+ graph = Mementus::Graph.new do
11
+ add_edge(Mementus::Edge.new(start_node, Mementus::Node.new(2, :node)))
12
+ add_edge(Mementus::Edge.new(Mementus::Node.new(2, :node), Mementus::Node.new(3, :node)))
13
+ add_edge(Mementus::Edge.new(Mementus::Node.new(2, :node), Mementus::Node.new(5, :node)))
14
+ add_edge(Mementus::Edge.new(Mementus::Node.new(1, :node), Mementus::Node.new(6, :node)))
15
+ add_edge(Mementus::Edge.new(Mementus::Node.new(2, :node), Mementus::Node.new(7, :node)))
16
+ add_edge(Mementus::Edge.new(Mementus::Node.new(7, :node), Mementus::Node.new(8, :node)))
17
+ add_edge(Mementus::Edge.new(Mementus::Node.new(5, :node), Mementus::Node.new(9, :node)))
18
+ end
18
19
  end
19
20
 
20
21
  specify 'DepthFirstSearch#each' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mementus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - maetl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-30 00:00:00.000000000 Z
11
+ date: 2016-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -69,20 +69,25 @@ files:
69
69
  - lib/mementus/breadth_first_search.rb
70
70
  - lib/mementus/depth_first_search.rb
71
71
  - lib/mementus/edge.rb
72
+ - lib/mementus/edge_builder.rb
72
73
  - lib/mementus/graph.rb
74
+ - lib/mementus/graph_builder.rb
75
+ - lib/mementus/integer_id.rb
73
76
  - lib/mementus/node.rb
77
+ - lib/mementus/node_builder.rb
74
78
  - lib/mementus/node_proxy.rb
75
79
  - lib/mementus/query/source.rb
76
80
  - lib/mementus/query/step.rb
77
81
  - lib/mementus/query/traversal.rb
78
- - lib/mementus/relation.rb
79
82
  - lib/mementus/structure.rb
80
83
  - lib/mementus/version.rb
81
84
  - mementus.gemspec
82
85
  - spec/graph_spec.rb
86
+ - spec/integer_id_spec.rb
83
87
  - spec/node_proxy_spec.rb
84
88
  - spec/query_spec.rb
85
89
  - spec/spec_helper.rb
90
+ - spec/structure_spec.rb
86
91
  - spec/traversal_spec.rb
87
92
  homepage: https://github.com/maetl/mementus
88
93
  licenses:
@@ -104,14 +109,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
109
  version: '0'
105
110
  requirements: []
106
111
  rubyforge_project:
107
- rubygems_version: 2.2.2
112
+ rubygems_version: 2.4.5
108
113
  signing_key:
109
114
  specification_version: 4
110
115
  summary: In-memory data model
111
116
  test_files:
112
117
  - spec/graph_spec.rb
118
+ - spec/integer_id_spec.rb
113
119
  - spec/node_proxy_spec.rb
114
120
  - spec/query_spec.rb
115
121
  - spec/spec_helper.rb
122
+ - spec/structure_spec.rb
116
123
  - spec/traversal_spec.rb
117
- has_rdoc:
@@ -1,68 +0,0 @@
1
- module Mementus
2
- module Relation
3
- module ClassMethods
4
-
5
- def where(constraints)
6
- Query.new(self.collection, self.cache).where(constraints)
7
- end
8
-
9
- def all
10
- Query.new(self.collection, self.cache).objects
11
- end
12
-
13
- def order(constraints)
14
- Query.new(self.collection, self.cache).order(constraints)
15
- end
16
-
17
- end
18
-
19
- # Chainable query object that delegates to the given relation.
20
- class Query
21
-
22
- def initialize(relation, cache)
23
- @relation = relation
24
- @cache = cache
25
- end
26
-
27
- # Filters the collection based on the given constraints.
28
- #
29
- # - Pass in a key-value hash to filter based on matching attributes by equality.
30
- # - Pass in a block to construct a more specialised predicate match.
31
- def where(constraints)
32
- Query.new(@relation.restrict(constraints), @cache)
33
- end
34
-
35
- # Order the collection by attribute and direction
36
- def order(constraints)
37
- ordered_relation = @relation.sort_by do |relation|
38
- constraints.keys.inject([]) do |list, constraint|
39
- direction = constraints[constraint].to_sym
40
- direction = :asc unless direction == :desc
41
- list << relation.send(constraint.to_sym).send(direction)
42
- end
43
- end
44
- Query.new(ordered_relation, @cache)
45
- end
46
-
47
- # Materializes the relation to an array of model objects.
48
- def objects
49
- @relation.inject([]) do |list, relation|
50
- list << @cache[relation[:__cache_key]]
51
- end
52
- end
53
-
54
- # Enumerate over each object.
55
- def each(&block)
56
- @relation.each do |relation|
57
- yield block
58
- end
59
- end
60
-
61
- # Number of objects.
62
- def count
63
- objects.count
64
- end
65
-
66
- end
67
- end
68
- end