package database import ( "crowsnest/internal/model" "database/sql" ) type ResponseModel struct { DB *sql.DB } // Get all the response object from the database. May throw an error if the // connection to the database fails. func (m *ResponseModel) All() ([]model.Response, error) { stmt := ` SELECT url, content, fetchDate, processed FROM responses ` rows, err := m.DB.Query(stmt) if err != nil { return nil, err } responses := []model.Response{} for rows.Next() { r := model.Response{} err := rows.Scan(&r.Url, &r.Content, &r.FetchDate, &r.Processed) if err != nil { return nil, err } responses = append(responses, r) } if err = rows.Err(); err != nil { return nil, err } return responses, nil } // Gets all those Response objects where the processed column is set to false. // May throw an error if the connection to the database fails. func (m *ResponseModel) UnprocessedUrls() ([]string, error) { stmt := ` SELECT url FROM responses WHERE NOT processed ` rows, err := m.DB.Query(stmt) if err != nil { return nil, err } urls := make([]string, 0) for rows.Next() { r := "" err := rows.Scan(&r) if err != nil { return nil, err } urls = append(urls, r) } if err = rows.Err(); err != nil { return nil, err } return urls, nil } // Checks if a given url exits in the database as a response. This may throw an // error if the connection to the database fails. func (m *ResponseModel) UrlExists(url string) (bool, error) { stmt := ` SELECT count(url) > 0 FROM responses WHERE url = $1 ` var result bool row := m.DB.QueryRow(stmt, url) err := row.Scan(&result) return result, err } // Gets a certain Response object by the unique url. This may throw an error if // there does not exist an response with the given url or the connection to the // database fails. func (m *ResponseModel) GetByUrl(url string) (model.Response, error) { stmt := ` SELECT url, content, fetchDate, processed FROM responses WHERE url = $1 ` res := model.Response{} row := m.DB.QueryRow(stmt, url) err := row.Scan(&res.Url, &res.Content, &res.FetchDate, &res.Processed) return res, err } // Inserts a new response object into the database given the url and response // body. This may fail on an unique contraint of the url or the connection to // the database. func (m *ResponseModel) Insert(url string, content []byte) error { // insert response stmt := `INSERT INTO responses (url, content) VALUES ($1, $2)` _, err := m.DB.Exec(stmt, url, content) return err } // Updates a response object in the database using the url of the given response // object as the id. This may throw an error if connection to the database // fails. func (m *ResponseModel) Update(res *model.Response) error { // insert response stmt := `UPDATE responses SET content = $1, fetchDate = $2, processed = $3 WHERE url = $4` _, err := m.DB.Exec(stmt, res.Content, res.FetchDate, res.Processed, res.Url) return err } // Sets the processed column of a certain response entry in the database, given // an url, to true. This may fail if the connection to the database fails. func (m *ResponseModel) Processed(url string) error { // insert response stmt := `UPDATE responses SET processed = true WHERE url = $1` _, err := m.DB.Exec(stmt, url) return err }