def create_aggregate_handler( handler )
type = nil
arity = -1
type = handler.function_type if handler.respond_to?(:function_type)
arity = handler.arity if handler.respond_to?(:arity)
name = handler.name
case type
when :numeric
type = SQLite::API::NUMERIC
when :text
type = SQLite::API::TEXT
when :args
type = SQLite::API::ARGS
end
step = proc do |func,*args|
ctx = SQLite::API.aggregate_context( func )
unless ctx[ :__error ]
ctx[ :handler ] ||= handler.new
begin
ctx[ :handler ].step( FunctionProxy.new( func, ctx ), *args )
rescue Exception => e
ctx[ :__error ] = e
end
end
end
finalize = proc do |func|
ctx = SQLite::API.aggregate_context( func )
unless ctx[ :__error ]
ctx[ :handler ] ||= handler.new
begin
ctx[ :handler ].finalize( FunctionProxy.new( func, ctx ) )
rescue Exception => e
ctx[ :__error ] = e
end
end
if ctx[ :__error ]
e = ctx[ :__error ]
SQLite::API.set_result_error( func, "#{e.message} (#{e.class})" )
end
end
SQLite::API.create_aggregate( @handle, name, arity, step, finalize )
SQLite::API.function_type( @handle, name, type ) if type
self
end