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/gettext.h>
18
#include <drizzled/plugin/listen_tcp.h>
19
#include <drizzled/plugin/client.h>
20
#include <drizzled/session.h>
21
#include <drizzled/module/option_map.h>
23
#include <drizzled/plugin/catalog.h>
27
#include <boost/program_options.hpp>
30
using namespace drizzled;
32
namespace po= boost::program_options;
34
static bool enabled= false;
35
static bool debug_enabled= false;
38
class ClientConsole: public plugin::Client
43
const std::string &username;
44
const std::string &password;
45
const std::string &schema;
46
const std::string &_catalog;
49
ClientConsole(const std::string &username_arg,
50
const std::string &password_arg,
51
const std::string &schema_arg,
52
const std::string &catalog_arg) :
56
username(username_arg),
57
password(password_arg),
62
virtual void printDebug(const char *message)
65
cout << "CONSOLE: " << message << endl;
68
catalog::Instance::shared_ptr catalog()
70
identifier::Catalog identifier(_catalog);
71
catalog::Instance::shared_ptr tmp= plugin::Catalog::getInstance(identifier);
74
std::cerr << "Invalid catalog '" << identifier << "', resorting to 'local' catalog" << std::endl;
79
virtual int getFileDescriptor(void)
81
printDebug("getFileDescriptor");
85
virtual bool isConnected(void)
87
printDebug("isConnected");
91
virtual bool isReading(void)
93
printDebug("isReading");
97
virtual bool isWriting(void)
99
printDebug("isWriting");
103
virtual bool flush(void)
109
virtual void close(void)
115
virtual bool authenticate(void)
117
printDebug("authenticate");
118
identifier::User::shared_ptr user= identifier::User::make_shared();
119
user->setUser(username);
120
session->setUser(user);
122
return session->checkUser(password, schema);
125
virtual bool readCommand(char **packet, uint32_t *packet_length)
132
cout << "drizzled> ";
137
/* Start with 1 byte offset so we can set command. */
142
*packet= (char *)realloc(*packet, length);
147
cin.getline(*packet + *packet_length, length - *packet_length, ';');
148
*packet_length+= cin.gcount();
151
while (cin.eof() == false && cin.fail() == true);
153
if ((*packet_length == 1 && cin.eof() == true) or
154
not strncasecmp(*packet + 1, "quit", 4) or
155
not strncasecmp(*packet + 1, "exit", 4) or
156
not strncasecmp(*packet + 1, "shutdown", sizeof("shutdown") -1))
160
(*packet)[0]= COM_SHUTDOWN;
165
/* Skip \r and \n for next time. */
168
(*packet)[0]= COM_QUERY;
173
virtual void sendOK(void)
175
cout << "OK" << endl;
178
virtual void sendEOF(void)
180
printDebug("sendEOF");
183
virtual void sendError(const drizzled::error_t sql_errno, const char *err)
185
cout << "Error: " << static_cast<long>(sql_errno) << " " << err << endl;
188
virtual bool sendFields(List<Item> *list)
190
List<Item>::iterator it(list->begin());
199
item->make_field(&field);
200
cout << field.col_name << "\t";
209
virtual void checkRowEnd(void)
211
if (++column % max_column == 0)
217
virtual bool store(Field *from)
222
char buff[MAX_FIELD_WIDTH];
223
String str(buff, sizeof(buff), &my_charset_bin);
224
from->val_str_internal(&str);
225
return store(str.ptr(), str.length());
228
virtual bool store(void)
230
cout << "NULL" << "\t";
235
virtual bool store(int32_t from)
237
cout << from << "\t";
242
virtual bool store(uint32_t from)
244
cout << from << "\t";
249
virtual bool store(int64_t from)
251
cout << from << "\t";
256
virtual bool store(uint64_t from)
258
cout << from << "\t";
263
virtual bool store(double from, uint32_t decimals, String *buffer)
265
buffer->set_real(from, decimals, &my_charset_bin);
266
return store(buffer->ptr(), buffer->length());
269
virtual bool store(const char *from, size_t length)
271
cout.write(from, length);
277
virtual bool haveMoreData(void)
279
printDebug("haveMoreData");
283
virtual bool haveError(void)
285
printDebug("haveError");
289
virtual bool wasAborted(void)
291
printDebug("wasAborted");
301
class ListenConsole: public plugin::Listen
304
const std::string username;
305
const std::string password;
306
const std::string schema;
307
const std::string _catalog;
310
ListenConsole(const std::string &name_arg,
311
const std::string &username_arg,
312
const std::string &password_arg,
313
const std::string &schema_arg,
314
const std::string &catalog_arg) :
315
plugin::Listen(name_arg),
316
username(username_arg),
317
password(password_arg),
319
_catalog(catalog_arg)
324
virtual ~ListenConsole()
326
if (pipe_fds[0] != -1)
333
virtual bool getFileDescriptors(std::vector<int> &fds)
341
if (pipe(pipe_fds) == -1)
343
errmsg_printf(error::ERROR, _("pipe() failed with errno %d"), errno);
347
fds.push_back(pipe_fds[0]);
348
assert(write(pipe_fds[1], "\0", 1) == 1);
352
virtual drizzled::plugin::Client *getClient(int fd)
355
assert(read(fd, buffer, 1) == 1);
357
return new ClientConsole(username, password, schema, _catalog);
361
static int init(drizzled::module::Context &context)
363
const module::option_map &vm= context.getOptions();
364
const string username(vm.count("username") ? vm["username"].as<string>() : "");
365
const string password(vm.count("password") ? vm["password"].as<string>() : "");
366
const string schema(vm.count("schema") ? vm["schema"].as<string>() : "");
368
const std::string catalog(vm.count("catalog") ? vm["catalog"].as<string>() : "LOCAL");
370
context.add(new ListenConsole("console", username, password, schema, catalog));
375
static void init_options(drizzled::module::option_context &context)
378
po::value<bool>(&enabled)->default_value(false)->zero_tokens(),
379
N_("Enable the console."));
381
po::value<bool>(&debug_enabled)->default_value(false)->zero_tokens(),
382
N_("Turn on extra debugging."));
385
N_("User to use for auth."));
388
N_("Password to use for auth."));
391
N_("Default catalog to use."));
394
N_("Default schema to use."));
397
DRIZZLE_DECLARE_PLUGIN
405
init, /* Plugin Init */
407
init_options /* config options */
409
DRIZZLE_DECLARE_PLUGIN_END;