예제 #1
0
파일: sqlite.c 프로젝트: exaphaser/neko_mod
static void free_db( value v ) {
	database *db = val_db(v);
	if( db->last != NULL )
		finalize_result(val_result(db->last),0);
	if( sqlite3_close(db->db) != SQLITE_OK ) {
		// No exception : we shouldn't alloc memory in a finalizer anyway
	}
}
예제 #2
0
파일: sqlite.c 프로젝트: exaphaser/neko_mod
/**
	result_next : 'result -> object?
	<doc>Returns the next row in the result or [null] if no more result.</doc>
**/
static value result_next( value v ) {
	int i;
	result *r;
	val_check_kind(v,k_result);
	r = val_result(v);
	if( r->done )
		return val_null;
	switch( sqlite3_step(r->r) ) {
	case SQLITE_ROW:
		r->first = 0;
		v = alloc_object(NULL);
		for(i=0;i<r->ncols;i++) {
			value f;
			switch( sqlite3_column_type(r->r,i) ) {
			case SQLITE_NULL:
				f = val_null;
				break;
			case SQLITE_INTEGER:
				if( r->bools[i] )
					f = alloc_bool(sqlite3_column_int(r->r,i));
				else
					f = alloc_int(sqlite3_column_int(r->r,i));
				break;
			case SQLITE_FLOAT:
				f = alloc_float(sqlite3_column_double(r->r,i));
				break;
			case SQLITE_TEXT:
				f = alloc_string((char*)sqlite3_column_text(r->r,i));
				break;
			case SQLITE_BLOB:
				{
					int size = sqlite3_column_bytes(r->r,i);
					f = alloc_empty_string(size);
					memcpy(val_string(f),sqlite3_column_blob(r->r,i),size);
					break;
				}
			default:
				{
					buffer b = alloc_buffer("Unknown Sqlite type #");
					val_buffer(b,alloc_int(sqlite3_column_type(r->r,i)));
					val_throw(buffer_to_string(b));
				}
			}
			alloc_field(v,r->names[i],f);
		}
		return v;
	case SQLITE_DONE:
		finalize_result(r,1);
		return val_null;
	case SQLITE_BUSY:
		val_throw(alloc_string("Database is busy"));
	case SQLITE_ERROR:
		sqlite_error(r->db->db);
	default:
		neko_error();
	}
	return val_null;
}
예제 #3
0
파일: sqlite.c 프로젝트: exaphaser/neko_mod
/**
	request : 'db -> sql:string -> 'result
	<doc>Executes the SQL request and returns its result</doc>
**/
static value request( value v, value sql ) {
	database *db;
	result *r;
	const char *tl;
	int i,j;
	val_check_kind(v,k_db);
	val_check(sql,string);
	db = val_db(v);
	r = (result*)alloc(sizeof(result));
	r->db = db;
	if( sqlite3_prepare(db->db,val_string(sql),val_strlen(sql),&r->r,&tl) != SQLITE_OK ) {
		buffer b = alloc_buffer("Sqlite error in ");
		val_buffer(b,sql);
		buffer_append(b," : ");
		buffer_append(b,sqlite3_errmsg(db->db));
		val_throw(buffer_to_string(b));
	}
	if( *tl ) {
		sqlite3_finalize(r->r);
		val_throw(alloc_string("Cannot execute several SQL requests at the same time"));
	}
	r->ncols = sqlite3_column_count(r->r);
	r->names = (field*)alloc_private(sizeof(field)*r->ncols);
	r->bools = (int*)alloc_private(sizeof(int)*r->ncols);
	r->first = 1;
	r->done = 0;
	for(i=0;i<r->ncols;i++) {
		field id = val_id(sqlite3_column_name(r->r,i));
		const char *dtype = sqlite3_column_decltype(r->r,i);
		for(j=0;j<i;j++)
			if( r->names[j] == id ) {
				if( strcmp(sqlite3_column_name(r->r,i),sqlite3_column_name(r->r,j)) == 0 ) {
					buffer b = alloc_buffer("Error, same field is two times in the request ");
					val_buffer(b,sql);
					sqlite3_finalize(r->r);
					val_throw(buffer_to_string(b));
				} else {
					buffer b = alloc_buffer("Error, same field ids for : ");
					buffer_append(b,sqlite3_column_name(r->r,i));
					buffer_append(b," and ");
					buffer_append(b,sqlite3_column_name(r->r,j));
					buffer_append_char(b,'.');
					sqlite3_finalize(r->r);
					val_throw(buffer_to_string(b));
				}
			}
		r->names[i] = id;
		r->bools[i] = dtype?(strcmp(dtype,"BOOL") == 0):0;
	}
	// changes in an update/delete
	if( db->last != NULL )
		finalize_result(val_result(db->last),0);
	db->last = alloc_abstract(k_result,r);
	return db->last;
}
예제 #4
0
파일: sqlite3.c 프로젝트: adh/dfsch
static dfsch_object_t* result_next(sqlite3_result_t* res){
  
  char* err;
  int ret;
  char**values;
  ret = sqlite3_step(res->stmt);

  if (ret == SQLITE_ROW){
     res->last_res = get_row_as_vector(res->stmt);
     return res;
  } else if (ret == SQLITE_BUSY) {
    dfsch_error("Database is busy", (dfsch_object_t*)res->db);
  } else if (ret == SQLITE_ERROR){
    finalize_result(res);
    return NULL;
  } else {
    return NULL;
  }
}
예제 #5
0
파일: sqlite.c 프로젝트: adh/dfsch
static dfsch_object_t* result_next(sqlite_result_t* res){
  
  char* err;
  int ret;
  char**values;
  pthread_mutex_lock(res->mutex);
  ret = sqlite_step(res->vm, &res->n_columns, &values, &res->names);

  if (ret == SQLITE_ROW){
     res->last_res = get_row_as_vector(res->n_columns, values);
     pthread_mutex_unlock(res->mutex);
     return res;
  } else {
    pthread_mutex_unlock(res->mutex);
    if (ret == SQLITE_BUSY) {
      dfsch_error("Database is busy", (dfsch_object_t*)res->db);
    } else if (ret == SQLITE_ERROR){
      finalize_result(res);
      return NULL;
    } else {
      return NULL;
    }
  }
}