18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
#include "drizzled/statement/execute.h"
24
#include "drizzled/session.h"
25
#include "drizzled/execute.h"
26
#include "drizzled/user_var_entry.h"
27
#include "drizzled/plugin/listen.h"
28
#include "drizzled/plugin/client.h"
29
#include "drizzled/plugin/null_client.h"
30
#include "drizzled/plugin/client/concurrent.h"
35
void mysql_parse(drizzled::Session *session, const char *inBuf, uint32_t length);
23
#include <drizzled/statement/execute.h>
24
#include <drizzled/session.h>
25
#include <drizzled/execute.h>
26
#include <drizzled/user_var_entry.h>
27
#include <drizzled/plugin/listen.h>
28
#include <drizzled/plugin/client.h>
29
#include <drizzled/plugin/null_client.h>
30
#include <drizzled/plugin/client/concurrent.h>
31
#include <drizzled/sql_lex.h>
35
void parse(drizzled::Session&, const char *inBuf, uint32_t length);
40
39
Execute::Execute(Session *in_session,
41
drizzled::execute_string_t to_execute_arg,
40
execute_string_t to_execute_arg,
43
42
bool is_concurrent_arg,
44
43
bool should_wait_arg) :
56
55
if (to_execute.isVariable())
58
user_var_entry *var= getSession()->getVariable(to_execute, false);
57
user_var_entry *var= session().getVariable(to_execute, false);
60
59
if (var && var->length && var->value && var->type == STRING_RESULT)
62
LEX_STRING tmp_for_var;
63
tmp_for_var.str= var->value;
64
tmp_for_var.length= var->length;
61
lex_string_t tmp_for_var;
62
tmp_for_var.assign(var->value, var->length);
65
63
to_execute.set(tmp_for_var);
75
bool statement::Execute::runStatement(plugin::NullClient *client, const std::string &arg)
73
bool statement::Execute::runStatement(plugin::NullClient& client, const std::string &arg)
78
if (not getSession()->executeStatement())
76
if (not session().executeStatement())
81
if (getSession()->is_error())
79
if (session().is_error())
99
97
bool statement::Execute::execute_shell()
101
if (to_execute.length == 0)
99
if (to_execute.size() == 0)
103
101
my_error(ER_WRONG_ARGUMENTS, MYF(0), "Invalid Variable");
116
114
if (is_concurrent)
118
if (not getSession()->isConcurrentExecuteAllowed())
116
if (not session().isConcurrentExecuteAllowed())
120
118
my_error(ER_WRONG_ARGUMENTS, MYF(0), "A Concurrent Execution Session can not launch another session.");
124
drizzled::Execute executer(*getSession(), should_wait);
125
executer.run(to_execute.str, to_execute.length);
122
drizzled::Execute executer(session(), should_wait);
123
executer.run(to_execute);
127
125
else // Non-concurrent run.
131
plugin::Client *temp= getSession()->getClient();
132
plugin::NullClient *null_client= new plugin::NullClient;
129
plugin::Client *temp= session().getClient();
130
boost::scoped_ptr<plugin::NullClient> null_client(new plugin::NullClient);
134
getSession()->setClient(null_client);
132
session().setClient(null_client.get());
136
134
bool error_occured= false;
137
135
bool is_savepoint= false;
139
137
std::string start_sql;
140
if (getSession()->inTransaction())
138
if (session().inTransaction())
142
140
// @todo Figure out something a bit more solid then this.
143
start_sql.append("SAVEPOINT execute_internal_savepoint");
141
start_sql= "SAVEPOINT execute_internal_savepoint";
144
142
is_savepoint= true;
148
start_sql.append("START TRANSACTION");
146
start_sql= "START TRANSACTION";
151
error_occured= runStatement(null_client, start_sql);
149
error_occured= runStatement(*null_client, start_sql);
154
152
// @note this is copied from code in NULL client, all of this belongs
156
154
if (not error_occured)
158
156
typedef boost::tokenizer<boost::escaped_list_separator<char> > Tokenizer;
159
std::string full_string(to_execute.str, to_execute.length);
157
std::string full_string(to_execute.data(), to_execute.size());
160
158
Tokenizer tok(full_string, boost::escaped_list_separator<char>("\\", ";", "\""));
162
for (Tokenizer::iterator iter= tok.begin();
163
iter != tok.end() and getSession()->getKilled() != Session::KILL_CONNECTION;
160
for (Tokenizer::iterator iter= tok.begin(); iter != tok.end(); ++iter)
166
if (runStatement(null_client, *iter))
162
if (session().getKilled() == Session::KILL_CONNECTION)
164
if (runStatement(*null_client, *iter))
168
166
error_occured= true;
175
173
std::string final_sql;
176
174
if (is_savepoint)
180
final_sql.append("ROLLBACK TO SAVEPOINT execute_internal_savepoint");
184
final_sql.append("RELEASE SAVEPOINT execute_internal_savepoint");
176
final_sql= error_occured ?
177
"ROLLBACK TO SAVEPOINT execute_internal_savepoint" :
178
"RELEASE SAVEPOINT execute_internal_savepoint";
191
final_sql.append("ROLLBACK");
195
final_sql.append("COMMIT");
182
final_sql= error_occured ? "ROLLBACK" : "COMMIT";
199
185
// Run the cleanup command, we currently ignore if an error occurs
201
(void)runStatement(null_client, final_sql);
187
(void)runStatement(*null_client, final_sql);
205
getSession()->setClient(temp);
206
if (getSession()->is_error())
191
session().setClient(temp);
192
if (session().is_error())
208
getSession()->clear_error(true);
194
session().clear_error(true);
212
getSession()->clearDiagnostics();
198
session().clearDiagnostics();
215
getSession()->my_ok();
217
203
null_client->close();
222
mysql_parse(getSession(), to_execute.str, to_execute.length);
207
parse(session(), to_execute.data(), to_execute.size());