using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using Dapper; using DataModel.Models; using NLog; namespace DataModel.Process { /// /// LotFinder cache database interface /// public partial class LotFinderDB { /// /// Default command timeout (ms) /// protected const int DEFAULT_TIMEOUT = 600; /// /// Shared logger instance /// protected static readonly Logger logger = LogManager.GetCurrentClassLogger(); /// /// Gets opened connection to LotFinder database /// /// Open SqlConnection to LotFinder database public static SqlConnection GetConnection() { SqlConnection connection = null; try { //Create and open connection to LotFinder database connection = new SqlConnection(Config.LotFinderDBCS); connection.Open(); } catch (Exception error) { //Log error and forward logger.Error("GetConnection: failed to open connection to DB: {0}.", error.Message); throw new Exception("LotFinderDB: failed to open connection to database.", error); } return connection; } /// /// SQL to rebuild all indices on table with fillfactor of 95 /// private const string SQL_REBUILD_INDICES = "ALTER INDEX ALL ON {0} REBUILD WITH (FILLFACTOR = 95);"; /// /// Rebuilds all the indices on the given table with fillfactor of 95 /// /// Name of table to rebuild indices on public static void RebuildIndices(string tableName) { using (SqlConnection connection = GetConnection()) { connection.Execute(string.Format(SQL_REBUILD_INDICES, tableName), commandTimeout: DEFAULT_TIMEOUT); } } /// /// Generates table-valued parameter data table /// /// Key data type /// Keys to store in table /// Populated table-value parameter data table public static DataTable GenerateTableParameter(List keys) { DataTable dataTable = new DataTable(); dataTable.Columns.Add("Key", typeof(T)); foreach (T key in keys) { dataTable.Rows.Add(key); } return dataTable; } private const string SQL_GET_LAST_DATA_UPDATES = @" WITH DU_CTE AS ( SELECT du.*, ROW_NUMBER() OVER (PARTITION BY du.TableName, du.UpdateType ORDER BY du.StartDT DESC) RN FROM dbo.DataUpdate AS du ) SELECT cte.SourceSystem, cte.SourceData, cte.TableName, cte.StartDT, cte.EndDT, cte.UpdateType, cte.WasSuccessful, cte.NumberRecords FROM DU_CTE cte WHERE cte.RN = 1"; public static List GetLastDataUpdates() { List dataUpdates = new List(); using (SqlConnection connection = GetConnection()) { dataUpdates.AddRange(connection.Query(SQL_GET_LAST_DATA_UPDATES)); } return dataUpdates; } private const string SQL_GET_TABLE_COLUMNS = @" SELECT c.name AS Name, CASE t2.name WHEN 'varchar' THEN 'VARCHAR(' + CAST(c.max_length AS VARCHAR(10)) + ')' WHEN 'decimal' THEN 'DECIMAL(' + CAST(c.precision AS VARCHAR(4)) + ',' + CAST(c.scale AS VARCHAR(4)) + ')' ELSE UPPER(t2.name) END AS Definition FROM sys.columns c INNER JOIN sys.types AS t2 ON (c.system_type_id = t2.system_type_id) INNER JOIN sys.tables t ON (c.object_id = t.object_id) WHERE t.name = @name ORDER BY c.column_id"; private const string SQL_GET_TABLE_PRIMARY_KEY = @" SELECT COLUMN_NAME AS Name FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)), 'IsPrimaryKey') = 1 AND TABLE_NAME = @name ORDER BY ORDINAL_POSITION"; public static TableSpec GetTableSpec(string name) { TableSpec tableSpec = new TableSpec() { Name = name }; using (SqlConnection connection = GetConnection()) { //Load columns tableSpec.Columns.AddRange(connection.Query(SQL_GET_TABLE_COLUMNS, new { name })); //Load primary key tableSpec.PrimaryKey.AddRange(connection.Query(SQL_GET_TABLE_PRIMARY_KEY, new { name }).Select(cn => tableSpec.GetColumn(cn))); } return tableSpec; } } }