diff --git a/database/database.go b/database/database.go new file mode 100644 index 0000000..371e898 --- /dev/null +++ b/database/database.go @@ -0,0 +1,151 @@ +package database + +import ( + "context" + "database/sql" + "fmt" + "os" + "strconv" + "strings" + "sync" + "time" + + _ "github.com/go-sql-driver/mysql" + "gittea.marcokittel.de/elio/eliotools/eliofile" + "gittea.marcokittel.de/elio/eliotools/logger" +) + +type DatabaseWriter struct { + wg *sync.WaitGroup + mu sync.Mutex + log logger.Logger + db *sql.DB +} + +func (d *DatabaseWriter) connectDB() (*sql.DB, error) { + db, err := sql.Open("mysql", "root:eliogeheim@tcp(127.0.0.1:3306)/elio?parseTime=true") + if err != nil { + return nil, err + } + + // Verbindungspool konfigurieren + db.SetMaxOpenConns(40) + db.SetMaxIdleConns(25) + db.SetConnMaxLifetime(5 * time.Minute) + + return db, nil +} + +func (d *DatabaseWriter) createWarehouseTableIfNotExist() error { + _, err := d.db.Exec(` + CREATE TABLE IF NOT EXISTS warehouseproducts ( + id INT AUTO_INCREMENT PRIMARY KEY, + warehouse char(2) NOT NULL, + productid VARCHAR(20) NOT NULL, + amount INT DEFAULT 0, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT location_product_must_be_one UNIQUE (warehouse, productid) + ) ENGINE=InnoDB; + `) + return err +} + +func (d *DatabaseWriter) createDeliveryTableIfNotExist() error { + + _, err := d.db.Exec(` + CREATE TABLE IF NOT EXISTS deliverytimes ( + id INT AUTO_INCREMENT PRIMARY KEY, + fromcountry varchar(4) NOT NULL, + tocountry varchar(4) NOT NULL, + state varchar(4) NULL, + delivery INT DEFAULT 0, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT delivery_from_to_country_must_be_one UNIQUE (fromcountry, tocountry) + ) ENGINE=InnoDB;`) + return err +} + +func NewDatabaseWriter(wg *sync.WaitGroup) *DatabaseWriter { + db := DatabaseWriter{log: logger.NewMarcoLogger(), + wg: wg, + } + sql, err := db.connectDB() + if err != nil { + fmt.Printf("Datenbank nicht gefunden. %w", err) + os.Exit(1) + } + db.db = sql + err = db.createWarehouseTableIfNotExist() + if err != nil { + fmt.Printf("Warenhaus-Tabellen-Erstellung fehlgeschlagen. %w", err) + os.Exit(1) + } + err = db.createDeliveryTableIfNotExist() + if err != nil { + fmt.Printf("Delivery-Tablellen-Erstellung fehlgeschlagen. %w", err) + os.Exit(1) + } + return &db +} + +func (d *DatabaseWriter) UpdateOrInsertWarehouseProduct(warehouse string, productID string, amount int) error { + _, err := d.db.Exec(` + INSERT INTO warehouseproducts (warehouse, productid, amount) + VALUES (?, ?, ?) + ON DUPLICATE KEY UPDATE amount = VALUES(amount)`, + warehouse, productID, amount) + + if err != nil { + return fmt.Errorf("upsert failed: %w", err) + } + return nil +} + +func (d *DatabaseWriter) UpdateOrInsertDelivery(fromcountry string, tocountry string, state string, delivery int) error { + _, err := d.db.Exec(` + INSERT INTO deliverytimes (fromcountry, tocountry, state, delivery) + VALUES (?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + fromcountry = VALUES(fromcountry), + tocountry = VALUES(tocountry), + state = VALUES(state), + delivery = VALUES(delivery)`, + fromcountry, tocountry, state, delivery) + + if err != nil { + return fmt.Errorf("upsert failed: %w", err) + } + return nil +} + +func (db *DatabaseWriter) HandleData(ctx context.Context, data eliofile.CountryCsvData) error { + // a.log.Info("HandleData") + if strings.Contains(strings.Join(data.Data, ","), "product_id") || strings.Contains(strings.Join(data.Data, ","), "delivery_time") { + return nil + } + //Todo: Csv reparieren. + switch data.Type { + case "stock": + { + menge := strings.Split(data.Data[0], ";") + amount, err := strconv.Atoi(menge[1]) + if err != nil { + fmt.Println(err) + return err + } + db.UpdateOrInsertWarehouseProduct(data.CountryID, menge[0], amount) + } + case "delivery": + { + menge := strings.Split(data.Data[0], ";") + amount, err := strconv.Atoi(menge[2]) + if err != nil { + fmt.Println(err) + return err + } + db.UpdateOrInsertDelivery(data.CountryID, menge[0], menge[1], amount) + } + } + + return nil +} diff --git a/database/go.mod b/database/go.mod new file mode 100644 index 0000000..8c9d650 --- /dev/null +++ b/database/go.mod @@ -0,0 +1,14 @@ +module gittea.marcokittel.de/elio/eliotools/database + +go 1.24.4 + +require ( + github.com/go-sql-driver/mysql v1.9.3 + gittea.marcokittel.de/elio/eliotools/eliofile v0.0.0-20250629191242-28cf9d7acd9a + gittea.marcokittel.de/elio/eliotools/logger v0.0.0-20250629191242-28cf9d7acd9a +) + +require ( + filippo.io/edwards25519 v1.1.0 // indirect + gittea.marcokittel.de/elio/eliotools/tools v0.0.0-20250626204134-2c2a5a5f5193 // indirect +) diff --git a/database/go.sum b/database/go.sum new file mode 100644 index 0000000..3b3ead6 --- /dev/null +++ b/database/go.sum @@ -0,0 +1,10 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +gittea.marcokittel.de/elio/eliotools/eliofile v0.0.0-20250629191242-28cf9d7acd9a h1:zzkfJpddfoER94d77tcGXvAw3w8Ci2L17D/jszxQ1cI= +gittea.marcokittel.de/elio/eliotools/eliofile v0.0.0-20250629191242-28cf9d7acd9a/go.mod h1:h9FfBWQD/1+fF3sFaYN89K3xH54t3LHKBKQj8YiAjnU= +gittea.marcokittel.de/elio/eliotools/logger v0.0.0-20250629191242-28cf9d7acd9a h1:ww1uKtxSa5VrBhGRBHreOt9VaIDdGSFy0bTBljk/w7E= +gittea.marcokittel.de/elio/eliotools/logger v0.0.0-20250629191242-28cf9d7acd9a/go.mod h1:WDmnG6o72HhGTSkgwj2kXYcRL2MaNFNsKNBeTh6NIzo= +gittea.marcokittel.de/elio/eliotools/tools v0.0.0-20250626204134-2c2a5a5f5193 h1:QOq2tQjE0ViQ31r/eBMUgjnRMth5ZPwoR4L794EzdJs= +gittea.marcokittel.de/elio/eliotools/tools v0.0.0-20250626204134-2c2a5a5f5193/go.mod h1:jJvuXliNOiG9i8VXrY9vK5Bqv9QwDtswCs3CNIIBvUQ=