SCRUM
prepared statements in embedded library
This commit is contained in:
parent
744fc5a5be
commit
7a763f3fe3
@ -560,6 +560,7 @@ typedef struct st_mysql_methods
|
|||||||
MYSQL_ROW column, uint field_count);
|
MYSQL_ROW column, uint field_count);
|
||||||
MYSQL_FIELD * (STDCALL *list_fields)(MYSQL *mysql);
|
MYSQL_FIELD * (STDCALL *list_fields)(MYSQL *mysql);
|
||||||
my_bool (STDCALL *read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
|
my_bool (STDCALL *read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
|
||||||
|
int (STDCALL *stmt_execute)(MYSQL_STMT *stmt);
|
||||||
} MYSQL_METHODS;
|
} MYSQL_METHODS;
|
||||||
|
|
||||||
MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query,
|
MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query,
|
||||||
|
@ -34,6 +34,13 @@ void end_server(MYSQL *mysql);
|
|||||||
my_bool mysql_reconnect(MYSQL *mysql);
|
my_bool mysql_reconnect(MYSQL *mysql);
|
||||||
void mysql_read_default_options(struct st_mysql_options *options,
|
void mysql_read_default_options(struct st_mysql_options *options,
|
||||||
const char *filename,const char *group);
|
const char *filename,const char *group);
|
||||||
|
my_bool STDCALL
|
||||||
|
cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
||||||
|
const char *header, ulong header_length,
|
||||||
|
const char *arg, ulong arg_length, my_bool skip_check);
|
||||||
|
|
||||||
|
void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
|
||||||
|
const char *sqlstate);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -54,3 +54,4 @@ MYSQL_FIELD * STDCALL cli_list_fields(MYSQL *mysql);
|
|||||||
my_bool STDCALL cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt);
|
my_bool STDCALL cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt);
|
||||||
MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
||||||
uint fields);
|
uint fields);
|
||||||
|
int STDCALL cli_stmt_execute(MYSQL_STMT *stmt);
|
||||||
|
@ -1494,8 +1494,8 @@ static void set_stmt_error(MYSQL_STMT * stmt, int errcode,
|
|||||||
Copy error message to statement handler
|
Copy error message to statement handler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
|
void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
|
||||||
const char *sqlstate)
|
const char *sqlstate)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("set_stmt_error_msg");
|
DBUG_ENTER("set_stmt_error_msg");
|
||||||
DBUG_PRINT("enter", ("error: %d/%s '%s'", errcode, sqlstate, err));
|
DBUG_PRINT("enter", ("error: %d/%s '%s'", errcode, sqlstate, err));
|
||||||
@ -1601,6 +1601,16 @@ my_bool STDCALL cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
|
|||||||
}
|
}
|
||||||
stmt->field_count= (uint) field_count;
|
stmt->field_count= (uint) field_count;
|
||||||
stmt->param_count= (ulong) param_count;
|
stmt->param_count= (ulong) param_count;
|
||||||
|
if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root,
|
||||||
|
sizeof(MYSQL_BIND)*
|
||||||
|
(stmt->param_count +
|
||||||
|
stmt->field_count))))
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
stmt->bind= stmt->params + stmt->param_count;
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1649,12 +1659,6 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length)
|
|||||||
stmt_close(stmt, 1);
|
stmt_close(stmt, 1);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root,
|
|
||||||
sizeof(MYSQL_BIND)*
|
|
||||||
(stmt->param_count +
|
|
||||||
stmt->field_count))))
|
|
||||||
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
|
||||||
stmt->bind= stmt->params + stmt->param_count;
|
|
||||||
|
|
||||||
stmt->state= MY_ST_PREPARE;
|
stmt->state= MY_ST_PREPARE;
|
||||||
stmt->mysql= mysql;
|
stmt->mysql= mysql;
|
||||||
@ -1975,36 +1979,21 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
|
|||||||
|
|
||||||
mysql->last_used_con= mysql;
|
mysql->last_used_con= mysql;
|
||||||
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
|
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
|
||||||
if ((*mysql->methods->advanced_command)(mysql, COM_EXECUTE, buff,
|
if (cli_advanced_command(mysql, COM_EXECUTE, buff,
|
||||||
MYSQL_STMT_HEADER, packet,
|
MYSQL_STMT_HEADER, packet,
|
||||||
length, 1) ||
|
length, 1) ||
|
||||||
mysql_read_query_result(mysql))
|
mysql_read_query_result(mysql))
|
||||||
{
|
{
|
||||||
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
|
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
stmt->state= MY_ST_EXECUTE;
|
|
||||||
mysql_free_result(stmt->result);
|
|
||||||
stmt->result= (MYSQL_RES *)0;
|
|
||||||
stmt->result_buffered= 0;
|
|
||||||
stmt->current_row= 0;
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int STDCALL cli_stmt_execute(MYSQL_STMT *stmt)
|
||||||
/*
|
|
||||||
Execute the prepare query
|
|
||||||
*/
|
|
||||||
|
|
||||||
int STDCALL mysql_execute(MYSQL_STMT *stmt)
|
|
||||||
{
|
{
|
||||||
DBUG_ENTER("mysql_execute");
|
DBUG_ENTER("cli_stmt_execute");
|
||||||
|
|
||||||
if (stmt->state == MY_ST_UNKNOWN)
|
|
||||||
{
|
|
||||||
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
if (stmt->param_count)
|
if (stmt->param_count)
|
||||||
{
|
{
|
||||||
NET *net= &stmt->mysql->net;
|
NET *net= &stmt->mysql->net;
|
||||||
@ -2065,6 +2054,30 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt)
|
|||||||
DBUG_RETURN((int) execute(stmt,0,0));
|
DBUG_RETURN((int) execute(stmt,0,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Execute the prepare query
|
||||||
|
*/
|
||||||
|
|
||||||
|
int STDCALL mysql_execute(MYSQL_STMT *stmt)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("mysql_execute");
|
||||||
|
|
||||||
|
if (stmt->state == MY_ST_UNKNOWN)
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
if ((*stmt->mysql->methods->stmt_execute)(stmt))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
stmt->state= MY_ST_EXECUTE;
|
||||||
|
mysql_free_result(stmt->result);
|
||||||
|
stmt->result= (MYSQL_RES *)0;
|
||||||
|
stmt->result_buffered= 0;
|
||||||
|
stmt->current_row= 0;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Return total parameters count in the statement
|
Return total parameters count in the statement
|
||||||
|
@ -100,7 +100,18 @@ emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)),
|
|||||||
{
|
{
|
||||||
MYSQL_DATA *result= ((THD*)mysql->thd)->data;
|
MYSQL_DATA *result= ((THD*)mysql->thd)->data;
|
||||||
if (!result)
|
if (!result)
|
||||||
return NULL;
|
{
|
||||||
|
if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
|
||||||
|
MYF(MY_WME | MY_ZEROFILL))))
|
||||||
|
{
|
||||||
|
NET *net = &mysql->net;
|
||||||
|
net->last_errno=CR_OUT_OF_MEMORY;
|
||||||
|
strmov(net->sqlstate, unknown_sqlstate);
|
||||||
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
*result->prev_ptr= NULL;
|
*result->prev_ptr= NULL;
|
||||||
((THD*)mysql->thd)->data= NULL;
|
((THD*)mysql->thd)->data= NULL;
|
||||||
return result;
|
return result;
|
||||||
@ -126,6 +137,16 @@ static my_bool STDCALL emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
|
|||||||
stmt->fields= mysql->fields;
|
stmt->fields= mysql->fields;
|
||||||
stmt->mem_root= mysql->field_alloc;
|
stmt->mem_root= mysql->field_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(stmt->bind=
|
||||||
|
(MYSQL_BIND *) alloc_root(&stmt->mem_root,
|
||||||
|
sizeof(MYSQL_BIND)*stmt->field_count)))
|
||||||
|
{
|
||||||
|
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
stmt->params= NULL; // we don't need parameter's buffer in embedded library
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,6 +175,23 @@ static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int STDCALL emb_stmt_execute(MYSQL_STMT *stmt)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("emb_stmt_execute");
|
||||||
|
THD *thd= (THD*)stmt->mysql->thd;
|
||||||
|
thd->client_param_count= stmt->param_count;
|
||||||
|
thd->client_parameters= stmt->params;
|
||||||
|
if (emb_advanced_command(stmt->mysql, COM_EXECUTE,0,0,
|
||||||
|
(const char*)&stmt->stmt_id,sizeof(stmt->stmt_id),1)
|
||||||
|
|| emb_mysql_read_query_result(stmt->mysql))
|
||||||
|
{
|
||||||
|
NET *net= &stmt->mysql->net;
|
||||||
|
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
MYSQL_METHODS embedded_methods=
|
MYSQL_METHODS embedded_methods=
|
||||||
{
|
{
|
||||||
emb_mysql_read_query_result,
|
emb_mysql_read_query_result,
|
||||||
@ -162,7 +200,8 @@ MYSQL_METHODS embedded_methods=
|
|||||||
mysql_store_result,
|
mysql_store_result,
|
||||||
emb_fetch_lengths,
|
emb_fetch_lengths,
|
||||||
emb_list_fields,
|
emb_list_fields,
|
||||||
emb_read_prepare_result
|
emb_read_prepare_result,
|
||||||
|
emb_stmt_execute
|
||||||
};
|
};
|
||||||
|
|
||||||
C_MODE_END
|
C_MODE_END
|
||||||
|
@ -636,10 +636,10 @@ void free_rows(MYSQL_DATA *cur)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static my_bool STDCALL
|
my_bool STDCALL
|
||||||
cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
||||||
const char *header, ulong header_length,
|
const char *header, ulong header_length,
|
||||||
const char *arg, ulong arg_length, my_bool skip_check)
|
const char *arg, ulong arg_length, my_bool skip_check)
|
||||||
{
|
{
|
||||||
NET *net= &mysql->net;
|
NET *net= &mysql->net;
|
||||||
my_bool result= 1;
|
my_bool result= 1;
|
||||||
@ -1407,7 +1407,8 @@ static MYSQL_METHODS client_methods=
|
|||||||
cli_mysql_use_result,
|
cli_mysql_use_result,
|
||||||
cli_fetch_lengths,
|
cli_fetch_lengths,
|
||||||
cli_list_fields,
|
cli_list_fields,
|
||||||
cli_read_prepare_result
|
cli_read_prepare_result,
|
||||||
|
cli_stmt_execute
|
||||||
};
|
};
|
||||||
|
|
||||||
MYSQL * STDCALL
|
MYSQL * STDCALL
|
||||||
|
@ -34,4 +34,5 @@
|
|||||||
|
|
||||||
#define cli_list_fields NULL
|
#define cli_list_fields NULL
|
||||||
#define cli_read_prepare_result NULL
|
#define cli_read_prepare_result NULL
|
||||||
|
#define cli_stmt_execute NULL
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user