~drizzle-trunk/drizzle/development

971.6.9 by Eric Day
Added console plugin.
1
/* Copyright (C) 2009 Sun Microsystems
2
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.
6
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.
11
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 */
15
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
16
#include "config.h"
971.6.9 by Eric Day
Added console plugin.
17
#include <drizzled/gettext.h>
18
#include <drizzled/plugin/listen_tcp.h>
19
#include <drizzled/plugin/client.h>
1305.1.2 by Eric Day
Added command line options to console to pass username, password, and db name during authentication step.
20
#include <drizzled/session.h>
1626.2.1 by Monty Taylor
Added wrapper around variables_map to allow us to pull values back out of
21
#include <drizzled/module/option_map.h>
971.6.9 by Eric Day
Added console plugin.
22
23
#include <iostream>
24
1625.1.8 by Monty Taylor
Converted really simple options in console plugin.
25
#include <boost/program_options.hpp>
26
971.6.9 by Eric Day
Added console plugin.
27
using namespace std;
28
using namespace drizzled;
29
1625.1.8 by Monty Taylor
Converted really simple options in console plugin.
30
namespace po= boost::program_options;
31
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
32
static bool enabled= false;
33
static bool debug_enabled= false;
1626.2.4 by Monty Taylor
Replaced terrible casting with strdup+free.
34
static char* username= NULL;
35
static char* password= NULL;
36
static char* db= NULL;
1305.1.2 by Eric Day
Added command line options to console to pass username, password, and db name during authentication step.
37
971.6.9 by Eric Day
Added console plugin.
38
39
class ClientConsole: public plugin::Client
40
{
41
  bool is_dead;
42
  uint32_t column;
43
  uint32_t max_column;
44
45
public:
46
  ClientConsole():
47
    is_dead(false),
48
    column(0),
49
    max_column(0)
50
  {}
51
52
  virtual void printDebug(const char *message)
53
  {
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
54
    if (debug_enabled)
971.6.9 by Eric Day
Added console plugin.
55
      cout << "CONSOLE: " << message << endl;
56
  }
57
58
  virtual int getFileDescriptor(void)
59
  {
60
    printDebug("getFileDescriptor");
61
    return 0;
62
  }
63
64
  virtual bool isConnected(void)
65
  {
66
    printDebug("isConnected");
67
    return true;
68
  }
69
70
  virtual bool isReading(void)
71
  {
72
    printDebug("isReading");
73
    return false;
74
  }
75
76
  virtual bool isWriting(void)
77
  {
78
    printDebug("isWriting");
79
    return false;
80
  }
81
82
  virtual bool flush(void)
83
  {
84
    printDebug("flush");
85
    return false;
86
  }
87
88
  virtual void close(void)
89
  {
90
    printDebug("close");
91
    is_dead= true;
92
  }
93
94
  virtual bool authenticate(void)
95
  {
96
    printDebug("authenticate");
1626.2.2 by Monty Taylor
Moved ownership of the variable_map to the module (avoids copying, also
97
    session->getSecurityContext().setUser(username);
1305.1.2 by Eric Day
Added command line options to console to pass username, password, and db name during authentication step.
98
    return session->checkUser(password, strlen(password), db);
971.6.9 by Eric Day
Added console plugin.
99
  }
100
101
  virtual bool readCommand(char **packet, uint32_t *packet_length)
102
  {
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
103
    uint32_t length;
971.6.9 by Eric Day
Added console plugin.
104
105
    if (is_dead)
106
      return false;
107
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
108
    cout << "drizzled> ";
109
110
    length= 1024;
111
    *packet= NULL;
112
113
    /* Start with 1 byte offset so we can set command. */
114
    *packet_length= 1;
115
116
    do
117
    {
118
      *packet= (char *)realloc(*packet, length);
119
      if (*packet == NULL)
120
        return false;
121
122
      cin.clear();
123
      cin.getline(*packet + *packet_length, length - *packet_length, ';');
124
      *packet_length+= cin.gcount();
125
      length*= 2;
126
    }
127
    while (cin.eof() == false && cin.fail() == true);
128
129
    if ((*packet_length == 1 && cin.eof() == true) ||
130
        !strncasecmp(*packet + 1, "quit", 4) ||
131
        !strncasecmp(*packet + 1, "exit", 4))
971.6.9 by Eric Day
Added console plugin.
132
    {
133
      is_dead= true;
134
      *packet_length= 1;
135
      (*packet)[0]= COM_SHUTDOWN;
136
      return true;
137
    }
138
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
139
    /* Skip \r and \n for next time. */
140
    cin.ignore(2, '\n');
141
971.6.9 by Eric Day
Added console plugin.
142
    (*packet)[0]= COM_QUERY;
143
    return true;
144
  }
145
146
  virtual void sendOK(void)
147
  {
148
    cout << "OK" << endl;
149
  }
150
151
  virtual void sendEOF(void)
152
  {
153
    printDebug("sendEOF");
154
  }
155
156
  virtual void sendError(uint32_t sql_errno, const char *err)
157
  {
158
    cout << "Error: " << sql_errno << " " << err << endl;
159
  }
160
161
  virtual bool sendFields(List<Item> *list)
162
  {
163
    List_iterator_fast<Item> it(*list);
164
    Item *item;
165
166
    column= 0;
167
    max_column= 0;
168
169
    while ((item=it++))
170
    {
171
      SendField field;
172
      item->make_field(&field);
173
      cout << field.col_name << "\t";
174
      max_column++;
175
    }
176
177
    cout << endl;
178
179
    return false;
180
  }
181
182
  virtual void checkRowEnd(void)
183
  {
184
    if (++column % max_column == 0)
185
      cout << endl;
186
  }
187
188
  using Client::store;
189
190
  virtual bool store(Field *from)
191
  {
192
    if (from->is_null())
193
      return store();
194
195
    char buff[MAX_FIELD_WIDTH];
196
    String str(buff, sizeof(buff), &my_charset_bin);
197
    from->val_str(&str);
198
    return store(str.ptr(), str.length());
199
  }
200
201
  virtual bool store(void)
202
  {
203
    cout << "NULL" << "\t";
204
    checkRowEnd();
205
    return false;
206
  }
207
208
  virtual bool store(int32_t from)
209
  {
210
    cout << from << "\t";
211
    checkRowEnd();
212
    return false;
213
  }
214
215
  virtual bool store(uint32_t from)
216
  {
217
    cout << from << "\t";
218
    checkRowEnd();
219
    return false;
220
  }
221
222
  virtual bool store(int64_t from)
223
  {
224
    cout << from << "\t";
225
    checkRowEnd();
226
    return false;
227
  }
228
229
  virtual bool store(uint64_t from)
230
  {
231
    cout << from << "\t";
232
    checkRowEnd();
233
    return false;
234
  }
235
236
  virtual bool store(double from, uint32_t decimals, String *buffer)
237
  {
238
    buffer->set_real(from, decimals, &my_charset_bin);
239
    return store(buffer->ptr(), buffer->length());
240
  }
241
242
  virtual bool store(const char *from, size_t length)
243
  {
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
244
    cout.write(from, length);
245
    cout << "\t";
971.6.9 by Eric Day
Added console plugin.
246
    checkRowEnd();
247
    return false;
248
  }
249
250
  virtual bool haveMoreData(void)
251
  {
252
    printDebug("haveMoreData");
253
    return false;
254
  }
255
256
  virtual bool haveError(void)
257
  {
258
    printDebug("haveError");
259
    return false;
260
  }
261
262
  virtual bool wasAborted(void)
263
  {
264
    printDebug("wasAborted");
265
    return false;
266
  }
267
};
268
269
class ListenConsole: public plugin::Listen
270
{
271
  int pipe_fds[2];
272
273
public:
1626.2.4 by Monty Taylor
Replaced terrible casting with strdup+free.
274
  ListenConsole(const std::string &name_arg) :
275
    plugin::Listen(name_arg)
971.6.9 by Eric Day
Added console plugin.
276
  {
277
    pipe_fds[0]= -1;
278
  }
279
280
  virtual ~ListenConsole()
281
  {
282
    if (pipe_fds[0] != -1)
283
    {
284
      close(pipe_fds[0]);
285
      close(pipe_fds[1]);
286
    }
1626.2.4 by Monty Taylor
Replaced terrible casting with strdup+free.
287
288
    /* Cleanup from the module strdup'ing these below */
289
    free(username);
290
    free(password);
291
    free(db);
971.6.9 by Eric Day
Added console plugin.
292
  }
293
294
  virtual bool getFileDescriptors(std::vector<int> &fds)
295
  {
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
296
    if (debug_enabled)
297
      enabled= true;
971.6.9 by Eric Day
Added console plugin.
298
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
299
    if (enabled == false)
971.6.9 by Eric Day
Added console plugin.
300
      return false;
301
302
    if (pipe(pipe_fds) == -1)
303
    {
304
      errmsg_printf(ERRMSG_LVL_ERROR, _("pipe() failed with errno %d"), errno);
305
      return true;
306
    }
307
308
    fds.push_back(pipe_fds[0]);
309
    assert(write(pipe_fds[1], "\0", 1) == 1);
310
    return false;
311
  }
312
313
  virtual drizzled::plugin::Client *getClient(int fd)
314
  {
315
    char buffer[1];
316
    assert(read(fd, buffer, 1) == 1);
317
    return new ClientConsole;
318
  }
319
};
320
1530.2.6 by Monty Taylor
Moved plugin::Context to module::Context.
321
static int init(drizzled::module::Context &context)
971.6.9 by Eric Day
Added console plugin.
322
{
1626.2.1 by Monty Taylor
Added wrapper around variables_map to allow us to pull values back out of
323
  const module::option_map &vm= context.getOptions();
1626.2.4 by Monty Taylor
Replaced terrible casting with strdup+free.
324
  /* duplicating these here means they need to be freed. They're global, so
325
     we'll just have the ListenConsole object do it in its destructor */
1626.2.2 by Monty Taylor
Moved ownership of the variable_map to the module (avoids copying, also
326
  if (vm.count("username"))
1626.2.4 by Monty Taylor
Replaced terrible casting with strdup+free.
327
    username= strdup(vm["username"].as<string>().c_str());
328
  else
329
    username= strdup("");
330
1626.2.2 by Monty Taylor
Moved ownership of the variable_map to the module (avoids copying, also
331
  if (vm.count("password"))
1626.2.4 by Monty Taylor
Replaced terrible casting with strdup+free.
332
    password= strdup(vm["password"].as<string>().c_str());
333
  else
334
    password= strdup("");
335
1626.2.2 by Monty Taylor
Moved ownership of the variable_map to the module (avoids copying, also
336
  if (vm.count("db"))
1626.2.4 by Monty Taylor
Replaced terrible casting with strdup+free.
337
    db= strdup(vm["db"].as<string>().c_str());
338
  else
339
    db= strdup("");
1626.2.1 by Monty Taylor
Added wrapper around variables_map to allow us to pull values back out of
340
1626.2.4 by Monty Taylor
Replaced terrible casting with strdup+free.
341
  context.add(new ListenConsole("console"));
971.6.9 by Eric Day
Added console plugin.
342
  return 0;
343
}
344
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
345
static DRIZZLE_SYSVAR_BOOL(enable, enabled, PLUGIN_VAR_NOCMDARG,
971.6.9 by Eric Day
Added console plugin.
346
                           N_("Enable the console."), NULL, NULL, false);
971.7.1 by Eric Day
Client/Listen cleanup, moved globals, console plugin cleanup.
347
static DRIZZLE_SYSVAR_BOOL(debug, debug_enabled, PLUGIN_VAR_NOCMDARG,
971.6.9 by Eric Day
Added console plugin.
348
                           N_("Turn on extra debugging."), NULL, NULL, false);
1625.1.8 by Monty Taylor
Converted really simple options in console plugin.
349
1626.2.2 by Monty Taylor
Moved ownership of the variable_map to the module (avoids copying, also
350
static DRIZZLE_SYSVAR_STR(username, username, PLUGIN_VAR_READONLY,
1305.1.2 by Eric Day
Added command line options to console to pass username, password, and db name during authentication step.
351
                          N_("User to use for auth."), NULL, NULL, NULL);
352
static DRIZZLE_SYSVAR_STR(password, password, PLUGIN_VAR_READONLY,
353
                          N_("Password to use for auth."), NULL, NULL, NULL);
354
static DRIZZLE_SYSVAR_STR(db, db, PLUGIN_VAR_READONLY,
355
                          N_("Default database to use."), NULL, NULL, NULL);
971.6.9 by Eric Day
Added console plugin.
356
1625.1.8 by Monty Taylor
Converted really simple options in console plugin.
357
static void init_options(drizzled::module::option_context &context)
358
{
359
  context("enable",
360
          po::value<bool>(&enabled)->default_value(false)->zero_tokens(),
361
          N_("Enable the console."));
362
  context("debug",
363
          po::value<bool>(&debug_enabled)->default_value(false)->zero_tokens(),
364
          N_("Turn on extra debugging."));
1626.2.2 by Monty Taylor
Moved ownership of the variable_map to the module (avoids copying, also
365
  context("username",
1626.2.1 by Monty Taylor
Added wrapper around variables_map to allow us to pull values back out of
366
          po::value<string>(),
367
          N_("User to use for auth."));
368
  context("password",
369
          po::value<string>(),
370
          N_("Password to use for auth."));
371
  context("db",
372
          po::value<string>(),
373
          N_("Default database to use."));
1625.1.8 by Monty Taylor
Converted really simple options in console plugin.
374
}
375
1228.1.5 by Monty Taylor
Merged in some naming things.
376
static drizzle_sys_var* vars[]= {
971.6.9 by Eric Day
Added console plugin.
377
  DRIZZLE_SYSVAR(enable),
378
  DRIZZLE_SYSVAR(debug),
1626.2.2 by Monty Taylor
Moved ownership of the variable_map to the module (avoids copying, also
379
  DRIZZLE_SYSVAR(username),
1305.1.2 by Eric Day
Added command line options to console to pass username, password, and db name during authentication step.
380
  DRIZZLE_SYSVAR(password),
381
  DRIZZLE_SYSVAR(db),
971.6.9 by Eric Day
Added console plugin.
382
  NULL
383
};
384
1228.1.5 by Monty Taylor
Merged in some naming things.
385
DRIZZLE_DECLARE_PLUGIN
971.6.9 by Eric Day
Added console plugin.
386
{
1241.10.2 by Monty Taylor
Added support for embedding the drizzle version number in the plugin file.
387
  DRIZZLE_VERSION_ID,
971.6.9 by Eric Day
Added console plugin.
388
  "console",
389
  "0.1",
390
  "Eric Day",
391
  "Console Client",
392
  PLUGIN_LICENSE_BSD,
393
  init,   /* Plugin Init */
394
  vars,   /* system variables */
1625.1.8 by Monty Taylor
Converted really simple options in console plugin.
395
  init_options    /* config options */
971.6.9 by Eric Day
Added console plugin.
396
}
1228.1.5 by Monty Taylor
Merged in some naming things.
397
DRIZZLE_DECLARE_PLUGIN_END;