home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 January
/
Chip_2001-01_cd1.bin
/
tema
/
mysql
/
mysql-3.23.28g-win-source.exe
/
sql
/
sql_class.h
< prev
next >
Wrap
C/C++ Source or Header
|
2000-11-16
|
14KB
|
492 lines
/* 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 */
/* Classes in mysql */
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
class Query_log_event;
class Load_log_event;
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE };
enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN };
// log info errors
#define LOG_INFO_EOF -1
#define LOG_INFO_IO -2
#define LOG_INFO_INVALID -3
#define LOG_INFO_SEEK -4
#define LOG_INFO_PURGE_NO_ROTATE -5
#define LOG_INFO_MEM -6
#define LOG_INFO_FATAL -7
#define LOG_INFO_IN_USE -8
typedef struct st_log_info
{
char log_file_name[FN_REFLEN];
my_off_t index_file_offset;
my_off_t pos;
bool fatal; // if the purge happens to give us a negative offset
pthread_mutex_t lock;
st_log_info():fatal(0) { pthread_mutex_init(&lock, NULL);}
~st_log_info() { pthread_mutex_destroy(&lock);}
} LOG_INFO;
class MYSQL_LOG {
private:
pthread_mutex_t LOCK_log, LOCK_index;
time_t last_time,query_start;
IO_CACHE log_file;
File index_file;
char *name;
volatile enum_log_type log_type;
char time_buff[20],db[NAME_LEN+1];
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
bool write_error,inited,opened;
bool no_rotate; // for binlog - if log name can never change
// we should not try to rotate it or write any rotation events
// the user should use FLUSH MASTER instead of FLUSH LOGS for
// purging
public:
MYSQL_LOG();
~MYSQL_LOG();
pthread_mutex_t* get_log_lock() { return &LOCK_log; }
void set_index_file_name(const char* index_file_name = 0);
void open(const char *log_name,enum_log_type log_type,
const char *new_name=0);
void new_file(void);
void write(THD *thd, enum enum_server_command command,const char *format,...);
void write(THD *thd, const char *query, uint query_length,
time_t query_start=0);
void write(Query_log_event* event_info); // binary log write
void write(Load_log_event* event_info);
int generate_new_name(char *new_name,const char *old_name);
void make_log_name(char* buf, const char* log_ident);
bool is_active(const char* log_file_name);
int purge_logs(THD* thd, const char* to_log);
void close(bool exiting = 0); // if we are exiting, we also want to close the
// index file
// iterating through the log index file
int find_first_log(LOG_INFO* linfo, const char* log_name);
int find_next_log(LOG_INFO* linfo);
int get_current_log(LOG_INFO* linfo);
inline bool is_open() { return log_type != LOG_CLOSED; }
char* get_index_fname() { return index_file_name;}
char* get_log_fname() { return log_file_name; }
void lock_index() { pthread_mutex_lock(&LOCK_index);}
void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
File get_index_file() { return index_file;}
};
/* character conversion tables */
class CONVERT
{
const uchar *from_map,*to_map;
void convert_array(const uchar *mapping,uchar *buff,uint length);
public:
const char *name;
CONVERT(const char *name_par,uchar *from_par,uchar *to_par)
:from_map(from_par),to_map(to_par),name(name_par) {}
friend CONVERT *get_convert_set(const char *name_ptr);
inline void convert(char *a,uint length)
{
convert_array(from_map, (uchar*) a,length);
}
bool store(String *, const char *,uint);
};
typedef struct st_copy_info {
ha_rows records;
ha_rows deleted;
ha_rows copied;
ha_rows error;
enum enum_duplicates handle_duplicates;
int escape_char;
} COPY_INFO;
class key_part_spec :public Sql_alloc {
public:
const char *field_name;
uint length;
key_part_spec(const char *name,uint len=0) :field_name(name), length(len) {}
};
class Alter_drop :public Sql_alloc {
public:
enum drop_type {KEY, COLUMN };
const char *name;
enum drop_type type;
Alter_drop(enum drop_type par_type,const char *par_name)
:name(par_name), type(par_type) {}
};
class Alter_column :public Sql_alloc {
public:
const char *name;
Item *def;
Alter_column(const char *par_name,Item *literal)
:name(par_name), def(literal) {}
};
class Key :public Sql_alloc {
public:
enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT };
enum Keytype type;
List<key_part_spec> columns;
const char *Name;
Key(enum Keytype type_par,const char *name_arg,List<key_part_spec> &cols)
:type(type_par), columns(cols),Name(name_arg) {}
~Key() {}
const char *name() { return Name; }
};
typedef struct st_mysql_lock
{
TABLE **table;
uint table_count,lock_count;
THR_LOCK_DATA **locks;
} MYSQL_LOCK;
class LEX_COLUMN : public Sql_alloc
{
public:
String column;
uint rights;
LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {}
};
#include "sql_lex.h" /* Must be here */
// needed to be able to have an I_List of char* strings.in mysqld.cc where we cannot use String
// because it is Sql_alloc'ed
class i_string: public ilink
{
public:
char* ptr;
i_string():ptr(0) { }
i_string(char* s) : ptr(s) {}
};
//needed for linked list of two strings for replicate-rewrite-db
class i_string_pair: public ilink
{
public:
char* key;
char* val;
i_string_pair():key(0),val(0) { }
i_string_pair(char* key, char* val) : key(key),val(val) {}
};
/****************************************************************************
** every connection is handle by a thread with a THD
****************************************************************************/
class delayed_insert;
class THD :public ilink {
public:
NET net;
LEX lex;
MEM_ROOT mem_root;
HASH user_vars;
String packet; /* Room for 1 row */
struct sockaddr_in remote;
struct rand_struct rand;
char *query,*thread_stack;
char *host,*user,*priv_user,*db,*ip;
const char *proc_info;
uint client_capabilities,max_packet_length;
uint master_access,db_access;
TABLE *open_tables,*temporary_tables;
MYSQL_LOCK *lock,*locked_tables;
ULL *ull;
struct st_my_thread_var *mysys_var;
enum enum_server_command command;
uint32 server_id;
const char *where;
char* last_nx_table; // last non-existent table, we need this for replication
char* last_nx_db; // database of the last nx table
time_t start_time,time_after_lock,user_time;
time_t connect_time,thr_create_time; // track down slow pthread_create
thr_lock_type update_lock_default;
delayed_insert *di;
struct st_transactions {
IO_CACHE trans_log;
void *bdb_tid;
uint bdb_lock_count;
} transaction;
Item *free_list;
CONVERT *convert_set;
Field *dupp_field;
#ifndef __WIN__
sigset_t signals,block_signals;
#endif
ulonglong next_insert_id,last_insert_id,current_insert_id;
ha_rows select_limit,offset_limit,default_select_limit,cuted_fields,
max_join_size,sent_row_count;
table_map used_tables;
ulong query_id,version, inactive_timeout,options,thread_id;
long dbug_thread_id;
pthread_t real_id;
uint current_tablenr,tmp_table,cond_count,col_access,query_length;
uint server_status,open_options;
bool slave_thread;
char scramble[9];
bool set_query_id,locked,count_cuted_fields,some_tables_deleted;
bool no_errors, allow_sum_func, password, fatal_error;
bool query_start_used,last_insert_id_used,insert_id_used;
bool volatile killed,bootstrap;
bool system_thread,in_lock_tables,global_read_lock;
bool query_error;
LOG_INFO* current_linfo;
// if we do a purge of binary logs, log index info of the threads
// that are currently reading it needs to be adjusted. To do that
// each thread that is using LOG_INFO needs to adjust the pointer to it
THD();
~THD();
bool store_globals();
inline time_t query_start() { query_start_used=1; return start_time; }
inline void set_time() { if (user_time) start_time=time_after_lock=user_time; else time_after_lock=time(&start_time); }
inline void end_time() { time(&start_time); }
inline void set_time(time_t t) { time_after_lock=start_time=user_time=t; }
inline void lock_time() { time(&time_after_lock); }
inline void insert_id(ulonglong id)
{ last_insert_id=id; insert_id_used=1; }
inline ulonglong insert_id(void)
{
if (!last_insert_id_used)
{
last_insert_id_used=1;
current_insert_id=last_insert_id;
}
return last_insert_id;
}
inline bool active_transaction() { return transaction.bdb_tid != 0; }
inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); }
inline gptr calloc(unsigned int size)
{
gptr ptr;
if ((ptr=alloc_root(&mem_root,size)))
bzero((char*) ptr,size);
return ptr;
}
inline char *strdup(const char *str)
{ return strdup_root(&mem_root,str); }
inline char *memdup(const char *str, unsigned int size)
{ return memdup_root(&mem_root,str,size); }
};
class sql_exchange :public Sql_alloc
{
public:
char *file_name;
String *field_term,*enclosed,*line_term,*line_start,*escaped;
bool opt_enclosed;
bool dumpfile;
uint skip_lines;
sql_exchange(char *name,bool dumpfile_flag);
~sql_exchange() {}
};
#include "log_event.h"
/*
** This is used to get result from a select
*/
class select_result :public Sql_alloc {
protected:
THD *thd;
public:
select_result();
virtual ~select_result() {};
virtual int prepare(List<Item> &list) { return 0; }
virtual bool send_fields(List<Item> &list,uint flag)=0;
virtual bool send_data(List<Item> &items)=0;
virtual void send_error(uint errcode,const char *err)=0;
virtual bool send_eof()=0;
virtual void abort() {}
};
class select_send :public select_result {
public:
select_send() {}
bool send_fields(List<Item> &list,uint flag);
bool send_data(List<Item> &items);
void send_error(uint errcode,const char *err);
bool send_eof();
};
class select_export :public select_result {
sql_exchange *exchange;
File file;
IO_CACHE cache;
ha_rows row_count;
uint field_term_length;
int field_sep_char,escape_char,line_sep_char;
bool fixed_row_size;
public:
select_export(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) {}
~select_export();
int prepare(List<Item> &list);
bool send_fields(List<Item> &list,
uint flag) { return 0; }
bool send_data(List<Item> &items);
void send_error(uint errcode,const char *err);
bool send_eof();
};
class select_dump :public select_result {
sql_exchange *exchange;
File file;
IO_CACHE cache;
ha_rows row_count;
char path[FN_REFLEN];
public:
select_dump(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L)
{ path[0]=0; }
~select_dump();
int prepare(List<Item> &list);
bool send_fields(List<Item> &list,
uint flag) { return 0; }
bool send_data(List<Item> &items);
void send_error(uint errcode,const char *err);
bool send_eof();
};
class select_insert :public select_result {
protected:
TABLE *table;
List<Item> *fields;
uint save_time_stamp;
ulonglong last_insert_id;
COPY_INFO info;
public:
select_insert(TABLE *table_par,List<Item> *fields_par,enum_duplicates duplic)
:table(table_par),fields(fields_par), save_time_stamp(0),last_insert_id(0)
{
bzero((char*) &info,sizeof(info));
info.handle_duplicates=duplic;
}
~select_insert();
int prepare(List<Item> &list);
bool send_fields(List<Item> &list,
uint flag) { return 0; }
bool send_data(List<Item> &items);
void send_error(uint errcode,const char *err);
bool send_eof();
};
class select_create: public select_insert {
ORDER *group;
const char *db;
const char *name;
List<create_field> *extra_fields;
List<Key> *keys;
HA_CREATE_INFO *create_info;
MYSQL_LOCK *lock;
Field **field;
public:
select_create (const char *db_name, const char *table_name,
HA_CREATE_INFO *create_info_par,
List<create_field> &fields_par,
List<Key> &keys_par,
List<Item> &select_fields,enum_duplicates duplic)
:select_insert (NULL, &select_fields, duplic), db(db_name),
name(table_name), extra_fields(&fields_par),keys(&keys_par),
create_info(create_info_par),
lock(0)
{}
int prepare(List<Item> &list);
bool send_data(List<Item> &values);
bool send_eof();
void abort();
};
/* Structs used when sorting */
typedef struct st_sort_field {
Field *field; /* Field to sort */
Item *item; /* Item if not sorting fields */
uint length; /* Length of sort field */
my_bool reverse; /* if descending sort */
Item_result result_type; /* Type of item */
} SORT_FIELD;
typedef struct st_sort_buffer {
uint index; /* 0 or 1 */
uint sort_orders;
uint change_pos; /* If sort-fields changed */
char **buff;
SORT_FIELD *sortorder;
} SORT_BUFFER;
/* Structure for db & table in sql_yacc */
class Table_ident :public Sql_alloc {
public:
LEX_STRING db;
LEX_STRING table;
inline Table_ident(LEX_STRING db_arg,LEX_STRING table_arg,bool force)
:table(table_arg)
{
if (!force && (current_thd->client_capabilities & CLIENT_NO_SCHEMA))
db.str=0;
else
db= db_arg;
}
inline Table_ident(LEX_STRING table_arg) :table(table_arg) {db.str=0;}
inline void change_db(char *db_name)
{ db.str= db_name; db.length=(uint) strlen(db_name); }
};
// this is needed for user_vars hash
class user_var_entry
{
public:
LEX_STRING name;
char *value;
ulong length;
Item_result type;
};