1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
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")
}
|