couchrest_model 2.0.4 → 2.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -2
- data/README.md +12 -3
- data/VERSION +1 -1
- data/benchmarks/Gemfile +7 -0
- data/benchmarks/connections.rb +69 -0
- data/couchrest_model.gemspec +11 -13
- data/history.md +6 -0
- data/lib/couchrest/model/design.rb +0 -2
- data/lib/couchrest/model/designs/view.rb +36 -16
- data/lib/couchrest/model/document_queries.rb +5 -9
- data/lib/couchrest/model/errors.rb +8 -0
- data/lib/couchrest/model/support/couchrest_database.rb +12 -4
- data/lib/couchrest/model/validations.rb +1 -1
- data/lib/couchrest/model/validations/uniqueness.rb +11 -1
- data/spec/fixtures/models/course.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/unit/assocations_spec.rb +1 -1
- data/spec/unit/attachment_spec.rb +1 -1
- data/spec/unit/base_spec.rb +5 -5
- data/spec/unit/casted_spec.rb +2 -2
- data/spec/unit/connection_spec.rb +3 -3
- data/spec/unit/design_spec.rb +2 -2
- data/spec/unit/designs/design_mapper_spec.rb +1 -1
- data/spec/unit/designs/migrations_spec.rb +1 -1
- data/spec/unit/designs/view_spec.rb +118 -43
- data/spec/unit/designs_spec.rb +10 -13
- data/spec/unit/embeddable_spec.rb +2 -4
- data/spec/unit/persistence_spec.rb +13 -5
- data/spec/unit/property_protection_spec.rb +5 -5
- data/spec/unit/property_spec.rb +9 -9
- data/spec/unit/proxyable_spec.rb +15 -15
- data/spec/unit/subclass_spec.rb +1 -1
- data/spec/unit/utils/migrate_spec.rb +3 -3
- data/spec/unit/validations_spec.rb +7 -7
- metadata +60 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57c0015876d459e0bee7cfb9e3f59a2aa5231d1d
|
4
|
+
data.tar.gz: 7c0e6f7444fa9e73fc041946c5736f94eb42b765
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 306a335f39a5530bd4273731affe1f1c238b0e487177d3340b8c6e9cefa885ec2e2048182cd008b3a3ab12ca31d487110f8e0bca036d28639b8d1b74c8872238
|
7
|
+
data.tar.gz: 9d09641f25b138dbb3c56cfbbe2663947d6ed04135a64d5d4157b8f94d068881989ac79f0f19d7e0c1af64cee4d42aedc9534becdc26c97551b04c8193ef0a5e
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -7,7 +7,7 @@ CouchRest Model helps you define models that are stored as documents in your Cou
|
|
7
7
|
It supports useful features such as setting properties with typecasting, callbacks, validations, associations, and helps
|
8
8
|
with creating CouchDB views to access your data.
|
9
9
|
|
10
|
-
CouchRest Model uses ActiveModel for a lot of the magic, so if you're using Rails, you'll need at least version 3.0.
|
10
|
+
CouchRest Model uses ActiveModel for a lot of the magic, so if you're using Rails, you'll need at least version 3.0. Releases since 2.0.0 are Rails 4.0 compatible, and we recommend Ruby 2.0+.
|
11
11
|
|
12
12
|
## Documentation
|
13
13
|
|
@@ -60,9 +60,9 @@ The library will try to detect a configuration file at `config/couchdb.yml` from
|
|
60
60
|
username: test
|
61
61
|
password: user
|
62
62
|
|
63
|
-
Note that the name of the database is either just the prefix and suffix combined or the prefix plus any text you
|
63
|
+
Note that the name of the database is either just the prefix and suffix combined or the prefix plus any text you specify using `use_database` method in your models with the suffix on the end.
|
64
64
|
|
65
|
-
The example config above for example would use a database called "project_test".
|
65
|
+
The example config above for example would use a database called "project_test". Here's an example using the `use_database` call:
|
66
66
|
|
67
67
|
```ruby
|
68
68
|
class Project < CouchRest::Model::Base
|
@@ -140,6 +140,15 @@ end
|
|
140
140
|
@cat.update_attributes(:name => 'Felix', :random_text => 'feline')
|
141
141
|
@cat.new? # false
|
142
142
|
@cat.random_text # Raises error!
|
143
|
+
|
144
|
+
# Fetching by views, loading all results into memory
|
145
|
+
cats = Cat.by_name.all
|
146
|
+
cats.first.name # "Felix"
|
147
|
+
|
148
|
+
# Streaming views, for efficient memory usage
|
149
|
+
Cat.by_name.all do |cat|
|
150
|
+
puts cat.name
|
151
|
+
end
|
143
152
|
```
|
144
153
|
|
145
154
|
## Development
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.
|
1
|
+
2.1.0.beta1
|
data/benchmarks/Gemfile
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#
|
2
|
+
# Simple Benchmarking Script.
|
3
|
+
#
|
4
|
+
# Meant to test performance for different types on connections under a typical
|
5
|
+
# scenario of requesting multiple objects from the database in series.
|
6
|
+
#
|
7
|
+
# To run, use `bundle install` then:
|
8
|
+
#
|
9
|
+
# bundle exec ruby connections.rb
|
10
|
+
#
|
11
|
+
|
12
|
+
require 'rubygems'
|
13
|
+
require 'bundler/setup'
|
14
|
+
|
15
|
+
require 'benchmark'
|
16
|
+
require 'couchrest_model'
|
17
|
+
require 'faker'
|
18
|
+
|
19
|
+
class SampleModel < CouchRest::Model::Base
|
20
|
+
use_database "benchmark"
|
21
|
+
|
22
|
+
property :name, String
|
23
|
+
property :date, Date
|
24
|
+
|
25
|
+
timestamps!
|
26
|
+
|
27
|
+
design do
|
28
|
+
view :by_name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
Benchmark.bm do |x|
|
34
|
+
x.report("Create: ") do
|
35
|
+
100.times do |i|
|
36
|
+
m = SampleModel.new(
|
37
|
+
name: Faker::Name.name,
|
38
|
+
date: Faker::Date.between(1.year.ago, Date.today)
|
39
|
+
)
|
40
|
+
m.save!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Make sure the view is fresh
|
45
|
+
SampleModel.by_name.limit(1).rows
|
46
|
+
|
47
|
+
x.report("Fetch inc/docs:") do
|
48
|
+
SampleModel.by_name.all.each do |doc|
|
49
|
+
doc.to_json
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
x.report("Fetch: ") do
|
54
|
+
SampleModel.by_name.rows.each do |row|
|
55
|
+
row.doc.to_json # Causes each doc to be fetched
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
if CouchRest::Model::VERSION >= '2.1.0'
|
60
|
+
x.report("Fetch w/block: ") do
|
61
|
+
SampleModel.by_name.rows do |row|
|
62
|
+
row.doc.to_json # Causes each doc to be fetched
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
SampleModel.database.delete!
|
69
|
+
|
data/couchrest_model.gemspec
CHANGED
@@ -14,24 +14,22 @@ Gem::Specification.new do |s|
|
|
14
14
|
"THANKS.md"
|
15
15
|
]
|
16
16
|
s.homepage = %q{http://github.com/couchrest/couchrest_model}
|
17
|
-
s.rubygems_version = %q{1.3.7}
|
18
|
-
s.summary = %q{Extends the CouchRest Document for advanced modelling.}
|
17
|
+
#s.rubygems_version = %q{1.3.7}
|
18
|
+
s.summary = %q{Extends the CouchRest Document class for advanced modelling.}
|
19
19
|
|
20
20
|
s.files = `git ls-files`.split("\n")
|
21
21
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
22
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
23
|
s.require_paths = ["lib"]
|
24
24
|
|
25
|
-
s.add_dependency(
|
26
|
-
s.add_dependency(
|
27
|
-
s.add_dependency(
|
28
|
-
s.
|
29
|
-
s.add_development_dependency(
|
30
|
-
s.add_development_dependency(%q<json>, ["~> 1.5.1"])
|
31
|
-
s.add_development_dependency(%q<rack-test>, ">= 0.5.7")
|
25
|
+
s.add_dependency("couchrest", "2.0.0.rc3")
|
26
|
+
s.add_dependency("activemodel", "~> 4.0")
|
27
|
+
s.add_dependency("tzinfo", ">= 0.3.22")
|
28
|
+
s.add_development_dependency("rspec", "~> 2.14.1")
|
29
|
+
s.add_development_dependency("rack-test", ">= 0.5.7")
|
32
30
|
s.add_development_dependency("rake", ">= 0.8.0")
|
33
|
-
|
34
|
-
|
35
|
-
s.add_development_dependency("kaminari", "
|
36
|
-
|
31
|
+
s.add_development_dependency("test-unit")
|
32
|
+
s.add_development_dependency("minitest", "> 4.1") #, "< 5.0") # For Kaminari and activesupport, pending removal
|
33
|
+
s.add_development_dependency("kaminari", ">= 0.14.1", "< 0.16.0")
|
34
|
+
s.add_development_dependency("mime-types", "< 3.0") # Mime-types > 3.0 don't bundle properly on JRuby
|
37
35
|
end
|
data/history.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# CouchRest Model Change History
|
2
2
|
|
3
|
+
## 2.1.0.beta1 - 2016-01-13
|
4
|
+
|
5
|
+
* Upgrading to CouchRest 2.0.0 series (@samlown)
|
6
|
+
* Support for streaming in View objects (@samlown)
|
7
|
+
* Support for ActiveModel >= 4.1 (@samlown)
|
8
|
+
|
3
9
|
## 2.0.4 - 2015-06-26
|
4
10
|
|
5
11
|
* Casting Array properties using anything that inherits from Hash. (@samlown)
|
@@ -58,10 +58,16 @@ module CouchRest
|
|
58
58
|
# are no results.
|
59
59
|
def rows
|
60
60
|
return @rows if @rows
|
61
|
-
if
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
if block_given?
|
62
|
+
execute do |row|
|
63
|
+
yield ViewRow.new(row, model, use_database)
|
64
|
+
end
|
65
|
+
else
|
66
|
+
if execute && result['rows']
|
67
|
+
@rows ||= result['rows'].map{|v| ViewRow.new(v, model, use_database)}
|
68
|
+
else
|
69
|
+
[ ]
|
70
|
+
end
|
65
71
|
end
|
66
72
|
end
|
67
73
|
|
@@ -69,16 +75,22 @@ module CouchRest
|
|
69
75
|
# not already been prepared for including documents in the query,
|
70
76
|
# it will be added automatically and reset any previously cached
|
71
77
|
# results.
|
72
|
-
def all
|
78
|
+
def all(&block)
|
73
79
|
include_docs!
|
74
|
-
docs
|
80
|
+
docs(&block)
|
75
81
|
end
|
76
82
|
|
77
83
|
# Provide all the documents from the view. If the view has not been
|
78
84
|
# prepared with the +include_docs+ option, each document will be
|
79
85
|
# loaded individually.
|
80
86
|
def docs
|
81
|
-
|
87
|
+
if block_given?
|
88
|
+
rows do |row|
|
89
|
+
yield row.doc
|
90
|
+
end
|
91
|
+
else
|
92
|
+
@docs ||= rows.map{|r| r.doc}
|
93
|
+
end
|
82
94
|
end
|
83
95
|
|
84
96
|
# If another request has been made on the view, this will return
|
@@ -413,16 +425,16 @@ module CouchRest
|
|
413
425
|
query[:database] || model.database
|
414
426
|
end
|
415
427
|
|
416
|
-
def execute
|
428
|
+
def execute(&block)
|
417
429
|
return self.result if result
|
418
|
-
raise
|
430
|
+
raise CouchRest::Model::DatabaseNotDefined if use_database.nil?
|
419
431
|
|
420
432
|
# Remove the reduce value if its not needed to prevent CouchDB errors
|
421
433
|
query.delete(:reduce) unless can_reduce?
|
422
434
|
|
423
435
|
design_doc.sync(use_database)
|
424
436
|
|
425
|
-
self.result = design_doc.view_on(use_database, name, query)
|
437
|
+
self.result = design_doc.view_on(use_database, name, query, &block)
|
426
438
|
end
|
427
439
|
|
428
440
|
# Class Methods
|
@@ -535,9 +547,10 @@ module CouchRest
|
|
535
547
|
# A special wrapper class that provides easy access to the key
|
536
548
|
# fields in a result row.
|
537
549
|
class ViewRow < Hash
|
538
|
-
attr_reader :model
|
539
|
-
def initialize(hash, model)
|
540
|
-
@model
|
550
|
+
attr_reader :model, :db
|
551
|
+
def initialize(hash, model, db = nil)
|
552
|
+
@model = model
|
553
|
+
@db = db || model.database
|
541
554
|
replace(hash)
|
542
555
|
end
|
543
556
|
def id
|
@@ -555,9 +568,16 @@ module CouchRest
|
|
555
568
|
# Send a request for the linked document either using the "id" field's
|
556
569
|
# value, or the ["value"]["_id"] used for linked documents.
|
557
570
|
def doc
|
558
|
-
|
559
|
-
|
560
|
-
|
571
|
+
@doc ||= begin
|
572
|
+
if self['doc']
|
573
|
+
obj = model.build_from_database(self['doc'])
|
574
|
+
obj.database ||= db
|
575
|
+
obj
|
576
|
+
else
|
577
|
+
doc_id = (value.is_a?(Hash) && value['_id']) ? value['_id'] : self.id
|
578
|
+
doc_id ? model.get(doc_id, db) : nil
|
579
|
+
end
|
580
|
+
end
|
561
581
|
end
|
562
582
|
end
|
563
583
|
|
@@ -33,11 +33,9 @@ module CouchRest
|
|
33
33
|
# id<String, Integer>:: Document ID
|
34
34
|
# db<Database>:: optional option to pass a custom database to use
|
35
35
|
def get(id, db = database)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
nil
|
40
|
-
end
|
36
|
+
get!(id, db)
|
37
|
+
rescue CouchRest::Model::DocumentNotFound
|
38
|
+
nil
|
41
39
|
end
|
42
40
|
alias :find :get
|
43
41
|
|
@@ -54,11 +52,9 @@ module CouchRest
|
|
54
52
|
# db<Database>:: optional option to pass a custom database to use
|
55
53
|
def get!(id, db = database)
|
56
54
|
raise CouchRest::Model::DocumentNotFound if id.blank?
|
57
|
-
|
58
|
-
doc = db.get
|
55
|
+
raise CouchRest::Model::DatabaseNotDefined if db.nil?
|
56
|
+
doc = db.get(id) or raise CouchRest::Model::DocumentNotFound
|
59
57
|
build_from_database(doc)
|
60
|
-
rescue RestClient::ResourceNotFound
|
61
|
-
raise CouchRest::Model::DocumentNotFound
|
62
58
|
end
|
63
59
|
alias :find! :get!
|
64
60
|
|
@@ -21,5 +21,13 @@ module CouchRest
|
|
21
21
|
end
|
22
22
|
|
23
23
|
class DocumentNotFound < Errors::CouchRestModelError; end
|
24
|
+
|
25
|
+
class DatabaseNotDefined < Errors::CouchRestModelError
|
26
|
+
def initialize(msg = nil)
|
27
|
+
msg ||= "Database must be defined in model or view!"
|
28
|
+
super(msg)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
24
32
|
end
|
25
33
|
end
|
@@ -3,11 +3,19 @@
|
|
3
3
|
# also emptied. Given that this is a rare event, and the consequences are not
|
4
4
|
# very severe, we just completely empty the cache.
|
5
5
|
#
|
6
|
-
CouchRest::
|
6
|
+
module CouchRest::Model
|
7
|
+
module Support
|
8
|
+
module Database
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
def delete!
|
11
|
+
Thread.current[:couchrest_design_cache] = { }
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
11
16
|
end
|
17
|
+
end
|
12
18
|
|
19
|
+
class CouchRest::Database
|
20
|
+
include(CouchRest::Model::Support::Database)
|
13
21
|
end
|
@@ -55,7 +55,7 @@ module CouchRest
|
|
55
55
|
# Asside from the standard options, you can specify the name of the view you'd like
|
56
56
|
# to use for the search inside the +:view+ option. The following example would search
|
57
57
|
# for the code in side the +all+ view, useful for when +unique_id+ is used and you'd
|
58
|
-
# like to check before receiving a
|
58
|
+
# like to check before receiving a CouchRest::Conflict error:
|
59
59
|
#
|
60
60
|
# validates_uniqueness_of :code, :view => 'all'
|
61
61
|
#
|
@@ -7,9 +7,16 @@ module CouchRest
|
|
7
7
|
# Validates if a field is unique
|
8
8
|
class UniquenessValidator < ActiveModel::EachValidator
|
9
9
|
|
10
|
+
SETUP_DEPRECATED = ActiveModel.respond_to?(:version) && ActiveModel.version >= Gem::Version.new('4.1')
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
super
|
14
|
+
setup_uniqueness_validation(options[:class]) if options[:class]
|
15
|
+
end
|
16
|
+
|
10
17
|
# Ensure we have a class available so we can check for a usable view
|
11
18
|
# or add one if necessary.
|
12
|
-
def
|
19
|
+
def setup_uniqueness_validation(model)
|
13
20
|
@model = model
|
14
21
|
if options[:view].blank?
|
15
22
|
attributes.each do |attribute|
|
@@ -24,6 +31,9 @@ module CouchRest
|
|
24
31
|
end
|
25
32
|
end
|
26
33
|
|
34
|
+
# Provide backwards compatibility for Rails < 4.1, which expects `#setup` to be defined.
|
35
|
+
alias_method :setup, :setup_uniqueness_validation unless SETUP_DEPRECATED
|
36
|
+
|
27
37
|
def validate_each(document, attribute, value)
|
28
38
|
opts = merge_view_options(attribute)
|
29
39
|
|
data/spec/spec_helper.rb
CHANGED
@@ -18,7 +18,7 @@ unless defined?(FIXTURE_PATH)
|
|
18
18
|
COUCHHOST = "http://127.0.0.1:5984"
|
19
19
|
TESTDB = 'couchrest-model-test'
|
20
20
|
TEST_SERVER = CouchRest.new COUCHHOST
|
21
|
-
TEST_SERVER.default_database = TESTDB
|
21
|
+
# TEST_SERVER.default_database = TESTDB
|
22
22
|
DB = TEST_SERVER.database(TESTDB)
|
23
23
|
end
|
24
24
|
|
@@ -38,7 +38,7 @@ end
|
|
38
38
|
Dir[ File.join(MODEL_PATH, "*.rb") ].sort.each { |file| require File.basename(file) }
|
39
39
|
|
40
40
|
class Basic < CouchRest::Model::Base
|
41
|
-
use_database
|
41
|
+
use_database DB
|
42
42
|
end
|
43
43
|
|
44
44
|
def reset_test_db!
|
@@ -25,7 +25,7 @@ describe "Assocations" do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should generate a proxy string if proxied" do
|
28
|
-
SaleInvoice.stub
|
28
|
+
SaleInvoice.stub(:proxy_owner_method).twice.and_return('company')
|
29
29
|
o = SaleInvoice.merge_assoc_opts(:cat)
|
30
30
|
o[:proxy].should eql('self.company.cats')
|
31
31
|
end
|