Class: ActiveRecord::PostgreSQLCursor

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/activerecord-postgresql-cursors.rb,
lib/active_record/postgresql_cursors/cursors.rb,
lib/active_record/postgresql_cursors/cursors_2.rb

Overview

PostgreSQLCursor is an Enumerable class so you can use each, map, any? and all of those nice Enumerable methods.

At the moment, cursors aren’t scrollable and are fetch forward-only and read-only.

This class isn’t really meant to be used outside of the ActiveRecord::Base#find method.

Instance Method Summary collapse

Constructor Details

#initialize(model, cursor_name, query, join_dependency = nil) ⇒ PostgreSQLCursor

Returns a new instance of PostgreSQLCursor.



31
32
33
34
35
36
37
38
# File 'lib/activerecord-postgresql-cursors.rb', line 31

def initialize(model, cursor_name, query, join_dependency = nil)
  @model = model
  @cursor_name = if cursor_name
    @model.connection.quote_table_name(cursor_name.gsub(/"/, '\"'))
  end
  @query = query
  @join_dependency = join_dependency
end

Instance Method Details

#eachObject

Calls block once for each record in the cursor, passing that record as a parameter.



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
# File 'lib/activerecord-postgresql-cursors.rb', line 46

def each
  @model.transaction do
    begin
      declare_cursor
      if @join_dependency
        rows = Array.new
        last_id = nil
        while row = fetch_forward
          current_id = row[@join_dependency.join_base.aliased_primary_key]
          last_id ||= current_id
          if last_id == current_id
            rows << row
            last_id = current_id
          else
            yield @join_dependency.instantiate(rows).first
            @join_dependency.clear_with_cursor
            rows = [ row ]
          end
          last_id = current_id
        end

        if !rows.empty?
          yield @join_dependency.instantiate(rows).first
        end
      else
        while row = fetch_forward
          yield row
        end
      end
    ensure
      close_cursor
    end
  end
  nil
end

#initialize_with_rails(model, cursor_name, relation, join_dependency = nil) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/active_record/postgresql_cursors/cursors.rb', line 69

def initialize_with_rails(model, cursor_name, relation, join_dependency = nil)
  @relation = relation

  query = if ActiveRecord::VERSION::MAJOR >= 4
    model.connection.unprepared_statement do
      relation.to_sql
    end
  else
    relation.to_sql
  end

  initialize_without_rails(model, cursor_name, query, join_dependency)
end

#initialize_with_rails_2(model, cursor_name, query, join_dependency = nil) ⇒ Object



70
71
72
# File 'lib/active_record/postgresql_cursors/cursors_2.rb', line 70

def initialize_with_rails_2(model, cursor_name, query, join_dependency = nil)
  initialize_without_rails_2(model, cursor_name, query, join_dependency)
end

#inspectObject



40
41
42
# File 'lib/activerecord-postgresql-cursors.rb', line 40

def inspect
  %{#<ActiveRecord::PostgreSQLCursor cursor_name: "#{cursor_name}", query: "#{@query}">}
end