~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/statement/execute.cc

  • Committer: Mark Atwood
  • Date: 2011-10-27 05:08:12 UTC
  • mfrom: (2445.1.11 rf)
  • Revision ID: me@mark.atwood.name-20111027050812-1icvs72lb0u4xdc4
mergeĀ lp:~olafvdspek/drizzle/refactor8

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
19
 */
20
20
 
21
 
#include "config.h"
22
 
 
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
 
 
32
 
namespace drizzled
33
 
{
34
 
 
35
 
void mysql_parse(drizzled::Session *session, const char *inBuf, uint32_t length);
36
 
 
37
 
namespace statement
38
 
{
 
21
#include <config.h>
 
22
 
 
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>
 
32
 
 
33
namespace drizzled {
 
34
 
 
35
void parse(drizzled::Session&, const char *inBuf, uint32_t length);
 
36
 
 
37
namespace statement {
39
38
 
40
39
Execute::Execute(Session *in_session,
41
 
                 drizzled::execute_string_t to_execute_arg,
 
40
                 execute_string_t to_execute_arg,
42
41
                 bool is_quiet_arg,
43
42
                 bool is_concurrent_arg,
44
43
                 bool should_wait_arg) :
55
54
{
56
55
  if (to_execute.isVariable())
57
56
  {
58
 
    user_var_entry *var= getSession()->getVariable(to_execute, false);
 
57
    user_var_entry *var= session().getVariable(to_execute, false);
59
58
 
60
59
    if (var && var->length && var->value && var->type == STRING_RESULT)
61
60
    {
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);
66
64
 
67
65
      return true;
72
70
}
73
71
 
74
72
 
75
 
bool statement::Execute::runStatement(plugin::NullClient *client, const std::string &arg)
 
73
bool statement::Execute::runStatement(plugin::NullClient& client, const std::string &arg)
76
74
{
77
 
  client->pushSQL(arg);
78
 
  if (not getSession()->executeStatement())
 
75
  client.pushSQL(arg);
 
76
  if (not session().executeStatement())
79
77
    return true;
80
78
 
81
 
  if (getSession()->is_error())
 
79
  if (session().is_error())
82
80
    return true;
83
81
 
84
82
  return false;
90
88
  bool ret= execute_shell();
91
89
 
92
90
  // We have to restore ourselves at the top for delete() to work.
93
 
  getSession()->getLex()->statement= this;
 
91
  lex().statement= this;
94
92
 
95
93
  return ret;
96
94
}
98
96
 
99
97
bool statement::Execute::execute_shell()
100
98
{
101
 
  if (to_execute.length == 0)
 
99
  if (to_execute.size() == 0)
102
100
  {
103
101
    my_error(ER_WRONG_ARGUMENTS, MYF(0), "Invalid Variable");
104
102
    return false;
115
113
 
116
114
  if (is_concurrent)
117
115
  {
118
 
    if (not getSession()->isConcurrentExecuteAllowed())
 
116
    if (not session().isConcurrentExecuteAllowed())
119
117
    {
120
118
      my_error(ER_WRONG_ARGUMENTS, MYF(0), "A Concurrent Execution Session can not launch another session.");
121
119
      return false;
122
120
    }
123
121
 
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);
126
124
  }
127
125
  else // Non-concurrent run.
128
126
  {
129
127
    if (is_quiet)
130
128
    {
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);
133
131
 
134
 
      getSession()->setClient(null_client);
 
132
      session().setClient(null_client.get());
135
133
      
136
134
      bool error_occured= false;
137
135
      bool is_savepoint= false;
138
136
      {
139
137
        std::string start_sql;
140
 
        if (getSession()->inTransaction())
 
138
        if (session().inTransaction())
141
139
        {
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;
145
143
        }
146
144
        else
147
145
        {
148
 
          start_sql.append("START TRANSACTION");
 
146
          start_sql= "START TRANSACTION";
149
147
        }
150
148
 
151
 
        error_occured= runStatement(null_client, start_sql);
 
149
        error_occured= runStatement(*null_client, start_sql);
152
150
      }
153
151
 
154
152
      // @note this is copied from code in NULL client, all of this belongs
156
154
      if (not error_occured)
157
155
      {
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>("\\", ";", "\""));
161
159
 
162
 
        for (Tokenizer::iterator iter= tok.begin();
163
 
             iter != tok.end() and getSession()->getKilled() != Session::KILL_CONNECTION;
164
 
             ++iter)
 
160
        for (Tokenizer::iterator iter= tok.begin(); iter != tok.end(); ++iter)
165
161
        {
166
 
          if (runStatement(null_client, *iter))
 
162
          if (session().getKilled() == Session::KILL_CONNECTION)
 
163
            break;
 
164
          if (runStatement(*null_client, *iter))
167
165
          {
168
166
            error_occured= true;
169
167
            break;
175
173
          std::string final_sql;
176
174
          if (is_savepoint)
177
175
          {
178
 
            if (error_occured)
179
 
            {
180
 
              final_sql.append("ROLLBACK TO SAVEPOINT execute_internal_savepoint");
181
 
            }
182
 
            else
183
 
            {
184
 
              final_sql.append("RELEASE SAVEPOINT execute_internal_savepoint");
185
 
            }
 
176
            final_sql= error_occured ? 
 
177
              "ROLLBACK TO SAVEPOINT execute_internal_savepoint" : 
 
178
              "RELEASE SAVEPOINT execute_internal_savepoint";
186
179
          }
187
180
          else
188
181
          {
189
 
            if (error_occured)
190
 
            {
191
 
              final_sql.append("ROLLBACK");
192
 
            }
193
 
            else
194
 
            {
195
 
              final_sql.append("COMMIT");
196
 
            }
 
182
            final_sql= error_occured ? "ROLLBACK" : "COMMIT";
197
183
          }
198
184
 
199
185
          // Run the cleanup command, we currently ignore if an error occurs
200
186
          // here.
201
 
          (void)runStatement(null_client, final_sql);
 
187
          (void)runStatement(*null_client, final_sql);
202
188
        }
203
189
      }
204
190
 
205
 
      getSession()->setClient(temp);
206
 
      if (getSession()->is_error())
 
191
      session().setClient(temp);
 
192
      if (session().is_error())
207
193
      {
208
 
        getSession()->clear_error(true);
 
194
        session().clear_error(true);
209
195
      }
210
196
      else
211
197
      {
212
 
        getSession()->clearDiagnostics();
 
198
        session().clearDiagnostics();
213
199
      }
214
200
 
215
 
      getSession()->my_ok();
 
201
      session().my_ok();
216
202
 
217
203
      null_client->close();
218
 
      delete null_client;
219
204
    }
220
205
    else
221
206
    {
222
 
      mysql_parse(getSession(), to_execute.str, to_execute.length);
 
207
      parse(session(), to_execute.data(), to_execute.size());
223
208
    }
224
209
  }
225
210