Skip to content

Commit

Permalink
each_instance working again
Browse files Browse the repository at this point in the history
  • Loading branch information
afair committed May 16, 2014
1 parent bbe7f80 commit eeb30c4
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 11 deletions.
11 changes: 11 additions & 0 deletions active_record/connection_adapters/postgresql/get_type_map.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module PostgreSQLCursor
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
def get_type_map
type_map
end
end
end
end
end
11 changes: 9 additions & 2 deletions lib/postgresql_cursor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
require 'postgresql_cursor/cursor'
require 'postgresql_cursor/active_record/relation/cursor_iterators'
require 'postgresql_cursor/active_record/sql_cursor'
require 'postgresql_cursor/active_record/connection_adapters/postgresql_type_map'

# ActiveRecord 4.x
require 'active_record'
require 'active_record/connection_adapters/postgresql_adapter'
ActiveRecord::Base.include(PostgreSQLCursor::ActiveRecord::SqlCursor)
ActiveRecord::Relation.include(PostgreSQLCursor::ActiveRecord::Relation::CursorIterators)
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.include(PostgreSQLCursor::ActiveRecord::ConnectionAdapters::PostgreSQLTypeMap)

# Temp test
ActiveRecord::Base.establish_connection(
"postgres://#{ENV['USER']}:@localhost/#{ENV['USER']}"
)
Expand All @@ -17,5 +20,9 @@ class List < ActiveRecord::Base
self.table_name = 'list'
end

List.order("list_id").each_row {|r| p r }
List.order("list_id").each_instance {|r| p r }
List.order("list_id").each_hash {|r| p r }
List.order("list_id").each_instance {|r|
r.upd_ts
$r = r
p r
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# lib/postgresql_cursor/active_record/connection_adapters/postgresql_type_map
module PostgreSQLCursor
module ActiveRecord
module ConnectionAdapters
module PostgreSQLTypeMap
def get_type_map
type_map
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def each_row(options={}, &block)
options = {:connection => self.connection}.merge(options)
PostgreSQLCursor::Cursor.new(to_sql, options).each(&block)
end
alias :each_hash :each_row

# Public: Like each_row, but returns an instantiated model object to the block
#
Expand All @@ -26,9 +27,11 @@ def each_row(options={}, &block)
# Returns the number of rows yielded to the block
def each_instance(options={}, &block)
options = {:connection => self.connection}.merge(options)
PostgreSQLCursor::Cursor.new(to_sql, options).each do |row|
model = instantiate(row)
block.call model
options[:symbolize_keys] = false # Must be strings to initiate
pgresult = nil
PostgreSQLCursor::Cursor.new(to_sql, options).each do |row, column_types|
model = instantiate(row, column_types)
yield model
end
end
end
Expand Down
35 changes: 29 additions & 6 deletions lib/postgresql_cursor/cursor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,19 @@ def initialize(sql, options={})
#
# Returns the count of rows processed
def each(&block)
has_do_until = @options.has_key?(:until)
has_do_while = @options.has_key?(:while)
@count = 0
has_do_until = @options.has_key?(:until)
has_do_while = @options.has_key?(:while)
@count = 0
@column_types = nil
@connection.transaction do
begin
open
while (row = fetch) do
break if row.size==0
@count += 1
row = row.symbolize_keys
rc = yield row
# TODO: Handle exceptions raised within block
row = cast_types(row, column_types) if options[:symbolize_keys]
row = row.symbolize_keys if options[:cast]
rc = yield(row, column_types)
break if has_do_until && rc == @options[:until]
break if has_do_while && rc != @options[:while]
end
Expand All @@ -75,6 +76,28 @@ def each(&block)
@count
end

def cast_types(row)
row
end

def column_types
return @column_types if @column_types

types = {}
fields = @result.fields
fields.each_with_index do |fname, i|
ftype = @result.ftype i
fmod = @result.fmod i
types[fname] = @connection.get_type_map.fetch(ftype, fmod) { |oid, mod|
warn "unknown OID: #{fname}(#{oid}) (#{sql})"
OID::Identity.new
}

end

@column_types = types
end

# Public: Opens (actually, "declares") the cursor. Call this before fetching
def open
set_cursor_tuple_fraction
Expand Down

0 comments on commit eeb30c4

Please sign in to comment.