mariadb/mysys/default_modify.c
unknown b59217ebbb Slow query log to file now displays queries with microsecond precission
--long-query-time is now given in seconds with microseconds as decimals
--min_examined_row_limit added for slow query log
long_query_time user variable is now double with 6 decimals
Added functions to get time in microseconds
Added faster time() functions for system that has gethrtime()  (Solaris)
We now do less time() calls.
Added field->in_read_set() and field->in_write_set() for easier field manipulation by handlers
set_var.cc and my_getopt() can now handle DOUBLE variables.
All time() calls changed to my_time()
my_time() now does retry's if time() call fails.
Added debug function for stopping in mysql_admin_table() when tables are locked
Some trivial function and struct variable renames to avoid merge errors.
Fixed compiler warnings
Initialization of some time variables on windows moved to my_init() 


include/my_getopt.h:
  Added support for double arguments
include/my_sys.h:
  Fixed wrong type to packfrm()
  Added new my_time functions
include/mysql/plugin.h:
  Added support for DOUBLE
libmysql/CMakeLists.txt:
  Added new time functions
libmysql/Makefile.shared:
  Added new time functions
mysql-test/r/variables.result:
  Testing of long_query_time
mysql-test/t/variables.test:
  Testing of long_query_time
mysys/charset.c:
  Fixed compiler warnings
mysys/default_modify.c:
  Fixed compiler warnings
mysys/hash.c:
  Fixed compiler warnings
mysys/mf_getdate.c:
  Use my_time()
mysys/mf_iocache2.c:
  Fixed compiler warnings
mysys/mf_pack.c:
  Fixed compiler warnings
mysys/mf_path.c:
  Fixed compiler warnings
mysys/my_append.c:
  Fixed compiler warnings
mysys/my_compress.c:
  Fixed compiler warnings
mysys/my_copy.c:
  Fixed compiler warnings
mysys/my_gethwaddr.c:
  Fixed compiler warnings
mysys/my_getopt.c:
  Added support for double arguments
mysys/my_getsystime.c:
  Added functions to get time in microseconds.
  Added faster time() functions for system that has gethrtime()  (Solaris)
  Moved windows initialization code to my_init()
mysys/my_init.c:
  Added initializing of variables needed for windows time functions
mysys/my_static.c:
  Added variables needed for windows time functions
mysys/my_static.h:
  Added variables needed for windows time functions
mysys/my_thr_init.c:
  Added THR_LOCK_time, used for faster my_time()
mysys/mysys_priv.h:
  Added THR_LOCK_time, used for faster my_time()
mysys/thr_alarm.c:
  time() -> my_time()
sql/event_data_objects.cc:
  end_time() -> set_current_time()
sql/event_queue.cc:
  end_time() -> set_current_time()
sql/event_scheduler.cc:
  Fixed compiler warnings
sql/field.h:
  Added field->in_read_set() and field->in_write_set() for easier field manipulation by handlers
sql/item.h:
  Added decimal to Item_float(double)
sql/item_cmpfunc.h:
  Added decimal to Item_float(double)
sql/item_timefunc.cc:
  time() -> my_time()
sql/item_xmlfunc.cc:
  Fixed compiler warning
sql/lock.cc:
  lock_time() -> set_time_after_lock()
sql/log.cc:
  Timing in slow query log to file is now done in microseconds
  Changed some while() loops to for() loops.
  Fixed indentation
  time() -> my_time()
sql/log.h:
  Slow query logging is now done based on microseconds
sql/log_event.cc:
  time() -> my_time()
  Fixed arguments to new Item_float()
sql/mysql_priv.h:
  Fixed compiler warnings
  Added opt_log_slow_slave_statements
sql/mysqld.cc:
  Added --log_slow_slave_statements and --min_examined_row_limit
  --long-query-time now takes a double argument with microsecond resolution
  Don't write shutdown message when using --help
  Removed not needed \n
  Thread create time and connect time is now done in microseconds
  time() -> my_time()
  Avoid some time() calls
sql/net_serv.cc:
  Fixed compiler warnings
sql/parse_file.cc:
  time() -> my_time()
sql/set_var.cc:
  Added support for DOUBLE variables
  Added support for variables that are given in seconds with microsecond resolution
sql/set_var.h:
  Added support for variables that are given in seconds with microsecond resolution
sql/slave.cc:
  Allow logging of slave queries to slow query log if 'opt_log_slow_slave_statements' is given
  time() -> my_time()
sql/sql_cache.h:
  Fixed compiler warning()
sql/sql_class.cc:
  Initialize new THD variables
sql/sql_class.h:
  long_query_time is now in microseconds
  Added min_examined_row_limit
  Reordered some THD elements for higher efficency
  Added timers in microseconds (connect_utime, thr_create_utime, start_utime and utime_after_lock)
  Start of query is now recorded both in seconds and in microseconds.
  Following renames was made for more clarity and avoid merge problems from earlier versions:
  connect_time -> connect_utime
  thr_create_time -> thr_create_utime
  end_time()  -> set_current_time()
  lock_time() -> set_time_after_lock()
  
  Added THD::start_utime, which is start of query in microseconds from some arbitary time
  Added function THD::current_utime()
  
  Removed safe_time() as retry's are handled in my_time()
sql/sql_connect.cc:
  User resources are now using microsecond resolution
sql/sql_insert.cc:
  end_time() -> set_current_time()
sql-common/client.c:
  time() -> my_time()
sql/sql_parse.cc:
  Testing if we should print to slow_query_log() is now done with microsecond precission.
  If min_examined_row_limit is given, only log queries to slow query log that has examined more rows than this.
sql/sql_select.cc:
  Simplify code now that Item_float() takes decimals as argument
sql/sql_show.cc:
  time() -> my_time()
  Added support for SYS_DOUBLE
sql/sql_table.cc:
  Added debug function for stopping in mysql_admin_table() when tables are locked
sql/structs.h:
  intime -> reset_utime
2007-07-30 11:33:50 +03:00

254 lines
8.2 KiB
C

/* Copyright (C) 2005 MySQL 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; version 2 of the License.
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 */
#include "my_global.h"
#include "mysys_priv.h"
#include "m_string.h"
#include <my_dir.h>
#define BUFF_SIZE 1024
#define RESERVE 1024 /* Extend buffer with this extent */
#ifdef __WIN__
#define NEWLINE "\r\n"
#define NEWLINE_LEN 2
#else
#define NEWLINE "\n"
#define NEWLINE_LEN 1
#endif
static char *add_option(char *dst, const char *option_value,
const char *option, int remove_option);
/*
Add/remove option to the option file section.
SYNOPSYS
modify_defaults_file()
file_location The location of configuration file to edit
option The name of the option to look for (can be NULL)
option value The value of the option we would like to set (can be NULL)
section_name The name of the section (must be NOT NULL)
remove_option This defines what we want to remove:
- MY_REMOVE_NONE -- nothing to remove;
- MY_REMOVE_OPTION -- remove the specified option;
- MY_REMOVE_SECTION -- remove the specified section;
IMPLEMENTATION
We open the option file first, then read the file line-by-line,
looking for the section we need. At the same time we put these lines
into a buffer. Then we look for the option within this section and
change/remove it. In the end we get a buffer with modified version of the
file. Then we write it to the file, truncate it if needed and close it.
Note that there is a small time gap, when the file is incomplete,
and this theoretically might introduce a problem.
RETURN
0 - ok
1 - some error has occured. Probably due to the lack of resourses
2 - cannot open the file
*/
int modify_defaults_file(const char *file_location, const char *option,
const char *option_value,
const char *section_name, int remove_option)
{
FILE *cnf_file;
MY_STAT file_stat;
char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer;
size_t opt_len= 0, optval_len= 0, sect_len;
uint nr_newlines= 0, buffer_size;
my_bool in_section= FALSE, opt_applied= 0;
uint reserve_extended;
uint new_opt_len;
int reserve_occupied= 0;
DBUG_ENTER("modify_defaults_file");
if (!(cnf_file= my_fopen(file_location, O_RDWR | O_BINARY, MYF(0))))
DBUG_RETURN(2);
/* my_fstat doesn't use the flag parameter */
if (my_fstat(fileno(cnf_file), &file_stat, MYF(0)))
goto malloc_err;
if (option && option_value)
{
opt_len= strlen(option);
optval_len= strlen(option_value);
}
new_opt_len= opt_len + 1 + optval_len + NEWLINE_LEN;
/* calculate the size of the buffer we need */
reserve_extended= (opt_len +
1 + /* For '=' char */
optval_len + /* Option value len */
NEWLINE_LEN + /* Space for newline */
RESERVE); /* Some additional space */
buffer_size= (file_stat.st_size +
1); /* The ending zero */
/*
Reserve space to read the contents of the file and some more
for the option we want to add.
*/
if (!(file_buffer= (char*) my_malloc(buffer_size + reserve_extended,
MYF(MY_WME))))
goto malloc_err;
sect_len= strlen(section_name);
for (dst_ptr= file_buffer; fgets(linebuff, BUFF_SIZE, cnf_file); )
{
/* Skip over whitespaces */
for (src_ptr= linebuff; my_isspace(&my_charset_latin1, *src_ptr);
src_ptr++)
{}
if (!*src_ptr) /* Empty line */
{
nr_newlines++;
continue;
}
/* correct the option (if requested) */
if (option && in_section && !strncmp(src_ptr, option, opt_len) &&
(*(src_ptr + opt_len) == '=' ||
my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) ||
*(src_ptr + opt_len) == '\0'))
{
char *old_src_ptr= src_ptr;
src_ptr= strend(src_ptr+ opt_len); /* Find the end of the line */
/* could be negative */
reserve_occupied+= (int) new_opt_len - (int) (src_ptr - old_src_ptr);
if (reserve_occupied >= (int) reserve_extended)
{
reserve_extended= (uint) reserve_occupied + RESERVE;
if (!(file_buffer= (char*) my_realloc(file_buffer, buffer_size +
reserve_extended,
MYF(MY_WME|MY_FREE_ON_ERROR))))
goto malloc_err;
}
opt_applied= 1;
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
}
else
{
/*
If we are going to the new group and have an option to apply, do
it now. If we are removing a single option or the whole section
this will only trigger opt_applied flag.
*/
if (in_section && !opt_applied && *src_ptr == '[')
{
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
opt_applied= 1; /* set the flag to do write() later */
reserve_occupied= new_opt_len+ opt_len + 1 + NEWLINE_LEN;
}
for (; nr_newlines; nr_newlines--)
dst_ptr= strmov(dst_ptr, NEWLINE);
/* Skip the section if MY_REMOVE_SECTION was given */
if (!in_section || remove_option != MY_REMOVE_SECTION)
dst_ptr= strmov(dst_ptr, linebuff);
}
/* Look for a section */
if (*src_ptr == '[')
{
/* Copy the line to the buffer */
if (!strncmp(++src_ptr, section_name, sect_len))
{
src_ptr+= sect_len;
/* Skip over whitespaces. They are allowed after section name */
for (; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++)
{}
if (*src_ptr != ']')
{
in_section= FALSE;
continue; /* Missing closing parenthesis. Assume this was no group */
}
if (remove_option == MY_REMOVE_SECTION)
dst_ptr= dst_ptr - strlen(linebuff);
in_section= TRUE;
}
else
in_section= FALSE; /* mark that this section is of no interest to us */
}
}
/*
File ended. Apply an option or set opt_applied flag (in case of
MY_REMOVE_SECTION) so that the changes are saved. Do not do anything
if we are removing non-existent option.
*/
if (!opt_applied && in_section && (remove_option != MY_REMOVE_OPTION))
{
/* New option still remains to apply at the end */
if (!remove_option && *(dst_ptr - 1) != '\n')
dst_ptr= strmov(dst_ptr, NEWLINE);
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
opt_applied= 1;
}
for (; nr_newlines; nr_newlines--)
dst_ptr= strmov(dst_ptr, NEWLINE);
if (opt_applied)
{
/* Don't write the file if there are no changes to be made */
if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
MYF(MY_WME)) ||
my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) ||
my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer),
MYF(MY_NABP)))
goto err;
}
if (my_fclose(cnf_file, MYF(MY_WME)))
DBUG_RETURN(1);
my_free(file_buffer, MYF(0));
DBUG_RETURN(0);
err:
my_free(file_buffer, MYF(0));
malloc_err:
my_fclose(cnf_file, MYF(0));
DBUG_RETURN(1); /* out of resources */
}
static char *add_option(char *dst, const char *option_value,
const char *option, int remove_option)
{
if (!remove_option)
{
dst= strmov(dst, option);
if (*option_value)
{
*dst++= '=';
dst= strmov(dst, option_value);
}
/* add a newline */
dst= strmov(dst, NEWLINE);
}
return dst;
}