142 lines
3.2 KiB
Go
142 lines
3.2 KiB
Go
package repositories
|
|
|
|
import (
|
|
"database/sql"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/satori/go.uuid"
|
|
|
|
"repodiff/constants"
|
|
e "repodiff/entities"
|
|
"repodiff/mappers"
|
|
repoSQL "repodiff/persistence/sql"
|
|
"repodiff/utils"
|
|
)
|
|
|
|
type project struct {
|
|
db *sql.DB
|
|
target e.MappedDiffTarget
|
|
timestampGenerator func() e.RepoTimestamp
|
|
}
|
|
|
|
func (p project) InsertDiffRows(diffRows []e.AnalyzedDiffRow) error {
|
|
return errors.Wrap(
|
|
repoSQL.SingleTransactionInsert(
|
|
p.db,
|
|
`INSERT INTO project_differential (
|
|
upstream_target_id,
|
|
downstream_target_id,
|
|
timestamp,
|
|
uuid,
|
|
row_index,
|
|
downstream_project,
|
|
upstream_project,
|
|
status,
|
|
files_changed,
|
|
line_insertions,
|
|
line_deletions,
|
|
line_changes,
|
|
commits_not_upstreamed,
|
|
project_type
|
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
mappers.PrependMappedDiffTarget(
|
|
p.target,
|
|
mappers.DiffRowsToPersistCols(diffRows, p.timestampGenerator()),
|
|
),
|
|
),
|
|
"Error inserting rows into project_differential",
|
|
)
|
|
}
|
|
|
|
func (p project) GetMostRecentOuterKey() (int64, uuid.UUID, error) {
|
|
var timestamp int64
|
|
var uuidBytes []byte
|
|
err := p.db.QueryRow(
|
|
`SELECT timestamp, uuid FROM project_differential WHERE upstream_target_id = ? AND downstream_target_id = ? AND timestamp=(
|
|
SELECT MAX(timestamp) FROM project_differential WHERE upstream_target_id = ? AND downstream_target_id = ?
|
|
) LIMIT 1`,
|
|
p.target.UpstreamTarget,
|
|
p.target.DownstreamTarget,
|
|
p.target.UpstreamTarget,
|
|
p.target.DownstreamTarget,
|
|
).Scan(
|
|
×tamp,
|
|
&uuidBytes,
|
|
)
|
|
if err != nil {
|
|
return 0, constants.NullUUID(), err
|
|
}
|
|
u, err := uuid.FromBytes(uuidBytes)
|
|
if err != nil {
|
|
return 0, constants.NullUUID(), errors.Wrap(err, "Error casting string to UUID")
|
|
}
|
|
return timestamp, u, nil
|
|
}
|
|
|
|
func (p project) GetMostRecentDifferentials() ([]e.AnalyzedDiffRow, error) {
|
|
timestamp, uid, err := p.GetMostRecentOuterKey()
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
// TODO this doesn't handle empty case properly
|
|
return nil, err
|
|
}
|
|
var errMapping error
|
|
|
|
var diffRows []e.AnalyzedDiffRow
|
|
errSelect := repoSQL.Select(
|
|
p.db,
|
|
func(row *sql.Rows) {
|
|
if errMapping != nil {
|
|
return
|
|
}
|
|
d, err := mappers.SQLRowToDiffRow(row)
|
|
errMapping = err
|
|
diffRows = append(
|
|
diffRows,
|
|
d,
|
|
)
|
|
},
|
|
`SELECT
|
|
timestamp,
|
|
uuid,
|
|
row_index,
|
|
downstream_project,
|
|
upstream_project,
|
|
status,
|
|
files_changed,
|
|
line_insertions,
|
|
line_deletions,
|
|
line_changes,
|
|
commits_not_upstreamed,
|
|
project_type
|
|
FROM project_differential
|
|
WHERE
|
|
upstream_target_id = ?
|
|
AND downstream_target_id = ?
|
|
AND timestamp = ?
|
|
AND uuid = ?`,
|
|
p.target.UpstreamTarget,
|
|
p.target.DownstreamTarget,
|
|
timestamp,
|
|
string(uid.Bytes()),
|
|
)
|
|
if errSelect != nil {
|
|
return nil, errSelect
|
|
}
|
|
if errMapping != nil {
|
|
return nil, errMapping
|
|
}
|
|
return diffRows, nil
|
|
}
|
|
|
|
func NewProjectRepository(target e.MappedDiffTarget) (project, error) {
|
|
db, err := repoSQL.GetDBConnectionPool()
|
|
return project{
|
|
db: db,
|
|
target: target,
|
|
timestampGenerator: utils.TimestampSeconds,
|
|
}, errors.Wrap(err, "Could not establish a database connection")
|
|
}
|