/** request : 'db -> sql:string -> 'result <doc>Executes the SQL request and returns its result</doc> **/ HL_PRIM sqlite_result *HL_NAME(request)(sqlite_database *db, vbyte *sql ) { sqlite_result *r; const char *tl; int i,j; r = (sqlite_result*)hl_gc_alloc_finalizer(sizeof(sqlite_result)); r->finalize = HL_NAME(finalize_result); r->db = db; if( sqlite3_prepare16_v2(db->db, sql, -1, &r->r, &tl) != SQLITE_OK ) { HL_NAME(error)(db->db, false); } if( *tl ) { sqlite3_finalize(r->r); hl_error("SQLite error: Cannot execute several SQL requests at the same time"); } r->ncols = sqlite3_column_count(r->r); r->names = (int*)hl_gc_alloc(sizeof(int)*r->ncols); r->bools = (int*)hl_gc_alloc(sizeof(int)*r->ncols); r->first = 1; r->done = 0; for(i=0;i<r->ncols;i++) { int id = hl_hash_gen((uchar*)sqlite3_column_name16(r->r,i), true); const char *dtype = sqlite3_column_decltype(r->r,i); for(j=0;j<i;j++) if( r->names[j] == id ) { if( strcmp(sqlite3_column_name16(r->r,i), sqlite3_column_name16(r->r,j)) == 0 ) { sqlite3_finalize(r->r); hl_buffer *b = hl_alloc_buffer(); hl_buffer_str(b, USTR("SQLite error: Same field is two times in the request: ")); hl_buffer_str(b, (uchar*)sql); hl_error_msg(hl_buffer_content(b, NULL)); } else { hl_buffer *b = hl_alloc_buffer(); hl_buffer_str(b, USTR("SQLite error: Same field ids for: ")); hl_buffer_str(b, sqlite3_column_name16(r->r,i)); hl_buffer_str(b, USTR(" and ")); hl_buffer_str(b, sqlite3_column_name16(r->r,j)); sqlite3_finalize(r->r); hl_error_msg(hl_buffer_content(b, NULL)); } } r->names[i] = id; r->bools[i] = dtype?(strcmp(dtype,"BOOL") == 0):0; } // changes in an update/delete if( db->last != NULL ) HL_NAME(finalize_request)(db->last, false); db->last = r; return db->last; }
static void hl_read_type( hl_reader *r, hl_type *t ) { t->kind = READ(); switch( (int)t->kind ) { case HFUN: case HMETHOD: { int i; int nargs = READ(); t->fun = (hl_type_fun*)hl_zalloc(&r->code->alloc,sizeof(hl_type_fun)); t->fun->nargs = nargs; t->fun->args = (hl_type**)hl_malloc(&r->code->alloc,sizeof(hl_type*)*nargs); for(i=0;i<nargs;i++) t->fun->args[i] = hl_get_type(r); t->fun->ret = hl_get_type(r); } break; case HOBJ: { int i; const uchar *name = hl_read_ustring(r); int super = INDEX(); int global = UINDEX(); int nfields = UINDEX(); int nproto = UINDEX(); int nbindings = UINDEX(); t->obj = (hl_type_obj*)hl_malloc(&r->code->alloc,sizeof(hl_type_obj)); t->obj->name = name; t->obj->super = super < 0 ? NULL : r->code->types + super; t->obj->global_value = (void**)(int_val)global; t->obj->nfields = nfields; t->obj->nproto = nproto; t->obj->nbindings = nbindings; t->obj->fields = (hl_obj_field*)hl_malloc(&r->code->alloc,sizeof(hl_obj_field)*nfields); t->obj->proto = (hl_obj_proto*)hl_malloc(&r->code->alloc,sizeof(hl_obj_proto)*nproto); t->obj->bindings = (int*)hl_malloc(&r->code->alloc,sizeof(int)*nbindings*2); t->obj->rt = NULL; for(i=0;i<nfields;i++) { hl_obj_field *f = t->obj->fields + i; f->name = hl_read_ustring(r); f->hashed_name = hl_hash_gen(f->name,true); f->t = hl_get_type(r); } for(i=0;i<nproto;i++) { hl_obj_proto *p = t->obj->proto + i; p->name = hl_read_ustring(r); p->hashed_name = hl_hash_gen(p->name,true); p->findex = UINDEX(); p->pindex = INDEX(); } for(i=0;i<nbindings;i++) { t->obj->bindings[i<<1] = UINDEX(); t->obj->bindings[(i<<1)|1] = UINDEX(); } } break; case HREF: t->tparam = hl_get_type(r); break; case HVIRTUAL: { int i; int nfields = UINDEX(); t->virt = (hl_type_virtual*)hl_malloc(&r->code->alloc,sizeof(hl_type_virtual)); t->virt->nfields = nfields; t->virt->fields = (hl_obj_field*)hl_malloc(&r->code->alloc,sizeof(hl_obj_field)*nfields); for(i=0;i<nfields;i++) { hl_obj_field *f = t->virt->fields + i; f->name = hl_read_ustring(r); f->hashed_name = hl_hash_gen(f->name,true); f->t = hl_get_type(r); } } break; case HABSTRACT: t->abs_name = hl_read_ustring(r); break; case HENUM: { int i,j; t->tenum = hl_malloc(&r->code->alloc,sizeof(hl_type_enum)); t->tenum->name = hl_read_ustring(r); t->tenum->global_value = (void**)(int_val)UINDEX(); t->tenum->nconstructs = READ(); t->tenum->constructs = (hl_enum_construct*)hl_malloc(&r->code->alloc, sizeof(hl_enum_construct)*t->tenum->nconstructs); for(i=0;i<t->tenum->nconstructs;i++) { hl_enum_construct *c = t->tenum->constructs + i; c->name = hl_read_ustring(r); c->nparams = UINDEX(); c->params = (hl_type**)hl_malloc(&r->code->alloc,sizeof(hl_type*)*c->nparams); c->offsets = (int*)hl_malloc(&r->code->alloc,sizeof(int)*c->nparams); for(j=0;j<c->nparams;j++) c->params[j] = hl_get_type(r); } } break; case HNULL: t->tparam = hl_get_type(r); break; default: if( t->kind >= HLAST ) ERROR("Invalid type"); break; } }
HL_PRIM int hl_hash( vbyte *b ) { return hl_hash_gen((uchar*)b,true); }