Deno で試すデータベースアクセス(Turso編)

Twitter の タイムラインに流れてきた Turso
のクローズドベータに申し込んだのと前後してパブリックベータが公開された。

Turso は、SQLite 使った Edge データベース。
近しいものは、Cloudflare D1 という認識をしている。
Cloudflare D1 は、Cloudflare worker 向けの方向性が強くちょっと二の足を踏んでいたが、 Turso は、この機能を独立して単独サービスされたものらしい。

いつもの Deno x 何かのデータベースアクセスの確認としてトライしてみたい。

参考

導入

Turso の設定をするためには、現状は管理画面のようなものは無い様子。
まずは、cli のセットアップが必要です。

まずはツールのインストール。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
$ brew install chiselstrike/tap/turso

# or

$ curl -sSfL https://get.tur.so/install.sh | bash
# 今回はこちらを採用

Welcome to the Turso installer!

.$$$$$$;;;;;;;;;;;;;;;;;,,,,,, ........
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ..,;$$$$$$$$$,
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ .,$$$$$$$$$$$$$;,
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ .'$$$$$$$$$$$$$$$$;,
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ,$$$$$$$$$$$$$$$$$$;,
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ '$$$$$$$$$$$$$$$$$$$$;,
;$$$$$$$$$$$. .$$$$$$$$$$$$$$$;'...
;$$$$$$$$$$$ .$$$$$$$$$$$$$$;..
;$$$$$$$$$$$ .'$$$$$$$$$$$$$$;.
;$$$$$$$$$$$. ...';$$$$$$$$$$$$$$$$.
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$,
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$;.
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$,.
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$;.
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$;'.
.$$$$$;;;;;;;;;;;;;;;;;,,,'...

Downloading Linux_x86_64 ...
######################################################################## 100.0%

Installing to /root/.turso

Updating profile /root/.bashrc

Turso will be available when you open a new terminal.
If you want to make Turso available in this terminal, please run:

source /root/.bashrc

Turso CLI installed!

If you are a new user, you can sign up with turso auth signup.

If you already have an account, please login with turso auth login.

アスキーアートは青色で表示されてるんですが、turso-cli で使用されているアートと同じもののようです。

先に、Web の画面でアカウントを作ってあるので、f you already have an account, please login with turso auth login.
の方で進めます。

1
2
3
4
5
$ turso auth login
error: Unable to open browser.
Visit this URL on this device to log in:
https://api.turso.io?port=40173&redirect=true
Waiting for authentication...

上記ではポートが40173 なのに、次起動すると別のものになってしまい、と中々辛みがあるものだった。
Docker コンテナ上で環境構築しようとすると、空けるべきポートを特定できない。
仕方ないので、WSL 環境を整えて再度コマンドのインストールを行い、再度実行。

1
2
3
4
5
6
7
8
9
10
11
12
$ turso auth login
error: Unable to open browser.
Visit this URL on this device to log in:
https://api.turso.io?port=43043&redirect=true
Waiting for authentication...

# このタイミングで上記のアドレスにアクセスすると、
# http://localhost:43043/?jwt=[文字列] にリダイレクトし、以下の表示が続く

✔ Success! Logged in as [github のアカウントID]
✏️ We are so happy you are here! Now that you are authenticated, it is time to create a database:
turso db create

認証ができると、ブラウザは以下の表示になる。

誘導にしたがって、データベースの作成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ turso db create
Created database [自動生成されたDB名] in Tokyo, Japan (nrt) in 46 seconds.

You can start an interactive SQL shell with:

turso db shell [自動生成されたDB名]

To see information about the database, including a connection URL, run:

turso db show [自動生成されたDB名]

✏️ Now that you created a database, the next step is to create a replica. Why don't we try?
turso db locations
turso db replicate [自動生成されたDB名] [location]

また、上記ではテーブル名を指定しなかったが、指定することは可能。

1
2
3
4
5
6
7
8
9
10
$ turso db create test-db
Created database test-db in Tokyo, Japan (nrt) in 39 seconds.

You can start an interactive SQL shell with:

turso db shell test-db

To see information about the database, including a connection URL, run:

turso db show test-db

また、誘導に従い、確認すると次のようになる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 turso db locations
ID LOCATION
ams Amsterdam, Netherlands
cdg Paris, France
den Denver, Colorado (US)
dfw Dallas, Texas (US)
ewr Secaucus, NJ (US)
fra Frankfurt, Germany
gru São Paulo, Brazil
hkg Hong Kong, Hong Kong
iad Ashburn, Virginia (US)
jnb Johannesburg, South Africa
lax Los Angeles, California (US)
lhr London, United Kingdom
maa Chennai (Madras), India
mad Madrid, Spain
mia Miami, Florida (US)
nrt Tokyo, Japan [default] # <= これだけ青色に
ord Chicago, Illinois (US)
otp Bucharest, Romania
scl Santiago, Chile
sea Seattle, Washington (US)
sin Singapore
sjc Sunnyvale, California (US)
syd Sydney, Australia
waw Warsaw, Poland
yul Montreal, Canada
yyz Toronto, Canada
1
2
3
4
5
6
7
8
9
10
11
$ turso db shell [自動生成されたDB名]
Connected to [自動生成されたDB名] at libsql://[自動生成されたDB名]-[github のアカウントID].turso.io

Welcome to Turso SQL shell!

Type ".quit" to exit the shell, ".tables" to list all tables, and ".schema" to show table schemas.

→ .tables
NAME
→ .schema
SQL

何もまだ設定していないので、.tables .schema が出ないのは当然といえば当然。
以下その他のコマンドも動作確認。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ turso account show
You are currently on starter plan.

RESOURCE USED MAX
storage 0 B 8.0 GiB
rows read 20 1000000000
databases 1 3
locations 1 3

$ turso db inspect [自動生成されたDB名]
Total space used for tables: 0 B
Total space used for indexes: 0 B
Number of rows read: 24

取りあえず、データベースは作成できたので、引き続きデータベースの操作を試みてみる。

実装 その前に

実装を進めるに当たり、接続先の確認/認証情報の取得が必要だが、これもまたコマンドで確認するものだった。

1
2
3
4
5
$ turso db list
NAME LOCATIONS URL
[自動生成されたDB名] nrt (primary) libsql://[自動生成されたDB名]-[github のアカウントID].turso.io

# (後で気が付いたけれども、`turso db shell` でも表示されていた。)
1
2
turso db tokens create [自動生成されたDB名] --expiration none
eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9........................

トークン文字列が取得できる。--expiration none 以外のオプションは、 'default'
'none'が選択できる様子。具体的な時刻は設定できない。

実装

先の通りのコマンドで接続先と認証トークンが取れたので、テストスクリプトを作成し接続を試みます。

turso-connect-test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import "https://deno.land/std@0.182.0/dotenv/load.ts";

import { type Config, createClient } from "https://esm.sh/@libsql/client";

const config = {
url: Deno.env.get("TURSO_DB_URL"),
authToken: Deno.env.get("TURSO_AUTH_TOKEN"),
} as Config;

const db = createClient(config);

const createResult = await db.execute(
"CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY AUTOINCREMENT, name);"
);
console.log(createResult);

const selectResult = await db.execute("SELECT * FROM users");
console.log(selectResult);

const insertResult1 = await db.execute(
"INSERT INTO users(name) VALUES('USER1')"
);
console.log(insertResult1);

const insertResult2 = await db.execute(
"INSERT INTO users(name) VALUES('USER2')"
);
console.log(insertResult2);

const updateResult = await db.execute(
"UPDATE users SET name = 'USER2-update' WHERE name = 'USER2'"
);
console.log(updateResult);

const serectResult2 = await db.execute("SELECT * FROM users");
console.log(serectResult2);

const deleteResult = await db.execute("DELETE from users WHERE name = 'USER1'");
console.log(deleteResult);

const serectResult3 = await db.execute("SELECT * FROM users");
console.log(serectResult3);

const dropResult = await db.execute("DROP TABLE users");
console.log(dropResult);

db.close();

動かしてみると次のようになる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ deno run -A  .\turso-connect-test.ts

{ columns: [], rows: [], rowsAffected: 0 }
{ columns: [ "id", "name" ], rows: [], rowsAffected: 0 }
{ columns: [], rows: [], rowsAffected: 1 }
{ columns: [], rows: [], rowsAffected: 1 }
{ columns: [], rows: [], rowsAffected: 1 }
{
columns: [ "id", "name" ],
rows: [ { id: 1, name: "USER1" }, { id: 2, name: "USER2-update" } ],
rowsAffected: 0
}
{ columns: [], rows: [], rowsAffected: 1 }
{
columns: [ "id", "name" ],
rows: [ { id: 2, name: "USER2-update" } ],
rowsAffected: 0
}
{ columns: [], rows: [], rowsAffected: 0 }

あとしまつ

Turso に作ったデータベースを削除する。

1
2
3
4
5
6
7
8
turso db destroy [自動生成されたDB名]
Database [自動生成されたDB名], all its replicas, and data will be destroyed.
Are you sure you want to do this? [y/n]: y
Destroyed database [自動生成されたDB名] in 3 seconds.

# 削除したのでリストに出てこない
$ turso db list
NAME LOCATIONS URL

データベースの削除は1分立たずに終了した。
容量が増えれば自然と長くなる可能性はある。


Turso
に接続してデータベースの作成/削除。テーブルの作成/削除。個別レコードの CRUD を動作確認できた。

現状パブリックベータではあるものの、シンプルに使えるので、非常に機体が持てるサービスだと感じた。

Turso の公式トップページに記載されている TURSO INTEGRATES WITH THESE TECHNOLOGIES には、Deno Deploy も記載されており、この点でも期待できる。

では。


余談。

クローズドベータ残り数日というところで申し込みをした後、音沙汰が無かったのでツイッターでぼやいたら、エゴサしていた? Turso の CEO に発見され、何かできることはないか? とリプライがあった。

結局パブリックベータの公開前後であったために、クローズドベータの申込者の処理が漏れていたらしい。
とりあえず Turso の CEO が、リプライを直接くれるくらい親切だったことは、共有したい。