write ahead log

ロールフォワード用

golangでWindows10上でSQLite3を使う

golangでSQLite3を使う情報は多いのだけれど,
Windowsで使うとなると一気に情報が減ってしまう.

事前準備

ちょっと面倒ですが,まずはgccが必要です.
以下からダウンロードします.

tdm-gcc

msys2なんかでよく使うMinGWではダメっぽいです.
(msys2使ってるので良い方法があるなら知りたいです)

ライブラリ作者のmattnさんもgolangのビルドにはmsys2使ってないっぽいですね.
github - issues -

そういうわけでcmd.exeでgo getします.

C:\Users\Twinbird>go get github.com/mattn/go-sqlite3

これで準備はOKです.

サンプルコード

見た方が早いですね.

package main

import (
    "os"
    "database/sql"
    _ "github.com/mattn/go-sqlite3"
)

func main() {
    dbfile := "./test.db"

    os.Remove(dbfile)

    db, err := sql.Open("sqlite3", dbfile)
    if err != nil { panic(err) }

    // 単発で実行
    _, err = db.Exec(`CREATE TABLE "messages" ("id" INTEGER PRIMARY KEY AUTOINCREMENT, "msg" VARCHAR(255))`)
    if err != nil { panic(err) }

    // 単発で実行
    _, err = db.Exec(`
      INSERT INTO "messages" ("msg") VALUES(?)`,
        "こんにちは",
    )
    if err != nil { panic(err) }

    // プリペアステートメント
    stmt, err := db.Prepare(`INSERT INTO "messages" ("msg") VALUES(?)`)
    if err != nil { panic(err) }

    if _, err = stmt.Exec("世界"); err != nil { panic(err) }
    if _, err = stmt.Exec("Hello"); err != nil { panic(err) }
    if _, err = stmt.Exec("World"); err != nil { panic(err) }

    stmt.Close()

    db.Close()
}

ビルド

これもcmd.exeでやりましょう.

C:\Users\Twinbird\samples>go build

実行と確認

実行はmsys2環境でもできます.

SQLiteで確認してみましょう.

SQLite version 3.10.0 2016-01-06 11:01:07
Enter ".help" for usage hints.
sqlite> .tables
messages
sqlite> select * from messages;
1|こんにちは
2|世界
3|Hello
4|World

うまくいきました.

msys2-launcherがすごい便利

msys2ってタスクバーにピン留めできんのかーと思っていたら
twitterでmattnさんが以下の様な事をつぶやいておられました.

探してみるとこりゃ便利そうです.

github - msys2-launcher

入れてみる

pacmanでお手軽に入れられます.

pacman -Sy msys2-launcher

msys64(64bit環境の場合)の配下にmsys2.exeが生成されているのでこれを使えばよいです.
バッチリタスクバーにピン留めできます.

参考

MSYS2 users list

Eclipseでビルド時に"Java heap space"が発生する

Eclipseでビルドするとすぐメモリ不足エラーが発生する.

大体は"GC"とか"heap"とかがメッセージに入る.

(だからロースペックマシンをよく使う私はJavaはあまり使いたくない....)

解決するにはJavaVMをちょっとチューニングとよい.
(メモリがあればの話ではありますが)

eclipse.iniを以下のように変更

~~~~~
中略
~~~~~
--launcher.XXMaxPermSize
1024M # 512Mから変更
~~~~~
中略
~~~~~
-Xms512m #256から変更

これでEclipseを再起動すればそこそこそれっぽく動く.
割り当ての変更だけなので実メモリが小さいと遅くなりますが.

ubuntuでtmuxを使うとlsで色がつかなくなった

現象

ubuntuでtmuxを使うとlsで色がつかなくなった.

なんでだ?と思ったら下記のコマンドでは色がつく.

ls --color=auto

どうも.bashrcが読み込まれていないらしい.(Ubuntuは.bashrcでalias入るので色がつく)
地味に困る.

対処

色々探したらこのサイトの一番下の追記に記載があった.感謝.

.tmux.confに以下を追記.

set-option -g default-shell /bin/bash
set-option -g default-command /bin/bash

bash以外のユーザさんは適宜変えてください.

これで元通り便利になった.

net/httpのhttp.HandlerFuncをラップするテクニック

golangでnet/httpを使うと下記のようなコードを書くことになる.

func main() {
    http.HandleFunc("/foo", fooHandler)
    http.HandleFunc("/bar", barHandler)

    http.ListenAndServe(":8080", nil)
}

ここで全てのハンドラの前に認証を追加したいなどと考えると,各ハンドラ関数に処理を書くのが明らかに無駄だと気づく.

こういう時にはHandlerFuncをwrapするテクニックが一般的なようだ.

func main() {
    http.HandleFunc("/foo", authenticate(fooHandler)) // authenticateでラップする.
    http.HandleFunc("/bar", authenticate(barHandler)) // authenticateでラップする.

    http.ListenAndServe(":8080", nil)
}

func authenticate(fn http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        log.Println("before process") // 処理の前の共通処理
        fn(w, r)
        log.Println("after process") // 処理の後の共通処理
    }
}

シンプルで良い.

catの-(ハイフン)オプションを使う

こんなファイルを用意する.

$ cat > test.txt <<EOS
test
test
test
test
EOS
$ cat > test2.txt <<EOS
test2
test2
test2
test2
EOS

これを普通にパイプでつなぐとパイプで入ってきた入力は無視される.

$ cat test.txt | cat test2.txt
test2
test2
test2
test2

-(ハイフン)を使うとファイルの入力のように扱うことができる.

標準入力を第一引数に指定する感じ.

$ cat test2.txt | cat - test.txt
test2
test2
test2
test2
test
test
test
test

標準入力を第二引数に指定する感じ.

$ cat test2.txt | cat test.txt -
test
test
test
test
test2
test2
test2
test2

ワンライナーとかで便利かも.

opensslを使って鍵の作成・ファイルの暗号化・復号化

opensslを使うと秘密鍵,公開鍵を作ってファイルを暗号化したり,復号化したりできる.

とても面白いのだけど,オプションが多くてややこしいのでメモしておく.

秘密鍵を作る

seckey.pemという名の秘密鍵を作る場合.

$ openssl genrsa -out seckey.pem -aes256 2048
  # 秘密鍵のパスワードとパスワードの確認入力が求められます

公開鍵を作る

seckey.pemという名の秘密鍵を使って,pubkey.pemという名の公開鍵を作る場合.

$ openssl rsa -in seckey.pem -pubout -out pubkey.pem

ファイルを暗号化する

secret.txtを暗号化して,secret.txt.secretを作ってみます.

とりあえずsecret.txtを作ります.

$ cat > secret.txt <<EOS
 this is a
 secret
 text.
EOS

続いて暗号化

$ openssl rsautl -pubin -inkey pubkey.pem -in secret.txt -encrypt -out secret.txt.secret

よくわからない内容のファイルができています.

$ cat secret.txt.secret
K>Fp] 4{^ F'ݿqgs&@ߟ%[jÜ
I50@1{._j?@w"BkAX+'
6>IgޓM=Fv^1v    p+zUޟ/Nؽ{$QR؃І+C
                               0>jB~*

ファイルを復号化する

seckey.pemを使ってsecret.txt.secretを復号化します.

cat secret.txt.secret | openssl

実行結果

$ cat secret.txt.secret | openssl rsautl -decrypt -inkey seckey.pem
Enter pass phrase for seckey.pem:  # 秘密鍵のパスワードを入力
this is a
secret
text.

割と簡単にできるんですね.