カテゴリー別アーカイブ: Programming

プログラミングの話題

SQLite3にformatみたいな関数がないのでTclでやる

1-12みたいな連番文字列を01012に一括変換したかった。別のカラムに分けるのが普通でしょうが、諸事情により。
SQLiteの組み込み関数には日付の操作関数は充実してるけど、文字列操作関数は大したものがない。
それで、Tclでやることにした。

package require sqlite3
sqlite3 db ./app.db; # handle and database file

db eval {SELECT * FROM squence WHERE field LIKE "%-%"} values {
	set R-V $values(field)
	if {[scan ${R-V} %d-%d R V] == 2} {
		set RRVVV [format %02d%03d $R $V]
		db eval [format {UPDATE squence SET field="%s" WHERE id=%d} $RRVVV $values(id)]
	}
}

02012みたいなのは、クォートしないと数値とみなされて2012みたいになってしまうので注意が必要です。
LIKE以外にもGLOBやREGEXPも使えるらしい。

050-で始まる電話番号を持つ人のリストを取得するなど。
select * from users where phone_number REGEXP “^050-.+$”

Tcl/TkでMutexを使った多重起動防止

Tcl単体でやろうとすると、ロックファイルでやりなさいということになるんですけど、その場合Tclの処理系が起動するまでに、別のインスタンスが起動できてしまう可能性があるので、厳密ではないです。たとえば、

run_twice.bat
start wish app.tcl
start wish app.tcl

とかやると、2重起動してしまいます。

プロセスリストを取得して処理する方法もあります http://goo.gl/K38a 。今まではこれを使っていました。ただ、プロセスリストの取得自体が結構時間かかるので、上記よりましですが確実ではないです。

別の方法として、socketで特定ポートをバインドして、多重起動時にエラーにするという方法があります。singleton application – Tcler’s Wiki
ネットワークを使わないのにファイアウォールの例外にするか聞かれたりするのが嫌です。

Mutexを使うと、VBやC#とかでやってるみたいな厳密な多重起動防止対策ができます(Windows限定)。

twapi 2.2.3での実装

package require twapi 2.2.3
twapi::import_commands

set appname "My Application"

set handle [create_mutex -name $appname]
if {[lock_mutex $handle -wait 1] > 0} {
	tk_messageBox -icon error \
		-title "Startup error" \
		-message "Another instance is running." \
		-type ok
	exit
}
console show

twapi 3.0 正式版での実装

先日twapi3.0の正式版がリリースされました。
3.0では従来通りpackage require するか、dllを1個loadするかが選べるようになりました。
x86版はTcl8.4をサポートしています。
3.0ではAPIの仕様がいろいろ変わって、lock_mutexの返り値がsignalled, timeout, abandonedのいずれかとなっています。

load twapi-x86-3.0.29.dll
twapi::import_commands

set appname "My Application"

set handle [create_mutex -name $appname]
if {[lock_mutex $handle -wait 1] ne "signalled"} {
	tk_messageBox -icon error \
		-title "Startup error" \
		-message "Another instance is running." \
		-type ok
	exit
}
console show

先に起動してたウインドウを閉じるかユーザに聞く

そういうことをする実験です。実際にはプロセスをkillするとか、ウィンドウの存在を監視して、完全に終了するのを待つとかが必要になると思います。

package require Tk
load twapi-x86-3.0.29.dll
twapi::import_commands

set appname "My Application"

set handle [create_mutex -name $appname]
if {[lock_mutex $handle -wait 1] ne "signalled"} {
	set ans [tk_messageBox -icon error \
		-title "Startup error" \
		-message "Another instance is running. Kill it?" \
		-type yesno]
	switch $ans {
	yes {
		set hWnds [find_windows -text $appname]
		foreach hWnd $hWnds {
			close_window $hWnd
		}
	}
	no {
		exit
	}
	}
}

wm title . $appname
wm protocol . DELETE_WINDOW EXIT
proc EXIT {} {
	after 3000 exit
}

DataGridViewをActiveXコントロールにラップしてTcl/Tkのウィンドウに埋め込む(3)

これまでの経緯
DataGridViewをActiveXコントロールにラップしてTcl/Tkのウィンドウに埋め込む(1)
DataGridViewをActiveXコントロールにラップしてTcl/Tkのウィンドウに埋め込む(2)

去年やってたoptclによるDataGridView埋め込みが、ようやく役に立つときが来た。
しかし、イベントを追加しようとしたところ、いきなり壁にぶち当たってしまった。

新たに定義したイベントにコールバックを登録できない。

続きを読む

C#とSQLiteの日時データ型とパフォーマンス

1年ほど前に手がけた仕事では、C#+Windows.Forms+Entity Framework+System.Data.SQLite という組み合わせでアプリケーションを作成しました。

次に始まる開発でもこの組み合わせにするつもりですが、いろいろとやりにくかった点をまとめておきたいと思います。まずは、SQLiteの日時カラムについて。

続きを読む

Atermのログを解析する

昨日あたりからしょっちゅうネットが見れなくなって、NECのルータのPPPoE接続をOFF/ONすることで一時的に回復させていた。最初はルータが寿命か?と思ったけど、どうやらそうでもなさそう。

外部からのハッキングについては今まであまり調べたことがなかったんだけど、この機会に調べてみようと思い、TclでAtermのログを解析するスクリプトを書いてみた。

書いた後で気づくのもなんだけど、誰がアクセスしてきてるのか分かったところで、こっちから逆に攻撃するわけにもいかず、大して役に立たない。

強力なルータに変えたら攻撃に耐えられるようになるのだろうか?その辺よく分からない。とりあえず早まってLa Fonera 2.0nを注文してしまった。前から買うつもりだったので、「しまった」というのはわざとらしいですが。

内容的には以下のようなもの。

  1. ログを読み込んで”NAT RX Not Found : TCP”という怪しいログを探す。
  2. その行から送り元のIPアドレスを抽出する。IPアドレスのヒストグラムを作成する。
  3. IPアドレスをwhoisに投げて、ドメインの情報を取得する。
  4. IPアドレスごとに、アクセスランキング、whoisの情報を列挙する。

続きを読む

Android開発環境インストールした

はじめてのAndroidを買ったので、開発環境のインストールのところだけやった。

関係ないけど、せっかくSDKをインストールしたので、前からやりたかったスクリーンショットを撮ってみる。

初めてのAndroid