Method: SQLite3::Database#create_aggregate_handler
- Defined in:
- lib/sqlite3/database.rb
#create_aggregate_handler(handler) ⇒ Object
This is another approach to creating an aggregate function (see #create_aggregate). Instead of explicitly specifying the name, callbacks, arity, and type, you specify a factory object (the “handler”) that knows how to obtain all of that information. The handler should respond to the following messages:
arity-
corresponds to the
arityparameter of #create_aggregate. This message is optional, and if the handler does not respond to it, the function will have an arity of -1. name-
this is the name of the function. The handler must implement this message.
new-
this must be implemented by the handler. It should return a new instance of the object that will handle a specific invocation of the function.
The handler instance (the object returned by the new message, described above), must respond to the following messages:
step-
this is the method that will be called for each step of the aggregate function’s evaluation. It should implement the same signature as the
stepcallback for #create_aggregate. finalize-
this is the method that will be called to finalize the aggregate function’s evaluation. It should implement the same signature as the
finalizecallback for #create_aggregate.
Example:
class LengthsAggregateHandler
def self.arity; 1; end
def self.name; 'lengths'; end
def initialize
@total = 0
end
def step( ctx, name )
@total += ( name ? name.length : 0 )
end
def finalize( ctx )
ctx.result = @total
end
end
db.create_aggregate_handler( LengthsAggregateHandler )
puts db.get_first_value( "select lengths(name) from A" )
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
# File 'lib/sqlite3/database.rb', line 543 def create_aggregate_handler( handler ) # This is a compatibility shim so the (basically pointless) FunctionProxy # "ctx" object is passed as first argument to both step() and finalize(). # Now its up to the library user whether he prefers to store his # temporaries as instance variables or fields in the FunctionProxy. # The library user still must set the result value with # FunctionProxy.result= as there is no backwards compatible way to # change this. proxy = Class.new(handler) do def initialize super @fp = FunctionProxy.new end def step( *args ) super(@fp, *args) end def finalize super(@fp) @fp.result end end define_aggregator2(proxy, proxy.name) self end |