カテゴリー別アーカイブ: データベース

Tcl SQLite build configuration

Prerequisites

Build tool = MinGW GCC v4.9.3
Tcl build path = /c/src/tcl8.6.6/win
Tcl install path = /c/bin/tcl8.6.6
SQLite3 build path = /c/src/sqlite-autoconf-3160200/tea
wxSQLite3 secure source path = /c/src/wxsqlite3-trunk/sqlite3/secure/src

Tcl

./configure --prefix=(Tcl install path)
make
make install

Tk

./configure --prefix=(Tcl install path) --with-tcl=(Tcl build path)
make
make install

TclSQLite

Copy the files in (wxSQLite3 secure source path) to (SQLite3 build path)/generic.
Open tclsqlite3.c and replace "sqlite3.c" by "sqlite3secure.c" in the line #4.
cd (SQLite3 build path)
./configure --enable-threads --prefix=(Tcl install path) --with-tcl=(Tcl build path) CFLAGS="-DSQLITE_HAS_CODEC -DSQLITE_ENABLE_FTS4_UNICODE61"
make
make install

This also works with ActiveTcl.

I could not make sqlite3 v3.8.2 independent from libgcc_s_dw2-1.dll with MinGW gcc v4.8.1.
I don't know the reason. But I could build it with nmake.
For example:
nmake -f makefile.vc TCLDIR=(Tcl install path) INSTALLDIR=(Tcl install path) OPTDEFINES="-DSQLITE_HAS_CODEC"

Ref. 暗号化APIを有効にしたSQLite3のTclバインディングをコンパイルする

TkSQLite Tcl script function

こんなに便利な機能があったのに使ってなかったなんて。

TkSQLite Tcl script function

こういうスクリプトを書いておいて、TkSQLiteの初期設定->SQLiteのタブに登録しておくと、

# unixepoch.tcl
proc UnixEpoch {t} {
	clock format $t -format "%Y-%m-%d %H:%M:%S"
}
db function unixepoch UnixEpoch
SELECT datetime(executed_at, 'unixepoch', 'localtime'), * FROM history; -- これが
SELECT unixepoch(executed_at),* FROM history; -- こんな風にかけるよ。

IsolationLevel.ReadCommittedが安全なケース

データベースにはロックのポリシーとして、分離レベルというのがある。
このレベルを高めれば、データの一貫性を維持できるが、その分ロックされる時間が増え、結果としてパフォーマンスに影響したり、一貫性を損なう処理をした場合の対応について考慮しなくてはいけなくなる。
 
最も分離レベルが高いのをSerializableという。これを設定すると、読み取り中にデータの変更ができない。書き込み中は読み取れないという、あらゆる矛盾を排除するようなロックがかけられる。そのかわりロックがかかっている間、処理がブロックされるのでパフォーマンスが落ちる。
 
ほとんどのデータベースはデフォルトでReadCommittedという分離レベルを使う。これはSerializableよりもロックが甘く、トランザクション中でもコミット済みデータの読み取りを許可する。ただし、途中で削除処理のトランザクションが完了すると、読み取り中のデータと矛盾してしまう。だから反復読み取りには矛盾が発生する可能性がある。
 
 
でも、アプリケーションの用途によっては、というかたいていの場合、ReadCommittedは安全なのだ。
 
例えば、月末で確定したデータを月初に帳票処理する業務アプリの場合、読み取るデータは全て確定済みなのだからそのデータに関しては変更されることがない。だから現実的には矛盾は発生しないし、そういう処理はアプリケーションで禁止してしまうことができる。
 
とはいえ、そう簡単に割り切れないケースもあるだろう。アプリケーション側でロックを実装する必要があるかもしれない。
 
 
並行処理が必要ないなら何にしたってかまわない。
 
自動的にデータを収集するシステムなどで、いつデータが入ってくるのか分からない場合はロックの少ないReadComittedを使うことでブロックしないアプリケーションが作れる。
 
OracleやSQLServerのような高度なデータベースはReadCommitted Snapshotなどというようなものを使えるらしい。