edit
関数で列データを任意アプリで編集できる!
成果物
一覧
SQL関数 | 概要 |
---|---|
fsdir() |
指定したパスを再帰的に解析してディレクトリやファイルの情報をもったテーブルを返す |
readfile() |
指定したパスのファイル内容を返す |
writefile() |
指定したパスに指定した内容を書き込む |
edit() |
指定したデータを指定したアプリで編集する |
SELECT * from fsdir('/tmp/work/');
SELECT readfile('/tmp/work/a.txt');
SELECT writefile('/tmp/work/a.txt', '内容');
SELECT edit('内容', 'vim');
テスト用ファイル作成
ターミナルで以下コマンド実行。
cd /tmp/work mkdir test_dir/ cd test_dir/ echo -e "あああ\nいいい" > test.txt sqlite3
fsdir()
指定したディレクトリ配下をテーブルで一覧する。
.headers on select * from fsdir('/tmp/work/test_dir/');
パスや内容などが得られる。
name|mode|mtime|data /tmp/work/test_dir/|16877|1565767985| /tmp/work/test_dir//test.txt|33188|1565767985|あああ いいい
name
はフルパス- なぜ
//test.txt
とスラッシュが2つあるのか謎
- なぜ
mode
って何? パーミッションと違うの?mtime
はたぶん最終更新日時。生成日時などがないのはファイルシステムごとに仕様が微妙に違うからか?data
はファイルの中身
readfile()
指定したファイルの内容を返す。以下のどちらでもOK。
select readfile('/tmp/work/test_dir//test.txt'); select readfile('/tmp/work/test_dir/test.txt');
あああ いいい
読込後のデータにはなぜか末尾に\n
が付与されてしまうためrtrim(readfile(), x'0A')
とすることで省く。
select rtrim(readfile('/tmp/work/test_dir//test.txt'),x'0A');
あああ いいい
writefile()
ファイルに書き込む。
ブログ用テーブルを作る。
create table posts(id integer primary key, title text, body text);
ブログの内容を挿入する。
insert into posts values(1, 'タイトル', '# 見出し * 項目A * 項目B ');
ファイル出力する。
select writefile('/tmp/work/' || title || '.md', body) from posts WHERE id=1;
以下のファイルが出力される。
/tmp/work/タイトル.md
# 見出し * 項目A * 項目B
edit()
ブログ用テーブルを作る。
create table posts(id integer primary key, title text, body text);
内容が空のレコードを作る。
insert into posts values(1, 'タイトル', '');
内容をエディタで編集させる。
UPDATE posts SET body=edit(body, 'vim') WHERE id=1;
vimが起動するので以下のように編集する。
# vimで編集 * すごい * かっこいい
:wq
で上書き終了。
エディタで編集が完了したらSQLite3対話モード画面に戻るので、テーブルをみてみる。
select * from posts;
1|タイトル|# vimで編集 * すごい * かっこいい
編集したデータが入っている! これでSQLite3のテーブルデータをアプリケーションで編集できる! これだよ、これがやりたかった。
edit()
の第二引数はアプリを指定する。vim
を任意のアプリにできる(フルパス指定でも可)- 画像などを
BLOB
型データにしてGIMP
アプリなどへ渡してやることも可
UPDATE posts SET body=edit(body, '/usr/local/bin/vim') WHERE id=1;
vimで画面崩壊
vim
で画面崩壊
edit(列, 'vim')
すると以下のようなエラーが出る。
Vim: 警告: 端末からの入力ではありません
その後、以下のような症状が現れる。
- 入力した文字が表示されない
Enter
キー入力しても改行されない- 表示に無駄なスペースがやたら入る
たとえばselect * from posts;
したら以下のように表示された。
System command returns 256 id|title|body 1|タイトル|# 見出し * 項目A * 項目B
以下コマンドで直せる。
stty sane
だが、SQLite3対話モードである。そこで以下コマンドを使った。
.shell stty sane
すると以下のように怒られた。
stty: 標準入力: デバイスに対する不適切なioctlです
仕方ないので親元のrun.sh
スクリプトファイル内で以下を実行した。
stty sane
ターミナルは謎の罠で満ちている。
GUIエディタで編集すべきなのか?
所感
なぜかedit
関数などの情報が全然見つからなかった。おかしいでしょ。めちゃくちゃ便利でしょこれ! もっとアピールして!
もちろん公式には書いてあるのだが、カテゴリおかしくない? なぜCLIとしてreadfile
関数などのことが書かれてるのか。
以下のようにSQL関数一覧に「File I/O関数」ページを作ってまとめてくれたら発見率が高まりSQLite3流行るよ! たぶん。
対象環境
- 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になってしまう