diff --git a/CHANGELOG.md b/CHANGELOG.md index 0347be8..c6ecf19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +Version 0.9.x + + * Added Garb::Model.all that paginates all data + Version 0.9.2 * Removed all deprecated features: Garb::Report, Garb::Resource, Garb::Profile, and Garb::Account diff --git a/README.md b/README.md index 05272c8..27c014a 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,13 @@ Get the Results Be forewarned, these numbers are for the last **30** days and may be slightly different from the numbers displayed in Google Analytics' dashboard for **1 month**. +Get all Results +--------------- + +Google Analytics returns 1000 results at a time. To paginate over all results: + + > Exits.all(profile) { |exit| ... } + Other Parameters ---------------- diff --git a/lib/garb/model.rb b/lib/garb/model.rb index d7c4ad4..d4d6a5d 100644 --- a/lib/garb/model.rb +++ b/lib/garb/model.rb @@ -43,6 +43,20 @@ def results(profile, options = {}) data = send_request_for_data(profile, build_params(param_set)) ReportResponse.new(data, instance_klass).results end + + def all(profile, options = {}, &block) + limit = options.delete(:limit) + total = 0 + while ((rs = results(profile, options)) && rs.any?) + rs.each do |r| + yield r + total += 1 + return self if limit and total >= limit + end + options[:offset] = total + end + self + end private def send_request_for_data(profile, params) @@ -86,4 +100,4 @@ def format_time(t) t.strftime('%Y-%m-%d') end end -end \ No newline at end of file +end diff --git a/test/unit/garb/model_test.rb b/test/unit/garb/model_test.rb index 8fbd62b..37415a2 100644 --- a/test/unit/garb/model_test.rb +++ b/test/unit/garb/model_test.rb @@ -108,7 +108,7 @@ class ModelTest < MiniTest::Unit::TestCase assert_equal ['result'], @test_model.results(@profile, :limit => 20) assert_data_params(@params.merge({'max-results' => 20})) end - + should "be able to offset" do assert_equal ['result'], @test_model.results(@profile, :offset => 10) assert_data_params(@params.merge({'start-index' => 10})) @@ -128,6 +128,28 @@ class ModelTest < MiniTest::Unit::TestCase assert_equal ['result'], @test_model.results(@profile) assert_received(ReportResponse, :new) {|e| e.with("raw report data", ResultKlass)} end + + should "be able to fetch multiple pages of results" do + results = [] + count = 0 + @test_model.all(@profile) do |result| + results << result + # stub a subsequent response + count += 1 + ReportResponse.stubs(:new).returns(stub(:results => [])) if count == 2 + end + assert_equal ['result', 'result'], results + end + + should "be able to fetch multiple pages of results with a limit" do + results = [] + @test_model.all(@profile, :limit => 1) do |result| + results << result + end + assert_equal ['result'], results + end + + end # should "return results as an array of the class it belongs to, if that class is an ActiveRecord descendant"