public static TableInformation RetrieveTableInformation()

in src/SqlAsyncCollector.cs [569:659]


            public static TableInformation RetrieveTableInformation(SqlConnection sqlConnection, string fullName, ILogger logger, ServerProperties serverProperties)
            {
                Dictionary<TelemetryPropertyName, string> sqlConnProps = sqlConnection.AsConnectionProps(serverProperties);
                var table = new SqlObject(fullName);

                var tableInfoSw = Stopwatch.StartNew();

                // Get all column names and types
                var columnDefinitionsFromSQL = new Dictionary<string, string>();
                var columnDefinitionsSw = Stopwatch.StartNew();
                try
                {
                    string getColumnDefinitionsQuery = GetColumnDefinitionsQuery(table);
                    var cmdColDef = new SqlCommand(getColumnDefinitionsQuery, sqlConnection);
                    using (SqlDataReader rdr = cmdColDef.ExecuteReaderWithLogging(logger))
                    {
                        while (rdr.Read())
                        {
                            string columnName = rdr[ColumnName].ToString();
                            columnDefinitionsFromSQL.Add(columnName, rdr[ColumnDefinition].ToString());
                        }
                        columnDefinitionsSw.Stop();
                        TelemetryInstance.TrackDuration(TelemetryEventName.GetColumnDefinitions, columnDefinitionsSw.ElapsedMilliseconds, sqlConnProps);
                    }

                }
                catch (Exception ex)
                {
                    TelemetryInstance.TrackException(TelemetryErrorName.GetColumnDefinitions, ex, sqlConnProps);
                    // Throw a custom error so that it's easier to decipher.
                    string message = $"Encountered exception while retrieving column names and types for table {table}. Cannot generate upsert command without them.";
                    throw new InvalidOperationException(message, ex);
                }

                if (columnDefinitionsFromSQL.Count == 0)
                {
                    string message = $"Table {table} does not exist.";
                    var ex = new InvalidOperationException(message);
                    TelemetryInstance.TrackException(TelemetryErrorName.GetColumnDefinitionsTableDoesNotExist, ex, sqlConnProps);
                    throw ex;
                }

                // Query SQL for table Primary Keys
                var primaryKeys = new List<PrimaryKey>();
                var primaryKeysSw = Stopwatch.StartNew();
                try
                {
                    string getPrimaryKeysQuery = GetPrimaryKeysQuery(table);
                    var cmd = new SqlCommand(getPrimaryKeysQuery, sqlConnection);
                    using (SqlDataReader rdr = cmd.ExecuteReaderWithLogging(logger))
                    {
                        while (rdr.Read())
                        {
                            string columnName = rdr[ColumnName].ToString();
                            primaryKeys.Add(new PrimaryKey(columnName, bool.Parse(rdr[IsIdentity].ToString()), bool.Parse(rdr[HasDefault].ToString())));
                        }
                        primaryKeysSw.Stop();
                        TelemetryInstance.TrackDuration(TelemetryEventName.GetPrimaryKeys, primaryKeysSw.ElapsedMilliseconds, sqlConnProps);
                    }
                }
                catch (Exception ex)
                {
                    TelemetryInstance.TrackException(TelemetryErrorName.GetPrimaryKeys, ex, sqlConnProps);
                    // Throw a custom error so that it's easier to decipher.
                    string message = $"Encountered exception while retrieving primary keys for table {table}. Cannot generate upsert command without them.";
                    throw new InvalidOperationException(message, ex);
                }

                if (primaryKeys.Count == 0)
                {
                    string message = $"Did not retrieve any primary keys for {table}. Cannot generate upsert command without them.";
                    var ex = new InvalidOperationException(message);
                    TelemetryInstance.TrackException(TelemetryErrorName.NoPrimaryKeys, ex, sqlConnProps);
                    throw ex;
                }

                // Match SQL Primary Key column names to POCO property objects. Ensure none are missing.
                IEnumerable<PropertyInfo> primaryKeyProperties = typeof(T).GetProperties().Where(f => primaryKeys.Any(k => string.Equals(k.Name, f.Name, StringComparison.Ordinal)));
                bool hasIdentityColumnPrimaryKeys = primaryKeys.Any(k => k.IsIdentity);
                bool hasDefaultColumnPrimaryKeys = primaryKeys.Any(k => k.HasDefault);

                tableInfoSw.Stop();
                var durations = new Dictionary<TelemetryMeasureName, double>()
                {
                    { TelemetryMeasureName.GetColumnDefinitionsDurationMs, columnDefinitionsSw.ElapsedMilliseconds },
                    { TelemetryMeasureName.GetPrimaryKeysDurationMs, primaryKeysSw.ElapsedMilliseconds }
                };
                sqlConnProps.Add(TelemetryPropertyName.HasIdentityColumnPrimaryKeys, hasIdentityColumnPrimaryKeys.ToString());
                sqlConnProps.Add(TelemetryPropertyName.HasDefaultColumnPrimaryKeys, hasDefaultColumnPrimaryKeys.ToString());
                TelemetryInstance.TrackDuration(TelemetryEventName.GetTableInfo, tableInfoSw.ElapsedMilliseconds, sqlConnProps, durations);
                logger.LogDebug($"RetrieveTableInformation DB and Table: {sqlConnection.Database}.{fullName}. Primary keys: [{string.Join(",", primaryKeys.Select(pk => pk.Name))}].\nSQL Column and Definitions:  [{string.Join(",", columnDefinitionsFromSQL)}]");