Open Source WEB

どこを変更すれば良いだろうか

フィールド毎に charset_info がフィールドのャラクタセットに対応した ものになっていればよい。

したがって、以下の ‥‥ここに挿入‥‥ の場所に、何らかの仕掛けを入れれば 何とかなるのではないだろうか。

  2220      for (uint off= 0; off < mysql_num_fields(result); off++)
  2221      {
  2222        const char *str= cur[off] ? cur[off] : "NULL";
  2223        field= mysql_fetch_field(result);
  2224        uint maxlength= field->max_length;
  2225        if (maxlength > MAX_COLUMN_LENGTH)
  2226        {
  2227          tee_fputs(str, PAGER);
  2228          tee_fputs(" |", PAGER);
  2229        }
  2230        else
  2231        {

                ‥‥ここに挿入‥‥

  2232          uint currlength= (uint) lengths[off];
  2233          uint numcells= charset_info->cset->numcells(charset_info,
  2234                                              str, str + currlength);
  2235          tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|",
  2236                      maxlength + currlength - numcells, str);
  2237        }
  2238      }

charset_infoは、

   178  static CHARSET_INFO *charset_info= &my_charset_latin1;

で定義されているのであるが、これはこのままにしておいて、 ‥‥ここに挿入‥‥ があるブロックの中だけの局所的な charset_info をでっちあげることにしよう。 そうすれば、他への影響が無いだろう。多分。

問題は、フィールドの情報

  2223        field= mysql_fetch_field(result);

から取得できるはずだ。

デフォルトキャラクタセットを元に、charset_infoを設定していると思われる 部分が以下の個所である。

   931    if (strcmp(default_charset, charset_info->csname) &&
   932        !(charset_info= get_charset_by_csname(default_charset,
   933                                      MY_CS_PRIMARY, MYF(MY_WME))))
   934      exit(1);

これを真似れば何とかなるのではないかと思う。

まず、fieldがどうなっているか調べてみよう。

  2173    MYSQL_FIELD   *field;

となっており、MYSQL_FIELD型へのポインタであることが分かる。

MYSQL_FIELD型は、mysqlクライアントだけでなく、mysql全体で共通の型で、 以下のようになっている。

include/mysql.h

typedef struct st_mysql_field {
  char *name;                 /* Name of column */
  char *org_name;             /* Original column name, if an alias */
  char *table;                /* Table of column if column was a field */
  char *org_table;            /* Org table name, if table was an alias */
  char *db;                   /* Database for table */
  char *catalog;              /* Catalog for table */
  char *def;                  /* Default value (set by mysql_list_fields) */
  unsigned long length;       /* Width of column (create length) */
  unsigned long max_length;   /* Max width for selected set */
  unsigned int name_length;
  unsigned int org_name_length;
  unsigned int table_length;
  unsigned int org_table_length;
  unsigned int db_length;
  unsigned int catalog_length;
  unsigned int def_length;
  unsigned int flags;         /* Div flags */
  unsigned int decimals;      /* Number of decimals in field */
  unsigned int charsetnr;     /* Character set */
  enum enum_field_types type; /* Type of field. See mysql_com.h for types */
} MYSQL_FIELD;

これを見ると、直接キャラクタセットを文字列で取得することはできないようだ。 その代わりに、 charsetnr というメンバーがキャラクタセットを整数値で示すようだ。

この整数値から、キャラクタセットを求める関数を探さねばならない。

あちこち探していたら、mysys/charset.c の中にそれらしいものがあった。 このファイルにキャラクタセット関連の関数が集められているらしい。

    25  /*
    26    The code below implements this functionality:
    27
    28      - Initializing charset related structures
    29      - Loading dynamic charsets
    30      - Searching for a proper CHARSET_INFO
    31        using charset name, collation name or collation ID
    32      - Setting server default character set
    33  */

この中で、キャラクタセットの番号を与えてキャラクタセットを 文字列として出してくれそうなのはこれであった。

   452  const char *get_charset_name(uint charset_number)
   453  {
   454    CHARSET_INFO *cs;
   455    init_available_charsets(MYF(0));
   456
   457    cs=all_charsets[charset_number];
   458    if (cs && (cs->number == charset_number) && cs->name )
   459      return (char*) cs->name;
   460
   461    return (char*) "?";   /* this mimics find_type() */
   462  }

たぶんこれらを組み合わせれば、大丈夫ではないかと思うのだが、どうだろう。


戻る:オプション指定はcharset_infoに反映される

次へ:フィールド毎にキャラクタセットを反映できた


フィードバック:

Name:
Comment:

There is no comment.

このサイトは、 IPA の「平成15年度オープンソフトウエア活用基盤整備事業」 の委託事業として開発されたKahuaで試験的に運用しております。

Copyright (c) 2004-2007 株式会社タイムインターメディア About Us