From 977a75819d0f00eab9fc7bfec7f64ab00c3ee430 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Mon, 25 Jun 2018 22:20:16 +0200 Subject: [PATCH] Add structs and corresponding API routes --- api/check.go | 76 +++++++++++++++++++++++++++++++ api/item.go | 83 +++++++++++++++++++++++++++++++++ api/room.go | 73 +++++++++++++++++++++++++++++ api/tag.go | 73 +++++++++++++++++++++++++++++ api/user.go | 87 +++++++++++++++++++++++++++++++++++ struct/check.go | 105 ++++++++++++++++++++++++++++++++++++++++++ struct/db.go | 3 +- struct/item.go | 114 ++++++++++++++++++++++++++++++++++++++++++++++ struct/itemtag.go | 74 ++++++++++++++++++++++++++++++ struct/room.go | 74 ++++++++++++++++++++++++++++++ struct/tag.go | 75 ++++++++++++++++++++++++++++++ struct/user.go | 106 ++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 942 insertions(+), 1 deletion(-) create mode 100644 api/check.go create mode 100644 api/item.go create mode 100644 api/room.go create mode 100644 api/tag.go create mode 100644 api/user.go create mode 100644 struct/check.go create mode 100644 struct/item.go create mode 100644 struct/itemtag.go create mode 100644 struct/room.go create mode 100644 struct/tag.go create mode 100644 struct/user.go diff --git a/api/check.go b/api/check.go new file mode 100644 index 0000000..ddcbbca --- /dev/null +++ b/api/check.go @@ -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 + } +} diff --git a/api/item.go b/api/item.go new file mode 100644 index 0000000..7046fc2 --- /dev/null +++ b/api/item.go @@ -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 + } +} diff --git a/api/room.go b/api/room.go new file mode 100644 index 0000000..e9ce5d5 --- /dev/null +++ b/api/room.go @@ -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 + } +} diff --git a/api/tag.go b/api/tag.go new file mode 100644 index 0000000..d1d341f --- /dev/null +++ b/api/tag.go @@ -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 + } +} diff --git a/api/user.go b/api/user.go new file mode 100644 index 0000000..2c9e956 --- /dev/null +++ b/api/user.go @@ -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 + } +} diff --git a/struct/check.go b/struct/check.go new file mode 100644 index 0000000..96c5d9c --- /dev/null +++ b/struct/check.go @@ -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 + } +} diff --git a/struct/db.go b/struct/db.go index acdc217..4efaeed 100644 --- a/struct/db.go +++ b/struct/db.go @@ -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 { diff --git a/struct/item.go b/struct/item.go new file mode 100644 index 0000000..913131e --- /dev/null +++ b/struct/item.go @@ -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 + } +} diff --git a/struct/itemtag.go b/struct/itemtag.go new file mode 100644 index 0000000..8ecffbf --- /dev/null +++ b/struct/itemtag.go @@ -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 + } +} diff --git a/struct/room.go b/struct/room.go new file mode 100644 index 0000000..f62e302 --- /dev/null +++ b/struct/room.go @@ -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 + } +} diff --git a/struct/tag.go b/struct/tag.go new file mode 100644 index 0000000..521c1e4 --- /dev/null +++ b/struct/tag.go @@ -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 + } +} diff --git a/struct/user.go b/struct/user.go new file mode 100644 index 0000000..5577227 --- /dev/null +++ b/struct/user.go @@ -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 + } +}