summaryrefslogtreecommitdiff
path: root/sql/log_event.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/log_event.h')
-rw-r--r--sql/log_event.h354
1 files changed, 354 insertions, 0 deletions
diff --git a/sql/log_event.h b/sql/log_event.h
new file mode 100644
index 00000000000..fb585f01dea
--- /dev/null
+++ b/sql/log_event.h
@@ -0,0 +1,354 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+#ifndef _LOG_EVENT_H
+#define _LOG_EVENT_H
+
+#if defined(__GNUC__) && !defined(MYSQL_CLIENT)
+#pragma interface /* gcc class implementation */
+#endif
+
+#define LOG_READ_EOF -1
+#define LOG_READ_BOGUS -2
+#define LOG_READ_IO -3
+#define LOG_READ_MEM -5
+
+#define LOG_EVENT_OFFSET 4
+
+
+enum Log_event_type { START_EVENT = 1, QUERY_EVENT =2,
+ STOP_EVENT=3, ROTATE_EVENT = 4, INTVAR_EVENT=5,
+ LOAD_EVENT=6};
+enum Int_event_type { INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
+ };
+
+#ifndef MYSQL_CLIENT
+class String;
+#endif
+
+class Log_event
+{
+public:
+ time_t when;
+ ulong exec_time;
+ int valid_exec_time; // if false, the exec time setting is bogus and needs
+
+ int write(FILE* file);
+ int write_header(FILE* file);
+ virtual int write_data(FILE* file __attribute__((unused))) { return 0; }
+ virtual Log_event_type get_type_code() = 0;
+ Log_event(time_t when_arg, ulong exec_time_arg = 0,
+ int valid_exec_time_arg = 0): when(when_arg),
+ exec_time(exec_time_arg), valid_exec_time(valid_exec_time_arg) {}
+
+ Log_event(const char* buf): valid_exec_time(1)
+ {
+ when = uint4korr(buf);
+ exec_time = uint4korr(buf + 5);
+ }
+
+ virtual ~Log_event() {}
+
+ virtual int get_data_size() { return 0;}
+ virtual void print(FILE* file, bool short_form = 0) = 0;
+
+ void print_timestamp(FILE* file);
+
+ static Log_event* read_log_event(FILE* file);
+ static Log_event* read_log_event(const char* buf, int max_buf);
+
+#ifndef MYSQL_CLIENT
+ static int read_log_event(FILE* file, String* packet);
+#endif
+
+};
+
+
+class Query_log_event: public Log_event
+{
+protected:
+ char* data_buf;
+public:
+ const char* query;
+ const char* db;
+ uint q_len; // if we already know the length of the query string
+ // we pass it here, so we would not have to call strlen()
+ // otherwise, set it to 0, in which case, we compute it with strlen()
+ uint db_len;
+ int thread_id;
+#if !defined(MYSQL_CLIENT)
+ THD* thd;
+ Query_log_event(THD* thd_arg, const char* query_arg):
+ Log_event(thd_arg->start_time), data_buf(0),
+ query(query_arg), db(thd_arg->db), q_len(thd_arg->query_length),
+ thread_id(thd_arg->thread_id), thd(thd_arg)
+ {
+ time_t end_time;
+ time(&end_time);
+ exec_time = end_time - thd->start_time;
+ valid_exec_time = 1;
+ db_len = (db) ? strlen(db) : 0;
+ }
+#endif
+
+ Query_log_event(FILE* file, time_t when);
+ Query_log_event(const char* buf, int max_buf);
+ ~Query_log_event()
+ {
+ if (data_buf)
+ {
+ my_free((gptr)data_buf, MYF(0));
+ }
+ }
+ Log_event_type get_type_code() { return QUERY_EVENT; }
+ int write(FILE* file);
+ int write_data(FILE* file); // returns 0 on success, -1 on error
+ int get_data_size()
+ {
+ return q_len + db_len + 2 +
+ sizeof(uint) // thread_id
+ + sizeof(uint) // exec_time
+ ;
+ }
+
+ void print(FILE* file, bool short_form = 0);
+};
+
+#define DUMPFILE_FLAG 0x1
+#define OPT_ENCLOSED_FLAG 0x2
+#define REPLACE_FLAG 0x4
+#define IGNORE_FLAG 0x8
+
+#define FIELD_TERM_EMPTY 0x1
+#define ENCLOSED_EMPTY 0x2
+#define LINE_TERM_EMPTY 0x4
+#define LINE_START_EMPTY 0x8
+#define ESCAPED_EMPTY 0x10
+
+
+struct sql_ex_info
+ {
+ char field_term;
+ char enclosed;
+ char line_term;
+ char line_start;
+ char escaped;
+ char opt_flags; // flags for the options
+ char empty_flags; // flags to indicate which of the terminating charact
+ } ;
+
+class Load_log_event: public Log_event
+{
+protected:
+ char* data_buf;
+public:
+ int thread_id;
+ uint table_name_len;
+ uint db_len;
+ uint fname_len;
+ uint num_fields;
+ const char* fields;
+ const uchar* field_lens;
+ uint field_block_len;
+
+
+ const char* table_name;
+ const char* db;
+ const char* fname;
+ uint skip_lines;
+ sql_ex_info sql_ex;
+
+#if !defined(MYSQL_CLIENT)
+ THD* thd;
+ String field_lens_buf;
+ String fields_buf;
+ Load_log_event(THD* thd, sql_exchange* ex, const char* table_name,
+ List<Item>& fields, enum enum_duplicates handle_dup ):
+ Log_event(thd->start_time),data_buf(0),thread_id(thd->thread_id),
+ num_fields(0),fields(0),field_lens(0),field_block_len(0),
+ table_name(table_name),
+ db(thd->db),
+ fname(ex->file_name),
+ thd(thd)
+ {
+ time_t end_time;
+ time(&end_time);
+ exec_time = end_time - thd->start_time;
+ valid_exec_time = 1;
+ db_len = (db) ? strlen(db) : 0;
+ table_name_len = (table_name) ? strlen(table_name) : 0;
+ fname_len = (fname) ? strlen(fname) : 0;
+ sql_ex.field_term = (*ex->field_term)[0];
+ sql_ex.enclosed = (*ex->enclosed)[0];
+ sql_ex.line_term = (*ex->line_term)[0];
+ sql_ex.line_start = (*ex->line_start)[0];
+ sql_ex.escaped = (*ex->escaped)[0];
+ sql_ex.opt_flags = 0;
+ if(ex->dumpfile)
+ sql_ex.opt_flags |= DUMPFILE_FLAG;
+ if(ex->opt_enclosed)
+ sql_ex.opt_flags |= OPT_ENCLOSED_FLAG;
+
+ sql_ex.empty_flags = 0;
+
+ switch(handle_dup)
+ {
+ case DUP_IGNORE: sql_ex.opt_flags |= IGNORE_FLAG; break;
+ case DUP_REPLACE: sql_ex.opt_flags |= REPLACE_FLAG; break;
+ case DUP_ERROR: break;
+ }
+
+ if(!ex->field_term->length())
+ sql_ex.empty_flags |= FIELD_TERM_EMPTY;
+ if(!ex->enclosed->length())
+ sql_ex.empty_flags |= ENCLOSED_EMPTY;
+ if(!ex->line_term->length())
+ sql_ex.empty_flags |= LINE_TERM_EMPTY;
+ if(!ex->line_start->length())
+ sql_ex.empty_flags |= LINE_START_EMPTY;
+ if(!ex->escaped->length())
+ sql_ex.empty_flags |= ESCAPED_EMPTY;
+
+ skip_lines = ex->skip_lines;
+
+ List_iterator<Item> li(fields);
+ field_lens_buf.length(0);
+ fields_buf.length(0);
+ Item* item;
+ while((item = li++))
+ {
+ num_fields++;
+ uchar len = (uchar)strlen(item->name);
+ field_block_len += len + 1;
+ fields_buf.append(item->name, len + 1);
+ field_lens_buf.append((char*)&len, 1);
+ }
+
+ field_lens = (const uchar*)field_lens_buf.ptr();
+ this->fields = fields_buf.ptr();
+ }
+ void set_fields(List<Item> &fields);
+#endif
+
+ Load_log_event(FILE* file, time_t when);
+ Load_log_event(const char* buf, int max_buf);
+ ~Load_log_event()
+ {
+ if (data_buf)
+ {
+ my_free((gptr)data_buf, MYF(0));
+ }
+ }
+ Log_event_type get_type_code() { return LOAD_EVENT; }
+ int write_data(FILE* file); // returns 0 on success, -1 on error
+ int get_data_size()
+ {
+ return table_name_len + 2 + db_len + 2 + fname_len
+ + sizeof(thread_id) // thread_id
+ + sizeof(exec_time) // exec_time
+ + sizeof(skip_lines)
+ + sizeof(field_block_len)
+ + sizeof(sql_ex) + field_block_len + num_fields*sizeof(uchar) ;
+ ;
+ }
+
+ void print(FILE* file, bool short_form = 0);
+};
+
+
+class Start_log_event: public Log_event
+{
+public:
+ Start_log_event() :Log_event(time(NULL))
+ {}
+ Start_log_event(FILE* file, time_t when_arg) :Log_event(when_arg)
+ {
+ my_fseek(file, 4L, MY_SEEK_CUR, MYF(MY_WME)); // skip the event length
+ }
+ Start_log_event(const char* buf) :Log_event(buf)
+ {
+ }
+ ~Start_log_event() {}
+ Log_event_type get_type_code() { return START_EVENT;}
+ void print(FILE* file, bool short_form = 0);
+};
+
+class Intvar_log_event: public Log_event
+{
+public:
+ ulonglong val;
+ uchar type;
+ Intvar_log_event(uchar type_arg, ulonglong val_arg)
+ :Log_event(time(NULL)),val(val_arg),type(type_arg)
+ {}
+ Intvar_log_event(FILE* file, time_t when);
+ Intvar_log_event(const char* buf);
+ ~Intvar_log_event() {}
+ Log_event_type get_type_code() { return INTVAR_EVENT;}
+ int get_data_size() { return sizeof(type) + sizeof(val);}
+ int write_data(FILE* file);
+
+
+ void print(FILE* file, bool short_form = 0);
+};
+
+class Stop_log_event: public Log_event
+{
+public:
+ Stop_log_event() :Log_event(time(NULL))
+ {}
+ Stop_log_event(FILE* file, time_t when_arg): Log_event(when_arg)
+ {
+ my_fseek(file, 4L, MY_SEEK_CUR, MYF(MY_WME)); // skip the event length
+ }
+ Stop_log_event(const char* buf):Log_event(buf)
+ {
+ }
+ ~Stop_log_event() {}
+ Log_event_type get_type_code() { return STOP_EVENT;}
+ void print(FILE* file, bool short_form = 0);
+};
+
+class Rotate_log_event: public Log_event
+{
+public:
+ const char* new_log_ident;
+ uchar ident_len;
+ bool alloced;
+
+ Rotate_log_event(const char* new_log_ident_arg, uint ident_len_arg = 0) :
+ Log_event(time(NULL)),
+ new_log_ident(new_log_ident_arg),
+ ident_len(ident_len_arg ? ident_len_arg : strlen(new_log_ident_arg)),
+ alloced(0)
+ {}
+
+ Rotate_log_event(FILE* file, time_t when) ;
+ Rotate_log_event(const char* buf, int max_buf);
+ ~Rotate_log_event()
+ {
+ if (alloced)
+ my_free((gptr) new_log_ident, MYF(0));
+ }
+ Log_event_type get_type_code() { return ROTATE_EVENT;}
+ int get_data_size() { return ident_len;}
+ int write_data(FILE* file);
+
+ void print(FILE* file, bool short_form = 0);
+};
+
+#endif