自分の記事さえ保存できればいいので少しは楽になるはず。
ブツ
実行
NAME='Sqlite3.Monaledge.MyArticles.20221009092136'
git clone https://github.com/ytyaru/$NAME
$NAME/src/run.sh
方法
モナレッジAPIを解析してみたとき結果として返ってきたJSONから名前や型をみてSQLテーブルに落とし込む。
DB
Table
users
articles
comments
categories
SQL
users
create table if not exists users(
id integer not null primary key,
address text not null unique,
created integer not null,
updated integer not null,
name text not null,
icon_image_path text
);
articles
create table if not exists articles(
id integer not null primary key,
created text not null,
updated text not null,
title text not null,
sent_mona text not null,
access integer not null,
ogp_path text not null,
category integer not null,
content text not null
);
comments
PRAGMA foreign_keys=true;
create table if not exists comments(
id integer not null primary key,
article_id integer not null,
created integer not null,
updated integer not null,
user_id integer not null,
content text not null,
foreign key (article_id) references articles(id)
);
categories
create table if not exists categories(
id integer not null primary key,
name text not null unique
);
insert into categories(id,name) values (0,'未分類'),(1,'その他'),(2,'暗号通貨'),(3,'モナコイン'),(4,'温泉'),(5,'神社・お寺'),(6,'趣味'),(10,'カーライフ'),(7,'日記'),(8,'IT技術'),(9,'ガジェット'),(11,'本'),(12,'創作話'),(13,'怖い話');
categoryUtils.jsを参考にした。
気になる点
users
でなくauthors
では?created
でなくcreated_at
では?
短くしたかったから現状にしたけど正しくない。細かいことにこだわりすぎぬようにしたいが気になる。
created
やupdated
は列の末尾につけるものでは?
列の定義順にルールがあるかは知らないが慣習的にはcreated
やupdated
は列の末尾につけるような気がする。でも今回は次のようなルールにしたつもり。そこまで厳密でない。
- ソース元を参考にする
- レコードを一意に特定するキー
- レコードのグループキー
- レコードのソートキー
- データ
- 代表的である
- 検索で使用するメタデータである
- データ量が少ない
テストデータ挿入
ちゃんと挿入できるか試してみた。article APIを発行して得たJSONをテキストファイルに保存し、そこからデータを抽出してinsert
文を発行する。
Escape() { echo "$(cat -)" | sed -e "s/'/''/g"; }
InsertArticle() {
JSON="$(cat 'test-data/article-454.json')"
ARTICLE_ID="$(echo "$JSON" | jq .id)"
TITLE="$(echo "$JSON" | jq -r .title | Escape)"
CONTENT="$(echo "$JSON" | jq -r .content | Escape)"
SENT_MONA="$(echo "$JSON" | jq -r .sent_mona)"
ACCESS="$(echo "$JSON" | jq -r .access)"
OGP_PATH="$(echo "$JSON" | jq -r .ogp_path | Escape)"
CATEGORY="$(echo "$JSON" | jq -r .category)"
CREATED="$(echo "$JSON" | jq -r .createdAt)"
UPDATED="$(echo "$JSON" | jq -r .updatedAt)"
SQL="insert into articles(id,created,updated,title,sent_mona,access,ogp_path,category,content) values($ARTICLE_ID,'$CREATED','$UPDATED','$TITLE',$SENT_MONA,$ACCESS,'$OGP_PATH',$CATEGORY,'$CONTENT')"
echo "$SQL"
sqlite3 "$DB" "$SQL"
SQL="select * from articles;"
sqlite3 "$DB" "$SQL"
}
InsertArticle
成功した。
失敗例
SQLのメタ文字'
が本文にあると構文エラーになる
SQLのメタ文字であるシングルクォーテーション'
が記事本文のマークダウン内に存在していたとき、そのマークダウンをSQLでinsert
しようとすると構文エラーになる。
SQL="insert into articles(article_id,created,updated,title,sent_mona,access,ogp_path,category,content) values($ARTICLE_ID,'$CREATED','$UPDATED','$TITLE',$SENT_MONA,$ACCESS,'$OGP_PATH',$CATEGORY,'$CONTENT')"
sqlite3 "$DB" "$SQL"
Error: in prepare, near "MEHCqJbgiNERCH3bRAtNSSD9uxPViEX1nu": syntax error
\n```javascript\nconst cpParams = {\n source: 'MEHCqJbgiNERCH3bRAtNSSD9uxPV
error here ---^
これはマークダウン内にJavaScriptのソースコードが書かれていて、その中で文字列を表現するときにシングルクォートが使われている。こうしたことはよくあることなので、シングルクォートがあっても動作するようにしたい。
そこでシングルクォートをエスケープする必要がある。''
のように2つ連続にすることでエスケープできる。
sed -e "s/'/''/g"
関数化したのが以下。パイプで受け取ったテキストに対してエスケープをかける。
Escape() { echo "$(cat -)" | sed -e "s/'/''/g"; }