Datenbank Calls Asyn gemacht. Problem: OOP Style für Context Passthrough benutzt. Dazu sterben meine Goroutinen nicht bei STRG+C. Scheiße!
This commit is contained in:
parent
fee5dd1474
commit
9732096f53
@ -1,12 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gittea.marcokittel.de/elio/eliotools/datawriter/internal/api"
|
||||
@ -46,9 +49,17 @@ const (
|
||||
|
||||
func main() {
|
||||
connectionString := os.Getenv("CONNECTIONSTRING")
|
||||
nps := database.NewProductService(connectionString)
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer cancel()
|
||||
|
||||
// Brauche Context für Asyncrone Calls. Darum nutze ich DI. Ist ein Golang Antipattern :-(
|
||||
// Muss noch mehr Lernen um idiomatisch zu werden
|
||||
|
||||
nps := database.NewProductService(ctx, connectionString)
|
||||
|
||||
//Hier prüfe ich nach alten Registrierungen und gebe Sie frei.
|
||||
nps.Autorelease()
|
||||
|
||||
if len(connectionString) == 0 {
|
||||
fmt.Println("Connectionstring fehlt!. Bsp.: <user>:<passwort>@tcp(127.0.0.1:3306)/elio?parseTime=true")
|
||||
return
|
||||
@ -184,4 +195,5 @@ func main() {
|
||||
log.Printf("Easy Peasy: Die Party startet auf Port %s\n", port)
|
||||
log.Printf("Probiers mal damit: %s\n", curlhelp)
|
||||
log.Fatal(http.ListenAndServe(port, nil))
|
||||
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ import (
|
||||
type DatabaseWriter struct {
|
||||
log logger.Logger
|
||||
db *sql.DB
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
type DatabaseReader struct {
|
||||
@ -26,8 +27,9 @@ type DatabaseReader struct {
|
||||
|
||||
type UUID string
|
||||
|
||||
func NewDatabaseReader(connectionString string) *DatabaseReader {
|
||||
return &DatabaseReader{*NewDatabaseWriter(connectionString)}
|
||||
// Das ist ein Golang Design Flaw... Context so zu übergeben, bitte nicht hauen
|
||||
func NewDatabaseReader(ctx context.Context, connectionString string) *DatabaseReader {
|
||||
return &DatabaseReader{*NewDatabaseWriter(ctx, connectionString)}
|
||||
}
|
||||
|
||||
func (d *DatabaseWriter) connectDB(connectionString string) (*sql.DB, error) {
|
||||
@ -102,8 +104,9 @@ func (d *DatabaseWriter) createReservationTableIfNotExist() error {
|
||||
return err
|
||||
}
|
||||
|
||||
func NewDatabaseWriter(connectionString string) *DatabaseWriter {
|
||||
db := DatabaseWriter{log: logger.NewMarcoLogger()}
|
||||
// Brauche einen Context für Asyncrone Datenbank-Abfragen. Design Flaw by me :-()
|
||||
func NewDatabaseWriter(ctx context.Context, connectionString string) *DatabaseWriter {
|
||||
db := DatabaseWriter{log: logger.NewMarcoLogger(), ctx: ctx}
|
||||
sql, err := db.connectDB(connectionString)
|
||||
if err != nil {
|
||||
fmt.Printf("Datenbank nicht gefunden. %s", err)
|
||||
@ -139,7 +142,9 @@ func (d *DatabaseWriter) ReleaseReservierungenAfterOneDay() error {
|
||||
}
|
||||
|
||||
func (d *DatabaseWriter) UpdateOrInsertWarehouseProduct(warehouse string, productID string, amount int) error {
|
||||
_, err := d.db.Exec(`
|
||||
ctx, cancel := context.WithTimeout(d.ctx, 100*time.Millisecond)
|
||||
defer cancel()
|
||||
_, err := d.db.ExecContext(ctx, `
|
||||
INSERT INTO warehouseproducts (warehouse, productid, amount)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE amount = VALUES(amount)`,
|
||||
@ -152,7 +157,9 @@ func (d *DatabaseWriter) UpdateOrInsertWarehouseProduct(warehouse string, produc
|
||||
}
|
||||
|
||||
func (d *DatabaseWriter) UpdateOrInsertDelivery(fromcountry string, tocountry string, state string, delivery int) error {
|
||||
_, err := d.db.Exec(`
|
||||
ctx, cancel := context.WithTimeout(d.ctx, 100*time.Millisecond)
|
||||
defer cancel()
|
||||
_, err := d.db.ExecContext(ctx, `
|
||||
INSERT INTO deliverytimes (fromcountry, tocountry, state, delivery)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
@ -177,6 +184,8 @@ type ProductDelivery struct {
|
||||
}
|
||||
|
||||
func (d *DatabaseReader) GetProductByProductIdDeliveryCountryAndState(prod_id, delivery_country, delivery_country_state string) ([]ProductDelivery, error) {
|
||||
ctx, cancel := context.WithTimeout(d.ctx, 100*time.Millisecond)
|
||||
defer cancel()
|
||||
stmt := `
|
||||
SELECT id, warehouse, (amount - reserviert) amount, delivery, deliveryId FROM(
|
||||
SELECT whp.id, warehouse, whp.amount, sum(coalesce(r.amount,0) )reserviert, d.delivery, d.id deliveryId
|
||||
@ -195,7 +204,7 @@ func (d *DatabaseReader) GetProductByProductIdDeliveryCountryAndState(prod_id, d
|
||||
having amount > 0
|
||||
`
|
||||
|
||||
rows, err := d.db.Query(stmt, prod_id, delivery_country, delivery_country_state)
|
||||
rows, err := d.db.QueryContext(ctx, stmt, prod_id, delivery_country, delivery_country_state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -212,10 +221,12 @@ func (d *DatabaseReader) GetProductByProductIdDeliveryCountryAndState(prod_id, d
|
||||
}
|
||||
|
||||
func (d *DatabaseReader) GetReservationStateById(productId UUID) (string, error) {
|
||||
ctx, cancel := context.WithTimeout(d.ctx, 100*time.Millisecond)
|
||||
defer cancel()
|
||||
stmt := `
|
||||
SELECT status FROM reservations WHERE id = ?
|
||||
`
|
||||
row, err := d.db.Query(stmt, productId)
|
||||
row, err := d.db.QueryContext(ctx, stmt, productId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -230,10 +241,12 @@ func (d *DatabaseReader) GetReservationStateById(productId UUID) (string, error)
|
||||
}
|
||||
|
||||
func (d *DatabaseReader) GetReservationItemsByGroupId(groupId UUID) (string, error) {
|
||||
ctx, cancel := context.WithTimeout(d.ctx, 100*time.Millisecond)
|
||||
defer cancel()
|
||||
stmt := `
|
||||
SELECT status FROM reservations WHERE id = ?
|
||||
`
|
||||
row, err := d.db.Query(stmt, groupId)
|
||||
row, err := d.db.QueryContext(ctx, stmt, groupId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -248,7 +261,9 @@ func (d *DatabaseReader) GetReservationItemsByGroupId(groupId UUID) (string, err
|
||||
}
|
||||
|
||||
func (d *DatabaseWriter) updateReservationState(Id UUID, status string) error {
|
||||
_, err := d.db.Exec("UPDATE reservations SET Status=? WHERE id=?", status, Id)
|
||||
ctx, cancel := context.WithTimeout(d.ctx, 100*time.Millisecond)
|
||||
defer cancel()
|
||||
_, err := d.db.ExecContext(ctx, "UPDATE reservations SET Status=? WHERE id=?", status, Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -256,7 +271,9 @@ func (d *DatabaseWriter) updateReservationState(Id UUID, status string) error {
|
||||
}
|
||||
|
||||
func (d *DatabaseWriter) updateReservationStateByGroupId(groupId UUID, status string) error {
|
||||
_, err := d.db.Exec("UPDATE reservations SET Status=? WHERE reservationGroupId=?", status, groupId)
|
||||
ctx, cancel := context.WithTimeout(d.ctx, 100*time.Millisecond)
|
||||
defer cancel()
|
||||
_, err := d.db.ExecContext(ctx, "UPDATE reservations SET Status=? WHERE reservationGroupId=?", status, groupId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
@ -82,7 +83,8 @@ func Setup(dbr *DatabaseReader) error {
|
||||
}
|
||||
|
||||
func TestDatabaseConnection(t *testing.T) {
|
||||
var dbr = NewDatabaseReader(connectionString)
|
||||
ctx := context.Background()
|
||||
var dbr = NewDatabaseReader(ctx, connectionString)
|
||||
err := dbr.db.Ping()
|
||||
if err != nil {
|
||||
t.Errorf("Datenbankverbindung fehlgeschlagen! %s", err)
|
||||
@ -90,7 +92,8 @@ func TestDatabaseConnection(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSelectStatementNoDatasetsAvailable(t *testing.T) {
|
||||
var dbr = NewDatabaseReader(connectionString)
|
||||
ctx := context.Background()
|
||||
var dbr = NewDatabaseReader(ctx, connectionString)
|
||||
err := Setup(dbr)
|
||||
if err != nil {
|
||||
t.Errorf("Setup failed! %s", err)
|
||||
@ -102,7 +105,8 @@ func TestSelectStatementNoDatasetsAvailable(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSelectStatement(t *testing.T) {
|
||||
var dbr = NewDatabaseReader(connectionString)
|
||||
ctx := context.Background()
|
||||
var dbr = NewDatabaseReader(ctx, connectionString)
|
||||
data, err := dbr.GetProductByProductIdDeliveryCountryAndState("A6053", "EU", "")
|
||||
if err != nil {
|
||||
t.Errorf("Es sollten Datensätze auffinbdar sein! %s", err)
|
||||
@ -121,7 +125,8 @@ func TestSelectStatement(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInsertStatement(t *testing.T) {
|
||||
var dbr = NewDatabaseReader(connectionString)
|
||||
ctx := context.Background()
|
||||
var dbr = NewDatabaseReader(ctx, connectionString)
|
||||
data, err := dbr.GetProductByProductIdDeliveryCountryAndState("A6053", "EU", "")
|
||||
if err != nil {
|
||||
t.Errorf("Es sollten Datensätze auffinbdar sein! %s", err)
|
||||
@ -140,7 +145,8 @@ func TestInsertStatement(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAbortReservationStatement(t *testing.T) {
|
||||
var dbr = NewDatabaseReader(connectionString)
|
||||
ctx := context.Background()
|
||||
var dbr = NewDatabaseReader(ctx, connectionString)
|
||||
data, err := dbr.GetProductByProductIdDeliveryCountryAndState("A6053", "EU", "")
|
||||
if err != nil {
|
||||
t.Errorf("Es sollten Datensätze auffinbdar sein! %s", err)
|
||||
@ -166,7 +172,8 @@ func TestAbortReservationStatement(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConfirmReservationStatement(t *testing.T) {
|
||||
var dbr = NewDatabaseReader(connectionString)
|
||||
ctx := context.Background()
|
||||
var dbr = NewDatabaseReader(ctx, connectionString)
|
||||
data, err := dbr.GetProductByProductIdDeliveryCountryAndState("A6053", "EU", "")
|
||||
if err != nil {
|
||||
t.Errorf("Es sollten Datensätze auffinbdar sein! %s", err)
|
||||
@ -192,7 +199,8 @@ func TestConfirmReservationStatement(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestReleasedReservationStatement(t *testing.T) {
|
||||
var dbr = NewDatabaseReader(connectionString)
|
||||
ctx := context.Background()
|
||||
var dbr = NewDatabaseReader(ctx, connectionString)
|
||||
data, err := dbr.GetProductByProductIdDeliveryCountryAndState("A6053", "EU", "")
|
||||
if err != nil {
|
||||
t.Errorf("Es sollten Datensätze auffinbdar sein! %s", err)
|
||||
@ -225,7 +233,8 @@ func TestFetchReservationData(t *testing.T) {
|
||||
t.Errorf("Dieser Fehler beim Konvertieren der JSON Payload sollte nicht passieren! \n%s", err)
|
||||
return
|
||||
}
|
||||
ps := NewProductService(connectionString)
|
||||
ctx := context.Background()
|
||||
ps := NewProductService(ctx, connectionString)
|
||||
// groupId := uuid.New().String()
|
||||
op, err := ps.FetchData(&payload)
|
||||
log.Println(op)
|
||||
@ -240,7 +249,8 @@ func TestFetchDataReservation(t *testing.T) {
|
||||
t.Errorf("Dieser Fehler beim Konvertieren der JSON Payload sollte nicht passieren! \n%s", err)
|
||||
return
|
||||
}
|
||||
ps := NewProductService(connectionString)
|
||||
ctx := context.Background()
|
||||
ps := NewProductService(ctx, connectionString)
|
||||
groupId := uuid.New().String()
|
||||
op, err := ps.FetchReservationData(&payload, UUID(groupId))
|
||||
if err != nil {
|
||||
@ -261,7 +271,8 @@ func TestFetchDataReservationVarition2(t *testing.T) {
|
||||
t.Errorf("Dieser Fehler beim Konvertieren der JSON Payload sollte nicht passieren! \n%s", err)
|
||||
return
|
||||
}
|
||||
ps := NewProductService(connectionString)
|
||||
ctx := context.Background()
|
||||
ps := NewProductService(ctx, connectionString)
|
||||
op, err := ps.FetchData(&payload)
|
||||
if err != nil {
|
||||
t.Errorf("Das Datafetchen und umwandeln in eine Map muss sauber funktionieren! %s", err)
|
||||
@ -281,7 +292,8 @@ func TestFetchDataReservationVarition3(t *testing.T) {
|
||||
t.Errorf("Dieser Fehler beim Konvertieren der JSON Payload sollte nicht passieren! \n%s", err)
|
||||
return
|
||||
}
|
||||
ps := NewProductService(connectionString)
|
||||
ctx := context.Background()
|
||||
ps := NewProductService(ctx, connectionString)
|
||||
op, err := ps.FetchData(&payload)
|
||||
if err != nil {
|
||||
t.Errorf("Das Datafetchen und umwandeln in eine Map muss sauber funktionieren! %s", err)
|
||||
@ -301,7 +313,8 @@ func TestOutgoingJsonString(t *testing.T) {
|
||||
t.Errorf("Dieser Fehler beim Konvertieren der JSON Payload sollte nicht passieren! \n%s", err)
|
||||
return
|
||||
}
|
||||
ps := NewProductService(connectionString)
|
||||
ctx := context.Background()
|
||||
ps := NewProductService(ctx, connectionString)
|
||||
op, err := ps.FetchData(&payload)
|
||||
if err != nil {
|
||||
t.Errorf("Das Datafetchen und umwandeln in eine Map muss sauber funktionieren! %s", err)
|
||||
@ -320,7 +333,8 @@ func TestOutgoingJsonString(t *testing.T) {
|
||||
func TestOutgoingReservationInDatabase(t *testing.T) {
|
||||
//Löscht die Tabellen und erzeugt die Testdaten neu.
|
||||
//Das Verbessert den Überblick
|
||||
var dbr = NewDatabaseReader(connectionString)
|
||||
ctx := context.Background()
|
||||
var dbr = NewDatabaseReader(ctx, connectionString)
|
||||
err := Setup(dbr)
|
||||
|
||||
if err != nil {
|
||||
@ -335,7 +349,7 @@ func TestOutgoingReservationInDatabase(t *testing.T) {
|
||||
return
|
||||
}
|
||||
groupId := uuid.New().String()
|
||||
ps := NewProductService(connectionString)
|
||||
ps := NewProductService(ctx, connectionString)
|
||||
op, err := ps.FetchReservationData(&payload, UUID(groupId))
|
||||
if err != nil {
|
||||
t.Errorf("Das Datafetchen und umwandeln in eine Map muss sauber funktionieren! %s", err)
|
||||
|
||||
@ -4,6 +4,8 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type ProductService struct {
|
||||
@ -49,8 +51,8 @@ type Context struct {
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
func NewProductService(connectionString string) *ProductService {
|
||||
dbr := NewDatabaseReader(connectionString)
|
||||
func NewProductService(ctx context.Context, connectionString string) *ProductService {
|
||||
dbr := NewDatabaseReader(ctx, connectionString)
|
||||
p := ProductService{dbr: dbr}
|
||||
return &p
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user