using System; using System.Collections.Generic; using System.Data; using System.Globalization; namespace ZeroLevel.SqlServer { public sealed class SqlDbInfo { #region Ctor public SqlDbInfo(SqlDbProvider provider) { _provider = provider; } #endregion private static string FixTableName(string tableName) { return tableName.Trim().ToLower(); } public void CollectDatabaseInfo(bool tables, bool views, bool storedProcedures) { if (tables) CollectTableInformation(); } public SqlDbTableInfo this[string tableName] { get { tableName = FixTableName(tableName); if (_tables.ContainsKey(tableName)) { return _tables[tableName]; } throw new KeyNotFoundException("Таблица " + tableName + " отсутствует в базе " + _provider.Server + "\\" + _provider.Base); } } #region Private Fields private readonly SqlDbProvider _provider; private readonly Dictionary _tables = new Dictionary(); private readonly List _foreignKeys = new List(); private readonly List _primaryKeys = new List(); private readonly List _storedProcedures = new List(); private readonly List _views = new List(); #endregion #region Public database info public IEnumerable Tables { get { return _tables.Keys; } } public IEnumerable TablesInfo { get { return _tables.Values; } } public IEnumerable PrimaryKeys { get { return _primaryKeys; } } public IEnumerable ForeignKeys { get { return _foreignKeys; } } public IEnumerable StoredProcedures { get { return _storedProcedures; } } public IEnumerable Views { get { return _views; } } #endregion #region Public methods public bool ContainTable(string tableName) { tableName = FixTableName(tableName); return _tables.ContainsKey(tableName); } public bool ContainPrimaryKey(SqlDbPrimaryKeyInfo pk) { return _primaryKeys.Contains(pk); } public bool ContainForeignKey(SqlDbForeignKeyInfo fk) { return _foreignKeys.Contains(fk); } public SqlDbTableInfo TableInfo(string tableName) { tableName = FixTableName(tableName); if (ContainTable(tableName)) { return _tables[tableName]; } return null; } #endregion #region Helpers /// /// Сбор информации о таблицах, перчиных и внешних ключах /// private void CollectTableInformation() { // Таблицы foreach (string table in GetTables()) { SqlDbTableInfo info = GetTableInfo(table); if (info != null) { string tableName = FixTableName(info.Name); _tables.Add(tableName, info); if (info.PrimaryKey != null) { _primaryKeys.Add(new SqlDbPrimaryKeyInfo { PrimaryKeyTable = tableName, PrimaryKeyColumn = info.PrimaryKey.Name }); } } } // Внешние ключи DataSet fkSet = _provider.ExecuteQuerySqlDataSet(SqlDbForeignKeyInfo.ForeignKeySelectQuery); if (fkSet != null && fkSet.Tables.Count > 0) { foreach (DataRow row in fkSet.Tables[0].Rows) { _foreignKeys.Add(new SqlDbForeignKeyInfo { ForeignKeyName = Convert.ToString(row["Constraint_Name"], CultureInfo.CurrentCulture), ForeignKeyTable = FixTableName(Convert.ToString(row["K_Table"], CultureInfo.CurrentCulture)), ForeignKeyColumn = Convert.ToString(row["FK_Column"], CultureInfo.CurrentCulture), PrimaryKeyTable = FixTableName(Convert.ToString(row["PK_Table"], CultureInfo.CurrentCulture)), PrimaryKeyColumn = Convert.ToString(row["PK_Column"], CultureInfo.CurrentCulture) }); } } } #region Private /// /// Получение списка таблиц из базы данных /// private List GetTables() { var tables = new List(); using (DataSet ds = _provider.ExecuteQuerySqlDataSet("exec sp_tables")) { if (ds != null && ds.Tables.Count > 0) { foreach (DataRow row in ds.Tables[0].Rows) { if (String.Equals(row.ItemArray[3].ToString(), "TABLE", StringComparison.OrdinalIgnoreCase) && (false == String.Equals(row.ItemArray[1].ToString(), "sys", StringComparison.OrdinalIgnoreCase))) tables.Add(FixTableName(row.ItemArray[2].ToString())); } } } return tables; } /// /// Получение информации о таблице по ее имени /// public SqlDbTableInfo GetTableInfo(string table) { if (String.IsNullOrEmpty(table)) { throw new ArgumentNullException("table"); } var info = new SqlDbTableInfo(FixTableName(table)); info.FillTableInfo(_provider); return info; } #endregion #endregion } }