ibm_sbdtc_rest 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +18 -0
- data/Rakefile +66 -0
- data/VERSION +1 -0
- data/bin/ibmcloud_admin +76 -0
- data/lib/ibm_cloud_rest/core/adapters/restclient.rb +45 -0
- data/lib/ibm_cloud_rest/core/address.rb +0 -0
- data/lib/ibm_cloud_rest/core/database.rb +328 -0
- data/lib/ibm_cloud_rest/core/http_abstraction.rb +48 -0
- data/lib/ibm_cloud_rest/core/image.rb +0 -0
- data/lib/ibm_cloud_rest/core/instance.rb +0 -0
- data/lib/ibm_cloud_rest/core/key.rb +0 -0
- data/lib/ibm_cloud_rest/core/request.rb +0 -0
- data/lib/ibm_cloud_rest/core/rest_api.rb +49 -0
- data/lib/ibm_cloud_rest/core/server.rb +88 -0
- data/lib/ibm_cloud_rest/core/storage.rb +0 -0
- data/lib/ibm_cloud_rest/mixins.rb +3 -0
- data/lib/ibm_cloud_rest/mixins/callbacks.rb +483 -0
- data/lib/ibm_cloud_rest/monkeypatches.rb +113 -0
- data/lib/ibm_cloud_rest/support/blank.rb +42 -0
- data/lib/ibm_cloud_rest/support/class.rb +176 -0
- data/lib/ibm_cloud_rest/support/rails.rb +35 -0
- data/lib/ibm_sbdtc_rest.rb +163 -0
- data/spec/ibm_sbdtc_rest_spec.rb +7 -0
- data/spec/spec_helper.rb +9 -0
- metadata +138 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 David Ruan
|
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,18 @@
|
|
1
|
+
= ibm_sbdtc_rest
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but
|
13
|
+
bump version in a commit by itself I can ignore when I pull)
|
14
|
+
* Send me a pull request. Bonus points for topic branches.
|
15
|
+
|
16
|
+
== Copyright
|
17
|
+
|
18
|
+
Copyright (c) 2009 David Ruan. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "ibm_sbdtc_rest"
|
8
|
+
gem.summary = %Q{isbdtc rest api client}
|
9
|
+
gem.description = %Q{isbdtc rest api client}
|
10
|
+
gem.email = "ruanwz@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/ruanwz/ibm_sbdtc_rest"
|
12
|
+
gem.authors = ["David Ruan"]
|
13
|
+
gem.add_development_dependency "rspec", ">=1.2.9"
|
14
|
+
gem.add_development_dependency "cucumber", ">= 0"
|
15
|
+
gem.add_development_dependency "jeweler", ">= 1.4.0"
|
16
|
+
gem.add_dependency "thor", ">=0.11.8"
|
17
|
+
gem.add_dependency "json", ">=1.1.9"
|
18
|
+
gem.add_dependency "rest-client", ">=1.0.4"
|
19
|
+
gem.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*'].to_a
|
20
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
21
|
+
end
|
22
|
+
Jeweler::GemcutterTasks.new
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'spec/rake/spectask'
|
28
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
31
|
+
end
|
32
|
+
|
33
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
34
|
+
spec.libs << 'lib' << 'spec'
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :spec => :check_dependencies
|
40
|
+
|
41
|
+
begin
|
42
|
+
require 'cucumber/rake/task'
|
43
|
+
Cucumber::Rake::Task.new(:features)
|
44
|
+
|
45
|
+
task :features => :check_dependencies
|
46
|
+
rescue LoadError
|
47
|
+
task :features do
|
48
|
+
abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
task :default => :spec
|
53
|
+
|
54
|
+
require 'rake/rdoctask'
|
55
|
+
Rake::RDocTask.new do |rdoc|
|
56
|
+
if File.exist?('VERSION')
|
57
|
+
version = File.read('VERSION')
|
58
|
+
else
|
59
|
+
version = ""
|
60
|
+
end
|
61
|
+
|
62
|
+
rdoc.rdoc_dir = 'rdoc'
|
63
|
+
rdoc.title = "ibm_sbdtc_rest #{version}"
|
64
|
+
rdoc.rdoc_files.include('README*')
|
65
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
66
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
data/bin/ibmcloud_admin
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'thor'
|
5
|
+
begin
|
6
|
+
if RUBY_VERSION <= '1.8.6'
|
7
|
+
require 'ruby-debug'
|
8
|
+
end
|
9
|
+
rescue LoadError
|
10
|
+
end
|
11
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
12
|
+
require 'ibm_sbdtc_rest'
|
13
|
+
require 'pp'
|
14
|
+
|
15
|
+
class IbmCloudAdmin < Thor
|
16
|
+
map "-h" => :help
|
17
|
+
map "-li" => :list_instances
|
18
|
+
map "-v" => :version
|
19
|
+
map "--list_instances" => :list_instances
|
20
|
+
|
21
|
+
desc 'list_instances', "list the current instances of IbmCloudAdmin"
|
22
|
+
def list_instances
|
23
|
+
server = IbmCloudRest.new
|
24
|
+
puts JSON.pretty_generate(server.instances)
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'version', "the current version of IbmCloudAdmin"
|
28
|
+
def version
|
29
|
+
version_file = File.dirname(__FILE__) + '/../VERSION'
|
30
|
+
if File.exists?(version_file) and version = File.read(version_file)
|
31
|
+
puts "IbmCloudAdmin version: #{version}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'help', 'help output'
|
36
|
+
def help
|
37
|
+
puts %{
|
38
|
+
Usage: #{$0} /path/to/your/app [options]
|
39
|
+
|
40
|
+
Options:
|
41
|
+
-g, --generate Run the generate command to build a project
|
42
|
+
-li, --list_instances List all instances
|
43
|
+
-j, --just_recipe Run the just_recipe command to only run specified recipes, templates, etc.
|
44
|
+
-d, --display Instead of running, show the template or recipe body
|
45
|
+
-r, --recipes Recipes to use
|
46
|
+
-s, --save Save current set of options
|
47
|
+
-u, --use Use a saved set of options
|
48
|
+
--gems Gems to include
|
49
|
+
|
50
|
+
IbmCloudAdmin Info:
|
51
|
+
-v, --version Show the IbmCloudAdmin version number and quit.
|
52
|
+
-l, --list Show the various recipes known to IbmCloudAdmin and quit.
|
53
|
+
-h, --help Show this help message and quit.
|
54
|
+
|
55
|
+
General Options:
|
56
|
+
|
57
|
+
Description:
|
58
|
+
IbmCloudAdmin is used for Ibm Cloud Service.
|
59
|
+
|
60
|
+
Example:
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
def method_missing(*args)
|
65
|
+
unless @activesupport_required
|
66
|
+
require 'activesupport'
|
67
|
+
@activesupport_required = true
|
68
|
+
m = args.shift
|
69
|
+
send(m, *args)
|
70
|
+
else
|
71
|
+
super
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
IbmCloudAdmin.start
|
76
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module RestClientAdapter
|
2
|
+
|
3
|
+
module API
|
4
|
+
def read_config
|
5
|
+
if File.exists? File.expand_path('~/.isbdtcrc')
|
6
|
+
return YAML.load(File.new(File.expand_path('~/.isbdtcrc')))
|
7
|
+
else
|
8
|
+
raise "Error while read config file"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
def proxy=(url)
|
12
|
+
RestClient.proxy = url
|
13
|
+
end
|
14
|
+
|
15
|
+
def proxy
|
16
|
+
RestClient.proxy
|
17
|
+
end
|
18
|
+
|
19
|
+
def get(uri, headers={:accept => 'application/json'})
|
20
|
+
#RestClient.get(uri, headers)
|
21
|
+
config = read_config
|
22
|
+
rest_get=RestClient::Request.new(:method => :get, :url => uri, :headers => headers,:user => config['user'], :password => config['password'])
|
23
|
+
rest_get.execute
|
24
|
+
end
|
25
|
+
|
26
|
+
def post(uri, payload, headers={:accept => 'application/json'})
|
27
|
+
RestClient.post(uri, payload, headers)
|
28
|
+
end
|
29
|
+
|
30
|
+
def put(uri, payload, headers={:accept => 'application/json'})
|
31
|
+
RestClient.put(uri, payload, headers)
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete(uri, headers={:accept => 'application/json'})
|
35
|
+
RestClient.delete(uri, headers)
|
36
|
+
end
|
37
|
+
|
38
|
+
def copy(uri, headers)
|
39
|
+
RestClient::Request.execute( :method => :copy,
|
40
|
+
:url => uri,
|
41
|
+
:headers => headers)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
File without changes
|
@@ -0,0 +1,328 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require "base64"
|
3
|
+
|
4
|
+
module IbmCloudRest
|
5
|
+
class Database
|
6
|
+
attr_reader :server, :host, :name, :root, :uri
|
7
|
+
attr_accessor :bulk_save_cache_limit
|
8
|
+
|
9
|
+
# Create a IbmCloudRest::Database adapter for the supplied IbmCloudRest::Server
|
10
|
+
# and database name.
|
11
|
+
#
|
12
|
+
# ==== Parameters
|
13
|
+
# server<IbmCloudRest::Server>:: database host
|
14
|
+
# name<String>:: database name
|
15
|
+
#
|
16
|
+
def initialize(server, name)
|
17
|
+
@name = name
|
18
|
+
@server = server
|
19
|
+
@host = server.uri
|
20
|
+
@uri = "/#{name.gsub('/','%2F')}"
|
21
|
+
@root = host + uri
|
22
|
+
@streamer = Streamer.new(self)
|
23
|
+
@bulk_save_cache = []
|
24
|
+
@bulk_save_cache_limit = 500 # must be smaller than the uuid count
|
25
|
+
end
|
26
|
+
|
27
|
+
# returns the database's uri
|
28
|
+
def to_s
|
29
|
+
@root
|
30
|
+
end
|
31
|
+
|
32
|
+
# GET the database info from CouchDB
|
33
|
+
def info
|
34
|
+
IbmCloudRest.get @root
|
35
|
+
end
|
36
|
+
|
37
|
+
# Query the <tt>_all_docs</tt> view. Accepts all the same arguments as view.
|
38
|
+
def documents(params = {})
|
39
|
+
keys = params.delete(:keys)
|
40
|
+
url = IbmCloudRest.paramify_url "#{@root}/_all_docs", params
|
41
|
+
if keys
|
42
|
+
IbmCloudRest.post(url, {:keys => keys})
|
43
|
+
else
|
44
|
+
IbmCloudRest.get url
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# load a set of documents by passing an array of ids
|
49
|
+
def get_bulk(ids)
|
50
|
+
documents(:keys => ids, :include_docs => true)
|
51
|
+
end
|
52
|
+
alias :bulk_load :get_bulk
|
53
|
+
|
54
|
+
# POST a temporary view function to CouchDB for querying. This is not
|
55
|
+
# recommended, as you don't get any performance benefit from CouchDB's
|
56
|
+
# materialized views. Can be quite slow on large databases.
|
57
|
+
def slow_view(funcs, params = {})
|
58
|
+
keys = params.delete(:keys)
|
59
|
+
funcs = funcs.merge({:keys => keys}) if keys
|
60
|
+
url = IbmCloudRest.paramify_url "#{@root}/_temp_view", params
|
61
|
+
JSON.parse(HttpAbstraction.post(url, funcs.to_json, {"Content-Type" => 'application/json'}))
|
62
|
+
end
|
63
|
+
|
64
|
+
# backwards compatibility is a plus
|
65
|
+
alias :temp_view :slow_view
|
66
|
+
|
67
|
+
# Query a CouchDB view as defined by a <tt>_design</tt> document. Accepts
|
68
|
+
# paramaters as described in http://wiki.apache.org/couchdb/HttpViewApi
|
69
|
+
def view(name, params = {}, &block)
|
70
|
+
keys = params.delete(:keys)
|
71
|
+
name = name.split('/') # I think this will always be length == 2, but maybe not...
|
72
|
+
dname = name.shift
|
73
|
+
vname = name.join('/')
|
74
|
+
url = IbmCloudRest.paramify_url "#{@root}/_design/#{dname}/_view/#{vname}", params
|
75
|
+
if keys
|
76
|
+
IbmCloudRest.post(url, {:keys => keys})
|
77
|
+
else
|
78
|
+
if block_given?
|
79
|
+
@streamer.view("_design/#{dname}/_view/#{vname}", params, &block)
|
80
|
+
else
|
81
|
+
IbmCloudRest.get url
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# GET a document from CouchDB, by id. Returns a Ruby Hash.
|
87
|
+
def get(id, params = {})
|
88
|
+
slug = escape_docid(id)
|
89
|
+
url = IbmCloudRest.paramify_url("#{@root}/#{slug}", params)
|
90
|
+
result = IbmCloudRest.get(url)
|
91
|
+
return result unless result.is_a?(Hash)
|
92
|
+
doc = if /^_design/ =~ result["_id"]
|
93
|
+
Design.new(result)
|
94
|
+
else
|
95
|
+
Document.new(result)
|
96
|
+
end
|
97
|
+
doc.database = self
|
98
|
+
doc
|
99
|
+
end
|
100
|
+
|
101
|
+
# GET an attachment directly from CouchDB
|
102
|
+
def fetch_attachment(doc, name)
|
103
|
+
uri = url_for_attachment(doc, name)
|
104
|
+
HttpAbstraction.get uri
|
105
|
+
end
|
106
|
+
|
107
|
+
# PUT an attachment directly to CouchDB
|
108
|
+
def put_attachment(doc, name, file, options = {})
|
109
|
+
docid = escape_docid(doc['_id'])
|
110
|
+
name = CGI.escape(name)
|
111
|
+
uri = url_for_attachment(doc, name)
|
112
|
+
JSON.parse(HttpAbstraction.put(uri, file, options))
|
113
|
+
end
|
114
|
+
|
115
|
+
# DELETE an attachment directly from CouchDB
|
116
|
+
def delete_attachment(doc, name, force=false)
|
117
|
+
uri = url_for_attachment(doc, name)
|
118
|
+
# this needs a rev
|
119
|
+
begin
|
120
|
+
JSON.parse(HttpAbstraction.delete(uri))
|
121
|
+
rescue Exception => error
|
122
|
+
if force
|
123
|
+
# get over a 409
|
124
|
+
doc = get(doc['_id'])
|
125
|
+
uri = url_for_attachment(doc, name)
|
126
|
+
JSON.parse(HttpAbstraction.delete(uri))
|
127
|
+
else
|
128
|
+
error
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Save a document to CouchDB. This will use the <tt>_id</tt> field from
|
134
|
+
# the document as the id for PUT, or request a new UUID from CouchDB, if
|
135
|
+
# no <tt>_id</tt> is present on the document. IDs are attached to
|
136
|
+
# documents on the client side because POST has the curious property of
|
137
|
+
# being automatically retried by proxies in the event of network
|
138
|
+
# segmentation and lost responses.
|
139
|
+
#
|
140
|
+
# If <tt>bulk</tt> is true (false by default) the document is cached for bulk-saving later.
|
141
|
+
# Bulk saving happens automatically when #bulk_save_cache limit is exceded, or on the next non bulk save.
|
142
|
+
def save_doc(doc, bulk = false)
|
143
|
+
if doc['_attachments']
|
144
|
+
doc['_attachments'] = encode_attachments(doc['_attachments'])
|
145
|
+
end
|
146
|
+
if bulk
|
147
|
+
@bulk_save_cache << doc
|
148
|
+
return bulk_save if @bulk_save_cache.length >= @bulk_save_cache_limit
|
149
|
+
return {"ok" => true} # Compatibility with Document#save
|
150
|
+
elsif !bulk && @bulk_save_cache.length > 0
|
151
|
+
bulk_save
|
152
|
+
end
|
153
|
+
result = if doc['_id']
|
154
|
+
slug = escape_docid(doc['_id'])
|
155
|
+
begin
|
156
|
+
IbmCloudRest.put "#{@root}/#{slug}", doc
|
157
|
+
rescue HttpAbstraction::ResourceNotFound
|
158
|
+
p "resource not found when saving even tho an id was passed"
|
159
|
+
slug = doc['_id'] = @server.next_uuid
|
160
|
+
IbmCloudRest.put "#{@root}/#{slug}", doc
|
161
|
+
end
|
162
|
+
else
|
163
|
+
begin
|
164
|
+
slug = doc['_id'] = @server.next_uuid
|
165
|
+
IbmCloudRest.put "#{@root}/#{slug}", doc
|
166
|
+
rescue #old version of couchdb
|
167
|
+
IbmCloudRest.post @root, doc
|
168
|
+
end
|
169
|
+
end
|
170
|
+
if result['ok']
|
171
|
+
doc['_id'] = result['id']
|
172
|
+
doc['_rev'] = result['rev']
|
173
|
+
doc.database = self if doc.respond_to?(:database=)
|
174
|
+
end
|
175
|
+
result
|
176
|
+
end
|
177
|
+
|
178
|
+
### DEPRECATION NOTICE
|
179
|
+
def save(doc, bulk=false)
|
180
|
+
puts "IbmCloudRest::Database's save method is being deprecated, please use save_doc instead"
|
181
|
+
save_doc(doc, bulk)
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
# POST an array of documents to CouchDB. If any of the documents are
|
186
|
+
# missing ids, supply one from the uuid cache.
|
187
|
+
#
|
188
|
+
# If called with no arguments, bulk saves the cache of documents to be bulk saved.
|
189
|
+
def bulk_save(docs = nil, use_uuids = true)
|
190
|
+
if docs.nil?
|
191
|
+
docs = @bulk_save_cache
|
192
|
+
@bulk_save_cache = []
|
193
|
+
end
|
194
|
+
if (use_uuids)
|
195
|
+
ids, noids = docs.partition{|d|d['_id']}
|
196
|
+
uuid_count = [noids.length, @server.uuid_batch_count].max
|
197
|
+
noids.each do |doc|
|
198
|
+
nextid = @server.next_uuid(uuid_count) rescue nil
|
199
|
+
doc['_id'] = nextid if nextid
|
200
|
+
end
|
201
|
+
end
|
202
|
+
IbmCloudRest.post "#{@root}/_bulk_docs", {:docs => docs}
|
203
|
+
end
|
204
|
+
alias :bulk_delete :bulk_save
|
205
|
+
|
206
|
+
# DELETE the document from CouchDB that has the given <tt>_id</tt> and
|
207
|
+
# <tt>_rev</tt>.
|
208
|
+
#
|
209
|
+
# If <tt>bulk</tt> is true (false by default) the deletion is recorded for bulk-saving (bulk-deletion :) later.
|
210
|
+
# Bulk saving happens automatically when #bulk_save_cache limit is exceded, or on the next non bulk save.
|
211
|
+
def delete_doc(doc, bulk = false)
|
212
|
+
raise ArgumentError, "_id and _rev required for deleting" unless doc['_id'] && doc['_rev']
|
213
|
+
if bulk
|
214
|
+
@bulk_save_cache << { '_id' => doc['_id'], '_rev' => doc['_rev'], '_deleted' => true }
|
215
|
+
return bulk_save if @bulk_save_cache.length >= @bulk_save_cache_limit
|
216
|
+
return { "ok" => true } # Mimic the non-deferred version
|
217
|
+
end
|
218
|
+
slug = escape_docid(doc['_id'])
|
219
|
+
IbmCloudRest.delete "#{@root}/#{slug}?rev=#{doc['_rev']}"
|
220
|
+
end
|
221
|
+
|
222
|
+
### DEPRECATION NOTICE
|
223
|
+
def delete(doc, bulk=false)
|
224
|
+
puts "IbmCloudRest::Database's delete method is being deprecated, please use delete_doc instead"
|
225
|
+
delete_doc(doc, bulk)
|
226
|
+
end
|
227
|
+
|
228
|
+
# COPY an existing document to a new id. If the destination id currently exists, a rev must be provided.
|
229
|
+
# <tt>dest</tt> can take one of two forms if overwriting: "id_to_overwrite?rev=revision" or the actual doc
|
230
|
+
# hash with a '_rev' key
|
231
|
+
def copy_doc(doc, dest)
|
232
|
+
raise ArgumentError, "_id is required for copying" unless doc['_id']
|
233
|
+
slug = escape_docid(doc['_id'])
|
234
|
+
destination = if dest.respond_to?(:has_key?) && dest['_id'] && dest['_rev']
|
235
|
+
"#{dest['_id']}?rev=#{dest['_rev']}"
|
236
|
+
else
|
237
|
+
dest
|
238
|
+
end
|
239
|
+
IbmCloudRest.copy "#{@root}/#{slug}", destination
|
240
|
+
end
|
241
|
+
|
242
|
+
### DEPRECATION NOTICE
|
243
|
+
def copy(doc, dest)
|
244
|
+
puts "IbmCloudRest::Database's copy method is being deprecated, please use copy_doc instead"
|
245
|
+
copy_doc(doc, dest)
|
246
|
+
end
|
247
|
+
|
248
|
+
# Compact the database, removing old document revisions and optimizing space use.
|
249
|
+
def compact!
|
250
|
+
IbmCloudRest.post "#{@root}/_compact"
|
251
|
+
end
|
252
|
+
|
253
|
+
# Create the database
|
254
|
+
def create!
|
255
|
+
bool = server.create_db(@name) rescue false
|
256
|
+
bool && true
|
257
|
+
end
|
258
|
+
|
259
|
+
# Delete and re create the database
|
260
|
+
def recreate!
|
261
|
+
delete!
|
262
|
+
create!
|
263
|
+
rescue HttpAbstraction::ResourceNotFound
|
264
|
+
ensure
|
265
|
+
create!
|
266
|
+
end
|
267
|
+
|
268
|
+
# Replicates via "pulling" from another database to this database. Makes no attempt to deal with conflicts.
|
269
|
+
def replicate_from other_db
|
270
|
+
raise ArgumentError, "must provide a CouchReset::Database" unless other_db.kind_of?(IbmCloudRest::Database)
|
271
|
+
IbmCloudRest.post "#{@host}/_replicate", :source => other_db.root, :target => name
|
272
|
+
end
|
273
|
+
|
274
|
+
# Replicates via "pushing" to another database. Makes no attempt to deal with conflicts.
|
275
|
+
def replicate_to other_db
|
276
|
+
raise ArgumentError, "must provide a CouchReset::Database" unless other_db.kind_of?(IbmCloudRest::Database)
|
277
|
+
IbmCloudRest.post "#{@host}/_replicate", :target => other_db.root, :source => name
|
278
|
+
end
|
279
|
+
|
280
|
+
# DELETE the database itself. This is not undoable and could be rather
|
281
|
+
# catastrophic. Use with care!
|
282
|
+
def delete!
|
283
|
+
clear_extended_doc_fresh_cache
|
284
|
+
IbmCloudRest.delete @root
|
285
|
+
end
|
286
|
+
|
287
|
+
private
|
288
|
+
|
289
|
+
def clear_extended_doc_fresh_cache
|
290
|
+
::IbmCloudRest::ExtendedDocument.subclasses.each{|klass| klass.design_doc_fresh = false if klass.respond_to?(:design_doc_fresh=) }
|
291
|
+
end
|
292
|
+
|
293
|
+
def uri_for_attachment(doc, name)
|
294
|
+
if doc.is_a?(String)
|
295
|
+
puts "IbmCloudRest::Database#fetch_attachment will eventually require a doc as the first argument, not a doc.id"
|
296
|
+
docid = doc
|
297
|
+
rev = nil
|
298
|
+
else
|
299
|
+
docid = doc['_id']
|
300
|
+
rev = doc['_rev']
|
301
|
+
end
|
302
|
+
docid = escape_docid(docid)
|
303
|
+
name = CGI.escape(name)
|
304
|
+
rev = "?rev=#{doc['_rev']}" if rev
|
305
|
+
"/#{docid}/#{name}#{rev}"
|
306
|
+
end
|
307
|
+
|
308
|
+
def url_for_attachment(doc, name)
|
309
|
+
@root + uri_for_attachment(doc, name)
|
310
|
+
end
|
311
|
+
|
312
|
+
def escape_docid id
|
313
|
+
/^_design\/(.*)/ =~ id ? "_design/#{CGI.escape($1)}" : CGI.escape(id)
|
314
|
+
end
|
315
|
+
|
316
|
+
def encode_attachments(attachments)
|
317
|
+
attachments.each do |k,v|
|
318
|
+
next if v['stub']
|
319
|
+
v['data'] = base64(v['data'])
|
320
|
+
end
|
321
|
+
attachments
|
322
|
+
end
|
323
|
+
|
324
|
+
def base64(data)
|
325
|
+
Base64.encode64(data).gsub(/\s/,'')
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|