class ActiveRecord::PostgreSQLCursor

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.

Public Class Methods

new(model, cursor_name, relation, join_dependency = nil) click to toggle source
# File lib/activerecord-postgresql-cursors.rb, line 15
def initialize(model, cursor_name, relation, join_dependency = nil)
  @model = model
  @relation = relation
  @join_dependency = join_dependency

  @cursor_name = if cursor_name
    @model.connection.quote_table_name(cursor_name.gsub(/"/, '\"'))
  end

  @query = model.connection.unprepared_statement do
    relation.to_sql
  end
end

Public Instance Methods

each() { |instantiate.first| ... } click to toggle source

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

# File lib/activerecord-postgresql-cursors.rb, line 35
def each
  @model.transaction do
    begin
      declare_cursor
      if @join_dependency
        rows = Array.new
        last_id = nil

        while row = fetch_forward
          instantiated_row = @join_dependency.instantiate([row], @join_dependency.aliases).first

          current_id = instantiated_row[@join_dependency.join_root.primary_key]
          last_id ||= current_id
          if last_id == current_id
            rows << row
            last_id = current_id
          else
            yield @join_dependency.instantiate(rows, @join_dependency.aliases).first
            rows = [ row ]
          end
          last_id = current_id
        end

        if !rows.empty?
          yield @join_dependency.instantiate(rows, @join_dependency.aliases).first
        end
      else
        while row = fetch_forward
          yield @model.instantiate(row)
        end
      end
    ensure
      close_cursor
    end
  end
  nil
end
inspect() click to toggle source
# File lib/activerecord-postgresql-cursors.rb, line 29
def inspect
  %{#<ActiveRecord::PostgreSQLCursor cursor_name: "#{cursor_name}", query: "#{@query}">}
end

Private Instance Methods

cursor_name() click to toggle source
# File lib/activerecord-postgresql-cursors.rb, line 75
def cursor_name
  @cursor_name ||= "cursor_#{(rand * 1_000_000).ceil}"
end