~drizzle-trunk/drizzle/development

1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2010 Andrew Hutchings
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
19
20
#include "drizzledump_data.h"
21
#include "client_priv.h"
22
#include <drizzled/gettext.h>
23
#include <string>
24
#include <iostream>
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
25
#include <boost/regex.hpp>
1751.4.24 by Andrew Hutchings
Fix ignore tables
26
#include <boost/unordered_set.hpp>
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
27
1751.4.25 by Andrew Hutchings
Fix error handling
28
#define EX_DRIZZLEERR 2
29
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
30
extern bool opt_no_create_info;
31
extern bool opt_no_data;
32
extern bool opt_create_db;
33
extern bool opt_disable_keys;
34
extern bool extended_insert;
35
extern bool opt_replace_into;
1751.4.25 by Andrew Hutchings
Fix error handling
36
extern bool opt_drop;
37
extern bool verbose;
38
extern bool opt_databases;
39
extern bool opt_alldbs;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
40
extern uint32_t show_progress_size;
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
41
extern bool opt_ignore;
1799.7.2 by Andrew Hutchings
Clean up some drizzledump options
42
extern bool opt_compress;
43
extern bool opt_drop_database;
44
extern bool opt_autocommit;
1799.7.4 by Andrew Hutchings
Fix up some more options and the docs
45
extern bool ignore_errors;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
46
1751.4.24 by Andrew Hutchings
Fix ignore tables
47
extern boost::unordered_set<std::string> ignore_table;
1751.4.25 by Andrew Hutchings
Fix error handling
48
extern void maybe_exit(int error);
1751.4.24 by Andrew Hutchings
Fix ignore tables
49
1751.4.23 by Andrew Hutchings
Fix various bugs
50
enum destinations {
51
  DESTINATION_DB,
52
  DESTINATION_FILES,
53
  DESTINATION_STDOUT
54
};
55
56
extern int opt_destination;
57
1751.4.24 by Andrew Hutchings
Fix ignore tables
58
/* returns true on keep, false on ignore */
59
bool DrizzleDumpDatabase::ignoreTable(std::string tableName)
60
{
61
  std::string dbTable(databaseName);
62
  dbTable.append(".");
63
  dbTable.append(tableName);
64
65
  boost::unordered_set<std::string>::iterator iter= ignore_table.find(dbTable);
66
  return (iter == ignore_table.end());
67
}
68
1751.4.25 by Andrew Hutchings
Fix error handling
69
void DrizzleDumpDatabase::cleanTableName(std::string &tableName)
70
{
71
  std::string replace("``");
72
  std::string find("`");
73
  size_t j = 0;
74
  for (;(j = tableName.find(find, j)) != std::string::npos;)
75
  {
76
    tableName.replace(j, find.length(), replace);
77
    j+= replace.length();
78
  }
79
80
}
81
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
82
std::ostream& operator <<(std::ostream &os, const DrizzleDumpIndex &obj)
83
{
84
  if (obj.isPrimary)
85
  {
86
    os << "  PRIMARY KEY ";
87
  }
88
  else if (obj.isUnique)
89
  {
90
    os << "  UNIQUE KEY `" << obj.indexName << "` ";
91
  }
92
  else
93
  {
94
    os << "  KEY `" << obj.indexName << "` ";
95
  }
96
97
  os << "(";
98
  
99
  std::vector<std::string>::iterator i;
100
  std::vector<std::string> fields = obj.columns;
101
  for (i= fields.begin(); i != fields.end(); ++i)
102
  {
103
    if (i != fields.begin())
104
      os << ",";
105
    std::string field= *i;
106
    os << "`" << field << "`";
1802.2.1 by Andrew Hutchings
Fix index lengths not shown for part-indexed columns.
107
    if (obj.length > 0)
108
      os << "(" << obj.length << ")";
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
109
  }
110
111
  os << ")";
112
113
  return os;
114
}
115
116
std::ostream& operator <<(std::ostream &os, const DrizzleDumpField &obj)
117
{
118
  os << "  `" << obj.fieldName << "` ";
119
  os << obj.type;
120
  if (((obj.type.compare("VARCHAR") == 0) or
121
   (obj.type.compare("VARBINARY") == 0)) and
122
   (obj.length > 0))
123
  {
124
    os << "(" << obj.length << ")";
125
  }
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
126
  else if (((obj.type.compare("DECIMAL") == 0) or
127
    (obj.type.compare("DOUBLE") == 0)) and
128
    ((obj.decimalPrecision + obj.decimalScale) > 0))
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
129
  {
130
    os << "(" << obj.decimalPrecision << "," << obj.decimalScale << ")";
131
  }
132
  else if (obj.type.compare("ENUM") == 0)
133
  {
134
    os << "(" << obj.enumValues << ")";
135
  }
136
137
  if (not obj.isNull)
138
  {
139
    os << " NOT NULL";
140
  }
141
142
  if ((not obj.collation.empty()) and (obj.collation.compare("binary") != 0))
143
  {
144
    os << " COLLATE " << obj.collation;
145
  }
146
147
  if (obj.isAutoIncrement)
148
    os << " AUTO_INCREMENT";
149
150
  if (not obj.defaultValue.empty())
151
  {
152
    if (obj.defaultValue.compare("CURRENT_TIMESTAMP") != 0)
153
     os << " DEFAULT '" << obj.defaultValue << "'";
154
    else
155
     os << " DEFAULT CURRENT_TIMESTAMP";
156
  }
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
157
  else if ((obj.defaultIsNull))
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
158
  {
159
    os << " DEFAULT NULL";
160
  }
161
162
  return os;
163
}
164
165
std::ostream& operator <<(std::ostream &os, const DrizzleDumpDatabase &obj)
166
{
1751.4.23 by Andrew Hutchings
Fix various bugs
167
  if ((opt_destination == DESTINATION_DB) or opt_databases or opt_alldbs)
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
168
  {
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
169
    if (verbose)
170
    {
171
      std::cerr << "--" << std::endl
172
        << "-- Current Database: `" << obj.databaseName << "`" << std::endl
173
        << "--" << std::endl << std::endl;
174
    }
1751.4.23 by Andrew Hutchings
Fix various bugs
175
176
    /* Love that this variable is the opposite of its name */
177
    if (not opt_create_db)
178
    {
1799.7.2 by Andrew Hutchings
Clean up some drizzledump options
179
      if (opt_drop_database)
180
        os << "DROP DATABASE IF EXISTS `" << obj.databaseName << "`" << std::endl;
181
1751.4.23 by Andrew Hutchings
Fix various bugs
182
      os << "CREATE DATABASE IF NOT EXISTS `" << obj.databaseName << "`";
183
      if (not obj.collate.empty())
184
       os << " COLLATE = " << obj.collate;
185
186
      os << ";" << std::endl << std::endl;
187
    }
188
189
    os << "USE `" << obj.databaseName << "`;" << std::endl << std::endl;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
190
  }
191
192
  std::vector<DrizzleDumpTable*>::iterator i;
193
  std::vector<DrizzleDumpTable*> output_tables = obj.tables;
194
  for (i= output_tables.begin(); i != output_tables.end(); ++i)
195
  {
196
    DrizzleDumpTable *table= *i;
197
    if (not opt_no_create_info)
198
      os << *table;
199
    if (not opt_no_data)
200
    {
1751.4.21 by Andrew Hutchings
Add database destination settings and connect it all up
201
      obj.dcon->setDB(obj.databaseName);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
202
      DrizzleDumpData *data= table->getData();
1751.4.25 by Andrew Hutchings
Fix error handling
203
      if (data == NULL)
204
      {
205
        std::cerr << "Error: Could not get data for table " << table->displayName << std::endl;
1799.7.4 by Andrew Hutchings
Fix up some more options and the docs
206
        if (not ignore_errors)
207
          maybe_exit(EX_DRIZZLEERR);
208
        else
209
          continue;
1751.4.25 by Andrew Hutchings
Fix error handling
210
      }
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
211
      os << *data;
212
      delete data;
213
    }
214
  }
215
216
  return os;
217
}
218
219
220
std::ostream& operator <<(std::ostream &os, const DrizzleDumpData &obj)
221
{
222
  bool new_insert= true;
223
  bool first= true;
224
  uint64_t rownr= 0;
225
226
  drizzle_row_t row;
227
1751.4.23 by Andrew Hutchings
Fix various bugs
228
  if (verbose)
1751.4.25 by Andrew Hutchings
Fix error handling
229
    std::cerr << _("-- Retrieving data for ") << obj.table->displayName << "..." << std::endl;
1751.4.23 by Andrew Hutchings
Fix various bugs
230
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
231
  if (drizzle_result_row_count(obj.result) < 1)
232
  {
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
233
    if (verbose)
234
    {
235
      std::cerr << "--" << std::endl
236
        << "-- No data to dump for table `" << obj.table->displayName << "`"
237
        << std::endl << "--" << std::endl << std::endl;
238
    }
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
239
    return os;
240
  }
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
241
  else if (verbose)
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
242
  {
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
243
    std::cerr << "--" << std::endl
244
      << "-- Dumping data for table `" << obj.table->displayName << "`"
245
      << std::endl << "--" << std::endl << std::endl;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
246
  }
247
  if (opt_disable_keys)
1751.4.25 by Andrew Hutchings
Fix error handling
248
    os << "ALTER TABLE `" << obj.table->displayName << "` DISABLE KEYS;" << std::endl;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
249
1799.7.2 by Andrew Hutchings
Clean up some drizzledump options
250
  /* Another option that does the opposite of its name, makes me sad :( */
251
  if (opt_autocommit)
252
    os << "START TRANSACTION;" << std::endl;
253
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
254
  std::streampos out_position= os.tellp();
255
256
  while((row= drizzle_row_next(obj.result)))
257
  {
258
    rownr++;
259
    if ((rownr % show_progress_size) == 0)
260
    {
1802.11.1 by Andrew Hutchings
1. date regex was broken
261
      std::cerr << "-- " << rownr << _(" rows dumped for table ") << obj.table->displayName << std::endl;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
262
    }
263
264
    size_t* row_sizes= drizzle_row_field_sizes(obj.result);
265
    if (not first)
266
    {
267
      if (extended_insert)
268
        os << "),(";
269
      else
270
        os << ");" << std::endl;
271
    }
272
    else
273
      first= false;
274
275
    if (new_insert)
276
    {
277
      if (opt_replace_into)
278
        os << "REPLACE ";
279
      else
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
280
      {
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
281
        os << "INSERT ";
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
282
        if (opt_ignore)
283
          os << "IGNORE ";
284
      }
1751.4.25 by Andrew Hutchings
Fix error handling
285
      os << "INTO `" << obj.table->displayName << "` VALUES (";
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
286
      if (extended_insert)
287
        new_insert= false;
288
    }
289
    for (uint32_t i= 0; i < drizzle_result_column_count(obj.result); i++)
290
    {
291
      if (not row[i])
292
      {
293
        os << "NULL";
294
      }
295
      /* time/date conversion for MySQL connections */
296
      else if (obj.table->fields[i]->convertDateTime)
297
      {
1802.11.1 by Andrew Hutchings
1. date regex was broken
298
        os << obj.checkDateTime(row[i], i);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
299
      }
300
      else
301
      {
302
        if (obj.table->fields[i]->type.compare("INT") != 0)
303
        {
304
          /* Hex blob processing or escape text */
305
          if (((obj.table->fields[i]->type.compare("BLOB") == 0) or
306
            (obj.table->fields[i]->type.compare("VARBINARY") == 0)))
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
307
            os << obj.convertHex((unsigned char*)row[i], row_sizes[i]);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
308
          else
1810.1.1 by Andrew Hutchings
Add table comments
309
            os << "'" << DrizzleDumpData::escape(row[i], row_sizes[i]) << "'";
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
310
        }
311
        else
312
          os << row[i];
313
      }
314
      if (i != obj.table->fields.size() - 1)
315
        os << ",";
316
    }
317
    /* Break insert up if it is too long */
318
    if (extended_insert and
319
      ((os.tellp() - out_position) >= DRIZZLE_MAX_LINE_LENGTH))
320
    {
321
      os << ");" << std::endl;
322
      new_insert= true;
323
      out_position= os.tellp();
324
    }
325
  }
326
  os << ");" << std::endl;
327
1799.7.2 by Andrew Hutchings
Clean up some drizzledump options
328
  if (opt_autocommit)
329
    os << "COMMIT;" << std::endl;
330
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
331
  if (opt_disable_keys)
332
    os << "ALTER TABLE `" << obj.table->tableName << "` ENABLE KEYS;" << std::endl;
333
334
  os << std::endl;
335
336
  return os;
337
}
338
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
339
std::string DrizzleDumpData::convertHex(const unsigned char* from, size_t from_size) const
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
340
{
341
  std::ostringstream output;
342
  if (from_size > 0)
343
    output << "0x";
344
  while (from_size > 0)
345
  {
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
346
    /* Would be nice if std::hex liked uint8_t, ah well */
347
    output << std::uppercase << std::hex << std::setw(2) << std::setfill('0') << (unsigned short)(*from);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
348
    *from++;
349
    from_size--;
350
  }
351
352
  return output.str();
353
}
354
355
/* Ripped out of libdrizzle, hopefully a little safer */
1810.1.1 by Andrew Hutchings
Add table comments
356
std::string DrizzleDumpData::escape(const char* from, size_t from_size)
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
357
{
358
  std::string output;
359
360
  while (from_size > 0)
361
  {
362
    if (!(*from & 0x80))
363
    {
364
      switch (*from)
365
      {
366
         case 0:
367
         case '\n':
368
         case '\r':
369
         case '\\':
370
         case '\'':
371
         case '"':
372
         case '\032':
373
           output.push_back('\\');
374
         default:
375
           break;
376
       }
377
    }
378
    output.push_back(*from);
379
    *from++;
380
    from_size--;
381
  }
382
383
  return output;
384
}
385
386
std::ostream& operator <<(std::ostream &os, const DrizzleDumpTable &obj)
387
{
1751.4.26 by Andrew Hutchings
Fix up for the drizzledump test cases
388
  if (verbose)
389
  {
390
    std::cerr << "--" << std::endl
391
      << "-- Table structure for table `" << obj.displayName << "`" << std::endl
392
      << "--" << std::endl << std::endl;
393
  }
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
394
395
  if (opt_drop)
1751.4.25 by Andrew Hutchings
Fix error handling
396
    os << "DROP TABLE IF EXISTS `" << obj.displayName <<  "`;" << std::endl;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
397
1751.4.25 by Andrew Hutchings
Fix error handling
398
  os << "CREATE TABLE `" << obj.displayName << "` (" << std::endl;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
399
  std::vector<DrizzleDumpField*>::iterator i;
400
  std::vector<DrizzleDumpField*> output_fields = obj.fields;
401
  for (i= output_fields.begin(); i != output_fields.end(); ++i)
402
  {
403
    if (i != output_fields.begin())
404
      os << "," << std::endl;
405
    DrizzleDumpField *field= *i;
406
    os << *field;
407
  }
408
409
  std::vector<DrizzleDumpIndex*>::iterator j;
410
  std::vector<DrizzleDumpIndex*> output_indexes = obj.indexes;
411
  for (j= output_indexes.begin(); j != output_indexes.end(); ++j)
412
  {
413
    os << "," << std::endl;;
414
    DrizzleDumpIndex *index= *j;
415
    os << *index;
416
  }
417
  os << std::endl;
418
  os << ") ENGINE=" << obj.engineName << " ";
1802.5.1 by Andrew Hutchings
Adds auto_increment to data_dictionary.tables and drizzledump (when connecting to a Drizzle server)
419
  if (obj.autoIncrement > 0)
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
420
  {
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
421
    os << "AUTO_INCREMENT=" << obj.autoIncrement << " ";
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
422
  }
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
423
1810.1.1 by Andrew Hutchings
Add table comments
424
  os << "COLLATE = " << obj.collate;
425
426
  if (not obj.comment.empty())
427
  {
428
    os << " COMMENT = '" << obj.comment << "'";
429
  }
430
431
  os << ";" << std::endl << std::endl;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
432
433
  return os;
434
}
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
435
436
DrizzleDumpConnection::DrizzleDumpConnection(std::string &host, uint16_t port, 
437
  std::string &username, std::string &password, bool drizzle_protocol) :
438
  hostName(host),
439
  drizzleProtocol(drizzle_protocol)
440
{
441
  drizzle_return_t ret;
442
443
  if (host.empty())
444
    host= "localhost";
445
446
  std::string protocol= (drizzle_protocol) ? "Drizzle" : "MySQL";
1751.4.23 by Andrew Hutchings
Fix various bugs
447
  if (verbose)
448
  {
449
    std::cerr << _("-- Connecting to ") << host  << _(" using protocol ")
450
      << protocol << "..." << std::endl;
451
  }
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
452
  drizzle_create(&drizzle);
453
  drizzle_con_create(&drizzle, &connection);
454
  drizzle_con_set_tcp(&connection, (char *)host.c_str(), port);
455
  drizzle_con_set_auth(&connection, (char *)username.c_str(),
456
    (char *)password.c_str());
457
  drizzle_con_add_options(&connection, 
458
    drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
459
  ret= drizzle_con_connect(&connection);
460
  if (ret != DRIZZLE_RETURN_OK)
461
  {
462
    errorHandler(NULL, ret, "when trying to connect");
1802.6.1 by Andrew Hutchings
Add better error handling and exception handling for database connect
463
    throw 1;
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
464
  }
465
466
  boost::match_flag_type flags = boost::match_default; 
467
468
  boost::regex mysql_regex("(5\\.[0-9]+\\.[0-9]+)");
469
  boost::regex drizzle_regex("(20[0-9]{2}\\.(0[1-9]|1[012])\\.[0-9]+)");
470
471
  std::string version(getServerVersion());
472
473
  if (regex_search(version, mysql_regex, flags))
474
    serverType= SERVER_MYSQL_FOUND;
1751.4.21 by Andrew Hutchings
Add database destination settings and connect it all up
475
  else if (regex_search(version, drizzle_regex, flags))
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
476
    serverType= SERVER_DRIZZLE_FOUND;
1751.4.21 by Andrew Hutchings
Add database destination settings and connect it all up
477
  else
478
    serverType= SERVER_UNKNOWN_FOUND;
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
479
}
480
481
drizzle_result_st* DrizzleDumpConnection::query(std::string &str_query)
482
{
483
  drizzle_return_t ret;
484
  drizzle_result_st* result= new drizzle_result_st;
485
  if (drizzle_query_str(&connection, result, str_query.c_str(), &ret) == NULL ||
486
      ret != DRIZZLE_RETURN_OK)
487
  {
488
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
489
    {
490
      std::cerr << _("Error executing query: ") <<
1751.4.23 by Andrew Hutchings
Fix various bugs
491
        drizzle_result_error(result) << std::endl;
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
492
      drizzle_result_free(result);
493
    }
494
    else
495
    {
496
      std::cerr << _("Error executing query: ") <<
1751.4.23 by Andrew Hutchings
Fix various bugs
497
        drizzle_con_error(&connection) << std::endl;
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
498
    }
499
    return NULL;
500
  }
501
502
  if (drizzle_result_buffer(result) != DRIZZLE_RETURN_OK)
503
  {
504
    std::cerr << _("Could not buffer result: ") <<
1751.4.23 by Andrew Hutchings
Fix various bugs
505
        drizzle_con_error(&connection) << std::endl;
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
506
    return NULL;
507
  }
508
  return result;
509
}
510
511
void DrizzleDumpConnection::freeResult(drizzle_result_st* result)
512
{
513
  drizzle_result_free(result);
514
  delete result;
515
}
516
517
bool DrizzleDumpConnection::queryNoResult(std::string &str_query)
518
{
519
  drizzle_return_t ret;
520
  drizzle_result_st result;
521
522
  if (drizzle_query_str(&connection, &result, str_query.c_str(), &ret) == NULL ||
523
      ret != DRIZZLE_RETURN_OK)
524
  {
525
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
526
    {
527
      std::cerr << _("Error executing query: ") <<
1751.4.23 by Andrew Hutchings
Fix various bugs
528
        drizzle_result_error(&result) << std::endl;
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
529
      drizzle_result_free(&result);
530
    }
531
    else
532
    {
533
      std::cerr << _("Error executing query: ") <<
1751.4.23 by Andrew Hutchings
Fix various bugs
534
        drizzle_con_error(&connection) << std::endl;
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
535
    }
536
    return false;
537
  }
538
539
  drizzle_result_free(&result);
540
  return true;
541
}
542
543
bool DrizzleDumpConnection::setDB(std::string databaseName)
544
{
545
  drizzle_return_t ret;
546
  drizzle_result_st result;
547
  if (drizzle_select_db(&connection, &result, databaseName.c_str(), &ret) == 
548
    NULL || ret != DRIZZLE_RETURN_OK)
549
  {
1751.4.25 by Andrew Hutchings
Fix error handling
550
    std::cerr << _("Error: Could not set db '") << databaseName << "'" << std::endl;
551
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
552
      drizzle_result_free(&result);
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
553
    return false;
554
  }
555
  drizzle_result_free(&result);
556
  return true;
557
}
558
1799.7.2 by Andrew Hutchings
Clean up some drizzledump options
559
void DrizzleDumpConnection::errorHandler(drizzle_result_st *res,
560
  drizzle_return_t ret, const char *when)
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
561
{
1802.6.1 by Andrew Hutchings
Add better error handling and exception handling for database connect
562
  if (res == NULL)
563
  {
564
    std::cerr << _("Got error: ") << drizzle_con_error(&connection) << " "
565
      << when << std::endl;
566
  }
567
  else if (ret == DRIZZLE_RETURN_ERROR_CODE)
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
568
  {
569
    std::cerr << _("Got error: ") << drizzle_result_error(res)
570
      << " (" << drizzle_result_error_code(res) << ") " << when << std::endl;
571
    drizzle_result_free(res);
572
  }
573
  else
574
  {
575
    std::cerr << _("Got error: ") << ret << " " << when << std::endl;
576
  }
577
578
  return;
579
}
580
581
DrizzleDumpConnection::~DrizzleDumpConnection()
582
{
1751.4.23 by Andrew Hutchings
Fix various bugs
583
  if (verbose)
584
    std::cerr << _("-- Disconnecting from ") << hostName << "..." << std::endl;
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
585
  drizzle_con_free(&connection);
586
  drizzle_free(&drizzle);
587
}