package postgres import ( "database/sql" "encoding/json" "fmt" "log" "os" "github.com/lib/pq" "../news" "../utils" ) type Postgres struct { host string port int username string password string database string psqlInfo string psqlConn *sql.DB isConnected bool } var pg *Postgres func init() { var err error pg = &Postgres{ host: os.Getenv("POSTGRES_HOST"), port: utils.AtoI(os.Getenv("POSTGRES_PORT")), username: os.Getenv("POSTGRES_USERNAME"), password: os.Getenv("POSTGRES_PASSWORD"), database: os.Getenv("POSTGRES_DATABASE"), } pg.psqlInfo = fmt.Sprintf( "host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", pg.host, pg.port, pg.username, pg.password, pg.database, ) pg.psqlConn, err = sql.Open("postgres", pg.psqlInfo) if err != nil { log.Fatalf("error while opening pg connection : %s", err) } if err = pg.psqlConn.Ping(); err != nil { log.Fatalf("error while pinging pg server : %s", err) } pg.isConnected = true } func Close() { if !pg.isConnected { return } if err := pg.psqlConn.Close(); err != nil { log.Fatalf("error while closing pg connection : %s", err) } pg.isConnected = false } func ListSports() ([]*news.Sport, error) { var sports []*news.Sport rows, err := pg.psqlConn.Query("SELECT id, name, clean_name FROM public.mainapp_sport") if err != nil { return nil, fmt.Errorf("error while querying postgres : %s", err) } for rows.Next() { sport := &news.Sport{} err = rows.Scan(&sport.Id, &sport.Name, &sport.CleanName) if err != nil { return nil, fmt.Errorf("error while scanning row from postgres : %s", err) } sports = append(sports, sport) } return sports, nil } func ListSources() ([]*news.Source, error) { var sources []*news.Source rows, err := pg.psqlConn.Query("SELECT id, name, clean_name, urls FROM public.mainapp_source") if err != nil { return nil, fmt.Errorf("error while querying postgres : %s", err) } for rows.Next() { source := &news.Source{} sourceUrls := "" err = rows.Scan(&source.Id, &source.Name, &source.CleanName, &sourceUrls) if err != nil { return nil, fmt.Errorf("error while scanning row from postgres : %s", err) } if err = json.Unmarshal([]byte(sourceUrls), &source.Urls); err != nil { return nil, fmt.Errorf("error while scanning row from postgres : %s", err) } sources = append(sources, source) } return sources, nil } func InsertNews(n *news.News) error { err := pg.psqlConn.QueryRow(` INSERT INTO public.mainapp_news (title, clean_title, link, pub_date, description, image, teaser, author, content, redirect, haystack, tags, clean_tags, error, trace, league_id, source_id, sport_id, team_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19) RETURNING id `, n.Title, n.CleanTitle, n.Link, n.PubDate, utils.NullableString(n.Description), utils.NullableString(n.Image), utils.NullableString(n.Teaser), utils.NullableString(n.Author), pq.Array(n.Content), utils.NullableString(n.Redirect), utils.NullableString(n.Haystack), pq.Array(n.Tags), pq.Array(n.CleanTags), utils.NullableString(n.Error), utils.NullableString(n.Trace), utils.NullableInt(n.LeagueId), n.Source.Id, n.Sport.Id, utils.NullableInt(n.TeamId), ).Scan(&n.Id) if err != nil { return err } return nil } func UpdateNews(n *news.News) error { if _, err := pg.psqlConn.Exec(` UPDATE public.mainapp_news SET title = $1, clean_title = $2, pub_date = $3, link = $4, description = $5, image = $6, teaser = $7, author = $8, content = $9, redirect = $10, haystack = $11, tags = $12, clean_tags = $13, error = $14, trace = $15, league_id = $16, source_id = $17, sport_id = $18, team_id = $19 WHERE id = $20 `, n.Title, n.CleanTitle, n.PubDate, n.Link, utils.NullableString(n.Description), utils.NullableString(n.Image), utils.NullableString(n.Teaser), utils.NullableString(n.Author), pq.Array(n.Content), utils.NullableString(n.Redirect), utils.NullableString(n.Haystack), pq.Array(n.Tags), pq.Array(n.CleanTags), utils.NullableString(n.Error), utils.NullableString(n.Trace), utils.NullableInt(n.LeagueId), n.Source.Id, n.Sport.Id, utils.NullableInt(n.TeamId), n.Id, ); err != nil { return err } return nil }