class SQLite3::Database
def create_aggregate(name, arity, step = nil, finalize = nil, text_rep = Constants::TextRep::ANY, &block)
See also #create_aggregate_handler for a more object-oriented approach to
puts db.get_first_value("select lengths(name) from table")
end
end
func.set_result(func[:total] || 0)
finalize do |func|
end
func[:total] += (value ? value.length : 0)
func[:total] ||= 0
step do |func, value|
db.create_aggregate("lengths", 1) do
Example:
store the result of the function.
function invocation. It should invoke FunctionProxy#set_result to
single parameter, the FunctionProxy instance representing the current
The +finalize+ parameter must be a +proc+ object that accepts only a
The +step+ callback will be invoked once for each row of the result set.
invocation), with any subsequent parameters (up to the function's arity).
parameter a FunctionProxy instance (representing the function
The +step+ parameter must be a proc object that accepts as its first
variable arity functions, use -1 for the arity.)
The new function will be added as +name+, with the given +arity+. (For
a query.)
is the "count" function, for determining the number of rows that match
instead of over just a single row. (A very common aggregate function
functions are functions that apply over every row in the result set,
Creates a new aggregate function for use in SQL statements. Aggregate
def create_aggregate(name, arity, step = nil, finalize = nil, text_rep = Constants::TextRep::ANY, &block) # begin if block proxy = AggregateDefinitionProxy.new proxy.instance_eval(&block) step ||= proxy.step_callback finalize ||= proxy.finalize_callback end step_callback = proc do |func, *args| ctx = @driver.aggregate_context(func) unless ctx[:__error] begin step.call(FunctionProxy.new(@driver, func, ctx), *args.map { |v| Value.new(self, v) }) rescue Exception => e ctx[:__error] = e end end end finalize_callback = proc do |func| ctx = @driver.aggregate_context(func) unless ctx[:__error] begin finalize.call(FunctionProxy.new(@driver, func, ctx)) rescue Exception => e @driver.result_error(func, "#{e.message} (#{e.class})", -1) end else e = ctx[:__error] @driver.result_error(func, "#{e.message} (#{e.class})", -1) end end result = @driver.create_function(@handle, name, arity, text_rep, nil, nil, step_callback, finalize_callback) Error.check(result, self) self end