github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/connection/connection_state_table_updater.go (about)

     1  package connection
     2  
     3  import (
     4  	"context"
     5  	"log"
     6  
     7  	"github.com/jackc/pgx/v5"
     8  	"github.com/jackc/pgx/v5/pgxpool"
     9  	"github.com/turbot/steampipe/pkg/constants"
    10  	"github.com/turbot/steampipe/pkg/db/db_common"
    11  	"github.com/turbot/steampipe/pkg/db/db_local"
    12  	"github.com/turbot/steampipe/pkg/introspection"
    13  	"github.com/turbot/steampipe/pkg/steampipeconfig"
    14  )
    15  
    16  type connectionStateTableUpdater struct {
    17  	updates *steampipeconfig.ConnectionUpdates
    18  	pool    *pgxpool.Pool
    19  }
    20  
    21  func newConnectionStateTableUpdater(updates *steampipeconfig.ConnectionUpdates, pool *pgxpool.Pool) *connectionStateTableUpdater {
    22  	log.Println("[DEBUG] newConnectionStateTableUpdater start")
    23  	defer log.Println("[DEBUG] newConnectionStateTableUpdater end")
    24  
    25  	return &connectionStateTableUpdater{
    26  		updates: updates,
    27  		pool:    pool,
    28  	}
    29  }
    30  
    31  // update connection state table to indicate the updates that will be done
    32  func (u *connectionStateTableUpdater) start(ctx context.Context) error {
    33  	log.Println("[DEBUG] connectionStateTableUpdater.start start")
    34  	defer log.Println("[DEBUG] connectionStateTableUpdater.start end")
    35  
    36  	var queries []db_common.QueryWithArgs
    37  
    38  	// update the conection state table to set appropriate state for all connections
    39  	// set updates to "updating"
    40  	for name, connectionState := range u.updates.FinalConnectionState {
    41  		// set the connection data state based on whether this connection is being created or deleted
    42  		if _, updatingConnection := u.updates.Update[name]; updatingConnection {
    43  			connectionState.State = constants.ConnectionStateUpdating
    44  			connectionState.CommentsSet = false
    45  		} else if validationError, connectionIsInvalid := u.updates.InvalidConnections[name]; connectionIsInvalid {
    46  			// if this connection has an error, set to error
    47  			connectionState.State = constants.ConnectionStateError
    48  			connectionState.ConnectionError = &validationError.Message
    49  		}
    50  		// get the sql to update the connection state in the table to match the struct
    51  		queries = append(queries, introspection.GetUpsertConnectionStateSql(connectionState)...)
    52  	}
    53  	// set deletions to "deleting"
    54  	for name := range u.updates.Delete {
    55  		// if we are we deleting the schema because schema_import="disabled", DO NOT set state to deleting -
    56  		// it will be set to "disabled below
    57  		if _, connectionDisabled := u.updates.Disabled[name]; connectionDisabled {
    58  			continue
    59  		}
    60  
    61  		queries = append(queries, introspection.GetSetConnectionStateSql(name, constants.ConnectionStateDeleting)...)
    62  	}
    63  
    64  	// set any connections with import_schema=disabled to "disabled"
    65  	// also build a lookup of disabled connections
    66  	for name := range u.updates.Disabled {
    67  		queries = append(queries, introspection.GetSetConnectionStateSql(name, constants.ConnectionStateDisabled)...)
    68  	}
    69  	conn, err := u.pool.Acquire(ctx)
    70  	if err != nil {
    71  		return err
    72  	}
    73  	defer conn.Release()
    74  	if _, err = db_local.ExecuteSqlWithArgsInTransaction(ctx, conn.Conn(), queries...); err != nil {
    75  		return err
    76  	}
    77  	return nil
    78  }
    79  
    80  func (u *connectionStateTableUpdater) onConnectionReady(ctx context.Context, conn *pgx.Conn, name string) error {
    81  	log.Println("[DEBUG] connectionStateTableUpdater.onConnectionReady start")
    82  	defer log.Println("[DEBUG] connectionStateTableUpdater.onConnectionReady end")
    83  
    84  	connection := u.updates.FinalConnectionState[name]
    85  	queries := introspection.GetSetConnectionStateSql(connection.ConnectionName, constants.ConnectionStateReady)
    86  	for _, q := range queries {
    87  		if _, err := conn.Exec(ctx, q.Query, q.Args...); err != nil {
    88  			return err
    89  		}
    90  	}
    91  	return nil
    92  }
    93  
    94  func (u *connectionStateTableUpdater) onConnectionCommentsLoaded(ctx context.Context, conn *pgx.Conn, name string) error {
    95  	log.Println("[DEBUG] connectionStateTableUpdater.onConnectionCommentsLoaded start")
    96  	defer log.Println("[DEBUG] connectionStateTableUpdater.onConnectionCommentsLoaded end")
    97  
    98  	connection := u.updates.FinalConnectionState[name]
    99  	queries := introspection.GetSetConnectionStateCommentLoadedSql(connection.ConnectionName, true)
   100  	for _, q := range queries {
   101  		if _, err := conn.Exec(ctx, q.Query, q.Args...); err != nil {
   102  			return err
   103  		}
   104  	}
   105  	return nil
   106  }
   107  
   108  func (u *connectionStateTableUpdater) onConnectionDeleted(ctx context.Context, conn *pgx.Conn, name string) error {
   109  	log.Println("[DEBUG] connectionStateTableUpdater.onConnectionDeleted start")
   110  	defer log.Println("[DEBUG] connectionStateTableUpdater.onConnectionDeleted end")
   111  
   112  	// if this connection has schema import disabled, DO NOT delete from the conneciotn state table
   113  	if _, connectionDisabled := u.updates.Disabled[name]; connectionDisabled {
   114  		return nil
   115  	}
   116  	queries := introspection.GetDeleteConnectionStateSql(name)
   117  	for _, q := range queries {
   118  		if _, err := conn.Exec(ctx, q.Query, q.Args...); err != nil {
   119  			return err
   120  		}
   121  	}
   122  	return nil
   123  }
   124  
   125  func (u *connectionStateTableUpdater) onConnectionError(ctx context.Context, conn *pgx.Conn, connectionName string, err error) error {
   126  	log.Println("[DEBUG] connectionStateTableUpdater.onConnectionError start")
   127  	defer log.Println("[DEBUG] connectionStateTableUpdater.onConnectionError end")
   128  
   129  	queries := introspection.GetConnectionStateErrorSql(connectionName, err)
   130  	for _, q := range queries {
   131  		if _, err := conn.Exec(ctx, q.Query, q.Args...); err != nil {
   132  			return err
   133  		}
   134  	}
   135  
   136  	return nil
   137  }