diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 17da479..1922ce2 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -91,7 +91,8 @@ paths: required: true schema: type: string - description: フォルダパス + example: School-ComputerScience-Python + description: フォルダパス ハイフン区切り responses: '200': description: OK diff --git a/schema.sql b/schema.sql index 668afbf..078c6c7 100644 --- a/schema.sql +++ b/schema.sql @@ -12,6 +12,7 @@ CREATE TABLE lectures ( title TEXT NOT NULL, content TEXT NOT NULL, folder_id INT(11) + folder_path TEXT NOT NULL, ); CREATE TABLE tags ( id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, @@ -27,6 +28,6 @@ CREATE TABLE tags_in_wiki ( CREATE TABLE folders ( id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, name TEXT NOT NULL, - parent_id INT(11), + parent_id INT(11), -- 0 if root UNIQUE KEY (name, parent_id) ); \ No newline at end of file diff --git a/src/handler/handler.go b/src/handler/handler.go index 791a10b..faf8bda 100644 --- a/src/handler/handler.go +++ b/src/handler/handler.go @@ -1,7 +1,12 @@ package handler import ( + "database/sql" + "errors" + "log" "net/http" + "strconv" + "strings" "github.com/jmoiron/sqlx" "github.com/labstack/echo" @@ -15,6 +20,109 @@ func NewHandler(db *sqlx.DB) *Handler { return &Handler{db: db} } +// /ping func (h *Handler) PingHandler(c echo.Context) error { return c.String(http.StatusOK, "pong") } + +// /lecture/byFolder/id/:folderId +func (h *Handler) GetLectureByFolderIDHandler(c echo.Context) error { + folderID, err := strconv.Atoi(c.Param("folderId")) + if err != nil { + log.Printf("failed to convert folderId to int: %v", err) + return c.JSON(http.StatusBadRequest, err) + } + + lectures := []LectureFromDB{} + err = h.db.Select(&lectures, "SELECT * FROM lectures WHERE folder_id = ?", folderID) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return c.JSON(http.StatusNotFound, err) + } + log.Printf("failed to get lectures: %v", err) + return c.JSON(http.StatusInternalServerError, err) + } + + lecturesWithFolderPath := []Lecture{} + for _, lecture := range lectures { + lecturesWithFolderPath = append(lecturesWithFolderPath, Lecture{ + ID: lecture.ID, + Title: lecture.Title, + Content: lecture.Content, + FolderPath: lecture.FolderPath, + }) + } + + return c.JSON(http.StatusOK, lecturesWithFolderPath) +} + +// /lecture/byFolder/path +func (h *Handler) GetLectureByFolderPathHandler(c echo.Context) error { + folderPath := c.QueryParam("folderPath") + + folderPath = "/" + strings.ReplaceAll(folderPath, "-", " /") + lectures := []LectureFromDB{} + err := h.db.Select(&lectures, "SELECT * FROM lectures WHERE folderpath = ?", folderPath) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return c.JSON(http.StatusNotFound, err) + } + log.Printf("failed to get lectures: %v", err) + return c.JSON(http.StatusInternalServerError, err) + } + + lecturesWithFolderPath := []Lecture{} + for _, lecture := range lectures { + lecturesWithFolderPath = append(lecturesWithFolderPath, Lecture{ + ID: lecture.ID, + Title: lecture.Title, + Content: lecture.Content, + FolderPath: lecture.FolderPath, + }) + } + + return c.JSON(http.StatusOK, lecturesWithFolderPath) +} + +// /lecture/folder/:folderId +func (h *Handler) GetLectureChildFolderHandler(c echo.Context) error { + folderID, err := strconv.Atoi(c.Param("folderId")) + if err != nil { + log.Printf("failed to convert folderId to int: %v", err) + return c.JSON(http.StatusBadRequest, err) + } + + files := []File{} + + childFolders := []FolderFromDB{} + err = h.db.Select(&childFolders, "SELECT * FROM folders WHERE parent_id = ?", folderID) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + log.Printf("failed to get child folders: %v", err) + return c.JSON(http.StatusInternalServerError, err) + } + + for _, folder := range childFolders { + files = append(files, File{ + ID: folder.ID, + Name: folder.Name, + IsFolder: true, + }) + } + + childLectures := []LectureOnlyName{} + err = h.db.Select(&childLectures, "SELECT id, title FROM lectures WHERE folder_id = ?", folderID) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + log.Printf("failed to get child lectures: %v", err) + return c.JSON(http.StatusInternalServerError, err) + } + + for _, lecture := range childLectures { + files = append(files, File{ + ID: lecture.ID, + Name: lecture.Title, + IsFolder: false, + }) + } + + return c.JSON(http.StatusOK, files) +} \ No newline at end of file diff --git a/src/handler/model.go b/src/handler/model.go new file mode 100644 index 0000000..607bb2c --- /dev/null +++ b/src/handler/model.go @@ -0,0 +1,32 @@ +package handler + +type LectureFromDB struct { + ID int `db:"id"` + Title string `db:"title"` + Content string `db:"content"` + FolderID int `db:"folder_id"` + FolderPath string `db:"folderpath"` +} + +type Lecture struct { + ID int `json:"id"` + Title string `json:"title"` + Content string `json:"content"` + FolderPath string `json:"folderpath"` +} + +type FolderFromDB struct { + ID int `db:"id"` + Name string `db:"name"` +} + +type File struct { + ID int `json:"id"` + Name string `json:"name"` + IsFolder bool `json:"isFolder"` +} + +type LectureOnlyName struct { + ID int `db:"id"` + Title string `db:"title"` +}