~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzletest.cc

  • Committer: Mark Atwood
  • Date: 2011-06-18 01:53:35 UTC
  • mfrom: (2318.5.40 refactor11)
  • Revision ID: me@mark.atwood.name-20110618015335-nxum0ocvpkljgf67
mergeĀ lp:~olafvdspek/drizzle/refactor11

Show diffs side-by-side

added added

removed removed

Lines of Context:
230
230
typedef boost::unordered_map<string, VAR *> var_hash_t;
231
231
var_hash_t var_hash;
232
232
 
233
 
struct st_connection
 
233
class st_connection
234
234
{
235
 
  drizzle_st* drizzle;
236
 
  drizzle_con_st con;
237
 
  char* name;
 
235
public:
 
236
  st_connection() : con(drizzle)
 
237
  {
 
238
    drizzle_con_add_options(*this, use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
 
239
  }
 
240
 
 
241
  operator drizzle::connection_c&()
 
242
  {
 
243
    return con;
 
244
  }
 
245
 
 
246
  operator drizzle_con_st*()
 
247
  {
 
248
    return &con.b_;
 
249
  }
 
250
 
 
251
  drizzle::drizzle_c drizzle;
 
252
  drizzle::connection_c con;
238
253
};
239
 
st_connection g_connections[128];
240
 
st_connection* cur_con= NULL, *next_con;
 
254
 
 
255
typedef map<string, st_connection*> connections_t;
 
256
connections_t g_connections;
 
257
st_connection* cur_con= NULL;
241
258
 
242
259
/*
243
260
  List of commands in drizzletest
465
482
/* For replace_column */
466
483
static char *replace_column[MAX_COLUMNS];
467
484
static uint32_t max_replace_column= 0;
468
 
void do_get_replace_column(struct st_command*);
 
485
void do_get_replace_column(st_command*);
469
486
void free_replace_column();
470
487
 
471
488
/* For replace */
475
492
/* For replace_regex */
476
493
void do_get_replace_regex(st_command* command);
477
494
 
478
 
void replace_append_mem(string *ds, const char *val,
479
 
                        int len);
 
495
void replace_append_mem(string& ds, const char *val, int len);
480
496
void replace_append(string *ds, const char *val);
481
497
void replace_append_uint(string *ds, uint32_t val);
482
 
void append_sorted(string* ds, string* ds_input);
 
498
void append_sorted(string& ds, const string& ds_input);
483
499
 
484
 
void handle_error(struct st_command*,
 
500
void handle_error(st_command*,
485
501
                  unsigned int err_errno, const char *err_error,
486
502
                  const char *err_sqlstate, string *ds);
487
 
void handle_no_error(struct st_command*);
 
503
void handle_no_error(st_command*);
488
504
 
489
505
 
490
506
void do_eval(string *query_eval, const char *query,
492
508
{
493
509
  char c, next_c;
494
510
  int escaped = 0;
495
 
  VAR *v;
496
511
 
497
512
  for (const char *p= query; (c= *p) && p < query_end; ++p)
498
513
  {
499
 
    switch(c) {
 
514
    switch(c) 
 
515
    {
500
516
    case '$':
501
517
      if (escaped)
502
518
      {
505
521
      }
506
522
      else
507
523
      {
508
 
        if (!(v= var_get(p, &p, 0, 0)))
 
524
        VAR* v= var_get(p, &p, 0, 0);
 
525
        if (not v)
509
526
          die("Bad variable in eval");
510
527
        query_eval->append(v->str_val, v->str_val_len);
511
528
      }
534
551
    default:
535
552
      escaped= 0;
536
553
      query_eval->append(p, 1);
537
 
      break;
538
554
    }
539
555
  }
540
 
  return;
541
556
}
542
557
 
543
558
 
570
585
    const char *next_pos= cur_pos;
571
586
 
572
587
    /* Search for quote in each string and replace with escaped quote */
573
 
    while((next_pos= strrchr(cur_pos, quote_str[0])) != NULL)
 
588
    while ((next_pos= strrchr(cur_pos, quote_str[0])) != NULL)
574
589
    {
575
590
      str->append(cur_pos, next_pos - cur_pos);
576
591
      str->append("\\", 1);
598
613
 
599
614
*/
600
615
 
601
 
static void show_query(drizzle_con_st *con, const char* query)
 
616
static int dt_query_log(drizzle::connection_c& con, drizzle::result_c& res, const std::string& query)
602
617
{
603
 
  drizzle_result_st res;
604
 
  drizzle_return_t ret;
605
 
 
606
 
  if (!con)
607
 
    return;
608
 
 
609
 
  if (drizzle_query_str(con, &res, query, &ret) == NULL ||
610
 
      ret != DRIZZLE_RETURN_OK)
 
618
  if (drizzle_return_t ret= con.query(res, query))
611
619
  {
612
620
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
613
621
    {
614
 
      log_msg("Error running query '%s': %d %s",
615
 
              query, drizzle_result_error_code(&res),
616
 
              drizzle_result_error(&res));
617
 
      drizzle_result_free(&res);
 
622
      log_msg("Error running query '%s': %d %s", query.c_str(), res.error_code(), res.error());
618
623
    }
619
624
    else
620
625
    {
621
 
      log_msg("Error running query '%s': %d %s",
622
 
              query, ret, drizzle_con_error(con));
 
626
      log_msg("Error running query '%s': %d %s", query.c_str(), ret, con.error());
623
627
    }
624
 
    return;
625
 
  }
626
 
 
627
 
  if (drizzle_result_column_count(&res) == 0 ||
628
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
629
 
  {
630
 
    /* No result set returned */
631
 
    drizzle_result_free(&res);
632
 
    return;
633
 
  }
634
 
 
635
 
  {
636
 
    drizzle_row_t row;
637
 
    unsigned int i;
638
 
    unsigned int row_num= 0;
639
 
    unsigned int num_fields= drizzle_result_column_count(&res);
640
 
    drizzle_column_st *column;
641
 
 
642
 
    fprintf(stderr, "=== %s ===\n", query);
643
 
    while ((row= drizzle_row_next(&res)))
 
628
    return 1;
 
629
  }
 
630
  return res.column_count() == 0;
 
631
}
 
632
 
 
633
static void show_query(drizzle::connection_c& con, const char* query)
 
634
{
 
635
  drizzle::result_c res;
 
636
  if (dt_query_log(con, res, query))
 
637
    return;
 
638
 
 
639
  unsigned int row_num= 0;
 
640
  unsigned int num_fields= res.column_count();
 
641
 
 
642
  fprintf(stderr, "=== %s ===\n", query);
 
643
  while (drizzle_row_t row= res.row_next())
 
644
  {
 
645
    size_t *lengths= res.row_field_sizes();
 
646
    row_num++;
 
647
 
 
648
    fprintf(stderr, "---- %d. ----\n", row_num);
 
649
    res.column_seek(0);
 
650
    for (unsigned int i= 0; i < num_fields; i++)
644
651
    {
645
 
      size_t *lengths= drizzle_row_field_sizes(&res);
646
 
      row_num++;
647
 
 
648
 
      fprintf(stderr, "---- %d. ----\n", row_num);
649
 
      drizzle_column_seek(&res, 0);
650
 
      for(i= 0; i < num_fields; i++)
651
 
      {
652
 
        column= drizzle_column_next(&res);
653
 
        fprintf(stderr, "%s\t%.*s\n",
654
 
                drizzle_column_name(column),
655
 
                (int)lengths[i], row[i] ? row[i] : "NULL");
656
 
      }
 
652
      drizzle_column_st* column= res.column_next();
 
653
      fprintf(stderr, "%s\t%.*s\n", drizzle_column_name(column), (int)lengths[i], row[i] ? row[i] : "NULL");
657
654
    }
658
 
    for (i= 0; i < strlen(query)+8; i++)
659
 
      fprintf(stderr, "=");
660
 
    fprintf(stderr, "\n\n");
661
655
  }
662
 
  drizzle_result_free(&res);
 
656
  for (size_t i= 0; i < strlen(query)+8; i++)
 
657
    fprintf(stderr, "=");
 
658
  fprintf(stderr, "\n\n");
663
659
}
664
660
 
665
661
 
676
672
 
677
673
*/
678
674
 
679
 
static void show_warnings_before_error(drizzle_con_st *con)
 
675
static void show_warnings_before_error(drizzle::connection_c& con)
680
676
{
681
 
  drizzle_result_st res;
682
 
  drizzle_return_t ret;
683
 
  const char* query= "SHOW WARNINGS";
684
 
 
685
 
  if (!con)
686
 
    return;
687
 
 
688
 
  if (drizzle_query_str(con, &res, query, &ret) == NULL ||
689
 
      ret != DRIZZLE_RETURN_OK)
690
 
  {
691
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
692
 
    {
693
 
      log_msg("Error running query '%s': %d %s",
694
 
              query, drizzle_result_error_code(&res),
695
 
              drizzle_result_error(&res));
696
 
      drizzle_result_free(&res);
697
 
    }
698
 
    else
699
 
    {
700
 
      log_msg("Error running query '%s': %d %s",
701
 
              query, ret, drizzle_con_error(con));
702
 
    }
703
 
    return;
704
 
  }
705
 
 
706
 
  if (drizzle_result_column_count(&res) == 0 ||
707
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
708
 
  {
709
 
    /* No result set returned */
710
 
    drizzle_result_free(&res);
711
 
    return;
712
 
  }
713
 
 
714
 
  if (drizzle_result_row_count(&res) <= 1)
715
 
  {
716
 
    /* Don't display the last row, it's "last error" */
717
 
  }
718
 
  else
719
 
  {
720
 
    drizzle_row_t row;
 
677
  drizzle::result_c res;
 
678
  if (dt_query_log(con, res, "show warnings"))
 
679
    return;
 
680
 
 
681
  if (res.row_count() >= 2) /* Don't display the last row, it's "last error" */
 
682
  {
721
683
    unsigned int row_num= 0;
722
 
    unsigned int num_fields= drizzle_result_column_count(&res);
 
684
    unsigned int num_fields= res.column_count();
723
685
 
724
686
    fprintf(stderr, "\nWarnings from just before the error:\n");
725
 
    while ((row= drizzle_row_next(&res)))
 
687
    while (drizzle_row_t row= res.row_next())
726
688
    {
727
 
      uint32_t i;
728
 
      size_t *lengths= drizzle_row_field_sizes(&res);
 
689
      size_t *lengths= res.row_field_sizes();
729
690
 
730
 
      if (++row_num >= drizzle_result_row_count(&res))
 
691
      if (++row_num >= res.row_count())
731
692
      {
732
693
        /* Don't display the last row, it's "last error" */
733
694
        break;
734
695
      }
735
696
 
736
 
      for(i= 0; i < num_fields; i++)
 
697
      for (uint32_t i= 0; i < num_fields; i++)
737
698
      {
738
 
        fprintf(stderr, "%.*s ", (int)lengths[i],
739
 
                row[i] ? row[i] : "NULL");
 
699
        fprintf(stderr, "%.*s ", (int)lengths[i], row[i] ? row[i] : "NULL");
740
700
      }
741
701
      fprintf(stderr, "\n");
742
702
    }
743
703
  }
744
 
  drizzle_result_free(&res);
745
 
 
746
 
  return;
747
704
}
748
705
 
749
 
 
750
706
enum arg_type
751
707
{
752
708
  ARG_STRING,
753
709
  ARG_REST
754
710
};
755
711
 
756
 
struct command_arg {
 
712
struct command_arg 
 
713
{
757
714
  const char *argname;       /* Name of argument   */
758
715
  enum arg_type type;        /* Type of argument   */
759
716
  bool required;          /* Argument required  */
767
724
                               const struct command_arg *args,
768
725
                               int num_args, const char delimiter_arg)
769
726
{
770
 
  int i;
771
727
  const char *ptr= arguments;
772
728
  const char *start;
773
729
 
774
 
  for (i= 0; i < num_args; i++)
 
730
  for (int i= 0; i < num_args; i++)
775
731
  {
776
732
    const struct command_arg *arg= &args[i];
777
733
    arg->ds->clear();
824
780
  }
825
781
  /* Check for too many arguments passed */
826
782
  ptr= command->last_argument;
827
 
  while(ptr <= command->end)
 
783
  while (ptr <= command->end)
828
784
  {
829
785
    if (*ptr && *ptr != ' ')
830
786
      die("Extra argument '%s' passed to '%.*s'",
839
795
{
840
796
  if (error != 0)
841
797
  {
842
 
    uint32_t i;
843
 
 
844
798
    if (command->abort_on_error)
845
 
      die("command \"%.*s\" failed with error %d",
846
 
          command->first_word_len, command->query, error);
847
 
    for (i= 0; i < command->expected_errors.count; i++)
 
799
      die("command \"%.*s\" failed with error %d", command->first_word_len, command->query, error);
 
800
    for (uint32_t i= 0; i < command->expected_errors.count; i++)
848
801
    {
849
 
      if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
850
 
          (command->expected_errors.err[i].code.errnum == error))
 
802
      if (command->expected_errors.err[i].type == ERR_ERRNO &&
 
803
          command->expected_errors.err[i].code.errnum == error)
851
804
      {
852
805
        return;
853
806
      }
866
819
}
867
820
 
868
821
 
869
 
static void close_connections()
870
 
{
871
 
  for (--next_con; next_con >= g_connections; --next_con)
872
 
  {
873
 
    if (next_con->drizzle != NULL)
874
 
    {
875
 
      drizzle_free(next_con->drizzle);
876
 
      next_con->drizzle= NULL;
877
 
    }
878
 
    free(next_con->name);
879
 
  }
880
 
}
881
 
 
882
 
 
883
822
static void close_files()
884
823
{
885
824
  for (; cur_file >= file_stack.data(); cur_file--)
893
832
 
894
833
static void free_used_memory()
895
834
{
896
 
  close_connections();
897
835
  close_files();
898
836
  BOOST_FOREACH(var_hash_t::reference i, var_hash)
899
837
  {
946
884
 
947
885
void die(const char *fmt, ...)
948
886
{
949
 
  static int dying= 0;
950
 
  va_list args;
951
 
 
952
887
  /*
953
888
    Protect against dying twice
954
889
    first time 'die' is called, try to write log files
955
890
    second time, just exit
956
891
  */
 
892
  static bool dying= false;
957
893
  if (dying)
958
894
    cleanup_and_exit(1);
959
 
  dying= 1;
 
895
  dying= true;
960
896
 
961
897
  /* Print the error message */
962
898
  fprintf(stderr, "drizzletest: ");
963
899
  if (cur_file && cur_file != file_stack.data())
964
 
    fprintf(stderr, "In included file \"%s\": ",
965
 
            cur_file->file_name);
 
900
    fprintf(stderr, "In included file \"%s\": ", cur_file->file_name);
966
901
  if (start_lineno > 0)
967
902
    fprintf(stderr, "At line %u: ", start_lineno);
968
903
  if (fmt)
969
904
  {
 
905
    va_list args;
970
906
    va_start(args, fmt);
971
907
    vfprintf(stderr, fmt, args);
972
908
    va_end(args);
981
917
  {
982
918
    int tail_lines= opt_tail_lines;
983
919
    const char* show_from= ds_res.c_str() + ds_res.length() - 1;
984
 
    while(show_from > ds_res.c_str() && tail_lines > 0 )
 
920
    while (show_from > ds_res.c_str() && tail_lines > 0 )
985
921
    {
986
922
      show_from--;
987
923
      if (*show_from == '\n')
1007
943
    been produced prior to the error
1008
944
  */
1009
945
  if (cur_con)
1010
 
    show_warnings_before_error(&cur_con->con);
 
946
    show_warnings_before_error(*cur_con);
1011
947
 
1012
948
  cleanup_and_exit(1);
1013
949
}
1016
952
void abort_not_supported_test(const char *fmt, ...)
1017
953
{
1018
954
  va_list args;
1019
 
  struct st_test_file* err_file= cur_file;
 
955
  st_test_file* err_file= cur_file;
1020
956
 
1021
957
 
1022
958
  /* Print include filestack */
1048
984
 
1049
985
void verbose_msg(const char *fmt, ...)
1050
986
{
1051
 
  va_list args;
1052
 
 
1053
987
  if (!verbose)
1054
988
    return;
1055
 
 
 
989
  va_list args;
1056
990
  va_start(args, fmt);
1057
991
  fprintf(stderr, "drizzletest: ");
1058
992
  if (cur_file && cur_file != file_stack.data())
1059
 
    fprintf(stderr, "In included file \"%s\": ",
1060
 
            cur_file->file_name);
 
993
    fprintf(stderr, "In included file \"%s\": ", cur_file->file_name);
1061
994
  if (start_lineno != 0)
1062
995
    fprintf(stderr, "At line %u: ", start_lineno);
1063
996
  vfprintf(stderr, fmt, args);
1072
1005
  char buff[512];
1073
1006
  size_t len;
1074
1007
 
1075
 
 
1076
1008
  va_start(args, fmt);
1077
1009
  ds_warning_messages.append("drizzletest: ");
1078
1010
  if (start_lineno != 0)
1123
1055
 
1124
1056
*/
1125
1057
 
1126
 
static void cat_file(string* ds, const char* filename)
 
1058
static void cat_file(string& ds, const char* filename)
1127
1059
{
1128
1060
  int fd= internal::my_open(filename, O_RDONLY, MYF(0));
1129
1061
  if (fd < 0)
1130
1062
    die("Failed to open file '%s'", filename);
1131
 
  uint32_t len;
1132
1063
  char buff[512];
1133
 
 
1134
 
  while((len= internal::my_read(fd, (unsigned char*)&buff, sizeof(buff), MYF(0))) > 0)
 
1064
  while (uint32_t len= internal::my_read(fd, (unsigned char*)&buff, sizeof(buff), MYF(0)))
1135
1065
  {
1136
1066
    char *p= buff, *start= buff;
1137
1067
    while (p < buff+len)
1142
1072
        /* Add fake newline instead of cr and output the line */
1143
1073
        *p= '\n';
1144
1074
        p++; /* Step past the "fake" newline */
1145
 
        ds->append(start, p-start);
 
1075
        ds.append(start, p - start);
1146
1076
        p++; /* Step past the "fake" newline */
1147
1077
        start= p;
1148
1078
      }
1150
1080
        p++;
1151
1081
    }
1152
1082
    /* Output any chars that might be left */
1153
 
    ds->append(start, p-start);
 
1083
    ds.append(start, p - start);
1154
1084
  }
1155
1085
  internal::my_close(fd, MYF(0));
1156
1086
}
1232
1162
 
1233
1163
*/
1234
1164
 
1235
 
static void show_diff(string* ds,
1236
 
                      const char* filename1, const char* filename2)
 
1165
static void show_diff(string* ds, const char* filename1, const char* filename2)
1237
1166
{
1238
 
 
1239
1167
  string ds_tmp;
1240
1168
 
1241
1169
  /* First try with unified diff */
1274
1202
      ds_tmp.append(" --- ");
1275
1203
      ds_tmp.append(filename1);
1276
1204
      ds_tmp.append(" >>>\n");
1277
 
      cat_file(&ds_tmp, filename1);
 
1205
      cat_file(ds_tmp, filename1);
1278
1206
      ds_tmp.append("<<<\n --- ");
1279
1207
      ds_tmp.append(filename1);
1280
1208
      ds_tmp.append(" >>>\n");
1281
 
      cat_file(&ds_tmp, filename2);
 
1209
      cat_file(ds_tmp, filename2);
1282
1210
      ds_tmp.append("<<<<\n");
1283
1211
    }
1284
1212
  }
1344
1272
      die("Failed to open second file: '%s'", fname);
1345
1273
    }
1346
1274
  }
1347
 
  while((len= internal::my_read(fd, (unsigned char*)&buff,
 
1275
  while ((len= internal::my_read(fd, (unsigned char*)&buff,
1348
1276
                      sizeof(buff), MYF(0))) > 0)
1349
1277
  {
1350
1278
    if ((len2= internal::my_read(fd2, (unsigned char*)&buff2,
1416
1344
  See 'compare_files2'
1417
1345
*/
1418
1346
 
1419
 
static int string_cmp(string* ds, const char *fname)
 
1347
static int string_cmp(const string& ds, const char *fname)
1420
1348
{
1421
1349
  char temp_file_path[FN_REFLEN];
1422
1350
 
1425
1353
    die("Failed to create temporary file for ds");
1426
1354
 
1427
1355
  /* Write ds to temporary file and set file pos to beginning*/
1428
 
  if (internal::my_write(fd, (unsigned char *) ds->c_str(), ds->length(), MYF(MY_FNABP | MY_WME)) ||
 
1356
  if (internal::my_write(fd, (unsigned char *) ds.data(), ds.length(), MYF(MY_FNABP | MY_WME)) ||
1429
1357
      lseek(fd, 0, SEEK_SET) == MY_FILEPOS_ERROR)
1430
1358
  {
1431
1359
    internal::my_close(fd, MYF(0));
1456
1384
 
1457
1385
*/
1458
1386
 
1459
 
static void check_result(string* ds)
 
1387
static void check_result(string& ds)
1460
1388
{
1461
1389
  const char* mess= "Result content mismatch\n";
1462
1390
 
1490
1418
      /* Put reject file in opt_logdir */
1491
1419
      internal::fn_format(reject_file, result_file_name.c_str(), opt_logdir.c_str(), ".reject", MY_REPLACE_DIR | MY_REPLACE_EXT);
1492
1420
    }
1493
 
    str_to_file(reject_file, ds->c_str(), ds->length());
 
1421
    str_to_file(reject_file, ds.data(), ds.length());
1494
1422
 
1495
 
    ds->erase(); /* Don't create a .log file */
 
1423
    ds.erase(); /* Don't create a .log file */
1496
1424
 
1497
1425
    show_diff(NULL, result_file_name.c_str(), reject_file);
1498
1426
    die("%s",mess);
1519
1447
 
1520
1448
*/
1521
1449
 
1522
 
static void check_require(string* ds, const string &fname)
 
1450
static void check_require(const string& ds, const string& fname)
1523
1451
{
1524
1452
  if (string_cmp(ds, fname.c_str()))
1525
1453
  {
1540
1468
  char* ptr= str;
1541
1469
 
1542
1470
  /* Check if the first non space character is c1 */
1543
 
  while(*ptr && my_isspace(charset_info, *ptr))
 
1471
  while (*ptr && my_isspace(charset_info, *ptr))
1544
1472
    ptr++;
1545
1473
  if (*ptr == c1)
1546
1474
  {
1549
1477
 
1550
1478
    /* Last non space charecter should be c2 */
1551
1479
    ptr= strchr(str, '\0')-1;
1552
 
    while(*ptr && my_isspace(charset_info, *ptr))
 
1480
    while (*ptr && my_isspace(charset_info, *ptr))
1553
1481
      ptr--;
1554
1482
    if (*ptr == c2)
1555
1483
    {
1785
1713
 
1786
1714
*/
1787
1715
 
 
1716
static void dt_query(drizzle::connection_c& con, drizzle::result_c& res, const std::string& query)
 
1717
{
 
1718
  if (drizzle_return_t ret= con.query(res, query))
 
1719
  {
 
1720
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
1721
    {
 
1722
      die("Error running query '%s': %d %s", query.c_str(), res.error_code(), res.error());
 
1723
    }
 
1724
    else
 
1725
    {
 
1726
      die("Error running query '%s': %d %s", query.c_str(), ret, con.error());
 
1727
    }
 
1728
  }
 
1729
  if (res.column_count() == 0)
 
1730
    die("Query '%s' didn't return a result set", query.c_str());
 
1731
}
 
1732
 
1788
1733
static void var_query_set(VAR *var, const char *query, const char** query_end)
1789
1734
{
1790
 
  const char *end = (char*)((query_end && *query_end) ?
1791
 
                            *query_end : query + strlen(query));
1792
 
  drizzle_result_st res;
1793
 
  drizzle_return_t ret;
1794
 
  drizzle_row_t row;
1795
 
  drizzle_con_st *con= &cur_con->con;
1796
 
  string ds_query;
1797
 
 
 
1735
  const char *end = ((query_end && *query_end) ? *query_end : query + strlen(query));
 
1736
  drizzle::connection_c& con= *cur_con;
1798
1737
 
1799
1738
  while (end > query && *end != '`')
1800
1739
    --end;
1802
1741
    die("Syntax error in query, missing '`'");
1803
1742
  ++query;
1804
1743
 
 
1744
  string ds_query;
1805
1745
  /* Eval the query, thus replacing all environment variables */
1806
1746
  do_eval(&ds_query, query, end, false);
1807
1747
 
1808
 
  if (drizzle_query(con, &res, ds_query.c_str(), ds_query.length(),
1809
 
                    &ret) == NULL ||
1810
 
      ret != DRIZZLE_RETURN_OK)
1811
 
  {
1812
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1813
 
    {
1814
 
      die("Error running query '%s': %d %s", ds_query.c_str(),
1815
 
          drizzle_result_error_code(&res), drizzle_result_error(&res));
1816
 
      drizzle_result_free(&res);
1817
 
    }
1818
 
    else
1819
 
    {
1820
 
      die("Error running query '%s': %d %s", ds_query.c_str(), ret,
1821
 
          drizzle_con_error(con));
1822
 
    }
1823
 
  }
1824
 
  if (drizzle_result_column_count(&res) == 0 ||
1825
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
1826
 
    die("Query '%s' didn't return a result set", ds_query.c_str());
 
1748
  drizzle::result_c res;
 
1749
  dt_query(con, res, ds_query);
1827
1750
 
1828
 
  if ((row= drizzle_row_next(&res)) && row[0])
 
1751
  drizzle_row_t row= res.row_next();
 
1752
  if (row && row[0])
1829
1753
  {
1830
1754
    /*
1831
1755
      Concatenate all fields in the first row with tab in between
1832
1756
      and assign that string to the $variable
1833
1757
    */
1834
1758
    string result;
1835
 
    size_t* lengths= drizzle_row_field_sizes(&res);
1836
 
    for (uint32_t i= 0; i < drizzle_result_column_count(&res); i++)
 
1759
    size_t* lengths= res.row_field_sizes();
 
1760
    for (uint32_t i= 0; i < res.column_count(); i++)
1837
1761
    {
1838
1762
      if (row[i])
1839
1763
      {
1840
1764
        /* Add column to tab separated string */
1841
1765
        result.append(row[i], lengths[i]);
1842
1766
      }
1843
 
      result.append("\t", 1);
 
1767
      result += "\t";
1844
1768
    }
1845
 
    end= result.c_str() + result.length()-1;
 
1769
    end= result.c_str() + result.length() - 1;
1846
1770
    eval_expr(var, result.c_str(), (const char**) &end);
1847
1771
  }
1848
1772
  else
1849
1773
    eval_expr(var, "", 0);
1850
 
 
1851
 
  drizzle_result_free(&res);
1852
 
  return;
1853
1774
}
1854
1775
 
1855
1776
 
1878
1799
static void var_set_query_get_value(st_command* command, VAR *var)
1879
1800
{
1880
1801
  int col_no= -1;
1881
 
  drizzle_result_st res;
1882
 
  drizzle_return_t ret;
1883
 
  drizzle_con_st *con= &cur_con->con;
 
1802
  drizzle::connection_c& con= *cur_con;
1884
1803
 
1885
1804
  string ds_query;
1886
1805
  string ds_col;
1912
1831
    die("Mismatched \"'s around query '%s'", ds_query.c_str());
1913
1832
  ds_query= unstripped_query;
1914
1833
 
1915
 
  /* Run the query */
1916
 
  if (drizzle_query(con, &res, ds_query.c_str(), ds_query.length(), &ret) == NULL ||
1917
 
      ret != DRIZZLE_RETURN_OK)
1918
 
  {
1919
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1920
 
    {
1921
 
      die("Error running query '%s': %d %s", ds_query.c_str(), drizzle_result_error_code(&res), drizzle_result_error(&res));
1922
 
      drizzle_result_free(&res);
1923
 
    }
1924
 
    else
1925
 
    {
1926
 
      die("Error running query '%s': %d %s", ds_query.c_str(), ret, drizzle_con_error(con));
1927
 
    }
1928
 
  }
1929
 
  if (drizzle_result_column_count(&res) == 0 ||
1930
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
1931
 
    die("Query '%s' didn't return a result set", ds_query.c_str());
 
1834
  drizzle::result_c res;
 
1835
  dt_query(con, res, ds_query);
1932
1836
 
1933
1837
  {
1934
1838
    /* Find column number from the given column name */
1935
 
    uint32_t num_fields= drizzle_result_column_count(&res);
 
1839
    uint32_t num_fields= res.column_count();
1936
1840
    for (uint32_t i= 0; i < num_fields; i++)
1937
1841
    {
1938
 
      drizzle_column_st* column= drizzle_column_next(&res);
 
1842
      drizzle_column_st* column= res.column_next();
1939
1843
      if (strcmp(drizzle_column_name(column), ds_col.c_str()) == 0 &&
1940
1844
          strlen(drizzle_column_name(column)) == ds_col.length())
1941
1845
      {
1945
1849
    }
1946
1850
    if (col_no == -1)
1947
1851
    {
1948
 
      drizzle_result_free(&res);
1949
 
      die("Could not find column '%s' in the result of '%s'",
1950
 
          ds_col.c_str(), ds_query.c_str());
 
1852
      die("Could not find column '%s' in the result of '%s'", ds_col.c_str(), ds_query.c_str());
1951
1853
    }
1952
1854
  }
1953
1855
 
1956
1858
    long rows= 0;
1957
1859
    const char* value= "No such row";
1958
1860
 
1959
 
    while (drizzle_row_t row= drizzle_row_next(&res))
 
1861
    while (drizzle_row_t row= res.row_next())
1960
1862
    {
1961
1863
      if (++rows == row_no)
1962
1864
      {
1963
 
 
1964
1865
        /* Found the row to get */
1965
 
        if (row[col_no])
1966
 
          value= row[col_no];
1967
 
        else
1968
 
          value= "NULL";
1969
 
 
 
1866
        value= row[col_no] ? row[col_no] : "NULL";
1970
1867
        break;
1971
1868
      }
1972
1869
    }
1973
1870
    eval_expr(var, value, 0);
1974
1871
  }
1975
 
  drizzle_result_free(&res);
1976
1872
}
1977
1873
 
1978
1874
 
2229
2125
 
2230
2126
    if (command->abort_on_error)
2231
2127
    {
2232
 
      log_msg("exec of '%s' failed, error: %d, status: %d, errno: %d",
2233
 
              ds_cmd.c_str(), error, status, errno);
 
2128
      log_msg("exec of '%s' failed, error: %d, status: %d, errno: %d", ds_cmd.c_str(), error, status, errno);
2234
2129
      die("command \"%s\" failed", command->first_argument);
2235
2130
    }
2236
2131
 
2252
2147
           command->expected_errors.err[0].code.errnum != 0)
2253
2148
  {
2254
2149
    /* Error code we wanted was != 0, i.e. not an expected success */
2255
 
    log_msg("exec of '%s failed, error: %d, errno: %d",
2256
 
            ds_cmd.c_str(), error, errno);
 
2150
    log_msg("exec of '%s failed, error: %d, errno: %d", ds_cmd.c_str(), error, errno);
2257
2151
    die("command \"%s\" succeeded - should have failed with errno %d...",
2258
2152
        command->first_argument, command->expected_errors.err[0].code.errnum);
2259
2153
  }
2714
2608
                     sizeof(cat_file_args)/sizeof(struct command_arg),
2715
2609
                     ' ');
2716
2610
 
2717
 
  cat_file(&ds_res, ds_filename.c_str());
 
2611
  cat_file(ds_res, ds_filename.c_str());
2718
2612
}
2719
2613
 
2720
2614
 
2758
2652
  handle_command_error(command, error);
2759
2653
}
2760
2654
 
2761
 
 
2762
 
static st_connection * find_connection_by_name(const char *name)
2763
 
{
2764
 
  for (st_connection* con= g_connections; con < next_con; con++)
2765
 
  {
2766
 
    if (not strcmp(con->name, name))
2767
 
      return con;
2768
 
  }
2769
 
  return NULL;
2770
 
}
2771
 
 
2772
 
 
2773
2655
/*
2774
2656
  SYNOPSIS
2775
2657
  do_send_quit
2782
2664
 
2783
2665
static void do_send_quit(st_command* command)
2784
2666
{
2785
 
  char *p= command->first_argument, *name;
2786
 
  st_connection *con;
2787
 
  drizzle_result_st result;
2788
 
  drizzle_return_t ret;
 
2667
  char* p= command->first_argument;
2789
2668
 
2790
 
  if (!*p)
 
2669
  if (not *p)
2791
2670
    die("Missing connection name in send_quit");
2792
 
  name= p;
2793
 
  while (*p && !my_isspace(charset_info,*p))
 
2671
  char* name= p;
 
2672
  while (*p && !my_isspace(charset_info, *p))
2794
2673
    p++;
2795
2674
 
2796
2675
  if (*p)
2797
2676
    *p++= 0;
2798
2677
  command->last_argument= p;
2799
2678
 
2800
 
  if (!(con= find_connection_by_name(name)))
 
2679
  st_connection* con= find_ptr2(g_connections, name);
 
2680
  if (not con)
2801
2681
    die("connection '%s' not found in connection pool", name);
2802
2682
 
2803
 
  if (drizzle_quit(&con->con,&result, &ret))
2804
 
    drizzle_result_free(&result);
 
2683
  drizzle::result_c result;
 
2684
  drizzle_return_t ret;
 
2685
  drizzle_quit(*con, &result.b_, &ret);
2805
2686
}
2806
2687
 
2807
2688
 
2821
2702
 
2822
2703
*/
2823
2704
 
2824
 
static void do_change_user(struct st_command *)
 
2705
static void do_change_user(st_command *)
2825
2706
{
2826
2707
  assert(0);
2827
2708
}
2847
2728
 
2848
2729
static void do_perl(st_command* command)
2849
2730
{
2850
 
  int error;
2851
 
  int fd;
2852
 
  FILE *res_file;
2853
2731
  char buf[FN_REFLEN];
2854
2732
  char temp_file_path[FN_REFLEN];
2855
2733
  string ds_script;
2856
2734
  string ds_delimiter;
2857
 
  const struct command_arg perl_args[] = {
 
2735
  const command_arg perl_args[] = {
2858
2736
    { "delimiter", ARG_STRING, false, &ds_delimiter, "Delimiter to read until" }
2859
2737
  };
2860
2738
 
2872
2750
  read_until_delimiter(&ds_script, &ds_delimiter);
2873
2751
 
2874
2752
  /* Create temporary file name */
2875
 
  if ((fd= internal::create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"),
2876
 
                            "tmp", MYF(MY_WME))) < 0)
 
2753
  int fd= internal::create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"), "tmp", MYF(MY_WME));
 
2754
  if (fd < 0)
2877
2755
    die("Failed to create temporary file for perl command");
2878
2756
  internal::my_close(fd, MYF(0));
2879
2757
 
2882
2760
  /* Format the "perl <filename>" command */
2883
2761
  snprintf(buf, sizeof(buf), "perl %s", temp_file_path);
2884
2762
 
2885
 
  if (!(res_file= popen(buf, "r")) && command->abort_on_error)
 
2763
  FILE* res_file= popen(buf, "r");
 
2764
  if (not res_file && command->abort_on_error)
2886
2765
    die("popen(\"%s\", \"r\") failed", buf);
2887
2766
 
2888
2767
  while (fgets(buf, sizeof(buf), res_file))
2892
2771
    else
2893
2772
      replace_append(&ds_res, buf);
2894
2773
  }
2895
 
  error= pclose(res_file);
 
2774
  int error= pclose(res_file);
2896
2775
 
2897
2776
  /* Remove the temporary file */
2898
2777
  internal::my_delete(temp_file_path, MYF(0));
2928
2807
static void do_echo(st_command* command)
2929
2808
{
2930
2809
  string ds_echo;
2931
 
 
2932
 
 
2933
2810
  do_eval(&ds_echo, command->first_argument, command->end, false);
2934
2811
  ds_res.append(ds_echo.c_str(), ds_echo.length());
2935
2812
  ds_res.append("\n");
2936
2813
  command->last_argument= command->end;
2937
2814
}
2938
2815
 
2939
 
 
2940
2816
static void do_wait_for_slave_to_stop()
2941
2817
{
2942
2818
  static int SLAVE_POLL_INTERVAL= 300000;
2943
 
  drizzle_con_st *con= &cur_con->con;
 
2819
  drizzle::connection_c& con= *cur_con;
2944
2820
  for (;;)
2945
2821
  {
2946
 
    drizzle_result_st res;
2947
 
    drizzle_return_t ret;
2948
 
    drizzle_row_t row;
2949
 
    int done;
2950
 
 
2951
 
    if (drizzle_query_str(con,&res,"show status like 'Slave_running'",
2952
 
                          &ret) == NULL || ret != DRIZZLE_RETURN_OK)
2953
 
    {
2954
 
      if (ret == DRIZZLE_RETURN_ERROR_CODE)
2955
 
      {
2956
 
        die("Query failed while probing slave for stop: %s",
2957
 
            drizzle_result_error(&res));
2958
 
        drizzle_result_free(&res);
2959
 
      }
2960
 
      else
2961
 
      {
2962
 
        die("Query failed while probing slave for stop: %s",
2963
 
            drizzle_con_error(con));
2964
 
      }
2965
 
    }
2966
 
 
2967
 
    if (drizzle_result_column_count(&res) == 0 ||
2968
 
        drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
2969
 
    {
2970
 
      die("Query failed while probing slave for stop: %s",
2971
 
          drizzle_con_error(con));
2972
 
    }
2973
 
 
2974
 
    if (!(row=drizzle_row_next(&res)) || !row[1])
2975
 
    {
2976
 
      drizzle_result_free(&res);
 
2822
    drizzle::result_c res;
 
2823
    dt_query(con, res, "show status like 'Slave_running'");
 
2824
    drizzle_row_t row= res.row_next();
 
2825
    if (!row || !row[1])
 
2826
    {
2977
2827
      die("Strange result from query while probing slave for stop");
2978
2828
    }
2979
 
    done = !strcmp(row[1],"OFF");
2980
 
    drizzle_result_free(&res);
2981
 
    if (done)
 
2829
    if (!strcmp(row[1], "OFF"))
2982
2830
      break;
2983
2831
    usleep(SLAVE_POLL_INTERVAL);
2984
2832
  }
2986
2834
 
2987
2835
static void do_sync_with_master2(long offset)
2988
2836
{
2989
 
  drizzle_result_st res;
2990
 
  drizzle_return_t ret;
2991
 
  drizzle_row_t row;
2992
 
  drizzle_con_st *con= &cur_con->con;
 
2837
  drizzle::connection_c& con= *cur_con;
2993
2838
  char query_buf[FN_REFLEN+128];
2994
2839
  int tries= 0;
2995
2840
 
3001
2846
 
3002
2847
wait_for_position:
3003
2848
 
3004
 
  if (drizzle_query_str(con, &res, query_buf, &ret) == NULL ||
3005
 
      ret != DRIZZLE_RETURN_OK)
3006
 
  {
3007
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
3008
 
    {
3009
 
      die("failed in '%s': %d: %s", query_buf, drizzle_result_error_code(&res),
3010
 
           drizzle_result_error(&res));
3011
 
      drizzle_result_free(&res);
3012
 
    }
3013
 
    else
3014
 
      die("failed in '%s': %d: %s", query_buf, ret, drizzle_con_error(con));
3015
 
  }
3016
 
 
3017
 
  if (drizzle_result_column_count(&res) == 0 ||
3018
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
3019
 
    die("drizzle_result_buffer() returned NULL for '%s'", query_buf);
3020
 
 
3021
 
  if (!(row= drizzle_row_next(&res)))
3022
 
  {
3023
 
    drizzle_result_free(&res);
 
2849
  drizzle::result_c res;
 
2850
  dt_query(con, res, query_buf);
 
2851
 
 
2852
  drizzle_row_t row= res.row_next();
 
2853
  if (!row)
 
2854
  {
3024
2855
    die("empty result in %s", query_buf);
3025
2856
  }
3026
2857
  if (!row[0])
3029
2860
      It may be that the slave SQL thread has not started yet, though START
3030
2861
      SLAVE has been issued ?
3031
2862
    */
3032
 
    drizzle_result_free(&res);
3033
2863
    if (tries++ == 30)
3034
2864
    {
3035
2865
      show_query(con, "SHOW MASTER STATUS");
3039
2869
    sleep(1); /* So at most we will wait 30 seconds and make 31 tries */
3040
2870
    goto wait_for_position;
3041
2871
  }
3042
 
  drizzle_result_free(&res);
3043
 
  return;
3044
2872
}
3045
2873
 
3046
2874
static void do_sync_with_master(st_command* command)
3068
2896
*/
3069
2897
static void do_save_master_pos()
3070
2898
{
3071
 
  drizzle_result_st res;
3072
 
  drizzle_return_t ret;
3073
 
  drizzle_row_t row;
3074
 
  drizzle_con_st *con= &cur_con->con;
3075
 
  const char *query;
3076
 
 
3077
 
 
3078
 
  if (drizzle_query_str(con, &res, query= "show master status", &ret) == NULL ||
3079
 
      ret != DRIZZLE_RETURN_OK)
3080
 
  {
3081
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
3082
 
    {
3083
 
      die("failed in '%s': %d: %s", query, drizzle_result_error_code(&res),
3084
 
           drizzle_result_error(&res));
3085
 
      drizzle_result_free(&res);
3086
 
    }
3087
 
    else
3088
 
      die("failed in '%s': %d: %s", query, ret, drizzle_con_error(con));
3089
 
  }
3090
 
 
3091
 
  if (drizzle_result_column_count(&res) == 0 ||
3092
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
3093
 
    die("drizzleclient_store_result() retuned NULL for '%s'", query);
3094
 
  if (!(row = drizzle_row_next(&res)))
 
2899
  drizzle::connection_c& con= *cur_con;
 
2900
  const char *query= "show master status";
 
2901
 
 
2902
  drizzle::result_c res;
 
2903
  dt_query(con, res, query);
 
2904
  drizzle_row_t row= res.row_next();
 
2905
  if (!row)
3095
2906
    die("empty result in show master status");
3096
2907
  strncpy(master_pos.file, row[0], sizeof(master_pos.file)-1);
3097
2908
  master_pos.pos = strtoul(row[1], (char**) 0, 10);
3098
 
  drizzle_result_free(&res);
3099
2909
}
3100
2910
 
3101
2911
 
3249
3059
 
3250
3060
static void fill_global_error_names()
3251
3061
{
3252
 
  drizzle_result_st res;
3253
 
  drizzle_return_t ret;
3254
 
  drizzle_con_st *con= &cur_con->con;
 
3062
  drizzle::connection_c& con= *cur_con;
3255
3063
 
3256
3064
  global_error_names.clear();
3257
3065
 
3258
 
  const std::string ds_query("select error_name, error_code from data_dictionary.errors");
3259
 
  if (drizzle_query_str(con, &res, ds_query.c_str(), &ret) == NULL ||
3260
 
      ret != DRIZZLE_RETURN_OK)
3261
 
  {
3262
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
3263
 
    {
3264
 
      die("Error running query '%s': %d %s", ds_query.c_str(), drizzle_result_error_code(&res), drizzle_result_error(&res));
3265
 
    }
3266
 
    else
3267
 
    {
3268
 
      die("Error running query '%s': %d %s", ds_query.c_str(), ret, drizzle_con_error(con));
3269
 
    }
3270
 
  }
3271
 
  if (drizzle_result_column_count(&res) == 0 ||
3272
 
      drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
3273
 
  {
3274
 
    drizzle_result_free(&res);
3275
 
    die("Query '%s' didn't return a result set", ds_query.c_str());
3276
 
  }
3277
 
 
3278
 
  while (drizzle_row_t row= drizzle_row_next(&res))
 
3066
  drizzle::result_c res;
 
3067
  dt_query(con, res, "select error_name, error_code from data_dictionary.errors");
 
3068
  while (drizzle_row_t row= res.row_next())
3279
3069
  {
3280
3070
    if (not row[0])
3281
3071
      break;
3283
3073
      Concatenate all fields in the first row with tab in between
3284
3074
      and assign that string to the $variable
3285
3075
    */
3286
 
    size_t *lengths= drizzle_row_field_sizes(&res);
 
3076
    size_t *lengths= res.row_field_sizes();
3287
3077
    try
3288
3078
    {
3289
3079
      global_error_names[string(row[0], lengths[0])] = boost::lexical_cast<uint32_t>(string(row[1], lengths[1]));
3290
3080
    }
3291
3081
    catch (boost::bad_lexical_cast &ex)
3292
3082
    {
3293
 
      drizzle_result_free(&res);
3294
3083
      die("Invalid error_code from Drizzle: %s", ex.what());
3295
3084
    }
3296
 
 
3297
3085
  }
3298
 
 
3299
 
  drizzle_result_free(&res);
3300
3086
}
3301
3087
 
3302
3088
static uint32_t get_errcode_from_name(const char *error_name, const char *error_end)
3502
3288
}
3503
3289
 
3504
3290
 
3505
 
static int select_connection_name(const char *name)
 
3291
static void select_connection_name(const char *name)
3506
3292
{
3507
 
  if (!(cur_con= find_connection_by_name(name)))
 
3293
  if (!(cur_con= find_ptr2(g_connections, name)))
3508
3294
    die("connection '%s' not found in connection pool", name);
3509
3295
 
3510
3296
  /* Update $drizzleclient_get_server_version to that of current connection */
3511
 
  var_set_drizzleclient_get_server_version(&cur_con->con);
3512
 
 
3513
 
  return(0);
 
3297
  var_set_drizzleclient_get_server_version(*cur_con);
3514
3298
}
3515
3299
 
3516
3300
 
3517
 
static int select_connection(st_command* command)
 
3301
static void select_connection(st_command* command)
3518
3302
{
3519
 
  char *name;
3520
3303
  char *p= command->first_argument;
3521
 
 
3522
 
 
3523
3304
  if (!*p)
3524
3305
    die("Missing connection name in connect");
3525
 
  name= p;
 
3306
  char* name= p;
3526
3307
  while (*p && !my_isspace(charset_info,*p))
3527
3308
    p++;
3528
3309
  if (*p)
3529
3310
    *p++= 0;
3530
3311
  command->last_argument= p;
3531
 
  return(select_connection_name(name));
 
3312
  select_connection_name(name);
3532
3313
}
3533
3314
 
3534
3315
 
3535
3316
static void do_close_connection(st_command* command)
3536
3317
{
3537
 
  char *p= command->first_argument, *name;
3538
 
  st_connection *con;
3539
 
 
 
3318
  char* p= command->first_argument;
3540
3319
  if (!*p)
3541
3320
    die("Missing connection name in disconnect");
3542
 
  name= p;
 
3321
  char* name= p;
3543
3322
  while (*p && !my_isspace(charset_info,*p))
3544
3323
    p++;
3545
3324
 
3547
3326
    *p++= 0;
3548
3327
  command->last_argument= p;
3549
3328
 
3550
 
  if (!(con= find_connection_by_name(name)))
 
3329
  st_connection* con= find_ptr2(g_connections, name);
 
3330
  if (!con)
3551
3331
    die("connection '%s' not found in connection pool", name);
3552
 
 
3553
 
  if (con->drizzle != NULL)
3554
 
  {
3555
 
    drizzle_free(con->drizzle);
3556
 
    con->drizzle= NULL;
3557
 
  }
3558
 
  free(con->name);
3559
 
 
3560
 
  /*
3561
 
    When the connection is closed set name to "-closed_connection-"
3562
 
    to make it possible to reuse the connection name.
3563
 
  */
3564
 
  con->name = strdup("-closed_connection-");
 
3332
  g_connections.erase(name);
 
3333
  delete con;
3565
3334
}
3566
3335
 
3567
3336
 
3590
3359
 
3591
3360
*/
3592
3361
 
3593
 
static void safe_connect(drizzle_con_st *con, const char *name,
3594
 
                         const string host, const string user, const char *pass,
3595
 
                         const string db, uint32_t port)
 
3362
static st_connection* safe_connect(const char *name, const string host, const string user, const char *pass, const string db, uint32_t port)
3596
3363
{
3597
3364
  uint32_t failed_attempts= 0;
3598
 
  static uint32_t connection_retry_sleep= 100000; /* Microseconds */
3599
 
  drizzle_return_t ret;
3600
 
 
 
3365
  st_connection* con0= new st_connection;
 
3366
  drizzle_con_st* con= *con0;
3601
3367
  drizzle_con_set_tcp(con, host.c_str(), port);
3602
3368
  drizzle_con_set_auth(con, user.c_str(), pass);
3603
3369
  drizzle_con_set_db(con, db.c_str());
3604
 
  while((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
 
3370
  while (drizzle_return_t ret= drizzle_con_connect(con))
3605
3371
  {
3606
3372
    /*
3607
3373
      Connect failed
3615
3381
         ret == DRIZZLE_RETURN_COULD_NOT_CONNECT) &&
3616
3382
        failed_attempts < opt_max_connect_retries)
3617
3383
    {
3618
 
      verbose_msg("Connect attempt %d/%d failed: %d: %s", failed_attempts,
3619
 
                  opt_max_connect_retries, ret, drizzle_con_error(con));
3620
 
      usleep(connection_retry_sleep);
 
3384
      verbose_msg("Connect attempt %d/%d failed: %d: %s", failed_attempts, opt_max_connect_retries, ret, drizzle_con_error(con));
 
3385
      usleep(100000);
3621
3386
    }
3622
3387
    else
3623
3388
    {
3624
3389
      if (failed_attempts > 0)
3625
 
        die("Could not open connection '%s' after %d attempts: %d %s", name,
3626
 
            failed_attempts, ret, drizzle_con_error(con));
 
3390
        die("Could not open connection '%s' after %d attempts: %d %s", name, failed_attempts, ret, drizzle_con_error(con));
3627
3391
      else
3628
 
        die("Could not open connection '%s': %d %s", name, ret,
3629
 
            drizzle_con_error(con));
 
3392
        die("Could not open connection '%s': %d %s", name, ret, drizzle_con_error(con));
3630
3393
    }
3631
3394
    failed_attempts++;
3632
3395
  }
3633
 
  return;
 
3396
  return con0;
3634
3397
}
3635
3398
 
3636
3399
 
3662
3425
                                   const char* user, const char* pass,
3663
3426
                                   const char* db, int port, const char* sock)
3664
3427
{
3665
 
  drizzle_return_t ret;
3666
 
 
3667
3428
  /* Only log if an error is expected */
3668
3429
  if (!command->abort_on_error &&
3669
3430
      !disable_query_log)
3692
3453
  drizzle_con_set_tcp(con, host, port);
3693
3454
  drizzle_con_set_auth(con, user, pass);
3694
3455
  drizzle_con_set_db(con, db);
3695
 
  if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
 
3456
  if (drizzle_return_t ret= drizzle_con_connect(con))
3696
3457
  {
3697
3458
    if (ret == DRIZZLE_RETURN_HANDSHAKE_FAILED)
3698
3459
    {
3699
3460
      var_set_errno(drizzle_con_error_code(con));
3700
 
      handle_error(command, drizzle_con_error_code(con), drizzle_con_error(con),
3701
 
                   drizzle_con_sqlstate(con), &ds_res);
 
3461
      handle_error(command, drizzle_con_error_code(con), drizzle_con_error(con), drizzle_con_sqlstate(con), &ds_res);
3702
3462
    }
3703
3463
    else
3704
3464
    {
3705
3465
      var_set_errno(ret);
3706
3466
      handle_error(command, ret, drizzle_con_error(con), "", &ds_res);
3707
3467
    }
3708
 
 
3709
3468
    return 0; /* Not connected */
3710
3469
  }
3711
 
 
3712
3470
  var_set_errno(0);
3713
3471
  handle_no_error(command);
3714
3472
  return 1; /* Connected */
3743
3501
static void do_connect(st_command* command)
3744
3502
{
3745
3503
  uint32_t con_port= opt_port;
3746
 
  const char *con_options;
3747
 
  st_connection* con_slot;
3748
3504
 
3749
3505
  string ds_connection_name;
3750
3506
  string ds_host;
3765
3521
    { "options", ARG_STRING, false, &ds_options, "Options to use while connecting" }
3766
3522
  };
3767
3523
 
3768
 
 
3769
3524
  strip_parentheses(command);
3770
3525
  check_command_args(command, command->first_argument, connect_args,
3771
3526
                     sizeof(connect_args)/sizeof(struct command_arg),
3790
3545
    {
3791
3546
      char buff[FN_REFLEN];
3792
3547
      internal::fn_format(buff, ds_sock.c_str(), TMPDIR, "", 0);
3793
 
      ds_sock.clear();
3794
 
      ds_sock.append(buff);
 
3548
      ds_sock= buff;
3795
3549
    }
3796
3550
  }
3797
3551
 
3798
3552
  /* Options */
3799
 
  con_options= ds_options.c_str();
 
3553
  const char* con_options= ds_options.c_str();
3800
3554
  while (*con_options)
3801
3555
  {
3802
 
    const char* end;
3803
3556
    /* Step past any spaces in beginning of option*/
3804
3557
    while (*con_options && my_isspace(charset_info, *con_options))
3805
3558
      con_options++;
3806
3559
    /* Find end of this option */
3807
 
    end= con_options;
 
3560
    const char* end= con_options;
3808
3561
    while (*end && !my_isspace(charset_info, *end))
3809
3562
      end++;
3810
 
    die("Illegal option to connect: %.*s",
3811
 
        (int) (end - con_options), con_options);
 
3563
    die("Illegal option to connect: %.*s", (int) (end - con_options), con_options);
3812
3564
    /* Process next option */
3813
3565
    con_options= end;
3814
3566
  }
3815
3567
 
3816
 
  if (find_connection_by_name(ds_connection_name.c_str()))
 
3568
  if (find_ptr2(g_connections, ds_connection_name))
3817
3569
    die("Connection %s already exists", ds_connection_name.c_str());
3818
3570
 
3819
 
  if (next_con != g_connections + sizeof(g_connections) / sizeof(st_connection) - 1)
3820
 
  {
3821
 
    con_slot= next_con;
3822
 
  }
3823
 
  else
3824
 
  {
3825
 
    if (!(con_slot= find_connection_by_name("-closed_connection-")))
3826
 
      die("Connection limit exhausted, you can have max %d connections",
3827
 
          (int) (sizeof(g_connections)/sizeof(st_connection)));
3828
 
  }
3829
 
 
3830
 
  if ((con_slot->drizzle= drizzle_create(NULL)) == NULL)
3831
 
    die("Failed on drizzle_create()");
3832
 
  if (!drizzle_con_create(con_slot->drizzle, &con_slot->con))
3833
 
    die("Failed on drizzle_con_create()");
3834
 
  drizzle_con_add_options(&con_slot->con, use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
 
3571
  st_connection* con_slot= new st_connection;
3835
3572
 
3836
3573
  /* Use default db name */
3837
 
  if (ds_database.length() == 0)
3838
 
    ds_database.append(opt_db);
 
3574
  if (ds_database.empty())
 
3575
    ds_database= opt_db;
3839
3576
 
3840
3577
  /* Special database to allow one to connect without a database name */
3841
 
  if (ds_database.length() && !strcmp(ds_database.c_str(),"*NO-ONE*"))
 
3578
  if (ds_database == "*NO-ONE*")
3842
3579
    ds_database.clear();
3843
3580
 
3844
 
  if (connect_n_handle_errors(command, &con_slot->con,
3845
 
                              ds_host.c_str(),ds_user.c_str(),
3846
 
                              ds_password.c_str(), ds_database.c_str(),
3847
 
                              con_port, ds_sock.c_str()))
 
3581
  if (connect_n_handle_errors(command, *con_slot, ds_host.c_str(), ds_user.c_str(), 
 
3582
    ds_password.c_str(), ds_database.c_str(), con_port, ds_sock.c_str()))
3848
3583
  {
3849
 
    con_slot->name= strdup(ds_connection_name.c_str());
 
3584
    g_connections[ds_connection_name]= con_slot;
3850
3585
    cur_con= con_slot;
3851
 
 
3852
 
    if (con_slot == next_con)
3853
 
      next_con++; /* if we used the next_con slot, advance the pointer */
3854
3586
  }
3855
3587
 
3856
3588
  /* Update $drizzleclient_get_server_version to that of current connection */
3857
 
  var_set_drizzleclient_get_server_version(&cur_con->con);
3858
 
 
3859
 
  return;
 
3589
  var_set_drizzleclient_get_server_version(*cur_con);
3860
3590
}
3861
3591
 
3862
3592
 
3863
 
static int do_done(st_command* command)
 
3593
static void do_done(st_command* command)
3864
3594
{
3865
3595
  /* Check if empty block stack */
3866
3596
  if (cur_block == block_stack)
3883
3613
    cur_block--;
3884
3614
    parser.current_line++;
3885
3615
  }
3886
 
  return 0;
3887
3616
}
3888
3617
 
3889
3618
 
3913
3642
 
3914
3643
*/
3915
3644
 
3916
 
static void do_block(enum block_cmd cmd, struct st_command* command)
 
3645
static void do_block(enum block_cmd cmd, st_command* command)
3917
3646
{
3918
3647
  char *p= command->first_argument;
3919
3648
  const char *expr_start, *expr_end;
3973
3702
 
3974
3703
  free(v.str_val);
3975
3704
  free(v.env_s);
3976
 
 
3977
 
  return;
3978
3705
}
3979
3706
 
3980
3707
 
3981
 
static void do_delimiter(struct st_command* command)
 
3708
static void do_delimiter(st_command* command)
3982
3709
{
3983
3710
  char* p= command->first_argument;
3984
3711
 
3992
3719
  delimiter_length= strlen(delimiter);
3993
3720
 
3994
3721
  command->last_argument= p + delimiter_length;
3995
 
  return;
3996
3722
}
3997
3723
 
3998
3724
 
4306
4032
{
4307
4033
  const char *ptr= command->query;
4308
4034
 
4309
 
  while(*ptr)
 
4035
  while (*ptr)
4310
4036
  {
4311
4037
    /*
4312
4038
      Look for query's that lines that start with a -- comment
4331
4057
      *end= 0;
4332
4058
      type= command_typelib.find_type(start, TYPELIB::e_default);
4333
4059
      if (type)
4334
 
        warning_msg("Embedded drizzletest command '--%s' detected in "
4335
 
                    "query '%s' was this intentional? ",
4336
 
                    start, command->query);
 
4060
        warning_msg("Embedded drizzletest command '--%s' detected in query '%s' was this intentional? ", start, command->query);
4337
4061
      *end= save;
4338
4062
    }
4339
 
 
4340
4063
    ptr++;
4341
4064
  }
4342
 
  return;
4343
4065
}
4344
4066
 
4345
4067
/*
4414
4136
#define MAX_QUERY (768*1024*2) /* 256K -- a test in sp-big is >128K */
4415
4137
static char read_command_buf[MAX_QUERY];
4416
4138
 
4417
 
static int read_command(struct st_command** command_ptr)
 
4139
static int read_command(st_command** command_ptr)
4418
4140
{
4419
4141
  char *p= read_command_buf;
4420
 
  struct st_command* command;
 
4142
  st_command* command;
4421
4143
 
4422
4144
 
4423
4145
  if (parser.current_line < parser.read_lines)
4485
4207
 
4486
4208
void str_to_file2(const char *fname, const char *str, int size, bool append)
4487
4209
{
4488
 
  int fd;
4489
4210
  char buff[FN_REFLEN];
4490
 
  int flags= O_WRONLY | O_CREAT;
4491
4211
  if (!internal::test_if_hard_path(fname))
4492
4212
  {
4493
4213
    snprintf(buff, sizeof(buff), "%s%s",opt_basedir.c_str(),fname);
4495
4215
  }
4496
4216
  internal::fn_format(buff, fname, "", "", MY_UNPACK_FILENAME);
4497
4217
 
 
4218
  int flags= O_WRONLY | O_CREAT;
4498
4219
  if (!append)
4499
4220
    flags|= O_TRUNC;
4500
 
  if ((fd= internal::my_open(buff, flags,
4501
 
                   MYF(MY_WME | MY_FFNF))) < 0)
 
4221
  int fd= internal::my_open(buff, flags, MYF(MY_WME | MY_FFNF));
 
4222
  if (fd < 0)
4502
4223
    die("Could not open '%s' for writing: errno = %d", buff, errno);
4503
4224
  if (append && lseek(fd, 0, SEEK_END) == MY_FILEPOS_ERROR)
4504
4225
    die("Could not find end of file '%s': errno = %d", buff, errno);
4530
4251
                        ! opt_logdir.empty() ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4531
4252
                        MY_REPLACE_EXT),
4532
4253
              buf, size);
4533
 
  fprintf(stderr, "\nMore results from queries before failure can be found in %s\n",
4534
 
          log_file);
 
4254
  fprintf(stderr, "\nMore results from queries before failure can be found in %s\n", log_file);
4535
4255
}
4536
4256
 
4537
4257
void dump_progress()
4577
4297
  {
4578
4298
    if (col_idx)
4579
4299
      ds->append("\t");
4580
 
    replace_append_mem(ds, val, (int)len);
 
4300
    replace_append_mem(*ds, val, (int)len);
4581
4301
  }
4582
4302
  else
4583
4303
  {
4584
4304
    ds->append(drizzle_column_name(column));
4585
4305
    ds->append("\t");
4586
 
    replace_append_mem(ds, val, (int)len);
 
4306
    replace_append_mem(*ds, val, (int)len);
4587
4307
    ds->append("\n");
4588
4308
  }
4589
4309
}
4594
4314
  Values may be converted with 'replace_column'
4595
4315
*/
4596
4316
 
4597
 
static void append_result(string *ds, drizzle_result_st *res)
 
4317
static void append_result(string *ds, drizzle::result_c& res)
4598
4318
{
4599
 
  drizzle_row_t row;
4600
 
  uint32_t num_fields= drizzle_result_column_count(res);
4601
 
  drizzle_column_st *column;
4602
 
  size_t *lengths;
4603
 
 
4604
 
  while ((row = drizzle_row_next(res)))
 
4319
  uint32_t num_fields= res.column_count();
 
4320
  while (drizzle_row_t row = res.row_next())
4605
4321
  {
4606
 
    uint32_t i;
4607
 
    lengths = drizzle_row_field_sizes(res);
4608
 
    drizzle_column_seek(res, 0);
4609
 
    for (i = 0; i < num_fields; i++)
 
4322
    size_t* lengths = res.row_field_sizes();
 
4323
    res.column_seek(0);
 
4324
    for (uint32_t i = 0; i < num_fields; i++)
4610
4325
    {
4611
 
      column= drizzle_column_next(res);
4612
 
      if (row[i] && (drizzle_column_type(column) == DRIZZLE_COLUMN_TYPE_TINY))
 
4326
      drizzle_column_st* column= res.column_next();
 
4327
      if (row[i] && drizzle_column_type(column) == DRIZZLE_COLUMN_TYPE_TINY)
4613
4328
      {
4614
4329
        if (boost::lexical_cast<uint32_t>(row[i]))
4615
4330
        {
4616
 
          if ((drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_UNSIGNED))
 
4331
          if (drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_UNSIGNED)
4617
4332
          {
4618
4333
            append_field(ds, i, column, "YES", 3, false);
4619
4334
          }
4624
4339
        }
4625
4340
        else
4626
4341
        {
4627
 
          if ((drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_UNSIGNED))
 
4342
          if (drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_UNSIGNED)
4628
4343
          {
4629
4344
            append_field(ds, i, column, "NO", 2, false);
4630
4345
          }
4636
4351
      }
4637
4352
      else
4638
4353
      {
4639
 
        append_field(ds, i, column,
4640
 
                     (const char*)row[i], lengths[i], !row[i]);
 
4354
        append_field(ds, i, column, (const char*)row[i], lengths[i], !row[i]);
4641
4355
      }
4642
4356
    }
4643
4357
    if (!display_result_vertically)
4644
4358
      ds->append("\n");
4645
 
 
4646
4359
  }
4647
4360
}
4648
4361
 
4651
4364
  Append metadata for fields to output
4652
4365
*/
4653
4366
 
4654
 
static void append_metadata(string *ds, drizzle_result_st *res)
 
4367
static void append_metadata(string *ds, drizzle::result_c& res)
4655
4368
{
4656
 
  drizzle_column_st *column;
4657
4369
  ds->append("Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
4658
4370
             "Column_alias\tType\tLength\tMax length\tIs_null\t"
4659
4371
             "Flags\tDecimals\tCharsetnr\n");
4660
4372
 
4661
 
  drizzle_column_seek(res, 0);
4662
 
  while ((column= drizzle_column_next(res)))
 
4373
  res.column_seek(0);
 
4374
  while (drizzle_column_st* column= res.column_next())
4663
4375
  {
4664
 
    ds->append(drizzle_column_catalog(column),
4665
 
               strlen(drizzle_column_catalog(column)));
4666
 
    ds->append("\t", 1);
 
4376
    ds->append(drizzle_column_catalog(column), strlen(drizzle_column_catalog(column)));
 
4377
    *ds += "\t";
4667
4378
    ds->append(drizzle_column_db(column), strlen(drizzle_column_db(column)));
4668
 
    ds->append("\t", 1);
4669
 
    ds->append(drizzle_column_orig_table(column),
4670
 
               strlen(drizzle_column_orig_table(column)));
4671
 
    ds->append("\t", 1);
4672
 
    ds->append(drizzle_column_table(column),
4673
 
               strlen(drizzle_column_table(column)));
4674
 
    ds->append("\t", 1);
4675
 
    ds->append(drizzle_column_orig_name(column),
4676
 
               strlen(drizzle_column_orig_name(column)));
4677
 
    ds->append("\t", 1);
4678
 
    ds->append(drizzle_column_name(column),
4679
 
               strlen(drizzle_column_name(column)));
4680
 
    ds->append("\t", 1);
 
4379
    *ds += "\t";
 
4380
    ds->append(drizzle_column_orig_table(column), strlen(drizzle_column_orig_table(column)));
 
4381
    *ds += "\t";
 
4382
    ds->append(drizzle_column_table(column), strlen(drizzle_column_table(column)));
 
4383
    *ds += "\t";
 
4384
    ds->append(drizzle_column_orig_name(column), strlen(drizzle_column_orig_name(column)));
 
4385
    *ds += "\t";
 
4386
    ds->append(drizzle_column_name(column), strlen(drizzle_column_name(column)));
 
4387
    *ds += "\t";
4681
4388
    replace_append_uint(ds, drizzle_column_type_drizzle(column));
4682
 
    ds->append("\t", 1);
 
4389
    *ds += "\t";
4683
4390
    replace_append_uint(ds, drizzle_column_size(column));
4684
 
    ds->append("\t", 1);
4685
 
    if (drizzle_column_type(column) == DRIZZLE_COLUMN_TYPE_TINY)
4686
 
    {
4687
 
      replace_append_uint(ds, 1);
4688
 
    }
4689
 
    else
4690
 
    {
4691
 
      replace_append_uint(ds, drizzle_column_max_size(column));
4692
 
    }
4693
 
    ds->append("\t", 1);
4694
 
    ds->append((char*) ((drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_NOT_NULL) ? "N" : "Y"), 1);
4695
 
    ds->append("\t", 1);
 
4391
    *ds += "\t";
 
4392
    replace_append_uint(ds, drizzle_column_type(column) == DRIZZLE_COLUMN_TYPE_TINY ? 1 : drizzle_column_max_size(column));
 
4393
    *ds += "\t";
 
4394
    ds->append((drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_NOT_NULL) ? "N" : "Y", 1);
 
4395
    *ds += "\t";
4696
4396
    replace_append_uint(ds, drizzle_column_flags(column));
4697
 
    ds->append("\t", 1);
 
4397
    *ds += "\t";
4698
4398
    replace_append_uint(ds, drizzle_column_decimals(column));
4699
 
    ds->append("\t", 1);
 
4399
    *ds += "\t";
4700
4400
    replace_append_uint(ds, drizzle_column_charset(column));
4701
 
    ds->append("\n", 1);
 
4401
    *ds += "\n";
4702
4402
  }
4703
4403
}
4704
4404
 
4726
4426
  Display the table headings with the names tab separated
4727
4427
*/
4728
4428
 
4729
 
static void append_table_headings(string *ds, drizzle_result_st *res)
 
4429
static void append_table_headings(string& ds, drizzle::result_c& res)
4730
4430
{
4731
4431
  uint32_t col_idx= 0;
4732
 
  drizzle_column_st *column;
4733
 
  drizzle_column_seek(res, 0);
4734
 
  while ((column= drizzle_column_next(res)))
 
4432
  res.column_seek(0);
 
4433
  while (drizzle_column_st* column= res.column_next())
4735
4434
  {
4736
4435
    if (col_idx)
4737
 
      ds->append("\t", 1);
4738
 
    replace_append(ds, drizzle_column_name(column));
 
4436
      ds += "\t";
 
4437
    replace_append(&ds, drizzle_column_name(column));
4739
4438
    col_idx++;
4740
4439
  }
4741
 
  ds->append("\n", 1);
 
4440
  ds += "\n";
4742
4441
}
4743
4442
 
4744
4443
/*
4748
4447
  Number of warnings appended to ds
4749
4448
*/
4750
4449
 
4751
 
static int append_warnings(string *ds, drizzle_con_st *con,
4752
 
                           drizzle_result_st *res)
 
4450
static int append_warnings(string& ds, drizzle::connection_c& con, drizzle::result_c& res)
4753
4451
{
4754
 
  uint32_t count;
4755
 
  drizzle_result_st warn_res;
4756
 
  drizzle_return_t ret;
4757
 
 
4758
 
 
4759
 
  if (!(count= drizzle_result_warning_count(res)))
4760
 
    return(0);
4761
 
 
4762
 
  if (drizzle_query_str(con, &warn_res, "SHOW WARNINGS", &ret) == NULL ||
4763
 
      ret != DRIZZLE_RETURN_OK)
4764
 
  {
4765
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
4766
 
      die("Error running query \"SHOW WARNINGS\": %s", drizzle_result_error(&warn_res));
4767
 
    else
4768
 
      die("Error running query \"SHOW WARNINGS\": %s", drizzle_con_error(con));
4769
 
  }
4770
 
 
4771
 
  if (drizzle_result_column_count(&warn_res) == 0 ||
4772
 
      drizzle_result_buffer(&warn_res) != DRIZZLE_RETURN_OK)
4773
 
    die("Warning count is %u but didn't get any warnings", count);
4774
 
 
4775
 
  append_result(ds, &warn_res);
4776
 
  drizzle_result_free(&warn_res);
4777
 
 
4778
 
  return(count);
 
4452
  uint32_t count= drizzle_result_warning_count(&res.b_);
 
4453
  if (!count)
 
4454
    return 0;
 
4455
 
 
4456
  drizzle::result_c warn_res;
 
4457
  dt_query(con, warn_res, "show warnings");
 
4458
  append_result(&ds, warn_res);
 
4459
  return count;
4779
4460
}
4780
4461
 
4781
4462
 
4792
4473
  ds    output buffer where to store result form query
4793
4474
*/
4794
4475
 
4795
 
static void run_query_normal(st_connection *cn,
 
4476
static void run_query_normal(st_connection& cn,
4796
4477
                             st_command* command,
4797
4478
                             int flags, char *query, int query_len,
4798
 
                             string *ds, string *ds_warnings)
 
4479
                             string *ds, string& ds_warnings)
4799
4480
{
4800
 
  drizzle_result_st res;
4801
4481
  drizzle_return_t ret;
4802
 
  drizzle_con_st *con= &cn->con;
 
4482
  drizzle_con_st *con= cn;
4803
4483
  int err= 0;
4804
4484
 
4805
4485
  drizzle_con_add_options(con, DRIZZLE_CON_NO_RESULT_READ);
4806
4486
 
 
4487
  drizzle::result_c res;
4807
4488
  if (flags & QUERY_SEND_FLAG)
4808
4489
  {
4809
4490
    /*
4810
4491
     * Send the query
4811
4492
     */
4812
4493
 
4813
 
    (void) drizzle_query(con, &res, query, query_len, &ret);
 
4494
    (void) drizzle_query(con, &res.b_, query, query_len, &ret);
4814
4495
    if (ret != DRIZZLE_RETURN_OK)
4815
4496
    {
4816
4497
      if (ret == DRIZZLE_RETURN_ERROR_CODE ||
4817
4498
          ret == DRIZZLE_RETURN_HANDSHAKE_FAILED)
4818
4499
      {
4819
 
        err= drizzle_result_error_code(&res);
4820
 
        handle_error(command, err, drizzle_result_error(&res),
4821
 
                     drizzle_result_sqlstate(&res), ds);
4822
 
        if (ret == DRIZZLE_RETURN_ERROR_CODE)
4823
 
          drizzle_result_free(&res);
 
4500
        err= res.error_code();
 
4501
        handle_error(command, err, res.error(), drizzle_result_sqlstate(&res.b_), ds);
4824
4502
      }
4825
4503
      else
4826
4504
      {
4837
4515
    /*
4838
4516
     * Read the result packet
4839
4517
     */
4840
 
    if (drizzle_result_read(con, &res, &ret) == NULL ||
 
4518
    if (drizzle_result_read(con, &res.b_, &ret) == NULL ||
4841
4519
        ret != DRIZZLE_RETURN_OK)
4842
4520
    {
4843
4521
      if (ret == DRIZZLE_RETURN_ERROR_CODE)
4844
4522
      {
4845
 
        handle_error(command, drizzle_result_error_code(&res),
4846
 
                     drizzle_result_error(&res), drizzle_result_sqlstate(&res),
4847
 
                     ds);
 
4523
        handle_error(command, res.error_code(), res.error(), drizzle_result_sqlstate(&res.b_), ds);
4848
4524
      }
4849
4525
      else
4850
4526
        handle_error(command, ret, drizzle_con_error(con), "", ds);
4851
 
      drizzle_result_free(&res);
4852
4527
      err= ret;
4853
4528
      goto end;
4854
4529
    }
4856
4531
    /*
4857
4532
      Store the result of the query if it will return any fields
4858
4533
    */
4859
 
    if (drizzle_result_column_count(&res) &&
4860
 
        (ret= drizzle_result_buffer(&res)) != DRIZZLE_RETURN_OK)
 
4534
    if (res.column_count() &&
 
4535
        (ret= drizzle_result_buffer(&res.b_)) != DRIZZLE_RETURN_OK)
4861
4536
    {
4862
4537
      if (ret == DRIZZLE_RETURN_ERROR_CODE)
4863
4538
      {
4864
 
        handle_error(command, drizzle_result_error_code(&res),
4865
 
                     drizzle_result_error(&res), drizzle_result_sqlstate(&res),
4866
 
                     ds);
 
4539
        handle_error(command, res.error_code(), res.error(), drizzle_result_sqlstate(&res.b_), ds);
4867
4540
      }
4868
4541
      else
4869
4542
        handle_error(command, ret, drizzle_con_error(con), "", ds);
4870
 
      drizzle_result_free(&res);
4871
4543
      err= ret;
4872
4544
      goto end;
4873
4545
    }
4876
4548
    {
4877
4549
      uint64_t affected_rows= 0;    /* Ok to be undef if 'disable_info' is set */
4878
4550
 
4879
 
      if (drizzle_result_column_count(&res))
 
4551
      if (res.column_count())
4880
4552
      {
4881
4553
        if (display_metadata)
4882
 
          append_metadata(ds, &res);
 
4554
          append_metadata(ds, res);
4883
4555
 
4884
4556
        if (!display_result_vertically)
4885
 
          append_table_headings(ds, &res);
 
4557
          append_table_headings(*ds, res);
4886
4558
 
4887
 
        append_result(ds, &res);
 
4559
        append_result(ds, res);
4888
4560
      }
4889
4561
 
4890
4562
      /*
4892
4564
        query to find the warnings
4893
4565
      */
4894
4566
      if (!disable_info)
4895
 
        affected_rows= drizzle_result_affected_rows(&res);
 
4567
        affected_rows= drizzle_result_affected_rows(&res.b_);
4896
4568
 
4897
4569
      /*
4898
4570
        Add all warnings to the result. We can't do this if we are in
4902
4574
      if (!disable_warnings)
4903
4575
      {
4904
4576
        drizzle_con_remove_options(con, DRIZZLE_CON_NO_RESULT_READ);
4905
 
        if (append_warnings(ds_warnings, con, &res) || ds_warnings->length())
 
4577
        if (append_warnings(ds_warnings, cn, res) || not ds_warnings.empty())
4906
4578
        {
4907
4579
          ds->append("Warnings:\n", 10);
4908
 
          ds->append(ds_warnings->c_str(), ds_warnings->length());
 
4580
          *ds += ds_warnings;
4909
4581
        }
4910
4582
      }
4911
4583
 
4912
4584
      if (!disable_info)
4913
 
        append_info(ds, affected_rows, drizzle_result_info(&res));
 
4585
        append_info(ds, affected_rows, drizzle_result_info(&res.b_));
4914
4586
    }
4915
4587
 
4916
 
    drizzle_result_free(&res);
4917
4588
  }
4918
4589
 
4919
4590
  /* If we come here the query is both executed and read successfully */
4928
4599
  */
4929
4600
  drizzle_con_remove_options(con, DRIZZLE_CON_NO_RESULT_READ);
4930
4601
  var_set_errno(err);
4931
 
  return;
4932
4602
}
4933
4603
 
4934
4604
 
4952
4622
                  unsigned int err_errno, const char *err_error,
4953
4623
                  const char *err_sqlstate, string *ds)
4954
4624
{
4955
 
  uint32_t i;
4956
 
 
4957
 
 
4958
4625
  if (! command->require_file.empty())
4959
4626
  {
4960
4627
    /*
4963
4630
      abort_not_supported_test
4964
4631
    */
4965
4632
    if (err_errno == DRIZZLE_RETURN_SERVER_GONE)
4966
 
      die("require query '%s' failed: %d: %s", command->query,
4967
 
          err_errno, err_error);
 
4633
      die("require query '%s' failed: %d: %s", command->query, err_errno, err_error);
4968
4634
 
4969
4635
    /* Abort the run of this test, pass the failed query as reason */
4970
 
    abort_not_supported_test("Query '%s' failed, required functionality " \
4971
 
                             "not supported", command->query);
 
4636
    abort_not_supported_test("Query '%s' failed, required functionality not supported", command->query);
4972
4637
  }
4973
4638
 
4974
4639
  if (command->abort_on_error)
4975
4640
    die("query '%s' failed: %d: %s", command->query, err_errno, err_error);
4976
4641
 
4977
 
  for (i= 0 ; (uint32_t) i < command->expected_errors.count ; i++)
 
4642
  uint32_t i= 0;
 
4643
  for (; i < command->expected_errors.count; i++)
4978
4644
  {
4979
4645
    if (((command->expected_errors.err[i].type == ERR_ERRNO) &&
4980
4646
         (command->expected_errors.err[i].code.errnum == err_errno)) ||
5024
4690
          command->query, err_sqlstate, err_error,
5025
4691
          command->expected_errors.err[0].code.sqlstate);
5026
4692
  }
5027
 
 
5028
 
  return;
5029
4693
}
5030
4694
 
5031
4695
 
5042
4706
 
5043
4707
void handle_no_error(st_command* command)
5044
4708
{
5045
 
 
5046
 
 
5047
4709
  if (command->expected_errors.err[0].type == ERR_ERRNO &&
5048
4710
      command->expected_errors.err[0].code.errnum != 0)
5049
4711
  {
5050
4712
    /* Error code we wanted was != 0, i.e. not an expected success */
5051
 
    die("query '%s' succeeded - should have failed with errno %d...",
5052
 
        command->query, command->expected_errors.err[0].code.errnum);
 
4713
    die("query '%s' succeeded - should have failed with errno %d...", command->query, command->expected_errors.err[0].code.errnum);
5053
4714
  }
5054
4715
  else if (command->expected_errors.err[0].type == ERR_SQLSTATE &&
5055
4716
           strcmp(command->expected_errors.err[0].code.sqlstate,"00000") != 0)
5056
4717
  {
5057
4718
    /* SQLSTATE we wanted was != "00000", i.e. not an expected success */
5058
 
    die("query '%s' succeeded - should have failed with sqlstate %s...",
5059
 
        command->query, command->expected_errors.err[0].code.sqlstate);
 
4719
    die("query '%s' succeeded - should have failed with sqlstate %s...", command->query, command->expected_errors.err[0].code.sqlstate);
5060
4720
  }
5061
 
 
5062
 
  return;
5063
4721
}
5064
4722
 
5065
4723
 
5076
4734
  is on the result will be read - for regular query, both bits must be on
5077
4735
*/
5078
4736
 
5079
 
static void run_query(st_connection *cn,
 
4737
static void run_query(st_connection& cn,
5080
4738
                      st_command* command,
5081
4739
                      int flags)
5082
4740
{
5083
 
  string *ds= NULL;
5084
 
  string *save_ds= NULL;
5085
 
  string ds_result;
5086
 
  string ds_sorted;
5087
 
  string ds_warnings;
5088
4741
  string eval_query;
5089
4742
  char *query;
5090
4743
  int query_len;
5114
4767
    Create a temporary dynamic string to contain the output from
5115
4768
    this query.
5116
4769
  */
5117
 
  if (! command->require_file.empty())
5118
 
  {
5119
 
    ds= &ds_result;
5120
 
  }
5121
 
  else
5122
 
  {
5123
 
    ds= &ds_res;
5124
 
  }
 
4770
  string ds_result;
 
4771
  string* ds= command->require_file.empty() ? &ds_res : &ds_result;
5125
4772
  /*
5126
4773
    Log the query into the output buffer
5127
4774
  */
5128
4775
  if (!disable_query_log && (flags & QUERY_SEND_FLAG))
5129
4776
  {
5130
 
    replace_append_mem(ds, query, query_len);
 
4777
    replace_append_mem(*ds, query, query_len);
5131
4778
    ds->append(delimiter, delimiter_length);
5132
4779
    ds->append("\n");
5133
4780
  }
5134
4781
 
 
4782
  string* save_ds= NULL;
 
4783
  string ds_sorted;
5135
4784
  if (display_result_sorted)
5136
4785
  {
5137
4786
    /*
5147
4796
    Always run with normal C API if it's not a complete
5148
4797
    SEND + REAP
5149
4798
  */
5150
 
  run_query_normal(cn, command, flags, query, query_len,
5151
 
                   ds, &ds_warnings);
 
4799
  string ds_warnings;
 
4800
  run_query_normal(cn, command, flags, query, query_len, ds, ds_warnings);
5152
4801
 
5153
4802
  if (display_result_sorted)
5154
4803
  {
5155
4804
    /* Sort the result set and append it to result */
5156
 
    append_sorted(save_ds, &ds_sorted);
 
4805
    append_sorted(*save_ds, ds_sorted);
5157
4806
    ds= save_ds;
5158
4807
  }
5159
4808
 
5163
4812
       and the output should be checked against an already
5164
4813
       existing file which has been specified using --require or --result
5165
4814
    */
5166
 
    check_require(ds, command->require_file);
 
4815
    check_require(*ds, command->require_file);
5167
4816
  }
5168
 
 
5169
 
  return;
5170
4817
}
5171
4818
 
5172
4819
 
5173
4820
/****************************************************************************/
5174
4821
 
5175
 
static void get_command_type(struct st_command* command)
 
4822
static void get_command_type(st_command* command)
5176
4823
{
5177
 
  char save;
5178
 
  uint32_t type;
5179
 
 
5180
 
 
5181
4824
  if (*command->query == '}')
5182
4825
  {
5183
4826
    command->type = Q_END_BLOCK;
5184
4827
    return;
5185
4828
  }
5186
4829
 
5187
 
  save= command->query[command->first_word_len];
 
4830
  char save= command->query[command->first_word_len];
5188
4831
  command->query[command->first_word_len]= 0;
5189
 
  type= command_typelib.find_type(command->query, TYPELIB::e_default);
 
4832
  uint32_t type= command_typelib.find_type(command->query, TYPELIB::e_default);
5190
4833
  command->query[command->first_word_len]= save;
5191
4834
  if (type > 0)
5192
4835
  {
5239
4882
  }
5240
4883
 
5241
4884
  /* Set expected error on command */
5242
 
  memcpy(&command->expected_errors, &saved_expected_errors,
5243
 
         sizeof(saved_expected_errors));
5244
 
  command->abort_on_error= (command->expected_errors.count == 0 &&
5245
 
                            abort_on_error);
5246
 
 
5247
 
  return;
 
4885
  memcpy(&command->expected_errors, &saved_expected_errors, sizeof(saved_expected_errors));
 
4886
  command->abort_on_error= (command->expected_errors.count == 0 && abort_on_error);
5248
4887
}
5249
4888
 
5250
4889
 
5258
4897
 
5259
4898
*/
5260
4899
 
5261
 
static void mark_progress(struct st_command*, int line)
 
4900
static void mark_progress(st_command*, int line)
5262
4901
{
5263
4902
  uint64_t timer= timer_now();
5264
4903
  if (!progress_start)
5316
4955
{
5317
4956
try
5318
4957
{
5319
 
  st_command* command;
5320
4958
  bool q_send_flag= 0, abort_flag= 0;
5321
4959
  uint32_t command_executed= 0, last_command_executed= 0;
5322
 
  string save_file("");
5323
 
  struct stat res_info;
 
4960
  string save_file;
5324
4961
 
5325
4962
  TMPDIR[0]= 0;
5326
4963
 
5444
5081
  /* Init expected errors */
5445
5082
  memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));
5446
5083
 
5447
 
  /* Init g_connections */
5448
 
  memset(g_connections, 0, sizeof(g_connections));
5449
 
  next_con= g_connections + 1;
5450
 
 
5451
5084
  /* Init file stack */
5452
5085
  memset(file_stack.data(), 0, sizeof(file_stack));
5453
5086
  cur_file= file_stack.data();
5596
5229
    cur_file->file_name= strdup("<stdin>");
5597
5230
    cur_file->lineno= 1;
5598
5231
  }
5599
 
  cur_con= g_connections;
5600
 
  if ((cur_con->drizzle= drizzle_create(NULL)) == NULL)
5601
 
    die("Failed in drizzle_create()");
5602
 
  if (!( drizzle_con_create(cur_con->drizzle, &cur_con->con)))
5603
 
    die("Failed in drizzle_con_create()");
5604
 
  drizzle_con_add_options(&cur_con->con, use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
5605
 
 
5606
 
  cur_con->name = strdup("default");
5607
 
  safe_connect(&cur_con->con, cur_con->name, opt_host, opt_user, opt_pass,
5608
 
               opt_db, opt_port);
 
5232
  cur_con= safe_connect("default", opt_host, opt_user, opt_pass, opt_db, opt_port);
 
5233
  g_connections["default"] = cur_con;
5609
5234
 
5610
5235
  fill_global_error_names();
5611
5236
 
5620
5245
  var_set_errno(-1);
5621
5246
 
5622
5247
  /* Update $drizzleclient_get_server_version to that of current connection */
5623
 
  var_set_drizzleclient_get_server_version(&cur_con->con);
 
5248
  var_set_drizzleclient_get_server_version(*cur_con);
5624
5249
 
5625
5250
  if (! opt_include.empty())
5626
5251
  {
5627
5252
    open_file(opt_include.c_str());
5628
5253
  }
5629
5254
 
 
5255
  st_command* command;
5630
5256
  while (!read_command(&command) && !abort_flag)
5631
5257
  {
5632
5258
    int current_line_inc = 1, processed = 0;
5743
5369
          command->require_file= save_file;
5744
5370
          save_file.clear();
5745
5371
        }
5746
 
        run_query(cur_con, command, flags);
 
5372
        run_query(*cur_con, command, flags);
5747
5373
        command_executed++;
5748
5374
        command->last_argument= command->end;
5749
5375
 
5773
5399
          the query and read the result some time later when reap instruction
5774
5400
          is given on this connection.
5775
5401
        */
5776
 
        run_query(cur_con, command, QUERY_SEND_FLAG);
 
5402
        run_query(*cur_con, command, QUERY_SEND_FLAG);
5777
5403
        command_executed++;
5778
5404
        command->last_argument= command->end;
5779
5405
        break;
5809
5435
        break;
5810
5436
      case Q_PING:
5811
5437
        {
5812
 
          drizzle_result_st result;
 
5438
          drizzle::result_c result;
5813
5439
          drizzle_return_t ret;
5814
 
          (void) drizzle_ping(&cur_con->con, &result, &ret);
5815
 
          if (ret == DRIZZLE_RETURN_OK || ret == DRIZZLE_RETURN_ERROR_CODE)
5816
 
            drizzle_result_free(&result);
 
5440
          (void) drizzle_ping(*cur_con, &result.b_, &ret);
5817
5441
        }
5818
5442
        break;
5819
5443
      case Q_EXEC:
5832
5456
        do_set_charset(command);
5833
5457
        break;
5834
5458
      case Q_DISABLE_RECONNECT:
5835
 
        set_reconnect(&cur_con->con, 0);
 
5459
        set_reconnect(*cur_con, 0);
5836
5460
        break;
5837
5461
      case Q_ENABLE_RECONNECT:
5838
 
        set_reconnect(&cur_con->con, 1);
 
5462
        set_reconnect(*cur_con, 1);
5839
5463
        break;
5840
5464
      case Q_DISABLE_PARSING:
5841
5465
        if (parsing_disabled == 0)
5928
5552
  */
5929
5553
  if (ds_res.length())
5930
5554
  {
5931
 
    if (! result_file_name.empty())
 
5555
    if (not result_file_name.empty())
5932
5556
    {
5933
5557
      /* A result file has been specified */
5934
5558
 
5943
5567
           - detect missing result file
5944
5568
           - detect zero size result file
5945
5569
        */
5946
 
        check_result(&ds_res);
 
5570
        check_result(ds_res);
5947
5571
      }
5948
5572
    }
5949
5573
    else
5957
5581
    die("The test didn't produce any output");
5958
5582
  }
5959
5583
 
5960
 
  if (!command_executed &&
5961
 
      ! result_file_name.empty() && !stat(result_file_name.c_str(), &res_info))
 
5584
  struct stat res_info;
 
5585
  if (!command_executed && not result_file_name.empty() && not stat(result_file_name.c_str(), &res_info))
5962
5586
  {
5963
5587
    /*
5964
5588
      my_stat() successful on result file. Check if we have not run a
6085
5709
 
6086
5710
void free_replace_column()
6087
5711
{
6088
 
  for (uint32_t i= 0 ; i < max_replace_column; i++)
 
5712
  for (uint32_t i= 0; i < max_replace_column; i++)
6089
5713
  {
6090
5714
    free(replace_column[i]);
6091
5715
    replace_column[i]= 0;
6125
5749
struct st_replace *init_replace(const char **from, const char **to, uint32_t count,
6126
5750
                                char *word_end_chars);
6127
5751
 
6128
 
void replace_strings_append(struct st_replace *rep, string* ds,
6129
 
                            const char *from, int len);
 
5752
void replace_strings_append(struct st_replace *rep, string& ds, const char *from, int len);
6130
5753
 
6131
5754
st_replace *glob_replace= NULL;
6132
5755
// boost::scoped_ptr<st_replace> glob_replace;
6206
5829
} REPLACE_STRING;
6207
5830
 
6208
5831
 
6209
 
void replace_strings_append(REPLACE *rep, string* ds,
6210
 
                            const char *str, int len)
 
5832
void replace_strings_append(REPLACE *rep, string& ds, const char *str, int len)
6211
5833
{
6212
 
  REPLACE *rep_pos;
6213
5834
  REPLACE_STRING *rep_str;
6214
 
  const char *start, *from;
6215
 
 
6216
 
 
6217
 
  start= from= str;
6218
 
  rep_pos=rep+1;
 
5835
  const char* start= str;
 
5836
  const char* from= str;
 
5837
 
 
5838
  REPLACE* rep_pos=rep+1;
6219
5839
  for (;;)
6220
5840
  {
6221
5841
    /* Loop through states */
6226
5846
    if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string)
6227
5847
    {
6228
5848
      /* No match found */
6229
 
      ds->append(start, from - start - 1);
 
5849
      ds.append(start, from - start - 1);
6230
5850
      return;
6231
5851
    }
6232
5852
 
6233
5853
    /* Append part of original string before replace string */
6234
 
    ds->append(start, (from - rep_str->to_offset) - start);
 
5854
    ds.append(start, (from - rep_str->to_offset) - start);
6235
5855
 
6236
5856
    /* Append replace string */
6237
 
    ds->append(rep_str->replace_string,
6238
 
               strlen(rep_str->replace_string));
 
5857
    ds.append(rep_str->replace_string, strlen(rep_str->replace_string));
6239
5858
 
6240
5859
    if (!*(from-=rep_str->from_offset) && rep_pos->found != 2)
6241
5860
      return;
6640
6259
 
6641
6260
static bool start_at_word(const char *pos)
6642
6261
{
6643
 
  return ((!memcmp(pos, "\\b",2) && pos[2]) || !memcmp(pos, "\\^", 2));
 
6262
  return (!memcmp(pos, "\\b",2) && pos[2]) || !memcmp(pos, "\\^", 2);
6644
6263
}
6645
6264
 
6646
6265
static bool end_of_word(const char *pos)
6663
6282
  char *to_pos, **to_array;
6664
6283
 
6665
6284
  /* Count number of states */
6666
 
  for (i=result_len=max_length=0 , states=2 ; i < count ; i++)
 
6285
  for (i=result_len=max_length=0 , states=2; i < count; i++)
6667
6286
  {
6668
6287
    len=replace_len(from[i]);
6669
6288
    if (!len)
6677
6296
      max_length=len;
6678
6297
  }
6679
6298
  memset(is_word_end, 0, sizeof(is_word_end));
6680
 
  for (i=0 ; word_end_chars[i] ; i++)
 
6299
  for (i=0; word_end_chars[i]; i++)
6681
6300
    is_word_end[(unsigned char) word_end_chars[i]]=1;
6682
6301
 
6683
6302
  REP_SETS sets;
6724
6343
        start_states->internal_set_bit(states);
6725
6344
    }
6726
6345
    const char *pos;
6727
 
    for (pos= from[i], len=0; *pos ; pos++)
 
6346
    for (pos= from[i], len=0; *pos; pos++)
6728
6347
    {
6729
6348
      if (*pos == '\\' && *(pos+1))
6730
6349
      {
6767
6386
  }
6768
6387
 
6769
6388
 
6770
 
  for (set_nr=0; set_nr < sets.count ; set_nr++)
 
6389
  for (set_nr=0; set_nr < sets.count; set_nr++)
6771
6390
  {
6772
6391
    set=sets.set+set_nr;
6773
6392
    default_state= 0;        /* Start from beginning */
6774
6393
 
6775
6394
    /* If end of found-string not found or start-set with current set */
6776
6395
 
6777
 
    for (i= UINT32_MAX; (i= set->get_next_bit(i)) ;)
 
6396
    for (i= UINT32_MAX; (i= set->get_next_bit(i));)
6778
6397
    {
6779
6398
      if (!follow[i].chr && !default_state)
6780
6399
        default_state= find_found(&found_set.front(), set->table_offset, set->found_offset+1);
6785
6404
 
6786
6405
    /* Find all chars that follows current sets */
6787
6406
    memset(used_chars, 0, sizeof(used_chars));
6788
 
    for (i= UINT32_MAX; (i= sets.set[used_sets].get_next_bit(i)) ;)
 
6407
    for (i= UINT32_MAX; (i= sets.set[used_sets].get_next_bit(i));)
6789
6408
    {
6790
6409
      used_chars[follow[i].chr]=1;
6791
6410
      if ((follow[i].chr == SPACE_CHAR && !follow[i+1].chr &&
6795
6414
 
6796
6415
    /* Mark word_chars used if \b is in state */
6797
6416
    if (used_chars[SPACE_CHAR])
6798
 
      for (const char *pos= word_end_chars ; *pos ; pos++)
 
6417
      for (const char *pos= word_end_chars; *pos; pos++)
6799
6418
        used_chars[(int) (unsigned char) *pos] = 1;
6800
6419
 
6801
6420
    /* Handle other used characters */
6802
 
    for (chr= 0 ; chr < 256 ; chr++)
 
6421
    for (chr= 0; chr < 256; chr++)
6803
6422
    {
6804
6423
      if (! used_chars[chr])
6805
6424
        set->next[chr]= chr ? default_state : -1;
6812
6431
        new_set->found_offset=set->found_offset+1;
6813
6432
        found_end=0;
6814
6433
 
6815
 
        for (i= UINT32_MAX ; (i= sets.set[used_sets].get_next_bit(i)) ; )
 
6434
        for (i= UINT32_MAX; (i= sets.set[used_sets].get_next_bit(i));)
6816
6435
        {
6817
6436
          if (!follow[i].chr || follow[i].chr == chr ||
6818
6437
              (follow[i].chr == SPACE_CHAR &&
6833
6452
        {
6834
6453
          new_set->found_len=0;      /* Set for testing if first */
6835
6454
          bits_set=0;
6836
 
          for (i= UINT32_MAX; (i= new_set->get_next_bit(i)) ;)
 
6455
          for (i= UINT32_MAX; (i= new_set->get_next_bit(i));)
6837
6456
          {
6838
6457
            if ((follow[i].chr == SPACE_CHAR ||
6839
6458
                 follow[i].chr == END_OF_LINE) && ! chr)
6882
6501
    rep_str=(REPLACE_STRING*) (replace+sets.count);
6883
6502
    to_array= (char **) (rep_str+found_sets+1);
6884
6503
    to_pos=(char *) (to_array+count);
6885
 
    for (i=0 ; i < count ; i++)
 
6504
    for (i=0; i < count; i++)
6886
6505
    {
6887
6506
      to_array[i]=to_pos;
6888
6507
      to_pos=strcpy(to_pos,to[i])+strlen(to[i])+1;
6889
6508
    }
6890
6509
    rep_str[0].found=1;
6891
6510
    rep_str[0].replace_string=0;
6892
 
    for (i=1 ; i <= found_sets ; i++)
 
6511
    for (i=1; i <= found_sets; i++)
6893
6512
    {
6894
6513
      const char *pos= from[found_set[i-1].table_offset];
6895
6514
      rep_str[i].found= !memcmp(pos, "\\^", 3) ? 2 : 1;
6897
6516
      rep_str[i].to_offset= found_set[i-1].found_offset-start_at_word(pos);
6898
6517
      rep_str[i].from_offset= found_set[i-1].found_offset-replace_len(pos) + end_of_word(pos);
6899
6518
    }
6900
 
    for (i=0 ; i < sets.count ; i++)
 
6519
    for (i=0; i < sets.count; i++)
6901
6520
    {
6902
 
      for (j=0 ; j < 256 ; j++)
 
6521
      for (j=0; j < 256; j++)
6903
6522
        if (sets.set[i].next[j] >= 0)
6904
6523
          replace[i].next[j]=replace+sets.set[i].next[j];
6905
6524
        else
6983
6602
 
6984
6603
void REP_SET::or_bits(const REP_SET *from)
6985
6604
{
6986
 
  for (uint32_t i= 0 ; i < size_of_bits; i++)
 
6605
  for (uint32_t i= 0; i < size_of_bits; i++)
6987
6606
    bits[i]|=from->bits[i];
6988
6607
}
6989
6608
 
7093
6712
    if (new_pos != pa->str)
7094
6713
    {
7095
6714
      ptrdiff_t diff= PTR_BYTE_DIFF(new_pos,pa->str);
7096
 
      for (i=0 ; i < pa->typelib.count ; i++)
 
6715
      for (i=0; i < pa->typelib.count; i++)
7097
6716
        pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff,
7098
6717
                                              char*);
7099
6718
      pa->str=new_pos;
7133
6752
/* Functions that uses replace and replace_regex */
7134
6753
 
7135
6754
/* Append the string to ds, with optional replace */
7136
 
void replace_append_mem(string *ds, const char *val, int len)
 
6755
void replace_append_mem(string& ds, const char *val, int len)
7137
6756
{
7138
6757
  char *v= strdup(val);
7139
6758
 
7148
6767
    replace_strings_append(glob_replace, ds, v, len);
7149
6768
  }
7150
6769
  else
7151
 
    ds->append(v, len);
 
6770
    ds.append(v, len);
7152
6771
}
7153
6772
 
7154
6773
 
7155
6774
/* Append zero-terminated string to ds, with optional replace */
7156
6775
void replace_append(string *ds, const char *val)
7157
6776
{
7158
 
  replace_append_mem(ds, val, strlen(val));
 
6777
  replace_append_mem(*ds, val, strlen(val));
7159
6778
}
7160
6779
 
7161
6780
/* Append uint32_t to ds, with optional replace */
7163
6782
{
7164
6783
  ostringstream buff;
7165
6784
  buff << val;
7166
 
  replace_append_mem(ds, buff.str().c_str(), buff.str().size());
 
6785
  replace_append_mem(*ds, buff.str().c_str(), buff.str().size());
7167
6786
 
7168
6787
}
7169
6788
 
7182
6801
*/
7183
6802
 
7184
6803
 
7185
 
void append_sorted(string* ds, string *ds_input)
 
6804
void append_sorted(string& ds, const string& ds_input)
7186
6805
{
7187
6806
  priority_queue<string, vector<string>, greater<string> > lines;
7188
6807
 
7189
 
  if (ds_input->empty())
 
6808
  if (ds_input.empty())
7190
6809
    return;  /* No input */
7191
6810
 
7192
 
  unsigned long eol_pos= 0;
7193
 
 
7194
 
  eol_pos= ds_input->find_first_of('\n', 0);
 
6811
  unsigned long eol_pos= ds_input.find_first_of('\n', 0);
7195
6812
  if (eol_pos == string::npos)
7196
6813
    return; // We should have at least one header here
7197
6814
 
7198
 
  ds->append(ds_input->substr(0, eol_pos+1));
 
6815
  ds.append(ds_input.substr(0, eol_pos+1));
7199
6816
 
7200
6817
  unsigned long start_pos= eol_pos+1;
7201
6818
 
7202
6819
  /* Insert line(s) in array */
7203
6820
  do {
7204
6821
 
7205
 
    eol_pos= ds_input->find_first_of('\n', start_pos);
 
6822
    eol_pos= ds_input.find_first_of('\n', start_pos);
7206
6823
    /* Find end of line */
7207
 
    lines.push(ds_input->substr(start_pos, eol_pos-start_pos+1));
 
6824
    lines.push(ds_input.substr(start_pos, eol_pos-start_pos+1));
7208
6825
    start_pos= eol_pos+1;
7209
6826
 
7210
6827
  } while ( eol_pos != string::npos);
7211
6828
 
7212
6829
  /* Create new result */
7213
 
  while (!lines.empty()) {
7214
 
    ds->append(lines.top());
 
6830
  while (!lines.empty()) 
 
6831
  {
 
6832
    ds.append(lines.top());
7215
6833
    lines.pop();
7216
6834
  }
7217
 
 
7218
 
  return;
7219
6835
}
7220
6836
 
7221
6837
static void free_all_replace()