Class: RockingChair::View

Inherits:
Object
  • Object
show all
Defined in:
lib/rocking_chair/view.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(database, design_document_name, view_name, options = {}) ⇒ View

Returns a new instance of View.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/rocking_chair/view.rb', line 17

def initialize(database, design_document_name, view_name, options = {})
  unless design_document_name == :all && view_name == :all
    RockingChair::Error.raise_404 unless database.exists?("_design/#{design_document_name}")
    @design_document = JSON.parse(database.storage["_design/#{design_document_name}"], :create_additions => false)
    @view_document = design_document['views'][view_name] || RockingChair::Error.raise_404
  end

  @database = database
  @keys = database.storage.keys
  @design_document_name = normalize_design_document_name(design_document_name)
  @view_name = view_name
  initialize_ruby_store
  
  @options = {
    'reduce' => false,
    'limit' => nil,
    'key' => nil,
    'filter_by_key' => false,
    'descending' => false,
    'include_docs' => false,
    'without_deleted' => false,
    'endkey' => nil,
    'startkey' => nil,
    'endkey_docid' => nil,
    'startkey_docid' => nil
  }.update(options)
  @options.assert_valid_keys('reduce', 'limit', 'key', 'descending', 'include_docs', 'without_deleted', 'endkey', 'startkey', 'endkey_docid', 'startkey_docid', 'filter_by_key')
  RockingChair::Helper.jsonfy_options(@options, 'key', 'startkey', 'endkey', 'startkey_docid', 'endkey_docid')
  
  if options.has_key?('key')
    # still filter even if key is nil
    @options['filter_by_key'] = true
  end
  
  normalize_view_name
  normalize_descending_options
end

Instance Attribute Details

#databaseObject

Returns the value of attribute database.



6
7
8
# File 'lib/rocking_chair/view.rb', line 6

def database
  @database
end

#design_documentObject

Returns the value of attribute design_document.



6
7
8
# File 'lib/rocking_chair/view.rb', line 6

def design_document
  @design_document
end

#design_document_nameObject

Returns the value of attribute design_document_name.



6
7
8
# File 'lib/rocking_chair/view.rb', line 6

def design_document_name
  @design_document_name
end

#keysObject

Returns the value of attribute keys.



6
7
8
# File 'lib/rocking_chair/view.rb', line 6

def keys
  @keys
end

#optionsObject

Returns the value of attribute options.



6
7
8
# File 'lib/rocking_chair/view.rb', line 6

def options
  @options
end

#ruby_storeObject

Returns the value of attribute ruby_store.



6
7
8
# File 'lib/rocking_chair/view.rb', line 6

def ruby_store
  @ruby_store
end

#view_documentObject

Returns the value of attribute view_document.



6
7
8
# File 'lib/rocking_chair/view.rb', line 6

def view_document
  @view_document
end

#view_nameObject

Returns the value of attribute view_name.



6
7
8
# File 'lib/rocking_chair/view.rb', line 6

def view_name
  @view_name
end

Class Method Details

.run(database, design_document_name, view_name, options = {}) ⇒ Object

Raises:

  • (ArgumentError)


8
9
10
11
# File 'lib/rocking_chair/view.rb', line 8

def self.run(database, design_document_name, view_name, options = {})
  raise ArgumentError, "Need a databae, a design_doc_name and a view_name" unless database.present? && design_document_name.present? && view_name.present?
  new(database, design_document_name, view_name, options).find.render
end

.run_all(database, options = {}) ⇒ Object



13
14
15
# File 'lib/rocking_chair/view.rb', line 13

def self.run_all(database, options = {})
  new(database, :all, :all, options).find.render_for_all
end

Instance Method Details

#findObject



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/rocking_chair/view.rb', line 55

def find
  if view_name == :all
    find_all
  elsif match = view_name.match(/\Aall_documents\Z/)
    find_all_by_class
  elsif match = view_name.match(/\Aby_(\w+)\Z/)
    find_by_attribute(match[1])
  elsif match = view_name.match(/\Aassociation_#{design_document_name}_belongs_to_(\w+)\Z/)
    find_belongs_to(match[1])
  elsif match = view_name.match(/\Aassociation_#{design_document_name}_has_and_belongs_to_many_(\w+)\Z/)
    find_has_and_belongs_to_many(match[1])
  else
    raise "Unknown View implementation for view #{view_name.inspect} in design document _design/#{design_document_name}"
  end
  self
end

#renderObject



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

def render
  offset = 0
  total_size = keys.size
  filter_by_startkey_docid_and_endkey_docid
  filter_by_limit
  
  if options['reduce'].to_s == 'true'
    { "rows" => [{'key' => options['key'], 'value' => keys.size }]}.to_json
  else
    rows = keys.map do |key|
      document = ruby_store[key]
      if options['include_docs'].to_s == 'true'
        {'id' => RockingChair::Helper.access('_id', document), 'value' => nil, 'doc' => (document.respond_to?(:_document) ? document._document : document) }.merge(key_description)
      else
        {'id' => RockingChair::Helper.access('_id', document), 'key' => options['key'], 'value' => nil}.merge(key_description)
      end
    end
    { "total_rows" => total_size, "offset" => offset, "rows" => rows}.to_json
  end
end

#render_for_allObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/rocking_chair/view.rb', line 93

def render_for_all
  #key_size_before_startkey_filter = keys.size
  #filter_items_not_in_range('_id', options['startkey'], nil) if options['startkey']
  #filter_items_not_in_range('_id', options['startkey'], options['endkey']) if options['endkey']
  offset = 0 #key_size_before_startkey_filter - keys.size
  #offset = filter_by_startkey
  #filter_by_endkey
  filter_by_limit
  
  rows = keys.map do |key|
    document = ruby_store[key]
    if options['include_docs'].to_s == 'true'
      {'id' => document['_id'], 'key' => document['_id'], 'value' => document.update('rev' => document['_rev'])}
    else
      {'id' => document['_id'], 'key' => document['_id'], 'value' => {'rev' => document['_rev']}}
    end
  end
  
  { "total_rows" => database.document_count, "offset" => offset, "rows" => rows}.to_json
end