using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; namespace Sdaleo.Systems.SQLServer { #region SQLServer Table Enums /// /// User Permissions on a Table /// public enum SQLServerTablePermission { SELECT, UPDATE, INSERT, DELETE, REFERENCES, // EXECUTE // <-- not a table permission } #endregion /// /// Specific actions for SQL Server Tables in a Database /// public class SQLServerTable { #region Internal Table Helper Functions /// /// We must strip out the '_' on the SQLTablePermission Enum to use it in an SQL Query /// internal static string SQLTablePermission_ToString(SQLServerTablePermission TablePermission) { return TablePermission.ToString().Replace('_', ' '); } /// /// Quick Helper function to get an SQLTablePermission[] that has all Permissions defined /// internal static SQLServerTablePermission[] SQLServerTablePermission_ToArray() { return (SQLServerTablePermission[])Enum.GetValues(typeof(SQLServerTablePermission)); } /// /// Returns a generated SQL Table Permissions string for the specified Table,Username with the specified permissions /// /// Name of a Table(required) /// Name of an existing User that exists in that Database where the Table Resides (required) /// Permission Action to take /// array of permissions /// a table permission string or empty string if error occured internal static string BuildSQLServerTablePermissionsStr(String TableName, string Username, SQLServerPermissionAction Action, SQLServerTablePermission[] tablePermissions) { if (String.IsNullOrEmpty(TableName) || String.IsNullOrEmpty(Username) || (tablePermissions == null)) return string.Empty; // First the Action string sql = Action.ToString() + " "; // add each permission individually for (int i = 0; i < tablePermissions.Length; ++i) { sql += SQLTablePermission_ToString(tablePermissions[i]); bool bIsLast = (i == (tablePermissions.Length - 1)); if (!bIsLast) sql += ","; } // Add Table sql += String.Format(" ON [{1}]", TableName); // add action adjective if (Action == SQLServerPermissionAction.REVOKE) sql += " FROM "; else sql += " TO "; // add user sql += string.Format("[{0}]", Username); return sql; } #endregion #region Table Permission /// /// Automatically grant,deny,revoke all permissions on the specified table for the specified user /// /// SQL Server Credentials with Database Info /// Specify the Username for the database (required) /// Specify the TableName to set permissions on (required) /// GRANT,DENY, or REVOKE 'Permission_All' Permission on that db /// DBError Object with ErrorOccured, if error Occured public static DBError TableUserPermissionsAll(IConnectDb credential, string Username, string TableName, SQLServerPermissionAction action) { DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER); if (dbError.ErrorOccured) return dbError; if (!credential.DBMS.IsDatabaseSetAndNonSystem) return DBError.Create("Invalid Database Passed In via Credential"); if (!ValidationConsts.Generic.IsValidUserName(Username)) return DBError.Create("Invalid Username Passed In"); dbError = Validation.IsValidTableName(TableName); if (dbError.ErrorOccured) return dbError; // Get All Permissions SQLServerTablePermission[] permissions = SQLServerTablePermission_ToArray(); // Perform the Action return TableUserPermissions(credential, Username, TableName, permissions, action); } /// /// Allows you to specify permissions to grant,deny,revoke on the specified table for the specified user /// /// SQL Server Credentials with Database Info /// Specify the Username for the database (required) /// Specify the TableName to set permissions on (required) /// an array of permissions to take action on on db /// GRANT,DENY, or REVOKE specified Permissions on that db /// DBError Object with ErrorOccured, if error Occured public static DBError TableUserPermissions(IConnectDb credential, string Username, string TableName, SQLServerTablePermission[] permissions, SQLServerPermissionAction action) { DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER); if (dbError.ErrorOccured) return dbError; if (!credential.DBMS.IsDatabaseSetAndNonSystem) return DBError.Create("Invalid Database Passed In via Credential"); if (!ValidationConsts.Generic.IsValidUserName(Username)) return DBError.Create("Invalid Username Passed In"); dbError = Validation.IsValidTableName(TableName); if (dbError.ErrorOccured) return dbError; // Build the SQL and Execute the Query string sql = BuildSQLServerTablePermissionsStr(TableName, Username, action, permissions); DB db = DB.Create(credential); DBRetVal retVal = db.ExecuteNonQuery(sql); return retVal; } #endregion #region Table Index /// /// Reindexes all Indexes on the Specified Table. /// /// SQL Server Credentials with Database Info /// Specify the TableName to set permissions on (required) /// DBError Object with ErrorOccured, if error Occured public static DBError TableReindex(IConnectDb credential, string TableName) { DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER); if (dbError.ErrorOccured) return dbError; if (!credential.DBMS.IsDatabaseSetAndNonSystem) return DBError.Create("Invalid Database Passed In via Credential"); dbError = Validation.IsValidTableName(TableName); if (dbError.ErrorOccured) return dbError; // Execute the Query string sql = String.Format("DBCC DBREINDEX(\"{0}\", \" \", 90);", TableName); DB db = DB.Create(credential); DBRetVal retVal = db.ExecuteNonQuery(sql); return retVal; } /// /// Runs DBCC INDEXDEFRAG on the Specified Database, Table and Index /// /// SQL Server Credentials with Database Info /// Name of Table (required) /// Name of Index (required) /// DBError Object with ErrorOccured, if error Occured public static DBError TableIndexDefrag(IConnectDb credential, string TableName, string IndexName) { DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER); if (dbError.ErrorOccured) return dbError; if (!credential.DBMS.IsDatabaseSetAndNonSystem) return DBError.Create("Invalid Database Passed In via Credential"); dbError = Validation.IsValidTableName(TableName); if (dbError.ErrorOccured) return dbError; if (String.IsNullOrEmpty(IndexName)) return DBError.Create("Invalid IndexName Passed In"); // Execute the Query string sql = String.Format("DBCC INDEXDEFRAG ([{0}], [{1}], [{2}]) WITH NO_INFOMSGS", credential.DBMS.Database, TableName, IndexName); DB db = DB.Create(credential); DBRetVal retVal = db.ExecuteNonQuery(sql); return retVal; } #endregion #region Common Table Functions /// /// Returns all the Table Names for the specified Database /// /// SQL Server Credentials with Database Info /// array of table names, or null if error occured /// DBError Object with ErrorOccured, if error Occured public static DBError Tables(IConnectDb credential, out string[] Tables) { Tables = null; DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER); if (dbError.ErrorOccured) return dbError; if (!credential.DBMS.IsDatabaseSetAndNonSystem) return DBError.Create("Invalid Database Passed In via Credential"); // Execute the Query string sql = "SELECT [name] FROM sys.Tables ORDER BY [name]"; DB db = DB.Create(credential); DBRetVal retVal = db.FillDataTable(sql); if (retVal.IsValid) { List retList = new List(); foreach (DataRow row in retVal.GetDataTableRetVal().Rows) retList.Add(row["name"].ToString()); Tables = retList.ToArray(); } return retVal; } /// /// Check to see if the Table Exists on the specified Database /// /// SQL Server Credentials with Database Info /// Specify the TableName to check for (required) /// true if exists, false otherwise /// DBError Object with ErrorOccured, if error Occured public static DBError TableExists(IConnectDb credential, string TableName, out bool bExists) { bExists = false; DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER); if (dbError.ErrorOccured) return dbError; if (!credential.DBMS.IsDatabaseSetAndNonSystem) return DBError.Create("Invalid Database Passed In via Credential"); dbError = Validation.IsValidTableName(TableName); if (dbError.ErrorOccured) return dbError; // Execute the Query string sql = String.Format("SELECT [name] FROM sys.Tables WHERE [name]='{0}' ORDER BY [name]", TableName); DB db = DB.Create(credential); DBRetVal retVal = db.ExecuteScalar(sql); bExists = !retVal.IsValid; return retVal; } /// /// Changes the Table Name for the specified Table /// /// SQL Server Credentials with Database Info /// Name of Table (required) /// Name of Table New (required) /// DBError Object with ErrorOccured, if error Occured public static DBError TableRename(IConnectDb credential, string TableName, string TableNameNew) { DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER); if (dbError.ErrorOccured) return dbError; if (!credential.DBMS.IsDatabaseSetAndNonSystem) return DBError.Create("Invalid Database Passed In via Credential"); dbError = Validation.IsValidTableName(TableName); if (dbError.ErrorOccured) return dbError; dbError = Validation.IsValidTableName(TableNameNew); if (dbError.ErrorOccured) return dbError; // Update the Index Names using SMO * UNTESTED * //Server server = DataType.ConvertCredentialToSMOServer(credential); //foreach (Index index in server.Databases[credential.Database].Tables[TableName].Indexes) // index.Name = index.Name.Replace(TableName, TableNameNew); //server.Databases[credential.Database].Tables[TableName].Alter(); // Execute the Query string sql = String.Format("EXEC sp_rename @objname = [{0}], @newname = [{1}], @objtype = 'OBJECT'", TableName, TableNameNew); DB db = DB.Create(credential); DBRetVal retVal = db.ExecuteNonQuery(sql); return retVal; } #endregion } }