@ -32,6 +32,7 @@ import (
// Import pq for postgres dialect
_ "github.com/lib/pq"
"helm.sh/helm/v4/internal/logging"
"helm.sh/helm/v4/pkg/release"
rspb "helm.sh/helm/v4/pkg/release/v1"
)
@ -89,6 +90,8 @@ type SQL struct {
db * sqlx . DB
namespace string
statementBuilder sq . StatementBuilderType
// Embed a LogHolder to provide logger functionality
logging . LogHolder
}
// Name returns the name of the driver.
@ -109,13 +112,13 @@ func (s *SQL) checkAlreadyApplied(migrations []*migrate.Migration) bool {
records , err := migrate . GetMigrationRecords ( s . db . DB , postgreSQLDialect )
migrate . SetDisableCreateTable ( false )
if err != nil {
s log . Debug ( "failed to get migration records" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to get migration records" , slog . Any ( "error" , err ) )
return false
}
for _ , record := range records {
if _ , ok := migrationsIDs [ record . Id ] ; ok {
s log . Debug ( "found previous migration" , "id" , record . Id , "appliedAt" , record . AppliedAt )
s . Logger ( ) . Debug ( "found previous migration" , "id" , record . Id , "appliedAt" , record . AppliedAt )
delete ( migrationsIDs , record . Id )
}
}
@ -123,7 +126,7 @@ func (s *SQL) checkAlreadyApplied(migrations []*migrate.Migration) bool {
// check if all migrations applied
if len ( migrationsIDs ) != 0 {
for id := range migrationsIDs {
s log . Debug ( "find unapplied migration" , "id" , id )
s . Logger ( ) . Debug ( "find unapplied migration" , "id" , id )
}
return false
}
@ -157,9 +160,9 @@ func (s *SQL) ensureDBSetup() error {
CREATE INDEX ON % s ( % s ) ;
CREATE INDEX ON % s ( % s ) ;
CREATE INDEX ON % s ( % s ) ;
GRANT ALL ON % s TO PUBLIC ;
ALTER TABLE % s ENABLE ROW LEVEL SECURITY ;
` ,
sqlReleaseTableName ,
@ -209,7 +212,7 @@ func (s *SQL) ensureDBSetup() error {
% s VARCHAR ( % d )
) ;
CREATE INDEX ON % s ( % s , % s ) ;
GRANT ALL ON % s TO PUBLIC ;
ALTER TABLE % s ENABLE ROW LEVEL SECURITY ;
` ,
@ -293,6 +296,7 @@ func NewSQL(connectionString string, namespace string) (*SQL, error) {
}
driver . namespace = namespace
driver . SetLogger ( slog . Default ( ) . Handler ( ) )
return driver , nil
}
@ -309,24 +313,24 @@ func (s *SQL) Get(key string) (release.Releaser, error) {
query , args , err := qb . ToSql ( )
if err != nil {
s log . Debug ( "failed to build query" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to build query" , slog . Any ( "error" , err ) )
return nil , err
}
// Get will return an error if the result is empty
if err := s . db . Get ( & record , query , args ... ) ; err != nil {
s log . Debug ( "got SQL error when getting release" , "key" , key , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "got SQL error when getting release" , "key" , key , slog . Any ( "error" , err ) )
return nil , ErrReleaseNotFound
}
release , err := decodeRelease ( record . Body )
if err != nil {
s log . Debug ( "failed to decode data" , "key" , key , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to decode data" , "key" , key , slog . Any ( "error" , err ) )
return nil , err
}
if release . Labels , err = s . getReleaseCustomLabels ( key , s . namespace ) ; err != nil {
s log . Debug ( "failed to get release custom labels" , "namespace" , s . namespace , "key" , key , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to get release custom labels" , "namespace" , s . namespace , "key" , key , slog . Any ( "error" , err ) )
return nil , err
}
@ -347,13 +351,13 @@ func (s *SQL) List(filter func(release.Releaser) bool) ([]release.Releaser, erro
query , args , err := sb . ToSql ( )
if err != nil {
s log . Debug ( "failed to build query" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to build query" , slog . Any ( "error" , err ) )
return nil , err
}
var records = [ ] SQLReleaseWrapper { }
if err := s . db . Select ( & records , query , args ... ) ; err != nil {
s log . Debug ( "failed to list" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to list" , slog . Any ( "error" , err ) )
return nil , err
}
@ -361,12 +365,12 @@ func (s *SQL) List(filter func(release.Releaser) bool) ([]release.Releaser, erro
for _ , record := range records {
release , err := decodeRelease ( record . Body )
if err != nil {
s log . Debug ( "failed to decode release" , "record" , record , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to decode release" , "record" , record , slog . Any ( "error" , err ) )
continue
}
if release . Labels , err = s . getReleaseCustomLabels ( record . Key , record . Namespace ) ; err != nil {
s log . Debug ( "failed to get release custom labels" , "namespace" , record . Namespace , "key" , record . Key , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to get release custom labels" , "namespace" , record . Namespace , "key" , record . Key , slog . Any ( "error" , err ) )
return nil , err
}
maps . Copy ( release . Labels , getReleaseSystemLabels ( release ) )
@ -394,7 +398,7 @@ func (s *SQL) Query(labels map[string]string) ([]release.Releaser, error) {
if _ , ok := labelMap [ key ] ; ok {
sb = sb . Where ( sq . Eq { key : labels [ key ] } )
} else {
s log . Debug ( "unknown label" , "key" , key )
s . Logger ( ) . Debug ( "unknown label" , "key" , key )
return nil , fmt . Errorf ( "unknown label %s" , key )
}
}
@ -407,13 +411,13 @@ func (s *SQL) Query(labels map[string]string) ([]release.Releaser, error) {
// Build our query
query , args , err := sb . ToSql ( )
if err != nil {
s log . Debug ( "failed to build query" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to build query" , slog . Any ( "error" , err ) )
return nil , err
}
var records = [ ] SQLReleaseWrapper { }
if err := s . db . Select ( & records , query , args ... ) ; err != nil {
s log . Debug ( "failed to query with labels" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to query with labels" , slog . Any ( "error" , err ) )
return nil , err
}
@ -425,12 +429,12 @@ func (s *SQL) Query(labels map[string]string) ([]release.Releaser, error) {
for _ , record := range records {
release , err := decodeRelease ( record . Body )
if err != nil {
s log . Debug ( "failed to decode release" , "record" , record , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to decode release" , "record" , record , slog . Any ( "error" , err ) )
continue
}
if release . Labels , err = s . getReleaseCustomLabels ( record . Key , record . Namespace ) ; err != nil {
s log . Debug ( "failed to get release custom labels" , "namespace" , record . Namespace , "key" , record . Key , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to get release custom labels" , "namespace" , record . Namespace , "key" , record . Key , slog . Any ( "error" , err ) )
return nil , err
}
@ -459,13 +463,13 @@ func (s *SQL) Create(key string, rel release.Releaser) error {
body , err := encodeRelease ( rls )
if err != nil {
s log . Debug ( "failed to encode release" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to encode release" , slog . Any ( "error" , err ) )
return err
}
transaction , err := s . db . Beginx ( )
if err != nil {
s log . Debug ( "failed to start SQL transaction" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to start SQL transaction" , slog . Any ( "error" , err ) )
return fmt . Errorf ( "error beginning transaction: %v" , err )
}
@ -494,7 +498,7 @@ func (s *SQL) Create(key string, rel release.Releaser) error {
int ( time . Now ( ) . Unix ( ) ) ,
) . ToSql ( )
if err != nil {
s log . Debug ( "failed to build insert query" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to build insert query" , slog . Any ( "error" , err ) )
return err
}
@ -508,17 +512,17 @@ func (s *SQL) Create(key string, rel release.Releaser) error {
Where ( sq . Eq { sqlReleaseTableNamespaceColumn : s . namespace } ) .
ToSql ( )
if buildErr != nil {
s log . Debug ( "failed to build select query" , "error" , buildErr )
s . Logger ( ) . Debug ( "failed to build select query" , "error" , buildErr )
return err
}
var record SQLReleaseWrapper
if err := transaction . Get ( & record , selectQuery , args ... ) ; err == nil {
s log . Debug ( "release already exists" , "key" , key )
s . Logger ( ) . Debug ( "release already exists" , "key" , key )
return ErrReleaseExists
}
s log . Debug ( "failed to store release in SQL database" , "key" , key , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to store release in SQL database" , "key" , key , slog . Any ( "error" , err ) )
return err
}
@ -541,13 +545,13 @@ func (s *SQL) Create(key string, rel release.Releaser) error {
if err != nil {
defer transaction . Rollback ( )
s log . Debug ( "failed to build insert query" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to build insert query" , slog . Any ( "error" , err ) )
return err
}
if _ , err := transaction . Exec ( insertLabelsQuery , args ... ) ; err != nil {
defer transaction . Rollback ( )
s log . Debug ( "failed to write Labels" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to write Labels" , slog . Any ( "error" , err ) )
return err
}
}
@ -570,7 +574,7 @@ func (s *SQL) Update(key string, rel release.Releaser) error {
body , err := encodeRelease ( rls )
if err != nil {
s log . Debug ( "failed to encode release" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to encode release" , slog . Any ( "error" , err ) )
return err
}
@ -587,12 +591,12 @@ func (s *SQL) Update(key string, rel release.Releaser) error {
ToSql ( )
if err != nil {
s log . Debug ( "failed to build update query" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to build update query" , slog . Any ( "error" , err ) )
return err
}
if _ , err := s . db . Exec ( query , args ... ) ; err != nil {
s log . Debug ( "failed to update release in SQL database" , "key" , key , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to update release in SQL database" , "key" , key , slog . Any ( "error" , err ) )
return err
}
@ -603,7 +607,7 @@ func (s *SQL) Update(key string, rel release.Releaser) error {
func ( s * SQL ) Delete ( key string ) ( release . Releaser , error ) {
transaction , err := s . db . Beginx ( )
if err != nil {
s log . Debug ( "failed to start SQL transaction" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to start SQL transaction" , slog . Any ( "error" , err ) )
return nil , fmt . Errorf ( "error beginning transaction: %v" , err )
}
@ -614,20 +618,20 @@ func (s *SQL) Delete(key string) (release.Releaser, error) {
Where ( sq . Eq { sqlReleaseTableNamespaceColumn : s . namespace } ) .
ToSql ( )
if err != nil {
s log . Debug ( "failed to build select query" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to build select query" , slog . Any ( "error" , err ) )
return nil , err
}
var record SQLReleaseWrapper
err = transaction . Get ( & record , selectQuery , args ... )
if err != nil {
s log . Debug ( "release not found" , "key" , key , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "release not found" , "key" , key , slog . Any ( "error" , err ) )
return nil , ErrReleaseNotFound
}
release , err := decodeRelease ( record . Body )
if err != nil {
s log . Debug ( "failed to decode release" , "key" , key , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to decode release" , "key" , key , slog . Any ( "error" , err ) )
transaction . Rollback ( )
return nil , err
}
@ -639,18 +643,18 @@ func (s *SQL) Delete(key string) (release.Releaser, error) {
Where ( sq . Eq { sqlReleaseTableNamespaceColumn : s . namespace } ) .
ToSql ( )
if err != nil {
s log . Debug ( "failed to build delete query" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to build delete query" , slog . Any ( "error" , err ) )
return nil , err
}
_ , err = transaction . Exec ( deleteQuery , args ... )
if err != nil {
s log . Debug ( "failed perform delete query" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed perform delete query" , slog . Any ( "error" , err ) )
return release , err
}
if release . Labels , err = s . getReleaseCustomLabels ( key , s . namespace ) ; err != nil {
s log . Debug ( "failed to get release custom labels" , "namespace" , s . namespace , "key" , key , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to get release custom labels" , "namespace" , s . namespace , "key" , key , slog . Any ( "error" , err ) )
return nil , err
}
@ -661,7 +665,7 @@ func (s *SQL) Delete(key string) (release.Releaser, error) {
ToSql ( )
if err != nil {
s log . Debug ( "failed to build delete Labels query" , slog . Any ( "error" , err ) )
s . Logger ( ) . Debug ( "failed to build delete Labels query" , slog . Any ( "error" , err ) )
return nil , err
}
_ , err = transaction . Exec ( deleteCustomLabelsQuery , args ... )