postgresql_cursor 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.rdoc +10 -6
- data/VERSION +1 -1
- data/lib/postgresql_cursor.rb +9 -5
- data/postgresql_cursor.gemspec +6 -5
- data/test/helper.rb +2 -2
- data/test/test_postgresql_cursor.rb +3 -1
- metadata +10 -14
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c7761053fbe88cc359b47415f7e79b620defe326
|
4
|
+
data.tar.gz: 8398abd146476cc6ddfa637e3d5215fcc446be38
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 18ebbe7bfa3fdee1435909725be137bf7b895f55f3ad87620a5486697fa67f06afab79d117945643ecbe2e4b1f7e6d6c6e30364358763429beb2c720cfe1d9fe
|
7
|
+
data.tar.gz: 482aeffdbe884a29ca1e05b8a860e897845c9cc86d134c4512475c2039c5f448c2585298c444f89a0afd4f4b781bd4b3221c2deccb321eba6b68f1d178abe49e
|
data/README.rdoc
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
= PostgreSQLCursor for handling large Result Sets
|
2
2
|
|
3
|
+
{<img src="https://badge.fury.io/rb/postgresql_cursor.svg" alt="Gem Version" />}[http://badge.fury.io/rb/postgresql_cursor]
|
4
|
+
|
3
5
|
PostgreSQLCursor extends ActiveRecord to allow for efficient processing of queries
|
4
6
|
returning a large number of rows.
|
5
7
|
|
8
|
+
Note: Rails/ActiveRecord 4.x support has been reworked in the v0.5 Branch. For AR < 4.x, use the gem 0.4.x series.
|
9
|
+
|
6
10
|
== Why use this?
|
7
11
|
|
8
12
|
ActiveRecord is designed and optimized for web performance. In a web transaction, only a "page" of
|
@@ -11,10 +15,10 @@ around 20 rows is returned to the user. When you do this
|
|
11
15
|
Model.find(:all, :conditions=>["id>0"]
|
12
16
|
|
13
17
|
The database returns all matching result set rows to ActiveRecord, which instantiates each row with
|
14
|
-
the data returned. This function returns an array of all these rows to the caller.
|
18
|
+
the data returned. This function returns an array of all these rows to the caller.
|
15
19
|
|
16
20
|
Asyncronous, Background, or Offline processing may require processing a large amount of data.
|
17
|
-
When there is a very large number of rows, this requires a lot more memory to hold the data. Ruby
|
21
|
+
When there is a very large number of rows, this requires a lot more memory to hold the data. Ruby
|
18
22
|
does not return that memory after processing the array, and the causes your process to "bloat". If you
|
19
23
|
don't have enough memory, it will cause an exception.
|
20
24
|
|
@@ -44,7 +48,7 @@ to declare a cursor to run a given query returning "chunks" of rows to the appli
|
|
44
48
|
retaining the position of the full result set in the database. This overcomes all the disadvantages
|
45
49
|
of using find_each and find_in_batches.
|
46
50
|
|
47
|
-
Also, with PostgreSQL, you have on option to have raw hashes of the row returned instead of the
|
51
|
+
Also, with PostgreSQL, you have on option to have raw hashes of the row returned instead of the
|
48
52
|
instantiated models. An informal benchmark showed that returning instances is a factor of 4 times
|
49
53
|
slower than returning hashes. If you are can work with the data in this form, you will find better
|
50
54
|
performance.
|
@@ -54,7 +58,7 @@ With PostgreSQL, you can work with cursors as follows:
|
|
54
58
|
Model.where("id>0").each_row { |hash| Model.process(hash) }
|
55
59
|
|
56
60
|
Model.where("id>0").each_instance { |model| model.process! }
|
57
|
-
Model.where("id>0").each_instance(
|
61
|
+
Model.where("id>0").each_instance(block_size:100000) { |model| model.process! }
|
58
62
|
|
59
63
|
Model.each_row_by_sql("select * from models") { |hash| Model.process(hash) }
|
60
64
|
|
@@ -62,7 +66,7 @@ With PostgreSQL, you can work with cursors as follows:
|
|
62
66
|
|
63
67
|
All these methods take an options hash to control things more:
|
64
68
|
|
65
|
-
|
69
|
+
block_size:n The number of rows to fetch from the database each time (default 1000)
|
66
70
|
while:value Continue looping as long as the block returns this value
|
67
71
|
until:value Continue looping until the block returns this value
|
68
72
|
connection:conn Use this connection instead of the current model connection
|
@@ -79,7 +83,7 @@ Thank you to:
|
|
79
83
|
* Julian Mehnle, julian@mehnle.net (Suggestions)
|
80
84
|
|
81
85
|
== Note on Patches/Pull Requests
|
82
|
-
|
86
|
+
|
83
87
|
* Fork the project.
|
84
88
|
* Make your feature addition or bug fix.
|
85
89
|
* Add tests for it. This is important so I don't break it in a
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.3
|
data/lib/postgresql_cursor.rb
CHANGED
@@ -65,8 +65,9 @@ class PostgreSQLCursor
|
|
65
65
|
break if has_do_while && rc != @options[:while]
|
66
66
|
end
|
67
67
|
rescue Exception => e
|
68
|
-
close
|
69
68
|
raise e
|
69
|
+
ensure
|
70
|
+
close
|
70
71
|
end
|
71
72
|
end
|
72
73
|
@count
|
@@ -89,7 +90,7 @@ class PostgreSQLCursor
|
|
89
90
|
end
|
90
91
|
|
91
92
|
# Private: Fetches the next block of rows into @block
|
92
|
-
def
|
93
|
+
def fetch_block(block_size=nil)
|
93
94
|
block_size ||= @block_size ||= @options.fetch(:block_size) { 1000 }
|
94
95
|
@result = @connection.execute("fetch #{block_size} from cursor_#{@cursor}")
|
95
96
|
@block = @result.collect {|row| row } # Make our own
|
@@ -116,7 +117,6 @@ end
|
|
116
117
|
|
117
118
|
# Defines extension to ActiveRecord to use this library
|
118
119
|
class ActiveRecord::Base
|
119
|
-
|
120
120
|
# Public: Returns each row as a hash to the given block
|
121
121
|
#
|
122
122
|
# sql - Full SQL statement, variables interpolated
|
@@ -128,6 +128,7 @@ class ActiveRecord::Base
|
|
128
128
|
#
|
129
129
|
# Returns the number of rows yielded to the block
|
130
130
|
def self.each_row_by_sql(sql, options={}, &block)
|
131
|
+
options = {:connection => self.connection}.merge(options)
|
131
132
|
PostgreSQLCursor.new(sql, options).each(&block)
|
132
133
|
end
|
133
134
|
|
@@ -138,6 +139,7 @@ class ActiveRecord::Base
|
|
138
139
|
#
|
139
140
|
# Returns the number of rows yielded to the block
|
140
141
|
def self.each_instance_by_sql(sql, options={}, &block)
|
142
|
+
options = {:connection => self.connection}.merge(options)
|
141
143
|
PostgreSQLCursor.new(sql, options).each do |row|
|
142
144
|
model = instantiate(row)
|
143
145
|
yield model
|
@@ -159,7 +161,8 @@ class ActiveRecord::Relation
|
|
159
161
|
#
|
160
162
|
# Returns the number of rows yielded to the block
|
161
163
|
def each_row(options={}, &block)
|
162
|
-
|
164
|
+
options = {:connection => self.connection}.merge(options)
|
165
|
+
PostgreSQLCursor.new(to_sql, options).each(&block)
|
163
166
|
end
|
164
167
|
|
165
168
|
# Public: Like each_row, but returns an instantiated model object to the block
|
@@ -168,9 +171,10 @@ class ActiveRecord::Relation
|
|
168
171
|
#
|
169
172
|
# Returns the number of rows yielded to the block
|
170
173
|
def each_instance(options={}, &block)
|
174
|
+
options = {:connection => self.connection}.merge(options)
|
171
175
|
PostgreSQLCursor.new(to_sql, options).each do |row|
|
172
176
|
model = instantiate(row)
|
173
|
-
|
177
|
+
block.call model
|
174
178
|
end
|
175
179
|
end
|
176
180
|
end
|
data/postgresql_cursor.gemspec
CHANGED
@@ -2,14 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: postgresql_cursor 0.4.3 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "postgresql_cursor"
|
8
|
-
s.version = "0.4.
|
9
|
+
s.version = "0.4.3"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
11
13
|
s.authors = ["Allen Fair"]
|
12
|
-
s.date = "
|
14
|
+
s.date = "2014-06-06"
|
13
15
|
s.description = "PostgreSQL Cursor is an extension to the ActiveRecord PostgreSQLAdapter for very large result sets. It provides a cursor open/fetch/close interface to access data without loading all rows into memory, and instead loads the result rows in \"chunks\" (default of 10_000 rows), buffers them, and returns the rows one at a time."
|
14
16
|
s.email = "allen.fair@gmail.com"
|
15
17
|
s.extra_rdoc_files = [
|
@@ -28,12 +30,11 @@ Gem::Specification.new do |s|
|
|
28
30
|
"test/test_postgresql_cursor.rb"
|
29
31
|
]
|
30
32
|
s.homepage = "http://github.com/afair/postgresql_cursor"
|
31
|
-
s.
|
32
|
-
s.rubygems_version = "1.8.24"
|
33
|
+
s.rubygems_version = "2.2.1"
|
33
34
|
s.summary = "ActiveRecord PostgreSQL Adapter extension for using a cursor to return a large result set"
|
34
35
|
|
35
36
|
if s.respond_to? :specification_version then
|
36
|
-
s.specification_version =
|
37
|
+
s.specification_version = 4
|
37
38
|
|
38
39
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
39
40
|
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
data/test/helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require '
|
2
|
+
require 'minitest'
|
3
3
|
require 'active_record'
|
4
4
|
|
5
5
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
@@ -21,5 +21,5 @@ end
|
|
21
21
|
|
22
22
|
Model.generate(1000) if Model.count == 0
|
23
23
|
|
24
|
-
class
|
24
|
+
class MiniTest::Unit::TestCase
|
25
25
|
end
|
metadata
CHANGED
@@ -1,30 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postgresql_cursor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.3
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Allen Fair
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-06-06 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: activerecord
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
description: PostgreSQL Cursor is an extension to the ActiveRecord PostgreSQLAdapter
|
@@ -38,7 +35,7 @@ extra_rdoc_files:
|
|
38
35
|
- LICENSE
|
39
36
|
- README.rdoc
|
40
37
|
files:
|
41
|
-
- .document
|
38
|
+
- ".document"
|
42
39
|
- LICENSE
|
43
40
|
- README.rdoc
|
44
41
|
- Rakefile
|
@@ -49,27 +46,26 @@ files:
|
|
49
46
|
- test/test_postgresql_cursor.rb
|
50
47
|
homepage: http://github.com/afair/postgresql_cursor
|
51
48
|
licenses: []
|
49
|
+
metadata: {}
|
52
50
|
post_install_message:
|
53
51
|
rdoc_options: []
|
54
52
|
require_paths:
|
55
53
|
- lib
|
56
54
|
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
55
|
requirements:
|
59
|
-
- -
|
56
|
+
- - ">="
|
60
57
|
- !ruby/object:Gem::Version
|
61
58
|
version: '0'
|
62
59
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
-
none: false
|
64
60
|
requirements:
|
65
|
-
- -
|
61
|
+
- - ">="
|
66
62
|
- !ruby/object:Gem::Version
|
67
63
|
version: '0'
|
68
64
|
requirements: []
|
69
65
|
rubyforge_project:
|
70
|
-
rubygems_version:
|
66
|
+
rubygems_version: 2.2.1
|
71
67
|
signing_key:
|
72
|
-
specification_version:
|
68
|
+
specification_version: 4
|
73
69
|
summary: ActiveRecord PostgreSQL Adapter extension for using a cursor to return a
|
74
70
|
large result set
|
75
71
|
test_files: []
|