github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/steampipeconfig/connection_state.go (about) 1 package steampipeconfig 2 3 import ( 4 "sort" 5 "strings" 6 "time" 7 8 typehelpers "github.com/turbot/go-kit/types" 9 "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 10 "github.com/turbot/steampipe/pkg/constants" 11 "github.com/turbot/steampipe/pkg/steampipeconfig/modconfig" 12 ) 13 14 // ConnectionState is a struct containing all details for a connection 15 // - the plugin name and checksum, the connection config and options 16 // json tags needed as this is stored in the connection state file 17 type ConnectionState struct { 18 // the connection name 19 ConnectionName string `json:"connection" db:"name"` 20 // connection type (expected value: "aggregator") 21 Type *string `json:"type,omitempty" db:"type"` 22 // should we create a postgres schema for the connection (expected values: "enable", "disable") 23 ImportSchema string `json:"import_schema" db:"import_schema"` 24 // the fully qualified name of the plugin 25 Plugin string `json:"plugin" db:"plugin"` 26 // the plugin instance 27 PluginInstance *string `json:"plugin_instance" db:"plugin_instance"` 28 // the connection state (pending, updating, deleting, error, ready) 29 State string `json:"state" db:"state"` 30 // error (if there is one - make a pointer to support null) 31 ConnectionError *string `json:"error,omitempty" db:"error"` 32 // schema mode - static or dynamic 33 SchemaMode string `json:"schema_mode" db:"schema_mode"` 34 // the hash of the connection schema - this is used to determine if a dynamic schema has changed 35 SchemaHash string `json:"schema_hash,omitempty" db:"schema_hash"` 36 // are the comments set 37 CommentsSet bool `json:"comments_set" db:"comments_set"` 38 // the creation time of the plugin file 39 PluginModTime time.Time `json:"plugin_mod_time" db:"plugin_mod_time"` 40 // the update time of the connection 41 ConnectionModTime time.Time `json:"connection_mod_time" db:"connection_mod_time"` 42 // the matching patterns of child connections (for aggregators) 43 Connections []string `json:"connections" db:"connections"` 44 FileName string `json:"file_name" db:"file_name"` 45 StartLineNumber int `json:"start_line_number" db:"start_line_number"` 46 EndLineNumber int `json:"end_line_number" db:"end_line_number"` 47 } 48 49 func NewConnectionState(connection *modconfig.Connection, creationTime time.Time) *ConnectionState { 50 state := &ConnectionState{ 51 Plugin: connection.Plugin, 52 PluginInstance: connection.PluginInstance, 53 ConnectionName: connection.Name, 54 PluginModTime: creationTime, 55 State: constants.ConnectionStateReady, 56 Type: &connection.Type, 57 ImportSchema: connection.ImportSchema, 58 Connections: connection.ConnectionNames, 59 } 60 state.setFilename(connection) 61 if connection.Error != nil { 62 state.SetError(connection.Error.Error()) 63 } 64 return state 65 } 66 67 func (d *ConnectionState) setFilename(connection *modconfig.Connection) { 68 d.FileName = connection.DeclRange.Filename 69 d.StartLineNumber = connection.DeclRange.Start.Line 70 d.EndLineNumber = connection.DeclRange.End.Line 71 } 72 73 func (d *ConnectionState) Equals(other *ConnectionState) bool { 74 if d.Plugin != other.Plugin { 75 return false 76 } 77 if d.GetType() != other.GetType() { 78 return false 79 } 80 if d.ImportSchema != other.ImportSchema { 81 return false 82 } 83 if d.Error() != other.Error() { 84 return false 85 } 86 87 names := d.Connections 88 sort.Strings(names) 89 otherNames := other.Connections 90 sort.Strings(otherNames) 91 if strings.Join(names, ",") != strings.Join(otherNames, "'") { 92 return false 93 } 94 95 if d.pluginModTimeChanged(other) { 96 return false 97 } 98 // do not look at connection mod time as the mod time for the desired state is not relevant 99 100 return true 101 } 102 103 // allow for sub ms rounding errors when converting from PG 104 func (d *ConnectionState) pluginModTimeChanged(other *ConnectionState) bool { 105 return d.PluginModTime.Sub(other.PluginModTime).Abs() > 1*time.Millisecond 106 } 107 108 func (d *ConnectionState) CanCloneSchema() bool { 109 return d.SchemaMode != plugin.SchemaModeDynamic && 110 d.GetType() != modconfig.ConnectionTypeAggregator 111 } 112 113 func (d *ConnectionState) Error() string { 114 return typehelpers.SafeString(d.ConnectionError) 115 } 116 117 func (d *ConnectionState) SetError(err string) { 118 d.State = constants.ConnectionStateError 119 d.ConnectionError = &err 120 } 121 122 // Loaded returns true if the connection state is 'ready' or 'error' 123 // Disabled connections are considered as 'loaded' 124 func (d *ConnectionState) Loaded() bool { 125 return d.Disabled() || d.State == constants.ConnectionStateReady || d.State == constants.ConnectionStateError 126 } 127 128 func (d *ConnectionState) Disabled() bool { 129 return d.State == constants.ConnectionStateDisabled 130 } 131 132 func (d *ConnectionState) GetType() string { 133 return typehelpers.SafeString(d.Type) 134 }