//export goXFinal func goXFinal(scp, udfp unsafe.Pointer) { udf := (*sqliteFunction)(udfp) cp := C.sqlite3_aggregate_context((*C.sqlite3_context)(scp), 0) if cp != nil { p := *(*unsafe.Pointer)(cp) if p != nil { c := (*AggregateContext)(p) delete(udf.aggrCtxs, c) c.sc = (*C.sqlite3_context)(scp) udf.final(c) } } // fmt.Printf("Contexts: %v\n", udf.aggrCtxts) }
func (ai *aggInfo) agg(ctx *C.sqlite3_context) (int64, reflect.Value, error) { aggIdx := (*int64)(C.sqlite3_aggregate_context(ctx, C.int(8))) if *aggIdx == 0 { *aggIdx = ai.next ret := ai.constructor.Call(nil) if len(ret) == 2 && ret[1].Interface() != nil { return 0, reflect.Value{}, ret[1].Interface().(error) } if ret[0].IsNil() { return 0, reflect.Value{}, errors.New("aggregator constructor returned nil state") } ai.next++ ai.active[*aggIdx] = ret[0] } return *aggIdx, ai.active[*aggIdx], nil }
//export goXStep func goXStep(scp, udfp unsafe.Pointer, argc int, argv unsafe.Pointer) { udf := (*sqliteFunction)(udfp) var cp unsafe.Pointer cp = C.sqlite3_aggregate_context((*C.sqlite3_context)(scp), C.int(unsafe.Sizeof(cp))) if cp != nil { var c *AggregateContext p := *(*unsafe.Pointer)(cp) if p == nil { c = new(AggregateContext) c.sc = (*C.sqlite3_context)(scp) *(*unsafe.Pointer)(cp) = unsafe.Pointer(c) // To make sure it is not cged udf.aggrCtxs[c] = true } else { c = (*AggregateContext)(p) } c.argv = (**C.sqlite3_value)(argv) udf.step(c, argc) c.argv = nil } }