loose_change 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Loose Change is a Ruby ORM for CouchDB
2
2
 
3
- * where 'ORM' is as accurate as ['Holy Roman
3
+ * where 'Object-Relational Mapper' is as accurate as ['Holy Roman
4
4
  Empire'](http://en.wikipedia.org/wiki/Holy_Roman_Empire#Analysis)
5
5
 
6
6
  ## Goals and Principles
@@ -10,11 +10,20 @@ Empire'](http://en.wikipedia.org/wiki/Holy_Roman_Empire#Analysis)
10
10
  * Make common tasks easy; get out of your way if you need the metal
11
11
  * Make working with [GeoCouch](http://github.com/vmx/couchdb) seamless
12
12
 
13
+ ## GeoCouch Support
14
+
15
+ Documents with spatial properties are now supported if you are running
16
+ the latest version of [GeoCouch from
17
+ git](http://github.com/vmx/couchdb). Only Point and MultiPoint
18
+ geometries are currently supported and tested.
19
+
13
20
  ## Warnings
14
21
 
15
- * This is pretty alpha at this point.
16
22
  * Only tested on Ruby 1.9.2. I'm not intentionally breaking 1.8.x, but neither do I guarantee anything.
17
- * The stuff about GeoCouch above was a goal I didn't get to yet.
23
+
24
+ ## Todo
25
+
26
+ * Add Rake tasks to push complicated views from a JS directory
18
27
 
19
28
  ## Help
20
29
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.7
1
+ 0.4.0
@@ -25,6 +25,7 @@ module LooseChange
25
25
  include PersistenceClassMethods
26
26
  extend Views
27
27
  extend Pagination
28
+ extend Spatial
28
29
  include Helpers
29
30
  extend Helpers
30
31
 
@@ -1,5 +1,9 @@
1
1
  module LooseChange
2
2
  module Helpers
3
+ def design_document_uri(database, model_name)
4
+ "#{ database.uri }/_design/#{ CGI.escape(model_name) }"
5
+ end
6
+
3
7
  def default_headers
4
8
  {
5
9
  :content_type => :json,
@@ -0,0 +1,47 @@
1
+ module LooseChange
2
+ module Spatial
3
+ # To define a spatial geometry property on a CouchDB document, use
4
+ # the geo_* methods as following:
5
+ #
6
+ # class Bar < LooseChange::Base
7
+ # geo_point :location
8
+ # geo_multipoint :catchment_area
9
+ # end
10
+ #
11
+ # bar = Bar.new(:location => [41.3913, 73.9813])
12
+ #
13
+ # For information on geometries see the GeoJSON documentation at
14
+ # http://geojson.org/geojson-spec.html
15
+
16
+ GEOMETRIES = %w(Point MultiPoint)
17
+
18
+ GEOMETRIES.each do |type|
19
+ define_method("geo_#{type}".downcase.to_sym) do |name|
20
+ design_doc = JSON.parse(RestClient.get(design_document_uri(database, model_name)))
21
+ function =<<JS
22
+ function(doc) {
23
+ if (doc.#{name} && doc.model_name == "#{ model_name }") {
24
+ emit({ type: "#{type}",
25
+ coordinates: doc.#{name} },
26
+ [doc._id, doc.#{name}]); }
27
+ }
28
+ JS
29
+ RestClient.put(design_document_uri(database, model_name),
30
+ design_doc.merge({"spatial" => (design_doc["spatial"] || {}).merge({ name => function })}).to_json, default_headers)
31
+ property(name)
32
+ end
33
+ end
34
+
35
+ # Locate documents with a bounding box (defined as two coordinate
36
+ # pairs, from lower-left to upper-right). The <tt>:name</tt>
37
+ # parameter identifies which location property to search.
38
+ #
39
+ # Bar.by_bounding_box(:location, 40, 72, 43, 74)
40
+ def by_bounding_box(name, lat1, lng1, lat2, lng2)
41
+ JSON.parse(RestClient.get("#{ design_document_uri(database, model_name) }/_spatial/#{name}?bbox=#{ [lat1,lng1,lat2,lng2].join(',') }", default_headers))['rows'].map do |row|
42
+ find(row['id'])
43
+ end
44
+ end
45
+
46
+ end
47
+ end
@@ -57,7 +57,7 @@ module LooseChange
57
57
  def add_view(name, map, reduce = nil)
58
58
  design_doc = JSON.parse(RestClient.get("#{ self.database.uri }/_design/#{ CGI.escape(self.model_name) }"))
59
59
  current_views = design_doc['views'] || {}
60
- JSON.parse(RestClient.put("#{ self.database.uri }/_design/#{ self.model_name }",
60
+ JSON.parse(RestClient.put("#{ self.database.uri }/_design/#{ CGI.escape(self.model_name) }",
61
61
  { '_id' => design_doc['_id'],
62
62
  '_rev' => design_doc['_rev'],
63
63
  'language' => 'javascript',
data/lib/loose_change.rb CHANGED
@@ -20,4 +20,5 @@ module LooseChange
20
20
  autoload :Views, File.dirname(__FILE__) + '/loose_change/views'
21
21
  autoload :Pagination, File.dirname(__FILE__) + '/loose_change/pagination'
22
22
  autoload :Helpers, File.dirname(__FILE__) + '/loose_change/helpers'
23
+ autoload :Spatial, File.dirname(__FILE__) + '/loose_change/spatial'
23
24
  end
data/loose_change.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{loose_change}
8
- s.version = "0.3.7"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Joshua Miller"]
12
- s.date = %q{2010-12-16}
12
+ s.date = %q{2010-12-22}
13
13
  s.email = %q{josh@joshinharrisburg.com}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  "lib/loose_change/pagination.rb",
35
35
  "lib/loose_change/persistence.rb",
36
36
  "lib/loose_change/server.rb",
37
+ "lib/loose_change/spatial.rb",
37
38
  "lib/loose_change/views.rb",
38
39
  "loose_change.gemspec",
39
40
  "test/attachment_test.rb",
@@ -44,6 +45,7 @@ Gem::Specification.new do |s|
44
45
  "test/pagination_test.rb",
45
46
  "test/persistence_test.rb",
46
47
  "test/resources/couchdb.png",
48
+ "test/spatial_test.rb",
47
49
  "test/test_helper.rb",
48
50
  "test/view_test.rb"
49
51
  ]
@@ -60,6 +62,7 @@ Gem::Specification.new do |s|
60
62
  "test/inheritance_test.rb",
61
63
  "test/pagination_test.rb",
62
64
  "test/persistence_test.rb",
65
+ "test/spatial_test.rb",
63
66
  "test/test_helper.rb",
64
67
  "test/view_test.rb"
65
68
  ]
@@ -0,0 +1,55 @@
1
+ require './test/test_helper'
2
+
3
+ class SpatialTest < ActiveSupport::TestCase
4
+
5
+ context "a basic spatial model with a point" do
6
+
7
+ setup do
8
+ class PointModel < LooseChange::Base
9
+ use_database "test_db"
10
+ geo_point :loc
11
+ end
12
+
13
+ PointModel.all.each(&:destroy)
14
+
15
+ @model = PointModel.new(:loc => [40.813874, 77.858219])
16
+ @model.save
17
+ end
18
+
19
+ should "have a lat,lng pair as a location" do
20
+ assert_equal [40.813874, 77.858219], @model.loc
21
+ end
22
+
23
+ should "be findable in a bounding box" do
24
+ assert_equal [@model], PointModel.by_bounding_box(:loc, 0, 0, 41, 80)
25
+ end
26
+
27
+ end
28
+
29
+ context "a spatial model with a multipoint" do
30
+
31
+ setup do
32
+ class MPModel < LooseChange::Base
33
+ use_database "test_db"
34
+ geo_multipoint :loc
35
+ end
36
+
37
+ MPModel.all.each(&:destroy)
38
+
39
+ @model = MPModel.new(:loc => [[40.813874, 77.858219], [42.134, 79.23434]])
40
+ @model.save
41
+ end
42
+
43
+ should "return its multipoint data" do
44
+ assert_equal [[40.813874, 77.858219], [42.134, 79.23434]], @model.loc
45
+ end
46
+
47
+ should "be findable in a bounding box" do
48
+ assert_equal [@model], MPModel.by_bounding_box(:loc, 0, 0, 43, 80)
49
+ assert_equal [], MPModel.by_bounding_box(:loc, 0, 0, 40, 80)
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 3
8
- - 7
9
- version: 0.3.7
7
+ - 4
8
+ - 0
9
+ version: 0.4.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Joshua Miller
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-16 00:00:00 -05:00
17
+ date: 2010-12-22 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -105,6 +105,7 @@ files:
105
105
  - lib/loose_change/pagination.rb
106
106
  - lib/loose_change/persistence.rb
107
107
  - lib/loose_change/server.rb
108
+ - lib/loose_change/spatial.rb
108
109
  - lib/loose_change/views.rb
109
110
  - loose_change.gemspec
110
111
  - test/attachment_test.rb
@@ -115,6 +116,7 @@ files:
115
116
  - test/pagination_test.rb
116
117
  - test/persistence_test.rb
117
118
  - test/resources/couchdb.png
119
+ - test/spatial_test.rb
118
120
  - test/test_helper.rb
119
121
  - test/view_test.rb
120
122
  has_rdoc: true
@@ -131,7 +133,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
131
133
  requirements:
132
134
  - - ">="
133
135
  - !ruby/object:Gem::Version
134
- hash: 383827445871452727
136
+ hash: -1403901373339618448
135
137
  segments:
136
138
  - 0
137
139
  version: "0"
@@ -158,5 +160,6 @@ test_files:
158
160
  - test/inheritance_test.rb
159
161
  - test/pagination_test.rb
160
162
  - test/persistence_test.rb
163
+ - test/spatial_test.rb
161
164
  - test/test_helper.rb
162
165
  - test/view_test.rb