Commit 7a763f3f authored by hf@deer.(none)'s avatar hf@deer.(none)

SCRUM

prepared statements in embedded library
parent 744fc5a5
...@@ -560,6 +560,7 @@ typedef struct st_mysql_methods ...@@ -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); ...@@ -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); ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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)), ...@@ -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) ...@@ -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) ...@@ -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= ...@@ -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) ...@@ -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= ...@@ -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 @@ ...@@ -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
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