agraph 0.1.0.beta1 → 0.1.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -14,6 +14,12 @@ The features that are exposed by this client are...
14
14
  * performing SparQL and Prolog queries
15
15
  * mapping of data type
16
16
 
17
+ == Installation
18
+
19
+ There are no special dependencies. Just type
20
+
21
+ gem install agraph
22
+
17
23
  == Repository management
18
24
 
19
25
  A repository can be created by simply typing the following.
@@ -62,7 +68,7 @@ The result will be an array that holds arrays of all matching statements.
62
68
  Before coordinates can be added, a fitting type has to be requested from the database. Coordinates can have the
63
69
  cartesian (x and y) or spherical (latitude and longitude) type. When creating the type, also a range has to be defined.
64
70
 
65
- cartesian_type = repository.geo.cartesian_type 1, 0, 0, 100, 100
71
+ cartesian_type = repository.geometric.cartesian_type 1, 0, 0, 100, 100
66
72
 
67
73
  The first argument specifies the strip width and the last four the top-left and bottom-right corner of the rectangle
68
74
  that represent the boundaries for any coordinate.
@@ -75,14 +81,19 @@ Afterwards, the return type can be used add geometric nodes (subjects or objects
75
81
 
76
82
  To find statements by thier assigned coordinates, the following methods are provided.
77
83
 
78
- repository.geo.inside_box
79
- repository.geo.inside_circle
80
- repository.geo.inside_haversine
81
- repository.geo.inside_polygon
84
+ repository.statements.find_inside_box
85
+ repository.statements.find_inside_circle
86
+ repository.statements.find_inside_haversine
87
+ repository.statements.find_inside_polygon
82
88
 
83
89
  The previously create statement will be returned by
84
90
 
85
- repository.geo.inside_box cartesian_type, "<a_predicate>", 10, 10, 30, 30
91
+ repository.geometric.find_inside_box :type => cartesian_type,
92
+ :predicate => "<a_predicate>",
93
+ :x_min => 10,
94
+ :y_min => 10,
95
+ :x_max => 30,
96
+ :y_max => 30
86
97
 
87
98
  == Transactions
88
99
 
data/Rakefile CHANGED
@@ -9,12 +9,13 @@ task :default => :spec
9
9
 
10
10
  specification = Gem::Specification.new do |specification|
11
11
  specification.name = "agraph"
12
- specification.version = "0.1.0.beta1"
13
- specification.date = "2010-03-29"
12
+ specification.version = "0.1.0.beta2"
13
+ specification.date = "2010-03-30"
14
14
  specification.email = "b.phifty@gmail.com"
15
15
  specification.homepage = "http://github.com/phifty/agraph"
16
16
  specification.summary = "Client for the AllegroGraph 4.x graph database."
17
17
  specification.description = "The gem provides a client for the AllegroGraph 4.x RDF graph database. Features like searching geo-spatial data, type mapping and transactions are supported."
18
+ specification.rubyforge_project = "agraph"
18
19
  specification.has_rdoc = true
19
20
  specification.authors = [ "Philipp Bruell" ]
20
21
  specification.files = [ "README.rdoc", "Rakefile" ] + Dir["{lib,spec}/**/*"]
data/lib/agraph.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), "allegro_graph")
data/lib/allegro_graph.rb CHANGED
@@ -1,5 +1,5 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), "allegro_graph", "server"))
2
- require File.expand_path(File.join(File.dirname(__FILE__), "allegro_graph", "catalog"))
3
- require File.expand_path(File.join(File.dirname(__FILE__), "allegro_graph", "repository"))
4
- require File.expand_path(File.join(File.dirname(__FILE__), "allegro_graph", "session"))
5
- require File.expand_path(File.join(File.dirname(__FILE__), "allegro_graph", "federation"))
1
+ require File.join(File.dirname(__FILE__), "allegro_graph", "server")
2
+ require File.join(File.dirname(__FILE__), "allegro_graph", "catalog")
3
+ require File.join(File.dirname(__FILE__), "allegro_graph", "repository")
4
+ require File.join(File.dirname(__FILE__), "allegro_graph", "session")
5
+ require File.join(File.dirname(__FILE__), "allegro_graph", "federation")
@@ -2,6 +2,8 @@ require File.join(File.dirname(__FILE__), "repository")
2
2
 
3
3
  module AllegroGraph
4
4
 
5
+ # The Catalog class wrap the corresponding resource on the AllegroGraph server. A catalog can hold
6
+ # many repositories.
5
7
  class Catalog
6
8
 
7
9
  attr_reader :server
@@ -1,11 +1,13 @@
1
1
  require File.join(File.dirname(__FILE__), "transport")
2
2
  require File.join(File.dirname(__FILE__), "proxy", "statements")
3
3
  require File.join(File.dirname(__FILE__), "proxy", "query")
4
- require File.join(File.dirname(__FILE__), "proxy", "geo")
4
+ require File.join(File.dirname(__FILE__), "proxy", "geometric")
5
5
  require File.join(File.dirname(__FILE__), "proxy", "mapping")
6
6
 
7
7
  module AllegroGraph
8
8
 
9
+ # The Federation class wrap the corresponding resource on the AllegroGraph server. A federation is a collection
10
+ # of many repositories that acts like a single one. Only read access is allowed.
9
11
  class Federation
10
12
 
11
13
  attr_reader :server
@@ -15,7 +17,7 @@ module AllegroGraph
15
17
 
16
18
  attr_reader :statements
17
19
  attr_reader :query
18
- attr_reader :geo
20
+ attr_reader :geometric
19
21
  attr_reader :mapping
20
22
 
21
23
  def initialize(server, name, options = { })
@@ -26,7 +28,7 @@ module AllegroGraph
26
28
 
27
29
  @statements = Proxy::Statements.new self
28
30
  @query = Proxy::Query.new self
29
- @geo = Proxy::Geo.new self
31
+ @geometric = Proxy::Geometric.new self
30
32
  @mapping = Proxy::Mapping.new self
31
33
  end
32
34
 
@@ -0,0 +1,51 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "utility", "parameter_mapper"))
2
+
3
+ module AllegroGraph
4
+
5
+ module Proxy
6
+
7
+ # The Geometric class acts as proxy to the geo-functions of the AllegroGraph server.
8
+ class Geometric
9
+
10
+ attr_reader :resource
11
+
12
+ def initialize(resource)
13
+ @resource = resource
14
+ end
15
+
16
+ def path
17
+ "#{@resource.path}/geo"
18
+ end
19
+
20
+ def cartesian_type(parameters = { })
21
+ parameters = Utility::ParameterMapper.map parameters, :cartesian_type
22
+ type = @resource.request :post, self.path + "/types/cartesian", :parameters => parameters, :expected_status_code => 200
23
+ type.sub! /^.*</, "<"
24
+ type.sub! />.*$/, ">"
25
+ type
26
+ end
27
+
28
+ def spherical_type(parameters = { })
29
+ parameters = Utility::ParameterMapper.map parameters, :spherical_type
30
+ type = @resource.request :post, self.path + "/types/spherical", :parameters => parameters, :expected_status_code => 200
31
+ type.sub! /^.*</, "<"
32
+ type.sub! />.*$/, ">"
33
+ type
34
+ end
35
+
36
+ def create_polygon(points, parameters = { })
37
+ type = parameters.delete :type
38
+ parameters = Utility::ParameterMapper.map parameters, :create_polygon
39
+
40
+ raise ArgumentError, "at least three points has to defined" unless points.is_a?(Array) && points.size >= 3
41
+ parameters[:point] = points.map{ |point| "\"%+g%+g\"^^%s" % [ point[0], point[1], type ] }
42
+
43
+ @resource.request :put, self.path + "/polygon", :parameters => parameters, :expected_status_code => 204
44
+ true
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -3,6 +3,7 @@ module AllegroGraph
3
3
 
4
4
  module Proxy
5
5
 
6
+ # The Mapping class acts as proxy to the data type mapping functions of the AllegroGraph server.
6
7
  class Mapping
7
8
 
8
9
  attr_reader :resource
@@ -3,6 +3,7 @@ module AllegroGraph
3
3
 
4
4
  module Proxy
5
5
 
6
+ # The Query class acts as proxy that bypasses SparQL and Prolog queries to the AllegroGraph server.
6
7
  class Query
7
8
 
8
9
  LANGUAGES = [ :sparql, :prolog ].freeze unless defined?(LANGUAGES)
@@ -21,8 +22,9 @@ module AllegroGraph
21
22
  end
22
23
 
23
24
  def language=(value)
24
- raise NotImplementedError, "query langauge [#{value}] is not implemented" unless LANGUAGES.include?(value.to_sym)
25
- @language = value.to_sym
25
+ value = value.to_sym
26
+ raise NotImplementedError, "query langauge [#{value}] is not implemented" unless LANGUAGES.include?(value)
27
+ @language = value
26
28
  end
27
29
 
28
30
  def perform(query)
@@ -1,8 +1,11 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "utility", "parameter_mapper"))
1
2
 
2
3
  module AllegroGraph
3
4
 
4
5
  module Proxy
5
6
 
7
+ # The Statement class acts as proxy to functions that add, remove or find statements
8
+ # in the AllegroGraph data store.
6
9
  class Statements
7
10
 
8
11
  attr_reader :resource
@@ -12,16 +15,27 @@ module AllegroGraph
12
15
  end
13
16
 
14
17
  def path
15
- "#{@resource.path}/statements"
18
+ @resource.path
16
19
  end
17
20
 
18
21
  def create(subject, predicate, object, context = nil)
19
22
  statement = [ subject, predicate, object ]
20
23
  statement << context if context
21
- @resource.request :post, self.path, :body => [ statement ], :expected_status_code => 204
24
+ @resource.request :post, self.path + "/statements", :body => [ statement ], :expected_status_code => 204
22
25
  true
23
26
  end
24
27
 
28
+ def delete(options = { })
29
+ parameters = { }
30
+
31
+ { :subject => :subj, :predicate => :pred, :object => :obj, :context => :context }.each do |option_key, parameter_key|
32
+ value = options[option_key]
33
+ parameters.merge! parameter_key => value if value
34
+ end
35
+
36
+ @resource.request :delete, self.path + "/statements", :parameters => parameters, :expected_status_code => 200
37
+ end
38
+
25
39
  def find(options = { })
26
40
  parameters = { }
27
41
 
@@ -38,18 +52,27 @@ module AllegroGraph
38
52
 
39
53
  parameters = nil if parameters.empty?
40
54
 
41
- @resource.request :get, self.path, :parameters => parameters, :expected_status_code => 200
55
+ @resource.request :get, self.path + "/statements", :parameters => parameters, :expected_status_code => 200
42
56
  end
43
57
 
44
- def delete(options = { })
45
- parameters = { }
58
+ def find_inside_box(parameters = { })
59
+ parameters = Utility::ParameterMapper.map parameters, :find_inside_box
60
+ @resource.request :get, self.path + "/geo/box", :parameters => parameters, :expected_status_code => 200
61
+ end
46
62
 
47
- { :subject => :subj, :predicate => :pred, :object => :obj, :context => :context }.each do |option_key, parameter_key|
48
- value = options[option_key]
49
- parameters.merge! parameter_key => value if value
50
- end
63
+ def find_inside_circle(parameters = { })
64
+ parameters = Utility::ParameterMapper.map parameters, :find_inside_circle
65
+ @resource.request :get, self.path + "/geo/circle", :parameters => parameters, :expected_status_code => 200
66
+ end
67
+
68
+ def find_inside_haversine(parameters = { })
69
+ parameters = Utility::ParameterMapper.map parameters, :find_inside_haversine
70
+ @resource.request :get, self.path + "/geo/haversine", :parameters => parameters, :expected_status_code => 200
71
+ end
51
72
 
52
- @resource.request :delete, self.path, :parameters => parameters, :expected_status_code => 200
73
+ def find_inside_polygon(parameters = { })
74
+ parameters = Utility::ParameterMapper.map parameters, :find_inside_polygon
75
+ @resource.request :get, self.path + "/geo/polygon", :parameters => parameters, :expected_status_code => 200
53
76
  end
54
77
 
55
78
  end
@@ -2,11 +2,13 @@ require File.join(File.dirname(__FILE__), "server")
2
2
  require File.join(File.dirname(__FILE__), "session")
3
3
  require File.join(File.dirname(__FILE__), "proxy", "statements")
4
4
  require File.join(File.dirname(__FILE__), "proxy", "query")
5
- require File.join(File.dirname(__FILE__), "proxy", "geo")
5
+ require File.join(File.dirname(__FILE__), "proxy", "geometric")
6
6
  require File.join(File.dirname(__FILE__), "proxy", "mapping")
7
7
 
8
8
  module AllegroGraph
9
9
 
10
+ # The Repository class wrap the corresponding resource on the AllegroGraph server. A repository acts as a scope for
11
+ # statements. Simple management methods are provided.
10
12
  class Repository
11
13
 
12
14
  attr_reader :server
@@ -15,7 +17,7 @@ module AllegroGraph
15
17
 
16
18
  attr_reader :statements
17
19
  attr_reader :query
18
- attr_reader :geo
20
+ attr_reader :geometric
19
21
  attr_reader :mapping
20
22
 
21
23
  def initialize(server_or_catalog, name, options = { })
@@ -24,7 +26,7 @@ module AllegroGraph
24
26
  @name = name
25
27
  @statements = Proxy::Statements.new self
26
28
  @query = Proxy::Query.new self
27
- @geo = Proxy::Geo.new self
29
+ @geometric = Proxy::Geometric.new self
28
30
  @mapping = Proxy::Mapping.new self
29
31
  end
30
32
 
@@ -74,14 +76,18 @@ module AllegroGraph
74
76
  end
75
77
 
76
78
  def transaction(&block)
77
- session = Session.create self
79
+ self.class.transaction self, &block
80
+ end
81
+
82
+ def self.transaction(repository, &block)
83
+ session = Session.create repository
78
84
  begin
79
85
  session.instance_eval &block
80
86
  rescue Object => error
81
87
  session.rollback
82
88
  raise error
83
89
  end
84
- session.commit
90
+ session.commit
85
91
  end
86
92
 
87
93
  end
@@ -1,11 +1,12 @@
1
1
  require File.join(File.dirname(__FILE__), "transport")
2
2
  require File.join(File.dirname(__FILE__), "proxy", "statements")
3
3
  require File.join(File.dirname(__FILE__), "proxy", "query")
4
- require File.join(File.dirname(__FILE__), "proxy", "geo")
4
+ require File.join(File.dirname(__FILE__), "proxy", "geometric")
5
5
  require File.join(File.dirname(__FILE__), "proxy", "mapping")
6
6
 
7
7
  module AllegroGraph
8
8
 
9
+ # The Session class wrap the corresponding resource on the AllegroGraph server.
9
10
  class Session
10
11
 
11
12
  attr_reader :url
@@ -14,7 +15,7 @@ module AllegroGraph
14
15
 
15
16
  attr_reader :statements
16
17
  attr_reader :query
17
- attr_reader :geo
18
+ attr_reader :geometric
18
19
  attr_reader :mapping
19
20
 
20
21
  def initialize(options = { })
@@ -24,7 +25,7 @@ module AllegroGraph
24
25
 
25
26
  @statements = Proxy::Statements.new self
26
27
  @query = Proxy::Query.new self
27
- @geo = Proxy::Geo.new self
28
+ @geometric = Proxy::Geometric.new self
28
29
  @mapping = Proxy::Mapping.new self
29
30
  end
30
31
 
@@ -50,7 +51,8 @@ module AllegroGraph
50
51
  url = repository.request :post, repository.path + "/session", :expected_status_code => 200
51
52
  url.sub! /^"/, ""
52
53
  url.sub! /"$/, ""
53
- new :url => url, :username => repository.server.username, :password => repository.server.password
54
+ server = repository.server
55
+ new :url => url, :username => server.username, :password => server.password
54
56
  end
55
57
 
56
58
  private
@@ -36,7 +36,7 @@ module AllegroGraph
36
36
  private
37
37
 
38
38
  def initialize_request_class
39
- request_class_name = @http_method.capitalize
39
+ request_class_name = @http_method.to_s.capitalize
40
40
  raise NotImplementedError, "the request method #{http_method} is not implemented" unless Net::HTTP.const_defined?(request_class_name)
41
41
  @request_class = Net::HTTP.const_get request_class_name
42
42
  end
@@ -62,11 +62,8 @@ module AllegroGraph
62
62
  def quote_parameters
63
63
  @quoted_parameters = { }
64
64
  @parameters.each do |key, value|
65
- if value.is_a?(Array)
66
- @quoted_parameters[ CGI.escape("#{key}") ] = value.map{ |element| CGI.escape element }
67
- else
68
- @quoted_parameters[ CGI.escape("#{key}") ] = CGI.escape value
69
- end
65
+ quoted_key = CGI.escape(key.to_s)
66
+ @quoted_parameters[quoted_key] = value.is_a?(Array) ? value.map{ |element| CGI.escape element } : CGI.escape(value)
70
67
  end
71
68
  end
72
69
 
@@ -93,6 +90,7 @@ module AllegroGraph
93
90
 
94
91
  end
95
92
 
93
+ # Extended transport layer for http transfers. Basic authorization and JSON transfers are supported.
96
94
  class ExtendedTransport < Transport
97
95
 
98
96
  # The UnexpectedStatusCodeError is raised if the :expected_status_code option is given to
@@ -159,9 +157,10 @@ module AllegroGraph
159
157
  end
160
158
 
161
159
  def parse_response
162
- @response = @response.body.nil? ? nil : JSON.parse(@response.body)
160
+ body = @response.body
161
+ @response = body.nil? ? nil : JSON.parse(body)
163
162
  rescue JSON::ParserError
164
- @response = @response.body.to_s
163
+ @response = body.to_s
165
164
  end
166
165
 
167
166
  end
@@ -0,0 +1,77 @@
1
+
2
+ module AllegroGraph
3
+
4
+ module Utility
5
+
6
+ module ParameterMapper
7
+
8
+ MAP = {
9
+ :strip_width => { :to => :stripWidth, :for => [ :cartesian_type, :spherical_type ], :default => 1 },
10
+ :x_min => { :to => :xmin, :for => [ :cartesian_type, :find_inside_box ] },
11
+ :y_min => { :to => :ymin, :for => [ :cartesian_type, :find_inside_box ] },
12
+ :x_max => { :to => :xmax, :for => [ :cartesian_type, :find_inside_box ] },
13
+ :y_max => { :to => :ymax, :for => [ :cartesian_type, :find_inside_box ] },
14
+ :unit => { :to => :unit, :for => [ :spherical_type, :find_inside_haversine ], :default => :degree },
15
+ :latitude_min => { :to => :latmin, :for => [ :spherical_type ] },
16
+ :longitude_min => { :to => :longmin, :for => [ :spherical_type ] },
17
+ :latitude_max => { :to => :latmax, :for => [ :spherical_type ] },
18
+ :longitude_max => { :to => :longmax, :for => [ :spherical_type ] },
19
+ :name => { :to => :resource, :for => [ :create_polygon ], :modifier => [ :quote ] },
20
+ :type => { :to => :type, :for => [ :find_inside_box, :find_inside_circle, :find_inside_haversine, :find_inside_polygon ] },
21
+ :predicate => { :to => :predicate, :for => [ :find_inside_box, :find_inside_circle, :find_inside_haversine, :find_inside_polygon ] },
22
+ :x => { :to => :x, :for => [ :find_inside_circle ] },
23
+ :y => { :to => :y, :for => [ :find_inside_circle ] },
24
+ :radius => { :to => :radius, :for => [ :find_inside_circle, :find_inside_haversine ] },
25
+ :latitude => { :to => :lat, :for => [ :find_inside_haversine ], :modifier => :latitude_to_iso },
26
+ :longitude => { :to => :long, :for => [ :find_inside_haversine ], :modifier => :longitude_to_iso },
27
+ :polygon_name => { :to => :polygon, :for => [ :find_inside_polygon ], :modifier => [ :quote ] }
28
+ }.freeze unless defined?(MAP)
29
+
30
+ def self.map(parameters, method_name)
31
+ result = { }
32
+ MAP.each do |key, mapping|
33
+ value = parameters[key] || mapping[:default]
34
+ required = [ mapping[:for] ].flatten.include? method_name.to_sym
35
+ if required
36
+ if value
37
+ [ mapping[:modifier] ].flatten.compact.each do |modifier|
38
+ value = send modifier, value
39
+ end
40
+ result[ mapping[:to] ] = value.to_s
41
+ else
42
+ raise ArgumentError, "missing parameter :#{key}!"
43
+ end
44
+ end
45
+ end
46
+ result
47
+ end
48
+
49
+ def self.quote(value)
50
+ "\"#{value}\""
51
+ end
52
+
53
+ def self.latitude_to_iso(value)
54
+ float_to_iso value, 2
55
+ end
56
+
57
+ def self.longitude_to_iso(value)
58
+ float_to_iso value, 3
59
+ end
60
+
61
+ private
62
+
63
+ def self.float_to_iso(value, digits)
64
+ sign = "+"
65
+ if value < 0
66
+ sign = "-"
67
+ value = -value
68
+ end
69
+ floor = value.to_i
70
+ sign + (("%%0%dd" % digits) % floor) + (".%07d" % ((value - floor) * 10000000))
71
+ end
72
+
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -166,22 +166,31 @@ describe "integration" do
166
166
 
167
167
  end
168
168
 
169
- describe "geo" do
169
+ describe "geo-spatial data" do
170
170
 
171
171
  before :each do
172
172
  @repository.create_if_missing!
173
- @geo = @repository.geo
173
+ @geometric = @repository.geometric
174
+ @statements = @repository.statements
174
175
  end
175
176
 
176
177
  describe "types" do
177
178
 
178
179
  it "should provide a cartesian type" do
179
- result = @geo.cartesian_type 1.0, 2.0, 2.0, 20.0, 20.0
180
+ result = @geometric.cartesian_type :strip_width => 1.0,
181
+ :x_min => 2.0,
182
+ :y_min => 2.0,
183
+ :x_max => 20.0,
184
+ :y_max => 20.0
180
185
  result.should == "<http://franz.com/ns/allegrograph/3.0/geospatial/cartesian/2.0/20.0/2.0/20.0/1.0>"
181
186
  end
182
187
 
183
188
  it "should provide a spherical type" do
184
- result = @geo.spherical_type 1.0, :degree, 2.0, 2.0, 20.0, 20.0
189
+ result = @geometric.spherical_type :strip_width => 1.0,
190
+ :latitude_min => 2.0,
191
+ :longitude_min => 2.0,
192
+ :latitude_max => 20.0,
193
+ :longitude_max => 20.0
185
194
  result.should == "<http://franz.com/ns/allegrograph/3.0/geospatial/spherical/degrees/2.0/20.0/2.0/20.0/1.0>"
186
195
  end
187
196
 
@@ -190,12 +199,16 @@ describe "integration" do
190
199
  describe "creating polygon" do
191
200
 
192
201
  before :each do
193
- @type = @geo.cartesian_type 1.0, 2.0, 2.0, 20.0, 20.0
202
+ @type = @geometric.cartesian_type :strip_width => 1.0,
203
+ :x_min => 2.0,
204
+ :y_min => 2.0,
205
+ :x_max => 20.0,
206
+ :y_max => 20.0
194
207
  @polygon = [ [ 2.0, 2.0 ], [ 11.0, 2.0 ], [ 11.0, 11.0 ], [ 2.0, 11.0 ] ]
195
208
  end
196
209
 
197
210
  it "should return true" do
198
- result = @geo.create_polygon "test_polygon", @type, @polygon
211
+ result = @geometric.create_polygon @polygon, :name => "test_polygon", :type => @type
199
212
  result.should be_true
200
213
  end
201
214
 
@@ -204,19 +217,32 @@ describe "integration" do
204
217
  context "in a cartesian system" do
205
218
 
206
219
  before :each do
207
- @type = @geo.cartesian_type 1.0, 2.0, 2.0, 20.0, 20.0
208
- @repository.statements.create "\"test_subject\"", "\"at\"", "\"+10+10\"^^#{@type}"
209
- @repository.statements.create "\"another_subject\"", "\"at\"", "\"+15+15\"^^#{@type}"
220
+ @type = @geometric.cartesian_type :strip_width => 1.0,
221
+ :x_min => 2.0,
222
+ :y_min => 2.0,
223
+ :x_max => 20.0,
224
+ :y_max => 20.0
225
+ @statements.create "\"test_subject\"", "\"at\"", "\"+10+10\"^^#{@type}"
226
+ @statements.create "\"another_subject\"", "\"at\"", "\"+15+15\"^^#{@type}"
210
227
  end
211
228
 
212
229
  it "should find objects inside a box" do
213
- result = @geo.inside_box @type, "\"at\"", 8.0, 8.0, 11.0, 11.0
230
+ result = @statements.find_inside_box :type => @type,
231
+ :predicate => "\"at\"",
232
+ :x_min => 8.0,
233
+ :y_min => 8.0,
234
+ :x_max => 11.0,
235
+ :y_max => 11.0
214
236
  result.should include([ "\"test_subject\"", "\"at\"", "\"+10.000000000931323+10.000000000931323\"^^#{@type}"])
215
237
  result.should_not include([ "\"another_subject\"", "\"at\"", "\"+15.000000000465661+15.000000000465661\"^^#{@type}"])
216
238
  end
217
239
 
218
240
  it "should find objects inside a circle" do
219
- result = @geo.inside_circle @type, "\"at\"", 9.0, 9.0, 2.0
241
+ result = @statements.find_inside_circle :type => @type,
242
+ :predicate => "\"at\"",
243
+ :x => 9.0,
244
+ :y => 9.0,
245
+ :radius => 2.0
220
246
  result.should include([ "\"test_subject\"", "\"at\"", "\"+10.000000000931323+10.000000000931323\"^^#{@type}"])
221
247
  result.should_not include([ "\"another_subject\"", "\"at\"", "\"+15.000000000465661+15.000000000465661\"^^#{@type}"])
222
248
  end
@@ -224,14 +250,22 @@ describe "integration" do
224
250
  context "with a defined polygon" do
225
251
 
226
252
  before :each do
227
- @type = @geo.cartesian_type 1, -100, -100, 100, 100
228
- @repository.statements.create "\"test_subject\"", "\"at\"", "\"+1+1\"^^#{@type}"
229
- @geo.create_polygon "test_polygon", @type, [ [ 0, -100 ], [ 0, 100 ], [ 100, 100 ], [ 100, -100 ] ]
253
+ @type = @geometric.cartesian_type :strip_width => 1,
254
+ :x_min => -100,
255
+ :y_min => -100,
256
+ :x_max => 100,
257
+ :y_max => 100
258
+ @statements.create "\"test_subject\"", "\"at\"", "\"+1+1\"^^#{@type}"
259
+ @geometric.create_polygon [ [ 0, -100 ], [ 0, 100 ], [ 100, 100 ], [ 100, -100 ] ],
260
+ :name => "test_polygon",
261
+ :type => @type
230
262
  end
231
263
 
232
264
  it "should find objects inside that polygon" do
233
265
  pending
234
- result = @geo.inside_polygon @type, "\"at\"", "test_polygon"
266
+ result = @statements.find_inside_polygon :type => @type,
267
+ :predicate => "\"at\"",
268
+ :polygon_name => "test_polygon"
235
269
  result.should include([ "\"test_subject\"", "\"at\"", "\"+1+1\"^^<http://franz.com/ns/allegrograph/3.0/geospatial/cartesian/2.0/20.0/2.0/20.0/1.0>"])
236
270
  end
237
271
 
@@ -242,12 +276,21 @@ describe "integration" do
242
276
  context "in a spherical system" do
243
277
 
244
278
  before :each do
245
- @type = @geo.spherical_type 1.0, :degree, 2.0, 2.0, 20.0, 20.0
246
- @repository.statements.create "\"test_subject\"", "\"at\"", "\"+10.00+010.00\"^^#{@type}"
279
+ @type = @geometric.spherical_type :strip_width => 1.0,
280
+ :latitude_min => 2.0,
281
+ :longitude_min => 2.0,
282
+ :latitude_max => 20.0,
283
+ :longitude_max => 20.0
284
+ @statements.create "\"test_subject\"", "\"at\"", "\"+10.00+010.00\"^^#{@type}"
247
285
  end
248
286
 
249
287
  it "should find objects inside a haversine" do
250
- result = @geo.inside_haversine @type, "\"at\"", 9.0, 9.0, 200.0, :km
288
+ result = @statements.find_inside_haversine :type => @type,
289
+ :predicate => "\"at\"",
290
+ :latitude => 9.0,
291
+ :longitude => 9.0,
292
+ :radius => 200.0,
293
+ :unit => :km
251
294
  result.should include([ "\"test_subject\"", "\"at\"", "\"+100000+0100000\"^^<http://franz.com/ns/allegrograph/3.0/geospatial/spherical/degrees/2.0/20.0/2.0/20.0/1.0>"])
252
295
  end
253
296
 
@@ -0,0 +1,65 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "lib", "allegro_graph", "proxy", "geometric"))
3
+
4
+ describe AllegroGraph::Proxy::Geometric do
5
+
6
+ before :each do
7
+ @server = AllegroGraph::Server.new :username => "test", :password => "test"
8
+ @catalog = AllegroGraph::Catalog.new @server, "test_catalog"
9
+ @repository = AllegroGraph::Repository.new @catalog, "test_repository"
10
+ @geometric = AllegroGraph::Proxy::Geometric.new @repository
11
+ @type = @geometric.cartesian_type :strip_width => 1.0,
12
+ :x_min => 2.0,
13
+ :y_min => 2.0,
14
+ :x_max => 20.0,
15
+ :y_max => 20.0
16
+ end
17
+
18
+ describe "path" do
19
+
20
+ it "should return the correct path" do
21
+ @geometric.path.should == "#{@repository.path}/geo"
22
+ end
23
+
24
+ end
25
+
26
+ describe "cartesian_type" do
27
+
28
+ it "should provide a cartesian type" do
29
+ result = @geometric.cartesian_type :strip_width => 1.0,
30
+ :x_min => 2.0,
31
+ :y_min => 2.0,
32
+ :x_max => 20.0,
33
+ :y_max => 20.0
34
+ result.should == "<http://franz.com/ns/allegrograph/3.0/geospatial/cartesian/2.0/20.0/2.0/20.0/1.0>"
35
+ end
36
+
37
+ end
38
+
39
+ describe "spherical_type" do
40
+
41
+ it "should provide a spherical type" do
42
+ result = @geometric.spherical_type :strip_width => 1.0,
43
+ :latitude_min => 2.0,
44
+ :longitude_min => 2.0,
45
+ :latitude_max => 20.0,
46
+ :longitude_max => 20.0
47
+ result.should == "<http://franz.com/ns/allegrograph/3.0/geospatial/spherical/degrees/2.0/20.0/2.0/20.0/1.0>"
48
+ end
49
+
50
+ end
51
+
52
+ describe "create_polygon" do
53
+
54
+ before :each do
55
+ @polygon = [ [ 2.0, 2.0 ], [ 10.0, 2.0 ], [ 10.0, 10.0 ], [ 2.0, 10.0 ] ]
56
+ end
57
+
58
+ it "should create a polygon" do
59
+ result = @geometric.create_polygon @polygon, :name => "test_polygon", :type => @type
60
+ result.should be_true
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -1,7 +1,7 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
2
2
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "lib", "allegro_graph", "proxy", "mapping"))
3
3
 
4
- describe AllegroGraph::Proxy::Geo do
4
+ describe AllegroGraph::Proxy::Geometric do
5
5
 
6
6
  before :each do
7
7
  @server = AllegroGraph::Server.new :username => "test", :password => "test"
@@ -8,12 +8,17 @@ describe AllegroGraph::Proxy::Statements do
8
8
  @catalog = AllegroGraph::Catalog.new @server, "test_catalog"
9
9
  @repository = AllegroGraph::Repository.new @catalog, "test_repository"
10
10
  @statements = AllegroGraph::Proxy::Statements.new @repository
11
+ @type = @repository.geometric.cartesian_type :strip_width => 1.0,
12
+ :x_min => 2.0,
13
+ :y_min => 2.0,
14
+ :x_max => 20.0,
15
+ :y_max => 20.0
11
16
  end
12
17
 
13
18
  describe "path" do
14
19
 
15
20
  it "should return the correct path" do
16
- @statements.path.should == "#{@repository.path}/statements"
21
+ @statements.path.should == @repository.path
17
22
  end
18
23
 
19
24
  end
@@ -27,6 +32,15 @@ describe AllegroGraph::Proxy::Statements do
27
32
 
28
33
  end
29
34
 
35
+ describe "delete" do
36
+
37
+ it "should delete all statements" do
38
+ result = @statements.delete :subject => "test_subject"
39
+ result.should be_true
40
+ end
41
+
42
+ end
43
+
30
44
  describe "find" do
31
45
 
32
46
  it "should find all statements" do
@@ -46,11 +60,54 @@ describe AllegroGraph::Proxy::Statements do
46
60
 
47
61
  end
48
62
 
49
- describe "delete" do
63
+ describe "find_inside_box" do
50
64
 
51
- it "should delete all statements" do
52
- result = @statements.delete :subject => "test_subject"
53
- result.should be_true
65
+ it "should find objects inside a box" do
66
+ result = @statements.find_inside_box :type => @type,
67
+ :predicate => "\"at\"",
68
+ :x_min => 8.0,
69
+ :y_min => 8.0,
70
+ :x_max => 11.0,
71
+ :y_max => 11.0
72
+ result.should include([ "\"test_subject\"", "\"at\"", "\"+10.000000000931323+10.000000000931323\"^^<http://franz.com/ns/allegrograph/3.0/geospatial/cartesian/2.0/20.0/2.0/20.0/1.0>" ])
73
+ end
74
+
75
+ end
76
+
77
+ describe "find_inside_circle" do
78
+
79
+ it "should find objects inside a circle" do
80
+ result = @statements.find_inside_circle :type => @type,
81
+ :predicate => "\"at\"",
82
+ :x => 9.0,
83
+ :y => 9.0,
84
+ :radius => 2.0
85
+ result.should include([ "\"test_subject\"", "\"at\"", "\"+10.000000000931323+10.000000000931323\"^^<http://franz.com/ns/allegrograph/3.0/geospatial/cartesian/2.0/20.0/2.0/20.0/1.0>" ])
86
+ end
87
+
88
+ end
89
+
90
+ describe "find_inside_haversine" do
91
+
92
+ it "should find objects inside a haversine" do
93
+ result = @statements.find_inside_haversine :type => @type,
94
+ :predicate => "\"at\"",
95
+ :latitude => 9.0,
96
+ :longitude => 9.0,
97
+ :radius => 200.0,
98
+ :unit => :km
99
+ result.should include([ "\"test_subject\"", "\"at\"", "\"+100000+0100000\"^^<http://franz.com/ns/allegrograph/3.0/geospatial/spherical/degrees/2.0/20.0/2.0/20.0/1.0>"])
100
+ end
101
+
102
+ end
103
+
104
+ describe "find_inside_polygon" do
105
+
106
+ it "should find objects inside a polygon" do
107
+ result = @statements.find_inside_polygon :type => @type,
108
+ :predicate => "\"at\"",
109
+ :polygon_name => "test_polygon"
110
+ result.should include([ "\"test_subject\"", "\"at\"", "\"+10.000000000931323+10.000000000931323\"^^<http://franz.com/ns/allegrograph/3.0/geospatial/cartesian/2.0/20.0/2.0/20.0/1.0>"])
54
111
  end
55
112
 
56
113
  end
@@ -0,0 +1,56 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "lib", "allegro_graph", "utility", "parameter_mapper"))
3
+
4
+ describe AllegroGraph::Utility::ParameterMapper do
5
+
6
+ before :each do
7
+ @parameters = {
8
+ :strip_width => 10,
9
+ :latitude_min => 2.0,
10
+ :longitude_min => 2.0,
11
+ :latitude_max => 20.0,
12
+ :longitude_max => 20.0,
13
+ :x_min => 2,
14
+ :y_min => 2,
15
+ :x_max => 20,
16
+ :y_max => 20,
17
+ :name => "test"
18
+ }
19
+ end
20
+
21
+ describe "map" do
22
+
23
+ def do_map(method_name = :spherical_type)
24
+ AllegroGraph::Utility::ParameterMapper.map @parameters, method_name
25
+ end
26
+
27
+ it "should return the mapped parameters" do
28
+ do_map.should == {
29
+ :stripWidth => "10",
30
+ :unit => "degree",
31
+ :latmin => "2.0",
32
+ :longmin => "2.0",
33
+ :latmax => "20.0",
34
+ :longmax => "20.0"
35
+ }
36
+ end
37
+
38
+ it "should map only the right parameters" do
39
+ do_map(:cartesian_type).should == {
40
+ :stripWidth => "10",
41
+ :xmin => "2",
42
+ :ymin => "2",
43
+ :xmax => "20",
44
+ :ymax => "20"
45
+ }
46
+ end
47
+
48
+ it "should modify the parameter values" do
49
+ do_map(:create_polygon).should == {
50
+ :resource => "\"test\""
51
+ }
52
+ end
53
+
54
+ end
55
+
56
+ end
metadata CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
6
6
  - 0
7
7
  - 1
8
8
  - 0
9
- - beta1
10
- version: 0.1.0.beta1
9
+ - beta2
10
+ version: 0.1.0.beta2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Philipp Bruell
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-03-29 00:00:00 +02:00
18
+ date: 2010-03-30 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -32,7 +32,7 @@ files:
32
32
  - Rakefile
33
33
  - lib/allegro_graph/federation.rb
34
34
  - lib/allegro_graph/catalog.rb
35
- - lib/allegro_graph/proxy/geo.rb
35
+ - lib/allegro_graph/proxy/geometric.rb
36
36
  - lib/allegro_graph/proxy/mapping.rb
37
37
  - lib/allegro_graph/proxy/query.rb
38
38
  - lib/allegro_graph/proxy/statements.rb
@@ -40,19 +40,22 @@ files:
40
40
  - lib/allegro_graph/server.rb
41
41
  - lib/allegro_graph/repository.rb
42
42
  - lib/allegro_graph/transport.rb
43
+ - lib/allegro_graph/utility/parameter_mapper.rb
43
44
  - lib/allegro_graph.rb
45
+ - lib/agraph.rb
44
46
  - lib/code_smells.reek
45
47
  - spec/spec_helper.rb
46
48
  - spec/lib/allegro_graph/server_spec.rb
47
49
  - spec/lib/allegro_graph/transport_spec.rb
48
50
  - spec/lib/allegro_graph/proxy/query_spec.rb
51
+ - spec/lib/allegro_graph/proxy/geometric_spec.rb
49
52
  - spec/lib/allegro_graph/proxy/statements_spec.rb
50
53
  - spec/lib/allegro_graph/proxy/mapping_spec.rb
51
- - spec/lib/allegro_graph/proxy/geo_spec.rb
52
54
  - spec/lib/allegro_graph/catalog_spec.rb
53
55
  - spec/lib/allegro_graph/session_spec.rb
54
56
  - spec/lib/allegro_graph/repository_spec.rb
55
57
  - spec/lib/allegro_graph/federation_spec.rb
58
+ - spec/lib/allegro_graph/utility/parameter_mapper_spec.rb
56
59
  - spec/fake_transport_helper.rb
57
60
  - spec/integration/basic_spec.rb
58
61
  - spec/fake_transport.yml
@@ -83,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
86
  version: 1.3.1
84
87
  requirements: []
85
88
 
86
- rubyforge_project:
89
+ rubyforge_project: agraph
87
90
  rubygems_version: 1.3.6
88
91
  signing_key:
89
92
  specification_version: 3
@@ -1,117 +0,0 @@
1
-
2
- module AllegroGraph
3
-
4
- module Proxy
5
-
6
- class Geo
7
-
8
- attr_reader :resource
9
-
10
- def initialize(resource)
11
- @resource = resource
12
- end
13
-
14
- def path
15
- "#{@resource.path}/geo"
16
- end
17
-
18
- def cartesian_type(strip_width, x_min, y_min, x_max, y_max)
19
- parameters = {
20
- :stripWidth => strip_width.to_s,
21
- :xmin => x_min.to_s,
22
- :ymin => y_min.to_s,
23
- :xmax => x_max.to_s,
24
- :ymax => y_max.to_s
25
- }
26
- type = @resource.request :post, self.path + "/types/cartesian", :parameters => parameters, :expected_status_code => 200
27
- type.sub! /^.*</, "<"
28
- type.sub! />.*$/, ">"
29
- type
30
- end
31
-
32
- def spherical_type(strip_width, unit, latitude_min, longitude_min, latitude_max, longitude_max)
33
- parameters = {
34
- :stripWidth => strip_width.to_s,
35
- :unit => unit.to_s,
36
- :latmin => latitude_min.to_s,
37
- :longmin => longitude_min.to_s,
38
- :latmax => latitude_max.to_s,
39
- :longmax => longitude_max.to_s
40
- }
41
- type = @resource.request :post, self.path + "/types/spherical", :parameters => parameters, :expected_status_code => 200
42
- type.sub! /^.*</, "<"
43
- type.sub! />.*$/, ">"
44
- type
45
- end
46
-
47
- def create_polygon(name, type, points)
48
- raise ArgumentError, "at least three points has to defined" unless points.is_a?(Array) && points.size >= 3
49
- parameters = {
50
- :resource => "\"#{name}\"",
51
- :point => points.map{ |point| "\"%+g%+g\"^^%s" % [ point[0], point[1], type ] }
52
- }
53
- @resource.request :put, self.path + "/polygon", :parameters => parameters, :expected_status_code => 204
54
- true
55
- end
56
-
57
- def inside_box(type, predicate, x_min, y_min, x_max, y_max)
58
- parameters = {
59
- :type => type,
60
- :predicate => predicate,
61
- :xmin => x_min.to_s,
62
- :ymin => y_min.to_s,
63
- :xmax => x_max.to_s,
64
- :ymax => y_max.to_s
65
- }
66
- @resource.request :get, self.path + "/box", :parameters => parameters, :expected_status_code => 200
67
- end
68
-
69
- def inside_circle(type, predicate, x, y, radius)
70
- parameters = {
71
- :type => type,
72
- :predicate => predicate,
73
- :x => x.to_s,
74
- :y => y.to_s,
75
- :radius => radius.to_s
76
- }
77
- @resource.request :get, self.path + "/circle", :parameters => parameters, :expected_status_code => 200
78
- end
79
-
80
- def inside_haversine(type, predicate, latitude, longitude, radius, unit = :km)
81
- parameters = {
82
- :type => type,
83
- :predicate => predicate,
84
- :lat => float_to_iso_6709(latitude, 2),
85
- :long => float_to_iso_6709(longitude, 3),
86
- :radius => radius.to_s,
87
- :unit => unit.to_s
88
- }
89
- @resource.request :get, self.path + "/haversine", :parameters => parameters, :expected_status_code => 200
90
- end
91
-
92
- def inside_polygon(type, predicate, name)
93
- parameters = {
94
- :type => type,
95
- :predicate => predicate,
96
- :polygon => "\"#{name}\""
97
- }
98
- @resource.request :get, self.path + "/polygon", :parameters => parameters, :expected_status_code => 200
99
- end
100
-
101
- private
102
-
103
- def float_to_iso_6709(value, digits)
104
- sign = "+"
105
- if value < 0
106
- sign = "-"
107
- value = -value
108
- end
109
- floor = value.to_i
110
- sign + (("%%0%dd" % digits) % floor) + (".%07d" % ((value - floor) * 10000000))
111
- end
112
-
113
- end
114
-
115
- end
116
-
117
- end
@@ -1,89 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
2
- require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "lib", "allegro_graph", "proxy", "geo"))
3
-
4
- describe AllegroGraph::Proxy::Geo do
5
-
6
- before :each do
7
- @server = AllegroGraph::Server.new :username => "test", :password => "test"
8
- @catalog = AllegroGraph::Catalog.new @server, "test_catalog"
9
- @repository = AllegroGraph::Repository.new @catalog, "test_repository"
10
- @geo = AllegroGraph::Proxy::Geo.new @repository
11
- @type = @geo.cartesian_type 1.0, 2.0, 2.0, 20.0, 20.0
12
- end
13
-
14
- describe "path" do
15
-
16
- it "should return the correct path" do
17
- @geo.path.should == "#{@repository.path}/geo"
18
- end
19
-
20
- end
21
-
22
- describe "cartesian_type" do
23
-
24
- it "should provide a cartesian type" do
25
- result = @geo.cartesian_type 1.0, 2.0, 2.0, 20.0, 20.0
26
- result.should == "<http://franz.com/ns/allegrograph/3.0/geospatial/cartesian/2.0/20.0/2.0/20.0/1.0>"
27
- end
28
-
29
- end
30
-
31
- describe "spherical_type" do
32
-
33
- it "should provide a spherical type" do
34
- result = @geo.spherical_type 1.0, :degree, 2.0, 2.0, 20.0, 20.0
35
- result.should == "<http://franz.com/ns/allegrograph/3.0/geospatial/spherical/degrees/2.0/20.0/2.0/20.0/1.0>"
36
- end
37
-
38
- end
39
-
40
- describe "create_polygon" do
41
-
42
- before :each do
43
- @polygon = [ [ 2.0, 2.0 ], [ 10.0, 2.0 ], [ 10.0, 10.0 ], [ 2.0, 10.0 ] ]
44
- end
45
-
46
- it "should create a polygon" do
47
- result = @geo.create_polygon "test_polygon", @type, @polygon
48
- result.should be_true
49
- end
50
-
51
- end
52
-
53
- describe "inside_box" do
54
-
55
- it "should find objects inside a box" do
56
- result = @geo.inside_box @type, "\"at\"", 8.0, 8.0, 11.0, 11.0
57
- result.should include([ "\"test_subject\"", "\"at\"", "\"+10.000000000931323+10.000000000931323\"^^<http://franz.com/ns/allegrograph/3.0/geospatial/cartesian/2.0/20.0/2.0/20.0/1.0>"])
58
- end
59
-
60
- end
61
-
62
- describe "inside_circle" do
63
-
64
- it "should find objects inside a circle" do
65
- result = @geo.inside_circle @type, "\"at\"", 9.0, 9.0, 2.0
66
- result.should include([ "\"test_subject\"", "\"at\"", "\"+10.000000000931323+10.000000000931323\"^^<http://franz.com/ns/allegrograph/3.0/geospatial/cartesian/2.0/20.0/2.0/20.0/1.0>"])
67
- end
68
-
69
- end
70
-
71
- describe "inside_haversine" do
72
-
73
- it "should find objects inside a haversine" do
74
- result = @geo.inside_haversine @type, "\"at\"", 9.0, 9.0, 200.0, :km
75
- result.should include([ "\"test_subject\"", "\"at\"", "\"+100000+0100000\"^^<http://franz.com/ns/allegrograph/3.0/geospatial/spherical/degrees/2.0/20.0/2.0/20.0/1.0>"])
76
- end
77
-
78
- end
79
-
80
- describe "inside_polygon" do
81
-
82
- it "should find objects inside a polygon" do
83
- result = @geo.inside_polygon @type, "\"at\"", "test_polygon"
84
- result.should include([ "\"test_subject\"", "\"at\"", "\"+10.000000000931323+10.000000000931323\"^^<http://franz.com/ns/allegrograph/3.0/geospatial/cartesian/2.0/20.0/2.0/20.0/1.0>"])
85
- end
86
-
87
- end
88
-
89
- end