Laboratory of Mobile Agricultural Chemicals Searcher
携帯農薬検索実験室

研究会

  ツリー表示 ┃スレッド表示 ┃一覧表示 ┃トピック表示 ┃番号順表示 ┃検索  
82 / 114 ツリー <前へ | 次へ>

〔185〕ACFinder LocalDB版 kabe (06/05/31 22:51)

〔313〕Re:日本語フィールド名 Hidemi Oya (06/06/19 23:03)
〔319〕Re:日本語フィールド名 Hidemi Oya (06/06/20 1:34)
〔321〕Re:日本語フィールド名 kabe (06/06/20 6:35)
〔322〕Re:日本語フィールド名 Hidemi Oya (06/06/20 9:16)
〔323〕Re:日本語フィールド名 Hidemi Oya (06/06/20 12:09)

〔313〕Re:日本語フィールド名
 Hidemi Oya WEB  (06/06/19 23:03)

引用なし
   kabe さん、こん**は。HidemiOya です。

>(1) SQL 文側では「hex("日本語文字列")」と書いておくと、この部分を「hex十六進文字列」にエンコードする
>(2) エラー表示/フィールド名表示の際には「hex十六進文字列」を「日本語文字列」にデコードする
 これに基づいたエンコード/デコード関数を作成しましたので、組み込みをお願いします。SQLite の本家サイトを探したんですが、フィールド名の最大長が分かりませんでした。長くなりすぎないように ShiftJIS の文字列をエンコードしていますが、もしかしたら文字数制限に引っかかるかも…。

 エンコード/デコードルーチンで、AnsiToUtf8/Utf8ToAnsi も行ってしまいます。また、エンコード時に「hex("日本語文字列")」、デコード時に「hex十六進文字列」を含まない文字列はほとんどオーバーヘッドなくオリジナル文字列をそのまま返します。ってことで、SQLite に SQL 文を渡す際には現在の AnsiToUtf8 関数の代わりに EncodeHex を、エラー表示やフィールド名表示の際は Utf8ToAnsi 関数の代わりに DecodeHex を常に使ってもらって問題ありません。
 なお、テンプレートの「jp_[field]」の部分は、「hex("[field]")」に変更する必要があります。

function EncodeHex(src: string): string;
var
 t, h: string;
 p: PChar;
begin
 RegExprModifierI := true;
 RegExprModifierS := true;
 Result := ReplaceRegExpr('hex\(\s+("[^"]*")\s+\)', AnsiToUtf8(src), 'hex($1)', true);
 while ExecRegExpr('hex\("[^"]+"\)', Result) do begin
  t := ReplaceRegExpr('.*?hex\("([^"]+)"\).*', Result, '$1', true);
  p := PChar(Utf8ToAnsi(t));
  h := '';
  while p^ <> #0 do begin
   h := h + IntToHex(Ord(p^), 2);
   Inc(p);
  end;
  Result := ReplaceRegExpr('hex\("' + t + '"\)', Result, 'hex' + h, false);
 end;
end;

function DecodeHex(src: string): string;
type
 THex2 = array[0..1] of char;
 PHex2 = ^THex2;
var
 t, s: string;
 p: PChar;
begin
 RegExprModifierI := true;
 RegExprModifierS := true;
// Result := src;
 Result := Utf8ToAnsi(src);
 while ExecRegExpr('hex[0-9a-f]+', Result) do begin
  t := ReplaceRegExpr('.*?hex([0-9a-f]+).*', Result, '$1', true);
  p := PChar(t);
  s := '';
  while p^ <> #0 do begin
   s := s + Chr(StrToInt('$' + PHex2(p)^));
   Inc(p, 2);
  end;
//  Result := ReplaceRegExpr('hex' + t + '([^0-9a-f])', Result, AnsiToUtf8(s) + '$1', true);
  Result := ReplaceRegExpr('hex' + t + '([^0-9a-f])', Result, s + '$1', true);
 end;
// Result := Utf8ToAnsi(Result);
end;

〔319〕Re:日本語フィールド名
 Hidemi Oya WEB  (06/06/20 1:34)

引用なし
   kabe さん、こん**は。HidemiOya です。

 EncodeHex 関数を書いている時に確認したんですが、UTF-8 では 0x00〜0x7F は使われないような感じです。したがって、[#280]
> UTF-8 文字列を URL エンコードすると、%xx の中に英小文字が散見されるので、恐らく sqlite3.dll はフィールド名を大文字に変換しちゃってるんでしょうね。
は間違いですね(^_^;)。英子文字が散見されたのは ShiftJIS ですね。

 では何故フィールドアリアスに UTF-8 が使えないのかというと、SQLite 側で大文字/小文字変換する際のバグですかねえ?

〔321〕Re:日本語フィールド名
 kabe WEB  (06/06/20 6:35)

引用なし
   >Hidemi Oyaさん

kabe です。

早速ありがとうございます。
ちょっと今やってみたのですが、DecodeHex の方がうまくいきません。
DecodeHex を使わない場合
hex("なす") を SQLite に渡すと
HEX82C882B7
とフィールド名が表示されます。
(SQLite が大文字に変換しているようです)
DecodeHex を使うと、無限ループになっているのか、応答なし状態になってしまいます。
MessageDlg(DecodeHex('HEX82C882B7'),mtInformation,[mbOk],0);
でも同様の症状なので、DecodeHex 関数の問題でしょうか。?
ソースはそのままコピペしただけなんですが、どこかチェックポイントありますか。

〔322〕Re:日本語フィールド名
 Hidemi Oya WEB  (06/06/20 9:16)

引用なし
   kabe さん、こん**は。Hidemi Oya です。

>ちょっと今やってみたのですが、DecodeHex の方がうまくいきません。
 あれ〜? D7 では全く問題なく動作してたんですが…。複数作物登録一覧表とその設定例でできた SQL 文を全部エンコード/デコードできたので、「なす」も動作確認済みです。

>DecodeHex を使わない場合
>hex("なす") を SQLite に渡すと
>HEX82C882B7
>とフィールド名が表示されます。
 EncodeHex で渡した SQL 文は、SQLite で問題なく動作するわけですね?

>(SQLite が大文字に変換しているようです)
 予測は当たってましたね。UTF-8 なら影響しないはずなんですけどね。
 ちなみに、hex が HEX になっても問題なく Decode できることを確認しています。

>MessageDlg(DecodeHex('HEX82C882B7'),mtInformation,[mbOk],0);
>でも同様の症状なので、DecodeHex 関数の問題でしょうか。?
 ですね。

>ソースはそのままコピペしただけなんですが、どこかチェックポイントありますか。
 D6 と D7 の仕様の違いだとすれば、怪しいのは
  p := PChar(t);
の部分(D3 でも大丈夫だったような気はするけど…)ですかねえ? とりあえず、
  p := @t[1];
だとどうでしょう?
 それと、現状では最初に SHiftJIS に戻してからデコードしてますが、UTF-8 のままデコードして最後に ShiftJIS に戻す方法を残してあります。// でコメントアウトした行を生かして、その下の行をコメントアウトしてください。
 とりあえず、今思いつく範囲ではこんなところです。

〔323〕Re:日本語フィールド名
 Hidemi Oya WEB  (06/06/20 12:09)

引用なし
   kabe さん、こん**は。Hidemi Oya です。

> D6 と D7 の仕様の違いだとすれば、怪しいのは
>  p := PChar(t);
>の部分(D3 でも大丈夫だったような気はするけど…)ですかねえ?
 EncodeHex で
  P := PChar(Utf8ToAnsi(t));
が OK ですから、こいつは問題ないですね。
 で、ソースを見直してみたら、フィールド名の書き戻しができないことが判明しました(^_^;)。エラーメッセージのデコードは問題ないはずです。DecodeHex の end; から上に5行目の
//  Result := ReplaceRegExpr('hex' + t + '([^0-9a-f])', Result, AnsiToUtf8(s) + '$1', true);
  Result := ReplaceRegExpr('hex' + t + '([^0-9a-f])', Result, s + '$1', true);

//  Result := ReplaceRegExpr('hex' + t + '([^0-9a-f]|$)', Result, AnsiToUtf8(s) + '$1', true);
  Result := ReplaceRegExpr('hex' + t + '([^0-9a-f]|$)', Result, s + '$1', true);
に書き換えてください。

 SQLite3 の基本エンコードは Unicode のようなので、データベースの内容も SQL のやりとりも全て UTF-16 にしてやれば、問題なく日本語が通るのかもしれません。SQLite 3.3.6 の DLL が日本語データベース名を通してくれないのも、Unicode でなく ShiftJIS だからかも…。
 UTF-8 のフィールド名が正常に使えないのは、UTF-8 を無理矢理 UTF-16 に変換しているせいだと考えれば、理解できるような気がします。

  ツリー表示 ┃スレッド表示 ┃一覧表示 ┃トピック表示 ┃番号順表示 ┃検索  
82 / 114 ツリー <前へ | 次へ>
ページ:  ┃  記事番号:   
(SS)C-BOARD vv3.8 is Free.