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 }