package storage import ( "database/sql" "fmt" "github.com/google/uuid" _ "github.com/lib/pq" "github.com/rs/zerolog/log" "github.com/spf13/viper" "strconv" "strings" ) type PostgresqlStorage struct { DbConnection *sql.DB Schema string Tables map[string]string } func NewPostgresqlStorage(cfg *viper.Viper) (PostgresqlStorage, error) { var ( host = cfg.GetString("storage.db.psql.host") port = cfg.GetString("storage.db.psql.port") user = cfg.GetString("storage.db.psql.user") password = cfg.GetString("storage.db.psql.password") dbname = cfg.GetString("storage.db.psql.dbname") sslmode = cfg.GetString("storage.db.psql.sslmode") pg_schema = cfg.GetString("storage.db.psql.schema") pgtables_users_firebase = cfg.GetString("storage.db.psql.tables.users_firebase") ) portInt, _ := strconv.Atoi(port) psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", host, portInt, user, password, dbname, sslmode) db, err := sql.Open("postgres", psqlconn) if err != nil { log.Error().Err(err).Msg("opening connection to postgresql failed") return PostgresqlStorage{}, fmt.Errorf("connection to postgresql failed") } err = db.Ping() if err != nil { log.Error().Err(err).Msg("ping to postgresql failed") return PostgresqlStorage{}, fmt.Errorf("connection to postgresql database failed") } return PostgresqlStorage{ DbConnection: db, Schema: pg_schema, Tables: map[string]string{ "users_firebase": fmt.Sprintf("%s.%s", pg_schema, pgtables_users_firebase), }, }, nil } func (s PostgresqlStorage) CreateFirebaseToken(user_id string, fcm_token string, device_platform string) (err error) { _, err = uuid.Parse(user_id) if err != nil { log.Error().Err(err).Msg("Postgresql Storage CreateFirebaseToken invalid User ID") return err } _, err = s.DbConnection.Exec(fmt.Sprintf("INSERT INTO %s (user_id , fcm_token , device_platform) VALUES($1,$2,$3)", s.Tables["users_firebase"]), user_id, fcm_token, device_platform) if err != nil { if strings.Contains(err.Error(), "duplicate key") { _ = s.UpdateFirebaseToken(user_id, device_platform, fcm_token) } } return nil } func (s PostgresqlStorage) GetFirebaseToken(user_id string) (fcm string, device_platform string, err error) { err = s.DbConnection.QueryRow(fmt.Sprintf("SELECT fcm_token , device_platform FROM %s WHERE user_id = $1", s.Tables["users_firebase"]), user_id). Scan( &fcm, &device_platform, ) if err != nil { return "", "", err } return fcm, device_platform, nil } func (s PostgresqlStorage) UpdateFirebaseToken(user_id string, fcm_token string, device_platform string) error { query := fmt.Sprintf("UPDATE %s SET fcm_token = $1 device_platform = $2 WHERE user_id = $3", s.Tables["users_firebase"]) _, err := s.DbConnection.Exec(query, fcm_token, device_platform, user_id) if err != nil { return err } return nil }