<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
<channel>
	<title>adiary開発日誌</title>
	<link>http://adiary.blog.abk.nu/</link>
	<language>ja</language>
	<description>おもにadiaryの開発に関する話題を扱います。 </description>
	<copyright>Copyright 2010</copyright>
	<pubDate>Wed, 10 Mar 2010 15:59:05 GMT</pubDate>
	<lastBuildDate>Wed, 10 Mar 2010 15:59:05 GMT</lastBuildDate>
	<generator>http://adiary.abk.nu/#2.12</generator>
	<docs>http://blogs.law.harvard.edu/tech/rss</docs> 
	<item>
		<title>SpeedyCGI で ImageMagick が動かない</title>
		<link>http://adiary.blog.abk.nu/0267#tm1267026622</link>
		<guid>http://adiary.blog.abk.nu/0267</guid>
		<category>プログラム::perl</category>
		<pubDate>Mon, 22 Feb 2010 14:16:26 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<p>Webアプリ開発中に ImageMagick（perlmagick）が SpeedyCGI 環境でまともに動かない不具合に当たりました。</p>
<ul>
	<li><a href="http://adiary.blog.abk.nu/0267#k267p1">問題の詳細</a>
	<li><a href="http://adiary.blog.abk.nu/0267#k267p2">問題の症状</a>
	<li><a href="http://adiary.blog.abk.nu/0267#k267p3">問題の原因</a>
	<li><a href="http://adiary.blog.abk.nu/0267#k267p4">問題の解決法？？</a>
	<li><a href="http://adiary.blog.abk.nu/0267#k267p5">まとめ</a>
	<li><a href="http://adiary.blog.abk.nu/0267#k267p6">メモ</a>
</ul>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0267#k267p1"><span>■</span></a>問題の詳細</h3>
<ul>
	<li>Image::Magick をロードして何かしら処理を行うルーチンを SpeedyCGI で実行する時、２回目以降のキャッシュされた状態で不具合が起こる<span><a title="スクリプトの処理が停止してしまう。もしくは処理中のまま返ってこなくなる" href="http://adiary.blog.abk.nu/0267#fk267n1">*1</a></span>。</li>
	<li>問題確認環境
	<ul>
		<li>Perl 5.8.8 + SpeedyCGI 2.22</li>
		<li>ImageMagick 6.3.7 および 6.5.9</li>
	</ul>
	</li>
</ul>
<p>この問題は FastCGI や mod_perl2 では起きません。</p>
</div>
<div>
	<p><a href="http://adiary.blog.abk.nu/0267#k267n1">*1</a> : スクリプトの処理が停止してしまう。もしくは処理中のまま返ってこなくなる</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0267#k267p2"><span>■</span></a>問題の症状</h3>
<p>スクリプト</p>
<pre>
#!/usr/bin/speedy

use Image::Magick();

print "Content-Type: text/plain\n\n";
print "Image::Magick Version $Image::Magick::VERSION \n";
my $image = Image::Magick-&gt;new;
$image-&gt;Read( 'x.png' );
}
</pre>
<p>実行結果。</p>
<pre>
<span>~$ test.pl</span>
Image::Magick Version 6.3.7
<span>~$ test.pl</span>
Segmentation fault
</pre>
<pre>
<span>~$ test.pl</span>
Image::Magick Version 6.5.9
<span>~$ test.pl</span>
Segmentation fault
</pre>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0267#k267p3"><span>■</span></a>問題の原因</h3>
<p>不明。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0267#k267p4"><span>■</span></a>問題の解決法？？</h3>
<p>ENDブロックを呼ばれないようにして終了時のメモリ開放はOSやPerl自身に任せる。</p>
<pre>
#!/usr/bin/speedy

use Image::Magick();
<strong>sub Image::Magick::END {}</strong>

print "Content-Type: text/plain\n\n";
print "Image::Magick Version $Image::Magick::VERSION \n";
my $image = Image::Magick-&gt;new;
$image-&gt;Read( 'x.png' );
}
</pre>
<p>たしかにこれで問題は起こらなくなるのですが、</p>
<pre>
$image-&gt;Write( 'x.jpg' );
</pre>
<p>をするだけでダメになる。とにかくメモリリークっぽい挙動ですが、詳細が不明の挙動不明で、試行錯誤の末 Image::Magick をロードするダミーモジュールを作成しましたが、これで回避できるケースと回避できないケースがあり暗中模索。</p>
<ul>
	<li>ImageMagick.pm
<pre>
use strict;
package ImageMagick;
sub new {
	require Image::Magick;
	return Image::Magick-&gt;new;
}
</pre>
	</li>
	<li>main.pl
<pre>
use ImageMagick();
my $img = ImageMagick-&gt;new;
#
# $img は Image::Magick のオブジェクトであるので、
# Image::Magick と同様に利用できる。
#
</pre>
	</li>
</ul>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0267#k267p5"><span>■</span></a>まとめ</h3>
<del>
<p>とりあえず現在のところ挙動が意味不明です。ファイル入出力と関連してバグっている様ですが……。</p>
</del>
<p><a href="https://bugs.launchpad.net/ubuntu/+source/gcc-4.2/+bug/235070">gccの（ライブラリlibgomp ）バグのようです</a>。gcc 4.3より前のVersion（4.2以下）で、amd64環境の時起こる模様。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0267#k267p6"><span>■</span></a>メモ</h3>
<p>256色png（8bitカラーパレット）で保存する方法。</p>
<pre>
$image-&gt;Read( 'x.png' );
$image-&gt;Resize(width=&gt;133, height=&gt;100);
$image-&gt;Quantize(colorspace=&gt;'RGB',colors=&gt;256);
$image-&gt;Set(depth =&gt; 8); 
$image-&gt;Write( 'y.png' );
</pre>

</div>

<hr>
<h4><a href="/0267#c">■コメント（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
<h4><a href="/0267#tb">■トラックバック（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
]]></description>
	</item>
	<item>
		<title>画像の縦横中央配置 / CSS / クロスブラウザ</title>
		<link>http://adiary.blog.abk.nu/0266#tm1267003688</link>
		<guid>http://adiary.blog.abk.nu/0266</guid>
		<category>プログラム::javascript</category>
		<pubDate>Thu, 18 Feb 2010 19:30:44 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<h3><a href="http://adiary.blog.abk.nu/0266#k266p1"><span>■</span></a>画像の縦横中央配置</h3>
<p>HTMLのソース。余計な改行やスペースを入れないこと。</p>
<pre>
&lt;div class="image"&gt;&lt;span class="dummy"&gt;&lt;/span&gt;&lt;img src="xxx.png" /&gt;&lt;/div&gt;
</pre>
<p>CSS。</p>
<pre>
div.image {
	border:		1px solid #8ff;

	min-width:	320px;
	width:		320px;
	height:		240px;
	_width:		322px;
	_height:	242px;

	text-align:	center;
	display:	block;
}
div.image span.dummy {
	height:		240px;
	width:		0px;
	vertical-align:	middle;
	display:	inline-block;
}
div.image img {
	max-width:	320px;
	max-height:	240px;
	vertical-align:	middle;

	/* IE6 hack */
	_margin-top:	-1px;
	/* IE6 でアスペクト比保存縮小のためのhack */
	_width:		expression(this.height&gt;240 &amp;&amp; this.width*3&lt;this.height*4 ? Math.floor(this.width*240/this.height) : (this.width &gt; 320 ? 320: true ));
	_height:	expression(this.height&gt;240 ? 240: true );
}
*:first-child+html div.image img { /* IE7 hack */
	margin-top:	-1px;
}
</pre>
<ul>
	<li>画像領域は320*240。</li>
	<li>モダンブラウザは問題なく表示。</li>
	<li>IE6は後方互換モード、IE7は標準準拠モード+ie8.js。</li>
	<li>"margin-top: -1px;"してあげないと画像がなぜか下に1pxずれてしまう。</li>
</ul>
<p>「span.dummy」を「display: inline-block」するのが縦方向センタリングのポイントです。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0266#k266p2"><span>■</span></a>IE6で縦横比保存なmax-width, max-height</h3>
<pre>
img {
	max-width:	320px;
	max-height:	240px;
	_width:		expression(this.height&gt;240 &amp;&amp; this.width*3&lt;this.height*4 ? Math.floor(this.width*240/this.height) : (this.width &gt; 320 ? 320: true ));
	_height:	expression(this.height&gt;240 ? 240: true );
}
</pre>
<p>240と320を好みのサイズに変更してください。</p>

</div>

<hr>
<h4><a href="/0266#c">■コメント（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
<h4><a href="/0266#tb">■トラックバック（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
]]></description>
	</item>
	<item>
		<title>JavaScriptでオブジェクト指向なメモ</title>
		<link>http://adiary.blog.abk.nu/0265#tm1265732391</link>
		<guid>http://adiary.blog.abk.nu/0265</guid>
		<category>プログラム::javascript</category>
		<pubDate>Sat, 30 Jan 2010 16:40:25 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<p>適当に追記します。</p>
<ul>
	<li><a href="http://adiary.blog.abk.nu/0265#k265p1">雑多なおさらい</a>
	<li><a href="http://adiary.blog.abk.nu/0265#k265p2">オブジェクト（っぽいもの）の生成</a>
	<li><a href="http://adiary.blog.abk.nu/0265#k265p3">メンバ関数をコールバックさせる　方法１</a>
	<li><a href="http://adiary.blog.abk.nu/0265#k265p4">メンバ関数をコールバックさせる　方法２</a>
</ul>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0265#k265p1"><span>■</span></a>雑多なおさらい</h3>
<ul>
	<li>JavaScriptのクラスの概念はないらしい。</li>
	<li>プリミティブな数字や文字列など意外は、すべてオブジェクトであり参照。</li>
	<li>参照なので代入した側でメンバ変数をいじると、代入元も書き換わる。</li>
	<li>関数を変数に代入できる。
<pre>
var f = function (x){ alert(x); }
f("msg");    // "msg"と表示される
</pre>
	</li>
</ul>
<p>Perl5のオブジェクトに似たところがありますが、クラス名前空間（パッケージ）を持たないため、Perl5よりも簡素な実装と言えそうです。</p>
<p><a href="http://adiary.blog.abk.nu/0265#k265p1">続きを読む</a></p>
</div>

<hr>
<h4><a href="/0265#c">■コメント（2件）</a></h4>
<div style="margin-left: 1em;">
Yorkfield『&gt; オブジェクト（っぽいもの）の生成 ・JavaScriptは大小文字を区別するのでそのままだとエラーになってしまいます。 ・メ...』(2010/02/06 28:49)</span><br>
なべ『&gt;・JavaScriptは大小文字を区別するので &gt;・メンバ関数add/subはメンバ変数を変更してないので、 しまった。単純な...』(2010/02/09 25:19)</span><br>
</div>
<h4><a href="/0265#tb">■トラックバック（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
]]></description>
	</item>
	<item>
		<title>PostgreSQL関連メモ</title>
		<link>http://adiary.blog.abk.nu/0264#tm1265265841</link>
		<guid>http://adiary.blog.abk.nu/0264</guid>
		<category>プログラム::DB</category>
		<pubDate>Sat, 30 Jan 2010 15:40:33 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<p>あとで適当に追記。</p>
<ul>
	<li><a href="http://adiary.blog.abk.nu/0264#k264p1">共有メモリ設定</a>
	<li><a href="http://adiary.blog.abk.nu/0264#k264p2">制約やカラムの操作</a>
</ul>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0264#k264p1"><span>■</span></a>共有メモリ設定</h3>
<p>共有メモリの確認</p>
<pre>
# ipcs -m
# cat /proc/sys/kernel/shmmax
</pre>
<p>共有メモリの変更</p>
<pre>
1G
# echo 1099511627776 &gt;/proc/sys/kernel/shmmax
1.5G
# echo 1649267441664 &gt;/proc/sys/kernel/shmmax
</pre>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0264#k264p2"><span>■</span></a>制約やカラムの操作</h3>
<p>Ver8.3で確認。テーブル名、カラム名が変更されていても作成時のものとなるので注意。</p>
<table>
<tbody>
	<tr><th>制約の種類</th><th>制約名</th></tr>
	<tr><th>PRIMARY KEY</th><td>[table]_pkey</td></tr>	<tr><th>UNIQUE</th><td>[table]_[col]_key</td></tr>	<tr><th>REFERENCES</th><td>[table]_[col]_fkey</td></tr></tbody></table>
<pre>
ALTER TABLE table ADD CONSTRAINT table_[col]_fkey FOREIGN KEY ([col]) REFERENCES usr([ref_col]);
ALTER TABLE table DROP CONSTRAINT table_[col]_key;
</pre>
<table>
<tbody>
	<tr><th>目的</th><th>SQL</th></tr>
	<tr><td>NOT NULLを付ける</td><td>ALTER TABLE table ALTER COLUMN [col] SET NOT NULL</td></tr>	<tr><td>NOT NULLを外す</td><td>ALTER TABLE table ALTER COLUMN [col] DROP NOT NULL</td></tr>	<tr><td>DEFAULTを付ける</td><td>ALTER TABLE table ALTER COLUMN [col] SET DEFAULT [value]</td></tr>	<tr><td>DEFAULTを外す</td><td>ALTER TABLE table ALTER COLUMN [col] DROP DEFAULT</td></tr>	<tr><td>カラム名を変える</td><td>ALTER TABLE table RENAME [old_col] TO [new_col]</td></tr>	<tr><td>テーブル名を変える</td><td>ALTER TABLE table RENAME TO table2</td></tr>
</tbody></table>

</div>

<hr>
<h4><a href="/0264#c">■コメント（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
<h4><a href="/0264#tb">■トラックバック（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
]]></description>
	</item>
	<item>
		<title>Perl用、日本語「全角」→「半角」変換ルーチン</title>
		<link>http://adiary.blog.abk.nu/0263#tm1263625582</link>
		<guid>http://adiary.blog.abk.nu/0263</guid>
		<category>プログラム::perl</category>
		<pubDate>Sat, 09 Jan 2010 08:29:27 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<p>よくネットショップ等で買い物をすると</p>
<blockquote>
<p><strong>郵便番号は半角で入力してください。</strong></p>
</blockquote>
<p>とか言われてウザくないですか？　こういうのを解消するためのルーチンです。</p>
<ul>
	<li><a href="http://adiary.blog.abk.nu/0263#k263p1">条件</a>
	<li><a href="http://adiary.blog.abk.nu/0263#k263p2">日本語に混ざる全角英数等を半角にする</a>
	<li><a href="http://adiary.blog.abk.nu/0263#k263p3">半角カタカナを全角カタカナにする</a>
	<ul>
		<li><a href="http://adiary.blog.abk.nu/0263#k263p3.1">Encode::JP::H2Z</a>
	</ul></li>
	<li><a href="http://adiary.blog.abk.nu/0263#k263p4">その他</a>
</ul>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0263#k263p1"><span>■</span></a>条件</h3>
<ul>
	<li><strong>Perl 5.8以降</strong></li>	<li>利用可能文字列はutf-8のみ（そうでない場合はutf8に変換して渡してください）</li>
	<li><a href="http://ja.wikipedia.org/wiki/WTFPL" title="Wikipedia">WTFPL</a>（PDS扱いでも可）。</li></ul>
<p>ソースは必ずutf-8で保存してください。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0263#k263p2"><span>■</span></a>日本語に混ざる全角英数等を半角にする</h3>
<pre>
use utf8;
use Encode ();
sub utf8_zen2han {
	my $str = shift;
	my $flag = utf8::is_utf8($str);
	Encode::_utf8_on($str);

	$str =~ tr/　！”＃＄％＆’（）＊＋，－．／０-９：；＜＝＞？＠Ａ-Ｚ［￥］＾＿｀ａ-ｚ｛｜｝/ -}/;

	if (!$flag) { Encode::_utf8_off($str); }
	return $str;
}
</pre>
<p>実行例。</p>
<pre>
（変換前）ａｂｃｄｅｆｇさささ１１０－２２４４あいう＃＃＄”
（変換後）abcdefgさささ110-2244あいう##$"
</pre>
<br>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0263#k263p3"><span>■</span></a>半角カタカナを全角カタカナにする</h3>
<pre>
use utf8;
use Encode ();

my %hankana_map = (
'ｶﾞ'=&gt;'ガ','ｷﾞ'=&gt;'ギ','ｸﾞ'=&gt;'グ','ｹﾞ'=&gt;'ゲ','ｺﾞ'=&gt;'ゴ',
'ｻﾞ'=&gt;'ザ','ｼﾞ'=&gt;'ジ','ｽﾞ'=&gt;'ズ','ｾﾞ'=&gt;'ゼ','ｿﾞ'=&gt;'ゾ',
'ﾀﾞ'=&gt;'ダ','ﾁﾞ'=&gt;'ヂ','ﾂﾞ'=&gt;'ヅ','ﾃﾞ'=&gt;'デ','ﾄﾞ'=&gt;'ド',
'ﾊﾞ'=&gt;'バ','ﾋﾞ'=&gt;'ビ','ﾌﾞ'=&gt;'ブ','ﾍﾞ'=&gt;'ベ','ﾎﾞ'=&gt;'ボ',
'ﾊﾟ'=&gt;'パ','ﾋﾟ'=&gt;'ピ','ﾌﾟ'=&gt;'プ','ﾍﾟ'=&gt;'ペ','ﾎﾟ'=&gt;'ポ',
'ｳﾞ'=&gt;'ヴ');

sub utf8_hankana2zen {
	my $str = shift;

	my $flag = utf8::is_utf8($$str);
	Encode::_utf8_on($$str);

	$str =~ s/(ｶﾞ|ｷﾞ|ｸﾞ|ｹﾞ|ｺﾞ|ｻﾞ|ｼﾞ|ｽﾞ|ｾﾞ|ｿﾞ|ﾀﾞ|ﾁﾞ|ﾂﾞ|ﾃﾞ|ﾄﾞ|ﾊﾞ|ﾋﾞ|ﾌﾞ|ﾍﾞ|ﾎﾞ|ﾊﾟ|ﾋﾟ|ﾌﾟ|ﾍﾟ|ﾎﾟ|ｳﾞ)/$hankana_map{$1}/g;
	$str =~ tr/｡-ﾟ/。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゛゜/;

	if (!$flag) { Encode::_utf8_off($str); }
	return $str;
}
</pre>
<h4><a href="http://adiary.blog.abk.nu/0263#k263p3.1"><span></span>Encode::JP::H2Z</a></h4>
<p>EUC-JPの場合は標準モジュールで行くようです。（竹さん感謝）</p>
<pre>
use Encode ();
use Encode::JP::H2Z ();

sub eucjp_hankana2zen {
	my $str = shift;
	Encode::JP::H2Z::h2z(\$str);
	return $str;
}
</pre>
<p>逆変換は Encode::JP::H2Z::z2h()。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0263#k263p4"><span>■</span></a>その他</h3>
<p>バグ等あったらコメントください。</p>

</div>

<hr>
<h4><a href="/0263#c">■コメント（4件）</a></h4>
<div style="margin-left: 1em;">
竹『Encode::JP::H2Z の h2z, z2h でいいのでは？』(2010/01/09 19:44)</span><br>
なべ『そんな便利なものが標準でついてましたか（汗） Jcode.pmに付いてるのは知ってたのですが(^^; 指摘感謝です。』(2010/01/09 19:49)</span><br>
つーさ『私は、住所欄に番地を半角で打って 「住所を全角で入力してください！」と言われるのが逆にウザいです……(笑』(2010/01/15 28:13)</span><br>
なべ『&gt;「住所を全角で入力してください！」と言われるのが逆にウザいです……(笑 よくありますね、それ。 いちいち全角で入れなきゃいかな...』(2010/01/16 16:06)</span><br>
</div>
<h4><a href="/0263#tb">■トラックバック（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
]]></description>
	</item>
	<item>
		<title>adiary Ver2.12リリース情報</title>
		<link>http://adiary.blog.abk.nu/0262#tm1268236745</link>
		<guid>http://adiary.blog.abk.nu/0262</guid>
		<category>adiary::リリース</category>
		<pubDate>Wed, 16 Dec 2009 15:49:42 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<p>Ver2.11に対しバグ修正を行いました。変更点を参照の上、必要ならばバージョンアップしてください。</p>
<p><a href="http://adiary.org/download.html">ダウンロードはこちらから</a>。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0262#k262p1"><span>■</span></a>Ver2.11→Ver2.12の変更点</h3>
<ul>
	<li>テーマディレクトリを変更すると「印刷用の表示」がリンク切れになるバグを修正。</li>
	<li>クラス追加。div.hatena-body0, a.adiary, li.to-album (_frame.html/_sidebar.html)</li>
	<li>浅野さんご指摘＆パッチ（感謝）。
	<ul>
		<li>アルバムのサムネイルビューでサムネイル上にマウスカーソルを置いたときにポップアップする情報が実際のファイルと一致しないバグを修正。</li>
		<li>アルバムのスライドショーでファイルを選択したときに左上に表示されるファイル名とバイト数が実際のファイルと一致しないバグを修正。</li>
		<li>アルバムで「すべて選択」「選択を解除」ボタンをクリックしても正常に動作しないバグを修正。</li>
		<li>携帯画面でのコメント表示がエラーになることがある不具合を修正。</li>
		<li>スーパーpre記法中等に行頭にスペースが1つ入る仕様を変更したことによる、バグ混入の問題を修正。<span><a title="正規表現の/eスイッチ（実行構文属性）を付け忘れた（汗）" href="http://adiary.blog.abk.nu/0262#fk262n1">*1</a></span></li>
		<li>aa記法が効かないバグを修正。</li>
		<li>テーマ選択時に下フレームで表示される画面のHTML（スケルトン）が正しくなかった問題を修正。</li>
		<li>テーマによって、「日記の削除/コメント・トラックバックの編集画面」でコメント・トラックバック件数部分の表示がおかしくなる不具合を修正。</li>
	</ul>
	</li>
	<li>Ver2.06以降、アップローダーで中間拡張子チェックで"adiary-1.00.tgz"などが跳ねられてしまう問題を解決するため、数字など特定の文字を含む拡張子を許可する機能をつけました。<span><a title="詳しくは uploader.conf.cgi の &lt;$v.allow_ex_match=&quot;&quot;&gt; を参照してください。" href="http://adiary.blog.abk.nu/0262#fk262n2">*2</a></span></li>
	<li>アップローダーで0byteのファイルをアップロードできるようにしました。<span><a title="今までは明示的エラーにならずアップロードもできなかったため、何が起きてるのかよく分からないという状態。" href="http://adiary.blog.abk.nu/0262#fk262n3">*3</a></span></li>
</ul>
</div>
<div>
	<p><a href="http://adiary.blog.abk.nu/0262#k262n1">*1</a> : 正規表現の/eスイッチ（実行構文属性）を付け忘れた（汗）</p>
	<p><a href="http://adiary.blog.abk.nu/0262#k262n2">*2</a> : 詳しくは uploader.conf.cgi の &lt;$v.allow_ex_match=""&gt; を参照してください。</p>
	<p><a href="http://adiary.blog.abk.nu/0262#k262n3">*3</a> : 今までは明示的エラーにならずアップロードもできなかったため、何が起きてるのかよく分からないという状態。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0262#k262p2"><span>■</span></a>Version2.00（β含む）以降からの乗り換え</h3>
<ul>
	<li>そのまま上書きしてください。</li>
	<li>Ver2.11以前の場合、uploader.conf.cgi をサンプルから再生成してください。</li>
</ul>
<p>なおVer2.06よりアルバムシステム関連のJavaScriptの置き場が変更になっていますので、紛らわしい場合は theme/*.js を消してから上書きしてください。</p>
<p><a href="http://adiary.org/man/update">アップデート方法の参考情報。</a></p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0262#k262p3"><span>■</span></a>Version1.44以前(C73/2.00α含む）以前からの乗り換え</h3>
<p><a href="http://adiary.blog.abk.nu/0226#p2" title="記事指定 ">Version2.00への移行処理</a>を先に行ってください。</p>

</div>

<hr>
<h4><a href="/0262#c">■コメント（7件） - 古いコメントが省略されています</a></h4>
<div style="margin-left: 1em;">
ひとぅ『遅くなりました。すみません。 なぜなのでしょうかねぇ？JavaScriptsがオフと言うことは無いですw。 「メール投稿はどの方...』(2010/02/20 5:48)</span><br>
なべ『メール投稿はpopモードか、それともメール起動かという話です。popモードなのかなあ。この手の症状が出やすいのはメールによるプロ...』(2010/02/20 14:49)</span><br>
ひとぅ『メール投稿はPOPモードです。 再現したのでソースを見てみると、うまく動作してるときはカレンダーの表示部分の前に以下のようなJa...』(2010/03/08 21:29)</span><br>
なべ『popモードかあ。なんだろうなあ……。 たまに起こるというのが気になりますが^^;; あとで確認してみますねぇ。』(2010/03/10 23:41)</span><br>
ひとぅ『すみません、お手数をおかけしますがよろしくお願いしますm(_ _)m。 何か追加で情報が必要でしたら言っていただけたら準備します...』(2010/03/10 24:59)</span><br>
</div>
<h4><a href="/0262#tb">■トラックバック（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
]]></description>
	</item>
	<item>
		<title>CORESERVER、メールの凶悪仕様（Gmailとの不具合の理由）</title>
		<link>http://adiary.blog.abk.nu/0261#tm1265448790</link>
		<guid>http://adiary.blog.abk.nu/0261</guid>
		<category>ネット</category>
		<pubDate>Mon, 30 Nov 2009 14:54:46 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<p>訳あってレンタルサーバの<a href="http://www.google.co.jp/search?lr=lang_ja&amp;ie=utf-8&amp;oe=utf-8&amp;q=CORESERVER.JP" title="Google検索 ">CORESERVER.JP</a>の利用を検討していたのですが、メールがらみで<strong><del>ひどい</del>素敵仕様</strong>を発見したので記録しておきます。<a href="http://www.google.co.jp/search?lr=lang_ja&amp;ie=utf-8&amp;oe=utf-8&amp;q=Gmail%20coreserver" title="Google検索 ">GmailとCORE SERVERの相性が悪い</a>という話がネットであちこち書かれていますが、おそらくこれが原因ではないかと思います。</p>
<ul>
	<li><a href="http://adiary.blog.abk.nu/0261#k261p1">メールの仕組みについて</a>
	<li><a href="http://adiary.blog.abk.nu/0261#k261p2">CORESERVERのおさらい</a>
	<li><a href="http://adiary.blog.abk.nu/0261#k261p3">CORESERVERの<del>血迷っ…</del>素敵過ぎる仕様</a>
	<ul>
		<li><a href="http://adiary.blog.abk.nu/0261#k261p3.1">Gmailには</a>
	</ul></li>
	<li><a href="http://adiary.blog.abk.nu/0261#k261p4">総評</a>
</ul>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0261#k261p1"><span>■</span></a>メールの仕組みについて</h3>
<p>問題について述べる前にメールサーバについて簡単におさらいしておきます。そんなの分かってるという人は飛ばしてください。</p>
<p>いわゆるメールサーバというのは、SMTPというプロトコルによってメールをサーバからサーバへ転送するサービスをしています。このSMTPというのは元々<strong>サーバも受信者も送信者もなにも区別がないプロトコル</strong>で、「SMTPサーバからSMTPサーバへどんどんタライまわしをしているといずれ受信サーバにたどりつく」というSPAMなんて存在しない、インターネットが限られた利用者が使用する紳士的な世界だった頃に作られました。その名残から、今もって</p>
<ul>
	<li>メール送信時にメールクライアントソフト（メーラー）が自分のメール送信用サーバに対してメールのデータを送るSMTPと</li>
	<li>メールサーバ間でメールのデータをやりとりするときに使われるSMTP</li>
</ul>
<p>には何の差も存在しません。こんな仕様だから、メール設定のいわゆるSMTPサーバ（送信サーバ）として使用するサーバには何かしら制限を加えておかないと、世界中からそのサーバを中継（経由）してSPAMを送り放題になってしまいます。このように「本来想定している人以外からのメールを送ること」を<a href="http://www.google.co.jp/search?lr=lang_ja&amp;ie=utf-8&amp;oe=utf-8&amp;q=%e7%ac%ac%e4%b8%89%e8%80%85%e4%b8%ad%e7%b6%99" title="Google検索 ">第三者中継</a>といいます<span><a title="199x年頃はこの第三者中継が標準でonになっていたのだから恐ろしいものです。" href="http://adiary.blog.abk.nu/0261#fk261n1">*1</a></span>。第三者中継をしないために通常は次のような制限を加えておきます（いずれかもしくは複数）。</p>
<ul>
	<li>特定のIPからしか送信できないようにする。プロバイダのSMTPサーバが、そのプロバイダの利用者IPのみに中継を許可する。</li>
	<li>SMTP-AUTH等の認証をする。ID/パスワードを確認するので、正規のID/パスワードを持つ利用者のみに中継を許可できる。</li>
	<li>POP before SMTPという特殊な方法を利用する。メール送信前に１度メールを受信させることで、そのIP利用者に<strong>短時間だけ（１～５分程度）</strong>中継を許可する。</li></ul>
<p>最初の方法だけで済めばよいのですが、どうしてもホテルやモバイルパソコンからメールを送信したいとなったときに必ずしも同じプロバイダを利用できるとは限らないので他の方法が必要になります。SMTP-AUTHがまだそんなに普及していなかった頃<span><a title="いくらその仕組みを用意してもクライアントソフトが対応するまで利用できる人が限られていた" href="http://adiary.blog.abk.nu/0261#fk261n2">*2</a></span>、過渡的な措置としてPOP before SMTPというのが考えられました。</p>
<p>以上はあくまで送る側の話で、SMTPサーバは送るためのサーバであると同時に受信サーバでもあることが多くあります<span><a title="この２つは分けることもできるが、小規模なケースでは一緒にしてしまうことが多い" href="http://adiary.blog.abk.nu/0261#fk261n3">*3</a></span>。このままだと何処から送られてくるかわからない自分宛のメールを受け取れなくなってしまうので、<strong>自分宛のメールは無条件で受け取る</strong>という設定をします。例えば、xxx@foo.com ならば foo.com は自分宛ですよと登録しておきます。</p>
</div>
<div>
	<p><a href="http://adiary.blog.abk.nu/0261#k261n1">*1</a> : 199x年頃はこの第三者中継が標準でonになっていたのだから恐ろしいものです。</p>
	<p><a href="http://adiary.blog.abk.nu/0261#k261n2">*2</a> : いくらその仕組みを用意してもクライアントソフトが対応するまで利用できる人が限られていた</p>
	<p><a href="http://adiary.blog.abk.nu/0261#k261n3">*3</a> : この２つは分けることもできるが、小規模なケースでは一緒にしてしまうことが多い</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0261#k261p2"><span>■</span></a>CORESERVERのおさらい</h3>
<ul>
	<li>CORESERVERは送信メールサーバ＝受信メールサーバ </li>
	<li>CORESERVERはPOP before SMTPのみ対応（<strong>SMTP-AUTH未対応</strong>）</li></ul>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0261#k261p3"><span>■</span></a>CORESERVERの<del>血迷っ…</del>素敵過ぎる仕様</h3><p>CORESERVERで普通にメールを設定して、メールを送ろうとしたらこんなエラーメールが帰ってきました。</p>
<pre>
&lt;test@s1xx.coresv.jp&gt;: host s1xx.coresv.jp[202.172.28.1xx] said: 552 sorry, your
    domain isn't in my list of allowed senderhosts (#5.7.1) (in reply to MAIL
    FROM command)
</pre>
<p>要するに「あなたのSMTPサーバは送信元ホスト許可リストに入っていません」と言っている。にも関わらず、他のぜんぜん関係ないメールサーバ（メールアカウント）からメールを送るとちゃんと受け取る。さっぱり意味不明。<a href="http://www.google.co.jp/search?lr=lang_ja&amp;ie=utf-8&amp;oe=utf-8&amp;q=CORESERVER%20senderhosts" title="Google検索 ">検索すると同じようにハマっている人多数</a>。</p>
<p>色々調べてみたところ、原因がはっきりしました。</p>
<ul>
	<li>POP before SMTPの設定時間（タイムアウト）が<strong>３時間以上！</strong></li>	<li>POP before SMTPで<strong>senderhostsリストに登録されると、そのIPからのSMTP接続はすべて外部への中継（リレー）として受け取る</strong></li></ul>
<p>どちらの仕様も<strong><del>バカ</del>素敵すぎて言葉もない。</strong></p>
<p>つまり、</p>
<ol>
	<li>SMTPサーバでもあるIPで、CORESERVERからメールを受信する。</li>
	<li>CORESERVER側でsenderhostsに登録される。</li>
	<li>手元のSMTPサーバからCORESERVER宛にメールを送信する。</li>
	<li>CORESERVERはsenderhostsに登録さているという理由だけで、<strong>外部から自分宛のメール送信を強制的に内部(CORESERVER)から外部へのメール送信</strong>と見なす。</li>	<li>CORESERVERは外部へのメール送信のとき、予め登録された自ドメインとSMTPのFROM（SMTPにおけるFROMであるのでFROMヘッダとは異なる）が一致しないためメールを拒否する。</li>
	<li>CORESERVERは<strong>自分宛のメールを552のエラーとして受取拒否する</strong>。</li></ol>
<p>ということです。</p>
<p>そしておそらくsenderhostsのリストはサーバごとに全ユーザ共有だと思われるので（未確認）、たとえ自分でPOPしていなくても時々メールが送れないサーバが出てくる……と。</p>
<h4><a href="http://adiary.blog.abk.nu/0261#k261p3.1"><span></span>Gmailには</a></h4>
<p>Gmailには、Gmailに統合してあるアカウント名義でメールを送信するため等の目的で外部SMTPサーバを使用してメールを送信する機能がありまして、それを使うとバッチリメールが送れなくなるわけです。</p>
<p>これをしないと、Gmailでは<a href="http://www.google.co.jp/search?lr=lang_ja&amp;ie=utf-8&amp;oe=utf-8&amp;q=gmail%20%e4%bb%a3%e7%90%86%e9%80%81%e4%bf%a1" title="Google検索 ">Fromの代理送信表示</a>がされてしまいます。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0261#k261p4"><span>■</span></a>総評</h3>
<p><a href="http://www.google.co.jp/search?lr=lang_ja&amp;ie=utf-8&amp;oe=utf-8&amp;q=VALUE%20DOMAIN" title="Google検索 ">VALUE DOMAIN</a>のDNS設定も、何行か書くとすぐバグるし（行を入れ替えないとダメとか）、いまいちツメが甘い印象がぬぐえない。所詮、安かろうなんたらでしょうか。サーバスペックはいいんだけど、障害対応も遅いみたいだしねぇ。今回は安定性重視なのでCORESERVERは却下の方向。</p>
<p>どこか、もちょっとマトモなレンタルサーバ知りませんか？（苦笑）</p>

</div>

<hr>
<h4><a href="/0261#c">■コメント（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
<h4><a href="/0261#tb">■トラックバック（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
]]></description>
	</item>
	<item>
		<title>adiary Ver2.11リリース情報</title>
		<link>http://adiary.blog.abk.nu/0260#tm1260868674</link>
		<guid>http://adiary.blog.abk.nu/0260</guid>
		<category>adiary::リリース</category>
		<pubDate>Sun, 22 Nov 2009 18:17:17 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<p>Ver2.09に対し、細かな機能変更とバグ修正を行いました。</p>
<p><a href="http://adiary.org/download.html">ダウンロードはこちらから</a>。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0260#k260p1"><span>■</span></a>Ver2.09→Ver2.11の変更点</h3>
<ul>
	<li>擬似データベース（pseudo DB）使用時、wikiコンテンツを開こうとするとDB速度が著しく低下する問題を修正しました。<strong>擬似データベース使用者は「管理」→「システム管理」→「管理者メニュー」→「Version 2.09以前 → Version 2.10以降へのアップグレード」を実行してください</strong>。擬似データベース以外は実行できません。</li>	<li>アルバムにソートの機能が付きました。</li>
	<li>一部テーマファイルのCSS修正。</li>
	<li>静的出力時に埋め込みテキストを出力しないオプションを追加。</li>
	<li>MySQLにて記事テキスト本文に64KBまでしか保存できない問題を修正しました。（新規に作成した日記帳のみ有効）<span><a title="既存のテーブルに対してこの変更を行いたい場合は直接SQLを発行して修正してください。" href="http://adiary.blog.abk.nu/0260#fk260n1">*1</a></span>（<a href="http://adiary.org/adiary-users/msg00356.html" title="adiary-users ML">Thanks to ひとぅ</a>）</li>	<li>rss10.html, rss10short.html, rss20short.html でRSSが生成できないバグを修正しました。（<a href="http://adiary.org/adiary-users/msg00361.html" title="adiary-users ML">Thanks to 小沼</a>）</li>	<li>次のような記述ができないコンパイラのバグを改善しました。
<pre>
&lt;$ifexec(index(ENV.HTTP_USER_AGENT, 'iPhone')&gt;=0, begin)&gt;
</pre>
	</li>
	<li>adiaryスーパーpre記法に行頭にスペースが1つ入ることがある仕様を改善しました。（<a href="http://nblog.jp/0133">Thanks to nblog</a>）</li>	<li>theme?xxx/xxx といったページ表示時にそのページを検索対象外にするmetaタグを出力するようにしました。</li>
	<li>月別リストの古い年を折りたたむようにしました。（<a href="http://adiary.blog.abk.nu/0229#c493" title="記事指定 ">Thanks to G</a>）<span><a title="この変更を直ちに適用するには、必要な場合は日記帳の設定を保存するか適当な記事を開いて保存してください。" href="http://adiary.blog.abk.nu/0260#fk260n2">*2</a></span></li>	<li>C74で配布した<a href="http://adiary.blog.abk.nu/?theme/satsuki/bigblue" title="テーマ ">bigblue</a>を収録しました。</li>	<li>C76で配布した<a href="http://adiary.blog.abk.nu/?theme/satsuki/yuu" title="テーマ ">yuu</a>テーマを収録しました。</li>	<li>【携帯】コメントの表示件数を10件ごとにしました。</li>
</ul>
<p>なお、<a href="http://adiary.org/adiary-users/msg00369.html" title="adiary-users ML">メーリングリストにある</a>のようなiPhone専用テーマを作成したいときは次のような細工をしてください。（<a href="http://hitoxu.com/adiary/iPhoneStyle.html">関連URL</a>）<span><a title="Ver2系はこの辺を吸収するにはちょっと無理がありますね。" href="http://adiary.blog.abk.nu/0260#fk260n3">*3</a></span></p>
<pre>
&lt;$ifexec(Is_mobile, begin)&gt;
	&lt;$v.template_dir = "&lt;@theme_dir&gt;satsuki-mobile/"&gt;
	&lt;$v.theme        = 'satsuki-mobile')&gt;
&lt;$end&gt;
</pre>
<p>の後ろで</p>
<pre>
&lt;$ifexec(0 &lt;= index(ENV.HTTP_USER_AGENT, 'iPhone'), begin)&gt;
      &lt;$v.template_dir = "&lt;@theme_dir&gt;satsuki-mobile/"&gt;
      &lt;$v.theme        = 'iphone'&gt;
      &lt;$Is_mobile=1&gt;
&lt;$end&gt;
</pre>
<h4><a href="http://adiary.blog.abk.nu/0260#k260p1.1"><span></span>Ver2.11β1からの変更ファイル</a></h4>
<ul>
	<li>diary.skel/format/month_list.html</li>
	<li>lib/Satsuki/Diary.pm</li>
</ul>
</div>
<div>
	<p><a href="http://adiary.blog.abk.nu/0260#k260n1">*1</a> : 既存のテーブルに対してこの変更を行いたい場合は<a href="http://adiary.org/adiary-users/msg00357.html" title="adiary-users ML">直接SQLを発行して修正してください</a>。</p>
	<p><a href="http://adiary.blog.abk.nu/0260#k260n2">*2</a> : この変更を直ちに適用するには、必要な場合は日記帳の設定を保存するか適当な記事を開いて保存してください。</p>
	<p><a href="http://adiary.blog.abk.nu/0260#k260n3">*3</a> : Ver2系はこの辺を吸収するにはちょっと無理がありますね。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0260#k260p2"><span>■</span></a>Version2.00（β含む）以降からの乗り換え</h3>
<ul>
	<li>そのまま上書きしてください。</li>
	<li>Ver2.05以前の場合、uploader.conf.cgi をサンプルから再生成してください。</li>
</ul>
<p>なおVer2.06よりアルバムシステム関連のJavaScriptの置き場が変更になっていますので、紛らわしい場合は theme/*.js を消してから上書きしてください。</p>
<p><a href="http://adiary.org/man/update">アップデート方法の参考情報。</a></p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0260#k260p3"><span>■</span></a>Version1.44以前(C73/2.00α含む）以前からの乗り換え</h3>
<p><a href="http://adiary.blog.abk.nu/0226#p2" title="記事指定 ">Version2.00への移行処理</a>を先に行ってください。</p>

</div>

<hr>
<h4><a href="/0260#c">■コメント（2件）</a></h4>
<div style="margin-left: 1em;">
ひとぅ『2.11β版のリリース、ありがとうございます。 遅くなりましたがようやく導入してみました。 特に「月別リストの古い年を折りたたむ...』(2009/11/27 24:55)</span><br>
なべ『ご要望感謝します。対応しました。 β2としてだそうかと思いましたが、このままリリースにもなりそうなのでちょい見送ります。』(2009/11/27 26:10)</span><br>
</div>
<h4><a href="/0260#tb">■トラックバック（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
]]></description>
	</item>
	<item>
		<title>MySQL/PostgreSQLでのシリアル値まとめ</title>
		<link>http://adiary.blog.abk.nu/0259#tm1258910411</link>
		<guid>http://adiary.blog.abk.nu/0259</guid>
		<category>プログラム::DB</category>
		<pubDate>Fri, 04 Sep 2009 18:02:30 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<p>adiaryではすべてのテーブルに pkey というシリアル値（PRIMARY KEY）を設定しています。その扱いについて。</p>
<p>特にMySQLで特別な加工せずに安全なシリアル値を取得する方法。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0259#k259p1"><span>■</span></a>PostgreSQLの場合</h3>
<p>PostgreSQLではそのままserial型というものがあり、</p>
<pre>
CREATE TABLE test(pkey SERIAL, x INT);
INSERT INTO test(x) VALUES(10);
</pre>
<p>とすることで、pkeyをプライマリキーとして自動的に生成することができます。</p>
<p>PostgreSQLでは<a href="http://www.postgresql.jp/document/pg840doc/html/functions-sequence.html">シーケンス操作関数</a>というものがあり、SERIAL型を定義すると自動的に作成されます。</p>
<p>例えば、現在の値を取得したければ</p>
<pre>
SELECT currval(pg_catalog.pg_get_serial_sequence('test', 'pkey'))
</pre>
<p>とします。pkeyに値を設定して INSERT したとき、シーケンス関数は自動的に再定義されないため次の関数で再設定する必要があります。</p>
<pre>
SELECT setval(pg_catalog.pg_get_serial_sequence('test', 'pkey'), (SELECT max(pkey) FROM test))
</pre>
<p>現在の値（最後に生成された値）を取得するには次のようにします。</p>
<pre>
SELECT currval(pg_catalog.pg_get_serial_sequence('test', 'pkey'), (SELECT max(pkey) FROM test))
</pre>
<p>同じセッション内でテーブル問わず最後に生成された値を取得する場合は次で済みます。</p>
<pre>
SELECT lastval()
</pre>
<p><strong>安全に</strong>（他のセッションともかぶらない唯一無二な）次のシリアル値を取得するには、次のようにします。</p>
<pre>
SELECT nextval(pg_catalog.pg_get_serial_sequence('test', 'pkey'))
</pre>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0259#k259p2"><span>■</span></a>MySQLの場合</h3>
<p>MySQLの場合auto_increment属性を使用します。</p>
<pre>
CREATE TABLE test(pkey INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, x INT);
INSERT INTO test(x) VALUES(10);
</pre>
<p>で、pkeyに自動的にシリアル値を設定することができます。</p>
<ul>
	<li>AUTO_INCREMENTは１つのテーブルに１カラムしか指定できない。</li>
	<li>AUTO_INCREMENTを指定したカラムに、例えばpkeyを指定してINSERTしても、AUTO_INCREMENTがよきにはからってくれる（PostgreSQLのように値を再設定する必要なし）。</li>
</ul>
<p>現在の値（最後に生成された値）を取得するには次のようにします。</p>
<pre>
SELECT * FROM test WHERE pkey IS NULL;
SELECT LAST_INSERT_ID();
</pre>
<p>ただしC API等では <a href="http://www.google.co.jp/search?lr=lang_ja&amp;ie=utf-8&amp;oe=utf-8&amp;q=mysql_insert_id%28%29" title="Google検索 ">mysql_insert_id()</a>というものがあるため、こちらを使用するほうが効率が良いようです。例えばPerl DBIならば $sth-&gt;mysql&#95;insertid。</p>
<h4><a href="http://adiary.blog.abk.nu/0259#k259p2.1"><span></span>値を取得、値の変更</a></h4>
<pre>
SHOW TABLE STATUS WHERE NAME = 'test';
</pre>
<p>で得られたテーブル情報の中からAuto_incrementカラムの値を参照します。得られるのは<strong>次に挿入される値です</strong>。</p>
<p>何かの都合で値を設定するときは次のようにします。</p>
<pre>
ALTER TABLE test AUTO_INCREMENT=1;
</pre>
<h4><a href="http://adiary.blog.abk.nu/0259#k259p2.2"><span></span>安全に次の値を取得</a></h4>
<p>MySQLでもっとも厄介なのはこれです。auto_incrementには安全に次の値を得る方法が提供されていません。別にシーケンステーブルを作る方法などがありますが、面倒です。</p>
<p>INSERTでしか得られないならINSERTしてしまえばいいやという単純な方法です。</p>
<pre>
INSERT INTO test() VALUES();
DELETE FROM test WHERE pkey=LAST_INSERT_ID();
SELECT LAST_INSERT_ID();
</pre>
<p>NOT NULL制約等が付いているとINSERTが失敗するので、CREATE TABLE等であらかじめ制約を満たすDEFAULT値を設定しておく必要があります。MyISAMではトランザクションが使えないため、NOT NULLかつUNIQUE制約が付いていると、複数のプロセスが同時に"INSERT INTO test() VALUES();"を実行したとき一方が失敗します。</p>
<p>MySQLの場合はINSERTしてUPDATEした方がスマートなのはたしかなのですが、PostgreSQLではシーケンス型の次の値を安全に取得できるし、INSERTに成功してUPDATEに失敗した場合を考えるとややこしいので。</p>

</div>

<hr>
<h4><a href="/0259#c">■コメント（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
<h4><a href="/0259#tb">■トラックバック（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
]]></description>
	</item>
	<item>
		<title>adiary C76 Special Edition</title>
		<link>http://adiary.blog.abk.nu/0258#tm1250452519</link>
		<guid>http://adiary.blog.abk.nu/0258</guid>
		<category>adiary::comiket</category>
		<pubDate>Mon, 10 Aug 2009 11:14:23 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<p>adiary C76 Special Editionがコミックマーケット76にて配布されます。</p>
<p>8/15(土) 「東2ホール Q-02b」</p>
<p>詳細は<a href="http://adiary.jp/C76">adiaryユーザ会のC76ページ</a>をご覧下さい。</p>
<ul>
	<li><a href="http://kaede.blog.abk.nu/01106" title="ID指定 ">C76限定テーマはこちらを見てね。</a></li>	<li>絵師さま多忙につき、レーベルをでっちあげるので（レーベルは）期待しないでください。同じ理由によりポストカードも用意できるか微妙。</li>
	<li>万が一、委託物で混雑していても<strong>adiary C76 Special Editionの配布を優先するので</strong>気軽に声をおかけください。</li></ul>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0258#k258p1"><span>■</span></a>頒布物の修正情報</h3>
<p><a href="http://adiary.jp/C76">http://adiary.jp/C76</a> を参照ください。</p>

</div>

<hr>
<h4><a href="/0258#c">■コメント（2件）</a></h4>
<div style="margin-left: 1em;">
nasano『本日はお疲れ様でした。 しかし東方の人気は凄いですね…。 スペースに辿りつくまで何度も心が折れそうになりました（笑）。』(2009/08/15 22:20)</span><br>
なべ『自分は経験したことのない混雑で、前に見える島には「正直、近寄りたくない」という感じでした（笑） あのひどい中、ご足労頂きありがと...』(2009/08/15 24:21)</span><br>
</div>
<h4><a href="/0258#tb">■トラックバック（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
]]></description>
	</item>
	<item>
		<title>PostgreSQLトランザクションとDBD::Pgの謎の挙動</title>
		<link>http://adiary.blog.abk.nu/0257#tm1250963072</link>
		<guid>http://adiary.blog.abk.nu/0257</guid>
		<category>プログラム::perl</category>
		<pubDate>Sun, 09 Aug 2009 13:51:42 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<ul>
	<li><a href="http://adiary.blog.abk.nu/0257#k257p1">PostgreSQLのトランザクションの仕様</a>
	<li><a href="http://adiary.blog.abk.nu/0257#k257p2">DBD::Pgの謎</a>
	<li><a href="http://adiary.blog.abk.nu/0257#k257p3">謎の解析</a>
	<ul>
		<li><a href="http://adiary.blog.abk.nu/0257#k257p3.1">追記</a>
	</ul></li>
	<li><a href="http://adiary.blog.abk.nu/0257#k257p4">メモ</a>
</ul>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0257#k257p1"><span>■</span></a>PostgreSQLのトランザクションの仕様</h3>
<pre>
CREATE TABLE test(x INT UNIQUE);
INSERT INTO test (x) VALUES (1);
INSERT INTO test (x) VALUES (2);
</pre>
<p>としておきます。</p>
<p>ここで、</p>
<pre>
 =&gt; BEGIN;
 =&gt; INSERT INTO test (x) VALUES (3);
INSERT 0 1
 =&gt; INSERT INTO test (x) VALUES (1);
ERROR:  duplicate key value violates unique constraint "test_x_key"
</pre>
<p>とするとエラーになります。<strong>PostgreSQLはトランザクション中にエラーが起こると、以後何をしてもエラーになり受け付けなくなります。</strong>ためしに続けて色々発行してみても、</p>
<pre>
 =&gt; INSERT INTO test (x) VALUES (10);
ERROR:  current transaction is aborted, commands ignored until end of transaction block
 =&gt; INSERT INTO test (x) VALUES (20);
ERROR:  current transaction is aborted, commands ignored until end of transaction block
</pre>
<p>こんな感じです。COMMITすると</p>
<pre>
 =&gt; COMMIT;
ROLLBACK
</pre>
<p>このようにROLLBACKされます。これがPostgreSQLの仕様です。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0257#k257p2"><span>■</span></a>DBD::Pgの謎</h3>
<ul>
	<li>確認環境
	<ul>
		<li>PostgreSQL 8.3.7</li>
		<li>DBD::Pg　Ver1.49</li>
	</ul>
	</li>
</ul>
<p>DBD::Pgの場合</p>
<pre>
01: $dbh-&gt;begin_work;
02: $dbh-&gt;do('INSERT INTO test (x) VALUES (10)');
03: $dbh-&gt;do('INSERT INTO test (x) VALUES (1);');
04: $dbh-&gt;do('INSERT INTO test (x) VALUES (20);');
05: $dbh-&gt;commit;
</pre>
<p>とすると、3行目でエラーが起こり、4行目の実行でも"ERROR:  current transaction is aborted, commands ignored until end of transaction block"といわれます。</p>
<p>これを、DBIのprepareを使用して</p>
<pre>
01: $dbh-&gt;begin_work;
02: $dbh-&gt;prepare('INSERT INTO test (x) VALUES (?)')-&gt;execute(10);
03: $dbh-&gt;prepare('INSERT INTO test (x) VALUES (?)')-&gt;execute(1);
04: $dbh-&gt;prepare('INSERT INTO test (x) VALUES (?)')-&gt;execute(20);
05: $dbh-&gt;commit;
</pre>
<p>とすると、3行目でエラーが起っても、<strong>4行目の実行が反映されてしまいます</strong>。謎の挙動です。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0257#k257p3"><span>■</span></a>謎の解析</h3>
<p>このようにソースを改変してログを取ってみました。</p>
<pre>
open(my $fh, "&gt;pg_log.txt");
$dbh-&gt;pg_server_trace($fh);
$dbh-&gt;begin_work;
$dbh-&gt;prepare('INSERT INTO test (x) VALUES (?)')-&gt;execute(10);
$dbh-&gt;prepare('INSERT INTO test (x) VALUES (?)')-&gt;execute(1);
$dbh-&gt;prepare('INSERT INTO test (x) VALUES (?)')-&gt;execute(20);
$dbh-&gt;pg_server_untrace();
close($fh);
</pre>
<p>このときサーバに対して次のようなコマンドが発行されていました。</p>
<pre>
 =&gt; BEGIN;
 =&gt; INSERT INTO test (x) VALUES (10);
 =&gt; INSERT INTO test (x) VALUES (1);
エラー : duplicate key value violates unique constraint "test_x_key"
 =&gt; ROLLBACK;
 =&gt; BEGIN;
 =&gt; INSERT INTO test (x) VALUES (20);
 =&gt; COMMIT;
</pre>
<p>どうりで最後のCOMMITが成功するはずです。<a href="http://adiary.blog.abk.nu/public/image/adiary/pg_log.txt" title="ファイル ">取得した生ログも置いておきます</a>。</p>
<p>これを、</p>
<pre>
01: $dbh-&gt;begin_work;
02: $dbh-&gt;prepare('INSERT INTO test (x) VALUES (10)')-&gt;execute();
03: $dbh-&gt;prepare('INSERT INTO test (x) VALUES ( 1)')-&gt;execute();
04: $dbh-&gt;prepare('INSERT INTO test (x) VALUES (20)')-&gt;execute();
05: $dbh-&gt;commit;
</pre>
<p>とすると再現しません。<del>prepare中にUNIQUE制約をチェックして、勝手にrollbackしているようですが、原因がPostgreSQL側なのかDBD::Pg側なのかは絞り込めませんでした。</del></p>
<h4><a href="http://adiary.blog.abk.nu/0257#k257p3.1"><span></span>追記</a></h4>
<p>DBD::Pgの実装仕様みたいです。トラックバックを参考にしてください（iakioさんに感謝）。</p>
<blockquote cite="http://postgresql.g.hatena.ne.jp/iakio/20090821/1250860855">
<p>DBD::Pgを直すとすれば、プレースホルダが破棄されてもトランザクションが終了するまでDEALLOCATEするのを待つ、くらいでしょうが。</p>
<cite><a href="http://postgresql.g.hatena.ne.jp/iakio/20090821/1250860855">明示的なトランザクション内でのエラーとDEALLOCATE</a></cite></blockquote><p>ROLLBACKしていいから、DEALLOCATE後に空のトランザクションを begin して、失敗させてくれればそれで十分な予感。</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0257#k257p4"><span>■</span></a>メモ</h3>
<ul>
	<li>どちらの場合も $dbh-&gt;commit(); の戻り値は "1" で成功している。</li>
</ul>

</div>

<hr>
<h4><a href="/0257#c">■コメント（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
<h4><a href="/0257#tb">■トラックバック（1件）</a></h4>
<div style="margin-left: 1em;">
<a href="http://postgresql.g.hatena.ne.jp/iakio/20090821/1250860855" rel="nofollow">[Perl][PHP]明示的なトランザクション内でのエラーとDEALLOCATE</a> （iakioの日記）<br>
</div>
]]></description>
	</item>
	<item>
		<title>動的ページと Last-Modified の検討</title>
		<link>http://adiary.blog.abk.nu/0256#tm1251126233</link>
		<guid>http://adiary.blog.abk.nu/0256</guid>
		<category>Satsuki-system</category>
		<pubDate>Thu, 09 Jul 2009 14:35:36 GMT</pubDate>
		<author>なべ</author>
		<description><![CDATA[<div>
<p>adairyの基盤システムであるフレームワーク（Satsuki-system）にあちこち手を入れてるのですが<span><a title="仕様の汚い場所を思想を持って直してる。" href="http://adiary.blog.abk.nu/0256#fk256n1">*1</a></span>、Last-modifiedをどう扱うかで悩んでしまいまいした。</p>
<p>あまり知られていないことですが、adiaryは<strong>正しいLast-modifiedヘッダを返します</strong>。ネットワーク負荷削減のためには大切なことなのですが、これを正しく返すため関連するすべてのファイルの更新日時を取得し、データベース情報にもテーブル単位で同じものを入れ管理しているためプログラム負荷（実行時間）が増えているという現実があります。</p>
<p>大手サイトはどうしてるのかなと思いまして少し調べてみました。</p>
<ul>
	<li>Last-modified を返さない
	<ul>
		<li>Yahoo、Yahooブログ</li>
		<li>mixi</li>
		<li>livedoorブログ</li>
	</ul>
	</li>
	<li>Last-modified を返す
	<ul>
		<li>はてなダイアリー</li>
		<li>アメーバブログ（トップページのみ）</li>
	</ul>
	</li>
</ul>
<p>あまり返さないところが多いようです。画像ファイルとかならともかく、今時テキストファイルコンテンツはあまり気にしなくて良いみたいですね。</p>
<ul>
	<li>Last-modified を返すメリット
	<ul>
		<li>ネットワーク負荷が減る</li>
		<li>うまくするとリクエストを受けた時点で、処理せずに出力内容を決定できる。トップページにおいて特に大きな効力がある。</li>
	</ul>
	</li>
	<li>Last-modified を返さないメリット
	<ul>
		<li>動的ページを同一出力する条件をいちいち探索しないため、構造が単純になる。</li>
		<li>動的ページ内で柔軟な処理が可能になる。例えばカウンタ機能を実装する等。</li>
	</ul>
	</li>
</ul>
<p>ちなみにRFC的には</p>
<blockquote cite="http://www.studyinghttp.net/cgi-bin/rfc.cgi?2616">
<p>HTTP/1.1 サーバは、可能であればいつでも Last-Modified を送るべきである。 </p>
<cite><a href="http://www.studyinghttp.net/cgi-bin/rfc.cgi?2616">RFC2616</a></cite></blockquote><p>です。それで結構苦労して後から<span><a title="と言ってもVer1.00よりずっと昔のβ時代" href="http://adiary.blog.abk.nu/0256#fk256n2">*2</a></span>実装したのですが、Satsuki-systemを扱う上で難しくしている要因でもあるので消そうかなあ。</p>
</div>
<div>
	<p><a href="http://adiary.blog.abk.nu/0256#k256n1">*1</a> : 仕様の汚い場所を思想を持って直してる。</p>
	<p><a href="http://adiary.blog.abk.nu/0256#k256n2">*2</a> : と言ってもVer1.00よりずっと昔のβ時代</p>
</div>

<div>
<h3><a href="http://adiary.blog.abk.nu/0256#k256p1"><span>■</span></a>結局</h3>
<p>消しました。実装がとてもすっきりしました。</p>

</div>

<hr>
<h4><a href="/0256#c">■コメント（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
<h4><a href="/0256#tb">■トラックバック（0件）</a></h4>
<div style="margin-left: 1em;">
</div>
]]></description>
	</item>
</channel>
</rss>
