Class: CouchClient::Document

Inherits:
ConsistentHash show all
Defined in:
lib/couch-client/document.rb

Overview

Document is an extended Hash that provides additional methods to save, update (with attachments), and delete documents on the CouchDB.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from ConsistentHash

#[]=, #default, #delete, #dup, #fetch, #key?, #merge, #regular_update, #regular_writer, #to_hash, #update, #values_at

Constructor Details

#initialize(code, body, connection, deleted = false) ⇒ Document

Document is constructed with a status code, response body, connection object and a flag stating if the document has been deleted.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/couch-client/document.rb', line 13

def initialize(code, body, connection, deleted = false)
  self.merge!(body)

  @code = code
  @error = {}
  @connection = connection
  @deleted = deleted

  if self.attachments
    self.attachments = AttachmentList.new(attachments)
    
    self.attachments.keys.each do |key|
      self.attachments[key] = Attachment.new(id, key, attachments[key], @connection)
    end
  end
end

Instance Attribute Details

#codeObject (readonly)

Returns the value of attribute code.



9
10
11
# File 'lib/couch-client/document.rb', line 9

def code
  @code
end

#errorObject (readonly)

Returns the value of attribute error.



9
10
11
# File 'lib/couch-client/document.rb', line 9

def error
  @error
end

Instance Method Details

#attach(name, content, content_type) ⇒ Object

Tries to attach a file to the document. If it us unable to, it will save the error and make it available via #error.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/couch-client/document.rb', line 82

def attach(name, content, content_type)
  # The document must already be saved to the server before a file can be attached.
  if self.rev
    @code, body = @connection.hookup.put([self.id, name], {"rev" => self.rev}, content, content_type)
    
    # If the document was saved
    if body["ok"]
      # Update rev and return `true`
      self.rev = body["rev"]
      true
    else
      # Else save error message and return `false`.
      @error = {body["error"] => body["reason"]}
      false
    end
  else
    # Raise an error if the document is new before trying to attach a file.
    raise AttachmentError.new("a document must exist before an attachment can be uploaded to it")
  end
end

#conflict?Boolean

Identifies that the document cannot be saved due to conflicts

Returns:

  • (Boolean)


142
143
144
# File 'lib/couch-client/document.rb', line 142

def conflict?
  !!@error["conflict"]
end

#delete!Object

Tries to delete a file from the server. If it us unable to, it will save the error and make it available via #error.



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/couch-client/document.rb', line 105

def delete!
  @code, body = @connection.hookup.delete([id], {"rev" => rev})
  
  # If the document was deleted
  if body["ok"]
    # Update the rev, set the deleted flag to `true` and return `true`
    self.rev = body["rev"]
    @deleted = true
    true
  else
    # Else save error message and return `false`.
    @error = {body["error"] => body["reason"]}
    false
  end
end

#deleted?Boolean

Identifies that the document has been deleted

Returns:

  • (Boolean)


147
148
149
# File 'lib/couch-client/document.rb', line 147

def deleted?
  @deleted
end

#design?Boolean

Identifies the document as a design document

Returns:

  • (Boolean)


122
123
124
# File 'lib/couch-client/document.rb', line 122

def design?
  !!self.id.match(/_design\//) # Design documents start with "_design/"
end

#error?Boolean

Identifies that there are currently errors that must be resolved

Returns:

  • (Boolean)


132
133
134
# File 'lib/couch-client/document.rb', line 132

def error?
  !@error.empty?
end

#invalid?Boolean

Identifies that the document does not yet pass a ‘validate_on_update` function

Returns:

  • (Boolean)


137
138
139
# File 'lib/couch-client/document.rb', line 137

def invalid?
  @code == 403 && @error["forbidden"]
end

#new?Boolean

Identifies the document as not yet being saved to the server

Returns:

  • (Boolean)


127
128
129
# File 'lib/couch-client/document.rb', line 127

def new?
  !rev
end

#saveObject

Tries to save the document to the server. If it us unable to, it will save the error and make it available via #error.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/couch-client/document.rb', line 53

def save
  # Ensure that "_id" is a String if it is defined.
  if self.key?("_id") && !self["_id"].is_a?(String)
    raise InvalidId.new("document _id must be a String")
  end
  
  # Documents without an id must use post, with an id must use put
  @code, body = if self.id
    @connection.hookup.put([self.id], nil, self)
  else
    @connection.hookup.post(nil, nil, self)
  end
  
  # If the document was saved
  if body["ok"]
    # Update id and rev, ensure the deleted flag is set to `false` and return `true`
    self.id ||= body["id"]
    self.rev  = body["rev"]
    @deleted  = false
    true
  else
    # Else save error message and return `false`.
    @error = {body["error"] => body["reason"]}
    false
  end
end

#saved_doc(query = {}) ⇒ Object

Returns a copy of the same document that is currently saved on the server.



43
44
45
46
47
48
49
# File 'lib/couch-client/document.rb', line 43

def saved_doc(query = {})
  if new?
    raise DocumentNotAvailable.new("this document is new and therefore has not been saved yet")
  else
    @connection[self.id, query]
  end
end