juozasg-couchrest 0.10.1 → 0.10.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. metadata +6 -101
  2. data/Rakefile +0 -86
  3. data/bin/couchapp +0 -58
  4. data/bin/couchdir +0 -20
  5. data/bin/couchview +0 -48
  6. data/examples/model/example.rb +0 -138
  7. data/examples/word_count/markov +0 -38
  8. data/examples/word_count/views/books/chunked-map.js +0 -3
  9. data/examples/word_count/views/books/united-map.js +0 -1
  10. data/examples/word_count/views/markov/chain-map.js +0 -6
  11. data/examples/word_count/views/markov/chain-reduce.js +0 -7
  12. data/examples/word_count/views/word_count/count-map.js +0 -6
  13. data/examples/word_count/views/word_count/count-reduce.js +0 -3
  14. data/examples/word_count/word_count.rb +0 -67
  15. data/examples/word_count/word_count_query.rb +0 -39
  16. data/lib/couchrest/commands/generate.rb +0 -71
  17. data/lib/couchrest/commands/push.rb +0 -103
  18. data/lib/couchrest/core/database.rb +0 -173
  19. data/lib/couchrest/core/design.rb +0 -89
  20. data/lib/couchrest/core/document.rb +0 -60
  21. data/lib/couchrest/core/model.rb +0 -557
  22. data/lib/couchrest/core/server.rb +0 -51
  23. data/lib/couchrest/core/view.rb +0 -4
  24. data/lib/couchrest/helper/file_manager.rb +0 -317
  25. data/lib/couchrest/helper/pager.rb +0 -103
  26. data/lib/couchrest/helper/streamer.rb +0 -44
  27. data/lib/couchrest/helper/templates/bar.txt +0 -11
  28. data/lib/couchrest/helper/templates/example-map.js +0 -8
  29. data/lib/couchrest/helper/templates/example-reduce.js +0 -10
  30. data/lib/couchrest/helper/templates/index.html +0 -26
  31. data/lib/couchrest/monkeypatches.rb +0 -24
  32. data/lib/couchrest.rb +0 -125
  33. data/spec/couchapp_spec.rb +0 -87
  34. data/spec/couchrest/core/couchrest_spec.rb +0 -191
  35. data/spec/couchrest/core/database_spec.rb +0 -478
  36. data/spec/couchrest/core/design_spec.rb +0 -131
  37. data/spec/couchrest/core/document_spec.rb +0 -96
  38. data/spec/couchrest/core/model_spec.rb +0 -660
  39. data/spec/couchrest/helpers/file_manager_spec.rb +0 -203
  40. data/spec/couchrest/helpers/pager_spec.rb +0 -122
  41. data/spec/couchrest/helpers/streamer_spec.rb +0 -23
  42. data/spec/fixtures/attachments/couchdb.png +0 -0
  43. data/spec/fixtures/attachments/test.html +0 -11
  44. data/spec/fixtures/views/lib.js +0 -3
  45. data/spec/fixtures/views/test_view/lib.js +0 -3
  46. data/spec/fixtures/views/test_view/only-map.js +0 -4
  47. data/spec/fixtures/views/test_view/test-map.js +0 -3
  48. data/spec/fixtures/views/test_view/test-reduce.js +0 -3
  49. data/spec/spec.opts +0 -6
  50. data/spec/spec_helper.rb +0 -14
  51. data/utils/remap.rb +0 -27
@@ -1,317 +0,0 @@
1
- require 'digest/md5'
2
-
3
- module CouchRest
4
- class FileManager
5
- attr_reader :db
6
- attr_accessor :loud
7
-
8
- LANGS = {"rb" => "ruby", "js" => "javascript"}
9
- MIMES = {
10
- "html" => "text/html",
11
- "htm" => "text/html",
12
- "png" => "image/png",
13
- "gif" => "image/gif",
14
- "css" => "text/css",
15
- "js" => "test/javascript"
16
- }
17
- def initialize(dbname, host="http://localhost:5984")
18
- @db = CouchRest.new(host).database(dbname)
19
- end
20
-
21
- def push_directory(push_dir, docid=nil)
22
- docid ||= push_dir.split('/').reverse.find{|part|!part.empty?}
23
-
24
- pushfiles = Dir["#{push_dir}/**/*.*"].collect do |f|
25
- {f.split("#{push_dir}/").last => open(f).read}
26
- end
27
-
28
- return if pushfiles.empty?
29
-
30
- @attachments = {}
31
- @signatures = {}
32
- pushfiles.each do |file|
33
- name = file.keys.first
34
- value = file.values.first
35
- @signatures[name] = md5(value)
36
-
37
- @attachments[name] = {
38
- "data" => value,
39
- "content_type" => MIMES[name.split('.').last]
40
- }
41
- end
42
-
43
- doc = @db.get(docid) rescue nil
44
-
45
- unless doc
46
- say "creating #{docid}"
47
- @db.save({"_id" => docid, "_attachments" => @attachments, "signatures" => @signatures})
48
- return
49
- end
50
-
51
- doc["signatures"] ||= {}
52
- doc["_attachments"] ||= {}
53
- # remove deleted docs
54
- to_be_removed = doc["signatures"].keys.select do |d|
55
- !pushfiles.collect{|p| p.keys.first}.include?(d)
56
- end
57
-
58
- to_be_removed.each do |p|
59
- say "deleting #{p}"
60
- doc["signatures"].delete(p)
61
- doc["_attachments"].delete(p)
62
- end
63
-
64
- # update existing docs:
65
- doc["signatures"].each do |path, sig|
66
- if (@signatures[path] == sig)
67
- say "no change to #{path}. skipping..."
68
- else
69
- say "replacing #{path}"
70
- doc["signatures"][path] = md5(@attachments[path]["data"])
71
- doc["_attachments"][path].delete("stub")
72
- doc["_attachments"][path].delete("length")
73
- doc["_attachments"][path]["data"] = @attachments[path]["data"]
74
- doc["_attachments"][path].merge!({"data" => @attachments[path]["data"]} )
75
- end
76
- end
77
-
78
- # add in new files
79
- new_files = pushfiles.select{|d| !doc["signatures"].keys.include?( d.keys.first) }
80
-
81
- new_files.each do |f|
82
- say "creating #{f}"
83
- path = f.keys.first
84
- content = f.values.first
85
- doc["signatures"][path] = md5(content)
86
-
87
- doc["_attachments"][path] = {
88
- "data" => content,
89
- "content_type" => MIMES[path.split('.').last]
90
- }
91
- end
92
-
93
- begin
94
- @db.save(doc)
95
- rescue Exception => e
96
- say e.message
97
- end
98
- end
99
-
100
- def push_views(view_dir)
101
- designs = {}
102
-
103
- Dir["#{view_dir}/**/*.*"].each do |design_doc|
104
- design_doc_parts = design_doc.split('/')
105
- next if /^lib\..*$/.match design_doc_parts.last
106
- pre_normalized_view_name = design_doc_parts.last.split("-")
107
- view_name = pre_normalized_view_name[0..pre_normalized_view_name.length-2].join("-")
108
-
109
- folder = design_doc_parts[-2]
110
-
111
- designs[folder] ||= {}
112
- designs[folder]["views"] ||= {}
113
- design_lang = design_doc_parts.last.split(".").last
114
- designs[folder]["language"] ||= LANGS[design_lang]
115
-
116
- libs = ""
117
- Dir["#{view_dir}/lib.#{design_lang}"].collect do |global_lib|
118
- libs << open(global_lib).read
119
- libs << "\n"
120
- end
121
- Dir["#{view_dir}/#{folder}/lib.#{design_lang}"].collect do |global_lib|
122
- libs << open(global_lib).read
123
- libs << "\n"
124
- end
125
- if design_doc_parts.last =~ /-map/
126
- designs[folder]["views"]["#{view_name}-map"] ||= {}
127
-
128
- designs[folder]["views"]["#{view_name}-map"]["map"] = read(design_doc, libs)
129
-
130
- designs[folder]["views"]["#{view_name}-reduce"] ||= {}
131
- designs[folder]["views"]["#{view_name}-reduce"]["map"] = read(design_doc, libs)
132
- end
133
-
134
- if design_doc_parts.last =~ /-reduce/
135
- designs[folder]["views"]["#{view_name}-reduce"] ||= {}
136
-
137
- designs[folder]["views"]["#{view_name}-reduce"]["reduce"] = read(design_doc, libs)
138
- end
139
- end
140
-
141
- # cleanup empty maps and reduces
142
- designs.each do |name, props|
143
- props["views"].each do |view, funcs|
144
- next unless view.include?("reduce")
145
- props["views"].delete(view) unless funcs.keys.include?("reduce")
146
- end
147
- end
148
-
149
- designs.each do |k,v|
150
- create_or_update("_design/#{k}", v)
151
- end
152
-
153
- designs
154
- end
155
-
156
- def pull_views(view_dir)
157
- prefix = "_design"
158
- ds = db.documents(:startkey => '#{prefix}/', :endkey => '#{prefix}/ZZZZZZZZZ')
159
- ds['rows'].collect{|r|r['id']}.each do |id|
160
- puts directory = id.split('/').last
161
- FileUtils.mkdir_p(File.join(view_dir,directory))
162
- views = db.get(id)['views']
163
-
164
- vgroups = views.keys.group_by{|k|k.sub(/\-(map|reduce)$/,'')}
165
- vgroups.each do|g,vs|
166
- mapname = vs.find {|v|views[v]["map"]}
167
- if mapname
168
- # save map
169
- mapfunc = views[mapname]["map"]
170
- mapfile = File.join(view_dir, directory, "#{g}-map.js") # todo support non-js views
171
- File.open(mapfile,'w') do |f|
172
- f.write mapfunc
173
- end
174
- end
175
-
176
- reducename = vs.find {|v|views[v]["reduce"]}
177
- if reducename
178
- # save reduce
179
- reducefunc = views[reducename]["reduce"]
180
- reducefile = File.join(view_dir, directory, "#{g}-reduce.js") # todo support non-js views
181
- File.open(reducefile,'w') do |f|
182
- f.write reducefunc
183
- end
184
- end
185
- end
186
- end
187
-
188
- end
189
-
190
- def push_app(appdir, appname)
191
- libs = []
192
- viewdir = File.join(appdir,"views")
193
- attachdir = File.join(appdir,"_attachments")
194
- views, lang = read_design_views(viewdir)
195
-
196
- docid = "_design/#{appname}"
197
- design = @db.get(docid) rescue {}
198
- design['_id'] = docid
199
- design['views'] = views
200
- design['language'] = lang if lang
201
- @db.save(design)
202
- push_directory(attachdir, docid)
203
-
204
- push_fields(appdir, docid)
205
- end
206
-
207
- def push_fields(appdir, docid)
208
- fields = {}
209
- (Dir["#{appdir}/**/*.*"] -
210
- Dir["#{appdir}/views/**/*.*"] -
211
- Dir["#{appdir}/doc.json"] -
212
- Dir["#{appdir}/_attachments/**/*.*"]).each do |file|
213
- farray = file.sub(appdir, '').sub(/^\//,'').split('/')
214
- myfield = fields
215
- while farray.length > 1
216
- front = farray.shift
217
- myfield[front] ||= {}
218
- myfield = myfield[front]
219
- end
220
- fname, fext = farray.shift.split('.')
221
- fguts = File.open(file).read
222
- if fext == 'json'
223
- myfield[fname] = JSON.parse(fguts)
224
- else
225
- myfield[fname] = fguts
226
- end
227
- end
228
- if File.exists?("#{appdir}/doc.json")
229
- default_json = JSON.parse(File.open("#{appdir}/doc.json").read)
230
- end
231
- design = @db.get(docid) rescue {}
232
- design.merge!(fields)
233
- design.merge!(default_json) if default_json
234
- @db.save(design)
235
- end
236
-
237
- # Generate an application in the given directory.
238
- # This is a class method because it doesn't depend on
239
- # specifying a database.
240
- def self.generate_app(app_dir)
241
- FileUtils.mkdir_p(app_dir)
242
- FileUtils.mkdir_p(File.join(app_dir,"_attachments"))
243
- FileUtils.mkdir_p(File.join(app_dir,"views"))
244
- FileUtils.mkdir_p(File.join(app_dir,"foo"))
245
-
246
- {
247
- "index.html" => "_attachments",
248
- 'example-map.js' => "views",
249
- 'example-reduce.js' => "views",
250
- 'bar.txt' => "foo",
251
- }.each do |filename, targetdir|
252
- template = File.join(File.expand_path(File.dirname(__FILE__)), 'templates',filename)
253
- dest = File.join(app_dir,targetdir,filename)
254
- FileUtils.cp(template, dest)
255
- end
256
- end
257
-
258
- private
259
-
260
- def read_design_views(viewdir)
261
- libs = []
262
- language = nil
263
- views = {}
264
- Dir["#{viewdir}/*.*"].each do |viewfile|
265
- view_parts = viewfile.split('/')
266
- viewfile_name = view_parts.last
267
- # example-map.js
268
- viewfile_name_parts = viewfile_name.split('.')
269
- viewfile_ext = viewfile_name_parts.last
270
- view_name_parts = viewfile_name_parts.first.split('-')
271
- func_type = view_name_parts.pop
272
- view_name = view_name_parts.join('-')
273
- contents = File.open(viewfile).read
274
- if /^lib\..*$/.match viewfile_name
275
- libs.push(contents)
276
- else
277
- views[view_name] ||= {}
278
- language = LANGS[viewfile_ext]
279
- views[view_name][func_type] = contents.sub(/(\/\/|#)include-lib/,libs.join("\n"))
280
- end
281
- end
282
- [views, language]
283
- end
284
-
285
- def say words
286
- puts words if @loud
287
- end
288
-
289
- def md5 string
290
- Digest::MD5.hexdigest(string)
291
- end
292
-
293
- def read(file, libs=nil)
294
- st = open(file).read
295
- st.sub!(/(\/\/|#)include-lib/,libs) if libs
296
- st
297
- end
298
-
299
- def create_or_update(id, fields)
300
- existing = @db.get(id) rescue nil
301
-
302
- if existing
303
- updated = existing.merge(fields)
304
- if existing != updated
305
- say "replacing #{id}"
306
- db.save(updated)
307
- else
308
- say "skipping #{id}"
309
- end
310
- else
311
- say "creating #{id}"
312
- db.save(fields.merge({"_id" => id}))
313
- end
314
-
315
- end
316
- end
317
- end
@@ -1,103 +0,0 @@
1
- module CouchRest
2
- class Pager
3
- attr_accessor :db
4
- def initialize db
5
- @db = db
6
- end
7
-
8
- def all_docs(count=100, &block)
9
- startkey = nil
10
- oldend = nil
11
-
12
- while docrows = request_all_docs(count+1, startkey)
13
- startkey = docrows.last['key']
14
- docrows.pop if docrows.length > count
15
- if oldend == startkey
16
- break
17
- end
18
- yield(docrows)
19
- oldend = startkey
20
- end
21
- end
22
-
23
- def key_reduce(view, count=2000, firstkey = nil, lastkey = nil, &block)
24
- # start with no keys
25
- startkey = firstkey
26
- # lastprocessedkey = nil
27
- keepgoing = true
28
-
29
- while keepgoing && viewrows = request_view(view, count, startkey)
30
- startkey = viewrows.first['key']
31
- endkey = viewrows.last['key']
32
-
33
- if (startkey == endkey)
34
- # we need to rerequest to get a bigger page
35
- # so we know we have all the rows for that key
36
- viewrows = @db.view(view, :key => startkey)['rows']
37
- # we need to do an offset thing to find the next startkey
38
- # otherwise we just get stuck
39
- lastdocid = viewrows.last['id']
40
- fornextloop = @db.view(view, :startkey => startkey, :startkey_docid => lastdocid, :count => 2)['rows']
41
-
42
- newendkey = fornextloop.last['key']
43
- if (newendkey == endkey)
44
- keepgoing = false
45
- else
46
- startkey = newendkey
47
- end
48
- rows = viewrows
49
- else
50
- rows = []
51
- for r in viewrows
52
- if (lastkey && r['key'] == lastkey)
53
- keepgoing = false
54
- break
55
- end
56
- break if (r['key'] == endkey)
57
- rows << r
58
- end
59
- startkey = endkey
60
- end
61
-
62
- key = :begin
63
- values = []
64
-
65
- rows.each do |r|
66
- if key != r['key']
67
- # we're on a new key, yield the old first and then reset
68
- yield(key, values) if key != :begin
69
- key = r['key']
70
- values = []
71
- end
72
- # keep accumulating
73
- values << r['value']
74
- end
75
- yield(key, values)
76
-
77
- end
78
- end
79
-
80
- private
81
-
82
- def request_all_docs count, startkey = nil
83
- opts = {}
84
- opts[:count] = count if count
85
- opts[:startkey] = startkey if startkey
86
- results = @db.documents(opts)
87
- rows = results['rows']
88
- rows unless rows.length == 0
89
- end
90
-
91
- def request_view view, count = nil, startkey = nil, endkey = nil
92
- opts = {}
93
- opts[:count] = count if count
94
- opts[:startkey] = startkey if startkey
95
- opts[:endkey] = endkey if endkey
96
-
97
- results = @db.view(view, opts)
98
- rows = results['rows']
99
- rows unless rows.length == 0
100
- end
101
-
102
- end
103
- end
@@ -1,44 +0,0 @@
1
- module CouchRest
2
- class Streamer
3
- attr_accessor :db
4
- def initialize db
5
- @db = db
6
- end
7
-
8
- # Stream a view, yielding one row at a time. Shells out to <tt>curl</tt> to keep RAM usage low when you have millions of rows.
9
- def view name, params = nil, &block
10
- urlst = /^_/.match(name) ? "#{@db.root}/#{name}" : "#{@db.root}/_view/#{name}"
11
- url = CouchRest.paramify_url urlst, params
12
- # puts "stream #{url}"
13
- first = nil
14
- IO.popen("curl --silent #{url}") do |view|
15
- first = view.gets # discard header
16
- while line = view.gets
17
- row = parse_line(line)
18
- block.call row
19
- end
20
- end
21
- parse_first(first)
22
- end
23
-
24
- private
25
-
26
- def parse_line line
27
- return nil unless line
28
- if /(\{.*\}),?/.match(line.chomp)
29
- JSON.parse($1)
30
- end
31
- end
32
-
33
- def parse_first first
34
- return nil unless first
35
- parts = first.split(',')
36
- parts.pop
37
- line = parts.join(',')
38
- JSON.parse("#{line}}")
39
- rescue
40
- nil
41
- end
42
-
43
- end
44
- end
@@ -1,11 +0,0 @@
1
- Couchapp will create a field on your document corresponding to any directories you make within the application directory, with the text of any files found as key/value pairs.
2
-
3
- Also, any files that end in .json will be treated as json rather than text, and put in the corresponding field. Also note that file.json, file.js, or file.txt will be stored under the "file" key, so don't make collisions in the filesystem unless you want unpredictable results.
4
-
5
- Of course you know that the views directory will be treated specially and -map and -reduce files will be mapped to the map and reduce functions. And the _attachments directory will be treated strangely as well.
6
-
7
- doc.json is a special case, it is treated as json and its keys are applied to the document root; eg it does not result in a "doc" field on your design document. If you need a doc field on the design document, you'll have to define it with a doc.json like so: {"doc":"value for doc field"}
8
-
9
- ps: each design document only has one language key: it will be set based on the file extensions in the views directory. CouchDB defaults to Javascript, so that's what you'll get if you don't define any views. You can override it with the doc.json file, but don't say we didn't warn you.
10
-
11
- Oh yeah it's recommended that you delete this file.
@@ -1,8 +0,0 @@
1
- // an example map function, emits the doc id
2
- // and the list of keys it contains
3
-
4
- function(doc) {
5
- var k, keys = []
6
- for (k in doc) keys.push(k);
7
- emit(doc._id, keys);
8
- };
@@ -1,10 +0,0 @@
1
- // example reduce function to count the
2
- // number of rows in a given key range.
3
-
4
- function(keys, values, rereduce) {
5
- if (rereduce) {
6
- return sum(values);
7
- } else {
8
- return values.length;
9
- }
10
- };
@@ -1,26 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Generated CouchApp</title>
5
- <link rel="stylesheet" href="screen.css" type="text/css">
6
- </head>
7
- <body>
8
- <h1>Generated CouchApp</h1>
9
- <ul id="view"></ul>
10
- </body>
11
- <script src="/_utils/script/json2.js"></script>
12
- <script src="/_utils/script/jquery.js?1.2.6"></script>
13
- <script src="/_utils/script/jquery.couch.js?0.8.0"></script>
14
- <script type="text/javascript" charset="utf-8">
15
- $(function() {
16
- var dbname = document.location.href.split('/')[3];
17
- var design = unescape(document.location.href).split('/')[5];
18
- var DB = $.couch.db(dbname);
19
- DB.view(design+"/example",{success: function(json) {
20
- $("#view").html(json.rows.map(function(row) {
21
- return '<li>'+row.key+'</li>';
22
- }).join(''));
23
- }});
24
- });
25
- </script>
26
- </html>
@@ -1,24 +0,0 @@
1
- # This file must be loaded after the JSON gem and any other library that beats up the Time class.
2
- class Time
3
- # This date format sorts lexicographically
4
- # and is compatible with Javascript's <tt>new Date(time_string)</tt> constructor.
5
- # Note this this format stores all dates in UTC so that collation
6
- # order is preserved. (There's no longer a need to set <tt>ENV['TZ'] = 'UTC'</tt>
7
- # in your application.)
8
-
9
- def to_json(options = nil)
10
- u = self.utc
11
- %("#{u.strftime("%Y/%m/%d %H:%M:%S +0000")}")
12
- end
13
-
14
- # Decodes the JSON time format to a UTC time.
15
- # Based on Time.parse from ActiveSupport. ActiveSupport's version
16
- # is more complete, returning a time in your current timezone,
17
- # rather than keeping the time in UTC. YMMV.
18
- # def self.parse string, fallback=nil
19
- # d = DateTime.parse(string).new_offset
20
- # self.utc(d.year, d.month, d.day, d.hour, d.min, d.sec)
21
- # rescue
22
- # fallback
23
- # end
24
- end
data/lib/couchrest.rb DELETED
@@ -1,125 +0,0 @@
1
- # Copyright 2008 J. Chris Anderson
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- require "rubygems"
16
- require 'json'
17
- require 'rest_client'
18
- # require 'extlib'
19
-
20
- $:.unshift File.dirname(__FILE__) unless
21
- $:.include?(File.dirname(__FILE__)) ||
22
- $:.include?(File.expand_path(File.dirname(__FILE__)))
23
-
24
-
25
- require 'couchrest/monkeypatches'
26
-
27
- # = CouchDB, close to the metal
28
- module CouchRest
29
- autoload :Server, 'couchrest/core/server'
30
- autoload :Database, 'couchrest/core/database'
31
- autoload :Document, 'couchrest/core/document'
32
- autoload :Design, 'couchrest/core/design'
33
- autoload :View, 'couchrest/core/view'
34
- autoload :Model, 'couchrest/core/model'
35
- autoload :Pager, 'couchrest/helper/pager'
36
- autoload :FileManager, 'couchrest/helper/file_manager'
37
- autoload :Streamer, 'couchrest/helper/streamer'
38
-
39
- # The CouchRest module methods handle the basic JSON serialization
40
- # and deserialization, as well as query parameters. The module also includes
41
- # some helpers for tasks like instantiating a new Database or Server instance.
42
- class << self
43
-
44
- # todo, make this parse the url and instantiate a Server or Database instance
45
- # depending on the specificity.
46
- def new(*opts)
47
- Server.new(*opts)
48
- end
49
-
50
- def parse url
51
- case url
52
- when /^http:\/\/(.*)\/(.*)\/(.*)/
53
- host = $1
54
- db = $2
55
- docid = $3
56
- when /^http:\/\/(.*)\/(.*)/
57
- host = $1
58
- db = $2
59
- when /^http:\/\/(.*)/
60
- host = $1
61
- when /(.*)\/(.*)\/(.*)/
62
- host = $1
63
- db = $2
64
- docid = $3
65
- when /(.*)\/(.*)/
66
- host = $1
67
- db = $2
68
- else
69
- db = url
70
- end
71
-
72
- db = nil if db && db.empty?
73
-
74
- {
75
- :host => host || "localhost:5984",
76
- :database => db,
77
- :doc => docid
78
- }
79
- end
80
-
81
- # ensure that a database exists
82
- # creates it if it isn't already there
83
- # returns it after it's been created
84
- def database! url
85
- parsed = parse url
86
- cr = CouchRest.new(parsed[:host])
87
- cr.database!(parsed[:database])
88
- end
89
-
90
- def database url
91
- parsed = parse url
92
- cr = CouchRest.new(parsed[:host])
93
- cr.database(parsed[:database])
94
- end
95
-
96
- def put uri, doc = nil
97
- payload = doc.to_json if doc
98
- JSON.parse(RestClient.put(uri, payload))
99
- end
100
-
101
- def get uri
102
- JSON.parse(RestClient.get(uri), :max_nesting => false)
103
- end
104
-
105
- def post uri, doc = nil
106
- payload = doc.to_json if doc
107
- JSON.parse(RestClient.post(uri, payload))
108
- end
109
-
110
- def delete uri
111
- JSON.parse(RestClient.delete(uri))
112
- end
113
-
114
- def paramify_url url, params = {}
115
- if params && !params.empty?
116
- query = params.collect do |k,v|
117
- v = v.to_json if %w{key startkey endkey}.include?(k.to_s)
118
- "#{k}=#{CGI.escape(v.to_s)}"
119
- end.join("&")
120
- url = "#{url}?#{query}"
121
- end
122
- url
123
- end
124
- end # class << self
125
- end