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
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
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
# File 'lib/couch-shell-plugin/core_views.rb', line 20
def execute_editview(argstr)
ensure_at_database
design_name, view_name = argstr.split(/\s+/, 2)
if design_name.nil? || view_name.nil?
raise ShellError, "design and view name required"
end
shell.request "GET", "_design/#{design_name}", nil, false
return unless shell.responses.current(&:ok?)
design = shell.responses.current.json_value
view = design.views[view_name] if design["views"]
mapval = view && view["map"]
reduceval = view && view["reduce"]
t = Tempfile.new(["view", ".js"])
t.puts("map")
if mapval
t.puts mapval
else
t.puts "function(doc) {\n emit(doc._id, doc);\n}"
end
if reduceval || view.nil?
t.puts
t.puts("reduce")
if reduceval
t.puts reduceval
else
t.puts "function(keys, values, rereduce) {\n\n}"
end
end
t.close
continue?("Press ENTER to edit #{view ? 'existing' : 'new'} view, " +
"CTRL+C to cancel ")
unless system(shell.editor_bin!, t.path)
raise ShellError, "editing command failed with exit status #{$?.exitstatus}"
end
text = t.open.read
@viewtext = text
t.close
mapf = nil
reducef = nil
inmap = false
inreduce = false
i = 0
text.each_line { |line|
i += 1
case line
when /^map\s*(.*)$/
unless $1.empty?
shell.msg "recover view text with `print viewtext'"
raise ShellError, "invalid map line at line #{i}"
end
unless mapf.nil?
shell.msg "recover view text with `print viewtext'"
raise ShellError, "duplicate map line at line #{i}"
end
inreduce = false
inmap = true
mapf = ""
when /^reduce\s*(.*)$/
unless $1.empty?
shell.msg "recover view text with `print viewtext'"
raise ShellError, "invalid reduce line at line #{i}"
end
unless reducef.nil?
shell.msg "recover view text with `print viewtext'"
raise ShellError, "duplicate reduce line at line #{i}"
end
inmap = false
inreduce = true
reducef = ""
else
if inmap
mapf << line
elsif inreduce
reducef << line
elsif line =~ /^\s*$/
else
shell.msg "recover view text with `print viewtext'"
raise ShellError, "unexpected content at line #{i}"
end
end
}
mapf.strip! if mapf
reducef.strip! if reducef
mapf = nil if mapf && mapf.empty?
reducef = nil if reducef && reducef.empty?
shell.prompt_msg "View parsed, following actions would be taken:"
if mapf && mapval.nil?
shell.prompt_msg " Add map function."
elsif mapf.nil? && mapval
shell.prompt_msg " Remove map function."
elsif mapf && mapval && mapf != mapval
shell.prompt_msg " Update map function."
end
if reducef && reduceval.nil?
shell.prompt_msg " Add reduce function."
elsif reducef.nil? && reduceval
shell.prompt_msg " Remove reduce function."
elsif reducef && reduceval && reducef != reduceval
shell.prompt_msg " Update reduce function."
end
continue? "Press ENTER to submit, CTRL+C to cancel "
if !design.respond_to?(:views)
design.set_attr!("views", {})
end
if view.nil?
design.views.set_attr!(view_name, {})
view = design.views[view_name]
end
if mapf.nil?
view.delete_attr!("map")
else
view.set_attr!("map", mapf)
end
if reducef.nil?
view.delete_attr!("reduce")
else
view.set_attr!("reduce", reducef)
end
shell.request "PUT", "_design/#{design_name}", design.to_s
unless shell.responses.current(&:ok?)
shell.msg "recover view text with `print viewtext'"
end
ensure
if t
t.close
t.unlink
end
end
|