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
type PageHandler struct {
Pages data.PageStore
Ctx data.Context
} //and add each actual handler as a method
func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
p, err := models.LoadPage(title)
// p, err := ph.Pages.Get(1)
// func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
func (ph PageHandler) view(w http.ResponseWriter, r *http.Request, title string) {
// p, err := models.LoadPage(title)
p, err := ph.Ctx.Pages.Get(title)
if err != nil {
http.Redirect(w, r, "/edit/"+title, http.StatusFound)
return
@ -23,18 +24,26 @@ func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
views.Template(w, "view", p)
}
func editHandler(w http.ResponseWriter, r *http.Request, title string) {
p, err := models.LoadPage(title)
func (ph PageHandler) edit(w http.ResponseWriter, r *http.Request, title string) {
// p, err := models.LoadPage(title)
p, err := ph.Ctx.Pages.Get(title)
if err != nil {
p = models.NewPage(0, title, nil)
p = *models.NewPage(0, title, nil)
}
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")
p := models.NewPage(0, title, []byte(body))
err := p.Save()
checkError(err, w)
// err := p.Save()
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)
}

View file

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

View file

@ -5,31 +5,29 @@ import (
"log"
_ "github.com/lib/pq" // postgresql database package
"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.
func UsePSQL() *sql.DB {
connStr := settings.ConnStr
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
defer db.Close()
func NewDB(connection string) (*sql.DB, error) {
err = db.Ping()
db, err := sql.Open("postgres", connection)
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!")
return db, nil
// store := NewUserStore(db)
// store.CreateTable()
return db
// u := models.TestUser()
// store.Add(u)
// log.Print(u)
@ -41,6 +39,19 @@ func UsePSQL() *sql.DB {
// 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
type Store interface {
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.
@ -10,4 +10,5 @@ Have fun
❤️
❤️
❤️

View file

@ -6,13 +6,13 @@ const (
CreateTablePages = `
CREATE TABLE IF NOT EXISTS pages (
id SERIAL PRIMARY KEY,
title TEXT UNIQUE NOT NULL
title TEXT UNIQUE NOT NULL,
body TEXT)
`
// GetPage is the SQL command used to retrieve a user from the table
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.
@ -47,4 +47,9 @@ const (
WHERE id = $1
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
func (us PageStore) Get(uid int) (models.Page, error) {
func (us PageStore) Get(t string) (models.Page, error) {
var id int
var title string
var body []byte
row := us.db.QueryRow(QueryGet, uid)
row := us.db.QueryRow(GetPage, t)
switch err := row.Scan(&id, &title, &body); err {
case sql.ErrNoRows:
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.
func (us PageStore) Add(u models.Page) {
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 {
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
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 {
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
// func (us PageStore) Find(k interface{}, v interface{}) ([]models.Page, error) {
// var id, title int

29
main.go
View file

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

View file

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