Class: Exegesis::Design

Inherits:
Object
  • Object
show all
Includes:
Document
Defined in:
lib/exegesis/design.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Document

included

Constructor Details

#initialize(db) ⇒ Design

Returns a new instance of Design.



107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/exegesis/design.rb', line 107

def initialize db
  begin
    super db.raw_get("_design/#{design_name}")
    self.database = db
  rescue RestClient::ResourceNotFound
    db.put("_design/#{design_name}", self.class.canonical_design)
    retry
  end
  unless self['views'] == self.class.canonical_design['views']
    self['views'].update(self.class.canonical_design['views'])
    save
  end
end

Class Method Details

.canonical_designObject



33
34
35
36
37
38
# File 'lib/exegesis/design.rb', line 33

def self.canonical_design
  @canonical_design ||= {
    '_id' => "_design/#{design_name}",
    'views' => {}
  }
end

.compose_canonicalObject



23
24
25
26
27
28
29
30
31
# File 'lib/exegesis/design.rb', line 23

def self.compose_canonical
  Dir[(design_directory + 'views' + '**/*.js').to_s].each do |view_func|
    path = view_func.split('/')
    func = path.pop.sub(/\.js$/,'')
    name = path.pop
    canonical_design['views'][name] ||= {}
    canonical_design['views'][name][func] = File.read(view_func)
  end
end

.design_directoryObject



11
12
13
# File 'lib/exegesis/design.rb', line 11

def self.design_directory
  @design_directory ||= Pathname.new("designs/#{design_name}")
end

.design_directory=(dir) ⇒ Object



7
8
9
# File 'lib/exegesis/design.rb', line 7

def self.design_directory= dir
  @design_directory = Pathname.new(dir)
end

.design_nameObject



19
20
21
# File 'lib/exegesis/design.rb', line 19

def self.design_name
  @design_name ||= name.scan(/^(?:[A-Za-z0-9\:]+::)([A-Za-z0-9]+)Design$/).first.first.downcase
end

.design_name=(n) ⇒ Object



15
16
17
# File 'lib/exegesis/design.rb', line 15

def self.design_name= n
  @design_name = n.to_s
end

.docs(name, default_options = {}) ⇒ Object

Raises:

  • (ArgumentError)


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

def self.docs name, default_options={}
  view_name = default_options.delete(:view) || name
  raise ArgumentError, "missing view #{view_name}" unless views.include?(view_name.to_s)
  if [:reduce, :group, :group_level].any? {|key| default_options.has_key?(key)}
    raise ArgumentError, "cannot reduce (:group, :group_level, :reduce) on a docs view"
  end
  
  default_options = {:include_docs => true}.merge(default_options)
  default_options.update({:reduce => false}) if reduceable?(view_name)

  define_method name do |*opts|
    key = opts.shift
    options = parse_opts key, opts.first, default_options
    Exegesis::DocumentCollection.new(call_view(view_name, options), database)
  end
end

.hash(name, default_options = {}) ⇒ Object

Raises:

  • (ArgumentError)


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/exegesis/design.rb', line 73

def self.hash name, default_options={}
  view_name = default_options.delete(:view) || name
  raise ArgumentError, "missing view #{view_name}" unless views.include?(view_name.to_s)
  raise NameError, "Cannot return a hash for views without a reduce function" unless reduceable?(view_name)
  if default_options.has_key?(:group) && default_options[:group] == false
    raise ArgumentError, "cannot turn off grouping for a hash view" 
  end
  
  default_options = {:group => true}.merge(default_options)
  
  define_method name do |*opts|
    options = parse_opts opts.shift, opts.first, default_options

    if options.has_key?(:group) && options[:group] == false
      raise ArgumentError, "cannot turn off grouping for a hash view"
    end

    if options[:key]
      options.delete(:group)
      options.delete(:group_level)
    end
    
    response = call_view view_name, options
    if response.size == 1 && response.first['key'].nil?
      response.first['value']
    else
      response.inject({}) do |memo, row|
        memo.update(row['key'] => row['value'])
      end
    end
  end
end

.reduceable?(view_name) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
47
# File 'lib/exegesis/design.rb', line 44

def self.reduceable? view_name
  view_name = view_name.to_s
  views.include?(view_name) && canonical_design['views'][view_name].has_key?('reduce')
end

.view(name, default_options = {}) ⇒ Object



49
50
51
52
53
54
# File 'lib/exegesis/design.rb', line 49

def self.view name, default_options={}
  define_method name do |*opts|
    options = parse_opts opts.shift, opts.first, default_options
    Exegesis::DocumentCollection.new(call_view(name, options), database)
  end
end

.viewsObject



40
41
42
# File 'lib/exegesis/design.rb', line 40

def self.views
  @views ||= canonical_design['views'].keys
end

Instance Method Details

#call_view(name, opts = {}) ⇒ Object



125
126
127
128
# File 'lib/exegesis/design.rb', line 125

def call_view name, opts={}
  url = "_design/#{design_name}/_view/#{name}"
  database.raw_get(url, opts)['rows']
end

#design_nameObject



130
131
132
# File 'lib/exegesis/design.rb', line 130

def design_name
  self.class.design_name
end

#parse_opts(key, opts = {}, defaults = {}) ⇒ Object



134
135
136
137
138
139
140
141
# File 'lib/exegesis/design.rb', line 134

def parse_opts key, opts={}, defaults={}
  opts = straighten_args key, opts, defaults
  parse_key opts
  parse_keys opts
  parse_range opts
  parse_reduce opts
  opts
end

#view(name, key = nil, opts = {}) ⇒ Object



121
122
123
# File 'lib/exegesis/design.rb', line 121

def view name, key=nil, opts={}
  call_view name, parse_opts(key, opts)
end