Drizzled Public API Documentation

execute.cc
00001 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2010 Brian Aker
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #include <config.h>
00022 
00023 #include <drizzled/session.h>
00024 #include <drizzled/user_var_entry.h>
00025 #include <drizzled/plugin/client/cached.h>
00026 #include <drizzled/plugin/client/concurrent.h>
00027 #include <drizzled/catalog/local.h>
00028 #include <drizzled/execute.h>
00029 
00030 namespace drizzled {
00031 
00032 Execute::Execute(Session &arg, bool wait_arg) :
00033   wait(wait_arg),
00034   _session(arg)
00035 {
00036 }
00037 
00038 void Execute::run(str_ref execution_string, sql::ResultSet &result_set)
00039 {
00040   if (not _session.isConcurrentExecuteAllowed())
00041   {
00042     my_error(ER_WRONG_ARGUMENTS, MYF(0), "A Concurrent Execution Session can not launch another session.");
00043     return;
00044   }
00045   thread_ptr thread;
00046   {
00047     plugin::client::Cached *client= new plugin::client::Cached(result_set);
00048     client->pushSQL(execution_string);
00049     Session::shared_ptr new_session= Session::make_shared(client, catalog::local());
00050     
00051     // We set the current schema.  @todo do the same with catalog
00052     util::string::ptr schema(_session.schema());
00053     if (not schema->empty())
00054       new_session->set_schema(*schema);
00055     
00056     new_session->setConcurrentExecute(false);
00057     
00058     // Overwrite the context in the next session, with what we have in our
00059     // session. Eventually we will allow someone to change the effective
00060     // user.
00061     new_session->user()= _session.user();
00062     new_session->setOriginatingServerUUID(_session.getOriginatingServerUUID());
00063     new_session->setOriginatingCommitID(_session.getOriginatingCommitID());
00064     
00065     if (Session::schedule(new_session))
00066     {
00067       Session::unlink(new_session);
00068     }
00069     else if (wait)
00070     {
00071       thread= new_session->getThread();
00072     }
00073   }
00074   
00075   if (wait && thread && thread->joinable())
00076   {
00077     // We want to make sure that we can be killed
00078     if (_session.getThread())
00079     {
00080       boost::this_thread::restore_interruption dl(_session.getThreadInterupt());
00081       
00082       try 
00083       {
00084         thread->join();
00085       }
00086       catch(boost::thread_interrupted const&)
00087       {
00088         // Just surpress and return the error
00089         my_error(drizzled::ER_QUERY_INTERRUPTED, MYF(0));
00090         return;
00091       }
00092     }
00093     else
00094     {
00095       thread->join();
00096     }
00097   }
00098 }
00099 
00100 void Execute::run(str_ref execution_string)
00101 {
00102   if (not _session.isConcurrentExecuteAllowed())
00103   {
00104     my_error(ER_WRONG_ARGUMENTS, MYF(0), "A Concurrent Execution Session can not launch another session.");
00105     return;
00106   }
00107   thread_ptr thread;
00108   {
00109     plugin::client::Concurrent *client= new plugin::client::Concurrent;
00110     client->pushSQL(execution_string);
00111     Session::shared_ptr new_session= Session::make_shared(client, catalog::local());
00112 
00113     // We set the current schema.  @todo do the same with catalog
00114     util::string::ptr schema(_session.schema());
00115     if (not schema->empty())
00116       new_session->set_schema(*schema);
00117 
00118     new_session->setConcurrentExecute(false);
00119 
00120     // Overwrite the context in the next session, with what we have in our
00121     // session. Eventually we will allow someone to change the effective
00122     // user.
00123     new_session->user()= _session.user();
00124 
00125     if (Session::schedule(new_session))
00126     {
00127       Session::unlink(new_session);
00128     }
00129     else if (wait)
00130     {
00131       thread= new_session->getThread();
00132     }
00133   }
00134 
00135   if (wait && thread && thread->joinable())
00136   {
00137     // We want to make sure that we can be killed
00138     if (_session.getThread())
00139     {
00140       boost::this_thread::restore_interruption dl(_session.getThreadInterupt());
00141 
00142       try 
00143       {
00144         thread->join();
00145       }
00146       catch(boost::thread_interrupted const&)
00147       {
00148         // Just surpress and return the error
00149         my_error(drizzled::ER_QUERY_INTERRUPTED, MYF(0));
00150         return;
00151       }
00152     }
00153     else
00154     {
00155       thread->join();
00156     }
00157   }
00158 }
00159 
00160 } /* namespace drizzled */