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:
aritycorresponds 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.namethis is the name of the function. The handler must implement this message.
newthis 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:
stepthis 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.finalizethis 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" )
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
# File 'lib/sqlite3/database.rb', line 451 def create_aggregate_handler( handler ) proxy = Class.new do def initialize klass @klass = klass @fp = FunctionProxy.new end def step( *args ) instance.step(@fp, *args) end def finalize instance.finalize @fp @instance = nil @fp.result end private def instance @instance ||= @klass.new end end define_aggregator(handler.name, proxy.new(handler)) self end |