-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
129 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
CREATE TABLE manual(id); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DROP TABLE manual; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
CREATE TABLE test(data); | ||
|
||
PRAGMA user_version = 1; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
DROP INDEX idx_test; | ||
|
||
PRAGMA user_version = 10; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
CREATE INDEX idx_test ON test(data); | ||
|
||
PRAGMA user_version = 2; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
{{define "create-migration-tables"}} | ||
{{.DB.Exec `CREATE TABLE IF NOT EXISTS migration_files(id INT PRIMARY KEY, name TEXT NOT NULL) STRICT;`}} | ||
{{.DB.Exec `CREATE TABLE IF NOT EXISTS migrations(id ANY, run_date INT NOT NULL, stmt TEXT NOT NULL, error TEXT, result TEXT, ok INT GENERATED ALWAYS AS (error IS NULL)) STRICT;`}} | ||
{{.DB.Exec `CREATE INDEX IF NOT EXISTS successful_migrations ON migrations(id) WHERE ok;`}} | ||
{{end}} | ||
|
||
<!-- | ||
'migrate' accepts a dot value with fields DB, ID, and STMT. Performs a database | ||
migration by executing the statement if a migration with the same ID has not | ||
succeeded. Must call `create-migration-tables` once before calling this | ||
template. | ||
Invoke like: {{template "migrate" (dict "DB" .DB "ID" 2024032816100 "STMT" `ALTER TABLE user ADD last_login DATETIME`)}} | ||
--> | ||
{{define "migrate"}} | ||
{{$applied := .DB.QueryVal `SELECT COUNT(id) FROM migrations WHERE ok AND id=?;` .ID}} | ||
{{if eq $applied 0}} | ||
{{$result := try .DB `Exec` .STMT}} | ||
{{if $result.OK}} | ||
{{$.DB.Exec `INSERT INTO migrations VALUES(?,?,?,NULL,?);` .ID now .STMT ($result.Value | toJson)}} | ||
{{else}} | ||
{{$.DB.Exec `INSERT INTO migrations VALUES(?,?,?,?,NULL);` .ID now .STMT ($result.Error | toJson)}} | ||
{{failf "failed to apply migration. id: %d, sqlerror: %s" .ID $result.Error}} | ||
{{end}} | ||
{{end}} | ||
{{end}} | ||
|
||
<!-- | ||
'migrate-dir' accepts a dot value with fields DB, DIR, and RE. Performs a | ||
database migration using the files listed in DIR that match the regex pattern | ||
RE. The RE patternn must have a subpattern that matches a nonzero numeric string | ||
within the file name which is the migration id. Migration IDs greater than the | ||
current `PRAGMA user_version` are run in id order. Must call | ||
`create-migration-tables` once before calling this template. | ||
Invoke like {{template "migrate-dir" (dict "DB" .DB "DIR" .FS "RE" `^schema\.(\d+)\.sql$`)}} | ||
--> | ||
{{define "migrate-dir"}} | ||
{{range .DIR.List "."}} | ||
{{$id := atoi (regexReplaceAll $.RE .Name "$1")}} | ||
{{if eq $id 0}}{{continue}}{{end}} | ||
{{.DB.Exec `INSERT INTO migration_files VALUES(?1,?2) ON CONFLICT DO UPDATE SET name = ?2;` $id .Name}} | ||
{{end}} | ||
{{range .DB.QueryRows `SELECT name,id FROM migration_files WHERE id > ? ORDER BY id;` (.DB.QueryVal `PRAGMA user_version;`)}} | ||
{{$stmt := $.DIR.Read .name}} | ||
{{$result := try $.DB `Exec` $stmt}} | ||
{{if $result.OK}} | ||
{{$.DB.Exec `INSERT INTO migrations VALUES(?,?,?,NULL,?);` .id now $stmt ($result.Value | toJson)}} | ||
{{$.DB.Exec (printf `PRAGMA user_version=%d;` .id)}} | ||
{{else}} | ||
{{$.DB.Exec `INSERT INTO migrations VALUES(?,?,?,?,NULL);` .id now $stmt ($result.Error | toJson)}} | ||
{{failf "failed to apply migration. id: %d, sqlerror: %s" .ID $result.Error}} | ||
{{end}} | ||
{{end}} | ||
{{end}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<!-- this runs at startup --> | ||
{{define "INIT db"}} | ||
{{template "create-migration-tables" .}} | ||
{{template "migrate-dir" (dict "DB" .DB "DIR" .Migrations "RE" `^schema\.(\d+)\.sql$`)}} | ||
{{end}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<!DOCTYPE html> | ||
|
||
<p>{{.DB.Migrate .Migrations `^schema\.(\d+)\.sql$` (.DB.QueryVal `PRAGMA user_version;`)}} migrations applied.</p> | ||
|
||
<p>Current user_version: {{.DB.QueryVal `PRAGMA user_version`}}</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<!DOCTYPE html> | ||
<script src="https://unpkg.com/htmx.org@1.9.12"></script> | ||
|
||
{{$RE := `^manual\.(\d+)\.sql$`}} | ||
<p>Run a manual migration:</p> | ||
{{range .Migrations.List "."}} | ||
{{$id := atoi (regexReplaceAll $RE .Name "$1")}} | ||
{{if eq $id 0}}{{continue}}{{end}} | ||
<form><button hx-post="/db/run" hx-target="#results" hx-swap="beforeend">{{.Name}} ({{$id}})</button><input type="hidden" name="id" value="{{$id}}"></form> | ||
{{end}} | ||
|
||
<p>Results:</p> | ||
<ul id="results"> | ||
</ul> | ||
|
||
{{define "POST /db/run"}} | ||
{{.Req.ParseForm}} | ||
{{$id := atoi (.Req.FormValue "id")}} | ||
{{if eq $id 0}}<li>Invalid id: {{$id}}</li>{{return}}{{end}} | ||
{{$file := printf "manual.%d.sql" $id}} | ||
{{$result := try .Migrations `Read` $file}} | ||
{{if not $result.OK}}<li>Failed to read file <code>{{$file}}</code>: <code>{{$result.Error}}</code></li>{{return}}{{end}} | ||
{{$stmt := $result.Value}} | ||
{{$result := try .DB `Exec` $stmt}} | ||
<li>{{now | date "2006-01-02 15:04:05"}}: | ||
{{if $result.OK}} | ||
Applied migration {{$id}}. | ||
{{else}} | ||
Migration error: <code>{{$result.Error}}</code> | ||
{{end}} | ||
</li> | ||
{{end}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
GET http://localhost:8080/db/manual | ||
|
||
HTTP 200 | ||
[Asserts] | ||
body contains "Run a manual migration" | ||
body contains "manual.1.sql (1)" | ||
|
||
|
||
POST http://localhost:8080/db/run | ||
[FormParams] | ||
id: 1 | ||
|
||
HTTP 200 | ||
[Asserts] | ||
body contains "Applied migration 1." |