~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/console/console.cc

  • Committer: Eric Herman
  • Date: 2008-12-07 15:29:44 UTC
  • mto: (656.1.14 devel)
  • mto: This revision was merged to the branch mainline in revision 670.
  • Revision ID: eric@mysql.com-20081207152944-cq1nx1cyi0huqj0f
Added pointer to online version of the FAQ

Show diffs side-by-side

added added

removed removed

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