Merge pull request #22 from syumai/fix-last-insert-id

fix last_row_id key name of D1
This commit is contained in:
syumai 2023-02-26 17:41:36 +09:00 committed by GitHub
commit 4e34fbaf38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 57 additions and 33 deletions

View File

@ -17,7 +17,7 @@ var (
// LastInsertId returns id of result's last row.
// If lastRowId can't be retrieved, this method returns error.
func (r *result) LastInsertId() (int64, error) {
v := r.resultObj.Get("meta").Get("lastRowId")
v := r.resultObj.Get("meta").Get("last_row_id")
if v.IsNull() || v.IsUndefined() {
return 0, errors.New("d1: lastRowId cannot be retrieved")
}

View File

@ -10,3 +10,15 @@ build:
.PHONY: publish
publish:
wrangler publish
.PHONY: generate
generate:
go generate ./...
.PHONY: init-db
init-db:
wrangler d1 execute d1-blog-server --file=./schema.sql
.PHONY: init-db-preview
init-db-preview:
wrangler d1 execute d1-blog-server-preview --file=./schema.sql

View File

@ -65,14 +65,20 @@ This project requires these tools to be installed globally.
### Commands
* Before development, 1. create your own D1 database, 2. set database ID to wrangler.toml and run `wrangler d1 migrations apply [DB Name]`.
```
# development
make init-db-preview # initialize preview DB (remove all rows)
make generate # generate easyjson models
make dev # run dev server
make build # build Go Wasm binary
# production
make init-db # initialize production DB (remove all rows)
make publish # publish worker
```
* Notice: This example uses raw SQL commands to initialize the DB for simplicity, but in general you should use `wrangler d1 migraions` for your application.
## Author
syumai

View File

@ -8,7 +8,6 @@ import (
"os"
"time"
"github.com/google/uuid"
"github.com/mailru/easyjson"
"github.com/syumai/workers/cloudflare/d1"
_ "github.com/syumai/workers/cloudflare/d1" // register driver
@ -62,22 +61,29 @@ func (h *articleHandler) createArticle(w http.ResponseWriter, req *http.Request,
now := time.Now().Unix()
article := model.Article{
ID: uuid.New().String(),
Title: createArticleReq.Title,
Body: createArticleReq.Body,
CreatedAt: uint64(now),
}
_, err := db.Exec(`
INSERT INTO articles (id, title, body, created_at)
VALUES (?, ?, ?, ?)
`, article.ID, article.Title, article.Body, article.CreatedAt)
result, err := db.Exec(`
INSERT INTO articles (title, body, created_at)
VALUES (?, ?, ?)
`, article.Title, article.Body, article.CreatedAt)
if err != nil {
log.Println(err)
h.handleErr(w, http.StatusInternalServerError,
"failed to save article")
return
}
id, err := result.LastInsertId()
if err != nil {
log.Println(err)
h.handleErr(w, http.StatusInternalServerError,
"failed to get ID of inserted article")
return
}
article.ID = uint64(id)
res := model.CreateArticleResponse{
Article: article,
@ -103,15 +109,15 @@ ORDER BY created_at DESC;
articles := []model.Article{}
for rows.Next() {
var (
id, title, body string
createdAt float64 // number value is always retrieved as float64.
title, body string
id, createdAt float64 // number value is always retrieved as float64.
)
err = rows.Scan(&id, &title, &body, &createdAt)
if err != nil {
break
}
articles = append(articles, model.Article{
ID: id,
ID: uint64(id),
Title: title,
Body: body,
CreatedAt: uint64(createdAt),

View File

@ -3,7 +3,7 @@ package model
//easyjson:json
type Article struct {
ID string `json:"id"`
ID uint64 `json:"id"`
Title string `json:"title"`
Body string `json:"body"`
CreatedAt uint64 `json:"createdAt"`

View File

@ -274,7 +274,7 @@ func easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel3(i
}
switch key {
case "id":
out.ID = string(in.String())
out.ID = uint64(in.Uint64())
case "title":
out.Title = string(in.String())
case "body":
@ -298,7 +298,7 @@ func easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel3(o
{
const prefix string = ",\"id\":"
out.RawString(prefix[1:])
out.String(string(in.ID))
out.Uint64(uint64(in.ID))
}
{
const prefix string = ",\"title\":"

View File

@ -9,7 +9,4 @@ require (
replace github.com/syumai/workers => ../../
require (
github.com/google/uuid v1.3.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
)
require github.com/josharian/intern v1.0.0 // indirect

View File

@ -1,5 +1,3 @@
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=

View File

@ -1,6 +1,6 @@
-- Migration number: 0000 2023-01-09T14:48:53.705Z
CREATE TABLE articles (
id TEXT NOT NULL,
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
body TEXT NOT NULL,
created_at INTEGER NOT NULL

View File

@ -0,0 +1,13 @@
DROP TABLE IF EXISTS articles;
CREATE TABLE IF NOT EXISTS articles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
body TEXT NOT NULL,
created_at INTEGER NOT NULL
);
CREATE INDEX idx_articles_on_created_at ON articles (created_at DESC);
INSERT INTO articles (title, body, created_at) VALUES (
'title of example post',
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
unixepoch()
);

View File

@ -9,12 +9,4 @@ command = "make build"
binding = "BlogDB"
database_name = "d1-blog-server"
database_id = "c6d5e4c0-3134-42fa-834c-812b24fea3cf"
preview_database_id = "9f44099e-a008-45c2-88e4-aed0bd754a86"
[[ d1_databases ]]
# workaround to migrate preview DB
# - https://github.com/cloudflare/wrangler2/issues/2446
binding = "BlogDB-Preview"
database_name = "d1-blog-server-preview"
database_id = "9f44099e-a008-45c2-88e4-aed0bd754a86"
preview_database_id = "9f44099e-a008-45c2-88e4-aed0bd754a86"
preview_database_id = "777e3713-4386-438e-ba71-30d2f772750d"