<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
	xmlns="http://purl.org/rss/1.0/"
	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:admin="http://webns.net/mvcb/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
	xml:lang="ja">
	<channel rdf:about="http://www.mono-space.net/blog/index.rss">
		<title>memo-space</title>
		<link>http://www.mono-space.net/blog</link>
		<description>PostgreSQL とか PHP とか Java とか</description>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<admin:generatorAgent rdf:resource="http://www.blosxom.com/?v=2.0"/>
		<admin:errorReportsTo rdf:resource="mailto:iakio@mono-space.net"/>
		<items>
			<rdf:Seq>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/pgsql/e080427_pgsql_g.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/pgsql/e080418_sqlpuzzle.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/pgsql/e071102_delete_vs_truncate.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/php/e071026_requestaction.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/python/e071023_definedat.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/php/e071022_transactiontoken.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/python/e071022_inspect.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/php/e071021_usort.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/php/e071015_cli_include.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/programming/e070830_start_ror.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/pgsql/e070824_plproxy.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/pgsql/e070619_fizzbuzz.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/php/e070615_smarty_truncate.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/misc/e070608_iroiro.htm"/>
				<rdf:li rdf:resource="http://www.mono-space.net/blog/php/e070531_directlink.htm"/>
			</rdf:Seq>
		</items>
	</channel>
	<item rdf:about="http://www.mono-space.net/blog/pgsql/e080427_pgsql_g.htm">
		<title>postgresql.g.hatena.ne.jpつくった</title>
		<link>http://www.mono-space.net/blog/pgsql/e080427_pgsql_g.htm</link>
		<description>深い意味はありませんが、こっそりPostgreSQLグループ作りました。今後PostgreSQL方面の話題は、iakioの日記 - postgresqlグループで。</description>
		<dc:subject>pgsql</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2008-04-27T15:15+09:00</dc:date>
		<content:encoded><![CDATA[<p>深い意味はありませんが、こっそりPostgreSQLグループ作りました。
今後PostgreSQL方面の話題は、
<a href="http://postgresql.g.hatena.ne.jp/iakio/">iakioの日記 - postgresqlグループ</a>
で。</p>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/pgsql/e080427_pgsql_g.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/pgsql/e080418_sqlpuzzle.htm">
		<title>ミックさんのSQLパズル：NULLの埋め立て</title>
		<link>http://www.mono-space.net/blog/pgsql/e080418_sqlpuzzle.htm</link>
		<description>SQLパズル：NULLの埋め立て - ミックのブログlimitは使っていいのかな。select keycol     , seq     ,(select val         from OmitTbl o2        where o1.keycol = o2.keycol          and o1.seq &gt;= o2.seq          and o2.val is not null        order by o2.seq desc         limit 1)  from OmitTbl o1こういうのは何故解けるかというとなんとなくわかっちゃうんだけど、そうじゃなくてデザパタみたいにSQLをパターンで整理できたらいいなぁとか思う。※追記おもいっきり題意読み違えてましたorz</description>
		<dc:subject>pgsql</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2008-04-18T03:09+09:00</dc:date>
		<content:encoded><![CDATA[<p><a href="http://d.hatena.ne.jp/mickmack/20080417/1208440152">SQLパズル：NULLの埋め立て - ミックのブログ</a></p>

<p>limitは使っていいのかな。
<hr class="seemore">

</p>

<pre class="prettyprint"><code>select keycol
     , seq
     ,(select val
         from OmitTbl o2
        where o1.keycol = o2.keycol
          and o1.seq &gt;= o2.seq
          and o2.val is not null
        order by o2.seq desc
         limit 1)
  from OmitTbl o1
</code></pre>

<p>こういうのは何故解けるかというとなんとなくわかっちゃうんだけど、そうじゃなくてデザパタみたいにSQLをパターンで整理できたらいいなぁとか思う。</p>

<p>※追記
おもいっきり題意読み違えてましたorz</p>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/pgsql/e080418_sqlpuzzle.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/pgsql/e071102_delete_vs_truncate.htm">
		<title>勝手に添削「PostgreSQL VACUUM FULLせずに不要領域を削除する」</title>
		<link>http://www.mono-space.net/blog/pgsql/e071102_delete_vs_truncate.htm</link>
		<description>そういう時はdeleteではなくtruncateを使う方法もあります。truncateはいきなりテーブルを(不要領域を残すことなく)空っぽにするSQLです。PostgreSQL VACUUM FULLせずに不要領域を削除する | Shin x blogなので、とても大きいテーブルのごく一部のデータだけ残して他を消す手順としては、同じテーブルレイアウトの一時保存先となるテーブルを作る一時保存先のテーブルにレコードを移行する元のテーブルをtruncate一時保存先のテーブルからレコードを戻す一時保存先テーブルをdropこの手順であればテーブルのOIDも変わりません。残すレコードが多ければ、3と4の間で一旦インデックスを削除して、5の後でインデックスを作り直した方がいいかもしれません。あと、一時保存先のテーブルは、CREATE TEMPORARY TABLEを使った方が速い(し、最後にテーブルをdropする手間も省ける)と思います。なので全体的な操作としては、CREATE TEMP TABLE items_temp SELECT * FROM items LIMIT 0;INSERT INTO items_temp SELECT * FROM items WHERE ...;TRUNCATE items;INSERT INTO items SELECT * FROM items_temp;といった感じです。もう一つついでに。CREATE TABLE items_new AS SELECT * FROM items LIMIT 0;は、CREATE TABLE items_new (LIKE items);と書くこともできます。この"LIKEほげほげ"は、(今回は必要ありませんが)オプションによって制約やデフォルト値もコピーでき、また以下のように、カラムを追加することもできるので、「似てるけどちょっと違うテーブル」を作る時に便利です。CREATE TABLE items_new (newcol1 int, LIKE items, newcol2 int);CREATE TABLE - PostgreSQLドキュメントTRUNCATE - PostgreSQLドキュメント</description>
		<dc:subject>pgsql</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-11-02T03:05+09:00</dc:date>
		<content:encoded><![CDATA[<p>そういう時はdeleteではなくtruncateを使う方法もあります。
truncateはいきなりテーブルを(不要領域を残すことなく)空っぽにするSQLです。</p>

<ul>
<li><a href="http://www.1x1.jp/blog/2007/11/postgresql_no_vacuum_full.html">PostgreSQL VACUUM FULLせずに不要領域を削除する | Shin x blog</a></li>
</ul>

<hr class="seemore">



<p>なので、とても大きいテーブルのごく一部のデータだけ残して他を消す手順としては、</p>

<ol>
<li>同じテーブルレイアウトの一時保存先となるテーブルを作る</li>
<li>一時保存先のテーブルにレコードを移行する</li>
<li>元のテーブルをtruncate</li>
<li>一時保存先のテーブルからレコードを戻す</li>
<li>一時保存先テーブルをdrop</li>
</ol>

<p>この手順であればテーブルのOIDも変わりません。</p>

<p>残すレコードが多ければ、3と4の間で一旦インデックスを削除して、5の後でインデックスを作り直した方がいいかもしれません。あと、一時保存先のテーブルは、CREATE TEMPORARY TABLEを使った方が速い(し、最後にテーブルをdropする手間も省ける)と思います。</p>

<p>なので全体的な操作としては、</p>

<pre class="prettyprint"><code>CREATE TEMP TABLE items_temp SELECT * FROM items LIMIT 0;
INSERT INTO items_temp SELECT * FROM items WHERE ...;
TRUNCATE items;
INSERT INTO items SELECT * FROM items_temp;
</code></pre>

<p>といった感じです。もう一つついでに。</p>

<pre class="prettyprint"><code>CREATE TABLE items_new AS SELECT * FROM items LIMIT 0;
</code></pre>

<p>は、</p>

<pre class="prettyprint"><code>CREATE TABLE items_new (LIKE items);
</code></pre>

<p>と書くこともできます。この"LIKEほげほげ"は、(今回は必要ありませんが)オプションによって制約やデフォルト値もコピーでき、
また以下のように、カラムを追加することもできるので、「似てるけどちょっと違うテーブル」を作る時に便利です。</p>

<pre class="prettyprint"><code>CREATE TABLE items_new (newcol1 int, LIKE items, newcol2 int);
</code></pre>

<ul>
<li><a href="http://www.postgresql.jp/document/current/html/sql-createtable.html">CREATE TABLE - PostgreSQLドキュメント</a></li>
<li><a href="http://www.postgresql.jp/document/current/html/sql-truncate.html">TRUNCATE - PostgreSQLドキュメント</a></li>
</ul>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/pgsql/e071102_delete_vs_truncate.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/php/e071026_requestaction.htm">
		<title>CakePHP日記:requestActionとSecurityコンポーネント</title>
		<link>http://www.mono-space.net/blog/php/e071026_requestaction.htm</link>
		<description>なるほど。viewからrequestAction()を呼びだすのか。なかなかよさそう。と思ってたらSecurityコンポーネントとの組み合わせでハマってしまいました。CakePHPでサイドバーにログインボックスを作る方法 - 「最果て」の支部via "全画面共通 login ボックスの置き方" フォーラム - CakePHP Users in JapanどうやらSecurityコンポーネントのrequireAuthを使ってると、requestAction()が呼ばれた時にセッション側のトークンが書き換えられてしまうので絶対トークンが一致しない様子。うーん困った。あと、セッションの中にはトークンのキーと同時に有効期限がセットされるんだけど、Sessionコンポーネントの有効期限がCAKE_SECURITY * CAKE_SESSION_TIMEOUTなのに、トークンの有効期限はCAKE_SECURITYだけで決まっちゃってる気がする。</description>
		<dc:subject>php</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-10-26T04:10+09:00</dc:date>
		<content:encoded><![CDATA[<p>なるほど。viewからrequestAction()を呼びだすのか。
なかなかよさそう。
と思ってたらSecurityコンポーネントとの組み合わせでハマってしまいました。</p>

<ul>
<li><a href="http://d.hatena.ne.jp/nori0620/20071006/1191684664">CakePHPでサイドバーにログインボックスを作る方法 - 「最果て」の支部</a></li>
<li>via <a href="http://cakephp.jp/modules/newbb/viewtopic.php?topic_id=768&amp;forum=7&amp;post_id=1426">"全画面共通 login ボックスの置き方" フォーラム - CakePHP Users in Japan</a></li>
</ul>

<p>どうやらSecurityコンポーネントのrequireAuthを使ってると、requestAction()が呼ばれた時にセッション側のトークンが書き換えられてしまうので絶対トークンが一致しない様子。うーん困った。</p>

<p>あと、セッションの中にはトークンのキーと同時に有効期限が
セットされるんだけど、
Sessionコンポーネントの有効期限が<code>CAKE_SECURITY</code> * <code>CAKE_SESSION_TIMEOUT</code>
なのに、トークンの有効期限は<code>CAKE_SECURITY</code>だけで決まっちゃってる気がする。</p>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/php/e071026_requestaction.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/python/e071023_definedat.htm">
		<title>Pythonで、メソッド定義されたクラスを知る方法</title>
		<link>http://www.mono-space.net/blog/python/e071023_definedat.htm</link>
		<description>  それより、あるオブジェクトのメソッドがどのクラスで定義されているか調べる方法を知りたいなぁ。と昨日書いたけど、わかった気がする。__dict__を調べればいいんじゃないだろうか。import inspectdef definedat(method):    attname = method.func_name    cls = method.im_class    for c in inspect.getmro(cls):        if attname in c.__dict__:            return cこんな感じ。&gt;&gt;&gt; class A:    def msg(self): return "A"&gt;&gt;&gt; class B(A):    pass&gt;&gt;&gt; a = A()&gt;&gt;&gt; b = B()&gt;&gt;&gt; definedat(a.msg)&lt;class __main__.A at 0x012B5150&gt;&gt;&gt;&gt; definedat(b.msg)&lt;class __main__.A at 0x012B5150&gt;ちゃんと基底クラスを返してくれます。さらに多重継承の例。&gt;&gt;&gt; class C(A):    def msg(self): return "C"&gt;&gt;&gt; class D1(B,C):    pass&gt;&gt;&gt; class D2(C,B):    pass&gt;&gt;&gt; d1 = D1()&gt;&gt;&gt; d2 = D2()&gt;&gt;&gt; d1.msg()'A'&gt;&gt;&gt; d2.msg()'C'&gt;&gt;&gt; definedat(d1.msg)&lt;class __main__.A at 0x012B5150&gt;&gt;&gt;&gt; definedat(d2.msg)&lt;class __main__.C at 0x012BA600&gt;うん、よさそう。実はインスタンス化しなくてもdefinedat(D1.msg)でも動きます。追記：ほぼ同じコードを発見してしまったorzinspect.getmro - 清水川Web</description>
		<dc:subject>python</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-10-23T02:30+09:00</dc:date>
		<content:encoded><![CDATA[<blockquote>
  <p>それより、あるオブジェクトのメソッドがどのクラスで定義されているか調べる方法を知りたいなぁ。</p>
</blockquote>

<p>と昨日書いたけど、わかった気がする。<code>__dict__</code>を調べればいいんじゃないだろうか。</p>

<hr class="seemore">



<pre class="prettyprint"><code>import inspect

def definedat(method):
    attname = method.func_name
    cls = method.im_class
    for c in inspect.getmro(cls):
        if attname in c.__dict__:
            return c
</code></pre>

<p>こんな感じ。</p>

<pre class="prettyprint"><code>&gt;&gt;&gt; class A:
    def msg(self): return "A"

&gt;&gt;&gt; class B(A):
    pass

&gt;&gt;&gt; a = A()
&gt;&gt;&gt; b = B()
&gt;&gt;&gt; definedat(a.msg)
&lt;class __main__.A at 0x012B5150&gt;
&gt;&gt;&gt; definedat(b.msg)
&lt;class __main__.A at 0x012B5150&gt;
</code></pre>

<p>ちゃんと基底クラスを返してくれます。さらに多重継承の例。</p>

<pre class="prettyprint"><code>&gt;&gt;&gt; class C(A):
    def msg(self): return "C"

&gt;&gt;&gt; class D1(B,C):
    pass

&gt;&gt;&gt; class D2(C,B):
    pass

&gt;&gt;&gt; d1 = D1()
&gt;&gt;&gt; d2 = D2()
&gt;&gt;&gt; d1.msg()
'A'
&gt;&gt;&gt; d2.msg()
'C'
&gt;&gt;&gt; definedat(d1.msg)
&lt;class __main__.A at 0x012B5150&gt;
&gt;&gt;&gt; definedat(d2.msg)
&lt;class __main__.C at 0x012BA600&gt;
</code></pre>

<p>うん、よさそう。実はインスタンス化しなくても<code>definedat(D1.msg)</code>でも動きます。</p>

<p>追記：ほぼ同じコードを発見してしまったorz</p>

<ul>
<li><a href="http://www.freia.jp/taka/blog/426">inspect.getmro - 清水川Web</a></li>
</ul>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/python/e071023_definedat.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/php/e071022_transactiontoken.htm">
		<title>「すごいリロード対策」ってトランザクショントークンのことだよね</title>
		<link>http://www.mono-space.net/blog/php/e071022_transactiontoken.htm</link>
		<description>いや記事いいんだけど、すごい勢いでブックマークされていることに驚いた。【PHP TIPS】 58. すごいリロード対策：ITproはてなブックマーク - 【PHP TIPS】 58. すごいリロード対策：ITproそれ、トランザクショントークンっていいます。ざっと調べてみたら、2003年頃からある手法らしい。【オープンソースでどこまでできる】第5回 Webアプリケーション・フレームワークStruts（3）：ITpro  Strutsでは，Transaction Tokenという機能により，これらの現象を検出できる。メモの日々(2003-07-26)  JavaWorld DAY 2003での発表資料からの抜粋で、Struts Transaction Tokenを紹介している。Submitボタンの2度押しやブラウザの戻るボタンによるトランザクションの混乱を防御する仕組みのようだ。かく言う僕も、以前はこれ知らずに発見した気になっていたけどwmemo-space :: メーリングリストのsubscribe風二重投稿の防止方法CakePHPだと、この手の処理はSecurityコンポーネントを使うと自動でこの手の処理をやってくれます。</description>
		<dc:subject>php</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-10-22T04:15+09:00</dc:date>
		<content:encoded><![CDATA[<p>いや記事いいんだけど、すごい勢いでブックマークされていることに驚いた。</p>

<ul>
<li><a href="http://itpro.nikkeibp.co.jp/article/COLUMN/20070910/281585/">【PHP TIPS】 58. すごいリロード対策：ITpro</a></li>
<li><a href="http://b.hatena.ne.jp/entry/http://itpro.nikkeibp.co.jp/article/COLUMN/20070910/281585/">はてなブックマーク - 【PHP TIPS】 58. すごいリロード対策：ITpro</a></li>
</ul>

<hr class="seemore">



<p>それ、トランザクショントークンっていいます。
ざっと調べてみたら、2003年頃からある手法らしい。</p>

<ul>
<li><a href="http://itpro.nikkeibp.co.jp/members/SI/oss/20031022/1/">【オープンソースでどこまでできる】第5回 Webアプリケーション・フレームワークStruts（3）：ITpro</a></li>
</ul>

<blockquote>
  <p>Strutsでは，Transaction Tokenという機能により，これらの現象を検出できる。</p>
</blockquote>

<ul>
<li><a href="http://ogawa.s18.xrea.com/tdiary/20030726.html">メモの日々(2003-07-26)</a></li>
</ul>

<blockquote>
  <p>JavaWorld DAY 2003での発表資料からの抜粋で、Struts Transaction Tokenを紹介している。Submitボタンの2度押しやブラウザの戻るボタンによるトランザクションの混乱を防御する仕組みのようだ。</p>
</blockquote>

<p>かく言う僕も、以前はこれ知らずに発見した気になっていたけどw</p>

<ul>
<li><a href="http://www.mono-space.net/blog/programming/040410doublepost.htm">memo-space :: メーリングリストのsubscribe風二重投稿の防止方法</a></li>
</ul>

<p>CakePHPだと、この手の処理はSecurityコンポーネントを使うと自動でこの手の処理をやってくれます。</p>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/php/e071022_transactiontoken.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/python/e071022_inspect.htm">
		<title>Pythonで、メソッドがどこで定義されたか外から知る方法</title>
		<link>http://www.mono-space.net/blog/python/e071022_inspect.htm</link>
		<description>inspect.getfile()とかinspect.getsourcelines()とかがそのものでした。subtech - 冬通りに消え行く制服ガールは、夢物語にリアルを求めない。 - Ruby で、メソッドがどこで定義されたか外から知る方法&gt;&gt;&gt; import inspect&gt;&gt;&gt; inspect.getfile(inspect)'C:\\Python24\\lib\\inspect.pyc'&gt;&gt;&gt; from os.path import abspath&gt;&gt;&gt; inspect.getfile(abspath)'C:\\Python24\\lib\\ntpath.py'それより、あるオブジェクトのメソッドがどのクラスで定義されているか調べる方法を知りたいなぁ。ガシガシ多重継承しているソースを読む場合、けっこう便利かもしれない。追記：続きあります。memo-space :: Pythonで、メソッド定義されたクラスを知る方法</description>
		<dc:subject>python</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-10-22T03:55+09:00</dc:date>
		<content:encoded><![CDATA[<p><code>inspect.getfile()</code>とか<code>inspect.getsourcelines()</code>とかがそのものでした。</p>

<p><a href="http://subtech.g.hatena.ne.jp/cho45/20071014/1192319823">subtech - 冬通りに消え行く制服ガールは、夢物語にリアルを求めない。 - Ruby で、メソッドがどこで定義されたか外から知る方法</a></p>

<hr class="seemore">



<pre class="prettyprint"><code>&gt;&gt;&gt; import inspect
&gt;&gt;&gt; inspect.getfile(inspect)
'C:\\Python24\\lib\\inspect.pyc'
&gt;&gt;&gt; from os.path import abspath
&gt;&gt;&gt; inspect.getfile(abspath)
'C:\\Python24\\lib\\ntpath.py'
</code></pre>

<p>それより、あるオブジェクトのメソッドがどのクラスで定義されているか調べる方法を知りたいなぁ。
ガシガシ多重継承しているソースを読む場合、けっこう便利かもしれない。</p>

<p>追記：続きあります。
<a href="http://www.mono-space.net/blog/python/e071023_definedat.htm">memo-space :: Pythonで、メソッド定義されたクラスを知る方法</a></p>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/python/e071022_inspect.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/php/e071021_usort.htm">
		<title>sortするならusort</title>
		<link>http://www.mono-space.net/blog/php/e071021_usort.htm</link>
		<description>個人的には、sortをするならusort()が好きです。Perlをはじめ他の言語を使ったことがある人ならそう思うんじゃないかな。PHPのarray_multisort関数が激便利だったので紹介 : akiyan.com&lt;?php&#036;sales = array(  2 =&gt; array(    'title' =&gt; 'ほげほげ１',    'amount' =&gt; 3,  ),  1 =&gt; array(    'title' =&gt; 'ほげほげ２',    'amount' =&gt; 2,  ),  0 =&gt; array(    'title' =&gt; 'ほげほげ３',    'amount' =&gt; 5,  ),);&#036;cmp = create_function('&#036;a, &#036;b', 'return &#036;a["amount"] - &#036;b["amount"];');usort(&#036;sales, &#036;cmp);var_dump(&#036;sales);?&gt;複数条件でソートする場合は、他の言語のように値を返すor演算子があれば'return &#036;a["amount"] - &#036;b["amount"] || strcmp(&#036;a["title"], &#036;b["title"]);'とか書けるんだけど。せいぜいこんな感じか。&#036;cmp = create_function('&#036;a, &#036;b', 'return (&#036;c = &#036;a["amount"] - &#036;b["amount"]) ? &#036;c : strcmp(&#036;a["title"], &#036;b["title"]);');</description>
		<dc:subject>php</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-10-21T04:56+09:00</dc:date>
		<content:encoded><![CDATA[<p>個人的には、sortをするならusort()が好きです。
Perlをはじめ他の言語を使ったことがある人ならそう思うんじゃないかな。</p>

<p><a href="http://www.akiyan.com/blog/archives/2007/10/phparray_multis.html">PHPのarray_multisort関数が激便利だったので紹介 : akiyan.com</a></p>

<hr class="seemore">



<pre class="prettyprint"><code>&lt;?php
&#036;sales = array(
  2 =&gt; array(
    'title' =&gt; 'ほげほげ１',
    'amount' =&gt; 3,
  ),
  1 =&gt; array(
    'title' =&gt; 'ほげほげ２',
    'amount' =&gt; 2,
  ),
  0 =&gt; array(
    'title' =&gt; 'ほげほげ３',
    'amount' =&gt; 5,
  ),
);
&#036;cmp = create_function('&#036;a, &#036;b', 'return &#036;a["amount"] - &#036;b["amount"];');
usort(&#036;sales, &#036;cmp);
var_dump(&#036;sales);
?&gt;
</code></pre>

<p>複数条件でソートする場合は、他の言語のように値を返すor演算子があれば</p>

<pre class="prettyprint"><code>'return &#036;a["amount"] - &#036;b["amount"] || strcmp(&#036;a["title"], &#036;b["title"]);'
</code></pre>

<p>とか書けるんだけど。せいぜいこんな感じか。</p>

<pre class="prettyprint"><code>&#036;cmp = create_function('&#036;a, &#036;b', 'return (&#036;c = &#036;a["amount"] - &#036;b["amount"]) ? &#036;c : strcmp(&#036;a["title"], &#036;b["title"]);');
</code></pre>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/php/e071021_usort.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/php/e071015_cli_include.htm">
		<title>phpのinclude_pathのカレントディレクトリ</title>
		<link>http://www.mono-space.net/blog/php/e071015_cli_include.htm</link>
		<description>require("foo.php")とrequire("./foo.php")って意味違うって知ってました？cliから実行する場合以外はあまり関係無いかもしれませんが。  読み込むファイルはまずカレントのワーキングディレクトリからの相対パスとしてinclude_path で探され、それから、カレントのスクリプトのディレクトリからの相対パスとしてinclude_path で探されます。 (中略)ファイル名が ./ あるいは ../ で始まっている場合は、 カレントのワーキングディレクトリからの相対パスとして探されるのみとなります。  (PHP: include - Manual)以下実験。include_pathは.:/php/includes:/usr/share/pearとなっています。で、例えばこんなディレクトリ構成になっているとします。+- foo/| +- bar/|   +- a.php|   +- b.inc+- b.inc+- c.incそれぞれのファイルの内容はこんな感じ。foo/bar/a.php&lt;?phpinclude "b.inc";include "./b.inc";include "../../c.inc";?&gt;foo/bar/b.incThis is foo/bar/b.incb.incThis is b.incc.incThis is c.incで、fooディレクトリの上のディレクトリから実行してみます。&#036; php foo/bar/a.phpThis is b.incThis is b.incPHP Warning:  include(../../c.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 4...実行結果は、すべてのファイルをスクリプトのあるディレクトリではなく現在の実行ディレクトリから探そうとしていることを意味していますね。include "b.inc"の場合は、ワーキングディレクトリ⇒スクリプトディレクトリの順で探すので、ここでb.incを削除してみると、&#036; php foo/bar/a.phpThis is foo/bar/b.incPHP Warning:  include(./b.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 3...PHP Warning:  include(../../c.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 4と、include "b.inc"は成功しますが、include "./b.inc"はエラーとなります。straceを見ると、いくつかのパスをトライしている様子が見えます。open("foo/bar/a.php", O_RDONLY)         = 3# include("b.php") の場合、# 最初にワーキングディレクトリopen("/path/to/b.inc", O_RDONLY) = -1 ENOENT (No such file or directory)# 次にinclude_pathopen("/php/includes/b.inc", O_RDONLY)   = -1 ENOENT (No such file or directory)open("/usr/share/pear/b.inc", O_RDONLY) = -1 ENOENT (No such file or directory)# 次スクリプトディレクトリで発見open("/path/to/foo/bar/b.inc", O_RDONLY) = 3This is foo/bar/b.inc# include("./b.php") の場合、ワーキングディレクトリに# 無ければすぐ諦めるopen("/path/to/b.inc", O_RDONLY) = -1 ENOENT (No such file or directory)PHP Warning:  include(./b.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 3でも何でこんな仕様になってるんだろう。</description>
		<dc:subject>php</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-10-15T17:29+09:00</dc:date>
		<content:encoded><![CDATA[<p>require("foo.php")とrequire("./foo.php")って意味違うって知ってました？
cliから実行する場合以外はあまり関係無いかもしれませんが。</p>

<blockquote>
  <p>読み込むファイルはまずカレントのワーキングディレクトリからの相対パスとしてinclude_path で探され、それから、カレントのスクリプトのディレクトリからの相対パスとしてinclude_path で探されます。 (中略)ファイル名が ./ あるいは ../ で始まっている場合は、 カレントのワーキングディレクトリからの相対パスとして探されるのみとなります。
  (<a href="http://jp.php.net/manual/ja/function.include.php">PHP: include - Manual</a>)</p>
</blockquote>

<hr class="seemore">



<p>以下実験。include_pathは<code>.:/php/includes:/usr/share/pear</code>となっています。
で、例えばこんなディレクトリ構成になっているとします。</p>

<pre class="prettyprint"><code>+- foo/
| +- bar/
|   +- a.php
|   +- b.inc
+- b.inc
+- c.inc
</code></pre>

<p>それぞれのファイルの内容はこんな感じ。</p>

<p>foo/bar/a.php</p>

<pre class="prettyprint"><code>&lt;?php
include "b.inc";
include "./b.inc";
include "../../c.inc";
?&gt;
</code></pre>

<p>foo/bar/b.inc</p>

<pre class="prettyprint"><code>This is foo/bar/b.inc
</code></pre>

<p>b.inc</p>

<pre class="prettyprint"><code>This is b.inc
</code></pre>

<p>c.inc</p>

<pre class="prettyprint"><code>This is c.inc
</code></pre>

<p>で、fooディレクトリの上のディレクトリから実行してみます。</p>

<pre class="prettyprint"><code>&#036; php foo/bar/a.php
This is b.inc
This is b.inc
PHP Warning:  include(../../c.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 4
...
</code></pre>

<p>実行結果は、すべてのファイルをスクリプトのあるディレクトリではなく現在の実行ディレクトリから探そうとしていることを意味していますね。</p>

<p><code>include "b.inc"</code>の場合は、ワーキングディレクトリ⇒スクリプトディレクトリの順で探すので、ここで<code>b.inc</code>を削除してみると、</p>

<pre class="prettyprint"><code>&#036; php foo/bar/a.php
This is foo/bar/b.inc
PHP Warning:  include(./b.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 3
...
PHP Warning:  include(../../c.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 4
</code></pre>

<p>と、<code>include "b.inc"</code>は成功しますが、<code>include "./b.inc"</code>はエラーとなります。
straceを見ると、いくつかのパスをトライしている様子が見えます。</p>

<pre class="prettyprint"><code>open("foo/bar/a.php", O_RDONLY)         = 3
# include("b.php") の場合、
# 最初にワーキングディレクトリ
open("/path/to/b.inc", O_RDONLY) = -1 ENOENT (No such file or directory)
# 次にinclude_path
open("/php/includes/b.inc", O_RDONLY)   = -1 ENOENT (No such file or directory)
open("/usr/share/pear/b.inc", O_RDONLY) = -1 ENOENT (No such file or directory)
# 次スクリプトディレクトリで発見
open("/path/to/foo/bar/b.inc", O_RDONLY) = 3
This is foo/bar/b.inc
# include("./b.php") の場合、ワーキングディレクトリに
# 無ければすぐ諦める
open("/path/to/b.inc", O_RDONLY) = -1 ENOENT (No such file or directory)
PHP Warning:  include(./b.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 3
</code></pre>

<p>でも何でこんな仕様になってるんだろう。</p>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/php/e071015_cli_include.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/programming/e070830_start_ror.htm">
		<title>間違ったRuby On Railsのはじめかた</title>
		<link>http://www.mono-space.net/blog/programming/e070830_start_ror.htm</link>
		<description>よくあるscaffoldを使ったチュートリアルをやる。scaffold :modelという一行が何なのか理解できずに悩む。2がスタティックメソッドの呼び出しであることを知り、Rubyではクラス定義の中に任意の式を書けることに驚く。paramsやsessionは何故@paramsや@sessionではないのか悩む。Module#attr_internalの存在を知り、気が遠くなる。←今ここどうもRubyのコードは苦手だ。masuidrive on rails ≫ Blog Archive ≫ Railsでアプリを組むのは簡単か?  Railsでアプリを組むのは、PHPやJavaより楽だけど、Ruby/Railsが使えるようになった人間が、アプリを組むのが楽だって言うだけで、Ruby/Railsを覚えるのがPHP/Javaより簡単って訳じゃない。なるほど。RailsはWebアプリケーションを作るための便利な黒魔術集といったところか。フレームワークとしてうんぬんより、script/generateは便利といった印象。ただしそのscript/generateの使い方をどこで調べたらいいのかよくわからないけど。</description>
		<dc:subject>programming</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-08-30T15:02+09:00</dc:date>
		<content:encoded><![CDATA[<ol>
<li>よくあるscaffoldを使ったチュートリアルをやる。</li>
<li><code>scaffold :model</code>という一行が何なのか理解できずに悩む。</li>
<li>2がスタティックメソッドの呼び出しであることを知り、Rubyではクラス定義の中に任意の式を書けることに驚く。</li>
<li><code>params</code>や<code>session</code>は何故<code>@params</code>や<code>@session</code>ではないのか悩む。</li>
<li><code>Module#attr_internal</code>の存在を知り、気が遠くなる。←今ここ</li>
</ol>

<p>どうもRubyのコードは苦手だ。</p>

<p><a href="http://blog.masuidrive.jp/index.php/2007/08/29/is-rails-easy/">masuidrive on rails ≫ Blog Archive ≫ Railsでアプリを組むのは簡単か?</a></p>

<blockquote>
  <p>Railsでアプリを組むのは、PHPやJavaより楽だけど、Ruby/Railsが使えるようになった人間が、アプリを組むのが楽だって言うだけで、Ruby/Railsを覚えるのがPHP/Javaより簡単って訳じゃない。</p>
</blockquote>

<p>なるほど。
RailsはWebアプリケーションを作るための便利な黒魔術集といったところか。</p>

<p>フレームワークとしてうんぬんより、script/generateは便利といった印象。
ただしそのscript/generateの使い方をどこで調べたらいいのかよくわからないけど。</p>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/programming/e070830_start_ror.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/pgsql/e070824_plproxy.htm">
		<title>PL/Proxyもおもしろいですよ</title>
		<link>http://www.mono-space.net/blog/pgsql/e070824_plproxy.htm</link>
		<description>書こう書こうと思いながら3ヶ月くらい放置していたネタです。巷ではMySQL Proxyが話題のようなので、あえて今年のPostgreSQL ConferenceのJoshのプレゼンでもちょっと出ていたPL/Proxyをいじってみました。spiritlooseのはてなダイアリー - MySQL Proxyがおもしろそうlivedoor Developers Blog:MySQL Proxy を試してみました - livedoor Blog（ブログ）いや実際MySQL Proxyとは全然似てないんですが。MySQL Proxyはクライアントとサーバーの間に挟まる立したサービスのようですが、PL/Proxyは、dblinkやdbmirrorのように、バックエンドから別のバックエンドに接続することでProxyとして動作します。複数のバックエンドに接続することで、クラスタリングやロードバランスを行なうこともできます。えーっと順を追って話すと、PL/Proxyは、名前にPLとあるように、PostgreSQLサーバの中で動く手続き言語です(PL/pgSQLのように)。このPL/Proxyで書いたユーザ定義関数を呼ぶ→別のバックエンドに接続して同じシグネチャの関数を呼ぶ→その戻り値を返す。ということをやります。SkypeGarage/DbProjects/PlProxy - Skype Developer ZoneSkypeGarage/DbProjects/PlProxy/LanguageSyntax - Skype Developer ZoneSkypeGarage/DbProjects/PlProxy/ClusterConfig - Skype Developer Zone実際、上記の3つのURLに書かれていることが全てです。とてもシンプル。インストール&#036; tar zxf plproxy-2.0.2.tar.gz&#036; cd plproxy-2.0.2&#036; gmake; gmake install&#036; psql -f /usr/local/pgsql/share/contrib/plproxy.sql データベース名 CREATE FUNCTIONCREATE LANGUAGEクラスタの設定db1、db2、db3と3つのデータベースがあって、db1にPL/Proxyをインストールしたとします。で、db2、db3にはそれぞれ、hello()というSQL関数を作ります。db2=# create function hello() returns text as &#036;&#036;select 'HELLO db2'::text;&#036;&#036; language sql;CREATE FUNCTIONdb2=# \c db3You are now connected to database "db3".db3=# create function hello() returns text as &#036;&#036;select 'HELLO db3'::text;&#036;&#036; language sql;CREATE FUNCTIONで、db1で、PL/Proxyでhello()関数を作ります。db1=# create function hello() returns text as &#036;&#036;  CLUSTER 'cluster1';  RUN ON ANY;&#036;&#036; language 'plproxy';CREATE FUNCTIONRUN ON ANYというのは、クラスタのどれか一つで実行してよ(要するにロードバランス)を意味しています。他にはRUN ON ALLや、特定のノードを指定して実行させることもできます。ところでそのクラスタの構成はどこで設定するかというと、設定ファイル等があるわけではなく、実はSET RETURN FUNCTION(行を返す関数)で定義します。db1=# create schema plproxy;CREATE SCHEMAdb1=# create or replace function plproxy.get_cluster_version(cluster_name text)db1-# returns integer as &#036;&#036;db1&#036;#   select 1;db1&#036;# &#036;&#036; language sql;CREATE FUNCTIONdb1=# create or replace function plproxy.get_cluster_partitions(cluster_name text)db1-# returns setof text as &#036;&#036;db1&#036;#   select 'dbname=db2'::textdb1&#036;#   uniondb1&#036;#   select 'dbname=db3'::text;db1&#036;# &#036;&#036; language sql;CREATE FUNCTIONdb1=# create or replace function plproxy.get_cluster_config(cluster_name text,db1(#                out key text, out val text)db1-# returns setof record as &#036;&#036;db1&#036;# begindb1&#036;#   return;db1&#036;# end;db1&#036;# &#036;&#036; language plpgsql;CREATE FUNCTION3つ関数を定義していますが、キモはplproxy.get_cluster_partitionsです。これは、クラスタの各ノードへの接続文字列(PQconnectdbの引数)を返すように定義します。今回は単にunionクエリにしてありますが、ここに色々複雑なロジックを書いてもいいわけです。逆に、単にテーブル上に定義したければ、それでもかまいません。db1=# select * from cluster_config; id |  conn_str----+------------  1 | dbname=db2  2 | dbname=db3(2 rows)db1=# create or replace function plproxy.get_cluster_partitions(cluster_name text)db1-# returns setof text as &#036;&#036;db1&#036;# select conn_str from cluster_config;db1&#036;# &#036;&#036; language sql;CREATE FUNCTION今回は同じマシン上で実行していますが、当然'host=... 'と書けば別のマシンに接続させることもできます。実行さてこれで準備ができたので、db1上で関数hello()を実行してみましょう。db1=# select hello();   hello----------- HELLO db2(1 row)db1=# select hello();   hello----------- HELLO db3(1 row)db1=# select hello();   hello----------- HELLO db3(1 row)db1=# select hello();   hello----------- HELLO db2(1 row)db1=# select hello();   hello----------- HELLO db3(1 row)非常に地味ですが。ロードバランスされていることがおわかりでしょうか。というわけで、繰り返しになりますが、やってることとしては、「自分が呼び出されたら、別のところに接続して同じものを呼び出す」だけというシンプルなものです。なんだよ関数呼び出しだけかよと思うかもしれませんが、PostgreSQLのpl/pgsqlやViewやRuleなどと組み合わせると、結構色々な使い方ができるんじゃないかなと思います。</description>
		<dc:subject>pgsql</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-08-24T11:56+09:00</dc:date>
		<content:encoded><![CDATA[<p>書こう書こうと思いながら3ヶ月くらい放置していたネタです。
巷ではMySQL Proxyが話題のようなので、
あえて今年のPostgreSQL ConferenceのJoshのプレゼンでもちょっと出ていたPL/Proxyをいじってみました。</p>

<ul>
<li><a href="http://d.hatena.ne.jp/spiritloose/20070628/1183008971">spiritlooseのはてなダイアリー - MySQL Proxyがおもしろそう</a></li>
<li><a href="http://blog.livedoor.jp/techblog/archives/64655991.html">livedoor Developers Blog:MySQL Proxy を試してみました - livedoor Blog（ブログ）</a></li>
</ul>

<hr class="seemore">



<p>いや実際MySQL Proxyとは全然似てないんですが。MySQL Proxyはクライアントとサーバーの間に挟まる立したサービスのようですが、
PL/Proxyは、dblinkやdbmirrorのように、バックエンドから別のバックエンドに接続することでProxyとして動作します。複数のバックエンドに接続することで、クラスタリングやロードバランスを行なうこともできます。</p>

<p>えーっと順を追って話すと、PL/Proxyは、名前に<code>PL</code>とあるように、PostgreSQLサーバの中で動く手続き言語です(PL/pgSQLのように)。
このPL/Proxyで書いたユーザ定義関数を呼ぶ→別のバックエンドに接続して同じシグネチャの関数を呼ぶ→その戻り値を返す。ということをやります。</p>

<ul>
<li><a href="https://developer.skype.com/SkypeGarage/DbProjects/PlProxy">SkypeGarage/DbProjects/PlProxy - Skype Developer Zone</a></li>
<li><a href="https://developer.skype.com/SkypeGarage/DbProjects/PlProxy/LanguageSyntax">SkypeGarage/DbProjects/PlProxy/LanguageSyntax - Skype Developer Zone</a></li>
<li><a href="https://developer.skype.com/SkypeGarage/DbProjects/PlProxy/ClusterConfig">SkypeGarage/DbProjects/PlProxy/ClusterConfig - Skype Developer Zone</a></li>
</ul>

<p>実際、上記の3つのURLに書かれていることが全てです。とてもシンプル。</p>

<h1>インストール</h1>

<pre class="prettyprint"><code>&#036; tar zxf plproxy-2.0.2.tar.gz
&#036; cd plproxy-2.0.2
&#036; gmake; gmake install
&#036; psql -f /usr/local/pgsql/share/contrib/plproxy.sql データベース名 
CREATE FUNCTION
CREATE LANGUAGE
</code></pre>

<h1>クラスタの設定</h1>

<p>db1、db2、db3と3つのデータベースがあって、db1にPL/Proxyをインストールしたとします。で、db2、db3にはそれぞれ、hello()というSQL関数を作ります。</p>

<pre class="prettyprint"><code>db2=# create function hello() returns text as &#036;&#036;select 'HELLO db2'::text;&#036;&#036; language sql;
CREATE FUNCTION
db2=# \c db3
You are now connected to database "db3".
db3=# create function hello() returns text as &#036;&#036;select 'HELLO db3'::text;&#036;&#036; language sql;
CREATE FUNCTION
</code></pre>

<p>で、db1で、PL/Proxyでhello()関数を作ります。</p>

<pre class="prettyprint"><code>db1=# create function hello() returns text as &#036;&#036;
  CLUSTER 'cluster1';
  RUN ON ANY;
&#036;&#036; language 'plproxy';
CREATE FUNCTION
</code></pre>

<p><code>RUN ON ANY</code>というのは、クラスタのどれか一つで実行してよ(要するにロードバランス)を意味しています。他には<code>RUN ON ALL</code>や、特定のノードを指定して実行させることもできます。</p>

<p>ところでそのクラスタの構成はどこで設定するかというと、設定ファイル等があるわけではなく、実はSET RETURN FUNCTION(行を返す関数)で定義します。</p>

<pre class="prettyprint"><code>db1=# create schema plproxy;
CREATE SCHEMA
db1=# create or replace function plproxy.get_cluster_version(cluster_name text)
db1-# returns integer as &#036;&#036;
db1&#036;#   select 1;
db1&#036;# &#036;&#036; language sql;
CREATE FUNCTION
db1=# create or replace function plproxy.get_cluster_partitions(cluster_name text)
db1-# returns setof text as &#036;&#036;
db1&#036;#   select 'dbname=db2'::text
db1&#036;#   union
db1&#036;#   select 'dbname=db3'::text;
db1&#036;# &#036;&#036; language sql;
CREATE FUNCTION
db1=# create or replace function plproxy.get_cluster_config(cluster_name text,
db1(#                out key text, out val text)
db1-# returns setof record as &#036;&#036;
db1&#036;# begin
db1&#036;#   return;
db1&#036;# end;
db1&#036;# &#036;&#036; language plpgsql;
CREATE FUNCTION
</code></pre>

<p>3つ関数を定義していますが、キモは<code>plproxy.get_cluster_partitions</code>です。
これは、クラスタの各ノードへの接続文字列(
<a href="http://www.postgresql.jp/document/current/html/libpq-connect.html">PQconnectdb</a>
の引数)を返すように定義します。
今回は単にunionクエリにしてありますが、ここに色々複雑なロジックを書いても
いいわけです。逆に、単にテーブル上に定義したければ、それでもかまいません。</p>

<pre class="prettyprint"><code>db1=# select * from cluster_config;
 id |  conn_str
----+------------
  1 | dbname=db2
  2 | dbname=db3
(2 rows)
db1=# create or replace function plproxy.get_cluster_partitions(cluster_name text)
db1-# returns setof text as &#036;&#036;
db1&#036;# select conn_str from cluster_config;
db1&#036;# &#036;&#036; language sql;
CREATE FUNCTION
</code></pre>

<p>今回は同じマシン上で実行していますが、当然<code>'host=... '</code>と書けば別のマシン
に接続させることもできます。</p>

<h1>実行</h1>

<p>さてこれで準備ができたので、db1上で関数<code>hello()</code>を実行してみましょう。</p>

<pre class="prettyprint"><code>db1=# select hello();
   hello
-----------
 HELLO db2
(1 row)

db1=# select hello();
   hello
-----------
 HELLO db3
(1 row)

db1=# select hello();
   hello
-----------
 HELLO db3
(1 row)

db1=# select hello();
   hello
-----------
 HELLO db2
(1 row)

db1=# select hello();
   hello
-----------
 HELLO db3
(1 row)
</code></pre>

<p>非常に地味ですが。ロードバランスされていることがおわかりでしょうか。</p>

<p>というわけで、繰り返しになりますが、やってることとしては、
「自分が呼び出されたら、別のところに接続して同じものを呼び出す」
だけというシンプルなものです。なんだよ関数呼び出しだけかよと
思うかもしれませんが、
PostgreSQLのpl/pgsqlやViewやRuleなどと組み合わせると、
結構色々な使い方ができるんじゃないかなと思います。</p>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/pgsql/e070824_plproxy.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/pgsql/e070619_fizzbuzz.htm">
		<title>今さらFizzBuzz(当然PostgreSQL)</title>
		<link>http://www.mono-space.net/blog/pgsql/e070619_fizzbuzz.htm</link>
		<description>色々考えたけど、まあ許せるのはこのくらいか。-- スタンダードにselect case  when i%15=0 then 'FizzBuzz'  when i%5=0 then 'Buzz'  when i%3=0 then 'Fizz'  else i::text end  from generate_series(1,100)as s(i);-- ちょっとアグレッシブに(8.2以降)select coalesce(v15.t, v3.t, v5.t, s.i::text)  from generate_series(1,100)as s(i)  left join(       values(0,'FizzBuzz')) as v15(i,t) on (s.i%15=v15.i)  left join(       values(0,'Fizz')) as v3(i,t) on (s.i%3=v3.i)  left join(       values(0,'Buzz')) as v5(i,t) on (s.i%5=v5.i)あ、valuesじゃなくて普通にサブクエリでいいのか。まあvaluesって書いてみたかっただけです。</description>
		<dc:subject>pgsql</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-06-19T10:18+09:00</dc:date>
		<content:encoded><![CDATA[<p>色々考えたけど、まあ許せるのはこのくらいか。</p>

<pre class="prettyprint"><code>-- スタンダードに
select case
  when i%15=0 then 'FizzBuzz'
  when i%5=0 then 'Buzz'
  when i%3=0 then 'Fizz'
  else i::text end
  from generate_series(1,100)as s(i);


-- ちょっとアグレッシブに(8.2以降)
select coalesce(v15.t, v3.t, v5.t, s.i::text)
  from generate_series(1,100)as s(i)
  left join(
       values(0,'FizzBuzz')) as v15(i,t) on (s.i%15=v15.i)
  left join(
       values(0,'Fizz')) as v3(i,t) on (s.i%3=v3.i)
  left join(
       values(0,'Buzz')) as v5(i,t) on (s.i%5=v5.i)
</code></pre>

<p>あ、valuesじゃなくて普通にサブクエリでいいのか。まあvaluesって書いてみたかっただけです。</p>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/pgsql/e070619_fizzbuzz.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/php/e070615_smarty_truncate.htm">
		<title>Smartyのtruncateはfunc_overloadでいいんじゃない</title>
		<link>http://www.mono-space.net/blog/php/e070615_smarty_truncate.htm</link>
		<description>ずいぶん前からよく見かける話題だけど、また最近見かけたので。Smarty研究（2）マルチバイト文字に対応した truncate 修飾子を作るgoogle:smarty truncateいちばん手っ取り早いのは、mbstring.func_overloadを設定しちゃうことだと思いますよ。自分でプラグイン書く必要とか無いです。マルチバイト対応版関数による既存関数のオーバーロード - PHPドキュメントthemeにセットされる変数（たとえば$xoops_pagetitle）の文字数を短く切りたい。</description>
		<dc:subject>php</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-06-15T03:51+09:00</dc:date>
		<content:encoded><![CDATA[<p>ずいぶん前からよく見かける話題だけど、また最近見かけたので。</p>

<ul>
<li><a href="http://c-brains.jp/blog/wsg/07/06/14-160910.php">Smarty研究（2）マルチバイト文字に対応した truncate 修飾子を作る</a></li>
<li><a href="http://www.google.co.jp/search?hl=ja&amp;q=smarty+truncate&amp;btnG=Google+%E6%A4%9C%E7%B4%A2&amp;lr=lang_ja">google:smarty truncate</a></li>
</ul>

<p>いちばん手っ取り早いのは、mbstring.func_overloadを設定しちゃうことだと思いますよ。自分でプラグイン書く必要とか無いです。</p>

<ul>
<li><a href="http://jp.php.net/manual/ja/ref.mbstring.php#mbstring.overload">マルチバイト対応版関数による既存関数のオーバーロード - PHPドキュメント</a></li>
<li><a href="http://kizumo.com/modules/smartfaq/faq.php?faqid=11">themeにセットされる変数（たとえば$xoops_pagetitle）の文字数を短く切りたい。</a></li>
</ul>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/php/e070615_smarty_truncate.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/misc/e070608_iroiro.htm">
		<title>交換不可能な(ry</title>
		<link>http://www.mono-space.net/blog/misc/e070608_iroiro.htm</link>
		<description>ちょっとささくれだってるんで。Q:交換不可能な能力に磨きをかけるに何をすべきか？ A:blogを書けばいいと思うよ - 一人シリコンバレー男 [ITmedia オルタナティブ・ブログ]小野和俊のブログ:梅田望夫氏が言うように、好きなことを貫いて仕事にしていくためにはどのようにすればよいのか「これは自分しか出来無い」なんてプレッシャーの中で仕事をしていくことが僕のゴールなのだろうか。</description>
		<dc:subject>misc</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-06-08T21:40+09:00</dc:date>
		<content:encoded><![CDATA[<p>ちょっとささくれだってるんで。</p>

<ul>
<li><a href="http://blogs.itmedia.co.jp/kudou/2007/06/q_ablog_553b.html?ref=rssall">Q:交換不可能な能力に磨きをかけるに何をすべきか？ A:blogを書けばいいと思うよ - 一人シリコンバレー男 [ITmedia オルタナティブ・ブログ]</a></li>
<li><a href="http://blog.livedoor.jp/lalha/archives/50167531.html">小野和俊のブログ:梅田望夫氏が言うように、好きなことを貫いて仕事にしていくためにはどのようにすればよいのか</a></li>
</ul>

<p>「これは自分しか出来無い」なんてプレッシャーの中で仕事をしていくことが僕のゴールなのだろうか。</p>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/misc/e070608_iroiro.trackback"/>
	</item>
	<item rdf:about="http://www.mono-space.net/blog/php/e070531_directlink.htm">
		<title>ファイルの直リンクを防止する方法をもう少し考えてみる</title>
		<link>http://www.mono-space.net/blog/php/e070531_directlink.htm</link>
		<description>Refererを使わずに直リンクを防止する方法を考えてみます。元ネタ: cl.pocari.org - PHP の apache_setenv と virtual を利用して，ファイルへの直リンクを防止する  この foo.php のファイル名を時間によって変えるなどすれば，まあ，直リンクを防止することができる……のかな？ちと強引ですが．つまり、「直リンクを防止する」ことを考えるより「ある一定時間しか有効でないURLを作る」ことを考えれば良いということじゃないでしょうか。で、foo.phpのファイル名を変えちゃうと、外部からの直リンクは防げても、内部からの普通のリンクを貼る時に困りそうです(それならぶっちゃけ、画像のファイル名そのものを時間によって変えちゃってもいいわけだし)。なので、時刻をパラメータとして渡す方針で。フェーズ1foo.php?t=....のようにfoo.phpにタイムスタンプを渡すfoo.phpの中で&#036;_GET['t']と現在時刻を比較し、n分以上たっていればはじくでもこれじゃ簡単に偽装されちゃうYO!なので、フェーズ2foo.phpにタイムスタンプと、(タイムスタンプ+秘密鍵)のHMACを渡す。foo.phpの中で、(タイムスタンプ+秘密鍵)のHMACを再計算して、渡ってきたHMACと一致するかチェック。foo.phpの中で&#036;_GET['t']と現在時刻を比較し、n分以上たっていればはじくな感じじゃないでしょうか。本当はapache moduleとかで書いた方が楽そうですが。</description>
		<dc:subject>php</dc:subject>
		<dc:creator>ISHIDA Akio (mailto:iakio@mono-space.net)</dc:creator>
		<dc:date>2007-05-31T07:58+09:00</dc:date>
		<content:encoded><![CDATA[<p>Refererを使わずに直リンクを防止する方法を考えてみます。</p>

<p>元ネタ: <a href="http://cl.pocari.org/2007-05-30-1.html">cl.pocari.org - PHP の apache_setenv と virtual を利用して，ファイルへの直リンクを防止する</a></p>

<blockquote>
  <p>この foo.php のファイル名を時間によって変えるなどすれば，まあ，直リンクを防止することができる……のかな？ちと強引ですが．</p>
</blockquote>

<p>つまり、「直リンクを防止する」ことを考えるより「ある一定時間しか有効でないURLを作る」ことを考えれば良いということじゃないでしょうか。</p>

<p>で、foo.phpのファイル名を変えちゃうと、外部からの直リンクは防げても、内部からの普通のリンクを貼る時に困りそうです(それならぶっちゃけ、画像のファイル名そのものを時間によって変えちゃってもいいわけだし)。</p>

<p>なので、時刻をパラメータとして渡す方針で。</p>

<p>フェーズ1</p>

<ol>
<li><code>foo.php?t=....</code>のようにfoo.phpにタイムスタンプを渡す</li>
<li>foo.phpの中で<code>&#036;_GET['t']</code>と現在時刻を比較し、n分以上たっていればはじく</li>
<li>でもこれじゃ簡単に偽装されちゃうYO!</li>
</ol>

<p>なので、フェーズ2</p>

<ol>
<li>foo.phpにタイムスタンプと、(タイムスタンプ+秘密鍵)のHMACを渡す。</li>
<li>foo.phpの中で、(タイムスタンプ+秘密鍵)のHMACを再計算して、渡ってきたHMACと一致するかチェック。</li>
<li>foo.phpの中で<code>&#036;_GET['t']</code>と現在時刻を比較し、n分以上たっていればはじく</li>
</ol>

<p>な感じじゃないでしょうか。本当はapache moduleとかで書いた方が楽そうですが。</p>
]]></content:encoded>
		<trackback:ping rdf:resource="http://www.mono-space.net/blog/php/e070531_directlink.trackback"/>
	</item>
</rdf:RDF>
