110 lines
2.7 KiB
Go
110 lines
2.7 KiB
Go
package databases
|
||
|
||
import (
|
||
"database/sql"
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"sync"
|
||
|
||
_ "github.com/go-sql-driver/mysql"
|
||
)
|
||
|
||
type Database struct {
|
||
db *sql.DB
|
||
mux sync.Mutex
|
||
}
|
||
|
||
// NewSQLDatabase создает новое соединение с базой данных
|
||
func NewSQLDatabase() *Database {
|
||
d := &Database{}
|
||
var err error
|
||
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s",
|
||
os.Getenv("MARIADB_USER"),
|
||
os.Getenv("MARIADB_PWD"),
|
||
os.Getenv("MARIADB_HOST"),
|
||
os.Getenv("MARIADB_PORT"),
|
||
os.Getenv("MARIADB_NAME"),
|
||
)
|
||
d.db, err = sql.Open("mysql", dsn)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
err = d.db.Ping()
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
return d
|
||
}
|
||
|
||
// Query выполняет запрос к базе данных и возвращает строки результата
|
||
func (d *Database) Query(query string) (*sql.Rows, error) {
|
||
d.mux.Lock()
|
||
defer d.mux.Unlock()
|
||
|
||
rows, err := d.db.Query(query)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return rows, nil
|
||
}
|
||
|
||
// Exec выполняет запрос к базе данных без возврата результата
|
||
func (d *Database) Exec(query string, args ...interface{}) error {
|
||
d.mux.Lock()
|
||
defer d.mux.Unlock()
|
||
|
||
_, err := d.db.Exec(query, args...)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// Insert выполняет вставку данных в указанную таблицу
|
||
func (d *Database) Insert(table string, columns []string, values []interface{}) error {
|
||
if len(columns) == 0 || len(values) == 0 {
|
||
return fmt.Errorf("columns and values must not be empty")
|
||
}
|
||
if len(columns) != len(values) {
|
||
return fmt.Errorf("the number of columns must match the number of values")
|
||
}
|
||
|
||
columnsStr := fmt.Sprintf("(%s)", joinStrings(columns, ", "))
|
||
valuesPlaceholders := fmt.Sprintf("(%s)", joinStrings(makePlaceholders(len(values)), ", "))
|
||
|
||
query := fmt.Sprintf("INSERT INTO %s %s VALUES %s", table, columnsStr, valuesPlaceholders)
|
||
return d.Exec(query, values...)
|
||
}
|
||
|
||
// Close закрывает соединение с базой данных
|
||
func (d *Database) Close() {
|
||
d.mux.Lock()
|
||
defer d.mux.Unlock()
|
||
|
||
if err := d.db.Close(); err != nil {
|
||
log.Println("Error closing the database connection:", err)
|
||
}
|
||
}
|
||
|
||
// joinStrings объединяет строки с указанным разделителем
|
||
func joinStrings(elements []string, delimiter string) string {
|
||
result := ""
|
||
for i, element := range elements {
|
||
if i > 0 {
|
||
result += delimiter
|
||
}
|
||
result += element
|
||
}
|
||
return result
|
||
}
|
||
|
||
// makePlaceholders создает строковые заполнители для значений
|
||
func makePlaceholders(n int) []string {
|
||
placeholders := make([]string, n)
|
||
for i := range placeholders {
|
||
placeholders[i] = "?"
|
||
}
|
||
return placeholders
|
||
}
|