1
/* Copyright (C) 2009 Sun Microsystems, Inc.
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
17
#include <drizzled/field.h>
18
#include <drizzled/gettext.h>
19
#include <drizzled/plugin/listen_tcp.h>
20
#include <drizzled/plugin/client.h>
21
#include <drizzled/session.h>
22
#include <drizzled/module/option_map.h>
23
#include <drizzled/plugin/catalog.h>
24
#include <drizzled/plugin.h>
28
#include <boost/program_options.hpp>
30
#include <client/user_detect.h>
33
using namespace drizzled;
35
namespace po= boost::program_options;
37
static bool enabled= false;
38
static bool debug_enabled= false;
41
class ClientConsole: public plugin::Client
46
const std::string &username;
47
const std::string &password;
48
const std::string &schema;
49
const std::string &_catalog;
52
ClientConsole(const std::string &username_arg,
53
const std::string &password_arg,
54
const std::string &schema_arg,
55
const std::string &catalog_arg) :
59
username(username_arg),
60
password(password_arg),
65
virtual void printDebug(const char *message)
68
cout << "CONSOLE: " << message << endl;
71
catalog::Instance::shared_ptr catalog()
73
identifier::Catalog identifier(_catalog);
74
catalog::Instance::shared_ptr tmp= plugin::Catalog::getInstance(identifier);
77
std::cerr << "Invalid catalog '" << identifier << "', resorting to 'local' catalog" << std::endl;
82
virtual int getFileDescriptor(void)
84
printDebug("getFileDescriptor");
88
virtual bool isConnected(void)
90
printDebug("isConnected");
94
virtual bool flush(void)
100
virtual void close(void)
106
virtual bool authenticate(void)
108
printDebug("authenticate");
109
identifier::user::mptr user= identifier::User::make_shared();
110
user->setUser(username);
111
session->setUser(user);
113
return session->checkUser(password, schema);
116
virtual bool readCommand(char **packet, uint32_t& packet_length)
123
cout << "drizzled> ";
128
/* Start with 1 byte offset so we can set command. */
133
*packet= (char *)realloc(*packet, length);
138
cin.getline(*packet + packet_length, length - packet_length, ';');
139
packet_length+= cin.gcount();
142
while (cin.eof() == false && cin.fail() == true);
144
if ((packet_length == 1 && cin.eof() == true) or
145
not strncasecmp(*packet + 1, "quit", 4) or
146
not strncasecmp(*packet + 1, "exit", 4) or
147
not strncasecmp(*packet + 1, "shutdown", sizeof("shutdown") -1))
151
(*packet)[0]= COM_SHUTDOWN;
156
/* Skip \r and \n for next time. */
159
(*packet)[0]= COM_QUERY;
164
virtual void sendOK(void)
166
cout << "OK" << endl;
169
virtual void sendEOF(void)
171
printDebug("sendEOF");
174
virtual void sendError(const drizzled::error_t sql_errno, const char *err)
176
cout << "Error: " << static_cast<long>(sql_errno) << " " << err << endl;
179
virtual void sendFields(List<Item>& list)
181
List<Item>::iterator it(list.begin());
186
while (Item* item=it++)
189
item->make_field(&field);
190
cout << field.col_name << "\t";
196
virtual void checkRowEnd(void)
198
if (++column % max_column == 0)
204
virtual void store(Field *from)
209
char buff[MAX_FIELD_WIDTH];
210
String str(buff, sizeof(buff), &my_charset_bin);
211
from->val_str_internal(&str);
212
return store(str.ptr(), str.length());
215
virtual void store(void)
217
cout << "NULL" << "\t";
221
virtual void store(int32_t from)
223
cout << from << "\t";
227
virtual void store(uint32_t from)
229
cout << from << "\t";
233
virtual void store(int64_t from)
235
cout << from << "\t";
239
virtual void store(uint64_t from)
241
cout << from << "\t";
245
virtual void store(double from, uint32_t decimals, String *buffer)
247
buffer->set_real(from, decimals, &my_charset_bin);
248
store(buffer->ptr(), buffer->length());
251
virtual void store(const char *from, size_t length)
253
cout.write(from, length);
258
virtual bool haveError()
260
printDebug("haveError");
264
virtual bool wasAborted()
266
printDebug("wasAborted");
270
bool isConsole() const
275
bool isInteractive() const
281
class ListenConsole: public plugin::Listen
284
const std::string username;
285
const std::string password;
286
const std::string schema;
287
const std::string _catalog;
290
ListenConsole(const std::string &name_arg,
291
const std::string &username_arg,
292
const std::string &password_arg,
293
const std::string &schema_arg,
294
const std::string &catalog_arg) :
295
plugin::Listen(name_arg),
296
username(username_arg),
297
password(password_arg),
299
_catalog(catalog_arg)
304
virtual ~ListenConsole()
306
if (pipe_fds[0] != -1)
313
virtual bool getFileDescriptors(std::vector<int> &fds)
321
if (pipe(pipe_fds) == -1)
323
errmsg_printf(error::ERROR, _("pipe() failed with errno %d"), errno);
327
fds.push_back(pipe_fds[0]);
328
assert(write(pipe_fds[1], "\0", 1) == 1);
332
virtual drizzled::plugin::Client *getClient(int fd)
335
assert(read(fd, buffer, 1) == 1);
337
return new ClientConsole(username, password, schema, _catalog);
341
static int init(drizzled::module::Context &context)
343
const module::option_map &vm= context.getOptions();
344
context.add(new ListenConsole("console", vm["username"].as<string>(),
345
vm["password"].as<string>(), vm["schema"].as<string>(), vm["catalog"].as<string>()));
349
static void init_options(drizzled::module::option_context &context)
352
po::value<bool>(&enabled)->default_value(false)->zero_tokens(),
353
N_("Enable the console."));
355
po::value<bool>(&debug_enabled)->default_value(false)->zero_tokens(),
356
N_("Turn on extra debugging."));
357
UserDetect detected_user;
358
const char* shell_user= detected_user.getUser();
360
po::value<string>()->default_value(shell_user ? shell_user : ""),
361
N_("User to use for auth."));
363
po::value<string>()->default_value(""),
364
N_("Password to use for auth."));
366
po::value<string>()->default_value("LOCAL"),
367
N_("Default catalog to use."));
369
po::value<string>()->default_value(""),
370
N_("Default schema to use."));
373
DRIZZLE_DECLARE_PLUGIN
381
init, /* Plugin Init */
383
init_options /* config options */
385
DRIZZLE_DECLARE_PLUGIN_END;