1
/* Copyright (C) 2009 Sun Microsystems
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>
25
#include <boost/program_options.hpp>
28
using namespace drizzled;
30
namespace po= boost::program_options;
32
static bool enabled= false;
33
static bool debug_enabled= false;
36
class ClientConsole: public plugin::Client
41
const std::string &username;
42
const std::string &password;
43
const std::string &db;
46
ClientConsole(const std::string &username_arg,
47
const std::string &password_arg,
48
const std::string &db_arg) :
52
username(username_arg),
53
password(password_arg),
57
virtual void printDebug(const char *message)
60
cout << "CONSOLE: " << message << endl;
63
virtual int getFileDescriptor(void)
65
printDebug("getFileDescriptor");
69
virtual bool isConnected(void)
71
printDebug("isConnected");
75
virtual bool isReading(void)
77
printDebug("isReading");
81
virtual bool isWriting(void)
83
printDebug("isWriting");
87
virtual bool flush(void)
93
virtual void close(void)
99
virtual bool authenticate(void)
101
printDebug("authenticate");
102
session->getSecurityContext().setUser(username);
103
return session->checkUser(password, db);
106
virtual bool readCommand(char **packet, uint32_t *packet_length)
113
cout << "drizzled> ";
118
/* Start with 1 byte offset so we can set command. */
123
*packet= (char *)realloc(*packet, length);
128
cin.getline(*packet + *packet_length, length - *packet_length, ';');
129
*packet_length+= cin.gcount();
132
while (cin.eof() == false && cin.fail() == true);
134
if ((*packet_length == 1 && cin.eof() == true) ||
135
!strncasecmp(*packet + 1, "quit", 4) ||
136
!strncasecmp(*packet + 1, "exit", 4))
140
(*packet)[0]= COM_SHUTDOWN;
144
/* Skip \r and \n for next time. */
147
(*packet)[0]= COM_QUERY;
151
virtual void sendOK(void)
153
cout << "OK" << endl;
156
virtual void sendEOF(void)
158
printDebug("sendEOF");
161
virtual void sendError(uint32_t sql_errno, const char *err)
163
cout << "Error: " << sql_errno << " " << err << endl;
166
virtual bool sendFields(List<Item> *list)
168
List_iterator_fast<Item> it(*list);
177
item->make_field(&field);
178
cout << field.col_name << "\t";
187
virtual void checkRowEnd(void)
189
if (++column % max_column == 0)
195
virtual bool store(Field *from)
200
char buff[MAX_FIELD_WIDTH];
201
String str(buff, sizeof(buff), &my_charset_bin);
202
from->val_str_internal(&str);
203
return store(str.ptr(), str.length());
206
virtual bool store(void)
208
cout << "NULL" << "\t";
213
virtual bool store(int32_t from)
215
cout << from << "\t";
220
virtual bool store(uint32_t from)
222
cout << from << "\t";
227
virtual bool store(int64_t from)
229
cout << from << "\t";
234
virtual bool store(uint64_t from)
236
cout << from << "\t";
241
virtual bool store(double from, uint32_t decimals, String *buffer)
243
buffer->set_real(from, decimals, &my_charset_bin);
244
return store(buffer->ptr(), buffer->length());
247
virtual bool store(const char *from, size_t length)
249
cout.write(from, length);
255
virtual bool haveMoreData(void)
257
printDebug("haveMoreData");
261
virtual bool haveError(void)
263
printDebug("haveError");
267
virtual bool wasAborted(void)
269
printDebug("wasAborted");
274
class ListenConsole: public plugin::Listen
277
const std::string username;
278
const std::string password;
279
const std::string db;
282
ListenConsole(const std::string &name_arg,
283
const std::string &username_arg,
284
const std::string &password_arg,
285
const std::string &db_arg) :
286
plugin::Listen(name_arg),
287
username(username_arg),
288
password(password_arg),
294
virtual ~ListenConsole()
296
if (pipe_fds[0] != -1)
303
virtual bool getFileDescriptors(std::vector<int> &fds)
311
if (pipe(pipe_fds) == -1)
313
errmsg_printf(ERRMSG_LVL_ERROR, _("pipe() failed with errno %d"), errno);
317
fds.push_back(pipe_fds[0]);
318
assert(write(pipe_fds[1], "\0", 1) == 1);
322
virtual drizzled::plugin::Client *getClient(int fd)
325
assert(read(fd, buffer, 1) == 1);
326
return new ClientConsole(username, password, db);
330
static int init(drizzled::module::Context &context)
332
const module::option_map &vm= context.getOptions();
333
const string username(vm.count("username") ? vm["username"].as<string>() : "");
334
const string password(vm.count("password") ? vm["password"].as<string>() : "");
335
const string db(vm.count("db") ? vm["db"].as<string>() : "");
336
context.registerVariable(new sys_var_bool_ptr("enable", &enabled));
337
context.registerVariable(new sys_var_bool_ptr("debug_enable", &debug_enabled));
338
context.registerVariable(new sys_var_const_string_val("username", username));
339
context.registerVariable(new sys_var_const_string_val("password", password));
340
context.registerVariable(new sys_var_const_string_val("db", db));
341
context.add(new ListenConsole("console", username, password, db));
345
static void init_options(drizzled::module::option_context &context)
348
po::value<bool>(&enabled)->default_value(false)->zero_tokens(),
349
N_("Enable the console."));
351
po::value<bool>(&debug_enabled)->default_value(false)->zero_tokens(),
352
N_("Turn on extra debugging."));
355
N_("User to use for auth."));
358
N_("Password to use for auth."));
361
N_("Default database to use."));
364
DRIZZLE_DECLARE_PLUGIN
372
init, /* Plugin Init */
373
NULL, /* system variables */
374
init_options /* config options */
376
DRIZZLE_DECLARE_PLUGIN_END;