diff options
author | unknown <vva@genie.(none)> | 2002-10-28 17:44:19 +0400 |
---|---|---|
committer | unknown <vva@genie.(none)> | 2002-10-28 17:44:19 +0400 |
commit | fc4c9c01ee8105888b75f01728f651c4c496cc22 (patch) | |
tree | 79f4355d0503e7a386a562644189da5ab9c08b60 /sql/sql_help.cc | |
parent | d2c7f44ff638ab28970f25baccc87210388588cd (diff) | |
download | mariadb-git-fc4c9c01ee8105888b75f01728f651c4c496cc22.tar.gz |
add help command on server side
include/mysqld_error.h:
add error for corrupt help db
scripts/Makefile.am:
add script for fill help db
scripts/mysql_install_db.sh:
modify for add help db
sql/Makefile.am:
modify for add sql_help.cc
sql/lex.h:
add help command
sql/mysql_priv.h:
add mysqld_help function declaration
sql/share/czech/errmsg.txt:
add message for help-db error
sql/share/danish/errmsg.txt:
add message for help-db error
sql/share/dutch/errmsg.txt:
add message for help-db error
sql/share/english/errmsg.txt:
add message for help-db error
sql/share/estonian/errmsg.txt:
add message for help-db error
sql/share/french/errmsg.txt:
add message for help-db error
sql/share/german/errmsg.txt:
add message for help-db error
sql/share/greek/errmsg.txt:
add message for help-db error
sql/share/hungarian/errmsg.txt:
add message for help-db error
sql/share/italian/errmsg.txt:
add message for help-db error
sql/share/japanese/errmsg.txt:
add message for help-db error
sql/share/korean/errmsg.txt:
add message for help-db error
sql/share/norwegian-ny/errmsg.txt:
add message for help-db error
sql/share/norwegian/errmsg.txt:
add message for help-db error
sql/share/polish/errmsg.txt:
add message for help-db error
sql/share/portuguese/errmsg.txt:
add message for help-db error
sql/share/romanian/errmsg.txt:
add message for help-db error
sql/share/russian/errmsg.txt:
add message for help-db error
sql/share/serbian/errmsg.txt:
add message for help-db error
sql/share/slovak/errmsg.txt:
add message for help-db error
sql/share/spanish/errmsg.txt:
add message for help-db error
sql/share/swedish/errmsg.txt:
add message for help-db error
sql/share/ukrainian/errmsg.txt:
add message for help-db error
sql/sql_lex.h:
add SQLCOM_END
and help_arg in Lex
sql/sql_parse.cc:
add SQLCOM_HELP handler
sql/sql_yacc.yy:
add help command
Diffstat (limited to 'sql/sql_help.cc')
-rw-r--r-- | sql/sql_help.cc | 408 |
1 files changed, 408 insertions, 0 deletions
diff --git a/sql/sql_help.cc b/sql/sql_help.cc new file mode 100644 index 00000000000..72cf1fdff7d --- /dev/null +++ b/sql/sql_help.cc @@ -0,0 +1,408 @@ +/* Copyright (C) 2000 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 */ + +#include "mysql_priv.h" +#include "sql_select.h" // For select_describe +#include "sql_acl.h" + +/*************************************************************************** +** Get help on string +***************************************************************************/ + +MI_INFO *open_help_file(THD *thd, const char *name) +{ + char path[FN_REFLEN]; + (void) sprintf(path,"%s/mysql_help/%s",mysql_data_home,name); + MI_INFO *res= 0; + if (!(res= mi_open(path,O_RDONLY,HA_OPEN_WAIT_IF_LOCKED))) + { + send_error(thd,ER_CORRUPT_HELP_DB); + return 0; + } + mi_extra(res,HA_EXTRA_WAIT_LOCK,0); + return res; +} + +#define size_hf_func_id 4 /* func_id int unsigned, */ +#define size_hf_name 64 /* name varchar(64), */ +#define size_hf_url 128 /* url varchar(128), */ +#define size_hf_description sizeof(char*) /* description text, */ +#define size_hf_example sizeof(char*) /* example text, */ +#define size_hf_min_args 16 /* min_args tinyint, */ +#define size_hf_max_args 16 /* max_args tinyint, */ +#define size_hf_date_created 8 /* date_created datetime, */ +#define size_hf_last_modified 8 /* last_modified timestamp, */ + +#define offset_hf_func_id 1 +#define offset_hf_name (offset_hf_func_id+size_hf_func_id) +#define offset_hf_url (offset_hf_name+size_hf_name) +#define offset_hf_description (offset_hf_url+size_hf_url) +#define offset_hf_example (offset_hf_description+size_hf_description) +#define offset_hf_min_args (offset_hf_example+size_hf_example) +#define offset_hf_max_args (offset_hf_min_args+size_hf_min_args) +#define offset_hf_date_created (offset_hf_max_args+size_hf_max_args) +#define offset_hf_last_modified (offset_hf_date_created+size_hf_date_created) + +#define HELP_LEAF_SIZE (offset_hf_last_modified+size_hf_last_modified) + +class help_leaf{ +public: + char record[HELP_LEAF_SIZE]; + + inline const char *get_name() + { + return &record[offset_hf_name]; + } + + inline const char *get_description() + { + return *((char**)&record[199/*offset_hf_description*/]); + } + + inline const char *get_example() + { + return *((char**)&record[209/*offset_hf_example*/]); + } + + void prepare_fields() + { + const char *name= get_name(); + const char *c= name + size_hf_name - 1; + while (*c==' ') c--; + int len= c-name+1; + ((char*)name)[len]= '\0'; + } +}; + +int search_functions(MI_INFO *file_leafs, const char *mask, + List<String> *names, + String **name, String **description, String **example) +{ + DBUG_ENTER("search_functions"); + int count= 0; + + if(mi_scan_init(file_leafs)) + DBUG_RETURN(-1); + + help_leaf leaf; + + while (!mi_scan(file_leafs,(byte*)&leaf)) + { + leaf.prepare_fields(); + + const char *lname= leaf.get_name(); + if (wild_case_compare(system_charset_info,lname,mask)) + continue; + count++; + + if (count>2) + { + String *s= new String(lname,system_charset_info); + if (!s->copy()) + names->push_back(s); + } + else if (count==1) + { + *description= new String(leaf.get_description(),system_charset_info); + *example= new String(leaf.get_example(),system_charset_info); + *name= new String(lname,system_charset_info); + (*description)->copy(); + (*example)->copy(); + (*name)->copy(); + } + else + { + names->push_back(*name); + delete *description; + delete *example; + *name= 0; + *description= 0; + *example= 0; + + String *s= new String(lname,system_charset_info); + if (!s->copy()) + names->push_back(s); + } + } + + DBUG_RETURN(count); +} + +#define size_hc_cat_id 2 /* cat_id smallint, */ +#define size_hc_name 64 /* name varchar(64), */ +#define size_hc_url 128 /* url varchar(128), */ +#define size_hc_date_created 8 /* date_created datetime, */ +#define size_hc_last_modified 8 /* last_modified timestamp, */ + +#define offset_hc_cat_id 0 +#define offset_hc_name (offset_hc_cat_id+size_hc_cat_id) +#define offset_hc_url (offset_hc_name+size_hc_name) +#define offset_hc_date_created (offset_hc_url+size_hc_url) +#define offset_hc_last_modified (offset_hc_date_created+size_hc_date_created) + +#define HELP_CATEGORY_SIZE (offset_hc_last_modified+size_hc_last_modified) + +class help_category{ +public: + char record[HELP_CATEGORY_SIZE]; + + inline int16 get_cat_id() + { + return sint2korr(&record[offset_hc_cat_id]); + } + + inline const char *get_name() + { + return &record[offset_hc_name]; + } + + void prepare_fields() + { + const char *name= get_name(); + const char *c= name + size_hc_name - 1; + while (*c==' ') c--; + int len= c-name+1; + ((char*)name)[len]= '\0'; + } +}; + +int search_categories(THD *thd, + const char *mask, List<String> *names, int16 *res_id) +{ + DBUG_ENTER("search_categories"); + int count= 0; + + MI_INFO *file_categories= 0; + if (!(file_categories= open_help_file(thd,"function_category_name"))) + DBUG_RETURN(-1); + + if(mi_scan_init(file_categories)) + { + mi_close(file_categories); + DBUG_RETURN(-1); + } + + help_category category; + + + while (!mi_scan(file_categories,(byte*)&category)) + { + category.prepare_fields(); + + const char *lname= category.get_name(); + if (mask && wild_case_compare(system_charset_info,lname,mask)) + continue; + count++; + + if (count==1 && res_id) + *res_id= category.get_cat_id(); + + String *s= new String(lname,system_charset_info); + if (!s->copy()) + names->push_back(s); + } + + mi_close(file_categories); + DBUG_RETURN(count); +} + +int send_variant_2_list(THD *thd, List<String> *names, my_bool is_category) +{ + DBUG_ENTER("send_names"); + + List_iterator<String> it(*names); + String *cur_name; + String *packet= &thd->packet; + while ((cur_name = it++)) + { + packet->length(0); + net_store_data(packet, cur_name->ptr()); + net_store_data(packet, is_category ? "Y" : "N"); + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) + DBUG_RETURN(-1); + } + + DBUG_RETURN(0); +} + +#define size_hcn_cat_id 2 /* cat_id smallint, */ +#define size_hcn_func_id 4 /* func_id int, */ + +#define offset_hcn_cat_id 1 +#define offset_hcn_func_id (offset_hcn_cat_id+size_hcn_cat_id) + +#define HELP_CATEGORY_NAME_SIZE (offset_hcn_func_id + size_hcn_func_id) + +class help_category_leaf{ +public: + char record[HELP_CATEGORY_NAME_SIZE]; + + inline int16 get_cat_id() + { + return sint2korr(&record[offset_hcn_cat_id]); + } + + inline int get_func_id() + { + return sint3korr(&record[offset_hcn_func_id]); + } +}; + +int get_all_names_for_category(THD *thd,MI_INFO *file_leafs, + int16 cat_id, List<String> *res) +{ + DBUG_ENTER("get_all_names_for_category"); + + MI_INFO *file_names_categories= 0; + if (!(file_names_categories= open_help_file(thd,"function_category"))) + DBUG_RETURN(1); + + help_category_leaf cat_leaf; + help_leaf leaf; + int key_res= mi_rkey(file_names_categories, (byte*)&cat_leaf, 0, + (const byte*)&cat_id,2,HA_READ_KEY_EXACT); + + while (!key_res && cat_leaf.get_cat_id()==cat_id) + { + int leaf_id= cat_leaf.get_func_id(); + + if (!mi_rkey(file_leafs, (byte*)&leaf, 0, + (const byte*)&leaf_id,4,HA_READ_KEY_EXACT)) + { + leaf.prepare_fields(); + String *s= new String(leaf.get_name(),system_charset_info); + if (!s->copy()) + res->push_back(s); + } + + key_res= mi_rnext(file_names_categories, (byte*)&cat_leaf, 0); + } + + mi_close(file_names_categories); + + DBUG_RETURN(0); +} + +int send_answer_1(THD *thd, const char *s1, const char *s2, + const char *s3, const char *s4) +{ + DBUG_ENTER("send_answer_1"); + List<Item> field_list; + field_list.push_back(new Item_empty_string("name",64)); + field_list.push_back(new Item_empty_string("is_category",1)); + field_list.push_back(new Item_empty_string("description",1000)); + field_list.push_back(new Item_empty_string("example",1000)); + + if (send_fields(thd,field_list,1)) + DBUG_RETURN(1); + + String *packet= &thd->packet; + packet->length(0); + net_store_data(packet, s1); + net_store_data(packet, s2); + net_store_data(packet, s3); + net_store_data(packet, s4); + + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) + DBUG_RETURN(-1); + + DBUG_RETURN(0); +} + +int send_header_2(THD *thd) +{ + DBUG_ENTER("send_header2"); + List<Item> field_list; + field_list.push_back(new Item_empty_string("name",64)); + field_list.push_back(new Item_empty_string("is_category",1)); + DBUG_RETURN(send_fields(thd,field_list,1)); +} + +int mysqld_help (THD *thd, const char *mask) +{ + DBUG_ENTER("mysqld_help"); + + MI_INFO *file_leafs= 0; + if (!(file_leafs= open_help_file(thd,"function"))) + DBUG_RETURN(1); + + List<String> function_list, categories_list; + String *name, *description, *example; + int res; + + int count= search_functions(file_leafs, mask, + &function_list,&name,&description,&example); + if (count<0) + { + res= 1; + goto end; + } + else if (count==0) + { + int16 category_id; + count= search_categories(thd, mask, &categories_list, &category_id); + if (count<0) + { + res= 1; + goto end; + } + else if (count==1) + { + if (res= get_all_names_for_category(thd, file_leafs, + category_id,&function_list)) + goto end; + List_iterator<String> it(function_list); + String *cur_leaf, example; + while ((cur_leaf = it++)) + { + example.append(*cur_leaf); + example.append("\n",1); + } + if (res= send_answer_1(thd, categories_list.head()->ptr(), + "Y","",example.ptr())) + goto end; + } + else + { + if ((res= send_header_2(thd)) || + (count==0 && + (search_categories(thd, 0, &categories_list, 0)<0 && + (res= 1))) || + (res= send_variant_2_list(thd,&categories_list,true))) + goto end; + } + } + else if (count==1) + { + if (res= send_answer_1(thd,name->ptr(),"N", + description->ptr(), example->ptr())) + goto end; + } + else if((res= send_header_2(thd)) || + (res= send_variant_2_list(thd,&function_list,false)) || + (search_categories(thd, mask, &categories_list, 0)<0 && + (res=1)) || + (res= send_variant_2_list(thd,&categories_list,true))) + { + goto end; + } + + send_eof(thd); + +end: + mi_close(file_leafs); + DBUG_RETURN(res); +} |