ibm_sbdtc_rest 0.0.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/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
|