Commit e9f2c7d4 authored by konstantin@mysql.com's avatar konstantin@mysql.com

Comments and cleanups in client library.

parent 3ac650c8
......@@ -558,7 +558,7 @@ typedef struct st_mysql_bind
enum enum_field_types buffer_type; /* buffer type */
unsigned long buffer_length; /* buffer length, must be set for str/binary */
/* Following are for internal use. Set by mysql_bind_param */
/* Following are for internal use. Set by mysql_stmt_bind_param */
unsigned char *inter_buffer; /* for the current data position */
unsigned long offset; /* offset position for char/binary fetch */
unsigned long internal_length; /* Used if length is 0 */
......
......@@ -2130,10 +2130,23 @@ mysql_stmt_result_metadata(MYSQL_STMT *stmt)
DBUG_RETURN(result);
}
/*
Returns parameter columns meta information in the form of
result set.
SYNOPSYS
mysql_stmt_param_metadata()
stmt statement handle
DESCRIPTION
This function can be called after you prepared the statement handle
with mysql_stmt_prepare().
XXX: not implemented yet.
RETURN
MYSQL_RES on success, 0 if there is no metadata.
Currently this function always returns 0.
*/
MYSQL_RES * STDCALL
......@@ -2146,25 +2159,36 @@ mysql_stmt_param_metadata(MYSQL_STMT *stmt)
/*
TODO: Fix this when server sends the information.
Till then keep a dummy prototype
Till then keep a dummy prototype.
*/
DBUG_RETURN(0);
}
/* Store type of parameter in network buffer. */
static void store_param_type(char **pos, MYSQL_BIND *param)
{
uint typecode= param->buffer_type | (param->is_unsigned ? 32768 : 0);
int2store(*pos, typecode);
*pos+= 2;
}
/*
Functions to store parameter data in network packet.
All functions have the following characteristics:
SYNOPSIS
store_param_xxx()
net MySQL NET connection
param MySQL bind param
RETURN VALUES
0 ok
1 Error (Can't alloc net->buffer)
DESCRIPTION
These funtions are invoked from mysql_stmt_execute by
MYSQL_BIND::store_param_func pointer. This pointer is set once per many
executions in mysql_stmt_bind_param. The caller must ensure that network
buffer have enough capacity to store parameter (MYSQL_BIND::buffer_length
contains needed number of bytes).
*/
static void store_param_tinyint(NET *net, MYSQL_BIND *param)
......@@ -2292,7 +2316,8 @@ static void store_param_str(NET *net, MYSQL_BIND *param)
DESCRIPTION
A data package starts with a string of bits where we set a bit
if a parameter is NULL
if a parameter is NULL. Unlike bit string in result set row, here
we don't have reserved bits for OK/error packet.
*/
static void store_param_null(NET *net, MYSQL_BIND *param)
......@@ -2303,8 +2328,9 @@ static void store_param_null(NET *net, MYSQL_BIND *param)
/*
Set parameter data by reading from input buffers from the
client application
Store one parameter in network packet: data is read from
client buffer and saved in network packet by means of one
of store_param_xxxx functions.
*/
static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
......@@ -2339,7 +2365,7 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
Send the prepared query to server for execution
*/
static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length)
{
MYSQL *mysql= stmt->mysql;
NET *net= &mysql->net;
......@@ -2365,14 +2391,6 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
}
static void store_param_type(char **pos, MYSQL_BIND *param)
{
uint typecode= param->buffer_type | (param->is_unsigned ? 32768 : 0);
int2store(*pos, typecode);
*pos+= 2;
}
int cli_stmt_execute(MYSQL_STMT *stmt)
{
DBUG_ENTER("cli_stmt_execute");
......@@ -2413,7 +2431,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
for (param= stmt->params; param < param_end; param++)
{
/* check if mysql_long_data() was used */
/* check if mysql_stmt_send_long_data() was used */
if (param->long_data_used)
param->long_data_used= 0; /* Clear for next execute call */
else if (store_param(stmt, param))
......@@ -2587,7 +2605,47 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
/*
Execute the prepared query
Send placeholders data to server (if there are placeholders)
and execute prepared statement.
SYNOPSIS
mysql_stmt_execute()
stmt statement handle. The handle must be created
with mysql_stmt_init() and prepared with
mysql_stmt_prepare(). If there are placeholders
in the statement they must be bound to local
variables with mysql_stmt_bind_param().
DESCRIPTION
This function will automatically flush pending result
set (if there is one), send parameters data to the server
and read result of statement execution.
If previous result set was cached with mysql_stmt_store_result()
it will also be freed in the beginning of this call.
The server can return 3 types of responses to this command:
- error, can be retrieved with mysql_stmt_error()
- ok, no result set pending. In this case we just update
stmt->insert_id and stmt->affected_rows.
- the query returns a result set: there could be 0 .. N
rows in it. In this case the server can also send updated
result set metadata.
Next steps you may want to make:
- find out if there is result set with mysql_stmt_field_count().
If there is one:
- optionally, cache entire result set on client to unblock
connection with mysql_stmt_store_result()
- bind client variables to result set columns and start read rows
with mysql_stmt_fetch().
- reset statement with mysql_stmt_reset() or close it with
mysql_stmt_close()
Otherwise:
- find out last insert id and number of affected rows with
mysql_stmt_insert_id(), mysql_stmt_affected_rows()
RETURN
0 success
1 error, message can be retrieved with mysql_stmt_error().
*/
int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
......@@ -2681,7 +2739,19 @@ unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt)
}
/*
Return last inserted id for auto_increment columns
Return last inserted id for auto_increment columns.
SYNOPSIS
mysql_stmt_insert_id()
stmt statement handle
DESCRIPTION
Current implementation of this call has a caveat: stmt->insert_id is
unconditionally updated from mysql->insert_id in the end of each
mysql_stmt_execute(). This works OK if mysql->insert_id contains new
value (sent in reply to mysql_stmt_execute()), otherwise stmt->insert_id
value gets undefined, as it's updated from some arbitrary value saved in
connection structure during some other call.
*/
my_ulonglong STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt)
......@@ -2693,11 +2763,24 @@ my_ulonglong STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt)
static my_bool int_is_null_true= 1; /* Used for MYSQL_TYPE_NULL */
static my_bool int_is_null_false= 0;
/*
Setup the parameter data buffers from application
Setup the input parameter data buffers from application
SYNOPSIS
mysql_stmt_bind_param()
stmt statement handle
The statement must be prepared with mysql_stmt_prepare().
bind Array of mysql_stmt_param_count() bind parameters.
RETURN
0 success
1 error, can be retrieved with mysql_stmt_error.
Note, that this function doesn't check that size of MYSQL_BIND
array is >= mysql_stmt_field_count(),
*/
my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)
{
uint count=0;
MYSQL_BIND *param, *end;
......@@ -3825,6 +3908,49 @@ err:
}
/*
Update meta data for statement
SYNOPSIS
stmt_update_metadata()
stmt Statement handler
row Binary data
NOTES
Only updates MYSQL_FIELD->max_length for strings
*/
static void stmt_update_metadata(MYSQL_STMT *stmt, MYSQL_ROWS *data)
{
MYSQL_BIND *bind, *end;
MYSQL_FIELD *field;
uchar *null_ptr, bit;
uchar *row= (uchar*) data->data;
#ifndef DBUG_OFF
uchar *row_end= row + data->length;
#endif
null_ptr= row;
row+= (stmt->field_count+9)/8; /* skip null bits */
bit= 4; /* first 2 bits are reserved */
/* Go throw all fields and calculate metadata */
for (bind= stmt->bind, end= bind + stmt->field_count, field= stmt->fields ;
bind < end ;
bind++, field++)
{
if (!(*null_ptr & bit))
(*bind->skip_result)(bind, field, &row);
DBUG_ASSERT(row <= row_end);
if (!((bit<<=1) & 255))
{
bit= 1; /* To next byte */
null_ptr++;
}
}
}
/*
Store or buffer the binary results to stmt
*/
......@@ -4116,50 +4242,6 @@ const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt)
}
/*
Update meta data for statement
SYNOPSIS
stmt_update_metadata()
stmt Statement handler
row Binary data
NOTES
Only updates MYSQL_FIELD->max_length for strings
*/
static void stmt_update_metadata(MYSQL_STMT *stmt, MYSQL_ROWS *data)
{
MYSQL_BIND *bind, *end;
MYSQL_FIELD *field;
uchar *null_ptr, bit;
uchar *row= (uchar*) data->data;
#ifndef DBUG_OFF
uchar *row_end= row + data->length;
#endif
null_ptr= row;
row+= (stmt->field_count+9)/8; /* skip null bits */
bit= 4; /* first 2 bits are reserved */
/* Go throw all fields and calculate metadata */
for (bind= stmt->bind, end= bind + stmt->field_count, field= stmt->fields ;
bind < end ;
bind++, field++)
{
if (!(*null_ptr & bit))
(*bind->skip_result)(bind, field, &row);
DBUG_ASSERT(row <= row_end);
if (!((bit<<=1) & 255))
{
bit= 1; /* To next byte */
null_ptr++;
}
}
}
/********************************************************************
Transactional APIs
*********************************************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment