view script

This commit is contained in:
Chris Anderson 2008-06-01 11:21:21 -07:00
parent 4063210302
commit 0c4f1e4a99
2 changed files with 148 additions and 0 deletions

60
script/push_views.rb Normal file
View file

@ -0,0 +1,60 @@
$: << File.expand_path(File.dirname(__FILE__)) + '/..'
require 'lib/parse'
require 'couchrest/couchrest'
require 'vendor/jsmin/lib/jsmin'
# require 'yaml'
# connect to couchdb
cr = CouchRest.new("http://localhost:5984")
cr.create_db('grabbit-import') rescue nil
db = cr.database('grabbit-import')
# create views from files
views = {}
viewfiles = Dir.glob(File.join(File.expand_path(File.dirname(__FILE__)),"..","views","**","*.js"))
libfiles = viewfiles.select{|f|/lib\.js/.match(f)}
all = (viewfiles-libfiles).collect do |file|
filename = /(\w.*)-(\w.*)\.js/.match file.split('/').pop
filename.to_a + [file]
end
@libfuncs = open(libfiles[0]).read
def readjs(file)
st = open(file).read
st.sub!(/\/\/include-lib/,@libfuncs)
JSMin.minify(st)
end
all.group_by do |f|
f[3].split('/')[-2]
end.each do |design,ps|
views[design] ||= {}
puts "design #{design}"
ps.group_by do |f|
f[1]
end.each do |view,parts|
puts "view #{view}"
views[design]["#{view}-reduce"] ||= {}
parts.each do |p|
puts "part #{p.inspect}"
views[design]["#{view}-reduce"][p[2]] = readjs(p[3])
end
views[design]["#{view}-map"] = {:map => views[design]["#{view}-reduce"]['map']}
views[design].delete("#{view}-reduce") unless views[design]["#{view}-reduce"]['reduce']
end
end
views.each do |design,viewfuncs|
begin
view = db.get("_design/#{design}")
db.delete(view)
rescue
end
db.save({
"_id" => "_design/#{design}",
:views => viewfuncs
})
end

88
script/views Executable file
View file

@ -0,0 +1,88 @@
#!/usr/bin/env ruby
commands = %w{pull push}
command = ARGV[0]
if !commands.include?(command)
puts <<-USAGE
Usage: script/views (pull|push) my-database-name
For help on pull and push run script/views (pull|push) without a database name.
USAGE
exit
end
if ARGV.length == 1
case command
when "pull"
puts <<-PULL
script/views pull my-database-name
I will automagically create a "views" directory in your current working directory if none exists.
Then I copy the design documents and views into a directory structure like:
./views/my-design-doc/view-name-map.js
./views/my-design-doc/view-name-reduce.js
If your view names don't end in "map" or "reduce" I'll add those suffixes as a pull. On push I'll put them in new locations corresponding to these new names (overwriting the old design documents). I'm opinionated, but if these conventions don't work for you, the source code is right here.
PULL
when "push"
puts <<-PUSH
script/views push my-database-name
I'll push all the files in your views directory to the specified database. Because CouchDB caches the results of view calculation by function content, there's no performance penalty for duplicating the map function twice, which I'll do if you have a reduce function. This makes it possible to browse the results of just the map, which can be useful for both queries and debugging.
./views/my-design-doc/view-name-map.js
./views/my-design-doc/view-name-reduce.js
Pushed to =>
http://localhost:5984/my-database-name/_design/my-design-doc
{
"views" : {
"view-name-map" : {
"map" : "### contents of view-name-map.js ###"
},
"view-name-reduce" : {
"map" : "### contents of view-name-map.js ###",
"reduce" : "### contents of view-name-reduce.js ###"
},
}
}
PUSH
end
exit
end
dbname = ARGV[1]
puts "Running #{command} on #{dbname}."
require File.expand_path(File.dirname(__FILE__)) + '/../couchrest'
# connect to couchdb
cr = CouchRest.new("http://localhost:5984")
db = cr.database(dbname)
__END__
#views to files
ds = db.documents(:startkey => '_design/', :endkey => '_design/ZZ')
ds['rows'].collect{|r|r['id']}.each do |id|
puts directory = id.split('/').last
db.get(id)['views'].each do |view,funcs|
next if /-map$/.match(view)
['map', 'reduce'].each do |func|
next unless funcs[func]
mapfile = File.join("views",directory,"#{view}-#{func}.js")
puts mapfile
File.open(mapfile,'w') do |f|
f.write funcs[func]
end
end
end
end