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
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

+4
View File
@@ -54,6 +54,10 @@ Mit Regeln kann ich die Zusammenstellung der Komponenten in der Stückliste anpa
### Konditionen
Konditionen dienen zur Preisfindung abhängig vom aktuellen Angebotskontextes (z.B. Kunde, VKOrg, etc.) und Preis- und Kostenstrukturen. Die Preisfindung ermittelt den Basispreis eines Produktes in einem Angebot. In der Preiskalkulation kann dann noch Angebots-spezifisch z.B. über Rabatte, der Preis finalisiert werden.
### User Management
Nur bekannte User können die Daten editieren. Hierzu ist es notwendig die User zu verwalten.
User anlegen, pflegen und löschen. Zu einem User gibt es einen Namen, ein Login und ein Password.
### Datenbank-Sicherungen
#### Sicherung erstellen: