change db from sqlite3 to postgresql
This commit is contained in:
@@ -5,13 +5,12 @@ import (
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
// TODO docstring
|
||||
type ArticleModel struct {
|
||||
DB *sql.DB
|
||||
DbDriver string
|
||||
DB *sql.DB
|
||||
}
|
||||
|
||||
// TODO docstring
|
||||
// Gets all the article objects from the database. This may throw an error if
|
||||
// the connection to the database fails.
|
||||
func (m *ArticleModel) All() ([]model.Article, error) {
|
||||
stmt := `
|
||||
SELECT id, title, sourceUrl, author, content, publishDate, fetchDate
|
||||
@@ -41,16 +40,18 @@ func (m *ArticleModel) All() ([]model.Article, error) {
|
||||
return articles, nil
|
||||
}
|
||||
|
||||
// TODO docstring
|
||||
// Will use the full-text search features of the underlying database to search
|
||||
// articles for a given search query. This may fail if the connection to the
|
||||
// database fails.
|
||||
func (m *ArticleModel) Search(query string) ([]model.Article, error) {
|
||||
stmt := `
|
||||
SELECT id, title, sourceUrl, author, content, publishDate, fetchDate
|
||||
FROM articles JOIN (
|
||||
SELECT id as id2, rank FROM fts_articles WHERE content MATCH ?
|
||||
) ON id = id2
|
||||
ORDER BY rank ASC, publishDate DESC
|
||||
LIMIT 10
|
||||
`
|
||||
SELECT id, title, sourceurl, author, content, publishdate, fetchDate
|
||||
FROM articles
|
||||
WHERE fts_vector @@ to_tsquery('german', $1)
|
||||
ORDER BY ts_rank(fts_vector, to_tsquery('german', $1)) DESC
|
||||
LIMIT 10
|
||||
`
|
||||
|
||||
rows, err := m.DB.Query(stmt, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -70,7 +71,6 @@ func (m *ArticleModel) Search(query string) ([]model.Article, error) {
|
||||
if err = rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return articles, nil
|
||||
}
|
||||
|
||||
@@ -78,55 +78,20 @@ func (m *ArticleModel) Search(query string) ([]model.Article, error) {
|
||||
// article will be ignored. May throw an error if the execution of the database
|
||||
// query fails.
|
||||
func (m *ArticleModel) Insert(a *model.Article) error {
|
||||
// begin transaction
|
||||
_, err := m.DB.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// insert article
|
||||
stmt := `INSERT INTO articles (title, sourceUrl, author, content, publishDate, fetchDate)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
`
|
||||
result, err := m.DB.Exec(stmt, a.Title, a.SourceUrl, a.Author, a.Content, a.PublishDate, a.FetchDate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lastId, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// insert into fts_articles for full-text search
|
||||
stmt = `INSERT INTO fts_articles (id, content)
|
||||
VALUES (?, ? || '\n' || ? || '\n' || ?)
|
||||
`
|
||||
_, err = m.DB.Exec(stmt, lastId, a.Title, a.Author, a.Content)
|
||||
_, err := m.DB.Exec(stmt, a.Title, a.SourceUrl, a.Author, a.Content, a.PublishDate, a.FetchDate)
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO docstring
|
||||
func (m *ArticleModel) Update(a *model.Article) error {
|
||||
// begin transaction
|
||||
_, err := m.DB.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// insert article
|
||||
stmt := `UPDATE articles
|
||||
SET title = ?, sourceUrl = ?, author = ?, content = ?, publishDate = ?, fetchDate = ?
|
||||
WHERE id = ?
|
||||
SET title = $1, sourceUrl = $2, author = $3, content = $4, publishDate = $5, fetchDate = $6
|
||||
WHERE id = $7
|
||||
`
|
||||
_, err = m.DB.Exec(stmt, a.Title, a.SourceUrl, a.Author, a.Content, a.PublishDate, a.FetchDate, a.Identifier)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// insert into fts_articles for full-text search
|
||||
stmt = `INSERT INTO fts_articles (id, content)
|
||||
VALUES (?, ? || '\n' || ? || '\n' || ?)
|
||||
`
|
||||
_, err = m.DB.Exec(stmt, a.Identifier, a.Title, a.Author, a.Content)
|
||||
_, err := m.DB.Exec(stmt, a.Title, a.SourceUrl, a.Author, a.Content, a.PublishDate, a.FetchDate, a.Identifier)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import (
|
||||
)
|
||||
|
||||
type ResponseModel struct {
|
||||
DB *sql.DB
|
||||
DbDriver string
|
||||
DB *sql.DB
|
||||
}
|
||||
|
||||
// TODO docstring
|
||||
// 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
|
||||
@@ -39,7 +39,8 @@ func (m *ResponseModel) All() ([]model.Response, error) {
|
||||
return responses, nil
|
||||
}
|
||||
|
||||
// TODO docstring
|
||||
// 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
|
||||
@@ -69,12 +70,28 @@ func (m *ResponseModel) UnprocessedUrls() ([]string, error) {
|
||||
return urls, nil
|
||||
}
|
||||
|
||||
// TODO docstring
|
||||
// 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 = ?
|
||||
WHERE url = $1
|
||||
`
|
||||
|
||||
res := model.Response{}
|
||||
@@ -84,19 +101,33 @@ func (m *ResponseModel) GetByUrl(url string) (model.Response, error) {
|
||||
return res, err
|
||||
}
|
||||
|
||||
// TODO docstring
|
||||
func (m *ResponseModel) Insert(url string, content string) error {
|
||||
// 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 (?, ?)`
|
||||
stmt := `INSERT INTO responses (url, content) VALUES ($1, $2)`
|
||||
_, err := m.DB.Exec(stmt, url, content)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO docstring
|
||||
// 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 = ?`
|
||||
stmt := `UPDATE responses SET processed = true WHERE url = $1`
|
||||
_, err := m.DB.Exec(stmt, url)
|
||||
|
||||
return err
|
||||
|
||||
@@ -5,7 +5,7 @@ import "time"
|
||||
// A simple cache for requests.
|
||||
type Response struct {
|
||||
Url string
|
||||
Content string
|
||||
Processed bool
|
||||
Content []byte
|
||||
Processed bool
|
||||
FetchDate time.Time
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user