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. // LastInsertId returns id of result's last row.
// If lastRowId can't be retrieved, this method returns error. // If lastRowId can't be retrieved, this method returns error.
func (r *result) LastInsertId() (int64, 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() { if v.IsNull() || v.IsUndefined() {
return 0, errors.New("d1: lastRowId cannot be retrieved") return 0, errors.New("d1: lastRowId cannot be retrieved")
} }

View File

@ -10,3 +10,15 @@ build:
.PHONY: publish .PHONY: publish
publish: publish:
wrangler 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 ### Commands
* Before development, 1. create your own D1 database, 2. set database ID to wrangler.toml and run `wrangler d1 migrations apply [DB Name]`.
``` ```
make dev # run dev server # development
make build # build Go Wasm binary 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 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 ## Author
syumai syumai

View File

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

View File

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

View File

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

View File

@ -9,7 +9,4 @@ require (
replace github.com/syumai/workers => ../../ replace github.com/syumai/workers => ../../
require ( require github.com/josharian/intern v1.0.0 // indirect
github.com/google/uuid v1.3.0 // indirect
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 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=

View File

@ -1,6 +1,6 @@
-- Migration number: 0000 2023-01-09T14:48:53.705Z -- Migration number: 0000 2023-01-09T14:48:53.705Z
CREATE TABLE articles ( CREATE TABLE articles (
id TEXT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL, title TEXT NOT NULL,
body TEXT NOT NULL, body TEXT NOT NULL,
created_at INTEGER 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" binding = "BlogDB"
database_name = "d1-blog-server" database_name = "d1-blog-server"
database_id = "c6d5e4c0-3134-42fa-834c-812b24fea3cf" database_id = "c6d5e4c0-3134-42fa-834c-812b24fea3cf"
preview_database_id = "9f44099e-a008-45c2-88e4-aed0bd754a86" preview_database_id = "777e3713-4386-438e-ba71-30d2f772750d"
[[ 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"