home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / mysqlbinlog / log_event.h < prev    next >
C/C++ Source or Header  |  2000-11-17  |  12KB  |  406 lines

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16.  
  17.  
  18. #ifndef _LOG_EVENT_H
  19. #define _LOG_EVENT_H
  20.  
  21. #if defined(__GNUC__) && !defined(MYSQL_CLIENT)
  22. #pragma interface            /* gcc class implementation */
  23. #endif
  24.  
  25. #define LOG_READ_EOF    -1
  26. #define LOG_READ_BOGUS  -2
  27. #define LOG_READ_IO     -3
  28. #define LOG_READ_MEM    -5
  29. #define LOG_READ_TRUNC  -6
  30.  
  31. #define LOG_EVENT_OFFSET 4
  32. #define BINLOG_VERSION    1
  33.  
  34. #define LOG_EVENT_HEADER_LEN 13
  35. #define QUERY_HEADER_LEN     (sizeof(uint32) + sizeof(uint32) + \
  36.  sizeof(uchar) + sizeof(uint16))
  37. #define LOAD_HEADER_LEN      (sizeof(uint32) + sizeof(uint32) + \
  38.   + sizeof(uint32) + 2 + sizeof(uint32))
  39. #define EVENT_LEN_OFFSET     9
  40. #define EVENT_TYPE_OFFSET    4
  41. #define MAX_EVENT_LEN        4*1024*1024 
  42. #define QUERY_EVENT_OVERHEAD  (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN)
  43. #define ROTATE_EVENT_OVERHEAD LOG_EVENT_HEADER_LEN
  44. #define LOAD_EVENT_OVERHEAD   (LOG_EVENT_HEADER_LEN+LOAD_HEADER_LEN+sizeof(sql_ex_info))
  45.  
  46. #define BINLOG_MAGIC        "\xfe\x62\x69\x6e"
  47.  
  48. enum Log_event_type { START_EVENT = 1, QUERY_EVENT =2,
  49.               STOP_EVENT=3, ROTATE_EVENT = 4, INTVAR_EVENT=5,
  50.                       LOAD_EVENT=6};
  51. enum Int_event_type { INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
  52.  };
  53.  
  54. #ifndef MYSQL_CLIENT
  55. class String;
  56. #endif
  57.  
  58. extern uint32 server_id;
  59.  
  60. class Log_event
  61. {
  62. public:
  63.   time_t when;
  64.   ulong exec_time;
  65.   int valid_exec_time; // if false, the exec time setting is bogus 
  66.   uint32 server_id;
  67.  
  68.   int write(IO_CACHE* file);
  69.   int write_header(IO_CACHE* file);
  70.   virtual int write_data(IO_CACHE* file __attribute__((unused))) { return 0; }
  71.   virtual Log_event_type get_type_code() = 0;
  72.   Log_event(time_t when_arg, ulong exec_time_arg = 0,
  73.         int valid_exec_time_arg = 0, uint32 server_id = 0): when(when_arg),
  74.     exec_time(exec_time_arg), valid_exec_time(valid_exec_time_arg)
  75.   {
  76.     if(!server_id) this->server_id = ::server_id;
  77.     else this->server_id = server_id;
  78.   }
  79.  
  80.   Log_event(const char* buf): valid_exec_time(0)
  81.   {
  82.    when = uint4korr(buf);
  83.    server_id = uint4korr(buf + 5);
  84.   }
  85.  
  86.   virtual ~Log_event() {}
  87.  
  88.   virtual int get_data_size() { return 0;}
  89.   virtual void print(FILE* file, bool short_form = 0) = 0;
  90.  
  91.   void print_timestamp(FILE* file, time_t *ts = 0);
  92.   void print_header(FILE* file);
  93.  
  94.   // if mutex is 0, the read will proceed without mutex
  95.   static Log_event* read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock);
  96.   static Log_event* read_log_event(const char* buf, int event_len);
  97.  
  98. #ifndef MYSQL_CLIENT
  99.   static int read_log_event(IO_CACHE* file, String* packet,
  100.                 pthread_mutex_t* log_lock);
  101. #endif
  102.   
  103. };
  104.  
  105.  
  106. class Query_log_event: public Log_event
  107. {
  108. protected:
  109.   char* data_buf;
  110. public:
  111.   const char* query;
  112.   const char* db;
  113.   uint32 q_len; // if we already know the length of the query string
  114.   // we pass it here, so we would not have to call strlen()
  115.   // otherwise, set it to 0, in which case, we compute it with strlen()
  116.   uint32 db_len;
  117.   uint16 error_code;
  118.   int thread_id;
  119. #if !defined(MYSQL_CLIENT)
  120.   THD* thd;
  121.   Query_log_event(THD* thd_arg, const char* query_arg):
  122.     Log_event(thd_arg->start_time,0,0,thd_arg->server_id), data_buf(0),
  123.     query(query_arg),  db(thd_arg->db), q_len(thd_arg->query_length),
  124.     error_code(thd_arg->net.last_errno),
  125.     thread_id(thd_arg->thread_id), thd(thd_arg)
  126.   {
  127.     time_t end_time;
  128.     time(&end_time);
  129.     exec_time = (ulong) (end_time  - thd->start_time);
  130.     valid_exec_time = 1;
  131.     db_len = (db) ? (uint32) strlen(db) : 0;
  132.   }
  133. #endif
  134.  
  135.   Query_log_event(IO_CACHE* file, time_t when, uint32 server_id);
  136.   Query_log_event(const char* buf, int event_len);
  137.   ~Query_log_event()
  138.   {
  139.     if (data_buf)
  140.     {
  141.       my_free((gptr) data_buf, MYF(0));
  142.     }
  143.   }
  144.   Log_event_type get_type_code() { return QUERY_EVENT; }
  145.   int write(IO_CACHE* file);
  146.   int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
  147.   int get_data_size()
  148.   {
  149.     return q_len + db_len + 2 +
  150.       sizeof(uint32) // thread_id
  151.       + sizeof(uint32) // exec_time
  152.       + sizeof(uint16) // error_code
  153.       ;
  154.   }
  155.  
  156.   void print(FILE* file, bool short_form = 0);
  157. };
  158.  
  159. #define DUMPFILE_FLAG 0x1
  160. #define OPT_ENCLOSED_FLAG 0x2
  161. #define REPLACE_FLAG  0x4
  162. #define IGNORE_FLAG   0x8
  163.  
  164. #define FIELD_TERM_EMPTY 0x1
  165. #define ENCLOSED_EMPTY   0x2
  166. #define LINE_TERM_EMPTY  0x4
  167. #define LINE_START_EMPTY 0x8
  168. #define ESCAPED_EMPTY    0x10
  169.  
  170.  
  171. struct sql_ex_info
  172.   {
  173.     char field_term;
  174.     char enclosed;
  175.     char line_term;
  176.     char line_start;
  177.     char escaped;
  178.     char opt_flags; // flags for the options
  179.     char empty_flags; // flags to indicate which of the terminating charact
  180.   } ;
  181.  
  182. class Load_log_event: public Log_event
  183. {
  184. protected:
  185.   char* data_buf;
  186.   void copy_log_event(const char *buf, ulong data_len);
  187.  
  188. public:
  189.   int thread_id;
  190.   uint32 table_name_len;
  191.   uint32 db_len;
  192.   uint32 fname_len;
  193.   uint32 num_fields;
  194.   const char* fields;
  195.   const uchar* field_lens;
  196.   uint32 field_block_len;
  197.   
  198.  
  199.   const char* table_name;
  200.   const char* db;
  201.   const char* fname;
  202.   uint32 skip_lines;
  203.   sql_ex_info sql_ex;
  204.   
  205. #if !defined(MYSQL_CLIENT)
  206.   THD* thd;
  207.   String field_lens_buf;
  208.   String fields_buf;
  209.   Load_log_event(THD* thd, sql_exchange* ex, const char* table_name,
  210.          List<Item>& fields, enum enum_duplicates handle_dup ):
  211.     Log_event(thd->start_time),data_buf(0),thread_id(thd->thread_id),
  212.     num_fields(0),fields(0),field_lens(0),field_block_len(0),
  213.     table_name(table_name),
  214.     db(thd->db),
  215.     fname(ex->file_name),
  216.     thd(thd)
  217.   {
  218.     time_t end_time;
  219.     time(&end_time);
  220.     exec_time = (ulong) (end_time  - thd->start_time);
  221.     valid_exec_time = 1;
  222.     db_len = (db) ? (uint32) strlen(db) : 0;
  223.     table_name_len = (table_name) ? (uint32) strlen(table_name) : 0;
  224.     fname_len = (fname) ? (uint) strlen(fname) : 0;
  225.     sql_ex.field_term = (*ex->field_term)[0];
  226.     sql_ex.enclosed = (*ex->enclosed)[0];
  227.     sql_ex.line_term = (*ex->line_term)[0];
  228.     sql_ex.line_start = (*ex->line_start)[0];
  229.     sql_ex.escaped = (*ex->escaped)[0];
  230.     sql_ex.opt_flags = 0;
  231.     if(ex->dumpfile)
  232.       sql_ex.opt_flags |= DUMPFILE_FLAG;
  233.     if(ex->opt_enclosed)
  234.       sql_ex.opt_flags |= OPT_ENCLOSED_FLAG;
  235.  
  236.     sql_ex.empty_flags = 0;
  237.  
  238.     switch(handle_dup)
  239.       {
  240.       case DUP_IGNORE: sql_ex.opt_flags |= IGNORE_FLAG; break;
  241.       case DUP_REPLACE: sql_ex.opt_flags |= REPLACE_FLAG; break;
  242.       case DUP_ERROR: break;    
  243.       }
  244.  
  245.     if(!ex->field_term->length())
  246.       sql_ex.empty_flags |= FIELD_TERM_EMPTY;
  247.     if(!ex->enclosed->length())
  248.       sql_ex.empty_flags |= ENCLOSED_EMPTY;
  249.     if(!ex->line_term->length())
  250.       sql_ex.empty_flags |= LINE_TERM_EMPTY;
  251.     if(!ex->line_start->length())
  252.       sql_ex.empty_flags |= LINE_START_EMPTY;
  253.     if(!ex->escaped->length())
  254.       sql_ex.empty_flags |= ESCAPED_EMPTY;
  255.     
  256.     skip_lines = ex->skip_lines;
  257.  
  258.     List_iterator<Item> li(fields);
  259.     field_lens_buf.length(0);
  260.     fields_buf.length(0);
  261.     Item* item;
  262.     while((item = li++))
  263.       {
  264.     num_fields++;
  265.     uchar len = (uchar) strlen(item->name);
  266.     field_block_len += len + 1;
  267.     fields_buf.append(item->name, len + 1);
  268.     field_lens_buf.append((char*)&len, 1);
  269.       }
  270.  
  271.     field_lens = (const uchar*)field_lens_buf.ptr();
  272.     this->fields = fields_buf.ptr();
  273.   }
  274.   void set_fields(List<Item> &fields);
  275. #endif
  276.  
  277.   Load_log_event(IO_CACHE * file, time_t when, uint32 server_id);
  278.   Load_log_event(const char* buf, int event_len);
  279.   ~Load_log_event()
  280.   {
  281.     if (data_buf)
  282.     {
  283.       my_free((gptr) data_buf, MYF(0));
  284.     }
  285.   }
  286.   Log_event_type get_type_code() { return LOAD_EVENT; }
  287.   int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
  288.   int get_data_size()
  289.   {
  290.     return table_name_len + 2 + db_len + 2 + fname_len
  291.       + sizeof(thread_id) // thread_id
  292.       + sizeof(exec_time) // exec_time
  293.       + sizeof(skip_lines)
  294.       + sizeof(field_block_len)
  295.       + sizeof(sql_ex) + field_block_len + num_fields*sizeof(uchar) ;
  296.       ;
  297.   }
  298.  
  299.   void print(FILE* file, bool short_form = 0);
  300. };
  301.  
  302. extern char server_version[50];
  303.  
  304. class Start_log_event: public Log_event
  305. {
  306. public:
  307.   uint32 created;
  308.   uint16 binlog_version;
  309.   char server_version[50];
  310.   
  311.   Start_log_event() :Log_event(time(NULL)),binlog_version(BINLOG_VERSION)
  312.   {
  313.     created = (uint32) when;
  314.     memcpy(server_version, ::server_version, sizeof(server_version));
  315.   }
  316.   Start_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id) :
  317.     Log_event(when_arg, 0, 0, server_id)
  318.   {
  319.     char buf[sizeof(server_version) + 2 + 4 + 4];
  320.     if (my_b_read(file, (byte*) buf, sizeof(buf)))
  321.       return;                
  322.     binlog_version = uint2korr(buf+4);
  323.     memcpy(server_version, buf + 6, sizeof(server_version));
  324.     created = uint4korr(buf + 6 + sizeof(server_version));
  325.   }
  326.   Start_log_event(const char* buf);
  327.   
  328.   ~Start_log_event() {}
  329.   Log_event_type get_type_code() { return START_EVENT;}
  330.   int write_data(IO_CACHE* file);
  331.   int get_data_size()
  332.   {
  333.     // sizeof(binlog_version) + sizeof(server_version) sizeof(created)
  334.     return 2 + sizeof(server_version) + 4;
  335.   }
  336.   void print(FILE* file, bool short_form = 0);
  337. };
  338.  
  339. class Intvar_log_event: public Log_event
  340. {
  341. public:
  342.   ulonglong val;
  343.   uchar type;
  344.   Intvar_log_event(uchar type_arg, ulonglong val_arg)
  345.     :Log_event(time(NULL)),val(val_arg),type(type_arg)
  346.   {}
  347.   Intvar_log_event(IO_CACHE* file, time_t when, uint32 server_id);
  348.   Intvar_log_event(const char* buf);
  349.   ~Intvar_log_event() {}
  350.   Log_event_type get_type_code() { return INTVAR_EVENT;}
  351.   int get_data_size() { return  sizeof(type) + sizeof(val);}
  352.   int write_data(IO_CACHE* file);
  353.   
  354.   
  355.   void print(FILE* file, bool short_form = 0);
  356. };
  357.  
  358. class Stop_log_event: public Log_event
  359. {
  360. public:
  361.   Stop_log_event() :Log_event(time(NULL))
  362.   {}
  363.   Stop_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id):
  364.     Log_event(when_arg,0,0,server_id)
  365.   {
  366.     byte skip[4];
  367.     my_b_read(file, skip, sizeof(skip));    // skip the event length
  368.   }
  369.   Stop_log_event(const char* buf):Log_event(buf)
  370.   {
  371.   }
  372.   ~Stop_log_event() {}
  373.   Log_event_type get_type_code() { return STOP_EVENT;}
  374.   void print(FILE* file, bool short_form = 0);
  375. };
  376.  
  377. class Rotate_log_event: public Log_event
  378. {
  379. public:
  380.   const char* new_log_ident;
  381.   uchar ident_len;
  382.   bool alloced;
  383.   
  384.   Rotate_log_event(const char* new_log_ident_arg, uint ident_len_arg = 0) :
  385.     Log_event(time(NULL)),
  386.     new_log_ident(new_log_ident_arg),
  387.     ident_len(ident_len_arg ? ident_len_arg : (uint) strlen(new_log_ident_arg)),
  388.     alloced(0)
  389.   {}
  390.   
  391.   Rotate_log_event(IO_CACHE* file, time_t when, uint32 server_id) ;
  392.   Rotate_log_event(const char* buf, int event_len);
  393.   ~Rotate_log_event()
  394.   {
  395.     if (alloced)
  396.       my_free((gptr) new_log_ident, MYF(0));
  397.   }
  398.   Log_event_type get_type_code() { return ROTATE_EVENT;}
  399.   int get_data_size() { return  ident_len;}
  400.   int write_data(IO_CACHE* file);
  401.   
  402.   void print(FILE* file, bool short_form = 0);
  403. };
  404.  
  405. #endif
  406.