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 ADDED
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ *.gemspec
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
@@ -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