2011年5月11日水曜日

mySQLについてのメモ

mySQLのINTのMAX値

  • Unsigned で、4G(40億)

mySQLでの正規表現の利用

  • 正規表現は where `name` REGEXP 'a*' のように使用する

mySQLのvarchar、textの比較について

  • インデックスを張る場合255文字以内のキー長を指定する必要がある

他のDBのテーブルを参照するには

  • 同じmySQLサーバ内なら、select * from db_name.table_nameでOK

他のDBのテーブルとJOINできるか

  • 下記のように普通にJOINできる
    SELECT * FROM `mytable` join `dbname`.`atable` A on `mytable`.`id`=A.`id`

synonymはあるか

  • 無い。
    viewを使えば同様のことができる。オーバーヘッドが問題にならないか注意して使う

日付時刻を丸める関数(TRUNCなど)はあるか

  • 日付丸め専用の関数はない。
  • 文字列にフォーマットして丸める例はよく見かける
  • 計算式で丸める例
     時間:DATE(`date`)+INTERVAL HOUR(`date`) HOUR
     日: DATE(`date`)
     週: DATE(`date`)-INTERVAL DAYOFWEEK(`date`)-1 DAY
     月: DATE(`date`)-INTERVAL DAYOFMONTH(`date`)-1 DAY

PostgreSqlにある「関数(式)インデックス」はあるか

  • 無い。→インデックスを使いたい式を展開した列が必要

タイムゾーンはDBもしくは接続毎に再指定可能か
  • 可能
    mysql> set time_zone = '-7:00';
    Query OK, 0 rows affected (0.00 sec)

    mysql> select now();
    +---------------------+
    | now() |
    +---------------------+
    | 2011-05-05 22:21:37 |
    +---------------------+
    1 row in set (0.00 sec)

    mysql> set time_zone='+9:00' ;
    Query OK, 0 rows affected (0.00 sec)

    mysql> select now();
    +---------------------+
    | now() |
    +---------------------+
    | 2011-05-06 14:22:01 |
    +---------------------+
    1 row in set (0.00 sec)

    2011年4月21日木曜日

    Ext4.0ドキュメントの印刷

    Ext4.0のドキュメントページを印刷するブックマークレットを作ってみた。

    今回は隠したインラインフレームに作成して、そのまま印刷するのではなく、
    印刷可能なWindowを表示するようにした。ExtWikiでも試行錯誤したが、プレビュー代わりになりこれが一番便利だった。
    また、ガイドがマニュアルに統合されたので、こちらも印刷しやすいようにしてみる。

    例によってブックマークレット表示サイトで表示してみる。
    ExtJS4.0 ドキュメント印刷(クラス)

    ExtJS4.0 ドキュメント印刷(ガイド)

    もともとβ3の時に作成したが、ファイナルで少し変わっていたので上記に修正した。β3の時のものはこんな感じ
    ExtJS4.0β3 ドキュメント印刷(クラス)

    2011年4月3日日曜日

    画像をphpスクリプトのみで表示する

    画像のパスが問題で、プラグインやライブラリの設計や導入方法が若干複雑になる事がある。
    こんなとき、画像をプログラムに取り込んでしまうと設定自体不要になるケースがある。

    そのやり方をメモしておく
    1.画像をbase64文字列に変換する
    2.変換したbase64文字列をプログラムに組み込む

    1.画像をbase64文字列に変換する
     次のようなプログラムでbase64文字列を作成できる
    img_encode.php
    
    <?php
      //クォート内はターゲットのファイル名
      die(base64_encode(file_get_contents(''));
    ?>
    

    出力は下記のようになる

    R0lGODlhFQATAPcAAP//////zP//mf//Zv//M///AP/M///MzP/Mmf/MZv/MM//MAP+Z//+ZzP+Zmf+ZZv+ZM/+ZAP9m//9mzP9mmf9mZv9mM/9mAP8z//8zzP8zmf8zZv8zM/8zAP8A//8AzP8Amf8AZv8AM/8AAMz//8z/zMz/mcz/Zsz/M8z/AMzM/8zMzMzMmczMZszMM8zMAMyZ/8yZzMyZmcyZZsyZM8yZAMxm/8xmzMxmmcxmZsxmM8xmAMwz/8wzzMwzmcwzZswzM8wzAMwA/8wAzMwAmcwAZswAM8wAAJn//5n/zJn/mZn/Zpn/M5n/AJnM/5nMzJnMmZnMZpnMM5nMAJmZ/5mZzJmZmZmZZpmZM5mZAJlm/5lmzJlmmZlmZplmM5lmAJkz/5kzzJkzmZkzZpkzM5kzAJkA/5kAzJkAmZkAZpkAM5kAAGb//2b/zGb/mWb/Zmb/M2b/AGbM/2bMzGbMmWbMZmbMM2bMAGaZ/2aZzGaZmWaZZmaZM2aZAGZm/2ZmzGZmmWZmZmZmM2ZmAGYz/2YzzGYzmWYzZmYzM2YzAGYA/2YAzGYAmWYAZmYAM2YAADP//zP/zDP/mTP/ZjP/MzP/ADPM/zPMzDPMmTPMZjPMMzPMADOZ/zOZzDOZmTOZZjOZMzOZADNm/zNmzDNmmTNmZjNmMzNmADMz/zMzzDMzmTMzZjMzMzMzADMA/zMAzDMAmTMAZjMAMzMAAAD//wD/zAD/mQD/ZgD/MwD/AADM/wDMzADMmQDMZgDMMwDMAACZ/wCZzACZmQCZZgCZMwCZAABm/wBmzABmmQBmZgBmMwBmAAAz/wAzzAAzmQAzZgAzMwAzAAAA/wAAzAAAmQAAZgAAMwAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAFQATAAAI/AABCBzoaRQpUVSopFJFaqDDgXny/JH4B8+fUchUOVP1UOCTKhEjjho5KlUqUqpGPXxSoKVLPwmp+CnZ0s/AJypaOqmCJ48fPFScUBGVqmVKgSRaqkhosSWVmi4LOAPgpkTUlkBdPjXqzBmpEjkLqFAhNKFSoUZNkkoqduxSJy7H1iw5ShXbq1iVbi0gCtVXt0up4PnpByYVskz9kKIz1okKnnkGQy0Aw2wBZCUcF6iy2elMP1H9iPLzCcAczqEnF8ha4I/AEnudthTlEtVWTwOtuqS9enZUPQ9LzASacKloVKj8dOoIoESehGXLCgbOXCAmT53++JmYB/fDgAA7

    2.変換した文字列をプログラムに組み込む
     上記で変換して得られたbase64文字列をbase64_decodeしヘッダーとともに出力する。
     1行が長い場合、適当な長さに切り、使うときに文字列として連結する。
    img_decode.php
    
    <?php
      $img = 'R0lGODlhFQATAPcAAP//////zP//mf//Zv//M///AP/M///MzP/Mmf/MZv/M'
     .'M//MAP+Z//+ZzP+Zmf+ZZv+ZM/+ZAP9m//9mzP9mmf9mZv9mM/9mAP8z//8z'
     .'zP8zmf8zZv8zM/8zAP8A//8AzP8Amf8AZv8AM/8AAMz//8z/zMz/mcz/Zsz/'
     .'M8z/AMzM/8zMzMzMmczMZszMM8zMAMyZ/8yZzMyZmcyZZsyZM8yZAMxm/8xm'
     .'zMxmmcxmZsxmM8xmAMwz/8wzzMwzmcwzZswzM8wzAMwA/8wAzMwAmcwAZswA'
     .'M8wAAJn//5n/zJn/mZn/Zpn/M5n/AJnM/5nMzJnMmZnMZpnMM5nMAJmZ/5mZ'
     .'zJmZmZmZZpmZM5mZAJlm/5lmzJlmmZlmZplmM5lmAJkz/5kzzJkzmZkzZpkz'
     .'M5kzAJkA/5kAzJkAmZkAZpkAM5kAAGb//2b/zGb/mWb/Zmb/M2b/AGbM/2bM'
     .'zGbMmWbMZmbMM2bMAGaZ/2aZzGaZmWaZZmaZM2aZAGZm/2ZmzGZmmWZmZmZm'
     .'M2ZmAGYz/2YzzGYzmWYzZmYzM2YzAGYA/2YAzGYAmWYAZmYAM2YAADP//zP/'
     .'zDP/mTP/ZjP/MzP/ADPM/zPMzDPMmTPMZjPMMzPMADOZ/zOZzDOZmTOZZjOZ'
     .'MzOZADNm/zNmzDNmmTNmZjNmMzNmADMz/zMzzDMzmTMzZjMzMzMzADMA/zMA'
     .'zDMAmTMAZjMAMzMAAAD//wD/zAD/mQD/ZgD/MwD/AADM/wDMzADMmQDMZgDM'
     .'MwDMAACZ/wCZzACZmQCZZgCZMwCZAABm/wBmzABmmQBmZgBmMwBmAAAz/wAz'
     .'zAAzmQAzZgAzMwAzAAAA/wAAzAAAmQAAZgAAMwAAAP///wAAAAAAAAAAAAAA'
     .'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
     .'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
     .'AAAAAAAAAAAAAAAAAAAAACwAAAAAFQATAAAI/AABCBzoaRQpUVSopFJFaqDD'
     .'gXny/JH4B8+fUchUOVP1UOCTKhEjjho5KlUqUqpGPXxSoKVLPwmp+CnZ0s/A'
     .'JypaOqmCJ48fPFScUBGVqmVKgSRaqkhosSWVmi4LOAPgpkTUlkBdPjXqzBmp'
     .'EjkLqFAhNKFSoUZNkkoqduxSJy7H1iw5ShXbq1iVbi0gCtVXt0up4PnpByYV'
     .'skz9kKIz1okKnnkGQy0Aw2wBZCUcF6iy2elMP1H9iPLzCcAczqEnF8ha4I/A'
     .'EnudthTlEtVWTwOtuqS9enZUPQ9LzASacKloVKj8dOoIoESehGXLCgbOXCAm'
     .'T53++JmYB/fDgAA7';
      header('Content-Type: image/gif');
      die(base64_decode($img));
    ?>
    

    apacheのmod_rewriteで%2fを変換

    apacheは通常エンコードされたパス分離文字(%2F)が存在するURLを404(Not found)エラーで拒否する。

    通常は問題にならないのだろうが、パラメータをURLに埋め込み、mod_rewiteでphpに処理させるとき、urlやpathのようなパラメータを扱おうとすると顕在化する。

    apacheにこれを許可させるには、apacheのhttpd.confに「AllowEncodedSlashes On」を記述すればよい。

    VartualHostディレクティブ内でもOKだが、.htaccessに記述するとエラーとなる。

    参考
    apacheマニュアル
    PHPプロ!mod_rewriteでの%2F問題

    2011年3月24日木曜日

    ExtJSのStoreにデータダウンロードの機能を追加する PART2

    前回、時間の無い中作った「ExtJSのGridやChartにデータダウンロードの機能を追加する」を利用したアプリケーションで、追加要望が出たので拡張について少し考えてみた。

    前回、拡張の方法としてはGridに特化して、Gridで表示されているカラムやrendererを利用して、見えているものが、タブ区切りでダウンロードできる事を検討した。が、見えているものとは別に列やフォーマットを指定できる方が汎用性が高いことが分かり、その方向で拡張を実施することとした。

    拡張したdownloadメソッド
     /**
      * Download store data
      * @param {Object} opt (optional) Specifies download filename and columns.
      */
     Ext.data.Store.prototype.download = function(opt){
      opt = opt||{};
      var output=[],o=[],
       columns = opt.columns||(function(st){
        var cs=[], i=0;
        st.fields.eachKey(function(k) {cs.push(k);});
        return cs;
       })(this),
       fn = opt.filename||opt.fn||'download.txt';
      for (var i=0,col; col=columns[i]; ++i) {
       if (typeof col === 'string') {
        columns[i] = col = {field: col}
       }
       if (!col.header) col.header = col.field;
       if (!col.format) col.format = function(v,r){return v;};
       o.push(col.header);
      }
      output.push(o.join('\t'));
      this.each(function(rec) {
       var o=[];
       for (var i=0,col; col=columns[i]; ++i) {
        o.push(col.format(rec.get(col.field), rec));
       }
       output.push(o.join('\t'));
      });
      var form = Ext.DomHelper.append(document.body, {
       tag: 'form',
       style: 'display:none',
       action: 'download.php',
       method: 'post',
       cn:[{
        tag:'textarea',
        name:'body',
        html:output.join('\n')
       },{
        tag:'input',
        name:'Content-Disposition',
        value:'attachment;filename='+'"'+fn+'"'
       },{
        tag:'input',
        name:'Content-Type',
        value:'text/tab-separated-values'
       }]
      });
      form.submit();
      document.body.removeChild(form);
     }
    

    呼出しサンプル1
    こちらではパラメータなしでdownloadメソッドを呼び出した例、storeの内容がそのままダウンロードされる

    呼出しサンプル2
    こちらはパラメータとして、ダウンロードファイル名や、列やフォーマットの指定を行ってダウンロードする例

    使用に当たっては「ExtJSのGridやChartにデータダウンロードの機能を追加する」で使用したdownload.phpが必要となります。

    phpの出力をブラウザやプロキシーにキャッシュさせない

    phpのヘッダーのマニュアル内にそのものが載っているが、下記を設定するとかなりキャッシュされにくくなるとのこと。

        header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
        header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // 過去の日付
    

    ちなみに少し以前のマニュアルの例では、もう少しコテコテやっていた。

        // 日付が過去
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        // 常に修正されている
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        // HTTP/1.1
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", false);
        // HTTP/1.0
        header("Pragma: no-cache");
    

    2011年3月11日金曜日

    phpで仮名を全角に、英数字と空白を半角に統一する(mb_convert_kana)

    何と1行でできる

    mb_convert_kanaを使用する

    /*「半角カタカナ」を「全角カタカナ」に変換し、
     「全角」英数字を「半角」に変換します。
      オプションの意味
       K: かな半→全
       V: 濁点をマージ
       a: 英数字を半角にする
       s: スペースを半角にする(U+3000 -> U+0020)
     */
    
    $str = mb_convert_kana($str, 'KVas', 'utf-8');
    

    エンコードをEUCもしくはUTF-8とすれば、ついでに英数字の後に続く長音記号をハイフンに変換するのも簡単。

    $str = mb_convert_kana($str, 'KVas', 'utf-8');
    $str = preg_replace('/([a-z0-9])ー/i', '${1}-', $str);