~drizzle-trunk/drizzle/development

1976.7.2 by Brian Aker
Adding execute command to go along with main command.
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
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
21
#include <config.h>
1976.7.2 by Brian Aker
Adding execute command to go along with main command.
22
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
23
#include <drizzled/session.h>
24
#include <drizzled/user_var_entry.h>
2116.1.41 by David Shrewsbury
Merge trunk and resolve conflicts
25
#include <drizzled/plugin/client/cached.h>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
26
#include <drizzled/plugin/client/concurrent.h>
27
#include <drizzled/catalog/local.h>
28
#include <drizzled/execute.h>
1976.7.2 by Brian Aker
Adding execute command to go along with main command.
29
2275.3.5 by Olaf van der Spek
Refactor
30
namespace drizzled {
1976.7.2 by Brian Aker
Adding execute command to go along with main command.
31
32
Execute::Execute(Session &arg, bool wait_arg) :
33
  wait(wait_arg),
34
  _session(arg)
35
{
36
}
37
38
void Execute::run(const char *arg, size_t length)
39
{
2275.3.5 by Olaf van der Spek
Refactor
40
  run(std::string(arg, length));
1976.7.2 by Brian Aker
Adding execute command to go along with main command.
41
}
42
2275.3.5 by Olaf van der Spek
Refactor
43
void Execute::run(const std::string &execution_string, sql::ResultSet &result_set)
2116.1.13 by David Shrewsbury
Initial work to access result set.
44
{
2275.3.5 by Olaf van der Spek
Refactor
45
  if (not _session.isConcurrentExecuteAllowed())
46
  {
47
    my_error(ER_WRONG_ARGUMENTS, MYF(0), "A Concurrent Execution Session can not launch another session.");
48
    return;
49
  }
2275.3.3 by Olaf van der Spek
Thread
50
  thread_ptr thread;
2116.1.13 by David Shrewsbury
Initial work to access result set.
51
  {
52
    plugin::client::Cached *client= new plugin::client::Cached(result_set);
53
    client->pushSQL(execution_string);
54
    Session::shared_ptr new_session= Session::make_shared(client, catalog::local());
55
    
56
    // We set the current schema.  @todo do the same with catalog
2269.1.7 by Olaf van der Spek
Use util::string::ptr
57
    util::string::ptr schema(_session.schema());
2116.1.13 by David Shrewsbury
Initial work to access result set.
58
    if (not schema->empty())
59
      new_session->set_db(*schema);
60
    
61
    new_session->setConcurrentExecute(false);
62
    
63
    // Overwrite the context in the next session, with what we have in our
64
    // session. Eventually we will allow someone to change the effective
65
    // user.
66
    new_session->user()= _session.user();
2290.1.2 by Joseph Daly
server uuid as part of replication table
67
    new_session->setOriginatingServerUUID(_session.getOriginatingServerUUID());
68
    new_session->setOriginatingCommitID(_session.getOriginatingCommitID());
2116.1.13 by David Shrewsbury
Initial work to access result set.
69
    
70
    if (Session::schedule(new_session))
71
    {
72
      Session::unlink(new_session);
73
    }
74
    else if (wait)
75
    {
76
      thread= new_session->getThread();
77
    }
78
  }
79
  
80
  if (wait && thread && thread->joinable())
81
  {
82
    // We want to make sure that we can be killed
83
    if (_session.getThread())
84
    {
85
      boost::this_thread::restore_interruption dl(_session.getThreadInterupt());
86
      
87
      try {
88
        thread->join();
89
      }
90
      catch(boost::thread_interrupted const&)
91
      {
92
        // Just surpress and return the error
93
        my_error(drizzled::ER_QUERY_INTERRUPTED, MYF(0));
94
        return;
95
      }
96
    }
97
    else
98
    {
99
      thread->join();
100
    }
101
  }
102
}
103
2275.3.5 by Olaf van der Spek
Refactor
104
void Execute::run(const std::string &execution_string)
1976.7.2 by Brian Aker
Adding execute command to go along with main command.
105
{
2275.3.5 by Olaf van der Spek
Refactor
106
  if (not _session.isConcurrentExecuteAllowed())
107
  {
108
    my_error(ER_WRONG_ARGUMENTS, MYF(0), "A Concurrent Execution Session can not launch another session.");
109
    return;
110
  }
2275.3.3 by Olaf van der Spek
Thread
111
  thread_ptr thread;
1976.7.2 by Brian Aker
Adding execute command to go along with main command.
112
  {
2116.1.13 by David Shrewsbury
Initial work to access result set.
113
    plugin::client::Concurrent *client= new plugin::client::Concurrent;
1976.7.2 by Brian Aker
Adding execute command to go along with main command.
114
    client->pushSQL(execution_string);
2039.6.3 by Brian Aker
Update for session to have a catalog object.
115
    Session::shared_ptr new_session= Session::make_shared(client, catalog::local());
1976.7.2 by Brian Aker
Adding execute command to go along with main command.
116
117
    // We set the current schema.  @todo do the same with catalog
2269.1.7 by Olaf van der Spek
Use util::string::ptr
118
    util::string::ptr schema(_session.schema());
1976.7.2 by Brian Aker
Adding execute command to go along with main command.
119
    if (not schema->empty())
120
      new_session->set_db(*schema);
121
122
    new_session->setConcurrentExecute(false);
123
124
    // Overwrite the context in the next session, with what we have in our
125
    // session. Eventually we will allow someone to change the effective
126
    // user.
2008.1.1 by Brian Aker
Adding user identifier that makes use of a shared ptr to handle concurrency
127
    new_session->user()= _session.user();
1976.7.2 by Brian Aker
Adding execute command to go along with main command.
128
129
    if (Session::schedule(new_session))
130
    {
131
      Session::unlink(new_session);
132
    }
133
    else if (wait)
134
    {
135
      thread= new_session->getThread();
136
    }
137
  }
138
139
  if (wait && thread && thread->joinable())
140
  {
141
    // We want to make sure that we can be killed
2079.4.1 by Brian Aker
Merge in code to all plugins to do whatever they need to do once all other
142
    if (_session.getThread())
143
    {
144
      boost::this_thread::restore_interruption dl(_session.getThreadInterupt());
145
146
      try {
147
        thread->join();
148
      }
149
      catch(boost::thread_interrupted const&)
150
      {
151
        // Just surpress and return the error
152
        my_error(drizzled::ER_QUERY_INTERRUPTED, MYF(0));
153
        return;
154
      }
155
    }
156
    else
157
    {
1976.7.2 by Brian Aker
Adding execute command to go along with main command.
158
      thread->join();
159
    }
160
  }
161
}
162
163
} /* namespace drizzled */