Re: [opendbx] Future plans again
Brought to you by:
nose
From: Norbert S. <no...@li...> - 2011-07-07 07:27:13
|
HI Thibault >> OK, but you don't gain much because this is only one malloc you >> will save. One more is needed for the auxiliary data and I think >> several are done by the native client libraries. The reason I opted >> against this was the choices you have to care about when you a) get >> an already initialized structure and b) get a structure that only >> seem to be initialized due to random data. > > The mallocs in the native client libraries are unavoidable, my point > was just to minimize their use since each one involves a lot of > overhead. I did not get the point about initialized data. Is there a > difference between stack and heap? Usually it's faster to get memory from the stack instead of the heap but on the stack only fixed size memory can be allocated. This means you can't use a dynamic number of connections. >> Many native database libraries support prepared statements. It's >> relatively simple: - Send the SQL with markers to the server and >> get back a handle - bind your values to this handle - Send only the >> data to the server (one or several times) - Get the binary values >> from the result set > >> Contrary to e.g. DBI I would favour a single function that copies >> the data to a memory area provided by the client. This can be used >> with all types of data and is faster and safer than allocating >> memory that must be freed by the client. > > I agree on this. The design I had in mind was more minimalistic such > as not to involve any memory allocation (except on stack): > odbx_prepare(conn_obj, query_obj, statement); // The statement > contains markers like %s or %i which are replaced by native client > library markers odbx_exec_prepared(conn_obj, query_obj, result_obj, > ...); // The variadic arguments are interpreted according to the > types known from the previous function and stored in query_obj The native database libraries usually provide a function like bind( stmt, position, value) They don't work with varadic arguments but you have to bind a value to every marker (usually the question mark) before executing the prepared statement. >> No, as this would interfere with the positive return values for >> e.g. odbx_result(). > > Misunderstanding, I meant to return values other than errors (In-band > error codes, which are dangerous > https://www.securecoding.cert.org/confluence/display/seccode/ERR02-C.+Avoid+in-band+error+indicators > ). The negative error codes design would allow this practice to be > used in other functions than odbx_result. Instead, ODBX_RES_ROWS and > NOROWS could be removed in favour of a mean to get the number of rows > after a SELECT. ODBX_RES_TIMEOUT in turn could be included as an > error code. OK, I see what you mean but you don't have in-band error codes in odbx_result() because this function only returns codes and no values. Nevertheless, there are functions with in-band errors (all that does return values from the database): - odbx_error - odbx_rows_affected - odbx_column_count - odbx_column_name - odbx_column_type - odbx_field_length - odbx_field_value >> The initial design decision was to allow having multiple result >> sets per connection even if most databases doesn't support this. >> But I didn't want to limit the client libraries that would be able >> to so even if none of the currently implemented ones can do so :-) > > Misunderstanding, I meant to call odbx_field_value( handle, result, i > ) rather than odbx_field_value( result, i ). The user might think > that he can free the connection and then still read the result > structure. Including the handle in all functions might however be > excessive, so you could simply replace odbx_result_finish(result) by > odbx_result_finish(handle, result). Thus, users have to keep the > handle alive while parsing the result structure. You are right, extending odbx_result_finish() by the connection handle can be a strong indicator for developers to keep the handle. Norbert |