Drizzled Public API Documentation

execute.cc
1 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2010 Brian Aker
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <config.h>
22 
23 #include <drizzled/session.h>
24 #include <drizzled/user_var_entry.h>
25 #include <drizzled/plugin/client/cached.h>
26 #include <drizzled/plugin/client/concurrent.h>
27 #include <drizzled/catalog/local.h>
28 #include <drizzled/execute.h>
29 
30 namespace drizzled {
31 
32 Execute::Execute(Session &arg, bool wait_arg) :
33  wait(wait_arg),
34  _session(arg)
35 {
36 }
37 
38 void Execute::run(str_ref execution_string, sql::ResultSet &result_set)
39 {
40  if (not _session.isConcurrentExecuteAllowed())
41  {
42  my_error(ER_WRONG_ARGUMENTS, MYF(0), "A Concurrent Execution Session can not launch another session.");
43  return;
44  }
45  thread_ptr thread;
46  {
47  plugin::client::Cached *client= new plugin::client::Cached(result_set);
48  client->pushSQL(execution_string);
49  Session::shared_ptr new_session= Session::make_shared(client, catalog::local());
50 
51  // We set the current schema. @todo do the same with catalog
52  util::string::ptr schema(_session.schema());
53  if (not schema->empty())
54  new_session->set_schema(*schema);
55 
56  new_session->setConcurrentExecute(false);
57 
58  // Overwrite the context in the next session, with what we have in our
59  // session. Eventually we will allow someone to change the effective
60  // user.
61  new_session->user()= _session.user();
62  new_session->setOriginatingServerUUID(_session.getOriginatingServerUUID());
63  new_session->setOriginatingCommitID(_session.getOriginatingCommitID());
64 
65  if (Session::schedule(new_session))
66  {
67  Session::unlink(new_session);
68  }
69  else if (wait)
70  {
71  thread= new_session->getThread();
72  }
73  }
74 
75  if (wait && thread && thread->joinable())
76  {
77  // We want to make sure that we can be killed
78  if (_session.getThread())
79  {
80  boost::this_thread::restore_interruption dl(_session.getThreadInterupt());
81 
82  try
83  {
84  thread->join();
85  }
86  catch(boost::thread_interrupted const&)
87  {
88  // Just surpress and return the error
89  my_error(drizzled::ER_QUERY_INTERRUPTED, MYF(0));
90  return;
91  }
92  }
93  else
94  {
95  thread->join();
96  }
97  }
98 }
99 
100 void Execute::run(str_ref execution_string)
101 {
102  if (not _session.isConcurrentExecuteAllowed())
103  {
104  my_error(ER_WRONG_ARGUMENTS, MYF(0), "A Concurrent Execution Session can not launch another session.");
105  return;
106  }
107  thread_ptr thread;
108  {
109  plugin::client::Concurrent *client= new plugin::client::Concurrent;
110  client->pushSQL(execution_string);
111  Session::shared_ptr new_session= Session::make_shared(client, catalog::local());
112 
113  // We set the current schema. @todo do the same with catalog
114  util::string::ptr schema(_session.schema());
115  if (not schema->empty())
116  new_session->set_schema(*schema);
117 
118  new_session->setConcurrentExecute(false);
119 
120  // Overwrite the context in the next session, with what we have in our
121  // session. Eventually we will allow someone to change the effective
122  // user.
123  new_session->user()= _session.user();
124 
125  if (Session::schedule(new_session))
126  {
127  Session::unlink(new_session);
128  }
129  else if (wait)
130  {
131  thread= new_session->getThread();
132  }
133  }
134 
135  if (wait && thread && thread->joinable())
136  {
137  // We want to make sure that we can be killed
138  if (_session.getThread())
139  {
140  boost::this_thread::restore_interruption dl(_session.getThreadInterupt());
141 
142  try
143  {
144  thread->join();
145  }
146  catch(boost::thread_interrupted const&)
147  {
148  // Just surpress and return the error
149  my_error(drizzled::ER_QUERY_INTERRUPTED, MYF(0));
150  return;
151  }
152  }
153  else
154  {
155  thread->join();
156  }
157  }
158 }
159 
160 } /* namespace drizzled */