テーブルのディスク使用量を取得する

SELECT relname, relfilenode, relpages FROM pg_class;

relname がテーブル名、relfilenode が実体ファイル名、 relpages が利用しているページ数概算。1ページは通常 8KB です。
 

SELECT c2.relname, c2.relpages
    FROM pg_class c, pg_class c2, pg_index i
    WHERE c.oid = i.indrelid
        AND c2.oid = i.indexrelid
    ORDER BY relpages DESC;

同様にインデックスの利用しているページ数を取得します。
 
参考:
ディスク使用量の監視(PostgreSQL 8.2.5 公式マニュアル)
pg_class(同上)

アクセス中のファイルに対する他のプロセスでのファイル読み書き禁止を制御する

.NET, C++ ともに FileStream 等でのファイルアクセス時に FileShare という列挙体のメンバを追加で指定することでロック制御することができます。
 
http://msdn2.microsoft.com/ja-jp/library/system.io.fileshare(VS.80).aspx より引用:

FileShare 列挙体のメンバ
 
Delete:
  後続のファイルの削除を許可します。
Inheritable:
  ファイル ハンドルを子プロセスで継承できるようにします。Win32 では、直接サポートされません。
None:
  現在のファイルの共有を解除します。ファイルを閉じるまで、このプロセスまたは別のプロセスがファイルを開く要求をしても失敗します。
Read:
  後続の読み取り用のファイルを開くことを許可します。このフラグが指定されていない場合は、ファイルを閉じるまで、このプロセスまたは別のプロセスが読み取り用のファイルを開く要求をしても失敗します。ただし、このフラグが指定されていても、ファイルにアクセスするために追加のアクセス許可が必要になることがあります。
ReadWrite:
  後続の読み取り用または書き込み用のファイルを開くことを許可します。このフラグが指定されていない場合は、ファイルを閉じるまで、このプロセスまたは別のプロセスが読み取り用または書き込み用のファイルを開く要求をしても失敗します。ただし、このフラグが指定されていても、ファイルにアクセスするために追加のアクセス許可が必要になることがあります。
Write:
  後続の書き込み用のファイルを開くことを許可します。このフラグが指定されていない場合は、ファイルを閉じるまで、このプロセスまたは別のプロセスが書き込み用のファイルを開く要求をしても失敗します。ただし、このフラグが指定されていても、ファイルにアクセスするために追加のアクセス許可が必要になることがあります。

参考:
FileShare 列挙体(System.IO)
開くファイルへの他のプロセスからのアクセスを制限する(dobon.net)

ひこにゃんに学ぶ著作権

今朝ニュースを見ていたら、第二のおふくろさん騒動ともいえるニュースが流れていました。
 
ひこにゃんピンチ!…作者、彦根市に使用中止求める(YOMIURI ONLINE) より引用:

もへろんさん(22)が「適正なキャラクター管理を怠った」などとして、市と同祭実行委員会に祭終了後の使用中止を求める調停を彦根簡裁に申し立てたが、市は9日、ひこにゃんを今後も市のマスコットとして使用すると発表した。
 
 実行委は祭のキャラクターとして2006年1月、もへろんさんが応募したネコをモチーフにした3種類の図柄を採用。実行委が許可した団体の出版物などへの利用を許可してきた。
 
 しかし、申立書によると、実行委は「お肉が好物」「特技はひこにゃんじゃんけん」など作者の意図しないひこにゃんの性格づけをしたと主張。粗悪品が出回りかねないのに無制限に使用を承認しているなどとしている。

 
財産権である著作権を持つ彦根市に対して、作者のもへろん氏が著作者人格権のうちの同一性保持権を行使している形ですね。
 
著作権は譲渡可能ですが、著作者人格権は Wikipedia の言葉を借りると「一身専属性を有する権利であるため他人に譲渡できない」権利であるとされているため、勝手な性質の追加に対して異義を唱える事は妥当である、と思います。
 
しかし、前述の記事のように「祭終了後の使用中止を求め」たり、スポニチアネックスの記事にあるように、営利目的の利用や対して「相当額の支払いを求め」たりということまで要求できるかは、祭以外の利用や営利目的の利用が、著作者の名誉声望を害するかは微妙なところではないでしょうか。
 
今回の事例が教えてくれることは、クリエイター、デザイナー、エンジニアなど個人と企業の間での契約では、個人が作成した成果物の著作権は企業が所有する、という契約が多いと思いますが、この契約上でも個人が著作物に対して著作者人格権を行使することができるということです。
 
 ちなみに、プログラムについては「特定のコンピュータで利用できるようにしたり、より効果的に利用し得るようにするために必要な改変(Wikipedia)」であれば同一性保持権でいう改変にはあたりません。
 
とりあえず彦根市の問題については、ひこにゃんは個人的にも好きなキャラクターですし、町興し成功の好例なので、当事者間でうまく話がまとまるといいなと思っています。
参考:
著作権法(Wikipedia)
著作者人格権

サンプルコード – Cache_Lite のファクトリメソッド(マルチユーザ対応)

Cache_Lite は大変便利なのですが、Linux/BSD などで、複数実行ユーザが同じ cacheDir (たとえば /tmp/ )を使った場合に、他ユーザが作ったキャッシュへのアクセス権限が得られないため正しく動作しません。
Cache_Lite の hashedDirectoryUmask オプションと umask() 関数で 0777 を指定すれば十分な権限が得られますが、キャッシュの盗聴やかいざんの可能性が出てくるためセキュリティ的によろしくありません。
 
簡単な対応として思い付くのは

‘cacheDir’ => ‘~/tmp’,

のようにユーザのホームディレクトリにフォルダを分けてやることですが、
今回はより汎用的にするため、ファクトリメソッド内部でユーザ判別をしてフォルダを分けることでマルチユーザ対応させてみました。
 
# 暫定的な実装なので、不備があるかもしれません。

// This source is made available under the terms of the BSD license.
 
/**
 * Cache_Lite 用汎用ファクトリメソッド。
 * (PHP 4, 5 対応)
 * @version 2007-11-08
 */
class CacheLiteFactory {
  /**
   * @access private
   */
  function CacheLiteFactory(){
      // no-op
  }
  /**
   * static.
   * @access private
   * @param array $newOptions
   * @return options
   */
  function _defaultOptions($newOptions = null){
     // 初期デフォルト設定
     static $defaultOptions = array(
         // 必要なら設定可。
      );
      if(!empty($newOptions)){
          $defaultOptions = $newOptions;
      }
      return $defaultOptions;
  }
  
   /**
    * インスタンス化に使うデフォルトのオプションを設定します。
    * 過去に設定していたオプションは全て消去されます。
    * 一部のオプションのみ追加、変更したい場合は getDefaultOption() で現在のデフォルトオプションを取得して再設定してください。
    *
    * static
    * @access public
    * @param array $newOptions 置き換えるオプション
    * @return void
    */
   function setDefaultOptions($newOptions){
      CacheLiteFactory::_defaultOptions($newOptions);
   }
   
   /**
    * インスタンス化に使われるデフォルトのオプションを取得します。
    * static
    * @access public
    * @return array 現在設定されているデフォルトのオプション
    */
   function getDefaultOptions(){
      return CacheLiteFactory::_defaultOptions();
   }
  
  /**
   * Cache_Lite インスタンスを取得する。
   * 引数を指定した場合、デフォルトオプションをベースに引数のオプションを追加,変更します。
   *
   * static
   * @access public
   * @param array $overrideOptions 上書きするオプションの連想配列
   * @return Cache_Lite
   */
   function factory($overrideOptions = array()){
       require_once “Cache/Lite.php”;
       // デフォルト値。
       $options = CacheLiteFactory::getDefaultOptions();
       
       if($overrideOptions && is_array($overrideOptions)){
            $options = array_merge($options, $overrideOptions);
       }
       if(empty($options[‘cacheDir’])){
           $options[‘cacheDir’] = “/tmp/”;
       }
        
       // 他ユーザのキャッシュはアクセス権限が十分にない(umask 0777 にしても削除はできない)ので
       // posix_getuid() で uid が取得できる場合はユーザごとにフォルダを分けるようにしておく。
      // ※ Windows 環境または –disable-posix オプション付きでビルドした場合は取得できないことに留意
       if(function_exists(“posix_getuid”)){
           if(@mkdir($options[‘cacheDir’], 0777)){ // PHP4 互換のため recursive なし
               @chmod($options[‘cacheDir’], 0777);
           }
           $options[‘cacheDir’].=”cache_uid_”.posix_getuid().DIRECTORY_SEPARATOR;
       }
       @mkdir($options[‘cacheDir’]); // PHP4 互換のため recursive はなし
       return new Cache_Lite($options);
    }
}

 

// 用例
/* —
  // デフォルトを与えるかは任意
CacheLiteFactory::setDefaultOptions(array(
    // ‘cacheDir’=>’/path/to/tmp/’,
    ‘lifeTime’ => 24 * 60 * 60, // set 1 day by default
    ‘hashedDirectoryLevel’ => 1,
    ‘automaticCleaningFactor’=>100,
  ));
— */
 
$cache = CacheLiteFactory::factory();
$value = $cache->get(“foo”);
if($value === false){
  $value = date(‘Y/m/d H:i:s’);
  $cache->save($value);
}
echo $value . “\n”;

プロジェクト内ファイルが増えて Eclipse が重い

既存のバージョン管理されていない、それなりに大きい規模のプロジェクトを SVN でバージョン管理しようとしている今日この頃。
 
手始めに現状のリソースの一部を Eclipse(+Subclipse) に 1プロジェクトとしていれてプロジェクトまるごとリポジトリに突っ込んだ結果、SVN を見に行く処理の度に激しく重くなってしまいました。
 
現時点でプロジェクトフォルダ内にあるファイル数は約 50000 個、フォルダは約 2500個、データ量 1.85GB。
 
いくら Eclipse が昔に比べパフォーマンスがよくなったとはいえ、この数を扱うとさすがに重い。そのせいなのか同期に失敗したり(というか反映が激しく遅かったり)、ところどころ動作が怪しい。
 
このままでは作業に支障がでる、ということでリポジトリから部分チェックアウトして別個プロジェクトとして作業することにし、無事軽快さを取り戻しました。
.project を svnignore に追加しておけばリポジトリとの齟齬もありません。
 
難点は現状チェックアウトフォルダがプロジェクトルートじゃないと同期がとれなくなることでしょうか。ある親フォルダの、一部の子フォルダのみバージョン管理させたい場合は子フォルダごとにプロジェクトを分けるか、親フォルダでチェックアウトして svnignore で更新フォルダを限定するかのどちらかの対応しかなさそうです。
 
前者で対応する場合、作業セット(working set)(パッケージエクスプローラの右上の▽ボタン)を使うと、VS.NET のソリューションみたくパッケージエクスプローラの表示をフィルタリングできるのでよさそうです。
 
ナビゲーターフィルターもそれなりに使えそうですが、こちらは表示しないものを選択するネガティブフィルタリングであることと、編集が若干手間なのがネックです。
 
[[|Eclipseのナビゲーターのフィルターパターン追加http://fenrir.naruoka.org/archives/000530.html]](Fenrir’s BLog)

JavaSctript で信頼できる数値の範囲

JavaScript’s Defects on Numbers
 
Eclipse の Java2Script Pacemaker プラグイン開発者のブログより、
0×20000000000000 (54ビット)を超える値は信用できないよ、という記事。
以下ほぼ原文訳。


テストスクリプト:

javascript:alert (0x1ffffffffffffe);
javascript:alert (0x1fffffffffffff);
javascript:alert (0x20000000000000);
javascript:alert (0x20000000000001);

上記のテストスクリプトを実行すると、最後の二つの値が全く同等になることが確認できます(Firefox 2.0, IE 6.0 で確認)。
 
結論として、安全な数値範囲は -0x1fffffffffffff(-9007199254740991) から 0x1fffffffffffff(9007199254740991)までの範囲(正負それぞれ53ビット)です。Java から JavaScript への変換で、Java の long 値を JavaScript の数値に変換する時は演算結果が正しくなくなることがあります。
 


上の記事では J2S についてのみ書かれてるのだと思いますが、GWT でも該当するかもしれません。

Highslide JS で簡単にサムネイル画像ポップアップ

 
Highslide JS
 
近頃は汎用的で高機能な Ajax JavaScript ライブラリが充実してきましたが、ただサムネイル拡大表示をスマートに行いたい、という時はこちらのほうがこれを使うのがよさそうです。
一番単純な例は次のようなものです。

<!– ヘッダで定義しておく –>
<script type=”text/javascript” src=”my-highslide-dir/highslide.js”></script>
<!– 実際にサムネイル表示する –>
<a href=”拡大画像のURL” class=”highslide” onclick=”return hs.expand(this)”>
    <img src=”サムネイル画像のURL” />
</a>

JavaScript 非対応の時はただ拡大画像へのリンクになるあたりがスマートです。
画像のポップアップだけではなく、ポップアップ画像に任意の説明を付与も比較的簡単にでき、機能面でも素晴らしいですね。
 
参考サイトを参照すると詳しい使い方や利用例があります。
 
参考:
Highslide JS でサムネイル画像を拡大表示する(小粋空間)
Highslide JS のサンプルページ(caramel-tea.com)

JSEclipse 導入でエラー

JavaScript 用 Eclipse プラグインは JSEclipse がよさそう、ということで
Eclipse 3.3.1 に JSEclipse 1.5.3 を下の更新サイト

http://www.interaktonline.com/

からいれてみたのですが、Eclipse を再起動して早速 *.js ファイルを開いてみたところ、次のようなエラーが…

Error opening the editor

 
とりあえず ソフトウェア更新→構成の管理→JSEclipse 1.5.3を選択し、更新をスキャンしてみたところ、Adobe Labs に JSEclipse 1.5.5 があるよ、と言われたのでそれをインストールし、無事動作しました。
最初から Adobe Labs からインストールすればよかったのですね。
 
Update site: Adobe Labs

http://download.macromedia.com/pub/labs/jseclipse/autoinstall/

 
ちなみに、InterAKT と Adobe の関係については FAQを参照するとわかるのですが、InterAKT が Adobe に買収され、その結果 JSEclipse を含む一部の製品が Adobe Labs に移ったようです。

PostgreSQL で使える全文検索エンジン

Ludia
wiki: http://ludia.sourceforge.jp/moin.cgi/#id9
 
内部で Senna と MeCab が使われています。
 
PostgreSQL に Ludia をインストールすると、Senna の構文での文字列検索を行える @@ 演算子等、全文検索用の機能が追加されます。

SELECT content FROM fooTable WHERE content @@ ‘今日は+です’

結果:

| content |
| 今日はくもりです |
| 今日はいい天気ですね。|

PHP4 と PHP5 の Sigleton Pattern

PHP4 での Singleton

error_reporting(E_ALL);
class Foo {
    function &getInstance(){
        static $_singleton;
        if(empty($_singleton)){
            $_singleton = new Foo();
        }
        return $_singleton;
    }
    var $_n;
    function add(){
        echo (++$_n).”\n”;
    }
}
$o1 =& Foo::getInstance();
$o1->add(); // 1
$o2 =& Foo::getInstance();
$o1->add(); // 2
$o2->add(); // 3
$o1->add(); // 4

 & と static の使い方が肝です。
static キーワードは、指定したローカル変数のライフサイクルを延長するためのキーワードです(注1)。
 メソッド定義とメソッド呼び出しの両方に & を付けないと、参照でなくコピーになってしまい、個別のインスタンスになるために結果が 1,2,1,3 になってしまいます。
 
PHP5 の場合も上のコードを変更なしで Singleton Pattern として動作させることが可能です。
さらに、メソッドの戻り値が標準で参照になるため、& を外しても singleton を実現することができ、クライアントコードが誤用する可能性がなくなったといえます(注2)。
 
このように PHP4 ではクライアントに特殊なメソッド呼び出し方をしないと意図しない結果になるため、Singleton な動作が必要な箇所については極力非公開にして内部利用にとどめるほうが賢明かも、です。
 
注1:
static キーワードには、スコープ(可用範囲)を広げる効果はありません。
ローカル変数がフィールドになるわけではないため、異なるメソッドで同じ名前の変数を指定しても、別個の変数になります。
注2:
ただし、クライアントコードで

$o1 = clone Foo::getInstance();

のように clone を使って意図的にコピーを行った場合、PHP4 で & を付けなかったときと同様の結果になります。
この場合はクライアント側で結果が予測できるため、問題にはならないでしょう。
 
参考:
PHP4 でデザインパターン(Do You PHP?)