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 arity parameter 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 step callback 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 finalize callback for #create_aggregate.

Example:

class LengthsAggregateHandler
  def self.arity; 1; 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" )


447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/sqlite3/database.rb', line 447

def create_aggregate_handler( handler )
  proxy = Class.new do
    def initialize handler
      @handler  = handler
      @fp       = FunctionProxy.new
    end

    def step( *args )
      @handler.step(@fp, *args)
    end

    def finalize
      @handler.finalize @fp
      @fp.result
    end
  end
  define_aggregator(handler.name, proxy.new(handler.new))
  self
end