couch_potato 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 25d897ae6682560bf5d76b11e037d2aab1cb67ed
4
+ data.tar.gz: 22d1dc7f80cf657bfa12957dd0ac7454b4a09bbe
5
+ SHA512:
6
+ metadata.gz: eb2dc8906dc29cdbd33137bbe94f2336757ab79d38d6082671b4f4d0f5292cfd583c0e4eafcb0dff5ffe79b9d01897f253aa9d1f8c6a4db11d1099b8e0b4c2dc
7
+ data.tar.gz: 0598953fcca4915c144ff632cb9d41630dd3493cb42bace24f7550f12f14221baeb159510a7338e51747a87cca02ce5be89cbbc60d13b5944575af8859d6f06d
data/.travis.yml CHANGED
@@ -1,8 +1,9 @@
1
1
  rvm:
2
2
  - 1.9.3
3
3
  - 2.0.0
4
+ - 2.1.0
4
5
  - jruby-19mode
5
- - rbx-19mode
6
+ - rbx-2.1.1
6
7
  gemfile:
7
8
  - active_support_3_2
8
9
  - active_support_4_0
data/CHANGES.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## Changes
2
2
 
3
+ ### 1.1.2
4
+
5
+ * fixes `CouchPotato.models` did not include subclasses
6
+ * adds `CouchPotato.use` (Daniel Lohse)
7
+ * fixes MapReduceToMatcher when reduce uses `sum` (Daniel Lohse)
8
+ * adds `CouchPotato::Config.database_host` for using multiple databases in a project (Daniel Lohse)
9
+ * makes `cast_native` cast floats with no leading digits (wrshawn)
10
+
3
11
  ### 1.1.1
4
12
 
5
13
  * fixes properties were leaked to sibling classes (Alexander Lang)
data/README.md CHANGED
@@ -27,7 +27,7 @@ Lastly Couch Potato aims to provide a seamless integration with Ruby on Rails, e
27
27
 
28
28
  ### Supported Environments
29
29
 
30
- * Ruby 1.9.3, 2.0, Rubinius
30
+ * Ruby 1.9.3, 2.0, 2.1, Rubinius
31
31
  * CouchDB 1.2.0
32
32
  * ActiveSupport 3.2, 4.0
33
33
 
@@ -52,6 +52,11 @@ The server URL will default to http://localhost:5984/ unless specified:
52
52
 
53
53
  CouchPotato::Config.database_name = "http://example.com:5984/name_of_the_db"
54
54
 
55
+ But you can also specify the database host separately from the database name:
56
+
57
+ CouchPotato::Config.database_host = "http://example.com:5984"
58
+ CouchPotato::Config.database_name = "name_of_the_db"
59
+
55
60
  Or with authentication
56
61
 
57
62
  CouchPotato::Config.database_name = "http://username:password@example.com:5984/name_of_the_db"
@@ -414,6 +419,11 @@ Couch Potato supports accessing multiple CouchDBs:
414
419
 
415
420
  Unless configured otherwise this would save the customer model to _http://127.0.0.1:5984/couch_customer_.
416
421
 
422
+ You can also first retrieve the database instance:
423
+
424
+ db = CouchPotato.use('couch_customer')
425
+ db.save @customer
426
+
417
427
  #### Testing
418
428
 
419
429
  To make testing easier and faster database logic has been put into its own class, which you can replace and stub out in whatever way you want:
data/lib/couch_potato.rb CHANGED
@@ -8,14 +8,15 @@ JSON.create_id = 'ruby_class'
8
8
  CouchRest.decode_json_objects = true
9
9
 
10
10
  module CouchPotato
11
- Config = Struct.new(:database_name, :split_design_documents_per_view, :default_language).new
11
+ Config = Struct.new(:database_host, :database_name, :split_design_documents_per_view, :default_language).new
12
12
  Config.split_design_documents_per_view = false
13
13
  Config.default_language = :javascript
14
+ Config.database_host = "http://127.0.0.1:5984"
14
15
 
15
16
  class NotFound < StandardError; end
16
17
  class Conflict < StandardError; end
17
18
 
18
- # returns all the classes that implement the CouchPotato::Persistence module
19
+ # returns all the classes that include the CouchPotato::Persistence module
19
20
  def self.models
20
21
  @models ||= []
21
22
  @models
@@ -28,7 +29,14 @@ module CouchPotato
28
29
 
29
30
  # Returns the underlying CouchRest database object if you want low level access to your CouchDB. You have to set the CouchPotato::Config.database_name before this works.
30
31
  def self.couchrest_database
31
- @@__couchrest_database ||= CouchRest.database(full_url_to_database)
32
+ @@__couchrest_database ||= CouchRest.database(full_url_to_database(CouchPotato::Config.database_name, CouchPotato::Config.database_host))
33
+ end
34
+
35
+ # Returns a specific database instance
36
+ def self.use(database_name)
37
+ @@__databases ||= {}
38
+ @@__databases["#{database_name}"] = Database.new(couchrest_database_for_name!(database_name)) unless @@__databases["#{database_name}"]
39
+ @@__databases["#{database_name}"]
32
40
  end
33
41
 
34
42
  # Executes a block of code and yields a datbase with the given name.
@@ -44,19 +52,24 @@ module CouchPotato
44
52
  yield(@@__databases["#{database_name}"])
45
53
  end
46
54
 
47
- # Creates a CouchRest-Database for directly accessing that functionality.
55
+ # Returns a CouchRest-Database for directly accessing that functionality.
48
56
  def self.couchrest_database_for_name(database_name)
49
- CouchRest.database(full_url_to_database(database_name))
57
+ CouchRest.database(full_url_to_database(database_name, CouchPotato::Config.database_host))
58
+ end
59
+
60
+ # Creates a CouchRest-Database for directly accessing that functionality.
61
+ def self.couchrest_database_for_name!(database_name)
62
+ CouchRest.database!(full_url_to_database(database_name))
50
63
  end
51
64
 
52
65
  private
53
66
 
54
- def self.full_url_to_database(database_name=CouchPotato::Config.database_name)
67
+ def self.full_url_to_database(database_name=CouchPotato::Config.database_name, database_host = CouchPotato::Config.database_host)
55
68
  raise('No Database configured. Set CouchPotato::Config.database_name') unless database_name
56
69
  if database_name.match(%r{https?://})
57
70
  database_name
58
71
  else
59
- "http://127.0.0.1:5984/#{database_name}"
72
+ "#{database_host}/#{database_name}"
60
73
  end
61
74
  end
62
75
  end
@@ -27,11 +27,17 @@ module CouchPotato
27
27
  attr_accessor :_id, :_rev, :_deleted, :database
28
28
  alias_method :id, :_id
29
29
  alias_method :id=, :_id=
30
+
31
+ def self.inherited(child)
32
+ super
33
+ CouchPotato.models << child
34
+ end
30
35
  end
31
36
 
32
37
  CouchPotato.models << base
33
38
  end
34
39
 
40
+
35
41
  # initialize a new instance of the model optionally passing it a hash of attributes.
36
42
  # the attributes have to be declared using the #property method.
37
43
  # the new model will be yielded to an optionally given block.
@@ -1,7 +1,7 @@
1
1
  module CouchPotato
2
2
  module Persistence
3
3
  class TypeCaster #:nodoc:
4
- NUMBER_REGEX = /-?\d+\.?\d*/
4
+ NUMBER_REGEX = /-?\d*\.?\d*/
5
5
 
6
6
  def cast(value, type)
7
7
  if type == :boolean
@@ -50,6 +50,9 @@ module CouchPotato
50
50
  var emit = function(key, value) {
51
51
  mapResults.push({key: key, value: value});
52
52
  };
53
+ var sum = function(values) {
54
+ return values.reduce(function(memo, value) { return memo + value; });
55
+ };
53
56
  for (var i in docs) {
54
57
  map(docs[i]);
55
58
  }
@@ -1,3 +1,3 @@
1
1
  module CouchPotato
2
- VERSION = "1.1.1"
2
+ VERSION = "1.1.2"
3
3
  end
@@ -26,7 +26,7 @@ module CouchPotato
26
26
  results['rows'].first.try(:[], 'value') || 0
27
27
  else
28
28
  results['rows'].map do |row|
29
- if row['doc'].instance_of?(klass)
29
+ if row['doc'].kind_of?(klass)
30
30
  row['doc']
31
31
  else
32
32
  result = row['doc'] || (row['value'].merge(:_id => row['id'] || row['key']) unless view_parameters[:include_docs])
@@ -12,6 +12,7 @@ class Watch
12
12
  property :custom_address, :type => [Address]
13
13
  property :overwritten_read
14
14
  property :overwritten_write
15
+ property :diameter, :type => Float
15
16
 
16
17
  def overwritten_read
17
18
  super.to_s
@@ -73,6 +74,20 @@ describe 'properties' do
73
74
  c.title.should == 3
74
75
  end
75
76
 
77
+ it "should persist a float with leading digits" do
78
+ w = Watch.new :diameter => "46.5"
79
+ CouchPotato.database.save_document! w
80
+ w = CouchPotato.database.load_document w.id
81
+ w.diameter.should == 46.5
82
+ end
83
+
84
+ it "should persist a float with no leading digits" do
85
+ w = Watch.new :diameter => ".465"
86
+ CouchPotato.database.save_document! w
87
+ w = CouchPotato.database.load_document w.id
88
+ w.diameter.should == 0.465
89
+ end
90
+
76
91
  it "should persist a big decimal" do
77
92
  require 'bigdecimal'
78
93
  c = BigDecimalContainer.new :number => BigDecimal.new( '42.42' )
@@ -7,23 +7,38 @@ describe CouchPotato, 'full_url_to_database' do
7
7
  after(:each) do
8
8
  CouchPotato::Config.database_name = @original_database_name
9
9
  end
10
-
10
+
11
11
  it "should add the default localhost and port if only a name is set" do
12
12
  CouchPotato::Config.database_name = 'test'
13
13
  CouchPotato.full_url_to_database.should == 'http://127.0.0.1:5984/test'
14
14
  end
15
-
15
+
16
16
  it "should return the set url" do
17
17
  CouchPotato::Config.database_name = 'http://db.local/test'
18
18
  CouchPotato.full_url_to_database.should == 'http://db.local/test'
19
19
  end
20
20
  end
21
21
 
22
+ describe CouchPotato, 'use' do
23
+ it 'should return the db object' do
24
+ db = CouchPotato.use("testdb")
25
+ db.couchrest_database.root.should == 'http://127.0.0.1:5984/testdb'
26
+ end
27
+ end
28
+
22
29
  describe CouchPotato, '.models' do
23
30
  it "returns all classes that have implemented CouchPotato::Persistence" do
24
31
  clazz = Class.new
25
32
  clazz.send(:include, CouchPotato::Persistence)
26
-
27
- CouchPotato.models.should include(clazz)
33
+
34
+ expect(CouchPotato.models).to include(clazz)
35
+ end
36
+
37
+ it 'returns all subclasses of classes that have implemented CouchPotato::Persistence' do
38
+ clazz = Class.new
39
+ clazz.send(:include, CouchPotato::Persistence)
40
+ subclazz = Class.new clazz
41
+
42
+ expect(CouchPotato.models).to include(subclazz)
28
43
  end
29
- end
44
+ end
@@ -145,6 +145,13 @@ describe CouchPotato::RSpec::MapReduceToMatcher do
145
145
  spec.should map_reduce({}).to({"key" => nil, "value" => "test"})
146
146
  end
147
147
 
148
+ it "should handle sum function" do
149
+ spec = stub(
150
+ :map_function => "function(doc) { emit(null, doc.age); }",
151
+ :reduce_function => "function(keys, values) { return sum(values); }")
152
+ spec.should map_reduce(@docs).to({"key" => nil, "value" => 103})
153
+ end
154
+
148
155
  context "without grouping" do
149
156
  it "should not group by key by default" do
150
157
  @view_spec.should map_reduce(@docs).to({"key" => nil, "value" => 8})
data/spec/views_spec.rb CHANGED
@@ -5,6 +5,7 @@ class Build
5
5
 
6
6
  property :state
7
7
  property :time
8
+ property :type, :type => String, :default => 'Build'
8
9
 
9
10
  view :timeline, :key => :time
10
11
  view :count, :key => :time, :reduce => true
@@ -17,9 +18,11 @@ class Build
17
18
  view :raw, :type => :raw, :map => "function(doc) {emit(doc._id, doc.state)}"
18
19
  view :filtered_raw, :type => :raw, :map => "function(doc) {emit(doc._id, doc.state)}", :results_filter => lambda{|res| res['rows'].map{|row| row['value']}}
19
20
  view :with_view_options, :group => true, :key => :time
21
+ view :all, :map => "function(doc) { if (doc && doc.type == 'Build') emit(doc._id, 1); }", :include_docs => true, :type => :custom
20
22
  end
21
23
 
22
24
  class CustomBuild < Build
25
+ property :server
23
26
  end
24
27
 
25
28
  class ErlangBuild
@@ -239,6 +242,13 @@ describe 'views' do
239
242
  @db.view(CustomBuild.timeline).size.should == 1
240
243
  @db.view(CustomBuild.timeline).first.should be_kind_of(CustomBuild)
241
244
  end
245
+
246
+ it "should return instances of subclasses as well if a special view exists" do
247
+ @db.save_document Build.new(:state => 'success', :time => '2008-01-01')
248
+ @db.save_document CustomBuild.new(:state => 'success', :time => '2008-01-01', :server => 'Jenkins')
249
+ results = @db.view(Build.all)
250
+ results.map(&:class).should == [CustomBuild, Build]
251
+ end
242
252
  end
243
253
 
244
254
  describe "list functions" do
metadata CHANGED
@@ -1,126 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: couch_potato
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
5
- prerelease:
4
+ version: 1.1.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Alexander Lang
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-11-29 00:00:00.000000000 Z
11
+ date: 2014-03-05 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: json
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: '1.6'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '1.6'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: couchrest
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
33
  version: 1.2.0
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
40
  version: 1.2.0
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: activemodel
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: rspec
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ~>
59
+ - - "~>"
68
60
  - !ruby/object:Gem::Version
69
61
  version: 2.11.0
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ~>
66
+ - - "~>"
76
67
  - !ruby/object:Gem::Version
77
68
  version: 2.11.0
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: timecop
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - ">="
84
74
  - !ruby/object:Gem::Version
85
75
  version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ! '>='
80
+ - - ">="
92
81
  - !ruby/object:Gem::Version
93
82
  version: '0'
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: tzinfo
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
- - - ! '>='
87
+ - - ">="
100
88
  - !ruby/object:Gem::Version
101
89
  version: '0'
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
- - - ! '>='
94
+ - - ">="
108
95
  - !ruby/object:Gem::Version
109
96
  version: '0'
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: rake
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
- - - ! '>='
101
+ - - ">="
116
102
  - !ruby/object:Gem::Version
117
103
  version: '0'
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
- - - ! '>='
108
+ - - ">="
124
109
  - !ruby/object:Gem::Version
125
110
  version: '0'
126
111
  description: Ruby persistence layer for CouchDB
@@ -129,8 +114,8 @@ executables: []
129
114
  extensions: []
130
115
  extra_rdoc_files: []
131
116
  files:
132
- - .gitignore
133
- - .travis.yml
117
+ - ".gitignore"
118
+ - ".travis.yml"
134
119
  - CHANGES.md
135
120
  - CREDITS
136
121
  - Gemfile
@@ -220,27 +205,26 @@ files:
220
205
  - spec/views_spec.rb
221
206
  homepage: http://github.com/langalex/couch_potato
222
207
  licenses: []
208
+ metadata: {}
223
209
  post_install_message:
224
210
  rdoc_options: []
225
211
  require_paths:
226
212
  - lib
227
213
  required_ruby_version: !ruby/object:Gem::Requirement
228
- none: false
229
214
  requirements:
230
- - - ! '>='
215
+ - - ">="
231
216
  - !ruby/object:Gem::Version
232
217
  version: '0'
233
218
  required_rubygems_version: !ruby/object:Gem::Requirement
234
- none: false
235
219
  requirements:
236
- - - ! '>='
220
+ - - ">="
237
221
  - !ruby/object:Gem::Version
238
222
  version: '0'
239
223
  requirements: []
240
224
  rubyforge_project:
241
- rubygems_version: 1.8.24
225
+ rubygems_version: 2.2.0
242
226
  signing_key:
243
- specification_version: 3
227
+ specification_version: 4
244
228
  summary: Ruby persistence layer for CouchDB
245
229
  test_files:
246
230
  - spec/attachments_spec.rb