Add structs and corresponding API routes

This commit is contained in:
nemunaire 2018-06-25 22:20:16 +02:00 committed by Pierre-Olivier Mercier
parent 16d2285ff3
commit 977a75819d
12 changed files with 942 additions and 1 deletions

76
api/check.go Normal file
View File

@ -0,0 +1,76 @@
package api
import (
"encoding/json"
"errors"
"strconv"
"git.nemunai.re/checkhome/struct"
"github.com/julienschmidt/httprouter"
)
func init() {
router.GET("/api/checks/", apiHandler(func (_ httprouter.Params, _ []byte) (interface{}, error) {
return ckh.GetChecks()
}))
router.GET("/api/rooms/:rid/items/:iid/checks/", apiHandler(itemHandler(func (item ckh.Item, _ ckh.Room, _ []byte) (interface{}, error) {
return item.GetChecks()
})))
router.POST("/api/rooms/:rid/items/:iid/checks/", apiHandler(itemHandler(newCheck)))
router.GET("/api/rooms/:rid/items/:iid/checks/:cid", apiHandler(checkHandler(func (check ckh.Check, _ ckh.Item, _ ckh.Room, _ []byte) (interface{}, error) {
return check, nil
})))
router.PUT("/api/rooms/:rid/items/:iid/checks/:cid", apiHandler(checkHandler(updateCheck)))
router.DELETE("/api/rooms/:rid/items/:iid/checks/:cid", apiHandler(checkHandler(func (check ckh.Check, _ ckh.Item, _ ckh.Room, _ []byte) (interface{}, error) {
return check.Delete()
})))
}
func checkHandler(f func(ckh.Check, ckh.Item, ckh.Room, []byte) (interface{}, error)) func(httprouter.Params, []byte) (interface{}, error) {
return func(ps httprouter.Params, body []byte) (interface{}, error) {
return itemHandler(func (item ckh.Item, room ckh.Room, _ []byte) (interface{}, error) {
if cid, err := strconv.ParseInt(string(ps.ByName("cid")), 10, 64); err != nil {
return nil, err
} else if check, err := item.GetCheck(cid); err != nil {
return nil, err
} else {
return f(check, item, room, body)
}
})(ps, body)
}
}
func newCheck(item ckh.Item, _ ckh.Room, body []byte) (interface{}, error) {
var uc ckh.Check
if err := json.Unmarshal(body, &uc); err != nil {
return nil, err
}
if len(uc.Passed) == 0 {
return nil, errors.New("Check's state cannot be empty")
}
return item.NewCheck(ckh.User{}, uc.Passed, uc.Comment)
}
func updateCheck(check ckh.Check, _ ckh.Item, _ ckh.Room, body []byte) (interface{}, error) {
var uc ckh.Check
if err := json.Unmarshal(body, &uc); err != nil {
return nil, err
}
if len(uc.Passed) == 0 {
return nil, errors.New("Check's state cannot be empty")
}
uc.Id = check.Id
if _, err := uc.Update(); err != nil {
return nil, err
} else {
return uc, nil
}
}

83
api/item.go Normal file
View File

@ -0,0 +1,83 @@
package api
import (
"encoding/json"
"errors"
"strconv"
"git.nemunai.re/checkhome/struct"
"github.com/julienschmidt/httprouter"
)
func init() {
router.GET("/api/items/", apiHandler(func (_ httprouter.Params, _ []byte) (interface{}, error) {
return ckh.GetItems()
}))
router.DELETE("/api/items/", apiHandler(func (_ httprouter.Params, _ []byte) (interface{}, error) {
return ckh.ClearItems()
}))
router.GET("/api/rooms/:rid/items/", apiHandler(roomHandler(func (room ckh.Room, _ []byte) (interface{}, error) {
return room.GetItems()
})))
router.POST("/api/rooms/:rid/items/", apiHandler(roomHandler(newItem)))
router.DELETE("/api/rooms/:rid/items/", apiHandler(roomHandler(func (room ckh.Room, _ []byte) (interface{}, error) {
return room.ClearItems()
})))
router.GET("/api/rooms/:rid/items/:iid/", apiHandler(itemHandler(func (item ckh.Item, _ ckh.Room, _ []byte) (interface{}, error) {
return item, nil
})))
router.PUT("/api/rooms/:rid/items/:iid/", apiHandler(itemHandler(updateItem)))
router.DELETE("/api/rooms/:rid/items/:iid/", apiHandler(itemHandler(func (item ckh.Item, _ ckh.Room, _ []byte) (interface{}, error) {
return item.Delete()
})))
}
func itemHandler(f func(ckh.Item, ckh.Room, []byte) (interface{}, error)) func(httprouter.Params, []byte) (interface{}, error) {
return func(ps httprouter.Params, body []byte) (interface{}, error) {
return roomHandler(func (room ckh.Room, _ []byte) (interface{}, error) {
if iid, err := strconv.ParseInt(string(ps.ByName("iid")), 10, 64); err != nil {
return nil, err
} else if item, err := room.GetItem(iid); err != nil {
return nil, err
} else {
return f(item, room, body)
}
})(ps, body)
}
}
func newItem(room ckh.Room, body []byte) (interface{}, error) {
var ui ckh.Item
if err := json.Unmarshal(body, &ui); err != nil {
return nil, err
}
if len(ui.Label) == 0 {
return nil, errors.New("Item's label cannot be empty")
}
return ckh.NewItem(ui.Label, ui.Description, room)
}
func updateItem(item ckh.Item, room ckh.Room, body []byte) (interface{}, error) {
var ui ckh.Item
if err := json.Unmarshal(body, &ui); err != nil {
return nil, err
}
if len(ui.Label) == 0 {
return nil, errors.New("Item's label cannot be empty")
}
ui.Id = item.Id
ui.IdRoom = room.Id
if _, err := ui.Update(); err != nil {
return nil, err
} else {
return ui, nil
}
}

73
api/room.go Normal file
View File

@ -0,0 +1,73 @@
package api
import (
"encoding/json"
"errors"
"strconv"
"git.nemunai.re/checkhome/struct"
"github.com/julienschmidt/httprouter"
)
func init() {
router.GET("/api/rooms/", apiHandler(func (_ httprouter.Params, _ []byte) (interface{}, error) {
return ckh.GetRooms()
}))
router.POST("/api/rooms/", apiHandler(newRoom))
router.DELETE("/api/rooms/", apiHandler(func (_ httprouter.Params, _ []byte) (interface{}, error) {
return ckh.ClearRooms()
}))
router.GET("/api/rooms/:rid", apiHandler(roomHandler(func (room ckh.Room, _ []byte) (interface{}, error) {
return room, nil
})))
router.PUT("/api/rooms/:rid", apiHandler(roomHandler(updateRoom)))
router.DELETE("/api/rooms/:rid", apiHandler(roomHandler(func (room ckh.Room, _ []byte) (interface{}, error) {
return room.Delete()
})))
}
func roomHandler(f func(ckh.Room, []byte) (interface{}, error)) func(httprouter.Params, []byte) (interface{}, error) {
return func(ps httprouter.Params, body []byte) (interface{}, error) {
if rid, err := strconv.ParseInt(string(ps.ByName("rid")), 10, 64); err != nil {
return nil, err
} else if room, err := ckh.GetRoom(rid); err != nil {
return nil, err
} else {
return f(room, body)
}
}
}
func newRoom(_ httprouter.Params, body []byte) (interface{}, error) {
var ur ckh.Room
if err := json.Unmarshal(body, &ur); err != nil {
return nil, err
}
if len(ur.Label) == 0 {
return nil, errors.New("Room's label cannot be empty")
}
return ckh.NewRoom(ur.Label)
}
func updateRoom(room ckh.Room, body []byte) (interface{}, error) {
var ur ckh.Room
if err := json.Unmarshal(body, &ur); err != nil {
return nil, err
}
if len(ur.Label) == 0 {
return nil, errors.New("Room's label cannot be empty")
}
ur.Id = room.Id
if _, err := ur.Update(); err != nil {
return nil, err
} else {
return ur, nil
}
}

73
api/tag.go Normal file
View File

@ -0,0 +1,73 @@
package api
import (
"encoding/json"
"errors"
"strconv"
"git.nemunai.re/checkhome/struct"
"github.com/julienschmidt/httprouter"
)
func init() {
router.GET("/api/tags/", apiHandler(func (_ httprouter.Params, _ []byte) (interface{}, error) {
return ckh.GetTags()
}))
router.POST("/api/tags/", apiHandler(newTag))
router.DELETE("/api/tags/", apiHandler(func (_ httprouter.Params, _ []byte) (interface{}, error) {
return ckh.ClearTags()
}))
router.GET("/api/tags/:tid", apiHandler(tagHandler(func (tag ckh.Tag, _ []byte) (interface{}, error) {
return tag, nil
})))
router.PUT("/api/tags/:tid", apiHandler(tagHandler(updateTag)))
router.DELETE("/api/tags/:tid", apiHandler(tagHandler(func (tag ckh.Tag, _ []byte) (interface{}, error) {
return tag.Delete()
})))
}
func tagHandler(f func(ckh.Tag, []byte) (interface{}, error)) func(httprouter.Params, []byte) (interface{}, error) {
return func(ps httprouter.Params, body []byte) (interface{}, error) {
if tid, err := strconv.ParseInt(string(ps.ByName("tid")), 10, 64); err != nil {
return nil, err
} else if tag, err := ckh.GetTag(tid); err != nil {
return nil, err
} else {
return f(tag, body)
}
}
}
func newTag(_ httprouter.Params, body []byte) (interface{}, error) {
var ut ckh.Tag
if err := json.Unmarshal(body, &ut); err != nil {
return nil, err
}
if len(ut.Label) == 0 {
return nil, errors.New("Tag's label cannot be empty")
}
return ckh.NewTag(ut.Label)
}
func updateTag(tag ckh.Tag, body []byte) (interface{}, error) {
var ut ckh.Tag
if err := json.Unmarshal(body, &ut); err != nil {
return nil, err
}
if len(ut.Label) == 0 {
return nil, errors.New("Tag's label cannot be empty")
}
ut.Id = tag.Id
if _, err := ut.Update(); err != nil {
return nil, err
} else {
return ut, nil
}
}

87
api/user.go Normal file
View File

@ -0,0 +1,87 @@
package api
import (
"encoding/json"
"errors"
"strconv"
"git.nemunai.re/checkhome/struct"
"github.com/julienschmidt/httprouter"
)
func init() {
router.GET("/api/users/", apiHandler(func (_ httprouter.Params, _ []byte) (interface{}, error) {
return ckh.GetUsers()
}))
router.POST("/api/users/", apiHandler(newUser))
router.DELETE("/api/users/", apiHandler(func (_ httprouter.Params, _ []byte) (interface{}, error) {
return ckh.ClearUsers()
}))
router.GET("/api/users/:uid", apiHandler(userHandler(func (user ckh.User, _ []byte) (interface{}, error) {
return user, nil
})))
router.PUT("/api/users/:uid", apiHandler(userHandler(updateUser)))
router.DELETE("/api/users/:uid", apiHandler(userHandler(func (user ckh.User, _ []byte) (interface{}, error) {
return user.Delete()
})))
}
func userHandler(f func(ckh.User, []byte) (interface{}, error)) func(httprouter.Params, []byte) (interface{}, error) {
return func(ps httprouter.Params, body []byte) (interface{}, error) {
if uid, err := strconv.ParseInt(string(ps.ByName("uid")), 10, 64); err != nil {
return nil, err
} else if user, err := ckh.GetUser(uid); err != nil {
return nil, err
} else {
return f(user, body)
}
}
}
type uploadedUser struct {
Username string `json:"username"`
Password string `json:"password"`
}
func newUser(_ httprouter.Params, body []byte) (interface{}, error) {
var uu uploadedUser
if err := json.Unmarshal(body, &uu); err != nil {
return nil, err
}
if len(uu.Username) == 0 {
return nil, errors.New("Username cannot be empty")
}
if len(uu.Password) == 0 {
return nil, errors.New("Password cannot be empty")
}
return ckh.NewUser(uu.Username, uu.Password)
}
func updateUser(user ckh.User, body []byte) (interface{}, error) {
var uu uploadedUser
if err := json.Unmarshal(body, &uu); err != nil {
return nil, err
}
if len(uu.Username) == 0 {
return nil, errors.New("Username cannot be empty")
}
if len(uu.Password) == 0 {
return nil, errors.New("Password cannot be empty")
}
user.Username = uu.Username
user.ChangePassword(uu.Password)
if _, err := user.Update(); err != nil {
return nil, err
} else {
return user, nil
}
}

105
struct/check.go Normal file
View File

@ -0,0 +1,105 @@
package ckh
import ()
type Check struct {
Id int64 `json:"id"`
IdItem int64 `json:"id_item"`
IdUser int64 `json:"id_user"`
Passed string `json:"passed"`
Comment string `json:"comment",omitempty`
}
func GetChecks() (checks []Check, err error) {
if rows, errr := DBQuery("SELECT id_check, id_item, id_user, passed, comment FROM checks"); errr != nil {
return nil, errr
} else {
defer rows.Close()
checks = make([]Check, 0)
for rows.Next() {
var c Check
if err = rows.Scan(&c.Id, &c.IdItem, &c.IdUser, &c.Passed, &c.Comment); err != nil {
return
}
checks = append(checks, c)
}
if err = rows.Err(); err != nil {
return
}
return
}
}
func (i Item) GetChecks() (checks []Check, err error) {
if rows, errr := DBQuery("SELECT id_check, id_item, id_user, passed, comment FROM checks WHERE id_item = ?", i.Id); errr != nil {
return nil, errr
} else {
defer rows.Close()
checks = make([]Check, 0)
for rows.Next() {
var c Check
if err = rows.Scan(&c.Id, &c.IdItem, &c.IdUser, &c.Passed, &c.Comment); err != nil {
return
}
checks = append(checks, c)
}
if err = rows.Err(); err != nil {
return
}
return
}
}
func GetCheck(id int64) (c Check, err error) {
err = DBQueryRow("SELECT id_check, id_item, id_user, passed, comment FROM checks WHERE id_check = ?", id).Scan(&c.Id, &c.IdUser, &c.Passed, &c.Comment)
return
}
func (i Item) GetCheck(id int64) (c Check, err error) {
err = DBQueryRow("SELECT id_check, id_item, id_user, passed, comment FROM checks WHERE id_check = ? AND id_item = ?", id, i.Id).Scan(&c.Id, &c.IdUser, &c.Passed, &c.Comment)
return
}
func (i Item) NewCheck(user User, state string, comment string) (Check, error) {
if res, err := DBExec("INSERT INTO checks (id_item, id_user, passed, comment) VALUES (?, ?, ?)", i.Id, user.Id, state, comment); err != nil {
return Check{}, err
} else if cid, err := res.LastInsertId(); err != nil {
return Check{}, err
} else {
return Check{cid, i.Id, user.Id, state, comment}, nil
}
}
func (c Check) Update() (int64, error) {
if res, err := DBExec("UPDATE checks SET id_item = ?, id_user = ?, passed = ?, comment = ? WHERE id_check = ?", c.IdItem, c.IdUser, c.Passed, c.Comment, c.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func (c Check) Delete() (int64, error) {
if res, err := DBExec("DELETE FROM checks WHERE id_check = ?", c.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func ClearChecks() (int64, error) {
if res, err := DBExec("DELETE FROM checks"); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}

View File

@ -62,7 +62,8 @@ CREATE TABLE IF NOT EXISTS rooms (id_room INTEGER NOT NULL PRIMARY KEY AUTO_INCR
CREATE TABLE IF NOT EXISTS tags (id_tag INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, label TEXT NOT NULL);
CREATE TABLE IF NOT EXISTS items (id_item INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, label TEXT NOT NULL, description TEXT NOT NULL, id_room INTEGER);
CREATE TABLE IF NOT EXISTS item_tag (id_item INTEGER NOT NULL, id_tag INTEGER NOT NULL);
CREATE TABLE IF NOT EXISTS users (id_user INTEGER NOT NULL, username VARCHAR(255), password BINARY(64));
CREATE TABLE IF NOT EXISTS users (id_user INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, username VARCHAR(255), password BINARY(64));
CREATE TABLE IF NOT EXISTS checks (id_check INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, id_item INTEGER NOT NULL, id_user INTEGER NOT NULL, passed ENUM('yes', 'no', 'yesbut', 'nobut') NOT NULL, comment TEXT NOT NULL);
`
for _, ln := range strings.Split(ct, "\n") {
if len(ln) == 0 {

114
struct/item.go Normal file
View File

@ -0,0 +1,114 @@
package ckh
import ()
type Item struct {
Id int64 `json:"id"`
Label string `json:"label"`
Description string `json:"description"`
IdRoom int64 `json:"id_room"`
}
func GetItems() (items []Item, err error) {
if rows, errr := DBQuery("SELECT id_item, label, description, id_room FROM items"); errr != nil {
return nil, errr
} else {
defer rows.Close()
items = make([]Item, 0)
for rows.Next() {
var i Item
if err = rows.Scan(&i.Id, &i.Label, &i.Description, &i.IdRoom); err != nil {
return
}
items = append(items, i)
}
if err = rows.Err(); err != nil {
return
}
return
}
}
func GetItem(id int64) (i Item, err error) {
err = DBQueryRow("SELECT id_item, label, description, id_room FROM items WHERE id_item = ?", id).Scan(&i.Id, &i.Label, &i.Description, &i.IdRoom)
return
}
func (r Room) GetItems() (items []Item, err error) {
if rows, errr := DBQuery("SELECT id_item, label, description, id_room FROM items WHERE id_room = ?", r.Id); errr != nil {
return nil, errr
} else {
defer rows.Close()
items = make([]Item, 0)
for rows.Next() {
var i Item
if err = rows.Scan(&i.Id, &i.Label, &i.Description, &i.IdRoom); err != nil {
return
}
items = append(items, i)
}
if err = rows.Err(); err != nil {
return
}
return
}
}
func (r Room) GetItem(id int64) (i Item, err error) {
err = DBQueryRow("SELECT id_item, label, description, id_room FROM items WHERE id_room = ? AND id_item = ?", r.Id, id).Scan(&i.Id, &i.Label, &i.Description, &i.IdRoom)
return
}
func NewItem(label string, description string, room Room) (Item, error) {
if res, err := DBExec("INSERT INTO items (label, description, id_room) VALUES (?, ?, ?)", label, description, room.Id); err != nil {
return Item{}, err
} else if iid, err := res.LastInsertId(); err != nil {
return Item{}, err
} else {
return Item{iid, label, description, room.Id}, nil
}
}
func (i Item) Update() (int64, error) {
if res, err := DBExec("UPDATE items SET label = ?, description = ?, id_room = ? WHERE id_item = ?", i.Label, i.Description, i.IdRoom, i.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func (i Item) Delete() (int64, error) {
if res, err := DBExec("DELETE FROM items WHERE id_item = ?", i.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func ClearItems() (int64, error) {
if res, err := DBExec("DELETE FROM items"); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func (r Room) ClearItems() (int64, error) {
if res, err := DBExec("DELETE FROM items WHERE id_room = ?", r.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}

74
struct/itemtag.go Normal file
View File

@ -0,0 +1,74 @@
package ckh
import ()
type ItemTag struct {
IdItem int64 `json:"iditem"`
IdTag int64 `json:"idtag"`
}
func (i Item) AddTag(t Tag) (ItemTag, error) {
if _, err := DBExec("INSERT INTO item_tag (id_item, id_tag) VALUES (?, ?)", i.Id, t.Id); err != nil {
return ItemTag{}, err
} else {
return ItemTag{i.Id, t.Id}, nil
}
}
func (t Tag) AddItem(i Item) (ItemTag, error) {
if _, err := DBExec("INSERT INTO item_tag (id_item, id_tag) VALUES (?, ?)", i.Id, t.Id); err != nil {
return ItemTag{}, err
} else {
return ItemTag{i.Id, t.Id}, nil
}
}
func (i Item) DeleteTag(t Tag) (int64, error) {
if res, err := DBExec("DELETE FROM item_tag WHERE id_item = ? AND id_tag = ?", i.Id, t.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func (t Tag) DeleteItem(i Item) (int64, error) {
if res, err := DBExec("DELETE FROM item_tag WHERE id_item = ? AND id_tag = ?", i.Id, t.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func ClearItemTags() (int64, error) {
if res, err := DBExec("DELETE FROM item_tag"); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func (i Item) ClearItemTags() (int64, error) {
if res, err := DBExec("DELETE FROM item_tag WHERE id_item = ?", i.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func (t Tag) ClearItemTags() (int64, error) {
if res, err := DBExec("DELETE FROM item_tag WHERE id_tag = ?", t.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}

74
struct/room.go Normal file
View File

@ -0,0 +1,74 @@
package ckh
import ()
type Room struct {
Id int64 `json:"id"`
Label string `json:"label"`
}
func GetRooms() (rooms []Room, err error) {
if rows, errr := DBQuery("SELECT id_room, label FROM rooms"); errr != nil {
return nil, errr
} else {
defer rows.Close()
for rows.Next() {
var r Room
if err = rows.Scan(&r.Id, &r.Label); err != nil {
return
}
rooms = append(rooms, r)
}
if err = rows.Err(); err != nil {
return
}
return
}
}
func GetRoom(id int64) (r Room, err error) {
err = DBQueryRow("SELECT id_room, label FROM rooms WHERE id_room = ?", id).Scan(&r.Id, &r.Label)
return
}
func NewRoom(label string) (Room, error) {
if res, err := DBExec("INSERT INTO rooms (label) VALUES (?)", label); err != nil {
return Room{}, err
} else if rid, err := res.LastInsertId(); err != nil {
return Room{}, err
} else {
return Room{rid, label}, nil
}
}
func (r Room) Update() (int64, error) {
if res, err := DBExec("UPDATE rooms SET label = ? WHERE id_room = ?", r.Label, r.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func (r Room) Delete() (int64, error) {
if res, err := DBExec("DELETE FROM rooms WHERE id_room = ?", r.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func ClearRooms() (int64, error) {
if res, err := DBExec("DELETE FROM rooms"); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}

75
struct/tag.go Normal file
View File

@ -0,0 +1,75 @@
package ckh
import ()
type Tag struct {
Id int64 `json:"id"`
Label string `json:"label"`
}
func GetTags() (tags []Tag, err error) {
if rows, errr := DBQuery("SELECT id_tag, label FROM tags"); errr != nil {
return nil, errr
} else {
defer rows.Close()
tags = make([]Tag, 0)
for rows.Next() {
var t Tag
if err = rows.Scan(&t.Id, &t.Label); err != nil {
return
}
tags = append(tags, t)
}
if err = rows.Err(); err != nil {
return
}
return
}
}
func GetTag(id int64) (t Tag, err error) {
err = DBQueryRow("SELECT id_tag, label FROM tags WHERE id_tag = ?", id).Scan(&t.Id, &t.Label)
return
}
func NewTag(label string) (Tag, error) {
if res, err := DBExec("INSERT INTO tags (label) VALUES (?)", label); err != nil {
return Tag{}, err
} else if tid, err := res.LastInsertId(); err != nil {
return Tag{}, err
} else {
return Tag{tid, label}, nil
}
}
func (t Tag) Update() (int64, error) {
if res, err := DBExec("UPDATE tags SET label = ? WHERE id_tag = ?", t.Label, t.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func (t Tag) Delete() (int64, error) {
if res, err := DBExec("DELETE FROM tags WHERE id_tag = ?", t.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func ClearTags() (int64, error) {
if res, err := DBExec("DELETE FROM tags"); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}

106
struct/user.go Normal file
View File

@ -0,0 +1,106 @@
package ckh
import (
"crypto"
_ "crypto/sha1"
)
type User struct {
Id int64 `json:"id"`
Username string `json:"username"`
password []byte
}
func GetUsers() (users []User, err error) {
if rows, errr := DBQuery("SELECT id_user, username, password FROM users"); errr != nil {
return nil, errr
} else {
defer rows.Close()
users = make([]User, 0)
for rows.Next() {
var u User
if err = rows.Scan(&u.Id, &u.Username, &u.password); err != nil {
return
}
users = append(users, u)
}
if err = rows.Err(); err != nil {
return
}
return
}
}
func GetUser(id int64) (u User, err error) {
err = DBQueryRow("SELECT id_user, username, password FROM users WHERE id_user = ?", id).Scan(&u.Id, &u.Username, &u.password)
return
}
func hashPassword(password string) []byte {
hash := crypto.SHA1.New()
return hash.Sum([]byte(password))
}
func NewUser(username string, password string) (User, error) {
hash := hashPassword(password)
if res, err := DBExec("INSERT INTO users (username, password) VALUES (?, ?)", username, hash); err != nil {
return User{}, err
} else if uid, err := res.LastInsertId(); err != nil {
return User{}, err
} else {
return User{uid, username, hash}, nil
}
}
func (u User) checkPassword(password string) bool {
givenHash := hashPassword(password)
if len(givenHash) != len(u.password) {
return false
}
for k := range u.password {
if u.password[k] != givenHash[k] {
return false
}
}
return true
}
func (u User) ChangePassword(password string) {
u.password = hashPassword(password)
}
func (u User) Update() (int64, error) {
if res, err := DBExec("UPDATE users SET username = ?, password = ? WHERE id_user = ?", u.Username, u.password, u.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func (u User) Delete() (int64, error) {
if res, err := DBExec("DELETE FROM users WHERE id_user = ?", u.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}
func ClearUsers() (int64, error) {
if res, err := DBExec("DELETE FROM users"); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
} else {
return nb, err
}
}