アーカイブ機能。
成果物
SQLite3 Archive形式
SQLite3 ArchiveはZIP
やtar
のSQLite3版みたいなもの。それらより1%ほど大きくなるがSQL文やSQLite3コマンドで操作できる。
ヘルプ
sqlite3 -A Wrong number of arguments. Usage: .archive ... Manage SQL archives Each command must have exactly one of the following options: -c, --create Create a new archive -u, --update Add files or update files with changed mtime -i, --insert Like -u but always add even if mtime unchanged -t, --list List contents of archive -x, --extract Extract files from archive Optional arguments: -v, --verbose Print each filename as it is processed -f FILE, --file FILE Operate on archive FILE (default is current db) -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS -C DIR, --directory DIR Change to directory DIR to read/extract files -n, --dryrun Show the SQL that would have occurred Examples: .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar .ar -tf archive.sar # List members of archive.sar .ar -xvf archive.sar # Verbosely extract files from archive.sar See also: http://sqlite.org/cli.html#sqlar_archive_support
使ってみる
テストファイル作成
echo -e "aaa\nAAA" > A.txt echo -e "bbb\nBBB" > B.txt
Archiveファイル作成
$ sqlite3 texts -Ac A.txt B.txt
texts
ファイルが作成される。
ls -1 | grep texts
texts
ファイル一覧
CLI。
$ sqlite3 texts -At
A.txt B.txt
一覧の詳細
sqlite3 texts -Atv
-rw-r--r-- 8 2019-08-16 04:54:47 A.txt -rw-r--r-- 8 2019-08-16 04:54:47 B.txt
ファイル展開
まずは元ファイルを削除する。
rm A.txt B.txt
次にSQLite3アーカイブファイルの内容を展開する。
sqlite3 texts -Ax
A.txt
, B.txt
ファイルが出力されている。
cat A.xt
aaa AAA
cat B.xt
bbb BBB
SQLiteで見てみる
sqlite3 texts
対話モードで開く。テーブル一覧する。
.tables
sqlar
というテーブルが出来ている。
sqlar
テーブルの中身を見てみる。
.headers on select * from sqlar;
name|mode|mtime|sz|data A.txt|33188|1565931287|8|aaa AAA B.txt|33188|1565931287|8|bbb BBB
ファイル名、権限、更新日時、サイズ、内容が入っている。
これでSQLでも操作できることがわかった。
挿入
まずは追加する元ファイルを作成する。
echo -e "ccc\nCCC" > C.txt
アーカイブファイルtexts
にC.txt
を追加する。
sqlite3 texts -Ai C.txt
一覧にてC.txt
が存在することを確認。
sqlite3 texts -At
A.txt B.txt C.txt
更新
ファイル内容の変更を確認する。削除はできない。一度作成されたらコマンドからは削除不可。
まずはアーカイブファイルの確認。
sqlite3 texts -At
A.txt B.txt C.txt
これをファイルシステムへ展開する。
sqlite3 texts -Ax
カレントディレクトリには以下のようなファイルが存在する状態になる。
ls
A.txt B.txt C.txt texts
ここでA.txt
ファイルを削除する。
rm A.txt
ls
B.txt C.txt texts
そしてB.txt
の内容を編集する。
echo "ばばば" >> B.txt
bbb BBB ばばば
この変更をアーカイブにマージする。
sqlite3 texts -Au *.txt
sqlite3 texts -At
texts
ファイルをSQLite3で開く。
sqlite3 texts
select * from sqlar;
A.txt|33188|1565931287|8|aaa AAA C.txt|33188|1565932536|8|ccc CCC B.txt|33188|1565933322|18|bbb BBB ばばば
B.txt
の変更はされている。だが、A.txt
ファイルは削除されていない。
ファイル削除するコマンドが見つからない。
ディレクトリを追加する
テスト用にディレクトリとファイルを作成する。
mkdir -p ./D/DD echo -e "ddd\nDDD" > ./D/DD/DDD.txt
ディレクトリを追加する。
sqlite3 texts -Ai D
一覧する。
sqlite3 texts -At
A.txt B.txt C.txt D D/DD D/DD/DDD.txt
詳細一覧する。
sqlite3 texts -Atv
-rw-r--r-- 8 2019-08-16 04:54:47 A.txt -rw-r--r-- 8 2019-08-16 05:15:36 C.txt -rw-r--r-- 18 2019-08-16 05:28:42 B.txt drwxr-xr-x 0 2019-08-16 05:39:42 D drwxr-xr-x 0 2019-08-16 05:40:30 D/DD -rw-r--r-- 8 2019-08-16 05:40:30 D/DD/DDD.txt
ディレクトリならmode
にd
フラグが付与される。
ファイルシステムから削除する。
rm -r A.txt B.txt C.txt D/
アーカイブから展開する。
sqlite3 texts -Ax
ディレクトリやその下にあるファイルも展開されていることを確認。
cat ./D/DD/DDD.txt
ddd DDD
削除
Archiveファイルの中身をSQLite3で見てみる。
sqlite3 texts ".headers on" "select * from sqlar;";
name|mode|mtime|sz|data A.txt|33188|1565938716|8|aaa AAA C.txt|33188|1565938717|8|ccc CCC B.txt|33188|1565938717|18|bbb BBB ばばば D|16877|1565938717|0| D/DD|16877|1565938717|0| D/DD/DDD.txt|33188|1565938717|8|ddd DDD
SQLのDELETE
文で削除してみる。
sqlite3 texts "delete from sqlar where name='A.txt'";
削除されている。成功。
sqlite3 texts ".headers on" "select * from sqlar;";
name|mode|mtime|sz|data C.txt|33188|1565938717|8|ccc CCC B.txt|33188|1565938717|18|bbb BBB ばばば D|16877|1565938717|0| D/DD|16877|1565938717|0| D/DD/DDD.txt|33188|1565938717|8|ddd DDD
というか、なぜ削除はCLIコマンドでできないの? 不便。それとも見落としている?
ディレクトリの再帰的削除はされない
sqlite3 texts "delete from sqlar where name='D'";
sqlite3 texts ".headers on" "select * from sqlar;";
name|mode|mtime|sz|data B.txt|33188|1565939371|8|bbb BBB C.txt|33188|1565939371|8|ccc CCC D/DD|16877|1565939371|0| D/DD/DDD.txt|33188|1565939371|8|ddd DDD
D
を消してもその配下であるD/DD
, D/DD/DDD.txt
が残っている。期待値としてはD
配下にあるものはすべて削除して欲しかった……。
もしやこれの実装が大変だから削除コマンドがないのかな?
だれかの親であればレコードがなくても展開される
親ディレクトリのレコードを削除した状態で展開してみる。
rm -rf A.txt B.txt C.txt D
sqlite3 texts -Ax
find .
. ./D ./D/DD ./D/DD/DDD.txt ./C.txt ./B.txt ./texts ./run.sh
D
ディレクトリが生成された。まあ他のファイル名にD/
があるから妥当。
ディレクトリ削除の確認(再帰削除されない。親レコードなくても展開される)
他のコマンド引数
引数 | 概要 |
---|---|
-f ファイルパス |
指定したファイルパスをアーカイブとして使う |
-a ファイルパス |
-f と同様だが、追記モード。appendvfs.c |
-C ディレクトリ |
相対パスの基準を指定したディレクトリパスに設定する |
-n |
アーカイブ操作するために実行するSQL文を表示する |
-- |
後続の語はすべてコマンド引数とする。 |
べつに使わなくていいかな。
関連情報
- Zipfileモジュール
- sqlite
- SQLITE_HAVE_ZLIB
- 5.アプリケーションコードからのSQLiteアーカイブの管理
sqlar_compress(X)
sqlar_uncompress(Y, SZ)
圧縮されてない
select sqlar_compress('AAA');
AAA
入力Xが圧縮できない場合、Xのコピーが返されます
圧縮できてないのでは? SQLITE_HAVE_ZLIBコンパイルオプションが必要だったのでは?
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13
- bash 4.4.12(1)-release
- SQLite 3.29.0
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux
前回まで
- SQLite3学習をはじめよう
- SQLite3学習 SQLiteについて
- SQLite3学習 SQLiteの適切な用途
- SQLite3学習 SQLiteの特徴
- SQLite3学習 SQLiteのクセ
- SQLite3学習 データ型とアフィニティ
- SQLite3学習 演算子の一覧
- SQLite3学習 よくある質問
- SQLite3学習 SQLiteダウンロード&コンパイル
- SQLite3学習 Tclで操作する
- SQLite3学習 ビルドオプション動作確認(SQLITE_ALLOW_URI_AUTHORITY)
- SQLite3学習 面白そうなコンパイルオプション
- SQLite3学習 SQLiteの拡張について
- SQLite3学習 JSON拡張
- SQLite3学習 JSON拡張(json_extract)
- SQLite3学習 JSON拡張(json_each)
- SQLite3学習 JSON拡張(json_tree オブジェクト→行)
- SQLite3学習 JSON拡張(json_tree オブジェクトツリー→行)
- SQLite3学習 JSON拡張(json_tree オブジェクト配列→行)
- SQLite3学習 JSON拡張(json_group_array 行→配列)
- SQLite3学習 JSON拡張(json_group_object 行→オブジェクト)
- SQLite3学習 JSON拡張(json_array_length)
- SQLite3学習 JSON拡張(json_type)
- SQLite3学習 JSON拡張(json_valid)
- SQLite3学習 JSON拡張(json_quote)
- SQLite3学習 JSON拡張(json_array)
- SQLite3学習 JSON拡張(json_object)
- SQLite3学習 JSON拡張(json_patch)
- SQLite3学習 JSON拡張(json_insert)
- SQLite3学習 JSON拡張(json_replace)
- SQLite3学習 JSON拡張(json_set)
- SQLite3学習 JSON拡張(json_remove)
- SQLite3学習 全文検索(FTS5)
- SQLite3学習 全文検索FTSを日本語で使う方法を調べてみた
- 形態素解析MeCabをインストールする
- SQLite3学習 全文検索FTS5のMeCab用トークナイザを実装する
- SQLite3学習 FTS5+MeCabでクエリ構文
- SQLite3学習 FTS5のテーブル作成と初期化
- SQLite3学習 FTS5の補助関数
- SQLite3学習 FTS5のfts5vocab仮想テーブル
- SQLite3学習 再帰クエリ(WITH RECURSIVE)
- SQLite3学習 R-Treeモジュール
- SQLite3学習 ファイル入出力(SQL集計)
- SQLite3学習 拡張関数(generate_series)
- SQLite3謎 主キーの型をintにするとinsertで値を省略したらNULLになってしまう
- SQLite3学習 入出力関数(fsdir, readfile, writefile, edit)
- SQLite3ビルド コンパイルオプションを付与する方法(CFLAGS等))
- SQLite3 コンパイルオプション確認方法(pragma compile_options)
- SQLite3ビルド ICUを有効にする(SQLITE_ENABLE_ICU)
- SQLite3拡張 ICUを動的ロードする
- SQLite3拡張 ICUでcollateする
- SQLite3拡張 ICUで全文検索する(FTS4)
- SQLite3拡張 SQL関数一覧(pragma function_list)
- SQLite3拡張 仮想テーブルモジュール一覧(pragma module_list)
- SQLite3拡張 プラグマ一覧(pragma pragma_list)
- SQLite3謎 values()構文
- SQLite3学習 インタフェース概要