~drizzle-trunk/drizzle/jenkins-Drizzle-Builder-213

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Brian Aker
  • Date: 2011-08-16 01:07:54 UTC
  • mfrom: (2363.1.8 drizzle-trunk)
  • mto: This revision was merged to the branch mainline in revision 2399.
  • Revision ID: brian@tangent.org-20110816010754-14sxcxr7r9jczh6a
Fixes for --help work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
204
204
 
205
205
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names) - 1, "", tx_isolation_names, NULL};
206
206
 
207
 
/*
208
 
  Used with --help for detailed option
209
 
*/
210
 
bool opt_help= false;
211
 
 
212
207
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
213
208
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
214
209
 {&Arg_comparator::compare_real,       &Arg_comparator::compare_e_real},
356
351
static void get_options();
357
352
static void fix_paths();
358
353
 
359
 
static void usage();
360
354
void close_connections();
361
355
 
362
356
fs::path base_plugin_dir(PKGPLUGINDIR);
363
357
 
 
358
po::options_description general_options(_("General Options"));
364
359
po::options_description config_options(_("Config File Options"));
365
360
po::options_description long_options(_("Kernel Options"));
366
361
po::options_description plugin_load_options(_("Plugin Loading Options"));
383
378
  return g_hostname;
384
379
}
385
380
 
 
381
static void print_version()
 
382
{
 
383
  /*
 
384
    Note: the instance manager keys off the string 'Ver' so it can find the
 
385
    version from the output of 'drizzled --version', so don't change it!
 
386
  */
 
387
  printf("%s  Ver %s for %s-%s on %s (%s)\n", internal::my_progname,
 
388
         PANDORA_RELEASE_VERSION, HOST_VENDOR, HOST_OS, HOST_CPU, COMPILATION_COMMENT);
 
389
}
 
390
 
386
391
/****************************************************************************
387
392
** Code to end drizzled
388
393
****************************************************************************/
454
459
  }
455
460
}
456
461
 
457
 
 
458
 
void unireg_abort(int exit_code)
459
 
{
460
 
  if (exit_code)
461
 
  {
462
 
    errmsg_printf(error::ERROR, _("Aborting"));
463
 
  }
464
 
  else if (opt_help)
465
 
  {
466
 
    usage();
467
 
  }
468
 
 
469
 
  clean_up(!opt_help && exit_code);
470
 
  internal::my_end();
471
 
  exit(exit_code);
 
462
static bool unireg_startup_completed= false;
 
463
void unireg_startup_finished()
 
464
{
 
465
  unireg_startup_completed= true;
 
466
}
 
467
 
 
468
void unireg_exit()
 
469
{
 
470
  internal::my_end();
 
471
  assert(unireg_startup_completed == false);
 
472
  exit(EXIT_SUCCESS);
 
473
}
 
474
 
 
475
void unireg_actual_abort(const char *file, int line, const char *func, const std::string& message)
 
476
{
 
477
  std::stringstream temp;
 
478
  temp << _("Aborting:") << "\"" << message << "\"" << ". Abort was called from " << file << ":" << line << " in " << func << "()";
 
479
  errmsg_printf(error::ERROR, temp.str().c_str());
 
480
 
 
481
  clean_up(vm.count("help") == 0);
 
482
  internal::my_end();
 
483
 
 
484
  assert(unireg_startup_completed == false);
 
485
  exit(EXIT_FAILURE);
472
486
}
473
487
 
474
488
 
518
532
      tmp_user_info= getpwnam(user);
519
533
      if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
520
534
          global_system_variables.log_warnings)
521
 
            errmsg_printf(error::WARN, _("One can only use the --user switch "
522
 
                            "if running as root\n"));
 
535
      {
 
536
        errmsg_printf(error::WARN, _("One can only use the --user switch if running as root"));
 
537
      }
523
538
    }
524
539
    return NULL;
525
540
  }
526
541
  if (not user)
527
542
  {
528
 
      errmsg_printf(error::ERROR, _("Fatal error: Please read \"Security\" section of "
529
 
                                    "the manual to find out how to run drizzled as root"));
530
 
    unireg_abort(1);
 
543
    unireg_abort << _("drizzled cannot be run as root, use --user to start drizzled up as another user");
531
544
  }
532
545
 
533
546
  if (not strcmp(user, "root"))
 
547
  {
534
548
    return NULL;                        // Avoid problem with dynamic libraries
 
549
  }
535
550
 
536
 
  if (!(tmp_user_info= getpwnam(user)))
 
551
  if ((tmp_user_info= getpwnam(user)) == NULL)
537
552
  {
538
553
    // Allow a numeric uid to be used
539
554
    const char *pos;
540
555
    for (pos= user; my_isdigit(&my_charset_utf8_general_ci,*pos); pos++) ;
541
556
    if (*pos)                                   // Not numeric id
542
557
      goto err;
543
 
    if (!(tmp_user_info= getpwuid(atoi(user))))
 
558
 
 
559
    if ((tmp_user_info= getpwuid(atoi(user))) == NULL)
544
560
      goto err;
545
561
  }
546
562
  return tmp_user_info;
547
563
 
548
564
err:
549
 
  errmsg_printf(error::ERROR, _("Fatal error: Can't change to run as user '%s' ;  "
550
 
                    "Please check that the user exists!\n"),user);
551
 
  unireg_abort(1);
 
565
  unireg_abort << "Fatal error: Can't change to run as user '" << user << "' ;  Please check that the user exists!";
552
566
 
553
567
#ifdef PR_SET_DUMPABLE
554
568
  if (getDebug().test(debug::CORE_ON_SIGNAL))
558
572
  }
559
573
#endif
560
574
 
561
 
/* Sun Studio 5.10 doesn't like this line.  5.9 requires it */
562
 
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x590)
563
575
  return NULL;
564
 
#endif
565
 
 
566
576
}
567
577
 
568
578
void set_user(const char *user, passwd *user_info_arg)
571
581
  initgroups(user, user_info_arg->pw_gid);
572
582
  if (setgid(user_info_arg->pw_gid) == -1)
573
583
  {
574
 
    sql_perror(_("Set process group ID failed"));
575
 
    unireg_abort(1);
 
584
    unireg_abort << _("Set process group ID failed ") << strerror(errno); 
576
585
  }
577
586
  if (setuid(user_info_arg->pw_uid) == -1)
578
587
  {
579
 
    sql_perror(_("Set process user ID failed"));
580
 
    unireg_abort(1);
 
588
    unireg_abort << _("Set process user ID failed") << strerror(errno);
581
589
  }
582
590
}
583
591
 
586
594
/** Change root user if started with @c --chroot . */
587
595
static void set_root(const char *path)
588
596
{
589
 
  if ((chroot(path) == -1) || !chdir("/"))
 
597
  if ((chroot(path) == -1) or chdir("/") == 0)
590
598
  {
591
 
    sql_perror(_("Process chroot failed"));
592
 
    unireg_abort(1);
 
599
    unireg_abort << _("Process chroot failed");
593
600
  }
594
601
}
595
602
 
688
695
  global_system_variables.auto_increment_increment= 1;
689
696
  if (in_auto_increment_increment < 1 || in_auto_increment_increment > UINT64_MAX)
690
697
  {
691
 
    cout << _("Error: Invalid Value for auto_increment_increment");
692
 
    exit(-1);
 
698
    unireg_abort << _("Invalid Value for auto_increment_increment");
693
699
  }
694
700
  global_system_variables.auto_increment_increment= in_auto_increment_increment;
695
701
}
699
705
  global_system_variables.auto_increment_offset= 1;
700
706
  if (in_auto_increment_offset < 1 || in_auto_increment_offset > UINT64_MAX)
701
707
  {
702
 
    cout << _("Error: Invalid Value for auto_increment_offset");
703
 
    exit(-1);
 
708
    unireg_abort << _("Invalid Value for auto_increment_offset");
704
709
  }
705
710
  global_system_variables.auto_increment_offset= in_auto_increment_offset;
706
711
}
710
715
  global_system_variables.completion_type= 0;
711
716
  if (in_completion_type > 2)
712
717
  {
713
 
    cout << _("Error: Invalid Value for completion_type");
714
 
    exit(-1);
 
718
    unireg_abort << _("Invalid Value for completion_type");
715
719
  }
716
720
  global_system_variables.completion_type= in_completion_type;
717
721
}
722
726
  global_system_variables.div_precincrement= 4;
723
727
  if (in_div_precincrement > DECIMAL_MAX_SCALE)
724
728
  {
725
 
    cout << _("Error: Invalid Value for div-precision-increment");
726
 
    exit(-1);
 
729
    unireg_abort << _("Invalid Value for div-precision-increment");
727
730
  }
728
731
  global_system_variables.div_precincrement= in_div_precincrement;
729
732
}
733
736
  global_system_variables.group_concat_max_len= 1024;
734
737
  if (in_group_concat_max_len > ULONG_MAX || in_group_concat_max_len < 4)
735
738
  {
736
 
    cout << _("Error: Invalid Value for group_concat_max_len");
737
 
    exit(-1);
 
739
    unireg_abort << _("Invalid Value for group_concat_max_len");
738
740
  }
739
741
  global_system_variables.group_concat_max_len= in_group_concat_max_len;
740
742
}
744
746
  global_system_variables.join_buff_size= (128*1024L);
745
747
  if (in_join_buffer_size < IO_SIZE*2 || in_join_buffer_size > ULONG_MAX)
746
748
  {
747
 
    cout << _("Error: Invalid Value for join_buffer_size");
748
 
    exit(-1);
 
749
    unireg_abort << _("Invalid Value for join_buffer_size");
749
750
  }
750
751
  in_join_buffer_size-= in_join_buffer_size % IO_SIZE;
751
752
  global_system_variables.join_buff_size= in_join_buffer_size;
756
757
  global_system_variables.max_allowed_packet= (64*1024*1024L);
757
758
  if (in_max_allowed_packet < 1024 || in_max_allowed_packet > 1024*1024L*1024L)
758
759
  {
759
 
    cout << _("Error: Invalid Value for max_allowed_packet");
760
 
    exit(-1);
 
760
    unireg_abort << _("Invalid Value for max_allowed_packet");
761
761
  }
762
762
  in_max_allowed_packet-= in_max_allowed_packet % 1024;
763
763
  global_system_variables.max_allowed_packet= in_max_allowed_packet;
768
768
  global_system_variables.max_error_count= DEFAULT_ERROR_COUNT;
769
769
  if (in_max_error_count > 65535)
770
770
  {
771
 
    cout << _("Error: Invalid Value for max_error_count");
772
 
    exit(-1);
 
771
    unireg_abort << _("Invalid Value for max_error_count");
773
772
  }
774
773
  global_system_variables.max_error_count= in_max_error_count;
775
774
}
779
778
  global_system_variables.max_heap_table_size= (16*1024*1024L);
780
779
  if (in_max_heap_table_size < 16384 || in_max_heap_table_size > MAX_MEM_TABLE_SIZE)
781
780
  {
782
 
    cout << _("Error: Invalid Value for max_heap_table_size");
783
 
    exit(-1);
 
781
    unireg_abort << _("Invalid Value for max_heap_table_size");
784
782
  }
785
783
  in_max_heap_table_size-= in_max_heap_table_size % 1024;
786
784
  global_system_variables.max_heap_table_size= in_max_heap_table_size;
791
789
  global_system_variables.min_examined_row_limit= 0;
792
790
  if (in_min_examined_row_limit > ULONG_MAX)
793
791
  {
794
 
    cout << _("Error: Invalid Value for min_examined_row_limit");
795
 
    exit(-1);
 
792
    unireg_abort << _("Invalid Value for min_examined_row_limit");
796
793
  }
797
794
  global_system_variables.min_examined_row_limit= in_min_examined_row_limit;
798
795
}
802
799
  global_system_variables.max_join_size= INT32_MAX;
803
800
  if ((uint64_t)in_max_join_size < 1 || (uint64_t)in_max_join_size > INT32_MAX)
804
801
  {
805
 
    cout << _("Error: Invalid Value for max_join_size");
806
 
    exit(-1);
 
802
    unireg_abort << _("Invalid Value for max_join_size");
807
803
  }
808
804
  global_system_variables.max_join_size= in_max_join_size;
809
805
}
813
809
  global_system_variables.max_length_for_sort_data= 1024;
814
810
  if (in_max_length_for_sort_data < 4 || in_max_length_for_sort_data > 8192*1024L)
815
811
  {
816
 
    cout << _("Error: Invalid Value for max_length_for_sort_data");
817
 
    exit(-1);
 
812
    unireg_abort << _("Invalid Value for max_length_for_sort_data");
818
813
  }
819
814
  global_system_variables.max_length_for_sort_data= in_max_length_for_sort_data;
820
815
}
824
819
  global_system_variables.max_seeks_for_key= ULONG_MAX;
825
820
  if (in_max_seeks_for_key < 1 || in_max_seeks_for_key > ULONG_MAX)
826
821
  {
827
 
    cout << _("Error: Invalid Value for max_seeks_for_key");
828
 
    exit(-1);
 
822
    unireg_abort << _("Invalid Value for max_seeks_for_key");
829
823
  }
830
824
  global_system_variables.max_seeks_for_key= in_max_seeks_for_key;
831
825
}
835
829
  global_system_variables.max_sort_length= 1024;
836
830
  if ((int64_t)in_max_sort_length < 4 || (int64_t)in_max_sort_length > 8192*1024L)
837
831
  {
838
 
    cout << _("Error: Invalid Value for max_sort_length");
839
 
    exit(-1);
 
832
    unireg_abort << _("Invalid Value for max_sort_length");
840
833
  }
841
834
  global_system_variables.max_sort_length= in_max_sort_length;
842
835
}
846
839
  global_system_variables.optimizer_search_depth= 0;
847
840
  if (in_optimizer_search_depth > MAX_TABLES + 2)
848
841
  {
849
 
    cout << _("Error: Invalid Value for optimizer_search_depth");
850
 
    exit(-1);
 
842
    unireg_abort << _("Invalid Value for optimizer_search_depth");
851
843
  }
852
844
  global_system_variables.optimizer_search_depth= in_optimizer_search_depth;
853
845
}
857
849
  global_system_variables.preload_buff_size= (32*1024L);
858
850
  if (in_preload_buff_size < 1024 || in_preload_buff_size > 1024*1024*1024L)
859
851
  {
860
 
    cout << _("Error: Invalid Value for preload_buff_size");
861
 
    exit(-1);
 
852
    unireg_abort << _("Invalid Value for preload_buff_size");
862
853
  }
863
854
  global_system_variables.preload_buff_size= in_preload_buff_size;
864
855
}
868
859
  global_system_variables.query_alloc_block_size= QUERY_ALLOC_BLOCK_SIZE;
869
860
  if (in_query_alloc_block_size < 1024)
870
861
  {
871
 
    cout << _("Error: Invalid Value for query_alloc_block_size");
872
 
    exit(-1);
 
862
    unireg_abort << _("Invalid Value for query_alloc_block_size");
873
863
  }
874
864
  in_query_alloc_block_size-= in_query_alloc_block_size % 1024;
875
865
  global_system_variables.query_alloc_block_size= in_query_alloc_block_size;
880
870
  global_system_variables.query_prealloc_size= QUERY_ALLOC_PREALLOC_SIZE;
881
871
  if (in_query_prealloc_size < QUERY_ALLOC_PREALLOC_SIZE)
882
872
  {
883
 
    cout << _("Error: Invalid Value for query_prealloc_size");
884
 
    exit(-1);
 
873
    unireg_abort << _("Invalid Value for query_prealloc_size");
885
874
  }
886
875
  in_query_prealloc_size-= in_query_prealloc_size % 1024;
887
876
  global_system_variables.query_prealloc_size= in_query_prealloc_size;
892
881
  global_system_variables.range_alloc_block_size= RANGE_ALLOC_BLOCK_SIZE;
893
882
  if (in_range_alloc_block_size < RANGE_ALLOC_BLOCK_SIZE)
894
883
  {
895
 
    cout << _("Error: Invalid Value for range_alloc_block_size");
896
 
    exit(-1);
 
884
    unireg_abort << _("Invalid Value for range_alloc_block_size");
897
885
  }
898
886
  in_range_alloc_block_size-= in_range_alloc_block_size % 1024;
899
887
  global_system_variables.range_alloc_block_size= in_range_alloc_block_size;
904
892
  global_system_variables.read_buff_size= (128*1024L);
905
893
  if (in_read_buff_size < IO_SIZE*2 || in_read_buff_size > INT32_MAX)
906
894
  {
907
 
    cout << _("Error: Invalid Value for read_buff_size");
908
 
    exit(-1);
 
895
    unireg_abort << _("Invalid Value for read_buff_size");
909
896
  }
910
897
  in_read_buff_size-= in_read_buff_size % IO_SIZE;
911
898
  global_system_variables.read_buff_size= in_read_buff_size;
916
903
  global_system_variables.read_rnd_buff_size= (256*1024L);
917
904
  if (in_read_rnd_buff_size < 64 || in_read_rnd_buff_size > UINT32_MAX)
918
905
  {
919
 
    cout << _("Error: Invalid Value for read_rnd_buff_size");
920
 
    exit(-1);
 
906
    unireg_abort << _("Invalid Value for read_rnd_buff_size");
921
907
  }
922
908
  global_system_variables.read_rnd_buff_size= in_read_rnd_buff_size;
923
909
}
927
913
  global_system_variables.sortbuff_size= MAX_SORT_MEMORY;
928
914
  if ((uint32_t)in_sortbuff_size < MIN_SORT_MEMORY)
929
915
  {
930
 
    cout << _("Error: Invalid Value for sort_buff_size");
931
 
    exit(-1);
 
916
    unireg_abort << _("Invalid Value for sort_buff_size");
932
917
  }
933
918
  global_system_variables.sortbuff_size= in_sortbuff_size;
934
919
}
938
923
  table_def_size= 128;
939
924
  if (in_table_def_size < 1 || in_table_def_size > 512*1024L)
940
925
  {
941
 
    cout << _("Error: Invalid Value for table_def_size");
942
 
    exit(-1);
 
926
    unireg_abort << _("Invalid Value for table_def_size");
943
927
  }
944
928
  table_def_size= in_table_def_size;
945
929
}
949
933
  table_cache_size= TABLE_OPEN_CACHE_DEFAULT;
950
934
  if (in_table_cache_size < TABLE_OPEN_CACHE_MIN || in_table_cache_size > 512*1024L)
951
935
  {
952
 
    cout << _("Error: Invalid Value for table_cache_size");
953
 
    exit(-1);
 
936
    unireg_abort << _("Invalid Value for table_cache_size");
954
937
  }
955
938
  table_cache_size= in_table_cache_size;
956
939
}
960
943
  table_lock_wait_timeout= 50;
961
944
  if (in_table_lock_wait_timeout < 1 || in_table_lock_wait_timeout > 1024*1024*1024)
962
945
  {
963
 
    cout << _("Error: Invalid Value for table_lock_wait_timeout");
964
 
    exit(-1);
 
946
    unireg_abort <<  _("Invalid Value for table_lock_wait_timeout");
965
947
  }
966
948
  table_lock_wait_timeout= in_table_lock_wait_timeout;
967
949
}
976
958
  global_system_variables.tmp_table_size= 16*1024*1024L;
977
959
  if (in_tmp_table_size < 1024 || in_tmp_table_size > MAX_MEM_TABLE_SIZE)
978
960
  {
979
 
    cout << _("Error: Invalid Value for table_lock_wait_timeout");
980
 
    exit(-1);
 
961
    unireg_abort << _("Invalid Value for table_lock_wait_timeout");
981
962
  }
982
963
  global_system_variables.tmp_table_size= in_tmp_table_size;
983
964
}
987
968
  transaction_message_threshold= 1024*1024;
988
969
  if ((int64_t) in_transaction_message_threshold < 128*1024 || (int64_t)in_transaction_message_threshold > 1024*1024)
989
970
  {
990
 
    cout << _("Error: Invalid Value for transaction_message_threshold valid values are between 131072 - 1048576 bytes");
991
 
    exit(-1);
 
971
    unireg_abort << _("Invalid Value for transaction_message_threshold valid values are between 131072 - 1048576 bytes");
992
972
  }
993
973
  transaction_message_threshold= in_transaction_message_threshold;
994
974
}
1024
1004
  {
1025
1005
    fs::path p(it);
1026
1006
    if (fs::is_regular_file(p))
 
1007
    {
1027
1008
      defaults_file_list.push_back(it);
 
1009
    }
1028
1010
    else
1029
1011
    {
1030
 
      errmsg_printf(error::ERROR, _("Defaults file '%s' not found\n"), it.c_str());
1031
 
      unireg_abort(1);
 
1012
      unireg_abort << "Defaults file '" << it << "' not found";
1032
1013
    }
1033
1014
  }
1034
1015
}
1035
1016
 
1036
 
int init_basic_variables(int argc, char **argv)
 
1017
bool init_variables_before_daemonizing(int argc, char **argv)
1037
1018
{
1038
1019
  umask(((~internal::my_umask) & 0666));
1039
1020
  decimal_zero.set_zero(); // set decimal_zero constant;
1041
1022
 
1042
1023
  time_t curr_time= time(NULL);
1043
1024
  if (curr_time == (time_t)-1)
1044
 
    return 1;
 
1025
  {
 
1026
    return false;
 
1027
  }
1045
1028
 
1046
1029
  max_system_variables.pseudo_thread_id= UINT32_MAX;
1047
1030
  server_start_time= flush_status_time= curr_time;
1065
1048
 
1066
1049
  system_config_dir /= "drizzle";
1067
1050
 
1068
 
  config_options.add_options()
1069
 
  ("help,?", po::value<bool>(&opt_help)->default_value(false)->zero_tokens(),
1070
 
  _("Display this help and exit."))
 
1051
  general_options.add_options()
 
1052
  ("help,?",
 
1053
  _("Display help and exit."))
1071
1054
  ("daemon,d", po::value<bool>(&opt_daemon)->default_value(false)->zero_tokens(),
1072
1055
  _("Run as a daemon."))
 
1056
  ("user,u", po::value<string>(),
 
1057
  _("Run drizzled daemon as user."))
 
1058
  ("version,V",
 
1059
  _("Print version information and exit."))
 
1060
    ;
 
1061
 
 
1062
  config_options.add_options()
1073
1063
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1074
1064
  _("Configuration file defaults are not used if no-defaults is set"))
1075
1065
  ("defaults-file", po::value<vector<string> >()->composing()->notifier(&compose_defaults_file_list),
1149
1139
  _("Default transaction isolation level."))
1150
1140
  ("transaction-message-threshold", po::value<size_t>(&transaction_message_threshold)->default_value(1024*1024)->notifier(&check_limits_transaction_message_threshold),
1151
1141
  _("Max message size written to transaction log, valid values 131072 - 1048576 bytes."))
1152
 
  ("user,u", po::value<string>(),
1153
 
  _("Run drizzled daemon as user."))
1154
 
  ("version,V",
1155
 
  _("Output version information and exit."))
1156
1142
  ("back-log", po::value<back_log_constraints>(&back_log),
1157
1143
  _("The number of outstanding connection requests Drizzle can have. This "
1158
1144
     "comes into play when the main Drizzle thread gets very many connection "
1260
1246
  full_options.add(long_options);
1261
1247
  full_options.add(plugin_load_options);
1262
1248
 
 
1249
  initial_options.add(general_options);
1263
1250
  initial_options.add(config_options);
1264
1251
  initial_options.add(plugin_load_options);
1265
1252
 
1266
1253
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
 
1254
 
1267
1255
  /* Get options about where config files and the like are */
1268
1256
  po::parsed_options parsed= po::command_line_parser(argc, argv).style(style).
1269
1257
    options(initial_options).allow_unregistered().run();
1270
 
  unknown_options=
1271
 
    po::collect_unrecognized(parsed.options, po::include_positional);
 
1258
 
 
1259
  unknown_options= po::collect_unrecognized(parsed.options, po::include_positional);
1272
1260
 
1273
1261
  try
1274
1262
  {
1276
1264
  }
1277
1265
  catch (std::exception&)
1278
1266
  {
1279
 
    errmsg_printf(error::ERROR, _("Duplicate entry for command line option\n"));
1280
 
    unireg_abort(1);
1281
 
  }
1282
 
 
1283
 
  if (not vm["no-defaults"].as<bool>())
 
1267
    unireg_abort << _("Duplicate entry for command line option");
 
1268
  }
 
1269
 
 
1270
  /* TODO: here is where we should add a process_env_vars */
 
1271
 
 
1272
  /* We need a notify here so that plugin_init will work properly */
 
1273
  try
 
1274
  {
 
1275
    po::notify(vm);
 
1276
  }
 
1277
  catch (po::validation_error &err)
 
1278
  {
 
1279
    unireg_abort << "Use --help to get a list of available options. " << err.what(); 
 
1280
  }
 
1281
 
 
1282
  if (vm.count("version"))
 
1283
  {
 
1284
    print_version();
 
1285
    unireg_exit();
 
1286
  }
 
1287
 
 
1288
  if (vm.count("no-defaults"))
1284
1289
  {
1285
1290
    fs::path system_config_file_drizzle(system_config_dir);
1286
1291
    system_config_file_drizzle /= "drizzled.cnf";
1301
1306
    }
1302
1307
  }
1303
1308
 
1304
 
  /* TODO: here is where we should add a process_env_vars */
1305
 
 
1306
 
  /* We need a notify here so that plugin_init will work properly */
1307
 
  try
1308
 
  {
1309
 
    po::notify(vm);
1310
 
  }
1311
 
  catch (po::validation_error &err)
1312
 
  {
1313
 
    errmsg_printf(error::ERROR, _("%s: %s.\nUse --help to get a list of available options\n"), internal::my_progname, err.what());
1314
 
    unireg_abort(1);
1315
 
  }
1316
 
 
1317
1309
  process_defaults_files();
1318
1310
 
1319
1311
  /* Process with notify a second time because a config file may contain
1325
1317
  }
1326
1318
  catch (po::validation_error &err)
1327
1319
  {
1328
 
    errmsg_printf(error::ERROR, _("%s: %s.\nUse --help to get a list of available options\n"), internal::my_progname, err.what());
1329
 
    unireg_abort(1);
 
1320
    unireg_abort << "Use --help to get a list of available options. " << err.what();
1330
1321
  }
1331
1322
 
1332
 
  return 0;
 
1323
  return true;
1333
1324
}
1334
1325
 
1335
 
int init_remaining_variables(module::Registry &plugins)
 
1326
// Return failure if we can't pass this, unireg_abort() will then be called
 
1327
// by the caller.
 
1328
bool init_variables_after_daemonizing(module::Registry &plugins)
1336
1329
{
1337
1330
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1338
1331
 
1344
1337
 
1345
1338
  if (plugin_init(plugins, plugin_options))
1346
1339
  {
1347
 
    errmsg_printf(error::ERROR, _("Failed to initialize plugins\n"));
1348
 
    unireg_abort(1);
 
1340
    unireg_abort << _("Failed to initialize plugins");
1349
1341
  }
1350
1342
 
1351
1343
  full_options.add(plugin_options);
1365
1357
  }
1366
1358
  catch (po::validation_error &err)
1367
1359
  {
1368
 
    errmsg_printf(error::ERROR,
1369
 
                  _("%s: %s.\n"
1370
 
                    "Use --help to get a list of available options\n"),
1371
 
                  internal::my_progname, err.what());
1372
 
    unireg_abort(1);
 
1360
    unireg_abort << "Use --help to get a list of available options. " << err.what();
1373
1361
  }
1374
1362
  catch (po::invalid_command_line_syntax &err)
1375
1363
  {
1376
 
    errmsg_printf(error::ERROR,
1377
 
                  _("%s: %s.\n"
1378
 
                    "Use --help to get a list of available options\n"),
1379
 
                  internal::my_progname, err.what());
1380
 
    unireg_abort(1);
 
1364
    unireg_abort << "Use --help to get a list of available options. " << err.what();
1381
1365
  }
1382
1366
  catch (po::unknown_option &err)
1383
1367
  {
1384
 
    errmsg_printf(error::ERROR,
1385
 
                  _("%s\nUse --help to get a list of available options\n"),
1386
 
                  err.what());
1387
 
    unireg_abort(1);
 
1368
    unireg_abort << "Use --help to get a list of available options. " << err.what();
1388
1369
  }
1389
1370
 
1390
1371
  try
1393
1374
  }
1394
1375
  catch (po::validation_error &err)
1395
1376
  {
1396
 
    errmsg_printf(error::ERROR,
1397
 
                  _("%s: %s.\n"
1398
 
                    "Use --help to get a list of available options\n"),
1399
 
                  internal::my_progname, err.what());
1400
 
    unireg_abort(1);
 
1377
    unireg_abort << "Use --help to get a list of available options. " << err.what();
1401
1378
  }
1402
1379
 
1403
1380
  get_options();
1406
1383
 
1407
1384
  global_system_variables.optimizer_prune_level= not vm.count("disable-optimizer-prune");
1408
1385
 
1409
 
  if (! vm["help"].as<bool>())
 
1386
  if ((user_info= check_user(drizzled_user)))
1410
1387
  {
1411
 
    if ((user_info= check_user(drizzled_user)))
1412
 
    {
1413
 
      set_user(drizzled_user, user_info);
1414
 
    }
 
1388
    set_user(drizzled_user, user_info);
1415
1389
  }
1416
1390
 
1417
1391
  fix_paths();
1420
1394
 
1421
1395
  item_create_init();
1422
1396
  if (sys_var_init())
1423
 
    return 1;
 
1397
  {
 
1398
    return false;
 
1399
  }
 
1400
 
1424
1401
  /* Creates static regex matching for temporal values */
1425
1402
  if (not init_temporal_formats())
1426
 
    return 1;
 
1403
  {
 
1404
    return false;
 
1405
  }
1427
1406
 
1428
 
  if (!(default_charset_info=
1429
 
        get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
 
1407
  if (!(default_charset_info= get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
1430
1408
  {
1431
1409
    errmsg_printf(error::ERROR, _("Error getting default charset"));
1432
 
    return 1;                           // Eof of the list
 
1410
    return false;                           // Eof of the list
1433
1411
  }
1434
1412
 
1435
1413
  if (vm.count("scheduler"))
 
1414
  {
1436
1415
    opt_scheduler= vm["scheduler"].as<string>().c_str();
 
1416
  }
1437
1417
 
1438
 
  if (default_collation_name)
1439
 
  {
1440
 
    const charset_info_st * const default_collation= get_charset_by_name(default_collation_name);
1441
 
    if (not default_collation)
1442
 
    {
1443
 
      errmsg_printf(error::ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
1444
 
      return 1;
1445
 
    }
1446
 
    if (not my_charset_same(default_charset_info, default_collation))
1447
 
    {
1448
 
      errmsg_printf(error::ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
1449
 
                    default_collation_name,
1450
 
                    default_charset_info->csname);
1451
 
      return 1;
1452
 
    }
1453
 
    default_charset_info= default_collation;
1454
 
  }
1455
1418
  /* Set collactions that depends on the default collation */
1456
1419
  global_system_variables.collation_server=      default_charset_info;
1457
1420
 
1459
1422
           get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
1460
1423
  {
1461
1424
    errmsg_printf(error::ERROR, _("Error setting collation"));
1462
 
    return 1;
 
1425
    return false;
1463
1426
  }
1464
1427
  global_system_variables.character_set_filesystem= character_set_filesystem;
1465
1428
 
1466
 
  if (!(my_default_lc_time_names=
1467
 
        my_locale_by_name(lc_time_names_name)))
 
1429
  if ((my_default_lc_time_names= my_locale_by_name(lc_time_names_name)) == NULL)
1468
1430
  {
1469
1431
    errmsg_printf(error::ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
1470
 
    return 1;
 
1432
    return false;
1471
1433
  }
1472
1434
  global_system_variables.lc_time_names= my_default_lc_time_names;
1473
1435
 
1474
1436
  /* Reset table_alias_charset */
1475
1437
  table_alias_charset= files_charset_info;
1476
1438
 
1477
 
  return 0;
1478
 
}
1479
 
 
 
1439
  return true;
 
1440
}
 
1441
 
 
1442
bool was_help_requested()
 
1443
{
 
1444
  if (vm.count("help") == 0)
 
1445
  {
 
1446
    return false;
 
1447
  }
 
1448
 
 
1449
  return true;
 
1450
}
 
1451
 
 
1452
void usage();
1480
1453
 
1481
1454
void init_server_components(module::Registry &plugins)
1482
1455
{
 
1456
  if (was_help_requested())
 
1457
  {
 
1458
    usage();
 
1459
  }
 
1460
 
1483
1461
  /*
1484
1462
    We need to call each of these following functions to ensure that
1485
1463
    all things are initialized so that unireg_abort() doesn't fail
1495
1473
  /* Allow storage engine to give real error messages */
1496
1474
  ha_init_errors();
1497
1475
 
1498
 
  if (opt_help)
1499
 
    unireg_abort(0);
1500
 
 
1501
1476
  if (plugin_finalize(plugins))
1502
1477
  {
1503
 
    unireg_abort(1);
 
1478
    unireg_abort << "plugin_finalize() failed";
1504
1479
  }
1505
1480
 
1506
1481
  if (plugin::Scheduler::setPlugin(opt_scheduler))
1507
1482
  {
1508
 
      errmsg_printf(error::ERROR, _("No scheduler found, cannot continue!\n"));
1509
 
      unireg_abort(1);
 
1483
    unireg_abort << _("No scheduler found");
1510
1484
  }
1511
1485
 
1512
1486
  /*
1524
1498
    plugin::StorageEngine *engine= plugin::StorageEngine::findByName(default_storage_engine_str);
1525
1499
    if (engine == NULL)
1526
1500
    {
1527
 
      errmsg_printf(error::ERROR, _("Unknown/unsupported storage engine: %s\n"), default_storage_engine_str);
1528
 
      unireg_abort(1);
 
1501
      unireg_abort << _("Unknown/unsupported storage engine: ") << default_storage_engine_str;
1529
1502
    }
1530
1503
    global_system_variables.storage_engine= engine;
1531
1504
  }
1533
1506
  if (plugin::XaResourceManager::recoverAllXids())
1534
1507
  {
1535
1508
    /* This function alredy generates error messages */
1536
 
    unireg_abort(1);
 
1509
    unireg_abort << "plugin::XaResourceManager::recoverAllXids() failed";
1537
1510
  }
1538
1511
 
1539
1512
  init_update_queries();
1611
1584
 
1612
1585
struct option my_long_options[] =
1613
1586
{
1614
 
 
1615
 
  {"help", '?', N_("Display this help and exit."),
1616
 
   (char**) &opt_help, NULL, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1617
 
   0, 0},
1618
 
  {"daemon", 'd', N_("Run as daemon."),
1619
 
   (char**) &opt_daemon, NULL, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1620
 
   0, 0},
1621
1587
  {"auto-increment-increment", OPT_AUTO_INCREMENT,
1622
1588
   N_("Auto-increment columns are incremented by this"),
1623
1589
   (char**) &global_system_variables.auto_increment_increment,
1638
1604
   N_("Chroot drizzled daemon during startup."),
1639
1605
   (char**) &drizzled_chroot, NULL, 0, GET_STR, REQUIRED_ARG,
1640
1606
   0, 0, 0, 0, 0, 0},
1641
 
  {"collation-server", OPT_DEFAULT_COLLATION,
1642
 
   N_("Set the default collation."),
1643
 
   (char**) &default_collation_name, NULL,
1644
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
1645
1607
  {"completion-type", OPT_COMPLETION_TYPE,
1646
1608
   N_("Default completion type."),
1647
1609
   (char**) &global_system_variables.completion_type,
1897
1859
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1898
1860
};
1899
1861
 
1900
 
static void print_version()
 
1862
void usage()
1901
1863
{
1902
 
  /*
1903
 
    Note: the instance manager keys off the string 'Ver' so it can find the
1904
 
    version from the output of 'drizzled --version', so don't change it!
1905
 
  */
1906
 
  printf("%s  Ver %s for %s-%s on %s (%s)\n", internal::my_progname,
1907
 
         PANDORA_RELEASE_VERSION, HOST_VENDOR, HOST_OS, HOST_CPU, COMPILATION_COMMENT);
1908
 
}
 
1864
  if ((default_charset_info= get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)) == NULL)
 
1865
  {
 
1866
    unireg_abort << "Failed to load default_charset_info:" << default_character_set_name;
 
1867
  }
1909
1868
 
1910
 
static void usage()
1911
 
{
1912
 
  if (!(default_charset_info= get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
1913
 
    exit(1);
1914
 
  if (!default_collation_name)
 
1869
  if (default_collation_name == NULL)
 
1870
  {
1915
1871
    default_collation_name= default_charset_info->name;
 
1872
  }
 
1873
 
1916
1874
  print_version();
1917
 
  puts(_("Copyright (C) 2008 Sun Microsystems\n"
 
1875
  puts(_("Copyright (C) 2010-2011 Drizzle Developers, Copyright (C) 2008 Sun Microsystems\n"
1918
1876
         "This software comes with ABSOLUTELY NO WARRANTY. "
1919
1877
         "This is free software,\n"
1920
1878
         "and you are welcome to modify and redistribute it under the GPL "
1924
1882
  printf(_("Usage: %s [OPTIONS]\n"), internal::my_progname);
1925
1883
 
1926
1884
  po::options_description all_options("Drizzled Options");
 
1885
  all_options.add(general_options);
1927
1886
  all_options.add(config_options);
1928
1887
  all_options.add(plugin_load_options);
1929
1888
  all_options.add(long_options);
1930
1889
  all_options.add(plugin_options);
1931
1890
  cout << all_options << endl;
1932
1891
 
 
1892
  unireg_exit();
1933
1893
}
1934
1894
 
1935
1895
/**
2026
1986
 
2027
1987
  if (vm.count("user"))
2028
1988
  {
2029
 
    if (! drizzled_user || ! strcmp(drizzled_user, vm["user"].as<string>().c_str()))
 
1989
    if (drizzled_user == NULL or strcmp(drizzled_user, vm["user"].as<string>().c_str()) == 0)
 
1990
    {
2030
1991
      drizzled_user= (char *)vm["user"].as<string>().c_str();
2031
 
 
 
1992
    }
2032
1993
    else
2033
 
      errmsg_printf(error::WARN, _("Ignoring user change to '%s' because the user was "
2034
 
                                       "set to '%s' earlier on the command line\n"),
 
1994
    {
 
1995
      errmsg_printf(error::WARN, _("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line"),
2035
1996
                    vm["user"].as<string>().c_str(), drizzled_user);
2036
 
  }
2037
 
 
2038
 
  if (vm.count("version"))
2039
 
  {
2040
 
    print_version();
2041
 
    exit(0);
 
1997
    }
2042
1998
  }
2043
1999
 
2044
2000
  if (vm.count("sort-heap-threshold"))
2045
2001
  {
2046
2002
    if ((vm["sort-heap-threshold"].as<uint64_t>() > 0) and
2047
 
      (vm["sort-heap-threshold"].as<uint64_t>() <
2048
 
      global_system_variables.sortbuff_size))
 
2003
      (vm["sort-heap-threshold"].as<uint64_t>() < global_system_variables.sortbuff_size))
2049
2004
    {
2050
 
      cout << _("Error: sort-heap-threshold cannot be less than sort-buffer-size") << endl;
2051
 
      exit(-1);
 
2005
      unireg_abort << _("sort-heap-threshold cannot be less than sort-buffer-size");
2052
2006
    }
2053
2007
 
2054
2008
    global_sort_buffer.setMaxSize(vm["sort-heap-threshold"].as<uint64_t>());
2057
2011
  if (vm.count("join-heap-threshold"))
2058
2012
  {
2059
2013
    if ((vm["join-heap-threshold"].as<uint64_t>() > 0) and
2060
 
      (vm["join-heap-threshold"].as<uint64_t>() <
2061
 
      global_system_variables.join_buff_size))
 
2014
      (vm["join-heap-threshold"].as<uint64_t>() < global_system_variables.join_buff_size))
2062
2015
    {
2063
 
      cout << _("Error: join-heap-threshold cannot be less than join-buffer-size") << endl;
2064
 
      exit(-1);
 
2016
      unireg_abort << _("join-heap-threshold cannot be less than join-buffer-size");
2065
2017
    }
2066
2018
 
2067
2019
    global_join_buffer.setMaxSize(vm["join-heap-threshold"].as<uint64_t>());
2070
2022
  if (vm.count("read-rnd-threshold"))
2071
2023
  {
2072
2024
    if ((vm["read-rnd-threshold"].as<uint64_t>() > 0) and
2073
 
      (vm["read-rnd-threshold"].as<uint64_t>() <
2074
 
      global_system_variables.read_rnd_buff_size))
 
2025
      (vm["read-rnd-threshold"].as<uint64_t>() < global_system_variables.read_rnd_buff_size))
2075
2026
    {
2076
 
      cout << _("Error: read-rnd-threshold cannot be less than read-rnd-buffer-size") << endl;
2077
 
      exit(-1);
 
2027
      unireg_abort << _("read-rnd-threshold cannot be less than read-rnd-buffer-size");
2078
2028
    }
2079
2029
 
2080
2030
    global_read_rnd_buffer.setMaxSize(vm["read-rnd-threshold"].as<uint64_t>());
2083
2033
  if (vm.count("read-buffer-threshold"))
2084
2034
  {
2085
2035
    if ((vm["read-buffer-threshold"].as<uint64_t>() > 0) and
2086
 
      (vm["read-buffer-threshold"].as<uint64_t>() <
2087
 
      global_system_variables.read_buff_size))
 
2036
      (vm["read-buffer-threshold"].as<uint64_t>() < global_system_variables.read_buff_size))
2088
2037
    {
2089
 
      cout << _("Error: read-buffer-threshold cannot be less than read-buffer-size") << endl;
2090
 
      exit(-1);
 
2038
      unireg_abort << _("read-buffer-threshold cannot be less than read-buffer-size");
2091
2039
    }
2092
2040
 
2093
2041
    global_read_buffer.setMaxSize(vm["read-buffer-threshold"].as<uint64_t>());
2113
2061
 
2114
2062
  if (vm.count("skip-symlinks"))
2115
2063
  {
2116
 
    internal::my_use_symdir=0;
 
2064
    internal::my_use_symdir= 0;
 
2065
  }
 
2066
 
 
2067
  if (vm.count("collation-server"))
 
2068
  {
 
2069
    const charset_info_st * const default_collation= get_charset_by_name(vm["collation-server"].as<string>().c_str());
 
2070
    if (not default_collation)
 
2071
    {
 
2072
      unireg_abort << "Unknown collation: " << default_collation_name;
 
2073
    }
 
2074
 
 
2075
    if (not my_charset_same(default_charset_info, default_collation))
 
2076
    {
 
2077
      unireg_abort << "COLLATION '" << default_collation_name << "' is not valid for CHARACTER SET '" << default_charset_info->csname << "'";
 
2078
    }
 
2079
    default_charset_info= default_collation;
2117
2080
  }
2118
2081
 
2119
2082
  if (vm.count("transaction-isolation"))
2149
2112
  }
2150
2113
 
2151
2114
  if (drizzled_chroot)
 
2115
  {
2152
2116
    set_root(drizzled_chroot);
 
2117
  }
2153
2118
 
2154
2119
  /*
2155
2120
    Set some global variables from the global_system_variables
2161
2126
 
2162
2127
static void fix_paths()
2163
2128
{
 
2129
  if (vm.count("help"))
 
2130
    return;
 
2131
 
2164
2132
  fs::path pid_file_path(pid_file);
2165
2133
  if (pid_file_path.root_path().string() == "")
2166
2134
  {
2169
2137
  }
2170
2138
  pid_file= fs::system_complete(pid_file_path);
2171
2139
 
2172
 
  if (not opt_help)
2173
 
  {
2174
 
    const char *tmp_string= getenv("TMPDIR");
2175
 
    struct stat buf;
2176
 
    drizzle_tmpdir.clear();
2177
 
 
2178
 
    if (vm.count("tmpdir"))
2179
 
    {
2180
 
      drizzle_tmpdir.append(vm["tmpdir"].as<string>());
2181
 
    }
2182
 
    else if (tmp_string == NULL)
2183
 
    {
2184
 
      drizzle_tmpdir.append(getDataHome().file_string());
2185
 
      drizzle_tmpdir.push_back(FN_LIBCHAR);
2186
 
      drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
2187
 
    }
2188
 
    else
2189
 
    {
2190
 
      drizzle_tmpdir.append(tmp_string);
2191
 
    }
2192
 
 
2193
 
    drizzle_tmpdir= fs::path(fs::system_complete(fs::path(drizzle_tmpdir))).file_string();
2194
 
    assert(drizzle_tmpdir.size());
2195
 
 
2196
 
    if (mkdir(drizzle_tmpdir.c_str(), 0777) == -1)
2197
 
    {
2198
 
      if (errno != EEXIST)
2199
 
      {
2200
 
        errmsg_printf(error::ERROR, _("There was an error creating the '%s' part of the path '%s'.  Please check the path exists and is writable.\n"), fs::path(drizzle_tmpdir).leaf().c_str(), drizzle_tmpdir.c_str());
2201
 
        exit(1);
2202
 
      }
2203
 
    }
2204
 
 
2205
 
    if (stat(drizzle_tmpdir.c_str(), &buf) || not S_ISDIR(buf.st_mode))
2206
 
    {
2207
 
      errmsg_printf(error::ERROR, _("There was an error opening the path '%s', please check the path exists and is writable.\n"), drizzle_tmpdir.c_str());
2208
 
      exit(1);
2209
 
    }
2210
 
  }
2211
 
 
 
2140
  const char *tmp_string= getenv("TMPDIR");
 
2141
  struct stat buf;
 
2142
  drizzle_tmpdir.clear();
 
2143
 
 
2144
  if (vm.count("tmpdir"))
 
2145
  {
 
2146
    drizzle_tmpdir.append(vm["tmpdir"].as<string>());
 
2147
  }
 
2148
  else if (tmp_string == NULL)
 
2149
  {
 
2150
    drizzle_tmpdir.append(getDataHome().file_string());
 
2151
    drizzle_tmpdir.push_back(FN_LIBCHAR);
 
2152
    drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
 
2153
  }
 
2154
  else
 
2155
  {
 
2156
    drizzle_tmpdir.append(tmp_string);
 
2157
  }
 
2158
 
 
2159
  drizzle_tmpdir= fs::path(fs::system_complete(fs::path(drizzle_tmpdir))).file_string();
 
2160
  assert(drizzle_tmpdir.size());
 
2161
 
 
2162
  assert(getuid() != 0 and geteuid() != 0);
 
2163
  if (getuid() == 0 or geteuid() == 0)
 
2164
  {
 
2165
    unireg_abort << "Drizzle cannot be run as root, please see the Security piece of the manual for more information.";
 
2166
  }
 
2167
 
 
2168
  if (mkdir(drizzle_tmpdir.c_str(), 0777) == -1)
 
2169
  {
 
2170
    if (errno != EEXIST)
 
2171
    {
 
2172
      unireg_abort << "There was an error creating the '" 
 
2173
        << fs::path(drizzle_tmpdir).leaf() 
 
2174
        << "' part of the path '" 
 
2175
        << drizzle_tmpdir 
 
2176
        << "'.  Please check the path exists and is writable.";
 
2177
    }
 
2178
  }
 
2179
 
 
2180
  if (stat(drizzle_tmpdir.c_str(), &buf) || not S_ISDIR(buf.st_mode))
 
2181
  {
 
2182
    unireg_abort << "There was an error opening the path '" << drizzle_tmpdir << "', please check the path exists and is writable.";
 
2183
  }
2212
2184
}
2213
2185
 
2214
2186
} /* namespace drizzled */