couch-client 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -2
- data/Manifest +12 -0
- data/README.markdown +30 -22
- data/couch-client.gemspec +4 -4
- data/lib/couch-client.rb +1 -1
- data/lib/couch-client/attachment.rb +16 -1
- data/lib/couch-client/hookup.rb +8 -5
- data/lib/couch-client/rake_task.rb +181 -0
- data/spec/attachment_spec.rb +15 -3
- data/spec/designs/create/people/fulltext/by_name/index.js +5 -0
- data/spec/designs/create/people/validate_on_update.js +6 -0
- data/spec/designs/create/people/views/all/map.js +3 -0
- data/spec/designs/create/people/views/sum/map.js +3 -0
- data/spec/designs/create/people/views/sum/reduce.js +3 -0
- data/spec/designs/update/people/fulltext/by_name/index.js +6 -0
- data/spec/designs/update/people/validate_on_update.js +9 -0
- data/spec/designs/update/people/views/sum/map.js +3 -0
- data/spec/designs/update/people/views/sum/reduce.js +3 -0
- data/spec/rake_task_spec.rb +78 -0
- metadata +16 -4
data/CHANGELOG
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
v0.1.1. Fixing Manifest contents and adding Rails information to README.
|
2
|
+
|
1
3
|
v0.1.0. Adding rake tasks to sync and manage database functions and design documents. Also added support for list and show functions; as well as fulltext administration.
|
2
4
|
|
3
|
-
v0.0.2. Fixing gemspec
|
5
|
+
v0.0.2. Fixing gemspec.
|
4
6
|
|
5
|
-
v0.0.1. First release
|
7
|
+
v0.0.1. First release.
|
data/Manifest
CHANGED
@@ -4,6 +4,7 @@ Manifest
|
|
4
4
|
README.markdown
|
5
5
|
Rakefile
|
6
6
|
TODO
|
7
|
+
couch-client.gemspec
|
7
8
|
lib/couch-client.rb
|
8
9
|
lib/couch-client/attachment.rb
|
9
10
|
lib/couch-client/attachment_list.rb
|
@@ -15,6 +16,7 @@ lib/couch-client/database.rb
|
|
15
16
|
lib/couch-client/design.rb
|
16
17
|
lib/couch-client/document.rb
|
17
18
|
lib/couch-client/hookup.rb
|
19
|
+
lib/couch-client/rake_task.rb
|
18
20
|
lib/couch-client/row.rb
|
19
21
|
spec/attachment_list_spec.rb
|
20
22
|
spec/attachment_spec.rb
|
@@ -25,9 +27,19 @@ spec/consistent_hash_spec.rb
|
|
25
27
|
spec/couch-client_spec.rb
|
26
28
|
spec/database_spec.rb
|
27
29
|
spec/design_spec.rb
|
30
|
+
spec/designs/create/people/fulltext/by_name/index.js
|
31
|
+
spec/designs/create/people/validate_on_update.js
|
32
|
+
spec/designs/create/people/views/all/map.js
|
33
|
+
spec/designs/create/people/views/sum/map.js
|
34
|
+
spec/designs/create/people/views/sum/reduce.js
|
35
|
+
spec/designs/update/people/fulltext/by_name/index.js
|
36
|
+
spec/designs/update/people/validate_on_update.js
|
37
|
+
spec/designs/update/people/views/sum/map.js
|
38
|
+
spec/designs/update/people/views/sum/reduce.js
|
28
39
|
spec/document_spec.rb
|
29
40
|
spec/files/image.png
|
30
41
|
spec/files/plain.txt
|
31
42
|
spec/hookup_spec.rb
|
43
|
+
spec/rake_task_spec.rb
|
32
44
|
spec/row_spec.rb
|
33
45
|
spec/spec_helper.rb
|
data/README.markdown
CHANGED
@@ -69,7 +69,7 @@ Working with a Document
|
|
69
69
|
-----------------------
|
70
70
|
|
71
71
|
# Building new documents
|
72
|
-
# Couch.build({:name => "alice"})
|
72
|
+
# person = Couch.build({:name => "alice"})
|
73
73
|
|
74
74
|
# Getting and setting fields (with indifferent access and value "stringification")
|
75
75
|
# person[:name] # => "alice"
|
@@ -116,16 +116,15 @@ Working with Collections
|
|
116
116
|
------------------------
|
117
117
|
|
118
118
|
# Getting all documents
|
119
|
-
Couch.all_docs
|
120
|
-
# {"id"=>"7f22af967b04d1b88212d3d26b018e89", "key"=>"7f22af967b04d1b88212d3d26b018e89", "value"=>{"rev"=>"3-3a635c1a2b5a8ff94bb5d63eee3cd6ef"}}]
|
119
|
+
Couch.all_docs
|
121
120
|
|
122
121
|
# Getting all documents with document fields
|
123
122
|
Couch.all_docs(:include_docs => true)
|
124
123
|
|
125
124
|
# Specifying a `key`, `startkey` or `endkey`
|
126
|
-
|
127
|
-
|
128
|
-
|
125
|
+
Couch.all_docs(:key => "7f22af967b04d1b88212d3d26b018e89")
|
126
|
+
Couch.all_docs(:startkey => 200)
|
127
|
+
Couch.all_docs(:endkey => [2010, 01, 01])
|
129
128
|
|
130
129
|
# Getting additional collection information
|
131
130
|
Couch.all_docs.info # => {"total_rows" => 2, "offset" => 0}
|
@@ -133,36 +132,36 @@ Working with Collections
|
|
133
132
|
Using Design Documents
|
134
133
|
----------------------
|
135
134
|
|
136
|
-
# Map
|
137
|
-
Couch.design(:people).view(:all)
|
138
|
-
|
135
|
+
# Map views
|
136
|
+
Couch.design(:people).view(:all)
|
137
|
+
|
138
|
+
# Map views with a key
|
139
|
+
Couch.design(:people).view(:by_sex, :key => "male")
|
139
140
|
|
140
|
-
# MapReduce
|
141
|
-
Couch.design(:people).view(:sum)
|
141
|
+
# MapReduce views
|
142
|
+
Couch.design(:people).view(:sum)
|
142
143
|
|
143
144
|
Using Show and List Functions
|
144
145
|
-----------------------------
|
145
146
|
|
146
|
-
# Show
|
147
|
-
Couch.design(:people).show(:html) # => "<h1>alice</h1>"
|
148
|
-
Couch.design(:people).show(:json) # => {"name" => "alice"}
|
147
|
+
# Show functions
|
148
|
+
Couch.design(:people).show(:html, "7f22af967b04d1b88212d3d26b018e89") # => "<h1>alice</h1>"
|
149
|
+
Couch.design(:people).show(:json, "7f22af967b04d1b88212d3d26b018e89") # => {"name" => "alice"}
|
149
150
|
|
150
|
-
# List
|
151
|
+
# List functions
|
151
152
|
Couch.design(:people).list(:json, :people, :all) # => ["alice", "bob", "charlie"]
|
152
153
|
|
153
154
|
Using FullText Search (Must Have CouchDB-Lucene Installed)
|
154
155
|
----------------------------------------------------------
|
155
156
|
|
156
157
|
# Getting search results
|
157
|
-
Couch.design(:people).fulltext(:by_name, :q => "ali*")
|
158
|
+
Couch.design(:people).fulltext(:by_name, :q => "ali*")
|
158
159
|
|
159
160
|
# Getting additional search results information
|
160
|
-
Couch.design(:people).fulltext(:by_name, :q => "ali*").info
|
161
|
-
# "total_rows"=>7, "search_duration"=>0, "fetch_duration"=>1}
|
161
|
+
Couch.design(:people).fulltext(:by_name, :q => "ali*").info
|
162
162
|
|
163
163
|
# Getting search index information
|
164
|
-
Couch.design(:people).fulltext(:by_name)
|
165
|
-
# "last_modified"=>"1288403429000", "optimized"=>false, "ref_count"=>2}
|
164
|
+
Couch.design(:people).fulltext(:by_name)
|
166
165
|
|
167
166
|
# Optimizing an index
|
168
167
|
Couch.design(:people).fulltext(:by_name, :optimize) # => true
|
@@ -180,6 +179,17 @@ CouchClient rake tasks can be enabled by adding the following to your `Rakefile`
|
|
180
179
|
c.design_path = "./designs"
|
181
180
|
end
|
182
181
|
|
182
|
+
Or you can add CouchClient rake tasks to your rails app by making the following file in `lib/tasks/couch.rake`.
|
183
|
+
|
184
|
+
require "#{Rails.root}/config/environment"
|
185
|
+
|
186
|
+
CouchClient::RakeTask.new do |c|
|
187
|
+
c.connection = Couch
|
188
|
+
c.design_path = "./app/designs"
|
189
|
+
end
|
190
|
+
|
191
|
+
You can then specify your CouchClient settings for each each environment in their respective configuration files (e.g. development.rb, test.rb and production.rb).
|
192
|
+
|
183
193
|
Two parameters are available, `connection` should be the actual variable used for your CouchDB interface and `design_path` should be the application's location where design documents will be stored.
|
184
194
|
|
185
195
|
Within the design path, you should format each design document with folders and files corresponding to the fields in your design document.
|
@@ -246,5 +256,3 @@ Performing Database Administration
|
|
246
256
|
# Delete the database
|
247
257
|
Couch.databse.delete!
|
248
258
|
|
249
|
-
|
250
|
-
|
data/couch-client.gemspec
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{couch-client}
|
5
|
-
s.version = "0.1.
|
5
|
+
s.version = "0.1.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Robert Sosinski"]
|
9
|
-
s.date = %q{2010-11-
|
9
|
+
s.date = %q{2010-11-11}
|
10
10
|
s.description = %q{A Ruby interface for CouchDB}
|
11
11
|
s.email = %q{email@robertsosinski.com}
|
12
|
-
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.markdown", "TODO", "lib/couch-client.rb", "lib/couch-client/attachment.rb", "lib/couch-client/attachment_list.rb", "lib/couch-client/collection.rb", "lib/couch-client/connection.rb", "lib/couch-client/connection_handler.rb", "lib/couch-client/consistent_hash.rb", "lib/couch-client/database.rb", "lib/couch-client/design.rb", "lib/couch-client/document.rb", "lib/couch-client/hookup.rb", "lib/couch-client/row.rb"]
|
13
|
-
s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.markdown", "Rakefile", "TODO", "lib/couch-client.rb", "lib/couch-client/attachment.rb", "lib/couch-client/attachment_list.rb", "lib/couch-client/collection.rb", "lib/couch-client/connection.rb", "lib/couch-client/connection_handler.rb", "lib/couch-client/consistent_hash.rb", "lib/couch-client/database.rb", "lib/couch-client/design.rb", "lib/couch-client/document.rb", "lib/couch-client/hookup.rb", "lib/couch-client/row.rb", "spec/attachment_list_spec.rb", "spec/attachment_spec.rb", "spec/collection_spec.rb", "spec/conection_handler_spec.rb", "spec/connection_spec.rb", "spec/consistent_hash_spec.rb", "spec/couch-client_spec.rb", "spec/database_spec.rb", "spec/design_spec.rb", "spec/document_spec.rb", "spec/files/image.png", "spec/files/plain.txt", "spec/hookup_spec.rb", "spec/
|
12
|
+
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.markdown", "TODO", "lib/couch-client.rb", "lib/couch-client/attachment.rb", "lib/couch-client/attachment_list.rb", "lib/couch-client/collection.rb", "lib/couch-client/connection.rb", "lib/couch-client/connection_handler.rb", "lib/couch-client/consistent_hash.rb", "lib/couch-client/database.rb", "lib/couch-client/design.rb", "lib/couch-client/document.rb", "lib/couch-client/hookup.rb", "lib/couch-client/rake_task.rb", "lib/couch-client/row.rb"]
|
13
|
+
s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.markdown", "Rakefile", "TODO", "couch-client.gemspec", "lib/couch-client.rb", "lib/couch-client/attachment.rb", "lib/couch-client/attachment_list.rb", "lib/couch-client/collection.rb", "lib/couch-client/connection.rb", "lib/couch-client/connection_handler.rb", "lib/couch-client/consistent_hash.rb", "lib/couch-client/database.rb", "lib/couch-client/design.rb", "lib/couch-client/document.rb", "lib/couch-client/hookup.rb", "lib/couch-client/rake_task.rb", "lib/couch-client/row.rb", "spec/attachment_list_spec.rb", "spec/attachment_spec.rb", "spec/collection_spec.rb", "spec/conection_handler_spec.rb", "spec/connection_spec.rb", "spec/consistent_hash_spec.rb", "spec/couch-client_spec.rb", "spec/database_spec.rb", "spec/design_spec.rb", "spec/designs/create/people/fulltext/by_name/index.js", "spec/designs/create/people/validate_on_update.js", "spec/designs/create/people/views/all/map.js", "spec/designs/create/people/views/sum/map.js", "spec/designs/create/people/views/sum/reduce.js", "spec/designs/update/people/fulltext/by_name/index.js", "spec/designs/update/people/validate_on_update.js", "spec/designs/update/people/views/sum/map.js", "spec/designs/update/people/views/sum/reduce.js", "spec/document_spec.rb", "spec/files/image.png", "spec/files/plain.txt", "spec/hookup_spec.rb", "spec/rake_task_spec.rb", "spec/row_spec.rb", "spec/spec_helper.rb"]
|
14
14
|
s.homepage = %q{http://github.com/robertsosinski/couch-client}
|
15
15
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Couch-client", "--main", "README.markdown"]
|
16
16
|
s.require_paths = ["lib"]
|
data/lib/couch-client.rb
CHANGED
@@ -11,7 +11,7 @@ require 'couch-client/attachment'
|
|
11
11
|
require 'couch-client/design'
|
12
12
|
require 'couch-client/collection'
|
13
13
|
require 'couch-client/row'
|
14
|
-
require
|
14
|
+
require 'couch-client/rake_task' if defined?(Rake)
|
15
15
|
|
16
16
|
# The CouchClient module is the overall container of all CouchClient logic.
|
17
17
|
module CouchClient
|
@@ -1,4 +1,6 @@
|
|
1
1
|
module CouchClient
|
2
|
+
class AttachmentNotFound < Exception; end
|
3
|
+
|
2
4
|
# Attachment is an extended Hash that provides additional methods
|
3
5
|
# to interact with attached files saved within a document.
|
4
6
|
class Attachment < ConsistentHash
|
@@ -26,7 +28,20 @@ module CouchClient
|
|
26
28
|
|
27
29
|
# Returns a string that contains attachment data
|
28
30
|
def data
|
29
|
-
@data
|
31
|
+
return @data if @data # Return data if it has been memoized
|
32
|
+
|
33
|
+
code, @data = @connection.hookup.get([@id, @name], nil, self["content_type"])
|
34
|
+
|
35
|
+
case code
|
36
|
+
when 200
|
37
|
+
@data # Return data if the attachment is found
|
38
|
+
when 404
|
39
|
+
# Raise an error if the attachment is not found
|
40
|
+
raise AttachmentNotFound.new("attachment '#{@name}' could not be found for document '#{@id}'")
|
41
|
+
else
|
42
|
+
# Also raise an error if something else happens
|
43
|
+
raise Error.new("code: #{code}, error: #{@data["error"]}, reason: #{@data["reason"]}")
|
44
|
+
end
|
30
45
|
end
|
31
46
|
end
|
32
47
|
end
|
data/lib/couch-client/hookup.rb
CHANGED
@@ -4,7 +4,6 @@ require 'json'
|
|
4
4
|
module CouchClient
|
5
5
|
class InvalidHTTPVerb < Exception; end
|
6
6
|
class InvalidJSONData < Exception; end
|
7
|
-
class SymbolUsedInField < Exception; end
|
8
7
|
|
9
8
|
# Hookup is the basic HTTP interface that connects CouchClient to CouchDB.
|
10
9
|
# Hookup can use any HTTP library if the conventions listed below are followed.
|
@@ -87,14 +86,18 @@ module CouchClient
|
|
87
86
|
# code is the http code (e.g. 200 or 404)
|
88
87
|
code = easy.response_code
|
89
88
|
|
90
|
-
# body is either a nil, a hash or a string containing attachment data
|
91
|
-
body = if
|
89
|
+
# body is either a nil, a hash or a string containing attachment data.
|
90
|
+
body = if verb == :head
|
91
|
+
# Head requests should return `nil`.
|
92
92
|
nil
|
93
|
-
|
93
|
+
# If the response is not a 200, then it must be JSON (as CouchDB returns all feedback as JSON), so parse it.
|
94
|
+
# If the response is a 200, it may not be JSON (if it is an attachment), therefore check the content type before parsing.
|
95
|
+
elsif code != 200 || [content_type, easy.content_type].include?("application/json")
|
94
96
|
begin
|
95
97
|
JSON.parse(easy.body_str)
|
96
98
|
rescue
|
97
|
-
|
99
|
+
# Raise an error of the JSON returned is malformed.
|
100
|
+
raise InvalidJSONData.new("data received is not valid JSON")
|
98
101
|
end
|
99
102
|
else
|
100
103
|
easy.body_str
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
require 'set'
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
module CouchClient
|
7
|
+
# RakeTask is a namespace for all Rake tasks that are bundled with
|
8
|
+
# CouchClient, such as database creation, sync, compaction and deletion.
|
9
|
+
class RakeTask < ::Rake::TaskLib
|
10
|
+
class MissingCouchClientConnection < Exception; end
|
11
|
+
|
12
|
+
attr_accessor :connection, :design_path
|
13
|
+
|
14
|
+
# Start using CouchClient::RakeTask by constructing a new instance with a block.
|
15
|
+
#
|
16
|
+
# CouchClient::RakeTask.new do |c|
|
17
|
+
# c.connection = Couch
|
18
|
+
# c.design_path = "./app/designs"
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# CouchClient::RakeTask.new takes the following options.
|
22
|
+
#
|
23
|
+
# connection: A CouchClient Connection, default being `Couch`.
|
24
|
+
# design_path: The path where design documents are stored, default being "./designs".
|
25
|
+
def initialize(&block)
|
26
|
+
instance_eval(&block) if block_given?
|
27
|
+
|
28
|
+
begin
|
29
|
+
@connection ||= Object.const_get("Couch")
|
30
|
+
rescue NameError
|
31
|
+
raise MissingCouchClientConnection.new("specify a CouchClient connection within your RakeTask setup.")
|
32
|
+
end
|
33
|
+
|
34
|
+
@design_path = Pathname.new(@design_path || './designs')
|
35
|
+
|
36
|
+
# Create Rake tasks.
|
37
|
+
namespace :couch do
|
38
|
+
desc "Syncs design documents with the database."
|
39
|
+
task :sync do
|
40
|
+
sync
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "Creates the database."
|
44
|
+
task :create do
|
45
|
+
create
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "Deletes the database and all its data."
|
49
|
+
task :delete do
|
50
|
+
delete
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "Compacts the database."
|
54
|
+
task :compact do
|
55
|
+
compact
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def sync
|
61
|
+
# Fetch all design documents that are cuurently saved in the database.
|
62
|
+
saved_design_docs = @connection.all_design_docs("include_docs" => true)
|
63
|
+
local_design_docs = {}
|
64
|
+
|
65
|
+
design_path_depth = design_path.to_s.count("/") + 1
|
66
|
+
|
67
|
+
# Recurse though the design directory and construct a hash of design functions.
|
68
|
+
recurser = lambda do |path|
|
69
|
+
path_breadcrumbs = path.to_s.match("[^\.]+")[0].split("/")[design_path_depth..-1] # e.g. ["people", "views", "all", "map"]
|
70
|
+
path_hash_follow = path_breadcrumbs.reduce(""){|memo, key| memo + "['#{key}']"} # e.g. ['people']['views']['all']['map']
|
71
|
+
|
72
|
+
if path.directory?
|
73
|
+
# Set an empty hash for the directory.
|
74
|
+
eval("local_design_docs#{path_hash_follow} = {}")
|
75
|
+
|
76
|
+
# Reject hidden filenames (filesnames that begin with a ".").
|
77
|
+
path.children.reject{|p| p.basename.to_s.match(/^\./)}.each do |child|
|
78
|
+
# Continue recursion.
|
79
|
+
recurser.call(child)
|
80
|
+
end
|
81
|
+
else
|
82
|
+
# Set a field with design function data.
|
83
|
+
eval("local_design_docs#{path_hash_follow} = #{path.read.inspect}")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
recurser.call(@design_path)
|
88
|
+
|
89
|
+
# Get a set of id's that are currently saved and a set that are avaiable locally.
|
90
|
+
saved_ids = saved_design_docs.map{|doc| doc["id"].gsub(/^_design\//, "")}.to_set
|
91
|
+
local_ids = local_design_docs.keys.to_set
|
92
|
+
|
93
|
+
doc_ids_to_create = local_ids.difference(saved_ids).to_a
|
94
|
+
doc_ids_to_update = saved_ids.intersection(local_ids).to_a
|
95
|
+
doc_ids_to_delete = saved_ids.difference(local_ids).to_a
|
96
|
+
|
97
|
+
# Create any new design documents.
|
98
|
+
doc_ids_to_create.each do |id|
|
99
|
+
new_doc = @connection.build
|
100
|
+
new_doc.id = "_design/#{id}"
|
101
|
+
new_doc.merge!(local_design_docs[id])
|
102
|
+
new_doc.merge!({"language" => "javascript"})
|
103
|
+
|
104
|
+
if new_doc.save
|
105
|
+
puts "Creating: #{new_doc.id} -- #{new_doc.rev}"
|
106
|
+
else
|
107
|
+
puts "Failure: #{new_doc.id} -- #{new_doc.error.inspect}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Construct design documents that already exist.
|
112
|
+
doc_ids_to_update.each do |id|
|
113
|
+
old_doc = saved_design_docs.detect{|d| d["id"] == "_design/#{id}"}["doc"]
|
114
|
+
|
115
|
+
new_doc = @connection.build
|
116
|
+
new_doc.id = old_doc.id
|
117
|
+
new_doc.rev = old_doc.rev
|
118
|
+
new_doc.merge!(local_design_docs[id])
|
119
|
+
new_doc.merge!({"language" => "javascript"})
|
120
|
+
|
121
|
+
# If the new document is the same as what is on the server
|
122
|
+
if old_doc == new_doc
|
123
|
+
# Keep the old design document.
|
124
|
+
puts "Keeping: #{new_doc.id} -- #{new_doc.rev}"
|
125
|
+
else
|
126
|
+
# Else save the new design docuemnt.
|
127
|
+
if new_doc.save
|
128
|
+
puts "Updating: #{new_doc.id} -- #{new_doc.rev}"
|
129
|
+
else
|
130
|
+
puts "Failure: #{new_doc.id} -- #{new_doc.error.inspect}"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Delete any documents that are not available locally.
|
136
|
+
doc_ids_to_delete.each do |id|
|
137
|
+
old_doc = saved_design_docs.detect{|d| d["id"] == "_design/#{id}"}["doc"]
|
138
|
+
|
139
|
+
if old_doc.delete!
|
140
|
+
puts "Deleting: #{old_doc.id} -- #{old_doc.rev}"
|
141
|
+
else
|
142
|
+
puts "Failure: #{old_doc.id} -- #{new_doc.error.inspect}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def create
|
148
|
+
resp = @connection.database.create
|
149
|
+
if resp["ok"]
|
150
|
+
puts "Created."
|
151
|
+
else
|
152
|
+
puts "The database could not be created, the file already exists."
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def delete
|
157
|
+
resp = @connection.database.delete!
|
158
|
+
|
159
|
+
if resp["ok"]
|
160
|
+
puts "Deleted."
|
161
|
+
else
|
162
|
+
puts "The database could not be deleted, the file does not exist."
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def compact
|
167
|
+
resp = @connection.database.compact!
|
168
|
+
|
169
|
+
if resp["ok"]
|
170
|
+
puts "Compaction Complete."
|
171
|
+
else
|
172
|
+
utils_uri = lambda{
|
173
|
+
handler = handler = @connection.hookup.handler
|
174
|
+
handler.uri.gsub(/#{handler.database}$/, "_utils")
|
175
|
+
}.call
|
176
|
+
|
177
|
+
puts "The database could not be compacted, see #{utils_uri} for more information."
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
data/spec/attachment_spec.rb
CHANGED
@@ -25,9 +25,17 @@ describe CouchClient::Attachment do
|
|
25
25
|
|
26
26
|
@alice.attach("plain.txt", @plain, "text/plain")
|
27
27
|
@alice.attach("image.png", @image, "image/png")
|
28
|
+
@alice.attach("missing", @plain, "text/plain") # will be deleted
|
28
29
|
|
29
|
-
@
|
30
|
-
|
30
|
+
@alice = @alice.saved_doc
|
31
|
+
|
32
|
+
@attachment_plain = @alice.attachments["plain.txt"]
|
33
|
+
@attachment_image = @alice.attachments["image.png"]
|
34
|
+
|
35
|
+
@attachment_missing = @alice.attachments["missing"]
|
36
|
+
|
37
|
+
@alice.attachments.delete("missing")
|
38
|
+
@alice.save
|
31
39
|
end
|
32
40
|
|
33
41
|
after(:all) do
|
@@ -48,10 +56,14 @@ describe CouchClient::Attachment do
|
|
48
56
|
end
|
49
57
|
end
|
50
58
|
|
51
|
-
describe '#
|
59
|
+
describe '#data' do
|
52
60
|
it 'should yield the file for the attachment as a string' do
|
53
61
|
@digest.call(@attachment_plain.data).should eql(@plain_digest)
|
54
62
|
@digest.call(@attachment_image.data).should eql(@image_digest)
|
55
63
|
end
|
64
|
+
|
65
|
+
it 'should raise an error if the attachment is not found' do
|
66
|
+
lambda{@attachment_missing.data}.should raise_error(CouchClient::AttachmentNotFound)
|
67
|
+
end
|
56
68
|
end
|
57
69
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
|
+
|
3
|
+
describe CouchClient::RakeTask do
|
4
|
+
before(:all) do
|
5
|
+
Couch = CouchClient.connect(COUCHDB_TEST_SETTINGS)
|
6
|
+
|
7
|
+
@task = CouchClient::RakeTask.new do |t|
|
8
|
+
t.connection = Couch
|
9
|
+
# t.design_path = "./spec/designs"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#sync' do
|
14
|
+
before(:all) do
|
15
|
+
Couch.database.create
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:all) do
|
19
|
+
Couch.database.delete!
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should create a new design document' do
|
23
|
+
@task.design_path = Pathname("./spec/designs/create")
|
24
|
+
|
25
|
+
lambda{Couch["_design/people"]}.should raise_error(CouchClient::DocumentNotFound)
|
26
|
+
|
27
|
+
suppress{@task.sync}
|
28
|
+
|
29
|
+
@doc = Couch["_design/people"]
|
30
|
+
@doc.code.should eql(200)
|
31
|
+
@rev = @doc.rev
|
32
|
+
@rev[0].should eql("1")
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should update an existing design document' do
|
36
|
+
@task.design_path = Pathname("./spec/designs/update")
|
37
|
+
|
38
|
+
suppress{@task.sync}
|
39
|
+
|
40
|
+
@doc = Couch["_design/people"]
|
41
|
+
@doc.code.should eql(200)
|
42
|
+
@doc.rev.should_not eql(@rev)
|
43
|
+
@doc.rev[0].should eql("2")
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should delete a missing design document' do
|
47
|
+
@task.design_path = Pathname("./spec/designs/delete")
|
48
|
+
|
49
|
+
suppress{@task.sync}
|
50
|
+
|
51
|
+
lambda{Couch["_design/people"]}.should raise_error(CouchClient::DocumentNotFound)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#create, #compact, #delete' do
|
56
|
+
describe '#create' do
|
57
|
+
it 'should create a new database' do
|
58
|
+
Couch.database.exists?.should be_false
|
59
|
+
suppress{@task.create}
|
60
|
+
Couch.database.exists?.should be_true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#compact' do
|
65
|
+
it 'should compact a database' do
|
66
|
+
suppress{@task.compact}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#delete' do
|
71
|
+
it 'should delete a database' do
|
72
|
+
Couch.database.exists?.should be_true
|
73
|
+
suppress{@task.delete}
|
74
|
+
Couch.database.exists?.should be_false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Robert Sosinski
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-11-
|
17
|
+
date: 2010-11-11 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -99,6 +99,7 @@ extra_rdoc_files:
|
|
99
99
|
- lib/couch-client/design.rb
|
100
100
|
- lib/couch-client/document.rb
|
101
101
|
- lib/couch-client/hookup.rb
|
102
|
+
- lib/couch-client/rake_task.rb
|
102
103
|
- lib/couch-client/row.rb
|
103
104
|
files:
|
104
105
|
- CHANGELOG
|
@@ -107,6 +108,7 @@ files:
|
|
107
108
|
- README.markdown
|
108
109
|
- Rakefile
|
109
110
|
- TODO
|
111
|
+
- couch-client.gemspec
|
110
112
|
- lib/couch-client.rb
|
111
113
|
- lib/couch-client/attachment.rb
|
112
114
|
- lib/couch-client/attachment_list.rb
|
@@ -118,6 +120,7 @@ files:
|
|
118
120
|
- lib/couch-client/design.rb
|
119
121
|
- lib/couch-client/document.rb
|
120
122
|
- lib/couch-client/hookup.rb
|
123
|
+
- lib/couch-client/rake_task.rb
|
121
124
|
- lib/couch-client/row.rb
|
122
125
|
- spec/attachment_list_spec.rb
|
123
126
|
- spec/attachment_spec.rb
|
@@ -128,13 +131,22 @@ files:
|
|
128
131
|
- spec/couch-client_spec.rb
|
129
132
|
- spec/database_spec.rb
|
130
133
|
- spec/design_spec.rb
|
134
|
+
- spec/designs/create/people/fulltext/by_name/index.js
|
135
|
+
- spec/designs/create/people/validate_on_update.js
|
136
|
+
- spec/designs/create/people/views/all/map.js
|
137
|
+
- spec/designs/create/people/views/sum/map.js
|
138
|
+
- spec/designs/create/people/views/sum/reduce.js
|
139
|
+
- spec/designs/update/people/fulltext/by_name/index.js
|
140
|
+
- spec/designs/update/people/validate_on_update.js
|
141
|
+
- spec/designs/update/people/views/sum/map.js
|
142
|
+
- spec/designs/update/people/views/sum/reduce.js
|
131
143
|
- spec/document_spec.rb
|
132
144
|
- spec/files/image.png
|
133
145
|
- spec/files/plain.txt
|
134
146
|
- spec/hookup_spec.rb
|
147
|
+
- spec/rake_task_spec.rb
|
135
148
|
- spec/row_spec.rb
|
136
149
|
- spec/spec_helper.rb
|
137
|
-
- couch-client.gemspec
|
138
150
|
has_rdoc: true
|
139
151
|
homepage: http://github.com/robertsosinski/couch-client
|
140
152
|
licenses: []
|