diff --git a/_examples/d1-blog-server/Makefile b/_examples/d1-blog-server/Makefile index 40a9d05..1e41aac 100644 --- a/_examples/d1-blog-server/Makefile +++ b/_examples/d1-blog-server/Makefile @@ -15,6 +15,6 @@ deploy: 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 +.PHONY: init-db-local +init-db-local: + wrangler d1 execute d1-blog-server --file=./schema.sql --local diff --git a/_examples/d1-blog-server/README.md b/_examples/d1-blog-server/README.md index 98250cc..e4ce37b 100644 --- a/_examples/d1-blog-server/README.md +++ b/_examples/d1-blog-server/README.md @@ -65,9 +65,9 @@ This project requires these tools to be installed globally. ``` # development -make init-db-preview # initialize preview DB (remove all rows) -make dev # run dev server -make build # build Go Wasm binary +make init-db-local # initialize local DB (remove all rows) +make dev # run dev server +make build # build Go Wasm binary # production make init-db # initialize production DB (remove all rows) diff --git a/_examples/d1-blog-server/app/handler.go b/_examples/d1-blog-server/app/handler.go index 0251f72..4fd78ca 100644 --- a/_examples/d1-blog-server/app/handler.go +++ b/_examples/d1-blog-server/app/handler.go @@ -10,34 +10,27 @@ import ( "time" "github.com/syumai/workers/_examples/d1-blog-server/app/model" - "github.com/syumai/workers/cloudflare/d1" - _ "github.com/syumai/workers/cloudflare/d1" // register driver ) -type articleHandler struct{} +type articleHandler struct { + db *sql.DB +} var _ http.Handler = (*articleHandler)(nil) -func NewArticleHandler() http.Handler { - return &articleHandler{} +func NewArticleHandler(db *sql.DB) http.Handler { + return &articleHandler{ + db: db, + } } func (h *articleHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { - // initialize DB. - // D1 connector requires request's context to initialize DB. - c, err := d1.OpenConnector("BlogDB") - if err != nil { - h.handleErr(w, http.StatusInternalServerError, fmt.Sprintf("failed to initialize DB: %v", err)) - } - // use sql.OpenDB instead of sql.Open. - db := sql.OpenDB(c) - switch req.Method { case http.MethodGet: - h.listArticles(w, req, db) + h.listArticles(w, req) return case http.MethodPost: - h.createArticle(w, req, db) + h.createArticle(w, req) return } w.WriteHeader(http.StatusNotFound) @@ -51,7 +44,7 @@ func (h *articleHandler) handleErr(w http.ResponseWriter, status int, msg string w.Write([]byte(msg)) } -func (h *articleHandler) createArticle(w http.ResponseWriter, req *http.Request, db *sql.DB) { +func (h *articleHandler) createArticle(w http.ResponseWriter, req *http.Request) { var createArticleReq model.CreateArticleRequest if err := json.NewDecoder(req.Body).Decode(&createArticleReq); err != nil { h.handleErr(w, http.StatusBadRequest, @@ -66,7 +59,7 @@ func (h *articleHandler) createArticle(w http.ResponseWriter, req *http.Request, CreatedAt: uint64(now), } - result, err := db.Exec(` + result, err := h.db.Exec(` INSERT INTO articles (title, body, created_at) VALUES (?, ?, ?) `, article.Title, article.Body, article.CreatedAt) @@ -95,12 +88,13 @@ VALUES (?, ?, ?) } } -func (h *articleHandler) listArticles(w http.ResponseWriter, req *http.Request, db *sql.DB) { - rows, err := db.Query(` +func (h *articleHandler) listArticles(w http.ResponseWriter, req *http.Request) { + rows, err := h.db.Query(` SELECT id, title, body, created_at FROM articles ORDER BY created_at DESC; `) if err != nil { + fmt.Printf("err: %v\n", err) h.handleErr(w, http.StatusInternalServerError, "failed to load article") return diff --git a/_examples/d1-blog-server/main.go b/_examples/d1-blog-server/main.go index 98d3dfb..abbcaee 100644 --- a/_examples/d1-blog-server/main.go +++ b/_examples/d1-blog-server/main.go @@ -1,13 +1,20 @@ package main import ( + "database/sql" + "log" "net/http" "github.com/syumai/workers" "github.com/syumai/workers/_examples/d1-blog-server/app" + _ "github.com/syumai/workers/cloudflare/d1" // register driver ) func main() { - http.Handle("/articles", app.NewArticleHandler()) + db, err := sql.Open("d1", "BlogDB") + if err != nil { + log.Fatalf("error opening DB: %s", err.Error()) + } + http.Handle("/articles", app.NewArticleHandler(db)) workers.Serve(nil) // use http.DefaultServeMux } diff --git a/_examples/d1-blog-server/wrangler.toml b/_examples/d1-blog-server/wrangler.toml index c86da8a..a935a52 100644 --- a/_examples/d1-blog-server/wrangler.toml +++ b/_examples/d1-blog-server/wrangler.toml @@ -1,6 +1,6 @@ name = "d1-blog-server" main = "./build/worker.mjs" -compatibility_date = "2023-01-09" +compatibility_date = "2024-04-15" [build] command = "make build" diff --git a/cloudflare/d1/driver.go b/cloudflare/d1/driver.go index c67e7af..12a417d 100644 --- a/cloudflare/d1/driver.go +++ b/cloudflare/d1/driver.go @@ -1,9 +1,9 @@ package d1 import ( + "context" "database/sql" "database/sql/driver" - "errors" ) func init() { @@ -16,6 +16,10 @@ var ( _ driver.Driver = (*Driver)(nil) ) -func (d *Driver) Open(string) (driver.Conn, error) { - return nil, errors.New("d1: Open is not supported. use d1.OpenConnector and sql.OpenDB instead") +func (d *Driver) Open(name string) (driver.Conn, error) { + connector, err := OpenConnector(name) + if err != nil { + return nil, err + } + return connector.Connect(context.Background()) }