mariadb/sql/parse_file.cc

786 lines
18 KiB
C++
Raw Normal View History

file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
/* Copyright (C) 2004 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; 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 */
// Text .frm files management routines
#include "mysql_priv.h"
#include <errno.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <my_dir.h>
/*
write string with escaping
SYNOPSIS
write_escaped_string()
file - IO_CACHE for record
val_s - string for writing
RETURN
FALSE - OK
TRUE - error
*/
static my_bool
write_escaped_string(IO_CACHE *file, LEX_STRING *val_s)
{
char *eos= val_s->str + val_s->length;
char *ptr= val_s->str;
for (; ptr < eos; ptr++)
{
/*
Should be in sync with read_escaped_string() and
parse_quated_escaped_string()
*/
switch(*ptr) {
case '\\': // escape character
if (my_b_append(file, "\\\\", 2))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
return TRUE;
break;
case '\n': // parameter value delimiter
if (my_b_append(file, "\\n", 2))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
return TRUE;
break;
case '\0': // problem for some string processing utilites
if (my_b_append(file, "\\0", 2))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
return TRUE;
break;
case 26: // problem for windows utilites (Ctrl-Z)
if (my_b_append(file, "\\z", 2))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
return TRUE;
break;
case '\'': // list of string delimiter
if (my_b_append(file, "\\\'", 2))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
return TRUE;
break;
default:
if (my_b_append(file, ptr, 1))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
return TRUE;
}
}
return FALSE;
}
/*
write parameter value to IO_CACHE
SYNOPSIS
write_parameter()
file pointer to IO_CACHE structure for writing
base pointer to data structure
parameter pointer to parameter descriptor
old_version for returning back old version number value
RETURN
FALSE - OK
TRUE - error
*/
static my_bool
write_parameter(IO_CACHE *file, gptr base, File_option *parameter,
ulonglong *old_version)
{
char num_buf[20]; // buffer for numeric operations
// string for numeric operations
String num(num_buf, sizeof(num_buf), &my_charset_bin);
DBUG_ENTER("write_parameter");
switch (parameter->type) {
case FILE_OPTIONS_STRING:
{
LEX_STRING *val_s= (LEX_STRING *)(base + parameter->offset);
if (my_b_append(file, val_s->str, val_s->length))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
DBUG_RETURN(TRUE);
break;
}
case FILE_OPTIONS_ESTRING:
{
if (write_escaped_string(file, (LEX_STRING *)(base + parameter->offset)))
DBUG_RETURN(TRUE);
break;
}
case FILE_OPTIONS_ULONGLONG:
{
num.set(*((ulonglong *)(base + parameter->offset)), &my_charset_bin);
if (my_b_append(file, num.ptr(), num.length()))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
DBUG_RETURN(TRUE);
break;
}
case FILE_OPTIONS_REV:
{
ulonglong *val_i= (ulonglong *)(base + parameter->offset);
*old_version= (*val_i)++;
num.set(*val_i, &my_charset_bin);
if (my_b_append(file, num.ptr(), num.length()))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
DBUG_RETURN(TRUE);
break;
}
case FILE_OPTIONS_TIMESTAMP:
{
/* string have to be allocated already */
LEX_STRING *val_s= (LEX_STRING *)(base + parameter->offset);
time_t tm= time(NULL);
get_date(val_s->str, GETDATE_DATE_TIME|GETDATE_GMT|GETDATE_FIXEDLENGTH,
tm);
val_s->length= PARSE_FILE_TIMESTAMPLENGTH;
if (my_b_append(file, val_s->str, PARSE_FILE_TIMESTAMPLENGTH))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
DBUG_RETURN(TRUE);
break;
}
case FILE_OPTIONS_STRLIST:
{
List_iterator_fast<LEX_STRING> it(*((List<LEX_STRING>*)
(base + parameter->offset)));
bool first= 1;
LEX_STRING *str;
while ((str= it++))
{
num.set((ulonglong)str->length, &my_charset_bin);
// ',' after string to detect list continuation
if ((!first && my_b_append(file, " ", 1)) ||
my_b_append(file, "\'", 1) ||
my_b_append(file, str->str, str->length) ||
my_b_append(file, "\'", 1))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
{
DBUG_RETURN(TRUE);
}
first= 0;
}
break;
}
default:
DBUG_ASSERT(0); // never should happened
}
DBUG_RETURN(FALSE);
}
/*
write new .frm
SYNOPSIS
sql_create_definition_file()
dir directory where put .frm
file .frm file name
type .frm type string (VIEW, TABLE)
base base address for parameter reading (structure like
TABLE)
parameters parameters description
max_versions number of versions to save
RETURN
FALSE - OK
TRUE - error
*/
my_bool
sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
const LEX_STRING *type,
gptr base, File_option *parameters,
uint max_versions)
{
File handler;
IO_CACHE file;
char path[FN_REFLEN+1]; // +1 to put temporary file name for sure
ulonglong old_version= ULONGLONG_MAX;
int path_end;
DBUG_ENTER("sql_create_definition_file");
DBUG_PRINT("enter", ("Dir: %s, file: %s, base 0x%lx",
dir->str, file_name->str, (ulong) base));
fn_format(path, file_name->str, dir->str, 0, MY_UNPACK_FILENAME);
path_end= strlen(path);
// temporary file name
path[path_end]='~';
path[path_end+1]= '\0';
if ((handler= my_create(path, CREATE_MODE, O_RDWR | O_TRUNC,
MYF(MY_WME))) <= 0)
{
DBUG_RETURN(TRUE);
}
if (init_io_cache(&file, handler, 0, SEQ_READ_APPEND, 0L, 0, MYF(MY_WME)))
goto err_w_file;
// write header (file signature)
if (my_b_append(&file, "TYPE=", 5) ||
my_b_append(&file, type->str, type->length) ||
my_b_append(&file, "\n", 1))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
goto err_w_file;
// write parameters to temporary file
for (File_option *param= parameters; param->name.str; param++)
{
if (my_b_append(&file, param->name.str, param->name.length) ||
my_b_append(&file, "=", 1) ||
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
write_parameter(&file, base, param, &old_version) ||
my_b_append(&file, "\n", 1))
file parser for new .frm include/my_sys.h: names for get_date format flags include/mysqld_error.h: error of parser libmysqld/Makefile.am: parser file added mysys/mf_getdate.c: function comment for get_date() 2 new flags added names for get_date format flags sql/Makefile.am: parser file added sql/mysql_priv.h: parser file added sql/share/czech/errmsg.txt: file parser errors sql/share/danish/errmsg.txt: file parser errors sql/share/dutch/errmsg.txt: file parser errors sql/share/english/errmsg.txt: file parser errors sql/share/estonian/errmsg.txt: file parser errors sql/share/french/errmsg.txt: file parser errors sql/share/german/errmsg.txt: file parser errors sql/share/greek/errmsg.txt: file parser errors sql/share/hungarian/errmsg.txt: file parser errors sql/share/italian/errmsg.txt: file parser errors sql/share/japanese/errmsg.txt: file parser errors sql/share/korean/errmsg.txt: file parser errors sql/share/norwegian-ny/errmsg.txt: file parser errors sql/share/norwegian/errmsg.txt: file parser errors sql/share/polish/errmsg.txt: file parser errors sql/share/portuguese/errmsg.txt: file parser errors sql/share/romanian/errmsg.txt: file parser errors sql/share/russian/errmsg.txt: file parser errors sql/share/serbian/errmsg.txt: file parser errors sql/share/slovak/errmsg.txt: file parser errors sql/share/spanish/errmsg.txt: file parser errors sql/share/swedish/errmsg.txt: file parser errors sql/share/ukrainian/errmsg.txt: file parser errors BitKeeper/etc/ignore: Added libmysqld/parse_file.cc to the ignore list
2004-05-11 22:23:49 +02:00
goto err_w_cache;
}
if (end_io_cache(&file))
goto err_w_file;
if (my_close(handler, MYF(MY_WME)))
{
DBUG_RETURN(TRUE);
}
// archive copies management
path[path_end]='\0';
if (!access(path, F_OK))
{
if (old_version != ULONGLONG_MAX && max_versions != 0)
{
// save buckup
char path_arc[FN_REFLEN];
// backup old version
char path_to[FN_REFLEN];
// check archive directory existence
fn_format(path_arc, "arc", dir->str, "", MY_UNPACK_FILENAME);
if (access(path_arc, F_OK))
{
if (my_mkdir(path_arc, 0777, MYF(MY_WME)))
{
DBUG_RETURN(TRUE);
}
}
my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lld",
path_arc, file_name->str, old_version);
if (my_rename(path, path_to, MYF(MY_WME)))
{
DBUG_RETURN(TRUE);
}
// remove very old version
if (old_version > max_versions)
{
my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lld",
path_arc, file_name->str,
old_version - max_versions);
if (!access(path_arc, F_OK) && my_delete(path_to, MYF(MY_WME)))
{
DBUG_RETURN(TRUE);
}
}
}
else
{
if (my_delete(path, MYF(MY_WME))) // no backups
{
DBUG_RETURN(TRUE);
}
}
}
{
// rename temporary file
char path_to[FN_REFLEN];
memcpy(path_to, path, path_end+1);
path[path_end]='~';
if (my_rename(path, path_to, MYF(MY_WME)))
{
DBUG_RETURN(TRUE);
}
}
DBUG_RETURN(FALSE);
err_w_cache:
end_io_cache(&file);
err_w_file:
my_close(handler, MYF(MY_WME));
DBUG_RETURN(TRUE);
}
/*
Prepare frm to parse (read to memory)
SYNOPSIS
sql_parse_prepare()
file_name - path & filename to .frm file
mem_root - MEM_ROOT for buffer allocation
bad_format_errors - send errors on bad content
RETURN
0 - error
parser object
NOTE
returned pointer + 1 will be type of .frm
*/
File_parser *
sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root,
bool bad_format_errors)
{
MY_STAT stat_info;
uint len;
char *end, *sign;
File_parser *parser;
File file;
DBUG_ENTER("sql__parse_prepare");
if (!my_stat(file_name->str, &stat_info, MYF(MY_WME)))
{
DBUG_RETURN(0);
}
if (stat_info.st_size > INT_MAX-1)
{
my_error(ER_FPARSER_TOO_BIG_FILE, MYF(0), file_name->str);
DBUG_RETURN(0);
}
if (!(parser= new(mem_root) File_parser))
{
DBUG_RETURN(0);
}
if (!(parser->buff= alloc_root(mem_root, stat_info.st_size+1)))
{
DBUG_RETURN(0);
}
if ((file= my_open(file_name->str, O_RDONLY | O_SHARE, MYF(MY_WME))) < 0)
{
DBUG_RETURN(0);
}
if ((len= my_read(file, parser->buff, stat_info.st_size, MYF(MY_WME))) ==
MY_FILE_ERROR)
{
my_close(file, MYF(MY_WME));
DBUG_RETURN(0);
}
if (my_close(file, MYF(MY_WME)))
{
DBUG_RETURN(0);
}
end= parser->end= parser->buff + len;
*end= '\0'; // barriaer for more simple parsing
// 7 = 5 (TYPE=) + 1 (leter at least of type name) + 1 ('\n')
if (len < 7 ||
parser->buff[0] != 'T' ||
parser->buff[1] != 'Y' ||
parser->buff[2] != 'P' ||
parser->buff[3] != 'E' ||
parser->buff[4] != '=')
goto frm_error;
// skip signature;
parser->file_type.str= sign= parser->buff + 5;
while (*sign >= 'A' && *sign <= 'Z' && sign < end)
sign++;
if (*sign != '\n')
goto frm_error;
parser->file_type.length= sign - parser->file_type.str;
// EOS for file signature just for safety
*sign= '\0';
parser->start= sign + 1;
parser->content_ok= 1;
DBUG_RETURN(parser);
frm_error:
if (bad_format_errors)
{
my_error(ER_FPARSER_BAD_HEADER, MYF(0), file_name->str);
DBUG_RETURN(0);
}
else
DBUG_RETURN(parser); // upper level have to check parser->ok()
}
/*
parse LEX_STRING
SYNOPSIS
parse_string()
ptr - pointer on string beginning
end - pointer on symbol after parsed string end (still owned
by buffer and can be accessed
mem_root - MEM_ROOT for parameter allocation
str - pointer on string, where results should be stored
RETURN
0 - error
# - pointer on symbol after string
*/
static char *
parse_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
{
// get string length
char *eol= strchr(ptr, '\n');
if (eol >= end)
return 0;
str->length= eol - ptr;
if (!(str->str= alloc_root(mem_root, str->length+1)))
return 0;
memcpy(str->str, ptr, str->length);
str->str[str->length]= '\0'; // just for safety
return eol+1;
}
/*
read escaped string from ptr to eol in already allocated str
SYNOPSIS
parse_escaped_string()
ptr - pointer on string beginning
eol - pointer on character after end of string
str - target string
RETURN
FALSE - OK
TRUE - error
*/
my_bool
read_escaped_string(char *ptr, char *eol, LEX_STRING *str)
{
char *write_pos= str->str;
for(; ptr < eol; ptr++, write_pos++)
{
char c= *ptr;
if (c == '\\')
{
ptr++;
if (ptr >= eol)
return TRUE;
/*
Should be in sync with write_escaped_string() and
parse_quated_escaped_string()
*/
switch(*ptr) {
case '\\':
*write_pos= '\\';
break;
case 'n':
*write_pos= '\n';
break;
case '0':
*write_pos= '\0';
break;
case 'z':
*write_pos= 26;
break;
case '\'':
*write_pos= '\'';
default:
return TRUE;
}
}
else
*write_pos= c;
}
str->str[str->length= write_pos-str->str]= '\0'; // just for safety
return FALSE;
}
/*
parse \n delimited escaped string
SYNOPSIS
parse_escaped_string()
ptr - pointer on string beginning
end - pointer on symbol after parsed string end (still owned
by buffer and can be accessed
mem_root - MEM_ROOT for parameter allocation
str - pointer on string, where results should be stored
RETURN
0 - error
# - pointer on symbol after string
*/
static char *
parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
{
char *eol= strchr(ptr, '\n');
if (eol == 0 || eol >= end ||
!(str->str= alloc_root(mem_root, (eol - ptr) + 1)) ||
read_escaped_string(ptr, eol, str))
return 0;
return eol+1;
}
/*
parse '' delimited escaped string
SYNOPSIS
parse_escaped_string()
ptr - pointer on string beginning
end - pointer on symbol after parsed string end (still owned
by buffer and can be accessed
mem_root - MEM_ROOT for parameter allocation
str - pointer on string, where results should be stored
RETURN
0 - error
# - pointer on symbol after string
*/
static char *
parse_quated_escaped_string(char *ptr, char *end,
MEM_ROOT *mem_root, LEX_STRING *str)
{
char *eol;
uint result_len= 0;
bool escaped= 0;
// starting '
if (*(ptr++) != '\'')
return 0;
// find ending '
for (eol= ptr; (*eol != '\'' || escaped) && eol < end; eol++)
{
if (!(escaped= (*eol == '\\' && !escaped)))
result_len++;
}
// process string
if (eol >= end ||
!(str->str= alloc_root(mem_root, result_len + 1)) ||
read_escaped_string(ptr, eol, str))
return 0;
return eol+1;
}
/*
parse parameters
SYNOPSIS
File_parser::parse()
base base address for parameter writing (structure like
TABLE)
mem_root MEM_ROOT for parameters allocation
parameters parameters description
required number of required parameters in above list
RETURN
FALSE - OK
TRUE - error
*/
my_bool
File_parser::parse(gptr base, MEM_ROOT *mem_root,
struct File_option *parameters, uint required)
{
uint first_param= 0, found= 0;
register char *ptr= start;
char *eol;
LEX_STRING *str;
MEM_ROOT *sql_mem;
List<LEX_STRING> *list;
bool change_mem;
DBUG_ENTER("File_parser::parse");
while (ptr < end && found < required)
{
char *line= ptr;
if (*ptr == '#')
{
// it is comment
if (!(ptr= strchr(ptr, '\n')))
{
my_error(ER_FPARSER_EOF_IN_COMMENT, MYF(0), line);
DBUG_RETURN(TRUE);
}
ptr++;
}
else
{
File_option *parameter= parameters+first_param,
*parameters_end= parameters+required;
int len= 0;
for(; parameter < parameters_end; parameter++)
{
len= parameter->name.length;
// check length
if (len < (end-ptr) && ptr[len] != '=')
continue;
// check keyword
if (memcmp(parameter->name.str, ptr, len) == 0)
break;
}
if (parameter < parameters_end)
{
found++;
/*
if we found first parameter, start search from next parameter
next time.
(this small optimisation should work, because they should be
written in same order)
*/
if (parameter == parameters+first_param)
first_param++;
// get value
ptr+= (len+1);
switch (parameter->type) {
case FILE_OPTIONS_STRING:
{
if (!(ptr= parse_string(ptr, end, mem_root,
(LEX_STRING *)(base +
parameter->offset))))
{
my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
parameter->name.str, line);
DBUG_RETURN(TRUE);
}
break;
}
case FILE_OPTIONS_ESTRING:
{
if (!(ptr= parse_escaped_string(ptr, end, mem_root,
(LEX_STRING *)
(base + parameter->offset))))
{
my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
parameter->name.str, line);
DBUG_RETURN(TRUE);
DBUG_RETURN(TRUE);
}
break;
}
case FILE_OPTIONS_ULONGLONG:
case FILE_OPTIONS_REV:
if (!(eol= strchr(ptr, '\n')))
{
my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
parameter->name.str, line);
DBUG_RETURN(TRUE);
}
*eol= '\0';
*((ulonglong*)(base + parameter->offset))= atoll(ptr);
*eol= '\n';
ptr= eol+1;
break;
case FILE_OPTIONS_TIMESTAMP:
{
/* string have to be allocated already */
LEX_STRING *val= (LEX_STRING *)(base + parameter->offset);
/* yyyy-mm-dd HH:MM:SS = 19(PARSE_FILE_TIMESTAMPLENGTH) characters */
if (ptr[PARSE_FILE_TIMESTAMPLENGTH] != '\n')
{
my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
parameter->name.str, line);
DBUG_RETURN(TRUE);
}
memcpy(val->str, ptr, PARSE_FILE_TIMESTAMPLENGTH);
val->str[val->length= PARSE_FILE_TIMESTAMPLENGTH]= '\0';
ptr+= (PARSE_FILE_TIMESTAMPLENGTH+1);
break;
}
case FILE_OPTIONS_STRLIST:
{
/*
TODO: remove play with mem_root, when List will be able
to store MEM_ROOT* pointer for list elements allocation
*/
sql_mem= my_pthread_getspecific_ptr(MEM_ROOT*, THR_MALLOC);
list= (List<LEX_STRING>*)(base + parameter->offset);
if ((change_mem= (sql_mem != mem_root)))
{
change_mem= 1;
my_pthread_setspecific_ptr(THR_MALLOC, mem_root);
}
list->empty();
// list parsing
while (ptr < end)
{
if (!(str= (LEX_STRING*)alloc_root(mem_root,
sizeof(LEX_STRING))) ||
list->push_back(str))
goto list_err;
if(!(ptr= parse_quated_escaped_string(ptr, end, mem_root, str)))
goto list_err_w_message;
switch (*ptr) {
case '\n':
goto end_of_list;
case ' ':
// we cant go over buffer bounds, because we have \0 at the end
ptr++;
break;
default:
goto list_err_w_message;
}
}
end_of_list:
if (*(ptr++) != '\n')
goto list_err;
if (change_mem)
my_pthread_setspecific_ptr(THR_MALLOC, sql_mem);
break;
list_err_w_message:
my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
parameter->name.str, line);
list_err:
if (change_mem)
my_pthread_setspecific_ptr(THR_MALLOC, sql_mem);
DBUG_RETURN(TRUE);
}
default:
DBUG_ASSERT(0); // never should happened
}
}
else
{
// skip unknown parameter
if (!(ptr= strchr(ptr, '\n')))
{
my_error(ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER, MYF(0),
line);
DBUG_RETURN(TRUE);
}
ptr++;
}
}
}
DBUG_RETURN(FALSE);
}