data: NewDB, NewContext, inject context into handlers, exits method in pagestore

This commit is contained in:
Ruidy Nemausat 2020-03-18 01:08:24 +01:00
parent ebfc92110b
commit f77bc38da5
8 changed files with 95 additions and 42 deletions

View file

@ -10,12 +10,13 @@ import (
// PageHandler will respond to requests using Handlers // PageHandler will respond to requests using Handlers
type PageHandler struct { type PageHandler struct {
Pages data.PageStore Ctx data.Context
} //and add each actual handler as a method } //and add each actual handler as a method
func viewHandler(w http.ResponseWriter, r *http.Request, title string) { // func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
p, err := models.LoadPage(title) func (ph PageHandler) view(w http.ResponseWriter, r *http.Request, title string) {
// p, err := ph.Pages.Get(1) // p, err := models.LoadPage(title)
p, err := ph.Ctx.Pages.Get(title)
if err != nil { if err != nil {
http.Redirect(w, r, "/edit/"+title, http.StatusFound) http.Redirect(w, r, "/edit/"+title, http.StatusFound)
return return
@ -23,18 +24,26 @@ func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
views.Template(w, "view", p) views.Template(w, "view", p)
} }
func editHandler(w http.ResponseWriter, r *http.Request, title string) { func (ph PageHandler) edit(w http.ResponseWriter, r *http.Request, title string) {
p, err := models.LoadPage(title) // p, err := models.LoadPage(title)
p, err := ph.Ctx.Pages.Get(title)
if err != nil { if err != nil {
p = models.NewPage(0, title, nil) p = *models.NewPage(0, title, nil)
} }
views.Template(w, "edit", p) views.Template(w, "edit", p)
} }
func saveHandler(w http.ResponseWriter, r *http.Request, title string) { func (ph PageHandler) save(w http.ResponseWriter, r *http.Request, title string) {
body := r.FormValue("body") body := r.FormValue("body")
p := models.NewPage(0, title, []byte(body)) p := models.NewPage(0, title, []byte(body))
err := p.Save() // err := p.Save()
checkError(err, w)
if !ph.Ctx.Pages.Exists(title) {
ph.Ctx.Pages.Add(*p)
} else {
ph.Ctx.Pages.Update(p.ID(), *p)
}
// checkError(err, w)
http.Redirect(w, r, "/view/"+title, http.StatusFound) http.Redirect(w, r, "/view/"+title, http.StatusFound)
} }

View file

@ -6,12 +6,11 @@ import (
) )
// Router dispatch the request to the corresponding route handlers. // Router dispatch the request to the corresponding route handlers.
func Router() { func Router(ph PageHandler) {
// http.HandleFunc("/", loveHandler) // http.HandleFunc("/", loveHandler)
// http.HandleFunc("/view/", makeHandler(ph.view)) http.HandleFunc("/view/", makeHandler(ph.view))
http.HandleFunc("/view/", makeHandler(viewHandler)) http.HandleFunc("/edit/", makeHandler(ph.edit))
http.HandleFunc("/edit/", makeHandler(editHandler)) http.HandleFunc("/save/", makeHandler(ph.save))
http.HandleFunc("/save/", makeHandler(saveHandler))
http.HandleFunc("/contact/", contactHandler) http.HandleFunc("/contact/", contactHandler)
http.HandleFunc("/", homeHandler) http.HandleFunc("/", homeHandler)
} }

View file

@ -5,31 +5,29 @@ import (
"log" "log"
_ "github.com/lib/pq" // postgresql database package _ "github.com/lib/pq" // postgresql database package
"github.com/rjNemo/go-wiki/models" "github.com/rjNemo/go-wiki/models"
"github.com/rjNemo/go-wiki/settings"
) )
// UsePSQL read the connection parameters to establish a connection to the // NewDB read the connection parameters to establish a connection to the
// database. // database.
func UsePSQL() *sql.DB { func NewDB(connection string) (*sql.DB, error) {
connStr := settings.ConnStr
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Ping() db, err := sql.Open("postgres", connection)
if err != nil { if err != nil {
log.Fatal(err) return nil, err
}
if err = db.Ping(); err != nil {
return nil, err
} }
log.Println("Connection to database successfully established!") log.Println("Connection to database successfully established!")
return db, nil
// store := NewUserStore(db) // store := NewUserStore(db)
// store.CreateTable() // store.CreateTable()
return db
// u := models.TestUser() // u := models.TestUser()
// store.Add(u) // store.Add(u)
// log.Print(u) // log.Print(u)
@ -41,6 +39,19 @@ func UsePSQL() *sql.DB {
// log.Println(store.Find("first_name", "John")) // log.Println(store.Find("first_name", "John"))
} }
// Context registers the application data stores
type Context struct {
Pages PageStore
Users UserStore
}
// NewContext returns a context instance
func NewContext(db *sql.DB) Context {
pageStore := NewPageStore(db)
userStore := NewUserStore(db)
return Context{Pages: pageStore, Users: userStore}
}
// Store interface defines the methods any store must satisfy // Store interface defines the methods any store must satisfy
type Store interface { type Store interface {
CreateTable() CreateTable()

View file

@ -1,4 +1,4 @@
Type a term in the search bar. Type a term in the search bar.
If it already exist you will reach this page. If it already exist you will reach this page.
@ -11,3 +11,4 @@ Have fun
❤️ ❤️
❤️ ❤️

View file

@ -6,13 +6,13 @@ const (
CreateTablePages = ` CreateTablePages = `
CREATE TABLE IF NOT EXISTS pages ( CREATE TABLE IF NOT EXISTS pages (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
title TEXT UNIQUE NOT NULL title TEXT UNIQUE NOT NULL,
body TEXT) body TEXT)
` `
// GetPage is the SQL command used to retrieve a user from the table // GetPage is the SQL command used to retrieve a user from the table
GetPage = ` GetPage = `
SELECT * FROM pages WHERE id = $1; SELECT * FROM pages WHERE title = $1;
` `
// GetAllPages is the SQL command used to retrieve all pages from the database. // GetAllPages is the SQL command used to retrieve all pages from the database.
@ -47,4 +47,9 @@ const (
WHERE id = $1 WHERE id = $1
RETURNING *; RETURNING *;
` `
// ExistsPage is the SQL command used to check whether a page from the database.
ExistsPage = `
SELECT EXISTS(SELECT * FROM pages WHERE title = $1)
`
) )

View file

@ -49,12 +49,12 @@ func (us PageStore) GetAll() ([]models.Page, error) {
} }
// Get retrieves the page identified by 'id' from database // Get retrieves the page identified by 'id' from database
func (us PageStore) Get(uid int) (models.Page, error) { func (us PageStore) Get(t string) (models.Page, error) {
var id int var id int
var title string var title string
var body []byte var body []byte
row := us.db.QueryRow(QueryGet, uid) row := us.db.QueryRow(GetPage, t)
switch err := row.Scan(&id, &title, &body); err { switch err := row.Scan(&id, &title, &body); err {
case sql.ErrNoRows: case sql.ErrNoRows:
log.Println("No entry returned") log.Println("No entry returned")
@ -70,7 +70,7 @@ func (us PageStore) Get(uid int) (models.Page, error) {
// Add inserts a page in the database. // Add inserts a page in the database.
func (us PageStore) Add(u models.Page) { func (us PageStore) Add(u models.Page) {
id := 0 id := 0
err := us.db.QueryRow(QueryInsert, u.Title(), u.Body()).Scan(&id) err := us.db.QueryRow(InsertPage, u.Title(), u.Body()).Scan(&id)
if err != nil { if err != nil {
log.Fatal(err) // too severe log.Fatal(err) // too severe
} }
@ -79,7 +79,7 @@ func (us PageStore) Add(u models.Page) {
// Update edits page identified by 'id' in the database // Update edits page identified by 'id' in the database
func (us PageStore) Update(id int, u models.Page) { func (us PageStore) Update(id int, u models.Page) {
res, err := us.db.Exec(QueryUpdate, id, u.Title(), u.Body()) res, err := us.db.Exec(UpdatePage, id, u.Title(), u.Body())
if err != nil { if err != nil {
log.Fatal(err) // too severe log.Fatal(err) // too severe
} }
@ -107,6 +107,16 @@ func (us PageStore) Delete(id int) {
} }
} }
func (ps PageStore) Exists(title string) bool {
var e bool
err := ps.db.QueryRow(ExistsPage, title).Scan(&e)
log.Println("e:", e)
if err != nil {
log.Fatal(err) // too severe
}
return e //== title
}
// Find retrieves a page from the database using an expression // Find retrieves a page from the database using an expression
// func (us PageStore) Find(k interface{}, v interface{}) ([]models.Page, error) { // func (us PageStore) Find(k interface{}, v interface{}) ([]models.Page, error) {
// var id, title int // var id, title int

29
main.go
View file

@ -10,15 +10,28 @@ import (
) )
func main() { func main() {
data.UsePSQL() // connect to db
startServer(settings.Port, controllers.Router) db, err := data.NewDB(settings.ConnStr)
} if err != nil {
log.Fatal(err)
}
func startServer(p string, r func()) { // register store and inject them in handlers
log.Printf("Start Go-wiki server on http://localhost:%s", p) ctx := data.NewContext(db)
port := ":" + p ctx.Pages.CreateTable()
r() // ctx.Users.CreateTable()
ph := controllers.PageHandler{Ctx: ctx}
// uh := controllers.UserHandler{Users: UserStore}
// startServer(, controllers.Router)
log.Printf("Start Go-wiki server on http://localhost:%s", settings.Port)
port := ":" + settings.Port
controllers.Router(ph)
log.Fatal(http.ListenAndServe(port, nil)) log.Fatal(http.ListenAndServe(port, nil))
} }
// appBuilder // func startServer(p string, r func()) {
// }
// // appBuilder

View file

@ -11,6 +11,11 @@ type Page struct {
body []byte body []byte
} }
// ID exposes Page's title field
func (p Page) ID() int {
return p.id
}
// Title exposes Page's title field // Title exposes Page's title field
func (p Page) Title() string { func (p Page) Title() string {
return p.title return p.title