acts_as_oqgraph 0.1.0 → 0.1.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.
- data/README.rdoc +36 -31
- data/VERSION +1 -1
- data/acts_as_oqgraph.gemspec +56 -0
- data/lib/graph_edge.rb +2 -1
- metadata +3 -2
data/README.rdoc
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
ActsAsOQGraph
|
2
|
-
|
1
|
+
*ActsAsOQGraph*
|
2
|
+
|
3
3
|
This gem can be used with ActiveRecord to access the features of the OQGraph
|
4
4
|
MySQL plugin.
|
5
5
|
|
@@ -11,10 +11,11 @@ pros and cons of both approaches, It really depends on your needs. Both librarie
|
|
11
11
|
use the C++ Boost graph library at the bottom layers. OQGraph has expensive
|
12
12
|
insert operations but is very fast at delivering the graph data and finding paths in a single SQL query.
|
13
13
|
|
14
|
-
Concepts
|
14
|
+
*Concepts*
|
15
|
+
|
15
16
|
The term graph we are using here is a mathematical one not a pretty picture (sorry designers).
|
16
17
|
For more see: http://en.wikipedia.org/wiki/Graph_(mathematics)
|
17
|
-
A graph consists of nodes (aka vertices) connected by edges (aka
|
18
|
+
A graph consists of nodes (aka vertices) connected by edges (aka links, paths).
|
18
19
|
In a directed graph an edge has a direction. That is, it has an 'from' node and and a 'to' node.
|
19
20
|
When tracing a path on the graph you can only go in the direction of the edge.
|
20
21
|
The OQGraph gem operates on directed graphs. To create a non directed graph you have to create two edges,
|
@@ -23,7 +24,8 @@ one each way between each node.
|
|
23
24
|
Edges can be assigned positive floating point values called weights. Weights default to 1.0
|
24
25
|
The weights are used in shortest path calculations, a path is shorter if the sum of weights over each edge is smaller.
|
25
26
|
|
26
|
-
What you can do with OQGraph
|
27
|
+
*What you can do with OQGraph?*
|
28
|
+
|
27
29
|
Imagine your shiny new social networking app, FarceBook.
|
28
30
|
You have lots and lots of users each with several friends. How do you find the friends of friends?
|
29
31
|
Or even the friends of friends of friends...right up to the six degrees of separation perhaps?
|
@@ -31,35 +33,37 @@ Or even the friends of friends of friends...right up to the six degrees of separ
|
|
31
33
|
Well you can do it, with some really slow and nasty SQL queries. Relational databases are good at set
|
32
34
|
based queries but no good at graph or tree based queries. The OQGraph engine is good at graph based queries,
|
33
35
|
it enables you in one simple SQL query to find all friends of friends.
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
Do this:
|
37
|
+
user.reachable
|
38
|
+
If you really want to you can rename the reachable method so you can do this in your User model:
|
39
|
+
alias friends, reachable
|
40
|
+
Then I can call:
|
41
|
+
user.friends
|
42
|
+
and I get the whole tree of friends of friends etc...
|
40
43
|
|
41
|
-
TODO: Perhaps I should hook into ActiveRecord associations somehow so these can be named associations instead of methods.
|
42
|
-
Not really sure of how to go about this as yet
|
43
|
-
.
|
44
44
|
Imagine you have a maze to solve. With OQGraph the solution is as simple as: start_cell.shortest_path_to(finish_cell).
|
45
45
|
|
46
46
|
It's good for representing tree structures, networks, routes between cities, roads etc.
|
47
47
|
|
48
|
-
Usage
|
48
|
+
*Usage*
|
49
|
+
|
50
|
+
In your node model file:
|
51
|
+
|
52
|
+
Class Foo < ActiveRecord::Base
|
53
|
+
acts_as_oqgraph
|
54
|
+
end
|
49
55
|
|
50
|
-
|
51
|
-
acts_as_oqgraph +options+
|
52
|
-
end
|
56
|
+
*Options*
|
53
57
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
* class_name - The name of the edge class, defaults to current class name appended with Edge. eg FooEdge
|
59
|
+
* table_name - The name of the edge table, defaults to table name of the specified class, eg foo_edges
|
60
|
+
* oqgraph_table_name - the name of the volatile oqgraph table. Default foo_edge_oqgraph
|
61
|
+
* from_key - The from key field in the edge table. Default 'from_id'
|
62
|
+
* to_key - The to key field in the edge table. Default: 'to_id'
|
63
|
+
* weight_column - The weight field in the edge table.
|
64
|
+
|
65
|
+
*Setup*
|
61
66
|
|
62
|
-
Setup:
|
63
67
|
This gem requires the use of MySQL or MariaDB with the OQGraph engine plugin.
|
64
68
|
For details of this see: http://openquery.com/products/graph-engine
|
65
69
|
|
@@ -71,7 +75,6 @@ You will need a table for the edges with the following schema:
|
|
71
75
|
end
|
72
76
|
The field names and table name can be changed via the options listed above.
|
73
77
|
You should be able also to extend the edge model as you wish.
|
74
|
-
|
75
78
|
The gem will automatically create the oqgraph table and the associations to it from your node model.
|
76
79
|
The associations are:
|
77
80
|
node_model.outgoing_edges
|
@@ -80,14 +83,15 @@ The associations are:
|
|
80
83
|
node_model.incoming_nodes
|
81
84
|
edge_model.to
|
82
85
|
edge_model.from
|
83
|
-
|
84
|
-
|
86
|
+
|
87
|
+
|
88
|
+
*Examples of use*
|
85
89
|
|
86
90
|
Creating edges:
|
87
91
|
foo.create_edge_to(bar)
|
88
92
|
foo.create_edge_to_and_from(bar)
|
89
93
|
|
90
|
-
|
94
|
+
Edge creation using ActiveRecord associations:
|
91
95
|
foo.outgoing_nodes << bar
|
92
96
|
or equivalently:
|
93
97
|
bar.incoming_nodes << foo
|
@@ -122,7 +126,8 @@ Path Finding:
|
|
122
126
|
All these methods return the node object with an additional weight field.
|
123
127
|
This enables you to query the weights associated with the edges found.
|
124
128
|
|
125
|
-
Behind the Scenes
|
129
|
+
*Behind the Scenes*
|
130
|
+
|
126
131
|
When you declare acts_as_oqgraph then the edge class gets created. You can add extra functionality
|
127
132
|
if you wish to the edge class by the usual Ruby monkey patching methods.
|
128
133
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
@@ -0,0 +1,56 @@
|
|
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
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{acts_as_oqgraph}
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Stuart Coyle"]
|
12
|
+
s.date = %q{2010-07-21}
|
13
|
+
s.description = %q{Acts As OQGraph allows ActiveRecord models to use the fast ans powerful OQGraph engine for MYSQL.}
|
14
|
+
s.email = %q{stuart.coyle@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"acts_as_oqgraph.gemspec",
|
27
|
+
"lib/acts_as_oqgraph.rb",
|
28
|
+
"lib/graph_edge.rb",
|
29
|
+
"test/helper.rb",
|
30
|
+
"test/models/custom_test_model.rb",
|
31
|
+
"test/models/test_model.rb",
|
32
|
+
"test/test_acts_as_oqgraph.rb"
|
33
|
+
]
|
34
|
+
s.homepage = %q{http://github.com/stuart/acts_as_oqgraph}
|
35
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
36
|
+
s.require_paths = ["lib"]
|
37
|
+
s.rubygems_version = %q{1.3.6}
|
38
|
+
s.summary = %q{Use the Open Query Graph engine with Active Record}
|
39
|
+
s.test_files = [
|
40
|
+
"test/helper.rb",
|
41
|
+
"test/models/custom_test_model.rb",
|
42
|
+
"test/models/test_model.rb",
|
43
|
+
"test/test_acts_as_oqgraph.rb"
|
44
|
+
]
|
45
|
+
|
46
|
+
if s.respond_to? :specification_version then
|
47
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
48
|
+
s.specification_version = 3
|
49
|
+
|
50
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
51
|
+
else
|
52
|
+
end
|
53
|
+
else
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
data/lib/graph_edge.rb
CHANGED
@@ -85,7 +85,6 @@ class GraphEdge < ActiveRecord::Base
|
|
85
85
|
node_class.find_by_sql select_for_node << sql
|
86
86
|
end
|
87
87
|
|
88
|
-
private
|
89
88
|
def add_to_graph
|
90
89
|
connection.execute <<-EOS
|
91
90
|
INSERT INTO #{oqgraph_table_name} (origid, destid, weight)
|
@@ -93,6 +92,8 @@ class GraphEdge < ActiveRecord::Base
|
|
93
92
|
EOS
|
94
93
|
end
|
95
94
|
|
95
|
+
private
|
96
|
+
|
96
97
|
def remove_from_graph
|
97
98
|
connection.execute <<-EOS
|
98
99
|
DELETE FROM #{oqgraph_table_name} WHERE origid = #{self.send(self.class.from_key)} AND destid = #{self.send(self.class.to_key)};
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Stuart Coyle
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- README.rdoc
|
35
35
|
- Rakefile
|
36
36
|
- VERSION
|
37
|
+
- acts_as_oqgraph.gemspec
|
37
38
|
- lib/acts_as_oqgraph.rb
|
38
39
|
- lib/graph_edge.rb
|
39
40
|
- test/helper.rb
|