From 0c4f1e4a9989c916229fc68a565ee09dfdb28399 Mon Sep 17 00:00:00 2001 From: Chris Anderson Date: Sun, 1 Jun 2008 11:21:21 -0700 Subject: [PATCH] view script --- script/push_views.rb | 60 ++++++++++++++++++++++++++++++ script/views | 88 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 script/push_views.rb create mode 100755 script/views diff --git a/script/push_views.rb b/script/push_views.rb new file mode 100644 index 0000000..9c2e6fd --- /dev/null +++ b/script/push_views.rb @@ -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 diff --git a/script/views b/script/views new file mode 100755 index 0000000..3855384 --- /dev/null +++ b/script/views @@ -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 \ No newline at end of file