1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
# Add speedup for model class creation from dataset
class Sequel::Postgres::Database
def optimize_model_load=(v)
Sequel::Deprecation.deprecate("Database#optimize_model_load= is deprecated. Optimized model loading is now enabled by default, and can only be disabled on a per-Dataset basis.")
v
end
def optimize_model_load
Sequel::Deprecation.deprecate("Database#optimize_model_load is deprecated. Optimized model loading is now enabled by default, and can only be disabled on a per-Dataset basis.")
true
end
end
# Add faster versions of Dataset#map, #as_hash, #to_hash_groups, #select_map, #select_order_map, and #select_hash
class Sequel::Postgres::Dataset
def optimize_model_load=(v)
Sequel::Deprecation.deprecate("Dataset#optimize_model_load= mutation method is deprecated. Switch to using Dataset#with_optimize_model_load, which returns a modified dataset")
opts[:optimize_model_load] = v
end
def optimize_model_load
Sequel::Deprecation.deprecate("Dataset#optimize_model_load method is deprecated. Optimized model loading is enabled by default.")
opts.has_key?(:optimize_model_load) ? opts[:optimize_model_load] : true
end
# :nocov:
if method_defined?(:as_set)
# :nocov:
if RUBY_VERSION > '4'
def as_set(column)
return super unless allow_sequel_pg_optimization?
clone(:_sequel_pg_type=>:map_set, :_sequel_pg_value=>column).fetch_rows(sql){|s| return s}
Set.new
end
# :nocov:
else
def as_set(column)
return super unless allow_sequel_pg_optimization?
rows = Set.new
clone(:_sequel_pg_type=>:map, :_sequel_pg_value=>column).fetch_rows(sql){|s| rows.add(s)}
rows
end
end
# :nocov:
end
# In the case where an argument is given, use an optimized version.
def map(sym=nil)
if sym
if block_given?
super
else
return super unless allow_sequel_pg_optimization?
clone(:_sequel_pg_type=>:map_array, :_sequel_pg_value=>sym).fetch_rows(sql){|a| return a}
[]
end
else
super
end
end
# Return a modified copy with the optimize_model_load setting changed.
def with_optimize_model_load(v)
clone(:optimize_model_load=>v)
end
# In the case where both arguments given, use an optimized version.
def as_hash(key_column, value_column = nil, opts = Sequel::OPTS)
if value_column && !opts[:hash]
return super unless allow_sequel_pg_optimization?
clone(:_sequel_pg_type=>:hash, :_sequel_pg_value=>[key_column, value_column]).fetch_rows(sql){|s| return s}
{}
elsif opts.empty?
super(key_column, value_column)
else
super
end
end
# :nocov:
unless Sequel::Dataset.method_defined?(:as_hash)
# Handle previous versions of Sequel that use to_hash instead of as_hash
alias to_hash as_hash
remove_method :as_hash
end
# :nocov:
# In the case where both arguments given, use an optimized version.
def to_hash_groups(key_column, value_column = nil, opts = Sequel::OPTS)
if value_column && !opts[:hash]
return super unless allow_sequel_pg_optimization?
clone(:_sequel_pg_type=>:hash_groups, :_sequel_pg_value=>[key_column, value_column]).fetch_rows(sql){|s| return s}
{}
elsif opts.empty?
super(key_column, value_column)
else
super
end
end
# Delegate to with_sql_all using the default SQL
def all(&block)
with_sql_all(sql, &block)
end
# :nocov:
# Generally overridden by the model support, only used if the model
# support is not used.
def with_sql_all(sql, &block)
return super unless allow_sequel_pg_optimization?
clone(:_sequel_pg_type=>:all).fetch_rows(sql) do |array|
if rp = row_proc
array.map!{|h| rp.call(h)}
end
post_load(array)
array.each(&block) if block
return array
end
[]
end
# :nocov:
protected
# Always use optimized version
def _select_map_multiple(ret_cols)
return super unless allow_sequel_pg_optimization?
clone(:_sequel_pg_type=>:array_array).fetch_rows(sql){|a| return a}
[]
end
# Always use optimized version
def _select_map_single
return super unless allow_sequel_pg_optimization?
clone(:_sequel_pg_type=>:first_array).fetch_rows(sql){|a| return a}
[]
end
# :nocov:
if method_defined?(:_select_set_multiple)
# :nocov:
if RUBY_VERSION > '4'
# Always use optimized version
def _select_set_multiple(ret_cols)
return super unless allow_sequel_pg_optimization?
clone(:_sequel_pg_type=>:array_set).fetch_rows(sql){|s| return s}
Set.new
end
# Always use optimized version
def _select_set_single
return super unless allow_sequel_pg_optimization?
clone(:_sequel_pg_type=>:first_set).fetch_rows(sql){|s| return s}
Set.new
end
# :nocov:
else
# Always use optimized version
def _select_set_multiple(ret_cols)
return super unless allow_sequel_pg_optimization?
set = Set.new
clone(:_sequel_pg_type=>:array).fetch_rows(sql){|s| set.add s}
set
end
# Always use optimized version
def _select_set_single
return super unless allow_sequel_pg_optimization?
set = Set.new
clone(:_sequel_pg_type=>:first).fetch_rows(sql){|s| set.add s}
set
end
end
# :nocov:
end
if defined?(Sequel::Model::ClassMethods)
require_relative 'model'
end
private
# Whether to allow sequel_pg to optimize the each/all/with_sql_all call.
def allow_sequel_pg_optimization?
(!opts[:graph] || opts[:eager_graph]) && !opts[:cursor]
end
end
if defined?(Sequel::Postgres::PGArray)
# pg_array extension previously loaded
class Sequel::Postgres::PGArray::Creator
# :nocov:
# Avoid method redefined verbose warning
alias call call if method_defined?(:call)
# :nocov:
# Override Creator to use sequel_pg's C-based parser instead of the pure ruby parser.
def call(string)
Sequel::Postgres::PGArray.new(Sequel::Postgres.parse_pg_array(string, @converter), @type)
end
end
# Remove the pure-ruby parser, no longer needed.
Sequel::Postgres::PGArray.send(:remove_const, :Parser)
end
|