Language Database Stack

This commit is contained in:
2026-07-26 02:48:48 +02:00
parent ddbbe10ec7
commit 2517600524
10 changed files with 2617 additions and 0 deletions
@@ -0,0 +1,108 @@
package controller
import (
"encoding/json"
"io"
"log"
"strconv"
"net/http"
"scpq-editor-server/models"
"scpq-editor-server/services"
"github.com/gin-gonic/gin"
)
type LanguagesController struct {
languagesService *services.LanguagesService
}
func NewLanguagesController(languagesService *services.LanguagesService) *LanguagesController {
return &LanguagesController{
languagesService: languagesService,
}
}
func (lc LanguagesController) CreateLanguage(ctx *gin.Context) {
body, err := io.ReadAll(ctx.Request.Body)
if err != nil {
log.Println("Error while reading create language request body", err)
ctx.AbortWithError(http.StatusInternalServerError, err)
return
}
var language models.Language
err = json.Unmarshal(body, &language)
if err != nil {
log.Println("Error while unmarshaling create runner request body",err)
ctx.AbortWithError(http.StatusInternalServerError, err)
return
}
response, responseErr := lc.languagesService.CreateLanguage(&language)
if responseErr != nil {
ctx.AbortWithStatusJSON(responseErr.Status,responseErr)
return
}
ctx.JSON(http.StatusOK, response)
}
func (lc LanguagesController) UpdateLanguage(ctx *gin.Context) {
body, err := io.ReadAll(ctx.Request.Body)
if err != nil {
log.Println("Error while reading update language request body", err)
ctx.AbortWithError(http.StatusInternalServerError,err)
return
}
var language models.Language
err = json.Unmarshal(body, &language)
if err != nil {
log.Println("Error while unmarshaling update language request body", err)
ctx.AbortWithError(http.StatusInternalServerError,err)
return
}
responseErr := lc.languagesService.UpdateLanguage(&language)
if responseErr != nil {
ctx.AbortWithStatusJSON(responseErr.Status,responseErr)
return
}
ctx.Status(http.StatusNoContent)
}
func (lc LanguagesController) DeleteLanguage(ctx *gin.Context) {
languageId := ctx.Param("id")
lId, err := strconv.Atoi(languageId)
if err != nil {
log.Println("Error languageId not int", err)
ctx.AbortWithError(http.StatusInternalServerError,err)
return
}
responseErr := lc.languagesService.DeleteLanguage(lId)
if responseErr != nil {
ctx.JSON(responseErr.Status, responseErr)
return
}
ctx.Status(http.StatusNoContent)
}
func (lc LanguagesController) GetLanguage(ctx *gin.Context) {
languageId := ctx.Param("id")
lId, err := strconv.Atoi(languageId)
if err != nil {
log.Println("Error languageId not int", err)
ctx.AbortWithError(http.StatusInternalServerError,err)
return
}
response, responseErr := lc.languagesService.GetLanguage(lId)
if responseErr != nil {
ctx.JSON(responseErr.Status, responseErr)
return
}
ctx.JSON(http.StatusOK, response)
}
func (lc LanguagesController) GetAllLanguages(ctx *gin.Context) {
response, responseErr := lc.languagesService.GetAllLanguages()
if responseErr != nil {
ctx.JSON(responseErr.Status, responseErr)
return
}
ctx.JSON(http.StatusOK, response)
}
@@ -0,0 +1,7 @@
package models
type Language struct {
ID int `json:"id"`
Locale string `json:"locale"`
Language string `json:"language"`
}
@@ -0,0 +1,6 @@
package models
type ResponseError struct {
Message string `json:"message"`
Status int `json:"-"`
}
@@ -0,0 +1,108 @@
package repositories
import (
"database/sql"
"net/http"
"scpq-editor-server/models"
)
type LanguagesRepository struct {
dbHandler *sql.DB
}
func NewLanguagesRepository(dbHandler *sql.DB) *LanguagesRepository {
return &LanguagesRepository{
dbHandler: dbHandler,
}
}
func (rr LanguagesRepository) CreateLanguage(language *models.Language) (*models.Language, *models.ResponseError) {
query:=`INSERT INTO languages(locale, language) VALUES($1,$2) RETURNING id`
rows, err := rr.dbHandler.Query(query, language.Locale, language.Language)
if err != nil {
return nil, &models.ResponseError{
Message: err.Error(),
Status: http.StatusInternalServerError,
}
}
defer rows.Close()
var languageId int
for rows.Next() {
err := rows.Scan(languageId)
if err != nil {
return nil, &models.ResponseError{
Message: err.Error(),
Status: http.StatusInternalServerError,
}
}
}
if rows.Err() != nil {
return nil, &models.ResponseError{
Message: err.Error(),
Status: http.StatusInternalServerError,
}
}
return &models.Language{
ID: languageId,
Locale: language.Locale,
Language: language.Language,
}, nil
}
func (rr LanguagesRepository) UpdateLanguage(language *models.Language) *models.ResponseError {
return &models.ResponseError{
Message: "UpdateLanguage not yet implementet",
Status: http.StatusInternalServerError,
}
}
func (rr LanguagesRepository) DeleteLanguage(languageId int) *models.ResponseError {
return &models.ResponseError{
Message: "UpdateLanguage not yet implementet",
Status: http.StatusInternalServerError,
}
}
func (rr LanguagesRepository) GetLanguage(languageId int) (*models.Language, *models.ResponseError) {
return nil, &models.ResponseError{
Message: "UpdateLanguage not yet implementet",
Status: http.StatusInternalServerError,
}
}
func (rr LanguagesRepository) GetAllLanguages()([]*models.Language, *models.ResponseError) {
query:="SELECT * FROM languages"
rows, err := rr.dbHandler.Query(query)
if err != nil {
return nil, &models.ResponseError{
Message: err.Error(),
Status: http.StatusInternalServerError,
}
}
defer rows.Close()
languages := make([]*models.Language, 0)
var id int
var locale, language string
for rows.Next() {
err := rows.Scan(id, locale, language)
if err != nil {
return nil, &models.ResponseError{
Message: err.Error(),
Status: http.StatusInternalServerError,
}
}
language := &models.Language {
ID: id,
Locale: locale,
Language: language,
}
languages = append(languages, language)
}
if rows.Err() != nil {
return nil, &models.ResponseError{
Message: err.Error(),
Status: http.StatusInternalServerError,
}
}
return languages, nil
}
@@ -4,6 +4,9 @@ import (
"log"
"net/http"
"database/sql"
"scpq-editor-server/controller"
"scpq-editor-server/repositories"
"scpq-editor-server/services"
"github.com/gin-gonic/gin"
"github.com/spf13/viper"
)
@@ -12,12 +15,33 @@ type HttpServer struct {
config *viper.Viper
router *gin.Engine
dbHandler *sql.DB
languageController *controller.LanguagesController
}
func InitHttpServer(config *viper.Viper, dbHandler *sql.DB) HttpServer {
// repository initialisation:
languagesRepository := repositories.NewLanguagesRepository(dbHandler)
// service initialisation:
languagesService := services.NewLanguagesService(languagesRepository)
// controller initialisation:
languageController := controller.NewLanguagesController(languagesService)
// Service API
router := gin.Default()
router.GET("/test", Test)
// language centric routing
router.POST("/language", languageController.CreateLanguage)
router.PUT("/language", languageController.UpdateLanguage)
router.DELETE("/language/:id", languageController.DeleteLanguage)
router.GET("/language/:id", languageController.GetLanguage)
router.GET("/languages", languageController.GetAllLanguages)
// server
return HttpServer{
config: config,
router: router,
@@ -0,0 +1,61 @@
package services
import (
"net/http"
"scpq-editor-server/models"
"scpq-editor-server/repositories"
)
type LanguagesService struct {
languagesRepository *repositories.LanguagesRepository
}
func NewLanguagesService(languagesRepository *repositories.LanguagesRepository) *LanguagesService {
return &LanguagesService {
languagesRepository: languagesRepository,
}
}
func (ls LanguagesService) CreateLanguage(language *models.Language) (*models.Language, *models.ResponseError) {
responseErr := validateLanguage(language)
if responseErr != nil {
return nil, responseErr
}
return ls.languagesRepository.CreateLanguage(language)
}
func (ls LanguagesService) UpdateLanguage(language *models.Language) *models.ResponseError {
responseErr := validateLanguage(language)
if responseErr != nil {
return responseErr
}
return ls.languagesRepository.UpdateLanguage(language)
}
func (ls LanguagesService) DeleteLanguage(languageId int) *models.ResponseError {
return ls.languagesRepository.DeleteLanguage(languageId)
}
func (ls LanguagesService) GetLanguage(languageId int) (*models.Language, *models.ResponseError) {
return ls.languagesRepository.GetLanguage(languageId)
}
func (ls LanguagesService) GetAllLanguages() ([]*models.Language, *models.ResponseError) {
return ls.languagesRepository.GetAllLanguages()
}
func validateLanguage(language *models.Language) *models.ResponseError {
if language.Locale == "" {
return &models.ResponseError{
Message: "Invalid locale",
Status: http.StatusBadRequest,
}
}
if language.Language == "" {
return &models.ResponseError{
Message: "Invalid language label",
Status: http.StatusBadRequest,
}
}
return nil
}