database: use constants to store queries
This commit is contained in:
parent
904ce6004f
commit
84319507df
@ -128,7 +128,7 @@ func TestRaceAffects(t *testing.T) {
|
|||||||
featureVersionVersion, _ := strconv.Atoi(featureVersion.Version.String())
|
featureVersionVersion, _ := strconv.Atoi(featureVersion.Version.String())
|
||||||
|
|
||||||
// Get actual affects.
|
// Get actual affects.
|
||||||
rows, err := datastore.Query(getQuery("s_complextest_featureversion_affects"),
|
rows, err := datastore.Query(searchComplexTestFeatureVersionAffects,
|
||||||
featureVersion.ID)
|
featureVersion.ID)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
@ -49,9 +49,9 @@ func (pgSQL *pgSQL) insertFeature(feature database.Feature) (int, error) {
|
|||||||
|
|
||||||
// Find or create Feature.
|
// Find or create Feature.
|
||||||
var id int
|
var id int
|
||||||
err = pgSQL.QueryRow(getQuery("soi_feature"), feature.Name, namespaceID).Scan(&id)
|
err = pgSQL.QueryRow(soiFeature, feature.Name, namespaceID).Scan(&id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, handleError("soi_feature", err)
|
return 0, handleError("soiFeature", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pgSQL.cache != nil {
|
if pgSQL.cache != nil {
|
||||||
@ -103,25 +103,25 @@ func (pgSQL *pgSQL) insertFeatureVersion(featureVersion database.FeatureVersion)
|
|||||||
promConcurrentLockVAFV.Inc()
|
promConcurrentLockVAFV.Inc()
|
||||||
defer promConcurrentLockVAFV.Dec()
|
defer promConcurrentLockVAFV.Dec()
|
||||||
t = time.Now()
|
t = time.Now()
|
||||||
_, err = tx.Exec(getQuery("l_vulnerability_affects_featureversion"))
|
_, err = tx.Exec(lockVulnerabilityAffects)
|
||||||
observeQueryTime("insertFeatureVersion", "lock", t)
|
observeQueryTime("insertFeatureVersion", "lock", t)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return 0, handleError("insertFeatureVersion.l_vulnerability_affects_featureversion", err)
|
return 0, handleError("insertFeatureVersion.lockVulnerabilityAffects", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find or create FeatureVersion.
|
// Find or create FeatureVersion.
|
||||||
var newOrExisting string
|
var newOrExisting string
|
||||||
|
|
||||||
t = time.Now()
|
t = time.Now()
|
||||||
err = tx.QueryRow(getQuery("soi_featureversion"), featureID, &featureVersion.Version).
|
err = tx.QueryRow(soiFeatureVersion, featureID, &featureVersion.Version).
|
||||||
Scan(&newOrExisting, &featureVersion.ID)
|
Scan(&newOrExisting, &featureVersion.ID)
|
||||||
observeQueryTime("insertFeatureVersion", "soi_featureversion", t)
|
observeQueryTime("insertFeatureVersion", "soiFeatureVersion", t)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return 0, handleError("soi_featureversion", err)
|
return 0, handleError("soiFeatureVersion", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if newOrExisting == "exi" {
|
if newOrExisting == "exi" {
|
||||||
@ -183,9 +183,9 @@ type vulnerabilityAffectsFeatureVersion struct {
|
|||||||
func linkFeatureVersionToVulnerabilities(tx *sql.Tx, featureVersion database.FeatureVersion) error {
|
func linkFeatureVersionToVulnerabilities(tx *sql.Tx, featureVersion database.FeatureVersion) error {
|
||||||
// Select every vulnerability and the fixed version that affect this Feature.
|
// Select every vulnerability and the fixed version that affect this Feature.
|
||||||
// TODO(Quentin-M): LIMIT
|
// TODO(Quentin-M): LIMIT
|
||||||
rows, err := tx.Query(getQuery("s_vulnerability_fixedin_feature"), featureVersion.Feature.ID)
|
rows, err := tx.Query(searchVulnerabilityFixedInFeature, featureVersion.Feature.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("s_vulnerability_fixedin_feature", err)
|
return handleError("searchVulnerabilityFixedInFeature", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ func linkFeatureVersionToVulnerabilities(tx *sql.Tx, featureVersion database.Fea
|
|||||||
|
|
||||||
err := rows.Scan(&affect.fixedInID, &affect.vulnerabilityID, &affect.fixedInVersion)
|
err := rows.Scan(&affect.fixedInID, &affect.vulnerabilityID, &affect.fixedInVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("s_vulnerability_fixedin_feature.Scan()", err)
|
return handleError("searchVulnerabilityFixedInFeature.Scan()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if featureVersion.Version.Compare(affect.fixedInVersion) < 0 {
|
if featureVersion.Version.Compare(affect.fixedInVersion) < 0 {
|
||||||
@ -205,17 +205,17 @@ func linkFeatureVersionToVulnerabilities(tx *sql.Tx, featureVersion database.Fea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = rows.Err(); err != nil {
|
if err = rows.Err(); err != nil {
|
||||||
return handleError("s_vulnerability_fixedin_feature.Rows()", err)
|
return handleError("searchVulnerabilityFixedInFeature.Rows()", err)
|
||||||
}
|
}
|
||||||
rows.Close()
|
rows.Close()
|
||||||
|
|
||||||
// Insert into Vulnerability_Affects_FeatureVersion.
|
// Insert into Vulnerability_Affects_FeatureVersion.
|
||||||
for _, affect := range affects {
|
for _, affect := range affects {
|
||||||
// TODO(Quentin-M): Batch me.
|
// TODO(Quentin-M): Batch me.
|
||||||
_, err := tx.Exec(getQuery("i_vulnerability_affects_featureversion"), affect.vulnerabilityID,
|
_, err := tx.Exec(insertVulnerabilityAffectsFeatureVersion, affect.vulnerabilityID,
|
||||||
featureVersion.ID, affect.fixedInID)
|
featureVersion.ID, affect.fixedInID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("i_vulnerability_affects_featureversion", err)
|
return handleError("insertVulnerabilityAffectsFeatureVersion", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,9 +41,9 @@ func (pgSQL *pgSQL) InsertKeyValue(key, value string) (err error) {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
// First, try to update.
|
// First, try to update.
|
||||||
r, err := pgSQL.Exec(getQuery("u_keyvalue"), value, key)
|
r, err := pgSQL.Exec(updateKeyValue, value, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("u_keyvalue", err)
|
return handleError("updateKeyValue", err)
|
||||||
}
|
}
|
||||||
if n, _ := r.RowsAffected(); n > 0 {
|
if n, _ := r.RowsAffected(); n > 0 {
|
||||||
// Updated successfully.
|
// Updated successfully.
|
||||||
@ -52,13 +52,13 @@ func (pgSQL *pgSQL) InsertKeyValue(key, value string) (err error) {
|
|||||||
|
|
||||||
// Try to insert the key.
|
// Try to insert the key.
|
||||||
// If someone else inserts the same key concurrently, we could get a unique-key violation error.
|
// If someone else inserts the same key concurrently, we could get a unique-key violation error.
|
||||||
_, err = pgSQL.Exec(getQuery("i_keyvalue"), key, value)
|
_, err = pgSQL.Exec(insertKeyValue, key, value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if isErrUniqueViolation(err) {
|
if isErrUniqueViolation(err) {
|
||||||
// Got unique constraint violation, retry.
|
// Got unique constraint violation, retry.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return handleError("i_keyvalue", err)
|
return handleError("insertKeyValue", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -70,13 +70,13 @@ func (pgSQL *pgSQL) GetKeyValue(key string) (string, error) {
|
|||||||
defer observeQueryTime("GetKeyValue", "all", time.Now())
|
defer observeQueryTime("GetKeyValue", "all", time.Now())
|
||||||
|
|
||||||
var value string
|
var value string
|
||||||
err := pgSQL.QueryRow(getQuery("s_keyvalue"), key).Scan(&value)
|
err := pgSQL.QueryRow(searchKeyValue, key).Scan(&value)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", handleError("s_keyvalue", err)
|
return "", handleError("searchKeyValue", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return value, nil
|
return value, nil
|
||||||
|
@ -41,13 +41,13 @@ func (pgSQL *pgSQL) FindLayer(name string, withFeatures, withVulnerabilities boo
|
|||||||
var namespaceName sql.NullString
|
var namespaceName sql.NullString
|
||||||
|
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
err := pgSQL.QueryRow(getQuery("s_layer"), name).
|
err := pgSQL.QueryRow(searchLayer, name).
|
||||||
Scan(&layer.ID, &layer.Name, &layer.EngineVersion, &parentID, &parentName, &namespaceID,
|
Scan(&layer.ID, &layer.Name, &layer.EngineVersion, &parentID, &parentName, &namespaceID,
|
||||||
&namespaceName)
|
&namespaceName)
|
||||||
observeQueryTime("FindLayer", "s_layer", t)
|
observeQueryTime("FindLayer", "searchLayer", t)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return layer, handleError("s_layer", err)
|
return layer, handleError("searchLayer", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !parentID.IsZero() {
|
if !parentID.IsZero() {
|
||||||
@ -78,11 +78,11 @@ func (pgSQL *pgSQL) FindLayer(name string, withFeatures, withVulnerabilities boo
|
|||||||
}
|
}
|
||||||
defer tx.Commit()
|
defer tx.Commit()
|
||||||
|
|
||||||
_, err = tx.Exec(getQuery("disable_hashjoin"))
|
_, err = tx.Exec(disableHashJoin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("FindLayer: could not disable hash join: %s", err)
|
log.Warningf("FindLayer: could not disable hash join: %s", err)
|
||||||
}
|
}
|
||||||
_, err = tx.Exec(getQuery("disable_mergejoin"))
|
_, err = tx.Exec(disableMergeJoin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("FindLayer: could not disable merge join: %s", err)
|
log.Warningf("FindLayer: could not disable merge join: %s", err)
|
||||||
}
|
}
|
||||||
@ -117,9 +117,9 @@ func getLayerFeatureVersions(tx *sql.Tx, layerID int) ([]database.FeatureVersion
|
|||||||
var featureVersions []database.FeatureVersion
|
var featureVersions []database.FeatureVersion
|
||||||
|
|
||||||
// Query.
|
// Query.
|
||||||
rows, err := tx.Query(getQuery("s_layer_featureversion"), layerID)
|
rows, err := tx.Query(searchLayerFeatureVersion, layerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return featureVersions, handleError("s_layer_featureversion", err)
|
return featureVersions, handleError("searchLayerFeatureVersion", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ func getLayerFeatureVersions(tx *sql.Tx, layerID int) ([]database.FeatureVersion
|
|||||||
&featureVersion.Feature.Name, &featureVersion.ID, &featureVersion.Version,
|
&featureVersion.Feature.Name, &featureVersion.ID, &featureVersion.Version,
|
||||||
&featureVersion.AddedBy.ID, &featureVersion.AddedBy.Name)
|
&featureVersion.AddedBy.ID, &featureVersion.AddedBy.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return featureVersions, handleError("s_layer_featureversion.Scan()", err)
|
return featureVersions, handleError("searchLayerFeatureVersion.Scan()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do transitive closure.
|
// Do transitive closure.
|
||||||
@ -149,7 +149,7 @@ func getLayerFeatureVersions(tx *sql.Tx, layerID int) ([]database.FeatureVersion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = rows.Err(); err != nil {
|
if err = rows.Err(); err != nil {
|
||||||
return featureVersions, handleError("s_layer_featureversion.Rows()", err)
|
return featureVersions, handleError("searchLayerFeatureVersion.Rows()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build result by converting our map to a slice.
|
// Build result by converting our map to a slice.
|
||||||
@ -173,10 +173,10 @@ func loadAffectedBy(tx *sql.Tx, featureVersions []database.FeatureVersion) error
|
|||||||
featureVersionIDs = append(featureVersionIDs, featureVersions[i].ID)
|
featureVersionIDs = append(featureVersionIDs, featureVersions[i].ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := tx.Query(getQuery("s_featureversions_vulnerabilities"),
|
rows, err := tx.Query(searchFeatureVersionVulnerability,
|
||||||
buildInputArray(featureVersionIDs))
|
buildInputArray(featureVersionIDs))
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return handleError("s_featureversions_vulnerabilities", err)
|
return handleError("searchFeatureVersionVulnerability", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
@ -188,12 +188,12 @@ func loadAffectedBy(tx *sql.Tx, featureVersions []database.FeatureVersion) error
|
|||||||
&vulnerability.Description, &vulnerability.Link, &vulnerability.Severity,
|
&vulnerability.Description, &vulnerability.Link, &vulnerability.Severity,
|
||||||
&vulnerability.Metadata, &vulnerability.Namespace.Name, &vulnerability.FixedBy)
|
&vulnerability.Metadata, &vulnerability.Namespace.Name, &vulnerability.FixedBy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("s_featureversions_vulnerabilities.Scan()", err)
|
return handleError("searchFeatureVersionVulnerability.Scan()", err)
|
||||||
}
|
}
|
||||||
vulnerabilities[featureversionID] = append(vulnerabilities[featureversionID], vulnerability)
|
vulnerabilities[featureversionID] = append(vulnerabilities[featureversionID], vulnerability)
|
||||||
}
|
}
|
||||||
if err = rows.Err(); err != nil {
|
if err = rows.Err(); err != nil {
|
||||||
return handleError("s_featureversions_vulnerabilities.Rows()", err)
|
return handleError("searchFeatureVersionVulnerability.Rows()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign vulnerabilities to every FeatureVersions
|
// Assign vulnerabilities to every FeatureVersions
|
||||||
@ -271,7 +271,7 @@ func (pgSQL *pgSQL) InsertLayer(layer database.Layer) error {
|
|||||||
|
|
||||||
if layer.ID == 0 {
|
if layer.ID == 0 {
|
||||||
// Insert a new layer.
|
// Insert a new layer.
|
||||||
err = tx.QueryRow(getQuery("i_layer"), layer.Name, layer.EngineVersion, parentID, namespaceID).
|
err = tx.QueryRow(insertLayer, layer.Name, layer.EngineVersion, parentID, namespaceID).
|
||||||
Scan(&layer.ID)
|
Scan(&layer.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
@ -280,21 +280,21 @@ func (pgSQL *pgSQL) InsertLayer(layer database.Layer) error {
|
|||||||
// Ignore this error, another process collided.
|
// Ignore this error, another process collided.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return handleError("i_layer", err)
|
return handleError("insertLayer", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Update an existing layer.
|
// Update an existing layer.
|
||||||
_, err = tx.Exec(getQuery("u_layer"), layer.ID, layer.EngineVersion, namespaceID)
|
_, err = tx.Exec(updateLayer, layer.ID, layer.EngineVersion, namespaceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return handleError("u_layer", err)
|
return handleError("updateLayer", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all existing Layer_diff_FeatureVersion.
|
// Remove all existing Layer_diff_FeatureVersion.
|
||||||
_, err = tx.Exec(getQuery("r_layer_diff_featureversion"), layer.ID)
|
_, err = tx.Exec(removeLayerDiffFeatureVersion, layer.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return handleError("r_layer_diff_featureversion", err)
|
return handleError("removeLayerDiffFeatureVersion", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,15 +355,15 @@ func (pgSQL *pgSQL) updateDiffFeatureVersions(tx *sql.Tx, layer, existingLayer *
|
|||||||
|
|
||||||
// Insert diff in the database.
|
// Insert diff in the database.
|
||||||
if len(addIDs) > 0 {
|
if len(addIDs) > 0 {
|
||||||
_, err = tx.Exec(getQuery("i_layer_diff_featureversion"), layer.ID, "add", buildInputArray(addIDs))
|
_, err = tx.Exec(insertLayerDiffFeatureVersion, layer.ID, "add", buildInputArray(addIDs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("i_layer_diff_featureversion.Add", err)
|
return handleError("insertLayerDiffFeatureVersion.Add", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(delIDs) > 0 {
|
if len(delIDs) > 0 {
|
||||||
_, err = tx.Exec(getQuery("i_layer_diff_featureversion"), layer.ID, "del", buildInputArray(delIDs))
|
_, err = tx.Exec(insertLayerDiffFeatureVersion, layer.ID, "del", buildInputArray(delIDs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("i_layer_diff_featureversion.Del", err)
|
return handleError("insertLayerDiffFeatureVersion.Del", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,14 +387,14 @@ func createNV(features []database.FeatureVersion) (map[string]*database.FeatureV
|
|||||||
func (pgSQL *pgSQL) DeleteLayer(name string) error {
|
func (pgSQL *pgSQL) DeleteLayer(name string) error {
|
||||||
defer observeQueryTime("DeleteLayer", "all", time.Now())
|
defer observeQueryTime("DeleteLayer", "all", time.Now())
|
||||||
|
|
||||||
result, err := pgSQL.Exec(getQuery("r_layer"), name)
|
result, err := pgSQL.Exec(removeLayer, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("r_layer", err)
|
return handleError("removeLayer", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
affected, err := result.RowsAffected()
|
affected, err := result.RowsAffected()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("r_layer.RowsAffected()", err)
|
return handleError("removeLayer.RowsAffected()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if affected <= 0 {
|
if affected <= 0 {
|
||||||
|
@ -37,9 +37,9 @@ func (pgSQL *pgSQL) Lock(name string, owner string, duration time.Duration, rene
|
|||||||
|
|
||||||
if renew {
|
if renew {
|
||||||
// Renew lock.
|
// Renew lock.
|
||||||
r, err := pgSQL.Exec(getQuery("u_lock"), name, owner, until)
|
r, err := pgSQL.Exec(updateLock, name, owner, until)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleError("u_lock", err)
|
handleError("updateLock", err)
|
||||||
return false, until
|
return false, until
|
||||||
}
|
}
|
||||||
if n, _ := r.RowsAffected(); n > 0 {
|
if n, _ := r.RowsAffected(); n > 0 {
|
||||||
@ -52,10 +52,10 @@ func (pgSQL *pgSQL) Lock(name string, owner string, duration time.Duration, rene
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Lock.
|
// Lock.
|
||||||
_, err := pgSQL.Exec(getQuery("i_lock"), name, owner, until)
|
_, err := pgSQL.Exec(insertLock, name, owner, until)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !isErrUniqueViolation(err) {
|
if !isErrUniqueViolation(err) {
|
||||||
handleError("i_lock", err)
|
handleError("insertLock", err)
|
||||||
}
|
}
|
||||||
return false, until
|
return false, until
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ func (pgSQL *pgSQL) Unlock(name, owner string) {
|
|||||||
|
|
||||||
defer observeQueryTime("Unlock", "all", time.Now())
|
defer observeQueryTime("Unlock", "all", time.Now())
|
||||||
|
|
||||||
pgSQL.Exec(getQuery("r_lock"), name, owner)
|
pgSQL.Exec(removeLock, name, owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindLock returns the owner of a lock specified by its name and its
|
// FindLock returns the owner of a lock specified by its name and its
|
||||||
@ -87,9 +87,9 @@ func (pgSQL *pgSQL) FindLock(name string) (string, time.Time, error) {
|
|||||||
|
|
||||||
var owner string
|
var owner string
|
||||||
var until time.Time
|
var until time.Time
|
||||||
err := pgSQL.QueryRow(getQuery("f_lock"), name).Scan(&owner, &until)
|
err := pgSQL.QueryRow(searchLock, name).Scan(&owner, &until)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return owner, until, handleError("f_lock", err)
|
return owner, until, handleError("searchLock", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return owner, until, nil
|
return owner, until, nil
|
||||||
@ -99,7 +99,7 @@ func (pgSQL *pgSQL) FindLock(name string) (string, time.Time, error) {
|
|||||||
func (pgSQL *pgSQL) pruneLocks() {
|
func (pgSQL *pgSQL) pruneLocks() {
|
||||||
defer observeQueryTime("pruneLocks", "all", time.Now())
|
defer observeQueryTime("pruneLocks", "all", time.Now())
|
||||||
|
|
||||||
if _, err := pgSQL.Exec(getQuery("r_lock_expired")); err != nil {
|
if _, err := pgSQL.Exec(removeLockExpired); err != nil {
|
||||||
handleError("r_lock_expired", err)
|
handleError("removeLockExpired", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,9 +38,9 @@ func (pgSQL *pgSQL) insertNamespace(namespace database.Namespace) (int, error) {
|
|||||||
defer observeQueryTime("insertNamespace", "all", time.Now())
|
defer observeQueryTime("insertNamespace", "all", time.Now())
|
||||||
|
|
||||||
var id int
|
var id int
|
||||||
err := pgSQL.QueryRow(getQuery("soi_namespace"), namespace.Name).Scan(&id)
|
err := pgSQL.QueryRow(soiNamespace, namespace.Name).Scan(&id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, handleError("soi_namespace", err)
|
return 0, handleError("soiNamespace", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pgSQL.cache != nil {
|
if pgSQL.cache != nil {
|
||||||
@ -51,9 +51,9 @@ func (pgSQL *pgSQL) insertNamespace(namespace database.Namespace) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pgSQL *pgSQL) ListNamespaces() (namespaces []database.Namespace, err error) {
|
func (pgSQL *pgSQL) ListNamespaces() (namespaces []database.Namespace, err error) {
|
||||||
rows, err := pgSQL.Query(getQuery("l_namespace"))
|
rows, err := pgSQL.Query(listNamespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return namespaces, handleError("l_namespace", err)
|
return namespaces, handleError("listNamespace", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
@ -62,13 +62,13 @@ func (pgSQL *pgSQL) ListNamespaces() (namespaces []database.Namespace, err error
|
|||||||
|
|
||||||
err = rows.Scan(&namespace.ID, &namespace.Name)
|
err = rows.Scan(&namespace.ID, &namespace.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return namespaces, handleError("l_namespace.Scan()", err)
|
return namespaces, handleError("listNamespace.Scan()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespaces = append(namespaces, namespace)
|
namespaces = append(namespaces, namespace)
|
||||||
}
|
}
|
||||||
if err = rows.Err(); err != nil {
|
if err = rows.Err(); err != nil {
|
||||||
return namespaces, handleError("l_namespace.Rows()", err)
|
return namespaces, handleError("listNamespace.Rows()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return namespaces, err
|
return namespaces, err
|
||||||
|
@ -18,10 +18,10 @@ func createNotification(tx *sql.Tx, oldVulnerabilityID, newVulnerabilityID int)
|
|||||||
// Insert Notification.
|
// Insert Notification.
|
||||||
oldVulnerabilityNullableID := sql.NullInt64{Int64: int64(oldVulnerabilityID), Valid: oldVulnerabilityID != 0}
|
oldVulnerabilityNullableID := sql.NullInt64{Int64: int64(oldVulnerabilityID), Valid: oldVulnerabilityID != 0}
|
||||||
newVulnerabilityNullableID := sql.NullInt64{Int64: int64(newVulnerabilityID), Valid: newVulnerabilityID != 0}
|
newVulnerabilityNullableID := sql.NullInt64{Int64: int64(newVulnerabilityID), Valid: newVulnerabilityID != 0}
|
||||||
_, err := tx.Exec(getQuery("i_notification"), uuid.New(), oldVulnerabilityNullableID, newVulnerabilityNullableID)
|
_, err := tx.Exec(insertNotification, uuid.New(), oldVulnerabilityNullableID, newVulnerabilityNullableID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return handleError("i_notification", err)
|
return handleError("insertNotification", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -33,19 +33,19 @@ func (pgSQL *pgSQL) GetAvailableNotification(renotifyInterval time.Duration) (da
|
|||||||
defer observeQueryTime("GetAvailableNotification", "all", time.Now())
|
defer observeQueryTime("GetAvailableNotification", "all", time.Now())
|
||||||
|
|
||||||
before := time.Now().Add(-renotifyInterval)
|
before := time.Now().Add(-renotifyInterval)
|
||||||
row := pgSQL.QueryRow(getQuery("s_notification_available"), before)
|
row := pgSQL.QueryRow(searchNotificationAvailable, before)
|
||||||
notification, err := pgSQL.scanNotification(row, false)
|
notification, err := pgSQL.scanNotification(row, false)
|
||||||
|
|
||||||
return notification, handleError("s_notification_available", err)
|
return notification, handleError("searchNotificationAvailable", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pgSQL *pgSQL) GetNotification(name string, limit int, page database.VulnerabilityNotificationPageNumber) (database.VulnerabilityNotification, database.VulnerabilityNotificationPageNumber, error) {
|
func (pgSQL *pgSQL) GetNotification(name string, limit int, page database.VulnerabilityNotificationPageNumber) (database.VulnerabilityNotification, database.VulnerabilityNotificationPageNumber, error) {
|
||||||
defer observeQueryTime("GetNotification", "all", time.Now())
|
defer observeQueryTime("GetNotification", "all", time.Now())
|
||||||
|
|
||||||
// Get Notification.
|
// Get Notification.
|
||||||
notification, err := pgSQL.scanNotification(pgSQL.QueryRow(getQuery("s_notification"), name), true)
|
notification, err := pgSQL.scanNotification(pgSQL.QueryRow(searchNotification, name), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return notification, page, handleError("s_notification", err)
|
return notification, page, handleError("searchNotification", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load vulnerabilities' LayersIntroducingVulnerability.
|
// Load vulnerabilities' LayersIntroducingVulnerability.
|
||||||
@ -149,10 +149,10 @@ func (pgSQL *pgSQL) loadLayerIntroducingVulnerability(vulnerability *database.Vu
|
|||||||
defer observeQueryTime("loadLayerIntroducingVulnerability", "all", tf)
|
defer observeQueryTime("loadLayerIntroducingVulnerability", "all", tf)
|
||||||
|
|
||||||
// Query with limit + 1, the last item will be used to know the next starting ID.
|
// Query with limit + 1, the last item will be used to know the next starting ID.
|
||||||
rows, err := pgSQL.Query(getQuery("s_notification_layer_introducing_vulnerability"),
|
rows, err := pgSQL.Query(searchNotificationLayerIntroducingVulnerability,
|
||||||
vulnerability.ID, startID, limit+1)
|
vulnerability.ID, startID, limit+1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, handleError("s_vulnerability_fixedin_feature", err)
|
return 0, handleError("searchVulnerabilityFixedInFeature", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
@ -161,13 +161,13 @@ func (pgSQL *pgSQL) loadLayerIntroducingVulnerability(vulnerability *database.Vu
|
|||||||
var layer database.Layer
|
var layer database.Layer
|
||||||
|
|
||||||
if err := rows.Scan(&layer.ID, &layer.Name); err != nil {
|
if err := rows.Scan(&layer.ID, &layer.Name); err != nil {
|
||||||
return -1, handleError("s_notification_layer_introducing_vulnerability.Scan()", err)
|
return -1, handleError("searchNotificationLayerIntroducingVulnerability.Scan()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
layers = append(layers, layer)
|
layers = append(layers, layer)
|
||||||
}
|
}
|
||||||
if err = rows.Err(); err != nil {
|
if err = rows.Err(); err != nil {
|
||||||
return -1, handleError("s_notification_layer_introducing_vulnerability.Rows()", err)
|
return -1, handleError("searchNotificationLayerIntroducingVulnerability.Rows()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
size := limit
|
size := limit
|
||||||
@ -187,8 +187,8 @@ func (pgSQL *pgSQL) loadLayerIntroducingVulnerability(vulnerability *database.Vu
|
|||||||
func (pgSQL *pgSQL) SetNotificationNotified(name string) error {
|
func (pgSQL *pgSQL) SetNotificationNotified(name string) error {
|
||||||
defer observeQueryTime("SetNotificationNotified", "all", time.Now())
|
defer observeQueryTime("SetNotificationNotified", "all", time.Now())
|
||||||
|
|
||||||
if _, err := pgSQL.Exec(getQuery("u_notification_notified"), name); err != nil {
|
if _, err := pgSQL.Exec(updatedNotificationNotified, name); err != nil {
|
||||||
return handleError("u_notification_notified", err)
|
return handleError("updatedNotificationNotified", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -196,14 +196,14 @@ func (pgSQL *pgSQL) SetNotificationNotified(name string) error {
|
|||||||
func (pgSQL *pgSQL) DeleteNotification(name string) error {
|
func (pgSQL *pgSQL) DeleteNotification(name string) error {
|
||||||
defer observeQueryTime("DeleteNotification", "all", time.Now())
|
defer observeQueryTime("DeleteNotification", "all", time.Now())
|
||||||
|
|
||||||
result, err := pgSQL.Exec(getQuery("r_notification"), name)
|
result, err := pgSQL.Exec(removeNotification, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("r_notification", err)
|
return handleError("removeNotification", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
affected, err := result.RowsAffected()
|
affected, err := result.RowsAffected()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("r_notification.RowsAffected()", err)
|
return handleError("removeNotification.RowsAffected()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if affected <= 0 {
|
if affected <= 0 {
|
||||||
|
@ -14,27 +14,20 @@
|
|||||||
|
|
||||||
package pgsql
|
package pgsql
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
var queries map[string]string
|
const (
|
||||||
|
lockVulnerabilityAffects = `LOCK Vulnerability_Affects_FeatureVersion IN SHARE ROW EXCLUSIVE MODE`
|
||||||
func init() {
|
disableHashJoin = `SET LOCAL enable_hashjoin = off`
|
||||||
queries = make(map[string]string)
|
disableMergeJoin = `SET LOCAL enable_mergejoin = off`
|
||||||
|
|
||||||
queries["l_vulnerability_affects_featureversion"] = `LOCK Vulnerability_Affects_FeatureVersion IN SHARE ROW EXCLUSIVE MODE`
|
|
||||||
queries["disable_hashjoin"] = `SET LOCAL enable_hashjoin = off`
|
|
||||||
queries["disable_mergejoin"] = `SET LOCAL enable_mergejoin = off`
|
|
||||||
|
|
||||||
// keyvalue.go
|
// keyvalue.go
|
||||||
queries["u_keyvalue"] = `UPDATE KeyValue SET value = $1 WHERE key = $2`
|
updateKeyValue = `UPDATE KeyValue SET value = $1 WHERE key = $2`
|
||||||
queries["i_keyvalue"] = `INSERT INTO KeyValue(key, value) VALUES($1, $2)`
|
insertKeyValue = `INSERT INTO KeyValue(key, value) VALUES($1, $2)`
|
||||||
queries["s_keyvalue"] = `SELECT value FROM KeyValue WHERE key = $1`
|
searchKeyValue = `SELECT value FROM KeyValue WHERE key = $1`
|
||||||
|
|
||||||
// namespace.go
|
// namespace.go
|
||||||
queries["soi_namespace"] = `
|
soiNamespace = `
|
||||||
WITH new_namespace AS (
|
WITH new_namespace AS (
|
||||||
INSERT INTO Namespace(name)
|
INSERT INTO Namespace(name)
|
||||||
SELECT CAST($1 AS VARCHAR)
|
SELECT CAST($1 AS VARCHAR)
|
||||||
@ -45,10 +38,10 @@ func init() {
|
|||||||
UNION
|
UNION
|
||||||
SELECT id FROM new_namespace`
|
SELECT id FROM new_namespace`
|
||||||
|
|
||||||
queries["l_namespace"] = `SELECT id, name FROM Namespace`
|
listNamespace = `SELECT id, name FROM Namespace`
|
||||||
|
|
||||||
// feature.go
|
// feature.go
|
||||||
queries["soi_feature"] = `
|
soiFeature = `
|
||||||
WITH new_feature AS (
|
WITH new_feature AS (
|
||||||
INSERT INTO Feature(name, namespace_id)
|
INSERT INTO Feature(name, namespace_id)
|
||||||
SELECT CAST($1 AS VARCHAR), CAST($2 AS INTEGER)
|
SELECT CAST($1 AS VARCHAR), CAST($2 AS INTEGER)
|
||||||
@ -59,7 +52,7 @@ func init() {
|
|||||||
UNION
|
UNION
|
||||||
SELECT id FROM new_feature`
|
SELECT id FROM new_feature`
|
||||||
|
|
||||||
queries["soi_featureversion"] = `
|
soiFeatureVersion = `
|
||||||
WITH new_featureversion AS (
|
WITH new_featureversion AS (
|
||||||
INSERT INTO FeatureVersion(feature_id, version)
|
INSERT INTO FeatureVersion(feature_id, version)
|
||||||
SELECT CAST($1 AS INTEGER), CAST($2 AS VARCHAR)
|
SELECT CAST($1 AS INTEGER), CAST($2 AS VARCHAR)
|
||||||
@ -68,26 +61,25 @@ func init() {
|
|||||||
)
|
)
|
||||||
SELECT 'exi', id FROM FeatureVersion WHERE feature_id = $1 AND version = $2
|
SELECT 'exi', id FROM FeatureVersion WHERE feature_id = $1 AND version = $2
|
||||||
UNION
|
UNION
|
||||||
SELECT 'new', id FROM new_featureversion
|
SELECT 'new', id FROM new_featureversion`
|
||||||
`
|
|
||||||
|
|
||||||
queries["s_vulnerability_fixedin_feature"] = `
|
searchVulnerabilityFixedInFeature = `
|
||||||
SELECT id, vulnerability_id, version FROM Vulnerability_FixedIn_Feature
|
SELECT id, vulnerability_id, version FROM Vulnerability_FixedIn_Feature
|
||||||
WHERE feature_id = $1`
|
WHERE feature_id = $1`
|
||||||
|
|
||||||
queries["i_vulnerability_affects_featureversion"] = `
|
insertVulnerabilityAffectsFeatureVersion = `
|
||||||
INSERT INTO Vulnerability_Affects_FeatureVersion(vulnerability_id,
|
INSERT INTO Vulnerability_Affects_FeatureVersion(vulnerability_id,
|
||||||
featureversion_id, fixedin_id) VALUES($1, $2, $3)`
|
featureversion_id, fixedin_id) VALUES($1, $2, $3)`
|
||||||
|
|
||||||
// layer.go
|
// layer.go
|
||||||
queries["s_layer"] = `
|
searchLayer = `
|
||||||
SELECT l.id, l.name, l.engineversion, p.id, p.name, n.id, n.name
|
SELECT l.id, l.name, l.engineversion, p.id, p.name, n.id, n.name
|
||||||
FROM Layer l
|
FROM Layer l
|
||||||
LEFT JOIN Layer p ON l.parent_id = p.id
|
LEFT JOIN Layer p ON l.parent_id = p.id
|
||||||
LEFT JOIN Namespace n ON l.namespace_id = n.id
|
LEFT JOIN Namespace n ON l.namespace_id = n.id
|
||||||
WHERE l.name = $1;`
|
WHERE l.name = $1;`
|
||||||
|
|
||||||
queries["s_layer_featureversion"] = `
|
searchLayerFeatureVersion = `
|
||||||
WITH RECURSIVE layer_tree(id, name, parent_id, depth, path, cycle) AS(
|
WITH RECURSIVE layer_tree(id, name, parent_id, depth, path, cycle) AS(
|
||||||
SELECT l.id, l.name, l.parent_id, 1, ARRAY[l.id], false
|
SELECT l.id, l.name, l.parent_id, 1, ARRAY[l.id], false
|
||||||
FROM Layer l
|
FROM Layer l
|
||||||
@ -105,7 +97,7 @@ func init() {
|
|||||||
WHERE ldf.featureversion_id = fv.id AND fv.feature_id = f.id AND f.namespace_id = fn.id
|
WHERE ldf.featureversion_id = fv.id AND fv.feature_id = f.id AND f.namespace_id = fn.id
|
||||||
ORDER BY ltree.ordering`
|
ORDER BY ltree.ordering`
|
||||||
|
|
||||||
queries["s_featureversions_vulnerabilities"] = `
|
searchFeatureVersionVulnerability = `
|
||||||
SELECT vafv.featureversion_id, v.id, v.name, v.description, v.link, v.severity, v.metadata,
|
SELECT vafv.featureversion_id, v.id, v.name, v.description, v.link, v.severity, v.metadata,
|
||||||
vn.name, vfif.version
|
vn.name, vfif.version
|
||||||
FROM Vulnerability_Affects_FeatureVersion vafv, Vulnerability v,
|
FROM Vulnerability_Affects_FeatureVersion vafv, Vulnerability v,
|
||||||
@ -116,64 +108,58 @@ func init() {
|
|||||||
AND v.namespace_id = vn.id
|
AND v.namespace_id = vn.id
|
||||||
AND v.deleted_at IS NULL`
|
AND v.deleted_at IS NULL`
|
||||||
|
|
||||||
queries["i_layer"] = `
|
insertLayer = `
|
||||||
INSERT INTO Layer(name, engineversion, parent_id, namespace_id, created_at)
|
INSERT INTO Layer(name, engineversion, parent_id, namespace_id, created_at)
|
||||||
VALUES($1, $2, $3, $4, CURRENT_TIMESTAMP)
|
VALUES($1, $2, $3, $4, CURRENT_TIMESTAMP)
|
||||||
RETURNING id`
|
RETURNING id`
|
||||||
|
|
||||||
queries["u_layer"] = `UPDATE LAYER SET engineversion = $2, namespace_id = $3 WHERE id = $1`
|
updateLayer = `UPDATE LAYER SET engineversion = $2, namespace_id = $3 WHERE id = $1`
|
||||||
|
|
||||||
queries["r_layer_diff_featureversion"] = `
|
removeLayerDiffFeatureVersion = `
|
||||||
DELETE FROM Layer_diff_FeatureVersion
|
DELETE FROM Layer_diff_FeatureVersion
|
||||||
WHERE layer_id = $1`
|
WHERE layer_id = $1`
|
||||||
|
|
||||||
queries["i_layer_diff_featureversion"] = `
|
insertLayerDiffFeatureVersion = `
|
||||||
INSERT INTO Layer_diff_FeatureVersion(layer_id, featureversion_id, modification)
|
INSERT INTO Layer_diff_FeatureVersion(layer_id, featureversion_id, modification)
|
||||||
SELECT $1, fv.id, $2
|
SELECT $1, fv.id, $2
|
||||||
FROM FeatureVersion fv
|
FROM FeatureVersion fv
|
||||||
WHERE fv.id = ANY($3::integer[])`
|
WHERE fv.id = ANY($3::integer[])`
|
||||||
|
|
||||||
queries["r_layer"] = `DELETE FROM Layer WHERE name = $1`
|
removeLayer = `DELETE FROM Layer WHERE name = $1`
|
||||||
|
|
||||||
// lock.go
|
// lock.go
|
||||||
queries["i_lock"] = `INSERT INTO Lock(name, owner, until) VALUES($1, $2, $3)`
|
insertLock = `INSERT INTO Lock(name, owner, until) VALUES($1, $2, $3)`
|
||||||
|
searchLock = `SELECT owner, until FROM Lock WHERE name = $1`
|
||||||
queries["f_lock"] = `SELECT owner, until FROM Lock WHERE name = $1`
|
updateLock = `UPDATE Lock SET until = $3 WHERE name = $1 AND owner = $2`
|
||||||
|
removeLock = `DELETE FROM Lock WHERE name = $1 AND owner = $2`
|
||||||
queries["u_lock"] = `UPDATE Lock SET until = $3 WHERE name = $1 AND owner = $2`
|
removeLockExpired = `DELETE FROM LOCK WHERE until < CURRENT_TIMESTAMP`
|
||||||
|
|
||||||
queries["r_lock"] = `DELETE FROM Lock WHERE name = $1 AND owner = $2`
|
|
||||||
|
|
||||||
queries["r_lock_expired"] = `DELETE FROM LOCK WHERE until < CURRENT_TIMESTAMP`
|
|
||||||
|
|
||||||
// vulnerability.go
|
// vulnerability.go
|
||||||
queries["f_vulnerability_base"] = `
|
searchVulnerabilityBase = `
|
||||||
SELECT v.id, v.name, n.id, n.name, v.description, v.link, v.severity, v.metadata
|
SELECT v.id, v.name, n.id, n.name, v.description, v.link, v.severity, v.metadata
|
||||||
FROM Vulnerability v JOIN Namespace n ON v.namespace_id = n.id`
|
FROM Vulnerability v JOIN Namespace n ON v.namespace_id = n.id`
|
||||||
|
searchVulnerabilityForUpdate = ` FOR UPDATE OF v`
|
||||||
|
searchVulnerabilityByNamespaceAndName = ` WHERE n.name = $1 AND v.name = $2 AND v.deleted_at IS NULL`
|
||||||
|
searchVulnerabilityByID = ` WHERE v.id = $1`
|
||||||
|
|
||||||
queries["f_vulnerability_for_update"] = ` FOR UPDATE OF v`
|
searchVulnerabilityFixedIn = `
|
||||||
queries["f_vulnerability_+by_name_namespace"] = ` WHERE n.name = $1 AND v.name = $2 AND v.deleted_at IS NULL`
|
|
||||||
queries["f_vulnerability_+by_id"] = ` WHERE v.id = $1`
|
|
||||||
|
|
||||||
queries["f_vulnerability_fixedin"] = `
|
|
||||||
SELECT vfif.version, f.id, f.Name
|
SELECT vfif.version, f.id, f.Name
|
||||||
FROM Vulnerability_FixedIn_Feature vfif JOIN Feature f ON vfif.feature_id = f.id
|
FROM Vulnerability_FixedIn_Feature vfif JOIN Feature f ON vfif.feature_id = f.id
|
||||||
WHERE vfif.vulnerability_id = $1`
|
WHERE vfif.vulnerability_id = $1`
|
||||||
|
|
||||||
queries["i_vulnerability"] = `
|
insertVulnerability = `
|
||||||
INSERT INTO Vulnerability(namespace_id, name, description, link, severity, metadata, created_at)
|
INSERT INTO Vulnerability(namespace_id, name, description, link, severity, metadata, created_at)
|
||||||
VALUES($1, $2, $3, $4, $5, $6, CURRENT_TIMESTAMP)
|
VALUES($1, $2, $3, $4, $5, $6, CURRENT_TIMESTAMP)
|
||||||
RETURNING id`
|
RETURNING id`
|
||||||
|
|
||||||
queries["i_vulnerability_fixedin_feature"] = `
|
insertVulnerabilityFixedInFeature = `
|
||||||
INSERT INTO Vulnerability_FixedIn_Feature(vulnerability_id, feature_id, version)
|
INSERT INTO Vulnerability_FixedIn_Feature(vulnerability_id, feature_id, version)
|
||||||
VALUES($1, $2, $3)
|
VALUES($1, $2, $3)
|
||||||
RETURNING id`
|
RETURNING id`
|
||||||
|
|
||||||
queries["f_featureversion_by_feature"] = `
|
searchFeatureVersionByFeature = `SELECT id, version FROM FeatureVersion WHERE feature_id = $1`
|
||||||
SELECT id, version FROM FeatureVersion WHERE feature_id = $1`
|
|
||||||
|
|
||||||
queries["r_vulnerability"] = `
|
removeVulnerability = `
|
||||||
UPDATE Vulnerability
|
UPDATE Vulnerability
|
||||||
SET deleted_at = CURRENT_TIMESTAMP
|
SET deleted_at = CURRENT_TIMESTAMP
|
||||||
WHERE namespace_id = (SELECT id FROM Namespace WHERE name = $1)
|
WHERE namespace_id = (SELECT id FROM Namespace WHERE name = $1)
|
||||||
@ -182,21 +168,21 @@ func init() {
|
|||||||
RETURNING id`
|
RETURNING id`
|
||||||
|
|
||||||
// notification.go
|
// notification.go
|
||||||
queries["i_notification"] = `
|
insertNotification = `
|
||||||
INSERT INTO Vulnerability_Notification(name, created_at, old_vulnerability_id, new_vulnerability_id)
|
INSERT INTO Vulnerability_Notification(name, created_at, old_vulnerability_id, new_vulnerability_id)
|
||||||
VALUES($1, CURRENT_TIMESTAMP, $2, $3)`
|
VALUES($1, CURRENT_TIMESTAMP, $2, $3)`
|
||||||
|
|
||||||
queries["u_notification_notified"] = `
|
updatedNotificationNotified = `
|
||||||
UPDATE Vulnerability_Notification
|
UPDATE Vulnerability_Notification
|
||||||
SET notified_at = CURRENT_TIMESTAMP
|
SET notified_at = CURRENT_TIMESTAMP
|
||||||
WHERE name = $1`
|
WHERE name = $1`
|
||||||
|
|
||||||
queries["r_notification"] = `
|
removeNotification = `
|
||||||
UPDATE Vulnerability_Notification
|
UPDATE Vulnerability_Notification
|
||||||
SET deleted_at = CURRENT_TIMESTAMP
|
SET deleted_at = CURRENT_TIMESTAMP
|
||||||
WHERE name = $1`
|
WHERE name = $1`
|
||||||
|
|
||||||
queries["s_notification_available"] = `
|
searchNotificationAvailable = `
|
||||||
SELECT id, name, created_at, notified_at, deleted_at
|
SELECT id, name, created_at, notified_at, deleted_at
|
||||||
FROM Vulnerability_Notification
|
FROM Vulnerability_Notification
|
||||||
WHERE (notified_at IS NULL OR notified_at < $1)
|
WHERE (notified_at IS NULL OR notified_at < $1)
|
||||||
@ -205,12 +191,12 @@ func init() {
|
|||||||
ORDER BY Random()
|
ORDER BY Random()
|
||||||
LIMIT 1`
|
LIMIT 1`
|
||||||
|
|
||||||
queries["s_notification"] = `
|
searchNotification = `
|
||||||
SELECT id, name, created_at, notified_at, deleted_at, old_vulnerability_id, new_vulnerability_id
|
SELECT id, name, created_at, notified_at, deleted_at, old_vulnerability_id, new_vulnerability_id
|
||||||
FROM Vulnerability_Notification
|
FROM Vulnerability_Notification
|
||||||
WHERE name = $1`
|
WHERE name = $1`
|
||||||
|
|
||||||
queries["s_notification_layer_introducing_vulnerability"] = `
|
searchNotificationLayerIntroducingVulnerability = `
|
||||||
SELECT l.ID, l.name
|
SELECT l.ID, l.name
|
||||||
FROM Vulnerability v, Vulnerability_Affects_FeatureVersion vafv, FeatureVersion fv, Layer_diff_FeatureVersion ldfv, Layer l
|
FROM Vulnerability v, Vulnerability_Affects_FeatureVersion vafv, FeatureVersion fv, Layer_diff_FeatureVersion ldfv, Layer l
|
||||||
WHERE v.id = $1
|
WHERE v.id = $1
|
||||||
@ -224,20 +210,13 @@ func init() {
|
|||||||
LIMIT $3`
|
LIMIT $3`
|
||||||
|
|
||||||
// complex_test.go
|
// complex_test.go
|
||||||
queries["s_complextest_featureversion_affects"] = `
|
searchComplexTestFeatureVersionAffects = `
|
||||||
SELECT v.name
|
SELECT v.name
|
||||||
FROM FeatureVersion fv
|
FROM FeatureVersion fv
|
||||||
LEFT JOIN Vulnerability_Affects_FeatureVersion vaf ON fv.id = vaf.featureversion_id
|
LEFT JOIN Vulnerability_Affects_FeatureVersion vaf ON fv.id = vaf.featureversion_id
|
||||||
JOIN Vulnerability v ON vaf.vulnerability_id = v.id
|
JOIN Vulnerability v ON vaf.vulnerability_id = v.id
|
||||||
WHERE featureversion_id = $1`
|
WHERE featureversion_id = $1`
|
||||||
}
|
)
|
||||||
|
|
||||||
func getQuery(name string) string {
|
|
||||||
if query, ok := queries[name]; ok {
|
|
||||||
return query
|
|
||||||
}
|
|
||||||
panic(fmt.Sprintf("pgsql: unknown query %v", name))
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildInputArray constructs a PostgreSQL input array from the specified integers.
|
// buildInputArray constructs a PostgreSQL input array from the specified integers.
|
||||||
// Useful to use the `= ANY($1::integer[])` syntax that let us use a IN clause while using
|
// Useful to use the `= ANY($1::integer[])` syntax that let us use a IN clause while using
|
||||||
|
@ -35,11 +35,11 @@ func (pgSQL *pgSQL) FindVulnerability(namespaceName, name string) (database.Vuln
|
|||||||
func findVulnerability(queryer Queryer, namespaceName, name string, forUpdate bool) (database.Vulnerability, error) {
|
func findVulnerability(queryer Queryer, namespaceName, name string, forUpdate bool) (database.Vulnerability, error) {
|
||||||
defer observeQueryTime("findVulnerability", "all", time.Now())
|
defer observeQueryTime("findVulnerability", "all", time.Now())
|
||||||
|
|
||||||
queryName := "f_vulnerability"
|
queryName := "searchVulnerabilityBase+searchVulnerabilityByNamespaceAndName"
|
||||||
query := getQuery("f_vulnerability_base") + getQuery("f_vulnerability_+by_name_namespace")
|
query := searchVulnerabilityBase + searchVulnerabilityByNamespaceAndName
|
||||||
if forUpdate {
|
if forUpdate {
|
||||||
queryName = queryName + "+for_update"
|
queryName = queryName + "+searchVulnerabilityForUpdate"
|
||||||
query = query + getQuery("f_vulnerability_for_update")
|
query = query + searchVulnerabilityForUpdate
|
||||||
}
|
}
|
||||||
|
|
||||||
return scanVulnerability(queryer, queryName, queryer.QueryRow(query, namespaceName, name))
|
return scanVulnerability(queryer, queryName, queryer.QueryRow(query, namespaceName, name))
|
||||||
@ -48,8 +48,8 @@ func findVulnerability(queryer Queryer, namespaceName, name string, forUpdate bo
|
|||||||
func (pgSQL *pgSQL) findVulnerabilityByIDWithDeleted(id int) (database.Vulnerability, error) {
|
func (pgSQL *pgSQL) findVulnerabilityByIDWithDeleted(id int) (database.Vulnerability, error) {
|
||||||
defer observeQueryTime("findVulnerabilityByIDWithDeleted", "all", time.Now())
|
defer observeQueryTime("findVulnerabilityByIDWithDeleted", "all", time.Now())
|
||||||
|
|
||||||
queryName := "f_vulnerability"
|
queryName := "searchVulnerabilityBase+searchVulnerabilityByID"
|
||||||
query := getQuery("f_vulnerability_base") + getQuery("f_vulnerability_+by_id")
|
query := searchVulnerabilityBase + searchVulnerabilityByID
|
||||||
|
|
||||||
return scanVulnerability(pgSQL, queryName, pgSQL.QueryRow(query, id))
|
return scanVulnerability(pgSQL, queryName, pgSQL.QueryRow(query, id))
|
||||||
}
|
}
|
||||||
@ -77,9 +77,9 @@ func scanVulnerability(queryer Queryer, queryName string, vulnerabilityRow *sql.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Query the FixedIn FeatureVersion now.
|
// Query the FixedIn FeatureVersion now.
|
||||||
rows, err := queryer.Query(getQuery("f_vulnerability_fixedin"), vulnerability.ID)
|
rows, err := queryer.Query(searchVulnerabilityFixedIn, vulnerability.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vulnerability, handleError("f_vulnerability_fixedin.Scan()", err)
|
return vulnerability, handleError("searchVulnerabilityFixedIn.Scan()", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ func scanVulnerability(queryer Queryer, queryName string, vulnerabilityRow *sql.
|
|||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vulnerability, handleError("f_vulnerability_fixedin.Scan()", err)
|
return vulnerability, handleError("searchVulnerabilityFixedIn.Scan()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !featureVersionID.IsZero() {
|
if !featureVersionID.IsZero() {
|
||||||
@ -115,7 +115,7 @@ func scanVulnerability(queryer Queryer, queryName string, vulnerabilityRow *sql.
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := rows.Err(); err != nil {
|
if err := rows.Err(); err != nil {
|
||||||
return vulnerability, handleError("f_vulnerability_fixedin.Rows()", err)
|
return vulnerability, handleError("searchVulnerabilityFixedIn.Rows()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return vulnerability, nil
|
return vulnerability, nil
|
||||||
@ -209,10 +209,10 @@ func (pgSQL *pgSQL) insertVulnerability(vulnerability database.Vulnerability, on
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mark the old vulnerability as non latest.
|
// Mark the old vulnerability as non latest.
|
||||||
_, err = tx.Exec(getQuery("r_vulnerability"), vulnerability.Namespace.Name, vulnerability.Name)
|
_, err = tx.Exec(removeVulnerability, vulnerability.Namespace.Name, vulnerability.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return handleError("r_vulnerability", err)
|
return handleError("removeVulnerability", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// The vulnerability is new, we don't want to have any types.MinVersion as they are only used
|
// The vulnerability is new, we don't want to have any types.MinVersion as they are only used
|
||||||
@ -234,7 +234,7 @@ func (pgSQL *pgSQL) insertVulnerability(vulnerability database.Vulnerability, on
|
|||||||
|
|
||||||
// Insert vulnerability.
|
// Insert vulnerability.
|
||||||
err = tx.QueryRow(
|
err = tx.QueryRow(
|
||||||
getQuery("i_vulnerability"),
|
insertVulnerability,
|
||||||
namespaceID,
|
namespaceID,
|
||||||
vulnerability.Name,
|
vulnerability.Name,
|
||||||
vulnerability.Description,
|
vulnerability.Description,
|
||||||
@ -245,7 +245,7 @@ func (pgSQL *pgSQL) insertVulnerability(vulnerability database.Vulnerability, on
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return handleError("i_vulnerability", err)
|
return handleError("insertVulnerability", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Vulnerability_FixedIn_Feature and Vulnerability_Affects_FeatureVersion now.
|
// Update Vulnerability_FixedIn_Feature and Vulnerability_Affects_FeatureVersion now.
|
||||||
@ -368,12 +368,12 @@ func (pgSQL *pgSQL) insertVulnerabilityFixedInFeatureVersions(tx *sql.Tx, vulner
|
|||||||
promConcurrentLockVAFV.Inc()
|
promConcurrentLockVAFV.Inc()
|
||||||
defer promConcurrentLockVAFV.Dec()
|
defer promConcurrentLockVAFV.Dec()
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
_, err = tx.Exec(getQuery("l_vulnerability_affects_featureversion"))
|
_, err = tx.Exec(lockVulnerabilityAffects)
|
||||||
observeQueryTime("insertVulnerability", "lock", t)
|
observeQueryTime("insertVulnerability", "lock", t)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return handleError("insertVulnerability.l_vulnerability_affects_featureversion", err)
|
return handleError("insertVulnerability.lockVulnerabilityAffects", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fv := range fixedIn {
|
for _, fv := range fixedIn {
|
||||||
@ -381,13 +381,13 @@ func (pgSQL *pgSQL) insertVulnerabilityFixedInFeatureVersions(tx *sql.Tx, vulner
|
|||||||
|
|
||||||
// Insert Vulnerability_FixedIn_Feature.
|
// Insert Vulnerability_FixedIn_Feature.
|
||||||
err = tx.QueryRow(
|
err = tx.QueryRow(
|
||||||
getQuery("i_vulnerability_fixedin_feature"),
|
insertVulnerabilityFixedInFeature,
|
||||||
vulnerabilityID, fv.Feature.ID,
|
vulnerabilityID, fv.Feature.ID,
|
||||||
&fv.Version,
|
&fv.Version,
|
||||||
).Scan(&fixedInID)
|
).Scan(&fixedInID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("i_vulnerability_fixedin_feature", err)
|
return handleError("insertVulnerabilityFixedInFeature", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert Vulnerability_Affects_FeatureVersion.
|
// Insert Vulnerability_Affects_FeatureVersion.
|
||||||
@ -403,9 +403,9 @@ func (pgSQL *pgSQL) insertVulnerabilityFixedInFeatureVersions(tx *sql.Tx, vulner
|
|||||||
func linkVulnerabilityToFeatureVersions(tx *sql.Tx, fixedInID, vulnerabilityID, featureID int, fixedInVersion types.Version) error {
|
func linkVulnerabilityToFeatureVersions(tx *sql.Tx, fixedInID, vulnerabilityID, featureID int, fixedInVersion types.Version) error {
|
||||||
// Find every FeatureVersions of the Feature that the vulnerability affects.
|
// Find every FeatureVersions of the Feature that the vulnerability affects.
|
||||||
// TODO(Quentin-M): LIMIT
|
// TODO(Quentin-M): LIMIT
|
||||||
rows, err := tx.Query(getQuery("f_featureversion_by_feature"), featureID)
|
rows, err := tx.Query(searchFeatureVersionByFeature, featureID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("f_featureversion_by_feature", err)
|
return handleError("searchFeatureVersionByFeature", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
@ -415,7 +415,7 @@ func linkVulnerabilityToFeatureVersions(tx *sql.Tx, fixedInID, vulnerabilityID,
|
|||||||
|
|
||||||
err := rows.Scan(&affected.ID, &affected.Version)
|
err := rows.Scan(&affected.ID, &affected.Version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("f_featureversion_by_feature.Scan()", err)
|
return handleError("searchFeatureVersionByFeature.Scan()", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if affected.Version.Compare(fixedInVersion) < 0 {
|
if affected.Version.Compare(fixedInVersion) < 0 {
|
||||||
@ -425,17 +425,17 @@ func linkVulnerabilityToFeatureVersions(tx *sql.Tx, fixedInID, vulnerabilityID,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = rows.Err(); err != nil {
|
if err = rows.Err(); err != nil {
|
||||||
return handleError("f_featureversion_by_feature.Rows()", err)
|
return handleError("searchFeatureVersionByFeature.Rows()", err)
|
||||||
}
|
}
|
||||||
rows.Close()
|
rows.Close()
|
||||||
|
|
||||||
// Insert into Vulnerability_Affects_FeatureVersion.
|
// Insert into Vulnerability_Affects_FeatureVersion.
|
||||||
for _, affected := range affecteds {
|
for _, affected := range affecteds {
|
||||||
// TODO(Quentin-M): Batch me.
|
// TODO(Quentin-M): Batch me.
|
||||||
_, err := tx.Exec(getQuery("i_vulnerability_affects_featureversion"), vulnerabilityID,
|
_, err := tx.Exec(insertVulnerabilityAffectsFeatureVersion, vulnerabilityID,
|
||||||
affected.ID, fixedInID)
|
affected.ID, fixedInID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleError("i_vulnerability_affects_featureversion", err)
|
return handleError("insertVulnerabilityAffectsFeatureVersion", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,10 +491,10 @@ func (pgSQL *pgSQL) DeleteVulnerability(namespaceName, name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var vulnerabilityID int
|
var vulnerabilityID int
|
||||||
err = tx.QueryRow(getQuery("r_vulnerability"), namespaceName, name).Scan(&vulnerabilityID)
|
err = tx.QueryRow(removeVulnerability, namespaceName, name).Scan(&vulnerabilityID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return handleError("r_vulnerability", err)
|
return handleError("removeVulnerability", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a notification.
|
// Create a notification.
|
||||||
|
Loading…
Reference in New Issue
Block a user