Commit 340162df authored by unknown's avatar unknown
Browse files

Comments and cleanups in client library.


include/mysql.h:
  mysql_bind_param -> mysql_stmt_bind_param
libmysql/libmysql.c:
  - more comments
  - trailing spaces stripped
  - update_statement_metadata moved to appropriate section (from 'Statement
  close and error reporting' section)
  - store_param_type moved to store_ functions
parent fe497c0b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 */
+236 −154
Original line number Diff line number Diff line
@@ -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)
@@ -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,8 +2763,21 @@ 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)
@@ -3825,6 +3908,49 @@ int cli_read_binary_rows(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++;
    }
  }
}


/*
  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
*********************************************************************/