sequel_pg_extended_columns 1.6.19

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.
@@ -0,0 +1,149 @@
1
+ unless Sequel::Postgres.respond_to?(:supports_streaming?)
2
+ raise LoadError, "either sequel_pg not loaded, or an old version of sequel_pg loaded"
3
+ end
4
+ unless Sequel::Postgres.supports_streaming?
5
+ raise LoadError, "streaming is not supported by the version of libpq in use"
6
+ end
7
+
8
+ # Database methods necessary to support streaming. You should load this extension
9
+ # into your database object:
10
+ #
11
+ # DB.extension(:pg_streaming)
12
+ #
13
+ # Then you can call #stream on your datasets to use the streaming support:
14
+ #
15
+ # DB[:table].stream.each{|row| ...}
16
+ #
17
+ # Or change a set so that all dataset calls use streaming:
18
+ #
19
+ # DB.stream_all_queries = true
20
+ module Sequel::Postgres::Streaming
21
+ attr_accessor :stream_all_queries
22
+
23
+ # Also extend the database's datasets to support streaming.
24
+ # This extension requires modifying connections, so disconnect
25
+ # so that new connections will get the methods.
26
+ def self.extended(db)
27
+ db.extend_datasets(DatasetMethods)
28
+ db.stream_all_queries = false
29
+ db.disconnect
30
+ end
31
+
32
+ # Make sure all new connections have the appropriate methods added.
33
+ def connect(server)
34
+ conn = super
35
+ conn.extend(AdapterMethods)
36
+ conn
37
+ end
38
+
39
+ private
40
+
41
+ # If streaming is requested, and a prepared statement is not
42
+ # used, tell the connection to use single row mode for the query.
43
+ def _execute(conn, sql, opts={}, &block)
44
+ if opts[:stream] && !sql.is_a?(Symbol)
45
+ conn.single_row_mode = true
46
+ end
47
+ super
48
+ end
49
+
50
+ # If streaming is requested, send the prepared statement instead
51
+ # of executing it and blocking.
52
+ def _execute_prepared_statement(conn, ps_name, args, opts)
53
+ if opts[:stream]
54
+ conn.send_prepared_statement(ps_name, args)
55
+ else
56
+ super
57
+ end
58
+ end
59
+
60
+ module AdapterMethods
61
+ # Whether the next query on this connection should use
62
+ # single_row_mode.
63
+ attr_accessor :single_row_mode
64
+
65
+ # Send the prepared statement on this connection using
66
+ # single row mode.
67
+ def send_prepared_statement(ps_name, args)
68
+ send_query_prepared(ps_name, args)
69
+ set_single_row_mode
70
+ block
71
+ self
72
+ end
73
+
74
+ private
75
+
76
+ if Sequel::Database.instance_methods.map(&:to_s).include?('log_connection_yield')
77
+ # If using single row mode, send the query instead of executing it.
78
+ def execute_query(sql, args)
79
+ if @single_row_mode
80
+ @single_row_mode = false
81
+ @db.log_connection_yield(sql, self, args){args ? send_query(sql, args) : send_query(sql)}
82
+ set_single_row_mode
83
+ block
84
+ self
85
+ else
86
+ super
87
+ end
88
+ end
89
+ else
90
+ def execute_query(sql, args)
91
+ if @single_row_mode
92
+ @single_row_mode = false
93
+ @db.log_yield(sql, args){args ? send_query(sql, args) : send_query(sql)}
94
+ set_single_row_mode
95
+ block
96
+ self
97
+ else
98
+ super
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ # Dataset methods used to implement streaming.
105
+ module DatasetMethods
106
+ # If streaming has been requested and the current dataset
107
+ # can be streamed, request the database use streaming when
108
+ # executing this query, and use yield_each_row to process
109
+ # the separate PGresult for each row in the connection.
110
+ def fetch_rows(sql)
111
+ if stream_results?
112
+ execute(sql, :stream=>true) do |conn|
113
+ yield_each_row(conn){|h| yield h}
114
+ end
115
+ else
116
+ super
117
+ end
118
+ end
119
+
120
+ # Use streaming to implement paging.
121
+ def paged_each(opts=Sequel::OPTS, &block)
122
+ stream.each(&block)
123
+ end
124
+
125
+ # Return a clone of the dataset that will use streaming to load
126
+ # rows.
127
+ def stream
128
+ clone(:stream=>true)
129
+ end
130
+
131
+ private
132
+
133
+ # Only stream results if streaming has been specifically requested
134
+ # and the query is streamable.
135
+ def stream_results?
136
+ (@opts[:stream] || db.stream_all_queries) && streamable?
137
+ end
138
+
139
+ # Queries using cursors are not streamable, and queries that use
140
+ # the map/select_map/to_hash/to_hash_groups optimizations are not
141
+ # streamable, but other queries are streamable.
142
+ def streamable?
143
+ spgt = (o = @opts)[:_sequel_pg_type]
144
+ (spgt.nil? || spgt == :model) && !o[:cursor]
145
+ end
146
+ end
147
+ end
148
+
149
+ Sequel::Database.register_extension(:pg_streaming, Sequel::Postgres::Streaming)
@@ -0,0 +1,103 @@
1
+ # Add speedup for model class creation from dataset
2
+ class Sequel::Postgres::Database
3
+ # Whether to optimize loads for all model datasets created from this dataset.
4
+ # Has certain limitations, see the README for details.
5
+ attr_accessor :optimize_model_load
6
+ end
7
+
8
+ # Add faster versions of Dataset#map, #to_hash, #select_map, #select_order_map, and #select_hash
9
+ class Sequel::Postgres::Dataset
10
+ # Set whether to enable optimized model loading for this dataset.
11
+ attr_writer :optimize_model_load
12
+
13
+ # In the case where an argument is given, use an optimized version.
14
+ def map(sym=nil)
15
+ if sym
16
+ if block_given?
17
+ super
18
+ else
19
+ rows = []
20
+ clone(:_sequel_pg_type=>:map, :_sequel_pg_value=>sym).fetch_rows(sql){|s| rows << s}
21
+ rows
22
+ end
23
+ else
24
+ super
25
+ end
26
+ end
27
+
28
+ # If this dataset has turned model loading on or off, use the default value from
29
+ # the Database object.
30
+ def optimize_model_load
31
+ defined?(@optimize_model_load) ? @optimize_model_load : db.optimize_model_load
32
+ end
33
+
34
+ # In the case where both arguments given, use an optimized version.
35
+ def to_hash(key_column, value_column = nil, opts = Sequel::OPTS)
36
+ if value_column && !opts[:hash]
37
+ clone(:_sequel_pg_type=>:hash, :_sequel_pg_value=>[key_column, value_column]).fetch_rows(sql){|s| return s}
38
+ elsif opts.empty?
39
+ super(key_column, value_column)
40
+ else
41
+ super
42
+ end
43
+ end
44
+
45
+ # In the case where both arguments given, use an optimized version.
46
+ def to_hash_groups(key_column, value_column = nil, opts = Sequel::OPTS)
47
+ if value_column && !opts[:hash]
48
+ clone(:_sequel_pg_type=>:hash_groups, :_sequel_pg_value=>[key_column, value_column]).fetch_rows(sql){|s| return s}
49
+ elsif opts.empty?
50
+ super(key_column, value_column)
51
+ else
52
+ super
53
+ end
54
+ end
55
+
56
+ # If model loads are being optimized and this is a model load, use the optimized
57
+ # version.
58
+ def each
59
+ if (rp = row_proc) && optimize_model_load?
60
+ clone(:_sequel_pg_type=>:model, :_sequel_pg_value=>rp).fetch_rows(sql, &Proc.new)
61
+ else
62
+ super
63
+ end
64
+ end
65
+
66
+ protected
67
+
68
+ # Always use optimized version
69
+ def _select_map_multiple(ret_cols)
70
+ rows = []
71
+ clone(:_sequel_pg_type=>:array).fetch_rows(sql){|s| rows << s}
72
+ rows
73
+ end
74
+
75
+ # Always use optimized version
76
+ def _select_map_single
77
+ rows = []
78
+ clone(:_sequel_pg_type=>:first).fetch_rows(sql){|s| rows << s}
79
+ rows
80
+ end
81
+
82
+ private
83
+
84
+ # The model load can only be optimized if it's for a model and it's not a graphed dataset
85
+ # or using a cursor.
86
+ def optimize_model_load?
87
+ (rp = row_proc).is_a?(Class) && (rp < Sequel::Model) && optimize_model_load && !opts[:use_cursor] && !opts[:graph]
88
+ end
89
+ end
90
+
91
+ if defined?(Sequel::Postgres::PGArray)
92
+ # pg_array extension previously loaded
93
+
94
+ class Sequel::Postgres::PGArray::Creator
95
+ # Override Creator to use sequel_pg's C-based parser instead of the pure ruby parser.
96
+ def call(string)
97
+ Sequel::Postgres::PGArray.new(Sequel::Postgres.parse_pg_array(string, @converter), @type)
98
+ end
99
+ end
100
+
101
+ # Remove the pure-ruby parser, no longer needed.
102
+ Sequel::Postgres::PGArray.send(:remove_const, :Parser)
103
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel_pg_extended_columns
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.6.19
5
+ platform: ruby
6
+ authors:
7
+ - Mansoor Ali Khan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-11-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pg
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.18.0
20
+ - - "!="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.2.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.18.0
30
+ - - "!="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.2.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: sequel
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 4.38.0
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 4.38.0
47
+ description: |
48
+ sequel_pg overwrites the inner loop of the Sequel postgres
49
+ adapter row fetching code with a C version. The C version
50
+ is significantly faster than the pure ruby version
51
+ that Sequel uses by default.
52
+
53
+ sequel_pg also offers optimized versions of some dataset
54
+ methods, as well as adds support for using PostgreSQL
55
+ streaming.
56
+ email: mansoorkhan108@gmail.com
57
+ executables: []
58
+ extensions:
59
+ - ext/sequel_pg/extconf.rb
60
+ extra_rdoc_files:
61
+ - README.rdoc
62
+ - CHANGELOG
63
+ - MIT-LICENSE
64
+ files:
65
+ - CHANGELOG
66
+ - MIT-LICENSE
67
+ - README.rdoc
68
+ - Rakefile
69
+ - ext/sequel_pg/extconf.rb
70
+ - ext/sequel_pg/sequel_pg.c
71
+ - lib/sequel/extensions/pg_streaming.rb
72
+ - lib/sequel_pg/sequel_pg.rb
73
+ homepage: https://github.com/mansoorkhan108/sequel_pg
74
+ licenses:
75
+ - MIT
76
+ metadata:
77
+ bug_tracker_uri: https://github.com/jeremyevans/sequel_pg/issues
78
+ changelog_uri: https://github.com/jeremyevans/sequel_pg/blob/master/CHANGELOG
79
+ documentation_uri: https://github.com/jeremyevans/sequel_pg/blob/master/README.rdoc
80
+ mailing_list_uri: https://groups.google.com/forum/#!forum/sequel-talk
81
+ source_code_uri: https://github.com/jeremyevans/sequel_pg
82
+ post_install_message:
83
+ rdoc_options:
84
+ - "--quiet"
85
+ - "--line-numbers"
86
+ - "--inline-source"
87
+ - "--title"
88
+ - 'sequel_pg: Faster SELECTs when using Sequel with pg'
89
+ - "--main"
90
+ - README.rdoc
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: 1.9.3
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubygems_version: 3.0.8
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: Faster SELECTs when using Sequel with pg
108
+ test_files: []