示例#1
0
char		*get_next_line(const int fd)
{
  static char	buffer[BUF_SIZE];
  int		found;
  char		c;
  int		ret;
  int		count;

  count = 0;
  found = 0;
  while (found == 0)
    {
      ret = read(fd, &c, READ_SIZE);
      if (ret == 0)
	{
	  if (my_eof(count, buffer, &found))
	    return (NULL);
	}      
      else
	my_line(c, buffer, &count, &found);
    }
  return(my_alloc(buffer));
}
bool mysqld_help(THD *thd, const char *mask)
{
  Protocol *protocol= thd->protocol;
  SQL_SELECT *select;
  st_find_field used_fields[array_elements(init_used_fields)];
  TABLE_LIST *leaves= 0;
  TABLE_LIST tables[4];
  List<String> topics_list, categories_list, subcategories_list;
  String name, description, example;
  int count_topics, count_categories, error;
  uint mlen= strlen(mask);
  size_t i;
  MEM_ROOT *mem_root= thd->mem_root;
  DBUG_ENTER("mysqld_help");

  bzero((char *)((uchar*)tables),sizeof(tables));
  tables[0].alias= tables[0].table_name= (char*) "help_topic";
  tables[0].lock_type= TL_READ;
  tables[0].next_global= tables[0].next_local= 
    tables[0].next_name_resolution_table= &tables[1];
  tables[1].alias= tables[1].table_name= (char*) "help_category";
  tables[1].lock_type= TL_READ;
  tables[1].next_global= tables[1].next_local= 
    tables[1].next_name_resolution_table= &tables[2];
  tables[2].alias= tables[2].table_name= (char*) "help_relation";
  tables[2].lock_type= TL_READ;
  tables[2].next_global= tables[2].next_local= 
    tables[2].next_name_resolution_table= &tables[3];
  tables[3].alias= tables[3].table_name= (char*) "help_keyword";
  tables[3].lock_type= TL_READ;
  tables[0].db= tables[1].db= tables[2].db= tables[3].db= (char*) "mysql";

  Open_tables_state open_tables_state_backup;
  if (open_system_tables_for_read(thd, tables, &open_tables_state_backup))
    goto error2;

  /*
    Init tables and fields to be usable from items
    tables do not contain VIEWs => we can pass 0 as conds
  */
  thd->lex->select_lex.context.table_list=
    thd->lex->select_lex.context.first_name_resolution_table= &tables[0];
  if (setup_tables(thd, &thd->lex->select_lex.context,
                   &thd->lex->select_lex.top_join_list,
                   tables, &leaves, FALSE))
    goto error;
  memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
  if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
    goto error;
  for (i=0; i<sizeof(tables)/sizeof(TABLE_LIST); i++)
    tables[i].table->file->init_table_handle_for_HANDLER();

  if (!(select=
	prepare_select_for_name(thd,mask,mlen,tables,tables[0].table,
				used_fields[help_topic_name].field,&error)))
    goto error;

  count_topics= search_topics(thd,tables[0].table,used_fields,
			      select,&topics_list,
			      &name, &description, &example);
  delete select;

  if (count_topics == 0)
  {
    int UNINIT_VAR(key_id);
    if (!(select=
          prepare_select_for_name(thd,mask,mlen,tables,tables[3].table,
                                  used_fields[help_keyword_name].field,
                                  &error)))
      goto error;

    count_topics= search_keyword(thd,tables[3].table, used_fields, select,
                                 &key_id);
    delete select;
    count_topics= (count_topics != 1) ? 0 :
                  get_topics_for_keyword(thd,tables[0].table,tables[2].table,
                                         used_fields,key_id,&topics_list,&name,
                                         &description,&example);
  }

  if (count_topics == 0)
  {
    int16 category_id;
    Field *cat_cat_id= used_fields[help_category_parent_category_id].field;
    if (!(select=
          prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
                                  used_fields[help_category_name].field,
                                  &error)))
      goto error;

    count_categories= search_categories(thd, tables[1].table, used_fields,
					select,
					&categories_list,&category_id);
    delete select;
    if (!count_categories)
    {
      if (send_header_2(protocol,FALSE))
	goto error;
    }
    else if (count_categories > 1)
    {
      if (send_header_2(protocol,FALSE) ||
	  send_variant_2_list(mem_root,protocol,&categories_list,"Y",0))
	goto error;
    }
    else
    {
      Field *topic_cat_id= used_fields[help_topic_help_category_id].field;
      Item *cond_topic_by_cat=
	new Item_func_equal(new Item_field(topic_cat_id),
			    new Item_int((int32)category_id));
      Item *cond_cat_by_cat=
	new Item_func_equal(new Item_field(cat_cat_id),
			    new Item_int((int32)category_id));
      if (!(select= prepare_simple_select(thd, cond_topic_by_cat,
                                          tables[0].table, &error)))
        goto error;
      get_all_items_for_category(thd,tables[0].table,
				 used_fields[help_topic_name].field,
				 select,&topics_list);
      delete select;
      if (!(select= prepare_simple_select(thd, cond_cat_by_cat,
                                          tables[1].table, &error)))
        goto error;
      get_all_items_for_category(thd,tables[1].table,
				 used_fields[help_category_name].field,
				 select,&subcategories_list);
      delete select;
      String *cat= categories_list.head();
      if (send_header_2(protocol, TRUE) ||
	  send_variant_2_list(mem_root,protocol,&topics_list,       "N",cat) ||
	  send_variant_2_list(mem_root,protocol,&subcategories_list,"Y",cat))
	goto error;
    }
  }
  else if (count_topics == 1)
  {
    if (send_answer_1(protocol,&name,&description,&example))
      goto error;
  }
  else
  {
    /* First send header and functions */
    if (send_header_2(protocol, FALSE) ||
	send_variant_2_list(mem_root,protocol, &topics_list, "N", 0))
      goto error;
    if (!(select=
          prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
                                  used_fields[help_category_name].field,&error)))
      goto error;
    search_categories(thd, tables[1].table, used_fields,
		      select,&categories_list, 0);
    delete select;
    /* Then send categories */
    if (send_variant_2_list(mem_root,protocol, &categories_list, "Y", 0))
      goto error;
  }
  my_eof(thd);

  close_system_tables(thd, &open_tables_state_backup);
  DBUG_RETURN(FALSE);

error:
  close_system_tables(thd, &open_tables_state_backup);

error2:
  DBUG_RETURN(TRUE);
}