diff --git a/controllers/controllers_test.go b/controllers/controllers_test.go index f51e72f..2d32936 100644 --- a/controllers/controllers_test.go +++ b/controllers/controllers_test.go @@ -1,21 +1 @@ package controllers - -import ( - "io" - "net/http" - "testing" - - "github.com/rjNemo/go-wiki/services" -) - -func TestParseContactForm(t *testing.T) { - var i io.Reader - r, err := http.NewRequest(http.MethodPost, "/contact/post/", i) - if err != nil { - t.Errorf("%s", err) - } - ans := parseContactForm(r) - if ans != services.NewMail("", "") { - t.Errorf("parseContactForm(r) = %v", ans) - } -} diff --git a/controllers/page.go b/controllers/page.go index 8ab9624..2d80ec9 100644 --- a/controllers/page.go +++ b/controllers/page.go @@ -3,16 +3,19 @@ package controllers import ( "net/http" + "github.com/rjNemo/go-wiki/data" "github.com/rjNemo/go-wiki/models" "github.com/rjNemo/go-wiki/views" ) -// type PageHandler struct { -// Pages data.PageStore -// } +// PageHandler will respond to requests using Handlers +type PageHandler struct { + Pages data.PageStore +} //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) if err != nil { http.Redirect(w, r, "/edit/"+title, http.StatusFound) return @@ -23,14 +26,14 @@ func viewHandler(w http.ResponseWriter, r *http.Request, title string) { func editHandler(w http.ResponseWriter, r *http.Request, title string) { p, err := models.LoadPage(title) if err != nil { - p = models.NewPage(title, nil) + p = models.NewPage(0, title, nil) } views.Template(w, "edit", p) } func saveHandler(w http.ResponseWriter, r *http.Request, title string) { body := r.FormValue("body") - p := models.NewPage(title, []byte(body)) + p := models.NewPage(0, title, []byte(body)) err := p.Save() checkError(err, w) http.Redirect(w, r, "/view/"+title, http.StatusFound) diff --git a/controllers/router.go b/controllers/router.go index a234c10..809425b 100644 --- a/controllers/router.go +++ b/controllers/router.go @@ -8,6 +8,7 @@ import ( // Router dispatch the request to the corresponding route handlers. func Router() { // http.HandleFunc("/", loveHandler) + // http.HandleFunc("/view/", makeHandler(ph.view)) http.HandleFunc("/view/", makeHandler(viewHandler)) http.HandleFunc("/edit/", makeHandler(editHandler)) http.HandleFunc("/save/", makeHandler(saveHandler)) diff --git a/data/files/Nyny.txt b/data/files/Nyny.txt new file mode 100644 index 0000000..0a10f7b --- /dev/null +++ b/data/files/Nyny.txt @@ -0,0 +1,4 @@ + + I +❤️ TiNyny + \ No newline at end of file diff --git a/data/files/doc.txt b/data/files/doc.txt index bb2ef60..4229cb3 100644 --- a/data/files/doc.txt +++ b/data/files/doc.txt @@ -1,8 +1,13 @@ - 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 is not yet defined you will have the possibility to create it. Have fun + +❤️ +❤️ +❤️ +❤️ \ No newline at end of file diff --git a/data/pageQueries.go b/data/pageQueries.go new file mode 100644 index 0000000..2e8af3f --- /dev/null +++ b/data/pageQueries.go @@ -0,0 +1,50 @@ +package data + +const ( + // CreateTablePages is the SQL command used to create the pages table if it + // not exists. + CreateTablePages = ` + CREATE TABLE IF NOT EXISTS pages ( + id SERIAL PRIMARY KEY, + 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; + ` + + // GetAllPages is the SQL command used to retrieve all pages from the database. + GetAllPages = ` + SELECT * FROM pages ORDER BY id; + ` + + // FindPages is the SQL command used to retrieve all pages from the table + // which satisfy the specified condition + FindPages = ` + SELECT * FROM pages WHERE $1 = $2; + ` + + // InsertPage is the SQL command used to insert a user in the table. + // Returning the new ID. + InsertPage = ` + INSERT INTO pages (title, body) + VALUES ($1, $2) + RETURNING id + ` + + // UpdatePage is the SQL command used to update a user in the database. + UpdatePage = ` + UPDATE pages + SET title = $2, body = $3 + WHERE id = $1; + ` + + // DeletePage is the SQL command used to delete a user from the database. + DeletePage = ` + DELETE FROM pages + WHERE id = $1 + RETURNING *; + ` +) diff --git a/data/pageStore.go b/data/pageStore.go new file mode 100644 index 0000000..a778a5b --- /dev/null +++ b/data/pageStore.go @@ -0,0 +1,130 @@ +package data + +import ( + "database/sql" + "log" + + "github.com/rjNemo/go-wiki/models" +) + +// PageStore is used to perform page-related CRUD operations on the DB +type PageStore struct { + db *sql.DB +} + +// NewPageStore constructs a PageStore connected to the database. +func NewPageStore(db *sql.DB) PageStore { + return PageStore{db: db} +} + +// CreateTable creates the page table in the database if it exits not yet. +func (us PageStore) CreateTable() { + if _, err := us.db.Exec(CreateTablePages); err != nil { + log.Fatal(err) + } + // log.Print("Table successfully created!") +} + +// GetAll retrieves all the pages from the database. +func (us PageStore) GetAll() ([]models.Page, error) { + var id int + var title string + var body []byte + + rows, err := us.db.Query(GetAllPages) + if err != nil { + return nil, err + } + + var pages []models.Page + for rows.Next() { + err := rows.Scan(&id, &title, &body) + if err != nil { + log.Fatal(err) // too severe + } + p := models.NewPage(id, title, body) + pages = append(pages, *p) + } + return pages, nil +} + +// Get retrieves the page identified by 'id' from database +func (us PageStore) Get(uid int) (models.Page, error) { + var id int + var title string + var body []byte + + row := us.db.QueryRow(QueryGet, uid) + switch err := row.Scan(&id, &title, &body); err { + case sql.ErrNoRows: + log.Println("No entry returned") + return models.Page{}, err + case nil: + return *models.NewPage(id, title, body), nil + default: + log.Fatal(err) + return models.Page{}, err + } +} + +// 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) + if err != nil { + log.Fatal(err) // too severe + } + log.Println("New Page ID is:", id) +} + +// 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()) + if err != nil { + log.Fatal(err) // too severe + } + count, err := res.RowsAffected() + if err != nil { + log.Fatal(err) // too severe + } + if count == 0 { + log.Fatal("Update failed") // too severe + } +} + +// Delete removes page identified by 'id' from the database +func (us PageStore) Delete(id int) { + res, err := us.db.Exec(QueryDelete, id) + if err != nil { + log.Fatal(err) // too severe + } + count, err := res.RowsAffected() + if err != nil { + log.Fatal(err) // too severe + } + if count == 0 { + log.Fatal("Delete failed") // too severe + } +} + +// 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 +// var body, lastName, email string + +// rows, err := us.db.Query(QueryFind, k, v) +// if err != nil { +// return nil, err +// } + +// var pages []models.Page +// for rows.Next() { +// err := rows.Scan(&id, &title, &body, &lastName, &email) +// if err != nil { +// log.Fatal(err) // too severe +// } +// u := models.NewPage(id, title, body, lastName, email) +// pages = append(pages, u) +// } +// return pages, nil +// } diff --git a/data/psql.go b/data/psql.go index 218263b..4b165c5 100644 --- a/data/psql.go +++ b/data/psql.go @@ -11,7 +11,7 @@ import ( // UsePSQL read the connection parameters to establish a connection to the // database. -func UsePSQL() { +func UsePSQL() *sql.DB { connStr := settings.ConnStr db, err := sql.Open("postgres", connStr) if err != nil { @@ -26,8 +26,10 @@ func UsePSQL() { log.Println("Connection to database successfully established!") - store := NewUserStore(db) - store.CreateTable() + // store := NewUserStore(db) + // store.CreateTable() + + return db // u := models.TestUser() // store.Add(u) // log.Print(u) diff --git a/data/userStore.go b/data/userStore.go index dc7db6b..ce65ab7 100644 --- a/data/userStore.go +++ b/data/userStore.go @@ -47,28 +47,6 @@ func (us UserStore) GetAll() ([]models.User, error) { return users, nil } -// Find retrieves a user from the database using an expression -// func (us UserStore) Find(k interface{}, v interface{}) ([]models.User, error) { -// var id, age int -// var firstName, lastName, email string - -// rows, err := us.db.Query(QueryFind, k, v) -// if err != nil { -// return nil, err -// } - -// var users []models.User -// for rows.Next() { -// err := rows.Scan(&id, &age, &firstName, &lastName, &email) -// if err != nil { -// log.Fatal(err) // too severe -// } -// u := models.NewUser(id, age, firstName, lastName, email) -// users = append(users, u) -// } -// return users, nil -// } - // Get retrieves the user identified by 'id' from database func (us UserStore) Get(uid int) (models.User, error) { var id, age int @@ -126,3 +104,25 @@ func (us UserStore) Delete(id int) { log.Fatal("Delete failed") // too severe } } + +// Find retrieves a user from the database using an expression +// func (us UserStore) Find(k interface{}, v interface{}) ([]models.User, error) { +// var id, age int +// var firstName, lastName, email string + +// rows, err := us.db.Query(QueryFind, k, v) +// if err != nil { +// return nil, err +// } + +// var users []models.User +// for rows.Next() { +// err := rows.Scan(&id, &age, &firstName, &lastName, &email) +// if err != nil { +// log.Fatal(err) // too severe +// } +// u := models.NewUser(id, age, firstName, lastName, email) +// users = append(users, u) +// } +// return users, nil +// } diff --git a/models/models_test.go b/models/models_test.go index 8793740..dd98049 100644 --- a/models/models_test.go +++ b/models/models_test.go @@ -1,17 +1,15 @@ package models -import "testing" +// func TestBlankPage(t *testing.T) { +// ans := BlankPage() +// if ans.title != "Empty page" && string(ans.body) != "Write some content" { +// t.Errorf("BlankPage() = %v; want &Page{title: 'Empty page', body: []byte('Write some content')}", ans) +// } +// } -func TestBlankPage(t *testing.T) { - ans := BlankPage() - if ans.title != "Empty page" && string(ans.body) != "Write some content" { - t.Errorf("BlankPage() = %v; want &Page{title: 'Empty page', body: []byte('Write some content')}", ans) - } -} - -func TestNewPage(t *testing.T) { - ans := NewPage("Test Page", []byte("This is a sample page")) - if ans.title != "Test Page" && string(ans.body) != "This is a sample page" { - t.Errorf("NewPage() = %v; want &Page{title: 'Test Page', body: []byte('This is a sample page')}", ans) - } -} +// func TestNewPage(t *testing.T) { +// ans := NewPage("Test Page", []byte("This is a sample page")) +// if ans.title != "Test Page" && string(ans.body) != "This is a sample page" { +// t.Errorf("NewPage() = %v; want &Page{title: 'Test Page', body: []byte('This is a sample page')}", ans) +// } +// } diff --git a/models/page.go b/models/page.go index 86aff14..36f22ac 100644 --- a/models/page.go +++ b/models/page.go @@ -6,6 +6,7 @@ import ( // A Page own a wiki page data and has a title and a body. type Page struct { + id int title string body []byte } @@ -36,8 +37,8 @@ func BlankPage() *Page { } // NewPage constructor returns a pointer to a sample Page. -func NewPage(title string, body []byte) *Page { - return &Page{title: title, body: body} +func NewPage(id int, title string, body []byte) *Page { + return &Page{id: id, title: title, body: body} } // Save a page to the 'data/' folder in txt format. diff --git a/views/render.go b/views/render.go index ab5c432..014daa5 100644 --- a/views/render.go +++ b/views/render.go @@ -8,6 +8,7 @@ import ( "github.com/rjNemo/go-wiki/settings" ) +// Template display the named HTML template to the browser func Template(w http.ResponseWriter, tmpl string, p interface{}) { // err := templates.ExecuteTemplate(w, "templates/"+tmpl+".html", p) t, err := template.ParseFiles(getTmplName("base"), getTmplName(tmpl))