ITS (Issue Tracking System) の trac では、チケットにコメントが書ける。
そのデータベーススキーマを調べた。
予備知識
アプリケーション仕様
このポストで調べたいことに関連する trac の仕様は以下のとおり:
- チケットへのコメント ... (1)
- チケットにコメントを投稿できる
- チケットのコメントを編集できる
- コメントの編集履歴が見れる
- チケットの属性管理 ... (2)
- チケットの属性を変更できる(属性 = チケットタイプ: bug/enhance/task ...)
- チケットの属性変更の履歴を見れる
- チケットの属性変更にコメントを付与できる
- チケットの属性変更のコメントを編集できる
- チケットの属性変更のコメントの編集履歴が見れる
- チケットのタイムラインには (1) および (2) が表示される
実際に操作したイメージはこんな感じ:
テーブル設計
チケットは ticket テーブルに、コメントは ticket_change テーブルに格納されている。
ticket_change テーブルはチケットのステータス変更なども管理するテーブルで、これにコメントも相乗りしている。
# .schema ticket_change
CREATE TABLE ticket_change (
ticket integer,
time integer,
author text,
field text,
oldvalue text,
newvalue text,
UNIQUE (ticket,time,field)
);
CREATE INDEX ticket_change_ticket_idx ON ticket_change (ticket);
CREATE INDEX ticket_change_time_idx ON ticket_change (time);
準備
Docker で trac を起動
docker run -d -p 8123:8123 --name my_trac stephenhsu/trac
hub.docker.com
trac のコンテナに入り、sqlite3 を実行
# at host
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
198a9f3be235 stephenhsu/trac "/bin/sh -c 'service…" 30 minutes ago Up 30 minutes 0.0.0.0:8123->8123/tcp my_trac
$ docker exec -it 198a9f3be235 /bin/bash
# at trac container
root@198a9f3be235:/# apt install sqlite3
root@198a9f3be235:/# sqlite3 /var/local/trac/db/trac.db
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> .headers ON
sqlite> .mode column
sqlite> .width 6 16 10 9 8 16
実験
以下の手順でコメントを追加、編集してDBのようすを観察する。
- comment:1 追加:c1
- comment:2 追加:c2
- comment:1 編集:c1 → c1u
- comment:1 編集:c1u → c1uu
むむむ
ticket time author field oldvalue newvalue
------ ---------------- ---------- --------- -------- ----------------
1 1658493681622019 trac_admin comment 1 c1uu
1 1658493681622019 trac_admin _comment0 c1 1658493692585483
1 1658493681622019 trac_admin _comment1 c1u 1658493697493613
1 1658493684972623 trac_admin comment 2 c2
なんじゃこりゃ
よくわからんので、各操作終了後のテーブルのようすをスナップショット的に
comment:1 追加:c1
sqlite> select * from ticket_change order by time;
ticket time author field oldvalue newvalue
------ ---------------- ---------- --------- -------- ----------------
1 1658494632622823 trac_admin comment 1 c1
- field = "comment"
- oldvalue = ${コメント番号}
- newvalue = ${コメント本文}
comment:2 追加:c2
sqlite> select * from ticket_change order by time;
ticket time author field oldvalue newvalue
------ ---------------- ---------- --------- -------- ----------------
1 1658494632622823 trac_admin comment 1 c1
1 1658494646691429 trac_admin comment 2 c2
おなじ。
comment:1 編集:c1 → c1u
sqlite> select * from ticket_change order by time;
ticket time author field oldvalue newvalue
------ ---------------- ---------- --------- -------- ----------------
1 1658494632622823 trac_admin comment 1 c1u
1 1658494632622823 trac_admin _comment0 c1 1658494660176808
1 1658494646691429 trac_admin comment 2 c2
- 古いレコード(1行目)
- time = ${コメント追加日時} ※変更なし
- field = "comment" ※ 変更なし
- oldvalue = ${コメント番号} ※ 変更なし
- newvalue = ${編集後のコメント本文} ※ ★更新★
- 新しいレコード(2行目)
- time = ${コメント追加日時} ← 編集日時じゃない!
- field = "_comment0"
- oldvalue = ${編集前のコメント本文}
- newvalue = ${コメント編集日時}
comment:1 編集:c1u → c1uu
sqlite> select * from ticket_change order by time;
ticket time author field oldvalue newvalue
------ ---------------- ---------- --------- -------- ----------------
1 1658494632622823 trac_admin comment 1 c1uu
1 1658494632622823 trac_admin _comment0 c1 1658494660176808
1 1658494632622823 trac_admin _comment1 c1u 1658494671706741
1 1658494646691429 trac_admin comment 2 c2