package main import ( "context" "fmt" "io" "log" "net/http" "os" "strconv" "github.com/gin-gonic/gin" "github.com/jackc/pgx/v5/pgxpool" "github.com/jaswdr/faker" ) var dbpool *pgxpool.Pool func main() { var err error dbpool, err = pgxpool.New(context.Background(), "postgresql://postgres:postgres@172.19.0.2:5432/postgres") if err != nil { log.Fatal(err) } defer dbpool.Close() sqlStmt := ` DROP TABLE IF EXISTS public.videos; CREATE TABLE IF NOT EXISTS public.videos ( id serial NOT NULL, filepath text, CONSTRAINT videos_pkey PRIMARY KEY (id) ) TABLESPACE pg_default; ALTER TABLE IF EXISTS public.videos OWNER to postgres; ` _, err = dbpool.Exec(context.Background(), sqlStmt) if err != nil { log.Fatalf("Unable to connection to database: %v\n", err) } faker := faker.New() for i := 0; i < 10; i++ { sqlStmt = fmt.Sprintf("insert into public.videos(filepath) values('%s')", faker.File().AbsoluteFilePathForUnix(2)) _, err = dbpool.Exec(context.Background(), sqlStmt) if err != nil { log.Fatalf("Unable to add videos: %v\n", err) } } router := gin.Default() router.SetTrustedProxies(nil) router.POST("/video", ReceiveChunk) router.POST("/video/completed", ReceiveFile) router.GET("/videos", listVideos) router.GET("/videos/:id", getVideo) router.Run("localhost:8080") } func ReceiveChunk(c *gin.Context) { /* get data from request write append data to file */ chunk, err := io.ReadAll(c.Request.Body) if err != nil { c.IndentedJSON(http.StatusBadRequest, "Unknown Error") return } fileName := c.GetHeader("file-name") f, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { log.Fatal(err) } if _, err := f.Write(chunk); err != nil { log.Fatal(err) } if err := f.Close(); err != nil { log.Fatal(err) } c.IndentedJSON(http.StatusOK, "Received chunk") } func ReceiveFile(c *gin.Context) { currentDir, err := os.Getwd() if err != nil { log.Fatalf("Unable to get current working dir: %v\n", err) } fileName, err := io.ReadAll(c.Request.Body) if err != nil { c.IndentedJSON(http.StatusBadRequest, "Unknown Error") return } filepath := fmt.Sprintf("%s/%s", currentDir, fileName) sqlStmt := fmt.Sprintf("insert into public.videos(filepath) values('%s')", filepath) _, err = dbpool.Exec(context.Background(), sqlStmt) if err != nil { log.Fatalf("Unable to add video: %v\n", err) } c.IndentedJSON(http.StatusOK, "Completed Upload") } func listVideos(c *gin.Context) { var err error rows, _ := dbpool.Query(context.Background(), "select * from videos") for rows.Next() { var id int var filepath string err = rows.Scan(&id, &filepath) if err != nil { log.Fatalf("Unable to list videos: %v\n", err) } fmt.Println(id, filepath) } err = rows.Err() if err != nil { log.Fatalf("Unable to list videos: %v\n", err) } } func getVideo(c *gin.Context) { var err error inputId, err := strconv.Atoi(c.Param("id")) if err != nil { log.Fatal(err) } sqlStmt := fmt.Sprintf("select * from videos where id = %d", inputId) rows, _ := dbpool.Query(context.Background(), sqlStmt) for rows.Next() { var id int var filepath string err = rows.Scan(&id, &filepath) if err != nil { log.Fatalf("Unable to list videos: %v\n", err) } fmt.Println(id, filepath) } err = rows.Err() if err != nil { log.Fatalf("Unable to list videos: %v\n", err) } }