/** result_next : 'result -> object? <doc>Returns the next row in the result or [null] if no more result.</doc> **/ HL_PRIM varray *HL_NAME(result_next)( sqlite_result *r ) { if( r->done ) return NULL; switch( sqlite3_step(r->r) ) { case SQLITE_ROW: r->first = 0; varray *a = hl_alloc_array(&hlt_dyn, r->ncols); int i; for(i=0;i<r->ncols;i++) { vdynamic *v; switch( sqlite3_column_type(r->r,i) ) { case SQLITE_NULL: v = NULL; break; case SQLITE_INTEGER: { int vint = sqlite3_column_int(r->r, i); if (r->bools[i]) v = hl_make_dyn(&vint, &hlt_bool); else v = hl_make_dyn(&vint, &hlt_i32); break; } case SQLITE_FLOAT: { double d = sqlite3_column_double(r->r, i); v = hl_make_dyn(&d, &hlt_f64); break; } case SQLITE_TEXT: { uchar *text16 = (uchar *)sqlite3_column_text16(r->r, i); v = hl_make_dyn(&text16, &hlt_bytes); break; } case SQLITE_BLOB: { vbyte *blob = (vbyte *)sqlite3_column_blob(r->r, i); v = hl_make_dyn(&blob, &hlt_bytes); break; } default: hl_error_msg(USTR("SQLite error: Unknown type #%d"), sqlite3_column_type(r->r,i)); } hl_aptr(a, vdynamic*)[i] = v; } return a; case SQLITE_DONE: HL_NAME(finalize_request)(r, true); return NULL; case SQLITE_BUSY: hl_error("SQLite error: Database is busy"); case SQLITE_ERROR: HL_NAME(error)(r->db->db, false); default: return NULL; } return NULL; }
HL_PRIM vdynamic *hl_dyn_call( vclosure *c, vdynamic **args, int nargs ) { struct { varray a; vdynamic *args[HL_MAX_ARGS+1]; } tmp; vclosure ctmp; int i = 0; if( nargs > HL_MAX_ARGS ) hl_error("Too many arguments"); tmp.a.t = &hlt_array; tmp.a.at = &hlt_dyn; tmp.a.size = nargs; if( c->hasValue && c->t->fun->nargs >= 0 ) { ctmp.t = c->t->fun->parent; ctmp.hasValue = 0; ctmp.fun = c->fun; tmp.args[0] = hl_make_dyn(&c->value,ctmp.t->fun->args[0]); tmp.a.size++; for(i=0;i<nargs;i++) tmp.args[i+1] = args[i]; c = &ctmp; } else { for(i=0;i<nargs;i++) tmp.args[i] = args[i]; } return hl_call_method((vdynamic*)c,&tmp.a); }
HL_PRIM vdynamic* hl_get_closure_value( vdynamic *c ) { vclosure *cl = (vclosure*)c; if( cl->hasValue == 2 ) return hl_get_closure_value((vdynamic*)((vclosure_wrapper*)c)->wrappedFun); if( cl->hasValue && cl->fun != fun_var_args ) return hl_make_dyn(&cl->value, cl->t->fun->parent->fun->args[0]); return (vdynamic*)cl->value; }
/** result_get_float : 'result -> n:int -> float <doc>Return the [n]th field of the current result row as a float.</doc> **/ HL_PRIM vdynamic *HL_NAME(result_get_float)( sqlite_result *r, int n ) { if( n < 0 || n >= r->ncols ) return NULL; if( r->first ) HL_NAME(result_next)(r); if( r->done ) return NULL; double value = sqlite3_column_double(r->r, n); return hl_make_dyn(&value, &hlt_f64); }
HL_PRIM vdynamic *hl_parse_int( vbyte *bytes, int pos, int len ) { uchar *c = (uchar*)(bytes + pos), *end = NULL; int h; if( len >= 2 && c[0] == '0' && (c[1] == 'x' || c[1] == 'X') ) { h = 0; c += 2; while( *c ) { uchar k = *c++; if( k >= '0' && k <= '9' ) h = (h << 4) | (k - '0'); else if( k >= 'A' && k <= 'F' ) h = (h << 4) | ((k - 'A') + 10); else if( k >= 'a' && k <= 'f' ) h = (h << 4) | ((k - 'a') + 10); else return NULL; } return hl_make_dyn(&h,&hlt_i32); } h = utoi(c,&end); return c == end ? NULL : hl_make_dyn(&h,&hlt_i32); }
/** result_get_length : 'result -> int <doc>Returns the number of rows in the result or the number of rows changed by the request.</doc> **/ HL_PRIM vdynamic *HL_NAME(result_get_length)( sqlite_result *r ) { if( r->ncols != 0 ) return NULL; return hl_make_dyn(&r->count, &hlt_i32); }
HL_PRIM void *hl_wrapper_call( void *_c, void **args, vdynamic *ret ) { vclosure_wrapper *c = (vclosure_wrapper*)_c; hl_type_fun *tfun = c->cl.t->fun; union { double d; int i; float f; } tmp[HL_MAX_ARGS]; void *vargs[HL_MAX_ARGS+1]; vdynamic out; vclosure *w = c->wrappedFun; int i; int p = 0; void *pret, *aret; if( ret == NULL ) ret = &out; if( w->fun == fun_var_args ) { varray *a; w = (vclosure*)w->value; // the real callback a = hl_alloc_array(&hlt_dyn,tfun->nargs); for(i=0;i<tfun->nargs;i++) { hl_type *t = tfun->args[i]; void *v = hl_is_ptr(t) ? args + i : args[i]; hl_aptr(a,void*)[i] = hl_make_dyn(v,t); } if( w->hasValue ) vargs[p++] = (vdynamic*)w->value; vargs[p++] = (vdynamic*)a; } else { if( w->hasValue ) vargs[p++] = (vdynamic*)w->value; for(i=0;i<w->t->fun->nargs;i++) { hl_type *t = tfun->args[i]; hl_type *to = w->t->fun->args[i]; void *v = hl_is_ptr(t) ? args + i : args[i]; switch( to->kind ) { case HUI8: case HUI16: case HI32: case HBOOL: tmp[i].i = hl_dyn_casti(v,t,to); v = &tmp[i].i; break; case HF32: tmp[i].f = hl_dyn_castf(v,t); v = &tmp[i].f; break; case HF64: tmp[i].d = hl_dyn_castd(v,t); v = &tmp[i].d; break; default: v = hl_dyn_castp(v,t,to); break; } vargs[p++] = v; } } pret = hlc_static_call(w->fun,w->hasValue ? w->t->fun->parent : w->t,vargs,ret); aret = hl_is_ptr(w->t->fun->ret) ? &pret : pret; if( aret == NULL ) aret = &pret; switch( tfun->ret->kind ) { case HVOID: return NULL; case HUI8: case HUI16: case HI32: case HBOOL: ret->v.i = hl_dyn_casti(aret,w->t->fun->ret,tfun->ret); break; case HF32: ret->v.f = hl_dyn_castf(aret,w->t->fun->ret); break; case HF64: ret->v.d = hl_dyn_castd(aret,w->t->fun->ret); break; default: pret = hl_dyn_castp(aret,w->t->fun->ret,tfun->ret); break; } return pret; }