#41 new
Julien Sanchez

Some streamer fixes

Reported by Julien Sanchez | October 8th, 2009 @ 04:58 AM

Some fixes I hope useful and correct:
* url must be quoted inside the curl command otherwise '&' between params are interpreted by shells * View url format updated * Streamer yielded the last row returned by curl ("}]") as nil

From 54dee070ad3e3ecc2543ce034380d3d577bd25dc Mon Sep 17 00:00:00 2001
From: Julien Sanchez <julien.sanchez@lim.eu>
Date: Thu, 8 Oct 2009 12:27:22 +0200
Subject: [PATCH] Streamer fixes

* url must be quoted inside the curl command otherwise '&' between
  params are interpreted by shells
* View url format updated
* Streamer yielded the last row returned by curl ("}]") as nil
* Specs
---
 lib/couchrest/helper/streamer.rb        |   15 ++++++++++---
 spec/couchrest/core/database_spec.rb    |   11 ++++++++-
 spec/couchrest/helpers/streamer_spec.rb |   33 +++++++++++++++++++++++++++++-
 3 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/lib/couchrest/helper/streamer.rb b/lib/couchrest/helper/streamer.rb
index 6d48ca0..35eb824 100644
--- a/lib/couchrest/helper/streamer.rb
+++ b/lib/couchrest/helper/streamer.rb
@@ -7,15 +7,22 @@ module CouchRest
     
     # Stream a view, yielding one row at a time. Shells out to <tt>curl</tt> to keep RAM usage low when you have millions of rows.
     def view name, params = nil, &block
-      urlst = /^_/.match(name) ? "#{@db.root}/#{name}" : "#{@db.root}/_view/#{name}"
+      urlst = if /^_/.match(name) then
+        "#{@db.root}/#{name}"
+      else
+        name = name.split('/')
+        dname = name.shift
+        vname = name.join('/')
+        "#{@db.root}/_design/#{dname}/_view/#{vname}"
+      end
       url = CouchRest.paramify_url urlst, params
       # puts "stream #{url}"
       first = nil
-      IO.popen("curl --silent #{url}") do |view|
+      IO.popen("curl --silent \"#{url}\"") do |view|
         first = view.gets # discard header
         while line = view.gets 
           row = parse_line(line)
-          block.call row
+          block.call row unless row.nil? # last line "}]" discarded
         end
       end
       parse_first(first)
@@ -41,4 +48,4 @@ module CouchRest
     end
     
   end
-end
\ No newline at end of file
+end
diff --git a/spec/couchrest/core/database_spec.rb b/spec/couchrest/core/database_spec.rb
index ff7982f..e315a6d 100644
--- a/spec/couchrest/core/database_spec.rb
+++ b/spec/couchrest/core/database_spec.rb
@@ -131,9 +131,16 @@ describe CouchRest::Database do
       rs = @db.view('first/test', :include_docs => true) do |row|
         rows << row
       end
-      rows.length.should == 4
+      rows.length.should == 3
       rs["total_rows"].should == 3
     end
+    it "should accept a block with several params" do
+      rows = []
+      rs = @db.view('first/test', :include_docs => true, :limit => 2) do |row|
+        rows << row
+      end
+      rows.length.should == 2
+    end
   end
 
   describe "GET (document by id) when the doc exists" do
@@ -711,4 +718,4 @@ describe CouchRest::Database do
   end
 
 
-end
\ No newline at end of file
+end
diff --git a/spec/couchrest/helpers/streamer_spec.rb b/spec/couchrest/helpers/streamer_spec.rb
index cf828ca..48ec6c3 100644
--- a/spec/couchrest/helpers/streamer_spec.rb
+++ b/spec/couchrest/helpers/streamer_spec.rb
@@ -9,6 +9,14 @@ describe CouchRest::Streamer do
     @streamer = CouchRest::Streamer.new(@db)
     @docs = (1..1000).collect{|i| {:integer => i, :string => i.to_s}}
     @db.bulk_save(@docs)
+    @db.save_doc({
+      "_id" => "_design/first",
+      :views => {
+        :test => {
+     :map => "function(doc){for(var w in doc){ if(!w.match(/^_/))emit(w,doc[w])}}"
+        }
+      }
+    })
   end
   
   it "should yield each row in a view" do
@@ -19,5 +27,26 @@ describe CouchRest::Streamer do
     end
     count.should == 1001
   end
-  
-end
\ No newline at end of file
+
+  it "should accept several params" do
+    count = 0
+    @streamer.view("_design/first/_view/test", :include_docs => true, :limit => 5) do |row|
+      count += 1
+    end
+    count.should == 5
+  end
+
+  it "should accept both view formats" do
+    count = 0
+    @streamer.view("_design/first/_view/test") do |row|
+      count += 1
+    end
+    count.should == 2000
+    count = 0
+    @streamer.view("first/test") do |row|
+      count += 1
+    end
+    count.should == 2000
+  end
+
+end
-- 
1.6.5.rc1

Comments and changes to this ticket

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

"CouchDB, close to the metal." <a href="http://github.com/jchris/couchrest/tree/master">CouchRest</a> is a RESTful layer for accessing CouchDB, based off CouchDB's included Javascript reference client. CouchRest also includes helpers for running large queries etc. There is also a base class for ActiveRecord / Datamapper style ORM, called CouchRest::Model.

People watching this ticket

Pages