will_paginate_couchrest 0.1.0
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/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +37 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/lib/will_paginate_couchrest.rb +145 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/will_paginate_couchrest_spec.rb +60 -0
- metadata +84 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 alex
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
= Will Paginate for Couchrest
|
2
|
+
|
3
|
+
Adds support for the will_paginate gem by mislav to {couchrest}[http://github.com/couchrest/couchrest].
|
4
|
+
|
5
|
+
Inspired by Kenneth Kalmer's post:
|
6
|
+
|
7
|
+
http://www.opensourcery.co.za/2010/02/08/paginating-documents-with-couchrest-and-will_paginate/
|
8
|
+
|
9
|
+
Automatically generate views with an extra reduce method used to generate the total number of documents.
|
10
|
+
|
11
|
+
== Install
|
12
|
+
|
13
|
+
gem install will_paginate_couchrest
|
14
|
+
|
15
|
+
== Usage
|
16
|
+
|
17
|
+
require 'rubygems'
|
18
|
+
require 'couchrest'
|
19
|
+
require 'will_paginate'
|
20
|
+
require 'will_paginate_couchrest'
|
21
|
+
|
22
|
+
class User < CouchRest::ExtendedDocument
|
23
|
+
|
24
|
+
property :nickname
|
25
|
+
|
26
|
+
paginated_view_by :nickname
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
@users = User.paginate_by_nickname :page => 1, :per_page => 10, :key => 'Fred'
|
31
|
+
|
32
|
+
will_paginate @users
|
33
|
+
|
34
|
+
|
35
|
+
== Copyright
|
36
|
+
|
37
|
+
Copyright (c) 2010 Sam Lown @ autofiscal S.L. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "will_paginate_couchrest"
|
8
|
+
gem.summary = %Q{adds will-paginate support to CouchRest}
|
9
|
+
gem.description = %Q{generate views specifically with support for using will_paginate with them}
|
10
|
+
gem.email = "me@samlown.com"
|
11
|
+
gem.homepage = "http://github.com/samlown/will_paginate_couchrest"
|
12
|
+
gem.authors = ["samlown"]
|
13
|
+
gem.add_dependency("couchrest", ">= 0.35")
|
14
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
+
spec.spec_opts = ['--options', "\"spec/spec.opts\""]
|
27
|
+
end
|
28
|
+
|
29
|
+
namespace :spec do
|
30
|
+
desc "Print Specdoc for all specs"
|
31
|
+
Spec::Rake::SpecTask.new(:doc) do |t|
|
32
|
+
t.spec_opts = ["--format", "specdoc", "--dry-run"]
|
33
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
38
|
+
spec.libs << 'lib' << 'spec'
|
39
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
40
|
+
spec.rcov = true
|
41
|
+
spec.rcov_opts = ['--exclude "spec/*,gems/*"']
|
42
|
+
end
|
43
|
+
|
44
|
+
task :spec => :check_dependencies
|
45
|
+
|
46
|
+
task :default => :spec
|
47
|
+
|
48
|
+
require 'rake/rdoctask'
|
49
|
+
Rake::RDocTask.new do |rdoc|
|
50
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
51
|
+
|
52
|
+
rdoc.rdoc_dir = 'rdoc'
|
53
|
+
rdoc.title = "will_paginate_couchrest #{version}"
|
54
|
+
rdoc.rdoc_files.include('README*')
|
55
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
56
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# Based on original validators in CouchRest::Validation
|
2
|
+
require 'couchrest/mixins/validation'
|
3
|
+
|
4
|
+
module CouchRest
|
5
|
+
module Mixins
|
6
|
+
module WillPaginate
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
# Define a CouchDB paginate view. The name of the view will be the concatenation
|
14
|
+
# of <tt>paginate_by</tt> and the keys joined by <tt>_and_</tt>
|
15
|
+
#
|
16
|
+
# ==== Example views:
|
17
|
+
#
|
18
|
+
# class Post
|
19
|
+
# # view with default options
|
20
|
+
# # query with Post.paginate_by_date
|
21
|
+
# paginated_view_by :date, :descending => true
|
22
|
+
#
|
23
|
+
# # view with compound sort-keys
|
24
|
+
# # query with Post.by_user_id_and_date
|
25
|
+
# paginated_view_by :user_id, :date
|
26
|
+
#
|
27
|
+
# # view with custom map/reduce functions
|
28
|
+
# # query with Post.by_tags :reduce => true
|
29
|
+
# paginated_view_by :tags,
|
30
|
+
# :map =>
|
31
|
+
# "function(doc) {
|
32
|
+
# if (doc['couchrest-type'] == 'Post' && doc.tags) {
|
33
|
+
# doc.tags.forEach(function(tag){
|
34
|
+
# emit(doc.tag, 1);
|
35
|
+
# });
|
36
|
+
# }
|
37
|
+
# }",
|
38
|
+
# :reduce =>
|
39
|
+
# "function(keys, values, rereduce) {
|
40
|
+
# return sum(values);
|
41
|
+
# }"
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# <tt>paginated_view_by :date</tt> will create a view defined by this Javascript
|
45
|
+
# function:
|
46
|
+
#
|
47
|
+
# function(doc) {
|
48
|
+
# if (doc['couchrest-type'] == 'Post' && doc.date) {
|
49
|
+
# emit(doc.date, 1);
|
50
|
+
# }
|
51
|
+
# }
|
52
|
+
#
|
53
|
+
# And a standard summing reduce function like the following:
|
54
|
+
#
|
55
|
+
# function(keys, values, rereduce) {
|
56
|
+
# return sum(values);
|
57
|
+
# }
|
58
|
+
#
|
59
|
+
# It can be queried by calling <tt>Post.paginate_by_date</tt> which accepts all
|
60
|
+
# valid options for CouchRest::Database#view. In addition, calling with
|
61
|
+
# the <tt>:raw => true</tt> option will return the view rows
|
62
|
+
# themselves. By default <tt>Post.by_date</tt> will return the
|
63
|
+
# documents included in the generated view.
|
64
|
+
#
|
65
|
+
# For further details on <tt>view_by</tt>'s other options, please see the
|
66
|
+
# standard documentation.
|
67
|
+
|
68
|
+
def paginated_view_by(*keys)
|
69
|
+
|
70
|
+
# Prepare the Traditional view
|
71
|
+
opts = keys.last.is_a?(Hash) ? keys.pop : {}
|
72
|
+
view_name = "by_#{keys.join('_and_')}"
|
73
|
+
method_name = "paginate_#{view_name}"
|
74
|
+
|
75
|
+
doc_keys = keys.collect{|k| "doc['#{k}']"}
|
76
|
+
key_emit = doc_keys.length == 1 ? "#{doc_keys.first}" : "[#{doc_keys.join(', ')}]"
|
77
|
+
guards = opts.delete(:guards) || []
|
78
|
+
guards.push("(doc['couchrest-type'] == '#{self.to_s}')")
|
79
|
+
guards.concat doc_keys
|
80
|
+
|
81
|
+
opts.reverse_merge!(
|
82
|
+
:map => "
|
83
|
+
function( doc ) {
|
84
|
+
if (#{guards.join(' && ')}) {
|
85
|
+
emit(#{key_emit}, 1 );
|
86
|
+
}
|
87
|
+
}
|
88
|
+
",
|
89
|
+
:reduce => "
|
90
|
+
function(keys, values, rereduce) {
|
91
|
+
return sum(values);
|
92
|
+
}
|
93
|
+
"
|
94
|
+
)
|
95
|
+
|
96
|
+
# View prepared, send to traditional view_by
|
97
|
+
view_by keys, opts
|
98
|
+
|
99
|
+
instance_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
100
|
+
def #{method_name}(options = {})
|
101
|
+
paginated_view('#{view_name}', options)
|
102
|
+
end
|
103
|
+
RUBY_EVAL
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
protected
|
109
|
+
|
110
|
+
##
|
111
|
+
# Return a WillPaginate collection suitable for usage
|
112
|
+
#
|
113
|
+
def paginated_view(view_name, options = {})
|
114
|
+
raise "Missing per_page parameter" if options[:per_page].nil?
|
115
|
+
|
116
|
+
options[:page] ||= 1
|
117
|
+
|
118
|
+
::WillPaginate::Collection.create( options[:page], options[:per_page] ) do |pager|
|
119
|
+
# perform view count first (should create designs if missing)
|
120
|
+
total = view( view_name, options.update(:reduce => true) )['rows'].pop
|
121
|
+
pager.total_entries = total ? total['value'] : 0
|
122
|
+
results = paginate(
|
123
|
+
options.merge(
|
124
|
+
:design_doc => self.to_s, :view_name => view_name,
|
125
|
+
:include_docs => true, :reduce => false
|
126
|
+
)
|
127
|
+
)
|
128
|
+
pager.replace( results )
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end # module mixins
|
135
|
+
end # module CouchRest
|
136
|
+
|
137
|
+
|
138
|
+
# Take the liberty of adding ourself to the couchrest library
|
139
|
+
|
140
|
+
module CouchRest
|
141
|
+
class ExtendedDocument < Document
|
142
|
+
include CouchRest::Mixins::WillPaginate
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'couchrest'
|
6
|
+
require 'will_paginate'
|
7
|
+
require 'will_paginate_couchrest'
|
8
|
+
require 'spec'
|
9
|
+
require 'spec/autorun'
|
10
|
+
|
11
|
+
unless defined?(SPEC_COUCH)
|
12
|
+
COUCH_URL = "http://127.0.0.1:5984"
|
13
|
+
COUCH_NAME = 'couchrest-test'
|
14
|
+
|
15
|
+
SPEC_COUCH = CouchRest.database!("#{COUCH_URL}/#{COUCH_NAME}")
|
16
|
+
end
|
17
|
+
|
18
|
+
def reset_test_db!
|
19
|
+
SPEC_COUCH.recreate! rescue nil
|
20
|
+
SPEC_COUCH
|
21
|
+
end
|
22
|
+
|
23
|
+
Spec::Runner.configure do |config|
|
24
|
+
config.before(:all) {
|
25
|
+
reset_test_db!
|
26
|
+
}
|
27
|
+
|
28
|
+
config.after(:all) do
|
29
|
+
SPEC_COUCH.delete! rescue nil
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe CouchRest::Mixins::WillPaginate do
|
4
|
+
|
5
|
+
class SomeDoc < CouchRest::ExtendedDocument
|
6
|
+
use_database SPEC_COUCH
|
7
|
+
|
8
|
+
property :name
|
9
|
+
|
10
|
+
paginated_view_by :name
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should respond to paginated_view_by class method" do
|
14
|
+
SomeDoc.should respond_to :paginated_view_by
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should call view_by method when paginated view_by included" do
|
18
|
+
SomeDoc.should_receive(:view_by)
|
19
|
+
class SomeDoc
|
20
|
+
paginated_view_by :name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should respond to the view and paginated method" do
|
25
|
+
SomeDoc.should respond_to :paginate_by_name
|
26
|
+
# @some_doc.stub(:id).and_return(123)
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "performing pagination with lots of documents" do
|
30
|
+
|
31
|
+
before(:each) do
|
32
|
+
reset_test_db!
|
33
|
+
20.times do |i|
|
34
|
+
txt = "%02d" % i
|
35
|
+
SomeDoc.new(:name => "document #{txt}").save
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should produce a will paginate collection" do
|
40
|
+
docs = SomeDoc.paginate_by_name( :page => 1, :per_page => 5 )
|
41
|
+
docs.class.should eql(::WillPaginate::Collection)
|
42
|
+
docs.total_pages.should eql(4)
|
43
|
+
docs.first.name.should eql('document 00')
|
44
|
+
docs.length.should eql(5)
|
45
|
+
docs.last.name.should eql('document 04')
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should produce second page from paginate collection" do
|
49
|
+
docs = SomeDoc.paginate_by_name( :page => 2, :per_page => 5 )
|
50
|
+
docs.first.name.should eql('document 05')
|
51
|
+
docs.length.should eql(5)
|
52
|
+
docs.last.name.should eql('document 09')
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: will_paginate_couchrest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- samlown
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-03-04 00:00:00 +00:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: couchrest
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0.35"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.9
|
34
|
+
version:
|
35
|
+
description: generate views specifically with support for using will_paginate with them
|
36
|
+
email: me@samlown.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README.rdoc
|
44
|
+
files:
|
45
|
+
- .gitignore
|
46
|
+
- LICENSE
|
47
|
+
- README.rdoc
|
48
|
+
- Rakefile
|
49
|
+
- VERSION
|
50
|
+
- lib/will_paginate_couchrest.rb
|
51
|
+
- spec/spec.opts
|
52
|
+
- spec/spec_helper.rb
|
53
|
+
- spec/will_paginate_couchrest_spec.rb
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/samlown/will_paginate_couchrest
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options:
|
60
|
+
- --charset=UTF-8
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
version:
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
version:
|
75
|
+
requirements: []
|
76
|
+
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 1.3.5
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: adds will-paginate support to CouchRest
|
82
|
+
test_files:
|
83
|
+
- spec/will_paginate_couchrest_spec.rb
|
84
|
+
- spec/spec_helper.rb
|