TIM Labs

2011年7月アーカイブ

Mercurialリポジトリのバックアップだって?

分散型なんでしょ。要らないじゃん。

OK、もちろんそういう観点はある。Mercurialは分散型なので、該当プロジェクトが熱いうちは、かなり障害に強い。中央リポジトリと言ったところで、それは単にプロジェクト内でそのリポジトリを中央と「見做して」いるだけで、基本的には他のリポジトリと変わらないからだ。せいぜい、コミットメールの設定等が行われているくらいだろう。だから、中央リポジトリサーバーがダウンしても気にせず作業を続けられるし、プロジェクトの誰かのリポジトリを改めて「中央と見做せ」ば良い。復旧も簡単だ。

だから、Subversionほどにはバックアップを気にする必要はない。

それでも、Mercurialで管理している情報の重要さを鑑みれば、バックアップはあるに越したことはない。ことバックアップが重要になってくるのは、前述「該当プロジェクトが熱いうちは」という前提が崩れたときにある。開発を終え、少人数の保守要員が残り、保守案件も下火になり、メンバーもローカルPCを更新したりして、「まあサーバーにあるからいいでしょ。しばらく使わないし、必要になったらcloneしよ」といって皆のローカルディスクからはcloneされたリポジトリが消えていく。唯一残るリポジトリはサーバーのものだけ...。そういうときに限って、サーバーとは壊れるものなのだ。

だから、Mercurialのリポジトリを預かるサーバーは、やはりバックアップについて少なからず気にする必要がある。

問題

ソフトウェア開発はクリエイティブでエキサイティングなものではありますが、いつもそうだとは限りません。 時には泥臭い作業が必要になることもあります。

例えばとある企業で運用されている業務用アプリケーションのメンテナンスを任されていたとしましょう。 時折 「△△部署が○○部署と☆☆部署に分割されたので関連データを移行してください。 対応関係は添付のExcelファイルを参照してください」 のような依頼が舞い込んできます。 これが5個程度なら手作業でSQLクエリーを書いても構わないのですが、 さすがに1万と2千個くらいになると手作業ではやっていられません。 となると何らかの方法で貰ったデータからSQLクエリーを生成することになります。

しかしこのSQLクエリーの生成が案外面倒だったりします。 貰ったデータがCSVの場合、これが素朴なデータならエディターにコピーして適当に置換すればいいのですが、 クォートが含まれていたりすると置換する気力が失せます。 さらに大抵の場合、*.csvではなく*.xlsでデータを貰うことになります。 *.xlsの場合、セルの内容に改行文字が含まれていることがあるため、 これもCSVと同様に「エディターにコピーして云々」ということは簡単にはできません。

そうなるとExcel上でSQLクエリーを生成する方が簡単です。 例えば以下のようなデータが記載された*.xlsがあるとしましょう:

  • A列に関連データのID
  • B列に移行前の部署のID
  • C列に移行後の部署のID

この場合、D列に以下のような数式を入力すればSQLクエリーを生成できます:

="UPDATE Foo SET section_id = '" & C1 & "' WHERE id = " & A1 & " AND section_id = '" & B1 & "'"

しかし、このような数式を入力するのは結構面倒です。 本来実行したいクエリーは以下のようなものなのですが:

UPDATE Foo SET section_id = 'C1' WHERE id = A1 AND section_id = 'B1'

文字列連結が入り乱れて読み難くなっていますし、 生成したクエリーにミスがあった場合、 それを修正するのも一苦労です。 上記の例の場合はまだパラメーターが3つだけですが、 実際には10個や20個は普通に使うことになるため、 書き難さや読み難さはさらに大変なことになります。

どうにかしてこのようなSQLクエリーの生成を簡単に済ませられないものでしょうか。

問題

LINQ はとても便利です。あまりにも便利すぎて、.NET Frameworkの外でも 「ここでLINQが使えたらな......」とついつい考えてしまいます。

しかし、LINQそのものの他言語への移植は、 本気で実装しようとするとLispのようなマクロが言語でサポートされていないと かなり厳しいです。 とはいえ、LINQ to SQLやLINQ to XMLなどと違い、 LINQ to Objectsならばただのリスト処理ライブラリに過ぎませんから、 やろうと思えば実装は簡単にできるはずです。

今時の言語なら標準でリスト処理ライブラリのひとつやふたつは付いていますが、 大抵の場合、個々の機能に対する名前はライブラリ毎に異なっているため、 「LINQで言うところの Where はRubyだと何て名前だったっけ......」 と悩んだり混乱したりしがちです。 LINQライクなリスト処理ライブラリが使えるならばそれに越したことはありません。

という訳で、LINQライクなリスト処理ライブラリを実装してみましょう。 言語は何でも良いのですが、ここではPythonを使うことにします (バージョンは2.5以降3.0未満です)。

なお、今回作成した PythonによるLINQライクなリスト処理ライブラリの実装はGitHubで公開中 です。

問題

Vim で多数のファイルを編集することはよくあります。 例えば「foo」という名前の Vim プラグインを開発しているとしましょう。 すると autoload.foo.vim、doc/foo.txt、plugin/foo.vim などの特定のファイルを頻繁に編集することになります。 このような状況では 「doc/foo.txt を編集しようと思ったけれどどのウィンドウにも doc/foo.txt は表示されていない」 ということは起こりがちです。 そこで問題のファイルを明示的に開く必要がでてきます。 しかしファイルを開く方法は沢山あります。 あなたならどうやって問題のファイルを開きますか? :edit? :buffer? それともお気に入りのバッファ管理プラグイン?

どれを選ぶにせよ、問題のファイルを開くためには何がしか追加情報を指定する必要があります。 例えば :edit を使うならファイルへのパスを指定しなければなりませんし、 :buffer を使うならバッファ番号を指定しなければなりませんし、 他の方法でも同様に何かヒントを指定する必要があります。 つまり、 何も指定せずに 問題のファイルを開く方法はありません。

先程例示した状況ではユーザーが「doc/foo.txt を編集したい」と思っている以上、 その 気持ちを汲み取って問題のファイルを自動的に判断して開いてほしい ものです。 どうすればよいでしょうか。

このアーカイブについて

このページには、2011年7月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2011年6月です。

次のアーカイブは2011年8月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。