Add ClumpRepository with implementations
parent
19b591e48b
commit
d88bf493de
|
@ -0,0 +1,96 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// ErrPasteNotInDatabase is returned when one calls PutClump with pastes that are not in the database.
|
||||
var ErrPasteNotInDatabase = errors.New("repository: given pastes are not in the database")
|
||||
|
||||
// Clump represents a group ("clump") of pastes
|
||||
type Clump struct {
|
||||
ID int
|
||||
Title string
|
||||
Handle uuid.UUID
|
||||
Pastes []Paste
|
||||
}
|
||||
|
||||
// ClumpRepository puts/gets a clump from the database
|
||||
type ClumpRepository interface {
|
||||
// GetClump gets a clump from the database
|
||||
GetClump(handle uuid.UUID) (Clump, error)
|
||||
// GetClump gets a clump from the database
|
||||
PutClump(title string, pastes ...Paste) (Clump, error)
|
||||
}
|
||||
|
||||
// GetClump gets a clump and all of its associated pastes
|
||||
func (db *DatabaseConnector) GetClump(handle uuid.UUID) (Clump, error) {
|
||||
pasteRows, err := db.DB.Query("SELECT paste.*, clump.* FROM paste JOIN CLUMP USING (clumpID) WHERE handle = $1", handle.String())
|
||||
if err != nil {
|
||||
return Clump{}, err
|
||||
}
|
||||
|
||||
clump := Clump{
|
||||
Pastes: []Paste{},
|
||||
}
|
||||
|
||||
for pasteRows.Next() {
|
||||
paste := Paste{}
|
||||
// Per the docs, "The number of values in dest must be the same as the number of columns in Rows."
|
||||
// Because the clump result will always be the same, we can just pull it on each row and update the same struct
|
||||
pasteRows.Scan(&paste.ID, &paste.Filename, &paste.Handle, &paste.ClumpID, &clump.ID, &clump.Title, &clump.Handle)
|
||||
clump.Pastes = append(clump.Pastes, paste)
|
||||
}
|
||||
|
||||
return clump, pasteRows.Err()
|
||||
}
|
||||
|
||||
// PutClump puts a clump into the database.
|
||||
// All given pastes must have already been inserted to the database. Returns ErrPasteNotInDatabase if condition isn't met.
|
||||
func (db *DatabaseConnector) PutClump(title string, pastes ...Paste) (Clump, error) {
|
||||
handle, err := uuid.NewUUID()
|
||||
if err != nil {
|
||||
return Clump{}, err
|
||||
}
|
||||
|
||||
clump := Clump{
|
||||
Handle: handle,
|
||||
}
|
||||
|
||||
tx, err := db.DB.Begin()
|
||||
insertResult := tx.QueryRow("INSERT INTO clump VALUES(DEFAULT, $1, $2) RETURNING clumpID", title, handle.String())
|
||||
err = insertResult.Scan(&clump.ID)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return Clump{}, err
|
||||
}
|
||||
|
||||
err = db.addPastesToClump(tx, clump.ID, pastes)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return Clump{}, err
|
||||
}
|
||||
|
||||
return clump, tx.Commit()
|
||||
}
|
||||
|
||||
func (db *DatabaseConnector) addPastesToClump(ex executor, clumpID int, pastes []Paste) error {
|
||||
for _, paste := range pastes {
|
||||
paste.ClumpID = clumpID
|
||||
result, err := db.updatePaste(ex, paste)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
numRows, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
} else if numRows == 0 {
|
||||
return ErrPasteNotInDatabase
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
package repository
|
||||
|
||||
import "github.com/google/uuid"
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// Paste represents a paste that the user has stored in the database
|
||||
type Paste struct {
|
||||
|
@ -55,7 +59,11 @@ func (db *DatabaseConnector) PutPaste(filename string) (Paste, error) {
|
|||
// UpdatePaste allows for a paste to be updated.
|
||||
// Currently, only the filename and clump id can be updated
|
||||
func (db *DatabaseConnector) UpdatePaste(paste Paste) error {
|
||||
_, err := db.DB.Exec("UPDATE paste SET filename = $1, clumpID = $2 WHERE pasteID = $3", paste.Filename, paste.ClumpID, paste.ID)
|
||||
_, err := db.updatePaste(db.DB, paste)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DatabaseConnector) updatePaste(ex executor, paste Paste) (sql.Result, error) {
|
||||
return db.DB.Exec("UPDATE paste SET filename = $1, clumpID = $2 WHERE pasteID = $3", paste.Filename, paste.ClumpID, paste.ID)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue