Class: Makura::Database

Inherits:
Object
  • Object
show all
Includes:
HTTPMethods
Defined in:
lib/makura/database.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from HTTPMethods

#get, #post, #put

Constructor Details

#initialize(server, name, auto_create = true) ⇒ Database

Initialize instance of Database and create if it doesn’t exist yet. To prevent automatic creation, pass false as 3rd parameter

Usage:

server = Makura::Server.new
# #<URI::HTTP:0xb7788234 URL:http://localhost:5984>
database = Makura::Database.new(server, 'foo')
# #<Makura::Database 'http://localhost:5984/foo'>


15
16
17
18
# File 'lib/makura/database.rb', line 15

def initialize(server, name, auto_create = true)
  @server, @name = server, name
  create if auto_create
end

Instance Attribute Details

#nameObject

Returns the value of attribute name.



4
5
6
# File 'lib/makura/database.rb', line 4

def name
  @name
end

#serverObject

Returns the value of attribute server.



4
5
6
# File 'lib/makura/database.rb', line 4

def server
  @server
end

Instance Method Details

#[](id, rev = nil) ⇒ Object



149
150
151
152
153
154
155
156
# File 'lib/makura/database.rb', line 149

def [](id, rev = nil)
  id = Makura.escape(id)
  if rev
    get(id, :rev => rev)
  else
    get(id)
  end
end

#[]=(id, doc) ⇒ Object



158
159
160
161
# File 'lib/makura/database.rb', line 158

def []=(id, doc)
  id = Makura.escape(id)
  put(id, :payload => prepare_doc(doc))
end

#all_docs(params = {}) ⇒ Object Also known as: documents



134
135
136
# File 'lib/makura/database.rb', line 134

def all_docs(params = {})
  get('_all_docs', params)
end

#base64(data) ⇒ Object



234
235
236
# File 'lib/makura/database.rb', line 234

def base64(data)
  [data.to_s].pack('m').delete("\n")
end

#bulk_docs(docs) ⇒ Object Also known as: bulk_save

NOTE:

* Seems like we don't even need to check _id, CouchDB will assign it.
  But in order to use our own uuids we still do it.


190
191
192
193
# File 'lib/makura/database.rb', line 190

def bulk_docs(docs)
  docs.each{|doc| doc['_id'] ||= @server.next_uuid }
  post("_bulk_docs", :payload => {:docs => docs}, 'Content-Type' => 'application/json')
end

#compact(design_name = nil) ⇒ Object



118
119
120
121
122
123
124
# File 'lib/makura/database.rb', line 118

def compact(design_name = nil)
  if design_name
    post("/_compact/#{design_name}")
  else
    post("/_compact")
  end
end

#createObject

Create the database if it doesn’t exist already.

Usage:

server = Makura::Server.new
# #<URI::HTTP:0xb76a4a98 URL:http://localhost:5984>

database = Makura::Database.new(server, 'foo', false)
# #<Makura::Database 'http://localhost:5984/foo'>

database.create
# {"update_seq"=>0, "doc_count"=>0, "purge_seq"=>0, "disk_size"=>4096,
#  "compact_running"=>false, "db_name"=>"foo", "doc_del_count"=>0}


33
34
35
36
37
# File 'lib/makura/database.rb', line 33

def create
  info
rescue Error::ResourceNotFound
  put("/", :payload => '')
end

#delete(doc, opts = {}) ⇒ Object

Will delete document in the CouchDB corresponding to given doc. Use #destroy to delete the database itself. Use #delete! to automatically rescue exceptions on conflicts.

Possible variations (User is a Makura::Model) are:

# deleting based on explicit _id and :rev option.
database.delete('manveru', :rev => 123134)

# deleting based on a Hash
database.delete('_id' => 'manveru', '_rev' => 123134)

user = User.new(:name => 'manveru')
user.save
database.delete(user)

Usage when deleting document:

doc = database.save('name' => 'manveru', 'time' => Time.now)
# {"rev"=>"484030692", "id"=>"67e086087d5b7e7196b5c99174b0b66c", "ok"=>true}

database[doc['id']]
# {"name"=>"manveru", "_rev"=>"484030692",
   "time"=>"Sat Nov 22 16:37:50 +0900 2008",
   "_id"=>"67e086087d5b7e7196b5c99174b0b66c"}

database.delete(doc['id'], :rev => doc['rev'])
# {"rev"=>"2034883605", "id"=>"67e086087d5b7e7196b5c99174b0b66c", "ok"=>true}

database[doc['id']]
RestClient::ResourceNotFound: RestClient::ResourceNotFound

database.delete(doc['id'], :rev => doc['rev'])
Makura::RequestFailed: {"reason"=>"Document update conflict.", "error"=>"conflict"}

Raises:

  • (ArgumentError)


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/makura/database.rb', line 73

def delete(doc, opts = {})
  case doc
  when Makura::Model
    doc_id, doc_rev = doc._id, doc._rev
  when Hash
    doc_id  = doc['_id']  || doc['id']  || doc[:_id]  || doc[:id]
    doc_rev = doc['_rev'] || doc['rev'] || doc[:_rev] || doc[:rev]
  else
    doc_id = doc
  end

  raise(ArgumentError, "document _id wasn't passed") unless doc_id

  doc_id = Makura.escape(doc_id)
  opts[:rev] ||= doc_rev if doc_rev

  request(:delete, doc_id.to_s, opts)
end

#delete!(doc, opts = {}) ⇒ Object



92
93
94
95
# File 'lib/makura/database.rb', line 92

def delete!(doc, opts = {})
  delete(doc, opts)
rescue Error::Conflict, Error::ResourceNotFound
end

#design_docs(params = {}) ⇒ Object



139
140
141
142
143
144
145
146
147
# File 'lib/makura/database.rb', line 139

def design_docs(params = {})
  pass = {
    startkey: '_design0',
    endkey: '_design',
    descending: true,
  }.merge(params)

  all_docs(pass)
end

#destroy(opts = {}) ⇒ Object

Delete the database itself.

Usage:

database.destroy
# {"ok"=>true}
database.info
# RestClient::ResourceNotFound: RestClient::ResourceNotFound


105
106
107
# File 'lib/makura/database.rb', line 105

def destroy(opts = {})
  request(:delete, '/', opts)
end

#destroy!(opts = {}) ⇒ Object



109
110
111
112
# File 'lib/makura/database.rb', line 109

def destroy!(opts = {})
  destroy(opts)
rescue Error::ResourceNotFound
end

#encode_attachments(attachments) ⇒ Object



226
227
228
229
230
231
232
# File 'lib/makura/database.rb', line 226

def encode_attachments(attachments)
  attachments.each do |key, value|
    next if value['stub']
    value['data'] = base64(value['data'])
  end
  attachments
end

#ensure_full_commitObject



130
131
132
# File 'lib/makura/database.rb', line 130

def ensure_full_commit
  post('/_ensure_full_commit')
end

#get_attachment(doc, file_id) ⇒ Object



196
197
198
199
200
201
# File 'lib/makura/database.rb', line 196

def get_attachment(doc, file_id)
  doc_id = doc.respond_to?(:_id) ? doc._id : doc.to_str
  file_id, doc_id = Makura.escape(file_id), Makura.escape(doc_id)

  get("#{doc_id}/#{file_id}", :raw => true)
end

#infoObject



114
115
116
# File 'lib/makura/database.rb', line 114

def info
  get('/')
end

#inspectObject



238
239
240
# File 'lib/makura/database.rb', line 238

def inspect
  "#<Makura::Database '#{@server.uri(name || '/')}'>"
end

#prepare_doc(doc) ⇒ Object



214
215
216
217
218
219
220
# File 'lib/makura/database.rb', line 214

def prepare_doc(doc)
  if attachments = doc['_attachments']
    doc['_attachments'] = encode_attachments(attachments)
  end

  return doc
end

#put_attachment(doc, file_id, file, options = {}) ⇒ Object

PUT an attachment directly to CouchDB



204
205
206
207
208
209
210
211
212
# File 'lib/makura/database.rb', line 204

def put_attachment(doc, file_id, file, options = {})
  doc_id, file_id = Makura.escape(doc._id), Makura.escape(file_id)

  options[:payload] = file
  options[:raw] = true
  options[:rev] = doc._rev if doc._rev

  put("#{doc_id}/#{file_id}", options)
end

#request(method, path, params = {}) ⇒ Object



222
223
224
# File 'lib/makura/database.rb', line 222

def request(method, path, params = {})
  @server.request(method, "/#{name}/#{path}", params)
end

#save(doc) ⇒ Object



176
177
178
179
180
181
182
183
184
185
# File 'lib/makura/database.rb', line 176

def save(doc)
  if id = doc['_id']
    id = Makura.escape(id)
    put(id, :payload => prepare_doc(doc))
  else
    id = doc['_id'] = @server.next_uuid
    id = Makura.escape(id)
    put(id, :payload => prepare_doc(doc))
  end
end

#temp_view(params = {}) ⇒ Object



163
164
165
166
167
168
169
170
# File 'lib/makura/database.rb', line 163

def temp_view(params = {})
  params[:payload] = functions = {}
  functions[:map] = params.delete(:map) if params[:map]
  functions[:reduce] = params.delete(:reduce) if params[:reduce]
  params['Content-Type'] = 'application/json'

  post('_temp_view', params)
end

#view(layout, params = {}) ⇒ Object



172
173
174
# File 'lib/makura/database.rb', line 172

def view(layout, params = {})
  get("_design/#{layout}", params)
end

#view_cleanupObject



126
127
128
# File 'lib/makura/database.rb', line 126

def view_cleanup
  post("/_view_cleanup")
end