247 lines
6.4 KiB
Go
247 lines
6.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"log/slog"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/jackc/pgx/v5"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
/* Variables */
|
|
var connPool *pgxpool.Pool
|
|
|
|
func Config() (*pgxpool.Config) {
|
|
const defaultMaxConns = int32(4)
|
|
const defaultMinConns = int32(0)
|
|
const defaultMaxConnLifetime = time.Hour
|
|
const defaultMaxConnIdleTime = time.Minute * 30
|
|
const defaultHealthCheckPeriod = time.Minute
|
|
const defaultConnectTimeout = time.Second * 5
|
|
// Your own Database URL
|
|
const DATABASE_URL string = "postgres://tooloftheweek:b4lKAuHRz3Xho6WUQq4YUGnfiAQs5zNg@10.0.100.172:5432/tooloftheweek"
|
|
dbConfig, err := pgxpool.ParseConfig(DATABASE_URL)
|
|
if err!=nil {
|
|
log.Fatal("Failed to create a config, error: ", err)
|
|
}
|
|
|
|
dbConfig.MaxConns = defaultMaxConns
|
|
dbConfig.MinConns = defaultMinConns
|
|
dbConfig.MaxConnLifetime = defaultMaxConnLifetime
|
|
dbConfig.MaxConnIdleTime = defaultMaxConnIdleTime
|
|
dbConfig.HealthCheckPeriod = defaultHealthCheckPeriod
|
|
dbConfig.ConnConfig.ConnectTimeout = defaultConnectTimeout
|
|
|
|
dbConfig.BeforeAcquire = func(ctx context.Context, c *pgx.Conn) bool {
|
|
slog.Info("Before acquiring the connection pool to the database")
|
|
return true
|
|
}
|
|
|
|
dbConfig.AfterRelease = func(c *pgx.Conn) bool {
|
|
slog.Info("After releasing the connection pool to the database")
|
|
return true
|
|
}
|
|
|
|
dbConfig.BeforeClose = func(c *pgx.Conn) {
|
|
slog.Info("Closed the connection pool to the database")
|
|
}
|
|
|
|
return dbConfig
|
|
}
|
|
|
|
/* Structs */
|
|
type tool struct {
|
|
Name string
|
|
Description string
|
|
Url string
|
|
Week_to_post int
|
|
}
|
|
|
|
|
|
/* Database Functions*/
|
|
func database_connection(url string) (*pgx.Conn, error) {
|
|
var err error
|
|
conn, err := pgx.Connect(context.Background(), url)
|
|
if err != nil {
|
|
slog.Error("Could not connect to database")
|
|
}
|
|
|
|
return conn, err
|
|
}
|
|
|
|
|
|
func insertTool(conn *pgx.Conn, new_tool tool) error {
|
|
_, err := conn.Exec(context.Background(), "INSERT INTO tool_tb(name,description) VALUES($1,$2)", new_tool.Name, new_tool.Description)
|
|
if err != nil {
|
|
slog.Error("Could not insert new tool into database")
|
|
if err.Error() == `ERROR: duplicate key value violates unique constraint "tool_tb_name_key" (SQLSTATE 23505)` {
|
|
slog.Error("Tool already in database.")
|
|
} else {
|
|
fmt.Println(err)
|
|
}
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func currentTool() (tool,error) {
|
|
var currenttool tool
|
|
var currentweek int
|
|
|
|
//Calculate current week
|
|
currenttime := int(time.Now().Unix()) + 259200
|
|
currentweek = currenttime/604800
|
|
fmt.Println(currentweek)
|
|
|
|
//Select current tool from database
|
|
rows, err := connPool.Query(context.Background(), "SELECT id,name,description,url,week_to_post FROM tool_tb WHERE week_to_post=$1", currentweek)
|
|
if err != nil {
|
|
slog.Error("Could not query tools_tb")
|
|
}
|
|
|
|
for rows.Next(){
|
|
var id int
|
|
var name string
|
|
var description string
|
|
var url string
|
|
var week_to_post int
|
|
//var currenttoolinloop tool
|
|
|
|
rows.Scan(&id, &name, &description, &url, &week_to_post)
|
|
if name == "" {
|
|
return currenttool, errors.New("Could not find tool for current week. Please update tool list.")
|
|
}
|
|
|
|
slog.Info("Found tool: " + name)
|
|
|
|
currenttool.Name = name
|
|
currenttool.Description = description
|
|
currenttool.Url = url
|
|
currenttool.Week_to_post = week_to_post
|
|
}
|
|
|
|
|
|
return currenttool, nil
|
|
}
|
|
|
|
func getTools() ([]tool,error) {
|
|
var err error
|
|
var tools []tool
|
|
|
|
rows, err := connPool.Query(context.Background(), "SELECT id,name,description,url,week_to_post FROM tool_tb")
|
|
if err != nil {
|
|
slog.Error("Could not query tool_tb")
|
|
return nil, err
|
|
}
|
|
|
|
for rows.Next(){
|
|
var id int
|
|
var name string
|
|
var description string
|
|
var url string
|
|
var week_to_post int
|
|
|
|
var currenttoolinloop tool
|
|
|
|
err := rows.Scan(&id, &name, &description, &url, &week_to_post)
|
|
if err != nil {
|
|
slog.Error("Could not scan query")
|
|
return nil, err
|
|
}
|
|
currenttoolinloop.Name = name
|
|
currenttoolinloop.Description = description
|
|
currenttoolinloop.Url = url
|
|
currenttoolinloop.Week_to_post = week_to_post
|
|
|
|
tools = append(tools, currenttoolinloop)
|
|
}
|
|
return tools, nil
|
|
}
|
|
|
|
/* Gin Functions */
|
|
func getToolsHandler(c *gin.Context) {
|
|
//var tools []tool
|
|
|
|
tools, err := getTools()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
fmt.Println(tools)
|
|
c.IndentedJSON(http.StatusOK, tools)
|
|
}
|
|
|
|
func currentToolHandler(c *gin.Context) {
|
|
var currenttool tool
|
|
//var tools []tool
|
|
|
|
currenttool, err := currentTool()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
fmt.Println(currenttool)
|
|
c.IndentedJSON(http.StatusOK, currenttool)
|
|
}
|
|
|
|
func insertToolHandler(c *gin.Context) {
|
|
var newTool tool
|
|
|
|
c.IndentedJSON(http.StatusCreated, newTool)
|
|
}
|
|
|
|
func updateToolHandler(c *gin.Context) {
|
|
var updatedTool tool
|
|
|
|
c.IndentedJSON(http.StatusOK, updatedTool)
|
|
}
|
|
|
|
func deleteToolHandler(c *gin.Context) {
|
|
var removedTool tool
|
|
|
|
c.IndentedJSON(http.StatusOK, removedTool)
|
|
}
|
|
|
|
|
|
func main() {
|
|
|
|
var err error
|
|
|
|
connPool, err = pgxpool.NewWithConfig(context.Background(), Config())
|
|
if err != nil {
|
|
log.Fatal("Error acquiring connection from database.")
|
|
}
|
|
|
|
conn, err := connPool.Acquire(context.Background())
|
|
if err!=nil {
|
|
log.Fatal("Error while acquiring connection from the database pool!!")
|
|
}
|
|
defer conn.Release()
|
|
|
|
err = conn.Ping(context.Background())
|
|
if err != nil {
|
|
log.Fatal("Could not ping database.")
|
|
}
|
|
|
|
slog.Info("Connection to database successful.")
|
|
|
|
|
|
_, err = conn.Exec(context.Background(), "CREATE TABLE IF NOT EXISTS tool_tb (id SERIAL, name TEXT UNIQUE, url TEXT, description TEXT, time_created TIMESTAMP, week_to_post INT)")
|
|
if err != nil {
|
|
slog.Error("Could not create tool table.")
|
|
}
|
|
|
|
router := gin.Default()
|
|
router.GET("/api/v0/tools", getToolsHandler)
|
|
router.GET("/api/v0/tooloftheweek", currentToolHandler)
|
|
router.POST("/api/v0/inserttool", insertToolHandler)
|
|
router.POST("/api/v0/updatetool", updateToolHandler)
|
|
router.POST("/api/v0/deletetool", deleteToolHandler)
|
|
|
|
router.Run("0.0.0.0:8080")
|
|
}
|