package db import ( "fmt" "reflect" "log" "git.belvedersky.ru/common/logger" "git.belvedersky.ru/common/logger/service" _ "github.com/jackc/pgx/stdlib" "github.com/jmoiron/sqlx" ) type DbConfig struct { Host string // Хост Port string // Порт User string // Пользователь Password string // Пароль Db string // База } type PostgresRepository struct { postgres *sqlx.DB logger *service.LoggerService Err service.TypeError } // Сервис для работы с базой func New(cfg *DbConfig, l *logger.Logger) *PostgresRepository { conn := fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=disable", cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.Db) db, err := sqlx.Connect("pgx", conn) if err != nil { log.Fatalf("%v Ошибка подключения бд: %v", conn, err.Error()) } return &PostgresRepository{postgres: db, logger: (*service.LoggerService)(l.Create("db")), Err: service.TypeError{Code: 500, Description: "Postgres Error"}} } func (s *PostgresRepository) GetDb() *sqlx.DB { return s.postgres } func (s *PostgresRepository) GetLog() *service.LoggerService { return s.logger } func (s *PostgresRepository) Close() { if err := s.postgres.Close(); err != nil { s.logger.Error(service.LogErrorStruct{Error: s.Err, Message: err.Error()}) } } func (s *PostgresRepository) Batch(query string, data []interface{}) error { tx, err := s.postgres.Beginx() if err != nil { return err } v := reflect.ValueOf(data[0]) maxBulkInsert := ((1 << 16) / v.NumField()) - 1 for i := 0; i < len(data); i += maxBulkInsert { batch := data[i:min(i+maxBulkInsert, len(data))] _, err := tx.NamedExec(query, batch) if err != nil { e := tx.Rollback() if e != nil { log.Printf("Couldn't rollback %+v", e) } log.Println(err) } } err = tx.Commit() if err != nil { e := tx.Rollback() if e != nil { log.Printf("Couldn't rollback %+v", err) } log.Printf("Couldn't commit %+v", err) } return nil } func min(a, b int) int { if a <= b { return a } return b }