1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

WL#2246 "IM: Add ability to change instance options, add server logs handling" ported to the

current version of the IM
This commit is contained in:
petr@mysql.com
2005-04-09 14:28:39 +04:00
parent eeeedd31b9
commit 83f9ee0786
15 changed files with 1053 additions and 48 deletions

View File

@ -15,38 +15,56 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "parse.h"
#include "factory.h"
#include <string.h>
enum Token
{
TOK_FLUSH = 0,
TOK_ERROR= 0, /* Encodes the "ERROR" word, it doesn't indicate error. */
TOK_FILES,
TOK_FLUSH,
TOK_GENERAL,
TOK_INSTANCE,
TOK_INSTANCES,
TOK_LOG,
TOK_OPTIONS,
TOK_SET,
TOK_SLOW,
TOK_START,
TOK_STATUS,
TOK_STOP,
TOK_SHOW,
TOK_UNSET,
TOK_NOT_FOUND, // must be after all tokens
TOK_END
};
struct tokens_st
{
uint length;
const char *tok_name;
};
static struct tokens_st tokens[]= {
{5, "ERROR"},
{5, "FILES"},
{5, "FLUSH"},
{7, "GENERAL"},
{8, "INSTANCE"},
{9, "INSTANCES"},
{3, "LOG"},
{7, "OPTIONS"},
{3, "SET"},
{4, "SLOW"},
{5, "START"},
{6, "STATUS"},
{4, "STOP"},
{4, "SHOW"}
{4, "SHOW"},
{5, "UNSET"}
};
@ -86,13 +104,6 @@ Token shift_token(const char **text, uint *word_len)
}
void print_token(const char *token, uint tok_len)
{
for (uint i= 0; i < tok_len; ++i)
printf("%c", token[i]);
}
int get_text_id(const char **text, uint *word_len, const char **id)
{
get_word(text, word_len);
@ -108,7 +119,15 @@ Command *parse_command(Command_factory *factory, const char *text)
uint word_len;
const char *instance_name;
uint instance_name_len;
const char *option;
uint option_len;
const char *option_value;
uint option_value_len;
const char *log_size;
Command *command;
const char *saved_text= text;
bool skip= false;
const char *tmp;
Token tok1= shift_token(&text, &word_len);
@ -143,6 +162,55 @@ Command *parse_command(Command_factory *factory, const char *text)
command= factory->new_Flush_instances();
break;
case TOK_UNSET:
skip= true;
case TOK_SET:
get_text_id(&text, &instance_name_len, &instance_name);
text+= instance_name_len;
/* the next token should be a dot */
get_word(&text, &word_len);
if (*text != '.')
goto syntax_error;
text++;
get_word(&text, &option_len, NONSPACE);
option= text;
if ((tmp= strchr(text, '=')) != NULL)
option_len= tmp - text;
text+= option_len;
get_word(&text, &word_len);
if (*text == '=')
{
text++; /* skip '=' */
get_word(&text, &option_value_len, NONSPACE);
option_value= text;
text+= option_value_len;
}
else
{
option_value= "";
option_value_len= 0;
}
/* should be empty */
get_word(&text, &word_len);
if (word_len)
{
goto syntax_error;
}
if (skip)
command= factory->new_Unset_option(instance_name, instance_name_len,
option, option_len, option_value,
option_value_len);
else
command= factory->new_Set_option(instance_name, instance_name_len,
option, option_len, option_value,
option_value_len);
break;
case TOK_SHOW:
switch (shift_token(&text, &word_len)) {
case TOK_INSTANCES:
@ -157,6 +225,7 @@ Command *parse_command(Command_factory *factory, const char *text)
case TOK_STATUS:
get_text_id(&text, &instance_name_len, &instance_name);
text+= instance_name_len;
/* check that this is the end of the command */
get_word(&text, &word_len);
if (word_len)
goto syntax_error;
@ -172,7 +241,87 @@ Command *parse_command(Command_factory *factory, const char *text)
}
break;
default:
goto syntax_error;
instance_name= text - word_len;
instance_name_len= word_len;
if (instance_name_len)
{
Log_type log_type;
switch (shift_token(&text, &word_len)) {
case TOK_LOG:
switch (Token tok3= shift_token(&text, &word_len)) {
case TOK_FILES:
get_word(&text, &word_len);
/* check that this is the end of the command */
if (word_len)
goto syntax_error;
command= (Command *)
factory->new_Show_instance_log_files(instance_name,
instance_name_len);
break;
case TOK_ERROR:
case TOK_GENERAL:
case TOK_SLOW:
/* define a log type */
switch (tok3) {
case TOK_ERROR:
log_type= LOG_ERROR;
break;
case TOK_GENERAL:
log_type= LOG_GENERAL;
break;
case TOK_SLOW:
log_type= LOG_SLOW;
break;
default:
goto syntax_error;
}
/* get the size of the log we want to retrieve */
get_text_id(&text, &word_len, &log_size);
text+= word_len;
/* this parameter is required */
if (!word_len)
goto syntax_error;
/* the next token should be comma, or nothing */
get_word(&text, &word_len);
switch (*text) {
case ',':
text++; /* swallow the comma */
/* read the next word */
get_word(&text, &word_len);
if (!word_len)
goto syntax_error;
command= (Command *)
factory->new_Show_instance_log(instance_name,
instance_name_len,
log_type,
log_size,
text);
//get_text_id(&text, &log_size_len, &log_size);
break;
case '\0':
command= (Command *)
factory->new_Show_instance_log(instance_name,
instance_name_len,
log_type,
log_size,
NULL);
break; /* this is ok */
default:
goto syntax_error;
}
break;
default:
goto syntax_error;
}
break;
default:
goto syntax_error;
}
}
else
goto syntax_error;
break;
}
break;
default:
@ -182,3 +331,43 @@ syntax_error:
return command;
}
/* additional parse function, needed to parse */
/* create an array of strings from the output, starting from "word" */
int parse_arguments(const char *command, const char *word, char *result,
int max_result_cardinality, size_t option_len)
{
int wordlen;
int i= 0; /* result array index */
/* should be enough to store the string from the output */
enum { MAX_LINE_LEN= 4096 };
char linebuf[MAX_LINE_LEN];
wordlen= strlen(word);
uint lineword_len= 0;
const char *linep= command;
get_word((const char **) &linep, &lineword_len, NONSPACE);
while ((*linep != '\0') && (i < max_result_cardinality))
{
if (!strncmp(word, linep, wordlen))
{
strncpy(result + i*option_len, linep, lineword_len);
*(result + i*option_len + lineword_len)= '\0';
linep+= lineword_len;
i++;
}
else
linep+= lineword_len;
get_word((const char **) &linep, &lineword_len, NONSPACE);
/* stop if we've filled the array */
if (i >= max_result_cardinality)
break;
}
return 0;
}