mirror of
https://github.com/rjNemo/go-wiki
synced 2026-06-06 02:36:40 +00:00
views package, add, update in userStore, user model rules, add todo.md
This commit is contained in:
parent
9044e6ed21
commit
ffa87e8131
17 changed files with 202 additions and 128 deletions
3
TODO.md
Normal file
3
TODO.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# TO DO
|
||||
|
||||
- [x] The mail field is case sensitive. Convert mail to lowercase before they are sent to InsertUser
|
||||
|
|
@ -2,18 +2,15 @@ package controller
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"regexp"
|
||||
|
||||
"github.com/rjNemo/go-wiki/model"
|
||||
"github.com/rjNemo/go-wiki/service"
|
||||
"github.com/rjNemo/go-wiki/settings"
|
||||
"github.com/rjNemo/go-wiki/views"
|
||||
)
|
||||
|
||||
// func ParseTemplates() *template.Template {
|
||||
// return template.Must(template.ParseFiles("templates/edit.html", "templates/view.html")) // add slice of fileNAmes
|
||||
// }
|
||||
var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")
|
||||
|
||||
// Router dispatch the request to the corresponding route handlers.
|
||||
func Router() {
|
||||
|
|
@ -27,7 +24,7 @@ func Router() {
|
|||
}
|
||||
|
||||
func homeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
renderTemplate(w, "home", nil)
|
||||
views.Template(w, "home", nil)
|
||||
}
|
||||
|
||||
func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||
|
|
@ -36,7 +33,7 @@ func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
|
|||
http.Redirect(w, r, "/edit/"+title, http.StatusFound)
|
||||
return
|
||||
}
|
||||
renderTemplate(w, "view", p)
|
||||
views.Template(w, "view", p)
|
||||
}
|
||||
|
||||
func editHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||
|
|
@ -44,7 +41,7 @@ func editHandler(w http.ResponseWriter, r *http.Request, title string) {
|
|||
if err != nil {
|
||||
p = model.NewPage(title, nil)
|
||||
}
|
||||
renderTemplate(w, "edit", p)
|
||||
views.Template(w, "edit", p)
|
||||
}
|
||||
|
||||
func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||
|
|
@ -56,7 +53,7 @@ func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
|
|||
}
|
||||
|
||||
func contactHandler(w http.ResponseWriter, r *http.Request) {
|
||||
renderTemplate(w, "contact", nil)
|
||||
views.Template(w, "contact", nil)
|
||||
}
|
||||
|
||||
func postContactHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -65,27 +62,13 @@ func postContactHandler(w http.ResponseWriter, r *http.Request) {
|
|||
mail := parseContactForm(r)
|
||||
mail.Send()
|
||||
fmt.Println(mail)
|
||||
renderTemplate(w, "contact_sent", nil)
|
||||
views.Template(w, "contact_sent", nil)
|
||||
}
|
||||
|
||||
func parseContactForm(r *http.Request) service.Mail {
|
||||
return service.NewMail(r.PostFormValue("email"), r.PostFormValue("message"))
|
||||
}
|
||||
|
||||
// var templates = template.Must(template.ParseFiles("templates/edit.html", "templates/view.html")) // add slice of fileNAmes
|
||||
|
||||
func renderTemplate(w http.ResponseWriter, tmpl string, p *model.Page) {
|
||||
// err := templates.ExecuteTemplate(w, "templates/"+tmpl+".html", p)
|
||||
t, err := template.ParseFiles(getTmplName("base"), getTmplName(tmpl))
|
||||
checkError(err, w)
|
||||
err = t.Execute(w, p)
|
||||
checkError(err, w)
|
||||
}
|
||||
|
||||
func getTmplName(tmpl string) string {
|
||||
return settings.TmplDir + tmpl + ".html"
|
||||
}
|
||||
|
||||
func checkError(err error, w http.ResponseWriter) {
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
|
|
@ -93,8 +76,6 @@ func checkError(err error, w http.ResponseWriter) {
|
|||
}
|
||||
}
|
||||
|
||||
var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")
|
||||
|
||||
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
m := validPath.FindStringSubmatch(r.URL.Path)
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
package data
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
|
||||
_ "github.com/lib/pq" // postgresql database package
|
||||
"github.com/rjNemo/go-wiki/model"
|
||||
"github.com/rjNemo/go-wiki/settings"
|
||||
)
|
||||
|
||||
// Connect read the connection parameters to establish a connection to the
|
||||
// database.
|
||||
func Connect() {
|
||||
log.Print("Inside connect func")
|
||||
connStr := settings.ConnStr
|
||||
db, err := sql.Open("postgres", connStr)
|
||||
log.Print("opened connect")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
log.Print("try to ping")
|
||||
err = db.Ping()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Database successfully connected!")
|
||||
|
||||
createTable(db)
|
||||
u := model.TestUser()
|
||||
insertUser(db, u)
|
||||
log.Print(u)
|
||||
}
|
||||
|
||||
func sqlExec(db *sql.DB, s string) {
|
||||
if _, err := db.Exec(s); err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
log.Printf("Command successfully executed!: %s", s)
|
||||
}
|
||||
|
||||
func createTable(db *sql.DB) {
|
||||
sqlExec(db, QueryCreateTable)
|
||||
log.Print("Table successfully created!")
|
||||
}
|
||||
|
||||
func insertUser(db *sql.DB, u model.User) {
|
||||
id := 0
|
||||
err := db.QueryRow(QueryInsertUser, u.Age(), u.Email(), u.FirstName(), u.LastName()).Scan(&id)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// u.SetID(id)
|
||||
log.Println("New User ID is:", id)
|
||||
}
|
||||
|
||||
func insertUsers(db *sql.DB) {
|
||||
query := `
|
||||
INSERT INTO users (age, email, first_name, last_name)
|
||||
VALUES ($1, $2, $3, $4)`
|
||||
|
||||
_, err := db.Exec(query, 32, "ruidy.nemausat@gmail.com", "Ruidy", "Nemausat")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
59
data/psql.go
Normal file
59
data/psql.go
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
package data
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
|
||||
_ "github.com/lib/pq" // postgresql database package
|
||||
"github.com/rjNemo/go-wiki/model"
|
||||
"github.com/rjNemo/go-wiki/settings"
|
||||
)
|
||||
|
||||
// UsePSQL read the connection parameters to establish a connection to the
|
||||
// database.
|
||||
func UsePSQL() {
|
||||
connStr := settings.ConnStr
|
||||
db, err := sql.Open("postgres", connStr)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
err = db.Ping()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Database successfully connected!")
|
||||
|
||||
createUserTable(db)
|
||||
store := NewUserStore(db)
|
||||
// u := model.TestUser()
|
||||
// store.Add(u)
|
||||
// log.Print(u)
|
||||
u1 := model.NewUser(3, 19, "paul", "newman", "PdsN@FDKML.COM")
|
||||
store.Update(16, u1)
|
||||
}
|
||||
|
||||
func sqlExec(db *sql.DB, s string) {
|
||||
if _, err := db.Exec(s); err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
log.Printf("Command successfully executed!: %s", s)
|
||||
}
|
||||
|
||||
func createUserTable(db *sql.DB) {
|
||||
sqlExec(db, QueryCreateTable)
|
||||
log.Print("Table successfully created!")
|
||||
}
|
||||
|
||||
// Store interface defines the methods any store must satisfy
|
||||
type Store interface {
|
||||
CreateTable()
|
||||
Add(i interface{})
|
||||
Get()
|
||||
Find(id int)
|
||||
Update(id int, i interface{})
|
||||
Delete(id int)
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package data
|
||||
|
||||
const (
|
||||
// QueryCreateTable is the SQL command used to create the users table if it
|
||||
// not exists.
|
||||
QueryCreateTable = `
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
age INT,
|
||||
first_name TEXT,
|
||||
last_name TEXT,
|
||||
email TEXT UNIQUE NOT NULL)
|
||||
`
|
||||
// QueryInsertUser is the SQL command used to insert a user in the table.
|
||||
// Returning the new ID.
|
||||
QueryInsertUser = `
|
||||
INSERT INTO users (age, email, first_name, last_name)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id
|
||||
`
|
||||
)
|
||||
34
data/userQueries.go
Normal file
34
data/userQueries.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package data
|
||||
|
||||
const (
|
||||
// QueryCreateTable is the SQL command used to create the users table if it
|
||||
// not exists.
|
||||
QueryCreateTable = `
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
age INT,
|
||||
first_name TEXT,
|
||||
last_name TEXT,
|
||||
email TEXT UNIQUE NOT NULL)
|
||||
`
|
||||
// QueryInsert is the SQL command used to insert a user in the table.
|
||||
// Returning the new ID.
|
||||
QueryInsert = `
|
||||
INSERT INTO users (age, email, first_name, last_name)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id
|
||||
`
|
||||
|
||||
// QueryUpdate is the SQL command used to update a user in the database.
|
||||
QueryUpdate = `
|
||||
UPDATE users
|
||||
SET age = $2, email = $3, first_name = $4, last_name = $5
|
||||
WHERE id = $1;
|
||||
`
|
||||
|
||||
// QueryDelete is the SQL command used to delete a user from the database.
|
||||
QueryDelete = `
|
||||
DELETE FROM users
|
||||
WHERE id = $1;
|
||||
`
|
||||
)
|
||||
58
data/userStore.go
Normal file
58
data/userStore.go
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package data
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
|
||||
"github.com/rjNemo/go-wiki/model"
|
||||
)
|
||||
|
||||
// UserStore is used to perform user-related CRUD operations on the DB
|
||||
type UserStore struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// NewUserStore constructs a UserStore connected to the database.
|
||||
func NewUserStore(db *sql.DB) UserStore {
|
||||
return UserStore{db: db}
|
||||
}
|
||||
|
||||
// Add inserts a user in the database.
|
||||
func (us UserStore) Add(u model.User) {
|
||||
id := 0
|
||||
err := us.db.QueryRow(QueryInsert, u.Age(), u.Email(), u.FirstName(), u.LastName()).Scan(&id)
|
||||
if err != nil {
|
||||
log.Fatal(err) // too severe
|
||||
}
|
||||
log.Println("New User ID is:", id)
|
||||
}
|
||||
|
||||
// Update edits user identified by 'id' in the database
|
||||
func (us UserStore) Update(id int, u model.User) {
|
||||
res, err := us.db.Exec(QueryUpdate, id, u.Age(), u.Email(), u.FirstName(), u.LastName())
|
||||
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 user identified by 'id' from the database
|
||||
func (us UserStore) 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("Update failed") // too severe
|
||||
}
|
||||
2
main.go
2
main.go
|
|
@ -8,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
data.Connect()
|
||||
data.UsePSQL()
|
||||
// startServer(settings.Port, controller.Router)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package model
|
||||
|
||||
import "strings"
|
||||
|
||||
// User represent a go-wiki user. It encapsulate its unique identifier, first and
|
||||
// last names, email and age
|
||||
type User struct {
|
||||
|
|
@ -16,7 +18,7 @@ func TestUser() User {
|
|||
id: 42,
|
||||
firstName: "John",
|
||||
lastName: "Doe",
|
||||
email: "jddd@mail.com",
|
||||
email: "jddddSZ@mail.com",
|
||||
age: 42,
|
||||
}
|
||||
}
|
||||
|
|
@ -25,9 +27,9 @@ func TestUser() User {
|
|||
func NewUser(id, age int, first, last, email string) User {
|
||||
return User{
|
||||
id: id,
|
||||
firstName: first,
|
||||
lastName: last,
|
||||
email: email,
|
||||
firstName: strings.Title(first),
|
||||
lastName: strings.Title(last),
|
||||
email: strings.ToLower(email),
|
||||
age: age,
|
||||
}
|
||||
}
|
||||
|
|
@ -37,11 +39,6 @@ func (u User) ID() int {
|
|||
return u.id
|
||||
}
|
||||
|
||||
// // SetID is a setter
|
||||
// func (u *User) SetID(id int) {
|
||||
// u.id = id
|
||||
// }
|
||||
|
||||
// FirstName is a getter
|
||||
func (u User) FirstName() string {
|
||||
return u.firstName
|
||||
|
|
@ -57,7 +54,12 @@ func (u User) Email() string {
|
|||
return u.email
|
||||
}
|
||||
|
||||
// FirstName is a getter
|
||||
// SetEmail is a setter
|
||||
func (u *User) SetEmail(email string) {
|
||||
u.email = strings.ToLower(email)
|
||||
}
|
||||
|
||||
// Age is a getter
|
||||
func (u User) Age() int {
|
||||
return u.age
|
||||
}
|
||||
|
|
|
|||
27
views/render.go
Normal file
27
views/render.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package views
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"text/template"
|
||||
|
||||
"github.com/rjNemo/go-wiki/model"
|
||||
"github.com/rjNemo/go-wiki/settings"
|
||||
)
|
||||
|
||||
func Template(w http.ResponseWriter, tmpl string, p *model.Page) {
|
||||
// err := templates.ExecuteTemplate(w, "templates/"+tmpl+".html", p)
|
||||
t, err := template.ParseFiles(getTmplName("base"), getTmplName(tmpl))
|
||||
checkError(err, w)
|
||||
err = t.Execute(w, p)
|
||||
checkError(err, w)
|
||||
}
|
||||
|
||||
func getTmplName(tmpl string) string {
|
||||
return settings.TmplDir + tmpl + ".html"
|
||||
}
|
||||
|
||||
// var templates = template.Must(template.ParseFiles("templates/edit.html", "templates/view.html")) // add slice of fileNAmes
|
||||
|
||||
// func ParseTemplates() *template.Template {
|
||||
// return template.Must(template.ParseFiles("templates/edit.html", "templates/view.html")) // add slice of fileNAmes
|
||||
// }
|
||||
1
views/templates/love.html
Normal file
1
views/templates/love.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<h1>Hi there, I love {{.Title}}</h1>
|
||||
Loading…
Reference in a new issue