Initial Commit
This commit is contained in:
279
Systems/SQLServer/Credential.cs
Normal file
279
Systems/SQLServer/Credential.cs
Normal file
@@ -0,0 +1,279 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Sdaleo.Systems.SQLServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles SQL Server Credentials, to be
|
||||
/// used by all our SQL Server Functions
|
||||
/// </summary>
|
||||
public class SQLServerCredential : IComparable, ICloneable, IConnectDb, IamDBMS, IsupportTimeouts
|
||||
{
|
||||
#region IConnectDb
|
||||
|
||||
/// <summary>
|
||||
/// Let Callers know this is a SQL Server Connection Object
|
||||
/// </summary>
|
||||
public DBSystem DBType { get { return DBSystem.SQL_SERVER; } }
|
||||
|
||||
/// <summary>
|
||||
/// Check to see if the Credential Object consists of valid input
|
||||
/// </summary>
|
||||
public bool IsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Validation.IsValidDataSource(_UDL.DataSource))
|
||||
return false;
|
||||
|
||||
if (!_UDL.TrustedConnection && !ValidationConsts.Generic.IsValidUserCredential(_UDL.Username, _UDL.Password))
|
||||
return false;
|
||||
|
||||
if (!String.IsNullOrEmpty(_UDL.DataBase) && IsDatabaseSet)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string ConnectionString { get { return _UDL.ConnectionString; } }
|
||||
|
||||
/// <summary>
|
||||
/// SQL Server uses Server N' Instance
|
||||
/// </summary>
|
||||
public string DataSource { get { return _UDL.DataSource; } }
|
||||
|
||||
/// <summary>
|
||||
/// SQL Server requires a user
|
||||
/// </summary>
|
||||
public string User { get { return _UDL.Username; } }
|
||||
|
||||
/// <summary>
|
||||
/// SQL Server supports is a DBMS
|
||||
/// </summary>
|
||||
public bool SupportsDBMS { get { return true; } }
|
||||
|
||||
/// <summary>
|
||||
/// SQL Server is a DBMS
|
||||
/// </summary>
|
||||
public IamDBMS DBMS { get { return this; } }
|
||||
|
||||
/// <summary>
|
||||
/// SQL Server supports Timeouts
|
||||
/// </summary>
|
||||
public bool SupportsTimeouts { get { return true; } }
|
||||
|
||||
/// <summary>
|
||||
/// SQL Server supports Timeouts
|
||||
/// </summary>
|
||||
public IsupportTimeouts Timeouts { get { return this; } }
|
||||
|
||||
#endregion
|
||||
|
||||
private UDL _UDL = null;
|
||||
|
||||
#region SQL Server Credential Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Create a SQL Server Connection from an UDL Object
|
||||
/// </summary>
|
||||
/// <param name="udl"></param>
|
||||
internal SQLServerCredential(UDL udl)
|
||||
{
|
||||
if (udl != null)
|
||||
_UDL = udl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an Untrusted SQLServer Credential with an Initial DB Specified
|
||||
/// </summary>
|
||||
public SQLServerCredential(string strServer, string strInstance, string strDatabase, string strUser, string strPassword)
|
||||
{
|
||||
_UDL = new UDL(strDatabase, strUser, strPassword, strServer, strInstance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an Untrusted SQLServer Credential with no Initial DB Specified
|
||||
/// </summary>
|
||||
public SQLServerCredential(string strServer, string strInstance, string strUser, string strPassword)
|
||||
{
|
||||
_UDL = new UDL(String.Empty, strUser, strPassword, strServer, strInstance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a Trusted SQLServer Credential with an Initial DB Specified
|
||||
/// </summary>
|
||||
public SQLServerCredential(string strServer, string strInstance, string strDatabase)
|
||||
{
|
||||
_UDL = new UDL(strDatabase, String.Empty, String.Empty, strServer, strInstance, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a Trusted SQLServer Credential with no Initial DB Specified
|
||||
/// </summary>
|
||||
public SQLServerCredential(string strServer, string strInstance)
|
||||
{
|
||||
_UDL = new UDL(String.Empty, String.Empty, String.Empty, strServer, strInstance, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a Trusted SQLServer Credential with SQLExpress on the Local Machine to Attach a DB File (Creates a User Instance)
|
||||
/// </summary>
|
||||
/// <param name="strAttachDBFile"></param>
|
||||
public SQLServerCredential(string strAttachSQLDBFile)
|
||||
{
|
||||
_UDL = new UDL(String.Empty, String.Empty, String.Empty, String.Empty, "SQLEXPRESS", strAttachSQLDBFile, true, false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IamDBMS
|
||||
|
||||
public string Server { get { return _UDL.ServerAddress; } }
|
||||
public string Instance { get { return _UDL.InstanceName; } }
|
||||
public string Database { get { return _UDL.DataBase; } }
|
||||
|
||||
public bool IsDatabaseSet
|
||||
{
|
||||
get
|
||||
{
|
||||
DBError dbError = Validation.IsValidDatabaseName(Database);
|
||||
return !dbError.ErrorOccured;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDatabaseSetAndNonSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsDatabaseSet && !SQLServerUtilities.IsSystemDatabaseName(Database))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDatabaseSetAndNonDefault
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsDatabaseSet && !SQLServerUtilities.IsDefaultDatabaseName(Database))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to quickly create a new SQLServerCredential with a different DatabaseName
|
||||
/// </summary>
|
||||
/// <param name="strDatabaseName">Name of Database To Set</param>
|
||||
/// <returns>a new SQLServerCredential Object</returns>
|
||||
public IConnectDb WithDatabase(string strDatabaseName)
|
||||
{
|
||||
// Create a new Credential Object and change the DatabaseName
|
||||
SQLServerCredential credential = (SQLServerCredential)Clone();
|
||||
credential._UDL.DataBase = strDatabaseName;
|
||||
return credential;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to quickly create a new SQLServerCredential with no DatabaseName defined
|
||||
/// </summary>
|
||||
/// <returns>a new SQLServerCredential Object</returns>
|
||||
public IConnectDb WithoutDatabase()
|
||||
{
|
||||
return WithDatabase(String.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IsupportTimeouts
|
||||
|
||||
public const int DEFAULT_COMMAND_TIMEOUT = 45;
|
||||
private uint _CommandTimeout = DEFAULT_COMMAND_TIMEOUT;
|
||||
public uint CommandTimeout
|
||||
{
|
||||
get { return _CommandTimeout; }
|
||||
set { _CommandTimeout = value; }
|
||||
}
|
||||
|
||||
public uint ConnectionTimeout { get { return _UDL.ConnectionTimeout; } set { _UDL.ConnectionTimeout = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Use this to quickly create a new SQLServerCredential with a different connection timeout
|
||||
/// </summary>
|
||||
/// <param name="nConnectionTimeout">Specify the Connection Timeout</param>
|
||||
/// <returns>a new SQLServerCredential Object</returns>
|
||||
public IConnectDb WithConnectionTimeout(uint nConnectionTimeout)
|
||||
{
|
||||
// Create a new Credential Object and change the Timeouts
|
||||
SQLServerCredential credential = (SQLServerCredential)Clone();
|
||||
credential.ConnectionTimeout = nConnectionTimeout;
|
||||
return credential;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to quickly create a new SQLServerCredential with a different command timeout
|
||||
/// </summary>
|
||||
/// <param name="nCommandTimeout">Specify the Command Timeout</param>
|
||||
/// <returns>a new SQLServerCredential Object</returns>
|
||||
public IConnectDb WithCommandTimeout(uint nCommandTimeout)
|
||||
{
|
||||
// Create a new Credential Object and change the Timeouts
|
||||
SQLServerCredential credential = (SQLServerCredential)Clone();
|
||||
credential.CommandTimeout = nCommandTimeout;
|
||||
return credential;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to quickly create a new SQLServerCredential with different Timeouts
|
||||
/// </summary>
|
||||
/// <param name="nConnectionTimeout">Specify the Connection Timeout</param>
|
||||
/// <param name="nCommandTimeout">Specify the Command Timeout</param>
|
||||
/// <returns>a new SQLServerCredential Object</returns>
|
||||
public IConnectDb WithTimeouts(uint nConnectionTimeout, uint nCommandTimeout)
|
||||
{
|
||||
// Create a new Credential Object and change the Timeouts
|
||||
SQLServerCredential credential = (SQLServerCredential)Clone();
|
||||
credential.ConnectionTimeout = nConnectionTimeout;
|
||||
credential.CommandTimeout = nCommandTimeout;
|
||||
return credential;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
SQLServerCredential credential = new SQLServerCredential((UDL)this._UDL.Clone());
|
||||
credential.CommandTimeout = this.CommandTimeout;
|
||||
return credential;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IComparable Members
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
SQLServerCredential otherCredential = obj as SQLServerCredential;
|
||||
if (otherCredential != null)
|
||||
{
|
||||
int nCompare = _UDL.CompareTo(otherCredential._UDL);
|
||||
return nCompare;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Object is not a SQLServerCredential");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
572
Systems/SQLServer/Database.cs
Normal file
572
Systems/SQLServer/Database.cs
Normal file
@@ -0,0 +1,572 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
|
||||
namespace Sdaleo.Systems.SQLServer
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Specific actions for SQL Server Databases
|
||||
/// </summary>
|
||||
public class SQLServerDatabase
|
||||
{
|
||||
#region Database List
|
||||
|
||||
/// <summary>
|
||||
/// Returns a array of any found Databases on the specified SQL Server intance
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="DatabaseList">list of Databases if any found, or null if not</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabasesListAll(IConnectDb credential, out string[] DatabaseList)
|
||||
{
|
||||
DatabaseList = null;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute the Query
|
||||
string sql = "SELECT [name] FROM sys.databases";
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
List<string> DataBaseNames = new List<String>();
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
DataBaseNames.Add(row["name"].ToString());
|
||||
DatabaseList = DataBaseNames.ToArray();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a array of any found Databases that are NOT SQL Default Databases (like master, model, etc);
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="DatabaseList">list of Databases if any found, or null if not</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabasesListNonDefault(IConnectDb credential, out string[] DatabaseList)
|
||||
{
|
||||
DatabaseList = null;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Look for all Databases that are Non-Default
|
||||
string[] DatabaseListAll = null;
|
||||
DBError retVal = DatabasesListAll(credential, out DatabaseListAll);
|
||||
if(!retVal.ErrorOccured && DatabaseListAll != null)
|
||||
{
|
||||
List<String> DatabaseListNonDefault = new List<String>();
|
||||
foreach (string DatabaseName in DatabaseListAll)
|
||||
{
|
||||
if(!SQLServerUtilities.IsDefaultDatabaseName(DatabaseName))
|
||||
DatabaseListNonDefault.Add(DatabaseName);
|
||||
}
|
||||
DatabaseList = DatabaseListNonDefault.ToArray();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Alter Database
|
||||
|
||||
/// <summary>
|
||||
/// Use this to Raise the specified Database to it's highest Compatibility Level as allowed
|
||||
/// on the specified SQLServer (2005/2008/etc.)
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseRaiseCompatibility(IConnectDb credential)
|
||||
{
|
||||
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");
|
||||
|
||||
// How to change compatibility level has changed in sql server 2008 (so we'll try to
|
||||
// use the newer way of doing it if we can.
|
||||
string sql = string.Empty;
|
||||
SQLServerVersion ServerVersion;
|
||||
DBError dberror = SQLServerGeneral.GetSQLServerVersion(credential, out ServerVersion);
|
||||
if (dberror.ErrorOccured)
|
||||
return dberror;
|
||||
|
||||
switch (ServerVersion)
|
||||
{
|
||||
case SQLServerVersion.SQL_SERVER_2008:
|
||||
sql = String.Format("ALTER DATABASE [{0}] SET COMPATIBILITY_LEVEL = {1}", credential.DBMS.Database, (int)ServerVersion);
|
||||
break;
|
||||
|
||||
default:
|
||||
sql = String.Format("EXEC sp_dbcmptlevel [{0}], {1}", credential.DBMS.Database, (int)ServerVersion);
|
||||
break;
|
||||
}
|
||||
|
||||
// Execute the Query and return result
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the caller to set the Database into Single User Mode. This is * microsoft recommended *
|
||||
/// for certain type of operations on the Database to make sure nobody else can use the DB.
|
||||
/// Note: If Database is in Use * This will timeout
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseSetToSingleUserMode(IConnectDb credential)
|
||||
{
|
||||
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 and return result
|
||||
string sql = String.Format("ALTER DATABASE [{0}] SET SINGLE_USER", credential.DBMS.Database);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the caller to set the Database into Multi User Mode. This should be called
|
||||
/// if the caller called DatabaseSetToSingleUserMode() previously
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseSetToMultiUserMode(IConnectDb credential)
|
||||
{
|
||||
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 and return result
|
||||
string sql = String.Format("ALTER DATABASE [{0}] SET MULTI_USER", credential.DBMS.Database);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls DBCC SHRINKDATABASE and DBCC UPDATEUSAGE on the passed in Database
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseShrink(IConnectDb credential)
|
||||
{
|
||||
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 and return result
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
string sql = String.Format("DBCC SHRINKDATABASE ([{0}])", credential.DBMS.Database);
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
if (!retVal.ErrorOccured)
|
||||
{
|
||||
sql = String.Format("DBCC UPDATEUSAGE ([{0}])", credential.DBMS.Database);
|
||||
retVal = db.ExecuteNonQuery(sql);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Iterates all tables on the database and enables/disables all trigers for each table
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="bEnable">true to enable, false to disable</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError EnableDisableAllTriggers(IConnectDb credential, bool bEnable)
|
||||
{
|
||||
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");
|
||||
|
||||
// Get All Table Names from the Database
|
||||
string[] TableNames = null;
|
||||
DBError dberror = SQLServerTable.Tables(credential, out TableNames);
|
||||
if (dberror.ErrorOccured)
|
||||
return dberror;
|
||||
|
||||
// Execute the Query and return result
|
||||
DB db = DB.Create(credential);
|
||||
DBRetVal retVal = new DBRetVal();
|
||||
foreach (string TableName in TableNames)
|
||||
{
|
||||
// Execute the Query for each Table
|
||||
string sql = String.Format("ALTER TABLE [{0}] {1} TRIGGER ALL", TableName, (bEnable ? "ENABLE" : "DISABLE"));
|
||||
retVal = db.ExecuteNonQuery(sql);
|
||||
if (retVal.ErrorOccured)
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Databae Create / Exists
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if we can query the specified server for the Database (Existence check)
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="bExists">Returns true if the Database Exists, false otherwise</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseExists(IConnectDb credential, 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");
|
||||
|
||||
// Execute the Query and return result
|
||||
string sql = String.Format("EXEC sp_helpdb @dbname = [{0}]", credential.DBMS.Database);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
bExists = !retVal.ErrorOccured;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new Database with the specified DatabaseName in the specified DataPath, if specified, or DefaultPath otherwise
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="DataPath">Data Path to Create Database in (not required)</param>
|
||||
/// <param name="TryAttachDBOnError">true to allow Attach Database when error occurs, false otherwise</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseCreate(IConnectDb credential, string DataPath, bool TryAttachDBOnError)
|
||||
{
|
||||
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 DataPath is empty, get default datapath for SQL ServerInstance
|
||||
if (String.IsNullOrEmpty(DataPath))
|
||||
SQLServerGeneral.SQLServerDefaultPath(credential.DBMS.WithoutDatabase(), out DataPath);
|
||||
|
||||
// Fill in Database FileName and Path Details
|
||||
string sql = String.Format("CREATE DATABASE [{0}] ", credential.DBMS.Database);
|
||||
if (!String.IsNullOrEmpty(DataPath))
|
||||
sql += String.Format(@"ON (NAME = [{0}_dat], FILENAME = '{1}\{0}.dat') LOG ON (NAME = [{0}_log], FILENAME = '{1}\{0}_log.ldf')", credential.DBMS.Database, DataPath);
|
||||
|
||||
// Execute the Command
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
|
||||
// Upon DB Creation error, see if we could possibly attach the DB
|
||||
bool bErrorOccuredThatCouldMaybeBeResolvedByAttaching = false;
|
||||
if (retVal.ErrorOccured && !retVal.GetAllErrorNumbers.Contains(ErrorConst.ERROR_DB_ALREADY_EXISTS) && (
|
||||
retVal.GetAllErrorNumbers.Contains(ErrorConst.ERROR_DB_SOME_FILE_NAMES_COULD_NOT_BE_CREATED) ||
|
||||
retVal.GetAllErrorNumbers.Contains(ErrorConst.ERROR_DB_CAN_NOT_CREATE_FILE_BECAUSE_IT_ALREADY_EXISTS) ||
|
||||
retVal.GetAllErrorNumbers.Contains(ErrorConst.ERROR_DB_THERE_ALREADY_IS_AN_OBJECT_IN_THE_DB_WITH_THIS_NAME)))
|
||||
{
|
||||
bErrorOccuredThatCouldMaybeBeResolvedByAttaching = true;
|
||||
}
|
||||
|
||||
// Upon Error, and if we are allowed to attach && datapath is valid, try to attach
|
||||
if (retVal.ErrorOccured && TryAttachDBOnError && bErrorOccuredThatCouldMaybeBeResolvedByAttaching && !String.IsNullOrEmpty(DataPath))
|
||||
{
|
||||
String[] strFileNames = new String[]
|
||||
{
|
||||
string.Format(@"{1}\{0}.dat", credential.DBMS.Database, DataPath),
|
||||
string.Format(@"{1}\{0}_log.ldf", credential.DBMS.Database, DataPath)
|
||||
};
|
||||
DBError retValError = DatabaseAttach(credential, strFileNames);
|
||||
return retValError;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Database Attach / Dettach
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a Database to an SQL Server Instance
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="strFileNames">Pass in the filenames when attaching Database (required)</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseAttach(IConnectDb credential, string[] strFileNames)
|
||||
{
|
||||
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 ((strFileNames == null || strFileNames.Length == 0))
|
||||
return DBError.Create("Invalid FileNames Passed In");
|
||||
|
||||
// Generate the SQL Query
|
||||
string sql = String.Format("EXEC sp_attach_db @dbname = [{0}]", credential.DBMS.Database);
|
||||
for (int i = 0; i < strFileNames.Length; ++i)
|
||||
sql = sql + String.Format(", @filename{0:d1} = '{1}'", (i + 1), strFileNames[i]);
|
||||
|
||||
// Execute the Query
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
|
||||
// If Error Occured try renaming dat files to mdf * legacy code *
|
||||
bool bRetryAttachingErrorOccured = false;
|
||||
if (retVal.ErrorOccured &&
|
||||
(retVal.GetAllErrorNumbers.Contains(ErrorConst.ERROR_DB_THERE_ALREADY_IS_AN_OBJECT_IN_THE_DB_WITH_THIS_NAME) ||
|
||||
retVal.GetAllErrorNumbers.Contains(ErrorConst.ERROR_DB_DEVICE_ACTIVATION_FAILED)))
|
||||
{
|
||||
bRetryAttachingErrorOccured = true;
|
||||
}
|
||||
|
||||
// Retry on Attach if failure occured &
|
||||
// filenames contain .dat files & we have an attach specific error * LEGACY CODE Usuage *
|
||||
if (retVal.ErrorOccured && bRetryAttachingErrorOccured)
|
||||
{
|
||||
bool bRetry = false;
|
||||
List<string> retryArr = new List<string>();
|
||||
foreach (string strFileName in strFileNames)
|
||||
{
|
||||
if (strFileName.Contains(".dat"))
|
||||
{
|
||||
strFileName.Replace(".dat", ".mdf");
|
||||
bRetry = true;
|
||||
}
|
||||
retryArr.Add(strFileName);
|
||||
}
|
||||
|
||||
// Only do an actually retry if .dat files were replaced
|
||||
if (bRetry)
|
||||
return DatabaseAttach(credential, retryArr.ToArray());
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dettaches a Database from an SQL Server Instance
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseDettach(IConnectDb credential)
|
||||
{
|
||||
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 and return result
|
||||
string sql = String.Format("sp_detach_db @dbname = [{0}]", credential.DBMS.Database);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Database Copy
|
||||
|
||||
/// <summary>
|
||||
/// Copies a specified Database on the specified SQLServer into a new specified Database
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="DatabaseNameDest">Name of Database To be copied To (required)</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseCopy(IConnectDb credential, string DatabaseNameDest)
|
||||
{
|
||||
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.IsValidDatabaseName(DatabaseNameDest);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
|
||||
string strDefaultPath;
|
||||
DBError dberror = SQLServerGeneral.SQLServerDefaultPath(credential, out strDefaultPath);
|
||||
if (dberror.ErrorOccured)
|
||||
return dberror;
|
||||
|
||||
// First Step - Backup the source database to a custom Backup file
|
||||
string sql = String.Format(@"BACKUP DATABASE [{0}] TO DISK = '{1}\{0}.DB Backup' WITH INIT, NAME = '{0} Backup', PASSWORD = 'dbCopy Backup', MEDIAPASSWORD = 'XaseY 1-33', INIT , FORMAT", credential.DBMS.Database, strDefaultPath);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
if (retVal.ErrorOccured)
|
||||
return retVal;
|
||||
|
||||
// Second Step - Retrieve the dat & log Logical Names for the newly backed-up Database
|
||||
string strDataLogical = string.Empty;
|
||||
string strLogLogical = string.Empty;
|
||||
sql = String.Format(@"RESTORE FILELISTONLY FROM DISK = '{0}\{1}.DB Backup' WITH FILE = 1, PASSWORD = 'dbCopy Backup', MEDIAPASSWORD = 'XaseY 1-33'", strDefaultPath, credential.DBMS.Database);
|
||||
retVal = db.FillDataTable(sql);
|
||||
if (!retVal.IsValid)
|
||||
return retVal;
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
{
|
||||
switch (row["Type"].ToString())
|
||||
{
|
||||
case "D":
|
||||
strDataLogical = row["LogicalName"].ToString();
|
||||
break;
|
||||
|
||||
case "L":
|
||||
strLogLogical = row["LogicalName"].ToString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (String.IsNullOrEmpty(strDataLogical) || String.IsNullOrEmpty(strLogLogical))
|
||||
return DBError.Create("DataLogical or LogLogical could not be found");
|
||||
|
||||
// Third Step - Restore Backup file to the new Database name
|
||||
sql = String.Format(@"RESTORE DATABASE [{0}] FROM DISK = '{1}\{2}.DB Backup' WITH FILE = 1, PASSWORD = 'dbCopy Backup', MEDIAPASSWORD = 'XaseY 1-33', MOVE '{3}' TO '{1}\{0}.dat', MOVE '{4}' TO '{1}\{0}_log.ldf', RECOVERY, REPLACE", DatabaseNameDest, strDefaultPath, credential.DBMS.Database, strDataLogical, strLogLogical);
|
||||
retVal = db.ExecuteNonQuery(sql);
|
||||
if (retVal.ErrorOccured)
|
||||
{
|
||||
// try again
|
||||
retVal = db.ExecuteNonQuery(sql);
|
||||
if (!retVal.IsValid)
|
||||
return retVal;
|
||||
}
|
||||
|
||||
// Fourth Step - Try to Delete the Backup file (No Need to have a potentially massive data file just sitting there
|
||||
// ~SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the
|
||||
// security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure.
|
||||
// For more information about enabling 'xp_cmdshell', see "Surface Area Configuration" in SQL Server Books Online
|
||||
// sql = String.Format("exec master.dbo.xp_cmdshell 'del /Q /F \"{0}\\{1}.DB Backup\"'", strDefaultPath, DatabaseNameSrc);
|
||||
// db.ExecuteNonQuery(sql);
|
||||
|
||||
// Legacy Usuage, we are leaving the Backup File behind (*leaking the file* so to speak)
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a specified Database on the specified SQLServer into a new specified Database onto a different specified Instance * Must be on Same Server *
|
||||
/// </summary>
|
||||
/// <param name="credentialSrc">SQL Server Credentials with Database Info to be copied from (required)</param>
|
||||
/// <param name="credentialDest">SQL Server Credentials with Database Info to be copied to (required)</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseCopySepInst(IConnectDb credentialSrc, IConnectDb credentialDst)
|
||||
{
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credentialSrc, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
if (!credentialSrc.DBMS.IsDatabaseSetAndNonSystem)
|
||||
return DBError.Create("Invalid Database Passed In via Credential");
|
||||
|
||||
dbError = ValidationConsts.IsCredentialValid(credentialDst, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
if (!credentialDst.DBMS.IsDatabaseSetAndNonSystem)
|
||||
return DBError.Create("Invalid Database Passed In via Credential");
|
||||
|
||||
if (String.Compare(credentialSrc.DBMS.Server, credentialDst.DBMS.Server, true) != 0)
|
||||
return DBError.Create("Must be on the Same Server");
|
||||
|
||||
if (String.Compare(credentialSrc.DBMS.Instance, credentialDst.DBMS.Instance, true) == 0)
|
||||
return DBError.Create("Can not be the same Instance");
|
||||
|
||||
// Get Src Default Path *of the DB*
|
||||
string strDefaultPathSrc;
|
||||
DBError dberror = SQLServerGeneral.SQLServerDefaultPath(credentialSrc, out strDefaultPathSrc);
|
||||
if (dberror.ErrorOccured)
|
||||
return dberror;
|
||||
|
||||
// Get Dest Default Path *of the Server*
|
||||
string strDefaultPathDest;
|
||||
dberror = SQLServerGeneral.SQLServerDefaultPath(credentialDst, out strDefaultPathDest);
|
||||
if (dberror.ErrorOccured)
|
||||
return dberror;
|
||||
|
||||
// Make sure that both Paths aren't the same *Two instances should never have the same path!*
|
||||
if (strDefaultPathSrc.ToUpper() == strDefaultPathDest.ToUpper())
|
||||
return DBError.Create(String.Format("The File Path of the Source Database {0} and the Destination Database {1} on Server {1} are identical.", credentialSrc.DBMS.Database, credentialDst.DBMS.Database, credentialDst.DBMS.Server));
|
||||
|
||||
// Create Src N' Dest Connections * No Limit on the Command timeout *
|
||||
// Could be very large database that we are trying to copy
|
||||
DB dbSrc = DB.Create(credentialSrc.DBMS.WithoutDatabase().Timeouts.WithCommandTimeout(0));
|
||||
DB dbDst = DB.Create(credentialDst.DBMS.WithoutDatabase().Timeouts.WithCommandTimeout(0));
|
||||
|
||||
// First Step - Backup the source database to a custom DB Backup file to the DESTINATION path
|
||||
string sql = String.Format(@"BACKUP DATABASE [{0}] TO DISK = '{1}\{0}.DB Backup' WITH INIT, NAME = '{0} Backup', PASSWORD = 'dbCopy Backup', MEDIAPASSWORD = 'XaseY 1-33', INIT , FORMAT", credentialSrc.DBMS.Database, strDefaultPathSrc);
|
||||
DBRetVal retVal = dbSrc.ExecuteNonQuery(sql);
|
||||
if (retVal.ErrorOccured)
|
||||
return retVal;
|
||||
|
||||
// Second Step - Retrieve the dat & log Logical Names for the newly backed-up Database File
|
||||
string strDataLogical = string.Empty;
|
||||
string strLogLogical = string.Empty;
|
||||
sql = String.Format(@"RESTORE FILELISTONLY FROM DISK = '{0}\{1}.DB Backup' WITH FILE = 1, PASSWORD = 'dbCopy Backup', MEDIAPASSWORD = 'XaseY 1-33'", strDefaultPathSrc, credentialSrc.DBMS.Database);
|
||||
retVal = dbSrc.FillDataTable(sql);
|
||||
if (!retVal.IsValid)
|
||||
return retVal;
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
{
|
||||
switch (row["Type"].ToString())
|
||||
{
|
||||
case "D":
|
||||
strDataLogical = row["LogicalName"].ToString();
|
||||
break;
|
||||
|
||||
case "L":
|
||||
strLogLogical = row["LogicalName"].ToString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (String.IsNullOrEmpty(strDataLogical) || String.IsNullOrEmpty(strLogLogical))
|
||||
return DBError.Create(String.Format("The retrieval of Logical Names for Database '{0}' failed for Server Instance '{1}' in Path '{2}'.", credentialSrc.DBMS.Database, credentialSrc.DataSource, strDefaultPathDest));
|
||||
|
||||
// Third Step - Restore Backup file to the new Database name onto the new (Dest) instance
|
||||
sql = String.Format(@"RESTORE DATABASE [{0}] FROM DISK = '{1}\{2}.DB Backup' WITH FILE = 1, PASSWORD = 'dbCopy Backup', MEDIAPASSWORD = 'XaseY 1-33', MOVE '{3}' TO '{5}\{0}.dat', MOVE '{4}' TO '{5}\{0}_log.ldf', RECOVERY, REPLACE", credentialDst.DBMS.Database, strDefaultPathSrc, credentialSrc.DBMS.Database, strDataLogical, strLogLogical, strDefaultPathDest);
|
||||
retVal = dbDst.ExecuteNonQuery(sql);
|
||||
if (!retVal.ErrorOccured)
|
||||
{
|
||||
// try again
|
||||
retVal = dbDst.ExecuteNonQuery(sql);
|
||||
if (!retVal.IsValid)
|
||||
return retVal;
|
||||
}
|
||||
|
||||
// Fourth Step - Try to Delete the Backup file (No Need to have a potentially massive data file just sitting there
|
||||
// ~SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the
|
||||
// security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure.
|
||||
// For more information about enabling 'xp_cmdshell', see "Surface Area Configuration" in SQL Server Books Online
|
||||
// sql = String.Format("exec master.dbo.xp_cmdshell 'del /Q /F \"{0}\\{1}.DB Backup\"'", strDefaultPath, DatabaseNameSrc);
|
||||
// db.RunSQLCommandTextExecuteNonQuery(sql);
|
||||
|
||||
// Legacy Usuage, we are leaving the Backup File behind (*leaking the file* so to speak)
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
482
Systems/SQLServer/General.cs
Normal file
482
Systems/SQLServer/General.cs
Normal file
@@ -0,0 +1,482 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using System.Net;
|
||||
using System.ServiceProcess;
|
||||
|
||||
namespace Sdaleo.Systems.SQLServer
|
||||
{
|
||||
#region SQLServer General Enums
|
||||
|
||||
/// <summary>
|
||||
/// SQL Server Versions as specified by SQL Server
|
||||
/// </summary>
|
||||
public enum SQLServerVersion
|
||||
{
|
||||
SQL_SERVER_2000 = 80,
|
||||
SQL_SERVER_2005 = 90,
|
||||
SQL_SERVER_2008 = 100,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// General SQL Server Functions
|
||||
/// </summary>
|
||||
public class SQLServerGeneral
|
||||
{
|
||||
#region SQL Version Functions
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the SQL Server Version Information from the specified SQL Server Instance
|
||||
/// (* Prefered Function to use *)
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="version">we pass out the SQL Server Specific Version</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError GetSQLServerVersion(IConnectDb credential, out SQLServerVersion version)
|
||||
{
|
||||
version = SQLServerVersion.SQL_SERVER_2000; // Default behavior
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
int nVersion = (int)SQLServerVersion.SQL_SERVER_2000;
|
||||
DBError dberror = GetSQLServerVersion(credential, out nVersion);
|
||||
if (dberror.ErrorOccured)
|
||||
return dberror;
|
||||
|
||||
// SQLServerVersion numbers are multiple of 10's
|
||||
nVersion = nVersion * 10;
|
||||
try
|
||||
{
|
||||
version = (SQLServerVersion)Enum.Parse(typeof(SQLServerVersion), nVersion.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
dberror = DBError.Create(e.Message);
|
||||
}
|
||||
return dberror;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the SQL Server Version String Information from the specified SQL Server Instance
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="strVersion">we pass out the SQL Server Specific Version String</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError GetSQLServerVersion(IConnectDb credential, out string strVersion)
|
||||
{
|
||||
strVersion = string.Empty;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute the Query
|
||||
string sql = "EXEC sp_server_info @attribute_id = 2";
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
strVersion = retVal.GetDataTableRetVal().Rows[0]["attribute_value"].ToString();
|
||||
strVersion.Replace("\t", ""); // remove tabs
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the SQL Server Version Integer Information from the specified SQL Server Instance
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="nVersion">we pass out the SQL Server Specific Version Int</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError GetSQLServerVersion(IConnectDb credential, out int nVersion)
|
||||
{
|
||||
nVersion = 0;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute the Query
|
||||
string sql = "SELECT CONVERT(char(20), SERVERPROPERTY('ProductVersion'))";
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteScalar(sql);
|
||||
if(retVal.IsValid)
|
||||
{
|
||||
string strVersion = retVal.GetScalarRetVal();
|
||||
String[] strVersionSplit = strVersion.Split('.');
|
||||
int.TryParse(strVersionSplit[0], out nVersion);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL File N' Disk functions
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the default path for the SQL Server Instance or for the Database on the SQL Server.
|
||||
/// Leave Database blank in the credential to find the default path for the Server.
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="DefaultPath">default path found or "" if not</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerDefaultPath(IConnectDb credential, out string DefaultPath)
|
||||
{
|
||||
DefaultPath = string.Empty;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Get the Path for the default Path for the Database if Specified
|
||||
string sql = String.Empty;
|
||||
if (credential.DBMS.IsDatabaseSetAndNonSystem)
|
||||
sql = String.Format("SELECT filename FROM [{0}]..sysfiles", credential.DBMS.Database);
|
||||
else
|
||||
sql = "SELECT filename FROM master..sysfiles where [name]='master'";
|
||||
|
||||
// Execute the Query
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteScalar(sql);
|
||||
if ((retVal.IsValid) && !String.IsNullOrEmpty(retVal.GetScalarRetVal()))
|
||||
{
|
||||
string strResult = retVal.GetScalarRetVal();
|
||||
int indx = strResult.LastIndexOf('\\');
|
||||
if (indx >= 0)
|
||||
strResult = strResult.Remove(indx);
|
||||
DefaultPath = strResult;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function retries an array of the Fixed HardDrives/Disks that are available on the Server
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="fixedDisks">an array of all the fixed disk's drive letters (i.e. C), empty list, if error occured</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerFixedDisks(IConnectDb credential, out string[] fixedDisks)
|
||||
{
|
||||
fixedDisks = null;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute the Query
|
||||
string sql = "EXEC master..xp_fixeddrives";
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
List<String> retList = new List<String>();
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
retList.Add(row["drive"].ToString());
|
||||
}
|
||||
fixedDisks = retList.ToArray();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function retries an array of directories for the specified Path on the specified SQL Server
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="Path">a valid path that exists on the server, i.e. C:\Program Files</param>
|
||||
/// <param name="Directories">an array of all directories found in the specified path, empty list if no directories found or if error occured</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerGetDirectoriesInPath(IConnectDb credential, string Path, out string[] Directories)
|
||||
{
|
||||
Directories = null;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute the Query
|
||||
string sql = String.Format("EXEC master..xp_dirtree '{0}', 1, 1", Path);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
List<String> retList = new List<String>();
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
{
|
||||
bool bIsDirectory = (row["file"].ToString() == "0");
|
||||
if (bIsDirectory)
|
||||
retList.Add(row["subdirectory"].ToString());
|
||||
}
|
||||
}
|
||||
Directories = retList.ToArray();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function retries an array of files for the specified Path on the specified SQL Server
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="Path">a valid path that exists on the server, i.e. C:\Program Files</param>
|
||||
/// <param name="Files">an array of all files found in the specified path, empty list if no files found or if error occured</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerGetFilesInPath(IConnectDb credential, string Path, out string[] Files)
|
||||
{
|
||||
Files = null;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute the Query
|
||||
string sql = String.Format("EXEC master..xp_dirtree '{0}', 1, 1", Path);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
List<String> retList = new List<String>();
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
{
|
||||
bool bIsFile = (row["file"].ToString() == "1");
|
||||
if (bIsFile)
|
||||
retList.Add(row["subdirectory"].ToString());
|
||||
}
|
||||
}
|
||||
Files = retList.ToArray();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL Connection Checkers
|
||||
|
||||
/// <summary>
|
||||
/// Quick Check function to see if the passed in credential allows us to connect to the server
|
||||
/// If Credential contains a Database, then it will verify the Database's Existence
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="nConnectionTimeout">Specify the ConnectionTimout</param>
|
||||
/// <param name="CanConnect">Returns true if successfull in connecting to the server</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerCheckConnection(IConnectDb credential, uint nConnectionTimeout, out bool CanConnect)
|
||||
{
|
||||
// the SQL Server should at least have a master db, so this list should never be empty,
|
||||
// if it is, an error must have occured, either with the credential or with the server
|
||||
CanConnect = false;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute Query
|
||||
string[] Databases = null;
|
||||
DBError dberror = SQLServerDatabase.DatabasesListAll(credential.DBMS.WithoutDatabase().Timeouts.WithConnectionTimeout(nConnectionTimeout), out Databases);
|
||||
if (dberror.ErrorOccured || (Databases == null) || (Databases.Length == 0))
|
||||
CanConnect = false;
|
||||
else
|
||||
CanConnect = true;
|
||||
|
||||
// Check Database Existence, if specified
|
||||
if (CanConnect)
|
||||
{
|
||||
dbError = Validation.IsValidDatabaseName(credential.DBMS.Database);
|
||||
if (!dberror.ErrorOccured)
|
||||
{
|
||||
// Verify that the Database exists
|
||||
bool bFound = false;
|
||||
foreach (string db in Databases)
|
||||
{
|
||||
if (db.ToUpper() == credential.DBMS.Database.ToUpper())
|
||||
{
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Let the Caller know if they can connect to the Database
|
||||
CanConnect = bFound;
|
||||
}
|
||||
}
|
||||
return dberror;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quick Check function to see if the passed in credential allows us to connect to the
|
||||
/// server, read some data, as well as check SysAdmin Rights for the passed in Credential
|
||||
/// If Credential contains a Database, then it will verify the Database's Existence
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="nConnectionTimeout">Specify the ConnectionTimout</param>
|
||||
/// <param name="IsValid">true, if passed in credential connects and is a sysadmin, false otherwise</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerCheckConnectionNCredential(IConnectDb credential, uint nConnectionTimeout, out bool IsValid)
|
||||
{
|
||||
IsValid = false;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
DBError dberror = SQLServerCheckConnection(credential, nConnectionTimeout, out IsValid);
|
||||
if (dberror.ErrorOccured || !IsValid)
|
||||
return dberror;
|
||||
|
||||
// Now also make sure that the credential is a SysAdmin
|
||||
dberror = SQLServerSecurity.LoginIsSysAdmin(credential, credential.User, out IsValid);
|
||||
return dberror;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL Browse
|
||||
|
||||
/// <summary>
|
||||
/// Returns a array of any found valid SQL Server intances * Using the SQLBrowse Functionallity *
|
||||
/// If SQLBrowse fails, will look in the Registry
|
||||
/// This Function can take a long time, depending on the Network
|
||||
/// </summary>
|
||||
/// <returns>list of valid SQLServers or null if error occured</returns>
|
||||
public static string[] SQLServerNamesAndInstaces()
|
||||
{
|
||||
// Call the SQL Browse Function
|
||||
List<String> validSQLServerInstances = new List<string>();
|
||||
string[] SQLServersRaw = SQLInfoEnumerator.EnumerateSQLServers();
|
||||
foreach (string SQLServerRaw in SQLServersRaw)
|
||||
{
|
||||
// Target name is empty - so add any valid instances found
|
||||
if (Validation.IsValidServerNameAndInstanceName(SQLServerRaw))
|
||||
validSQLServerInstances.Add(SQLServerRaw);
|
||||
}
|
||||
|
||||
// Last thing to try if EnumerateSQLServers() failed is to query the registry
|
||||
// for all possible SQL Server Installations there * and return those *
|
||||
if (validSQLServerInstances.Count == 0)
|
||||
{
|
||||
string strInstalledInstances = RegKey.GetKey<string>(HKEYRoot.LocalMachine, "Microsoft\\Microsoft SQL Server", "InstalledInstances", String.Empty);
|
||||
if (!String.IsNullOrEmpty(strInstalledInstances))
|
||||
{
|
||||
string MachineName = Dns.GetHostName();
|
||||
// Add any Registry Found Instances
|
||||
string[] Instances = strInstalledInstances.Split(' ');
|
||||
foreach (string Instance in Instances)
|
||||
validSQLServerInstances.Add(MachineName + "\\" + Instance);
|
||||
}
|
||||
}
|
||||
return validSQLServerInstances.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL Service Functions
|
||||
|
||||
/// <summary>
|
||||
/// Use this to start a SQL Service on the specified Server. You must have Windows admin/SController rights to
|
||||
/// that machine in order for this function to work
|
||||
/// </summary>
|
||||
/// <param name="ServerOrServerNInstance">Name of the SQL Server or SQL ServerNInstance you want to start (required)</param>
|
||||
/// <param name="WaitTimeoutInSeconds">Set to Value > 0 to force a wait for the specified amount of seconds(not required)</param>
|
||||
/// <returns>true if Service was started or was already running, false if an error occured</returns>
|
||||
public static bool SQLServerServiceStart(string ServerOrServerNInstance, int WaitTimeoutInSeconds)
|
||||
{
|
||||
string Server = string.Empty;
|
||||
string Instance = string.Empty;
|
||||
if (String.IsNullOrEmpty(ServerOrServerNInstance))
|
||||
return false;
|
||||
|
||||
if (!SQLServerUtilities.SplitServerOrServerNInstance(ServerOrServerNInstance, out Server, out Instance))
|
||||
return false;
|
||||
|
||||
// Construct the proper service name
|
||||
string Service = string.Empty;
|
||||
if (!String.IsNullOrEmpty(Instance))
|
||||
Service = String.Format("MSSQL${0}", Instance);
|
||||
else
|
||||
Service = "MSSQLSERVER";
|
||||
|
||||
string MachineName = Dns.GetHostName();
|
||||
bool bIsOnThisMachine = (MachineName.ToLower() == Server.ToLower());
|
||||
try
|
||||
{
|
||||
ServiceController service = null;
|
||||
if (bIsOnThisMachine)
|
||||
service = new ServiceController(Service);
|
||||
else
|
||||
service = new ServiceController(Service, Server);
|
||||
|
||||
bool bStartService = (service.Status != ServiceControllerStatus.Running);
|
||||
if (bStartService)
|
||||
{
|
||||
service.Start();
|
||||
if (WaitTimeoutInSeconds > 0)
|
||||
{
|
||||
TimeSpan timeout = TimeSpan.FromSeconds(WaitTimeoutInSeconds);
|
||||
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
|
||||
return (service.Status == ServiceControllerStatus.Running);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to stop a SQL Service on the specified Server. You must have Windows admin/SController rights to
|
||||
/// that machine in order for this function to work
|
||||
/// </summary>
|
||||
/// <param name="ServerOrServerNInstance">Name of the SQL Server or SQL ServerNInstance you want to stop (required)</param>
|
||||
/// <param name="WaitTimeoutInSeconds">Set to Value > 0 to force a wait for the specified amount of seconds(not required)</param>
|
||||
/// <returns>true if Service was stopped or was already stopped, false if an error occured</returns>
|
||||
public static bool SQLServerServiceStop(string ServerOrServerNInstance, int WaitTimeoutInSeconds)
|
||||
{
|
||||
string Server = string.Empty;
|
||||
string Instance = string.Empty;
|
||||
if (String.IsNullOrEmpty(ServerOrServerNInstance))
|
||||
return false;
|
||||
|
||||
if (!SQLServerUtilities.SplitServerOrServerNInstance(ServerOrServerNInstance, out Server, out Instance))
|
||||
return false;
|
||||
|
||||
// Construct the proper service name
|
||||
string Service = string.Empty;
|
||||
if (!String.IsNullOrEmpty(Instance))
|
||||
Service = String.Format("MSSQL${0}", Instance);
|
||||
else
|
||||
Service = "MSSQLSERVER";
|
||||
|
||||
string MachineName = Dns.GetHostName();
|
||||
bool bIsOnThisMachine = (MachineName.ToLower() == Server.ToLower());
|
||||
try
|
||||
{
|
||||
ServiceController service = null;
|
||||
if (bIsOnThisMachine)
|
||||
service = new ServiceController(Service);
|
||||
else
|
||||
service = new ServiceController(Service, Server);
|
||||
|
||||
bool bStopService = (service.Status != ServiceControllerStatus.Stopped);
|
||||
if (bStopService)
|
||||
{
|
||||
service.Stop();
|
||||
if (WaitTimeoutInSeconds > 0)
|
||||
{
|
||||
TimeSpan timeout = TimeSpan.FromSeconds(WaitTimeoutInSeconds);
|
||||
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
|
||||
return (service.Status == ServiceControllerStatus.Stopped);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to restart a SQL Service on the specified Server. You must have Windows admin/SController rights to
|
||||
/// that machine in order for this function to work
|
||||
/// </summary>
|
||||
/// <param name="ServerOrServerNInstance">Name of the SQL Server or SQL ServerNInstance you want to restart (required)</param>
|
||||
/// <param name="WaitTimeoutInSeconds">Set to Value > 0 to force a wait for the specified amount of seconds(not required)</param>
|
||||
/// <returns>true if Service was restared successfully, false if an error occured</returns>
|
||||
public static bool SQLServerServiceRestart(string ServerOrServerNInstance, int WaitTimeoutInSeconds)
|
||||
{
|
||||
return SQLServerServiceStop(ServerOrServerNInstance, WaitTimeoutInSeconds) && SQLServerServiceStart(ServerOrServerNInstance, WaitTimeoutInSeconds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
19
Systems/SQLServer/Internal/ErrorConst.cs
Normal file
19
Systems/SQLServer/Internal/ErrorConst.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Sdaleo.Systems.SQLServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Database Error Constants to Use to handle specific Error
|
||||
/// </summary>
|
||||
internal static class ErrorConst
|
||||
{
|
||||
public const int ERROR_DB_ALREADY_EXISTS = 1801;
|
||||
public const int ERROR_DB_SOME_FILE_NAMES_COULD_NOT_BE_CREATED = 1802;
|
||||
public const int ERROR_DB_CAN_NOT_CREATE_FILE_BECAUSE_IT_ALREADY_EXISTS = 5170;
|
||||
public const int ERROR_DB_THERE_ALREADY_IS_AN_OBJECT_IN_THE_DB_WITH_THIS_NAME = 3092;
|
||||
public const int ERROR_DB_DEVICE_ACTIVATION_FAILED = 5105;
|
||||
}
|
||||
}
|
||||
189
Systems/SQLServer/Internal/SQLInfoEnumerator.cs
Normal file
189
Systems/SQLServer/Internal/SQLInfoEnumerator.cs
Normal file
@@ -0,0 +1,189 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Sdaleo.Systems.SQLServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for SQLInfoEnumerator.
|
||||
/// This class Enumerates a network for SQL Server instances and returns a list.
|
||||
/// For a given SQL Server instance a list of all available databases is returned
|
||||
/// For more information see
|
||||
/// </summary>
|
||||
/// <see cref="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcsqlbrowseconnect.asp"/>
|
||||
/// <seealso cref="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp09192002.asp"/>
|
||||
internal class SQLInfoEnumerator
|
||||
{
|
||||
#region ODBC32 external function definitions
|
||||
|
||||
[DllImport("odbc32.dll")]
|
||||
private static extern short SQLAllocHandle(short handleType, IntPtr inputHandle, out IntPtr outputHandlePtr);
|
||||
|
||||
[DllImport("odbc32.dll")]
|
||||
private static extern short SQLSetEnvAttr(IntPtr environmentHandle, int attribute, IntPtr valuePtr, int stringLength);
|
||||
|
||||
[DllImport("odbc32.dll")]
|
||||
private static extern short SQLFreeHandle(short hType, IntPtr Handle);
|
||||
|
||||
[DllImport("odbc32.dll", CharSet = CharSet.Ansi)]
|
||||
private static extern short SQLBrowseConnect(IntPtr handleConnection, StringBuilder inConnection, short stringLength, StringBuilder outConnection, short bufferLength, out short stringLength2Ptr);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constants
|
||||
|
||||
private const string SQL_DRIVER_STR = "DRIVER={SQL SERVER};";
|
||||
private const short SQL_SUCCESS = 0;
|
||||
private const short SQL_SUCCESS_WITH_INFO = 1;
|
||||
private const short SQL_HANDLE_ENV = 1;
|
||||
private const short SQL_HANDLE_DBC = 2;
|
||||
private const int SQL_ATTR_ODBC_VERSION = 200;
|
||||
private const int SQL_OV_ODBC3 = 3;
|
||||
private const short SQL_NEED_DATA = 99;
|
||||
private const short DEFAULT_RESULT_SIZE = 1024;
|
||||
private const string START_STR = "{";
|
||||
private const string END_STR = "}";
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Enumerate the SQL Servers returning a list (if any exist)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static string[] EnumerateSQLServers()
|
||||
{
|
||||
return RetrieveInformation(SQL_DRIVER_STR);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerate the specified SQL server returning a list of databases (if any exist)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static string[] EnumerateSQLServersDatabases(string SQLServerNInstance)
|
||||
{
|
||||
return RetrieveInformation(SQL_DRIVER_STR + "SERVER=" + SQLServerNInstance + ";");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerate the specified SQL server returning a list of databases (if any exist)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static string[] EnumerateSQLServersDatabases(string SQLServerNInstance, string Username, string Password)
|
||||
{
|
||||
return RetrieveInformation(SQL_DRIVER_STR + "SERVER=" + SQLServerNInstance + ";" + "UID=" + Username + ";" + "PWD=" + Password + ";");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerate for SQLServer/Databases based on the passed information it the string
|
||||
/// The more information provided to SQLBrowseConnect the more granular it gets so
|
||||
/// if only DRIVER=SQL SERVER passed then a list of all SQL Servers is returned
|
||||
/// If DRIVER=SQL SERVER;Server=ServerName is passed then a list of all Databases on the
|
||||
/// servers is returned etc
|
||||
/// </summary>
|
||||
/// <param name="InputParam">A valid string to query for</param>
|
||||
/// <returns></returns>
|
||||
private static string[] RetrieveInformation(string InputParam)
|
||||
{
|
||||
IntPtr m_environmentHandle = IntPtr.Zero;
|
||||
IntPtr m_connectionHandle = IntPtr.Zero;
|
||||
|
||||
StringBuilder inConnection = new StringBuilder(InputParam);
|
||||
short stringLength = (short)inConnection.Length;
|
||||
|
||||
StringBuilder outConnection = new StringBuilder(DEFAULT_RESULT_SIZE);
|
||||
|
||||
short stringLength2Ptr = 0;
|
||||
bool bConnectSuccessful = false;
|
||||
|
||||
try
|
||||
{
|
||||
// Prepare the SQL Environment Handles
|
||||
if ((IsSQLSuccess(SQLAllocHandle(SQL_HANDLE_ENV, m_environmentHandle, out m_environmentHandle))) &&
|
||||
(IsSQLSuccess(SQLSetEnvAttr(m_environmentHandle, SQL_ATTR_ODBC_VERSION, (IntPtr)SQL_OV_ODBC3, 0))) &&
|
||||
(IsSQLSuccess(SQLAllocHandle(SQL_HANDLE_DBC, m_environmentHandle, out m_connectionHandle))))
|
||||
{
|
||||
|
||||
// Fetch the Data * First get the size of the buffer, then call it to get the buffer *
|
||||
if (IsSQLDataSuccess(SQLBrowseConnect(m_connectionHandle, inConnection, stringLength, null, 0, out stringLength2Ptr)) &&
|
||||
IsSQLDataSuccess(SQLBrowseConnect(m_connectionHandle, inConnection, stringLength, outConnection, stringLength2Ptr, out stringLength2Ptr))
|
||||
)
|
||||
{
|
||||
bConnectSuccessful = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { /* ignore */ }
|
||||
finally
|
||||
{
|
||||
FreeConnection(m_connectionHandle);
|
||||
FreeConnection(m_environmentHandle);
|
||||
}
|
||||
|
||||
if (bConnectSuccessful && outConnection.ToString() != "")
|
||||
{
|
||||
return ParseSQLOutConnection(outConnection.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#region Helper Functions
|
||||
|
||||
/// <summary>
|
||||
/// For quick SQL Return value evaluation
|
||||
/// </summary>
|
||||
private static bool IsSQLSuccess(short SQL_VALUE)
|
||||
{
|
||||
if (SQL_VALUE == SQL_SUCCESS || SQL_VALUE == SQL_SUCCESS_WITH_INFO)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For quick SQL Return value evaluation
|
||||
/// </summary>
|
||||
private static bool IsSQLDataSuccess(short SQL_VALUE)
|
||||
{
|
||||
if (SQL_VALUE == SQL_SUCCESS || SQL_VALUE == SQL_SUCCESS_WITH_INFO || SQL_VALUE == SQL_NEED_DATA)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse an outConnection string returned from SQLBrowseConnect
|
||||
/// </summary>
|
||||
/// <param name="outConnection">string to parse</param>
|
||||
/// <returns>Parsed Server names, or Empty Array if none found</returns>
|
||||
private static string[] ParseSQLOutConnection(string outConnection)
|
||||
{
|
||||
int m_Start = outConnection.IndexOf(START_STR) + 1;
|
||||
int m_lenString = outConnection.IndexOf(END_STR) - m_Start;
|
||||
if ((m_Start > 0) && (m_lenString > 0))
|
||||
{
|
||||
outConnection = outConnection.Substring(m_Start, m_lenString);
|
||||
}
|
||||
else
|
||||
{
|
||||
outConnection = string.Empty;
|
||||
}
|
||||
return outConnection.Split(",".ToCharArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this to Free a SQL handle
|
||||
/// </summary>
|
||||
private static void FreeConnection(IntPtr handleToFree)
|
||||
{
|
||||
if (handleToFree != IntPtr.Zero)
|
||||
SQLFreeHandle(SQL_HANDLE_DBC, handleToFree);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
100
Systems/SQLServer/Internal/Validation.cs
Normal file
100
Systems/SQLServer/Internal/Validation.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Sdaleo.Systems.SQLServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Central Location for SQL Server Input Validation
|
||||
/// </summary>
|
||||
internal class Validation
|
||||
{
|
||||
/// <summary>
|
||||
/// Main Validation Function to validate DatabaseName
|
||||
/// </summary>
|
||||
/// <param name="strDatabaseName">Name of Database</param>
|
||||
/// <returns>true if valid, false otherise</returns>
|
||||
internal static DBError IsValidDatabaseName(string strDatabaseName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(strDatabaseName))
|
||||
{
|
||||
return DBError.Create("DatabaseName is null");
|
||||
}
|
||||
else if (strDatabaseName.Length < 1 || strDatabaseName.Length > 52) // limit database Name length
|
||||
{
|
||||
return DBError.Create("DatabaseName length is invalid");
|
||||
}
|
||||
else if (!ValidationConsts.ContainsOnlyLegalChars(strDatabaseName, ValidationConsts.CharSet_AllowedDatabaseNames))
|
||||
{
|
||||
return DBError.Create("DatabaseName contains illegal characters");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DBError();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// validate SQL Server Table Names
|
||||
/// </summary>
|
||||
/// <param name="strTableName"></param>
|
||||
/// <returns></returns>
|
||||
public static DBError IsValidTableName(string strTableName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(strTableName))
|
||||
{
|
||||
return DBError.Create("TableName is null");
|
||||
}
|
||||
else if (strTableName.Length < 1 || strTableName.Length > 52) // limit Table Name length
|
||||
{
|
||||
return DBError.Create("TableName length is invalid");
|
||||
}
|
||||
else if (!ValidationConsts.ContainsOnlyLegalChars(strTableName, ValidationConsts.CharSet_AllowedTableNames))
|
||||
{
|
||||
return DBError.Create("TableName contains illegal characters");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DBError();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates a DataSource String which can include a Server and Instance, or just be a Server
|
||||
/// </summary>
|
||||
/// <param name="strDataSource">a DataSource String</param>
|
||||
/// <returns>true if valid, false otherise</returns>
|
||||
internal static bool IsValidDataSource(string strDataSource)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(strDataSource) && (strDataSource.IndexOf('\\') >= 0))
|
||||
{
|
||||
string[] values = strDataSource.Split('\\');
|
||||
if (values.Length == 2)
|
||||
return ValidationConsts.Generic.IsValidServerName(values[0]) && ValidationConsts.Generic.IsValidInstanceName(values[1]);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(strDataSource) && (strDataSource.IndexOf('\\') == 0))
|
||||
{
|
||||
return ValidationConsts.Generic.IsValidServerName(strDataSource);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the passedin string has both a valid server and a valid Instance
|
||||
/// </summary>
|
||||
/// <param name="strServerNameNInstance">a string to check for server and instance</param>
|
||||
/// <returns>true if valid, false otherwise</returns>
|
||||
internal static bool IsValidServerNameAndInstanceName(string strServerNameNInstance)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(strServerNameNInstance) && (strServerNameNInstance.IndexOf('\\') >= 0))
|
||||
{
|
||||
string[] values = strServerNameNInstance.Split('\\');
|
||||
if (values.Length == 2)
|
||||
return ValidationConsts.Generic.IsValidServerName(values[0]) && ValidationConsts.Generic.IsValidInstanceName(values[1]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
778
Systems/SQLServer/Security.cs
Normal file
778
Systems/SQLServer/Security.cs
Normal file
@@ -0,0 +1,778 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
|
||||
namespace Sdaleo.Systems.SQLServer
|
||||
{
|
||||
#region SQLServer Security Enums
|
||||
|
||||
/// <summary>
|
||||
/// Server Roles as specified in SQL Server
|
||||
/// </summary>
|
||||
public enum SQLServerRole
|
||||
{
|
||||
sysadmin,
|
||||
securityadmin,
|
||||
serveradmin,
|
||||
setupadmin,
|
||||
processadmin,
|
||||
diskadmin,
|
||||
dbcreator,
|
||||
bulkadmin,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User Roles as specified in SQL Server
|
||||
/// </summary>
|
||||
public enum SQLServerUserRole
|
||||
{
|
||||
db_accessadmin,
|
||||
db_backupoperator,
|
||||
db_datareader,
|
||||
db_datawriter,
|
||||
db_ddladmin,
|
||||
db_denydatareader,
|
||||
db_denydatawriter,
|
||||
db_owner,
|
||||
db_securityadmin,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// These are the SQL Actions you can take on
|
||||
/// SQLTablePermissions or SQLServerDatabasePermissions
|
||||
/// </summary>
|
||||
public enum SQLServerPermissionAction
|
||||
{
|
||||
GRANT,
|
||||
REVOKE,
|
||||
DENY
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User Permissions on any User Database ('_' must be stripped before using in in sql)
|
||||
/// </summary>
|
||||
public enum SQLServerDatabasePermission
|
||||
{
|
||||
CREATE_DATABASE, // <--- permission only allowed on 'Master' Database
|
||||
CONNECT,
|
||||
CREATE_TABLE,
|
||||
CREATE_DEFAULT,
|
||||
CREATE_FUNCTION,
|
||||
CREATE_PROCEDURE,
|
||||
CREATE_RULE,
|
||||
CREATE_VIEW,
|
||||
BACKUP_DATABASE,
|
||||
BACKUP_LOG
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Security/Permission SQL Server Related
|
||||
/// </summary>
|
||||
public class SQLServerSecurity
|
||||
{
|
||||
#region Internal Security Helper Functions
|
||||
|
||||
/// <summary>
|
||||
/// We must strip out the '_' on the SQLServerDatabasePermission Enum to use it in an SQL Query
|
||||
/// </summary>
|
||||
internal static string SQLServerDatabasePermission_ToString(SQLServerDatabasePermission DatabasePermission)
|
||||
{
|
||||
return DatabasePermission.ToString().Replace('_', ' ');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quick Helper function to get an SQLServerDatabasePermission[] that has all Permissions defined
|
||||
/// </summary>
|
||||
internal static SQLServerDatabasePermission[] SQLServerDatabasePermission_ToArray()
|
||||
{
|
||||
return (SQLServerDatabasePermission[])Enum.GetValues(typeof(SQLServerDatabasePermission));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns generated SQL Database Permissions string for the specified Database,Username with the specified permissions
|
||||
/// </summary>
|
||||
/// <param name="Username">Name of an existing User (required)</param>
|
||||
/// <param name="Action">Permission Action to take (required)</param>
|
||||
/// <param name="databasePermissions">array of User Database permissions (required)</param>
|
||||
/// <param name="bIsMasterDB">Some User Permission require to be executed ONLY on the Master Database, set to true if this is sql is being generated for 'master'</param>
|
||||
/// <returns>a Database permission string or empty string if error occured</returns>
|
||||
internal static string BuildSQLServerDatabasePermissionsStr(string Username, SQLServerDatabasePermission[] databasePermissions, SQLServerPermissionAction Action, bool bIsMasterDB)
|
||||
{
|
||||
if (String.IsNullOrEmpty(Username) || (databasePermissions == null))
|
||||
return string.Empty;
|
||||
|
||||
// add Action
|
||||
string sql = Action.ToString() + " ";
|
||||
|
||||
// add each permission individually
|
||||
for (int i = 0; i < databasePermissions.Length; ++i)
|
||||
{
|
||||
// Skip certain permissions, unless this is the Master DB
|
||||
if ((databasePermissions[i] == SQLServerDatabasePermission.CREATE_DATABASE) && !bIsMasterDB)
|
||||
continue;
|
||||
|
||||
sql += SQLServerDatabasePermission_ToString(databasePermissions[i]);
|
||||
bool bIsLast = (i == (databasePermissions.Length - 1));
|
||||
if (!bIsLast)
|
||||
sql += ",";
|
||||
}
|
||||
|
||||
// add action adjective
|
||||
if (Action == SQLServerPermissionAction.REVOKE)
|
||||
sql += " FROM ";
|
||||
else
|
||||
sql += " TO ";
|
||||
|
||||
// add user
|
||||
sql += string.Format("[{0}]", Username);
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Database User Role
|
||||
|
||||
/// <summary>
|
||||
/// Use this to add a specified User Role to a specified User in the DB
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="Username">an existing Username to add role to (required)</param>
|
||||
/// <param name="Role">Role to add to specified MemberName</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public DBError DatabaseUserRoleAdd(IConnectDb credential, string Username, SQLServerUserRole Role)
|
||||
{
|
||||
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");
|
||||
|
||||
// Execute the Query
|
||||
string sql = String.Format("sp_addrolemember @membername = '{0}', @rolename = '{1}'", Username, Role.ToString());
|
||||
DB db = DB.Create(credential);
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to drop a specified User Role from a specified User in the DB
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="Username">an existing Username to drop role from (required)</param>
|
||||
/// <param name="Role">Role to drop from specified MemberName</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseUserRoleDrop(IConnectDb credential, string Username, SQLServerUserRole Role)
|
||||
{
|
||||
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");
|
||||
|
||||
// Execute and return the Query
|
||||
string sql = String.Format("sp_droprolemember @membername = '{0}', @rolename = '{1}'", Username, Role.ToString());
|
||||
DB db = DB.Create(credential);
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Database User
|
||||
|
||||
/// <summary>
|
||||
/// Use this to query if the Username already exists as an SQL Database User (Does not query Server users ONLY DB Users)
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="Username">Specify the Username to Query for (required)</param>
|
||||
/// <param name="bExists">True if the User exists in the specified Database, False otherwise</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseUserExists(IConnectDb credential, string Username, 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");
|
||||
|
||||
if (!ValidationConsts.Generic.IsValidUserName(Username))
|
||||
return DBError.Create("Invalid Username Passed In");
|
||||
|
||||
// Execute the Query and return
|
||||
string sql = string.Format("SELECT [name] FROM sys.database_principals WHERE [type_desc]='SQL_USER' and [name] = '{0}'", Username);
|
||||
DB db = DB.Create(credential);
|
||||
DBRetVal retVal = db.ExecuteScalar(sql);
|
||||
bExists = retVal.IsValid;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to retrieve a list of all the Database users for the specified SQL Server with DB Credentials
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="Users">a list of Database User, or Null if error occured</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseUsers(IConnectDb credential, out string[] Users)
|
||||
{
|
||||
Users = 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.database_principals WHERE [type_desc]='SQL_USER'";
|
||||
DB db = DB.Create(credential);
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
List<String> retList = new List<string>();
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
retList.Add(row["name"].ToString());
|
||||
Users = retList.ToArray();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a new Username to the Specified Database for the specified Login
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="Username">Specify the Username for the database (can be same as LoginName) (required)</param>
|
||||
/// <param name="Loginname">Specify the LoginName (valid SQL Server Login Name) to create Username for (required)</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseUserAdd(IConnectDb credential, string Username, string LoginName)
|
||||
{
|
||||
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");
|
||||
|
||||
if (!ValidationConsts.Generic.IsValidUserName(LoginName))
|
||||
return DBError.Create("Invalid LoginName Passed In");
|
||||
|
||||
// Execute the Query
|
||||
string sql = string.Format("CREATE USER [{0}] FOR LOGIN [{1}] WITH DEFAULT_SCHEMA = [{0}]", Username, LoginName);
|
||||
DB db = DB.Create(credential);
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
if (!retVal.ErrorOccured)
|
||||
{
|
||||
// Since SQL 2005, We should create a SCHEMA for each User
|
||||
sql = string.Format("CREATE SCHEMA [{0}] AUTHORIZATION [{0}]", Username);
|
||||
retVal = db.ExecuteNonQuery(sql);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Drops an existing Username from the Specified Database
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="Username">Specify the Username for the database (required)</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseUserDrop(IConnectDb credential, string Username)
|
||||
{
|
||||
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");
|
||||
|
||||
// Since SQL 2005, We must drop the SCHEMA first for each User
|
||||
string sql = string.Format("DROP SCHEMA [{0}]", Username);
|
||||
DB db = DB.Create(credential);
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
if (!retVal.ErrorOccured)
|
||||
{
|
||||
sql = string.Format("DROP USER [{0}]", Username);
|
||||
retVal = db.ExecuteNonQuery(sql);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Database User Permission
|
||||
|
||||
/// <summary>
|
||||
/// Automatically grant,deny,revoke all permissions on the database for the specified user
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="Username">Specify the Username for the database (required)</param>
|
||||
/// <param name="action">GRANT,DENY, or REVOKE 'Permission_All' Permission on that db</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseUserPermissionsAll(IConnectDb credential, string Username, 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");
|
||||
|
||||
// Execute and return
|
||||
return DatabaseUserPermissions(credential, Username, SQLServerDatabasePermission_ToArray(), action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows you to specify permissions to grant,deny,revoke on the database for the specified user
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="Username">Specify the Username for the database (required)</param>
|
||||
/// <param name="permissions">an array of permissions to take action on on db</param>
|
||||
/// <param name="action">GRANT,DENY, or REVOKE specified Permissions on that db</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseUserPermissions(IConnectDb credential, string Username, SQLServerDatabasePermission[] 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");
|
||||
|
||||
// Execute the Query
|
||||
string sql = BuildSQLServerDatabasePermissionsStr(Username, permissions, action, SQLServerUtilities.IsSQLServerMasterDatabaseName(credential.DBMS.Database));
|
||||
DB db = DB.Create(credential);
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Database Ownership
|
||||
|
||||
/// <summary>
|
||||
/// Changes the Specified Database's Ownership to be owned by the specified LoginName
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="LoginName">Specify the Login Name to To take over Database Ownership for (required)</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseChangeOwnership(IConnectDb credential, string LoginName)
|
||||
{
|
||||
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(LoginName))
|
||||
return DBError.Create("Invalid LoginName Passed In");
|
||||
|
||||
// Make sure that Login doesn't already own that Database
|
||||
bool bContinue = true;
|
||||
string[] ownedDBs = null;
|
||||
DBError dberror = DatabasesOwnedByLogin(credential.DBMS.WithoutDatabase(), LoginName, out ownedDBs);
|
||||
if (!dberror.ErrorOccured && ownedDBs != null)
|
||||
{
|
||||
foreach (string dbName in ownedDBs)
|
||||
{
|
||||
if (dbName.ToLower() == credential.DBMS.Database.ToLower())
|
||||
{
|
||||
bContinue = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change the Database Ownership
|
||||
if (bContinue)
|
||||
{
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
string sql = String.Format("ALTER Authorization On Database::[{0}] To [{1}])", credential.DBMS.Database, LoginName);
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
return dberror;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the SQL Login that is the Owner of the specified Database for the specified SQL Server
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="Owner">Name of DB Owner</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabaseOwner(IConnectDb credential, out string Owner)
|
||||
{
|
||||
Owner = String.Empty;
|
||||
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
|
||||
DB db = DB.Create(credential);
|
||||
string sql = String.Format("Select suser_sname(owner_sid) from sys.databases where [name] = '{0}'", credential.DBMS.Database);
|
||||
DBRetVal retVal = db.ExecuteScalar(sql);
|
||||
if (retVal.IsValid)
|
||||
Owner = retVal.GetScalarRetVal();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to retrieve all Databases that are owned by the specified Login for the specified SQL Server
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="LoginName">Specify the Login Name to Query Database Ownership for (required)</param>
|
||||
/// <param name="DatabasesOwned">DatabaseNames that are owned by this Login, null if none are found or error occured</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError DatabasesOwnedByLogin(IConnectDb credential, string LoginName, out string[] DatabasesOwned)
|
||||
{
|
||||
DatabasesOwned = 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");
|
||||
|
||||
if (!ValidationConsts.Generic.IsValidUserName(LoginName))
|
||||
return DBError.Create("Invalid LoginName Passed In");
|
||||
|
||||
// Execute the Query
|
||||
string sql = String.Format("Select [name] from sys.databases where [owner_sid] = SUSER_SID('{0}')", LoginName);
|
||||
DB db = DB.Create(credential);
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
List<String> retList = new List<String>();
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
retList.Add(row["name"].ToString());
|
||||
DatabasesOwned = retList.ToArray();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Login Roles
|
||||
|
||||
/// <summary>
|
||||
/// Use this to add a specified Server Role to a specified Login in the DB
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="LoginName">existing login name to add server role to (required)</param>
|
||||
/// <param name="Role">Role to add to specified LoginName</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError LoginRoleAdd(IConnectDb credential, string LoginName, SQLServerRole Role)
|
||||
{
|
||||
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(LoginName))
|
||||
return DBError.Create("Invalid LoginName Passed In");
|
||||
|
||||
// Execute the Query and Return
|
||||
string sql = String.Format("sp_addsrvrolemember @loginame = '{0}', @rolename = '{1}'", LoginName, Role.ToString());
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to drop a specified Server Role from a specified Login in the DB
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="LoginName">existing login name to drop server role from (required)</param>
|
||||
/// <param name="Role">Role to drop from a specified LoginName</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError LoginRoleDrop(IConnectDb credential, string LoginName, SQLServerRole Role)
|
||||
{
|
||||
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(LoginName))
|
||||
return DBError.Create("Invalid LoginName Passed In");
|
||||
|
||||
// Execute Query
|
||||
string sql = String.Format("sp_dropsrvrolemember @loginame = '{0}', @rolename = '{1}'", LoginName, Role.ToString());
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to query the SQLServer for the roles that are defined for the specified LoginName
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="LoginName">existing login name to query server roles for</param>
|
||||
/// <param name="Roles">Roles Corresponding the the ServerLogin</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError LoginRoles(IConnectDb credential, string LoginName, out SQLServerRole[] Roles)
|
||||
{
|
||||
Roles = 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");
|
||||
|
||||
if (!ValidationConsts.Generic.IsValidUserName(LoginName))
|
||||
return DBError.Create("Invalid LoginName Passed In");
|
||||
|
||||
// Build SQL String
|
||||
string sql = "SELECT * FROM sys.server_role_members rm JOIN sys.server_principals Roles ON ";
|
||||
sql += "rm.role_principal_id = Roles.principal_id JOIN sys.server_principals Logins ON ";
|
||||
sql += "rm.member_principal_id = Logins.principal_id ";
|
||||
sql += String.Format("Where Logins.name = '{0}'", LoginName);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
|
||||
// Fetch the Data
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
List<SQLServerRole> retList = new List<SQLServerRole>();
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
{
|
||||
SQLServerRole role = (SQLServerRole)Enum.Parse(typeof(SQLServerRole), row["name"].ToString());
|
||||
retList.Add(role);
|
||||
}
|
||||
Roles = retList.ToArray();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Login
|
||||
|
||||
/// <summary>
|
||||
/// Easy Check to see if the passed in Login has SysAdmin rights (Full Control)
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="LoginName">existing login name to query sysadmin role for</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError LoginIsSysAdmin(IConnectDb credential, string LoginName, out bool IsAdmin)
|
||||
{
|
||||
IsAdmin = 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");
|
||||
|
||||
if (!ValidationConsts.Generic.IsValidUserName(LoginName))
|
||||
return DBError.Create("Invalid LoginName Passed In");
|
||||
|
||||
SQLServerRole[] roles = null;
|
||||
DBError dberror = LoginRoles(credential, LoginName, out roles);
|
||||
if (dberror.ErrorOccured)
|
||||
return dberror;
|
||||
|
||||
IsAdmin = roles.Contains(SQLServerRole.sysadmin);
|
||||
return dberror;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to query if the LoginName already exists as an SQL Server User (Does not query db User ONLY server Users)
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="LoginName">Specify the Login Name to Query for (required)</param>
|
||||
/// <param name="bExists">true if login already exist as an SQL User in the system, false otherwise</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError LoginExists(IConnectDb credential, string LoginName, out bool bExists)
|
||||
{
|
||||
bExists = true;
|
||||
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(LoginName))
|
||||
return DBError.Create("Invalid LoginName Passed In");
|
||||
|
||||
// Execute Query
|
||||
string sql = string.Format("SELECT [name] FROM sys.sql_logins WHERE [name] = '{0}'", LoginName);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteScalar(sql);
|
||||
bExists = retVal.IsValid;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to retrieve all the SQL Logins for the specified Server
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="ServerLogins">All SQL Server Logins on the specified server, or null if error occured</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError Logins(IConnectDb credential, out string[] ServerLogins)
|
||||
{
|
||||
ServerLogins = 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");
|
||||
|
||||
string sql = "SELECT [name] FROM sys.sql_logins";
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
List<String> retList = new List<string>();
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
retList.Add(row["name"].ToString());
|
||||
ServerLogins = retList.ToArray();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a Login to the SQL Server Instance
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="LoginName">LoginName (required)</param>
|
||||
/// <param name="LoginPassword">LoginPassword (required)</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError LoginAdd(IConnectDb credential, string LoginName, string LoginPassword)
|
||||
{
|
||||
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(LoginName))
|
||||
return DBError.Create("Invalid LoginName Passed In");
|
||||
|
||||
if (!ValidationConsts.Generic.IsValidPassword(LoginPassword))
|
||||
return DBError.Create("Invalid LoginPassword Passed In");
|
||||
|
||||
// Execute the Query
|
||||
string sql = String.Format("CREATE LOGIN [{0}] WITH PASSWORD = '{1}', CHECK_EXPIRATION = OFF, CHECK_POLICY = OFF", LoginName, LoginPassword);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Drops a Login from the SQL Server Instance
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="LoginName">LoginName (required)</param>
|
||||
/// <param name="FallbackLoginName">Fallback Login used to change ownership to, in case error occurs because LoginName owns Databases (not required)</param>
|
||||
/// <returns>true if successful, false otherwise</returns>
|
||||
public static DBError LoginDrop(IConnectDb credential, string LoginName, string FallbackLoginName)
|
||||
{
|
||||
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(LoginName))
|
||||
return DBError.Create("Invalid LoginName Passed In");
|
||||
|
||||
// If User owns Databases, the Login Drop will fail, so
|
||||
// query for existing databases
|
||||
string[] ownedDBs = null;
|
||||
DBError dberror = DatabasesOwnedByLogin(credential, LoginName, out ownedDBs);
|
||||
|
||||
// If Fallback Login was specified, use it to change the ownership on the Databases
|
||||
if (ValidationConsts.Generic.IsValidUserName(FallbackLoginName) && (ownedDBs != null))
|
||||
{
|
||||
foreach (string ownedDB in ownedDBs)
|
||||
{
|
||||
dberror = DatabaseChangeOwnership(credential.DBMS.WithDatabase(ownedDB), FallbackLoginName);
|
||||
if (dberror.ErrorOccured)
|
||||
return dberror;
|
||||
}
|
||||
|
||||
// Query Ownership again
|
||||
dberror = DatabasesOwnedByLogin(credential, LoginName, out ownedDBs);
|
||||
}
|
||||
|
||||
// If ther are no Owned DBs, this should succeed
|
||||
if (ownedDBs == null)
|
||||
{
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
string sql = String.Format("DROP LOGIN [{0}]", LoginName);
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
return dberror;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the Password for the Login Name being passed in. The Login Name can be the same name as the User specified
|
||||
/// via Credential (if that is the case, you must update your credential object, when this function returns true)
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="LoginName">LoginName to change password for(can be the same/different than the User passed in thru credential) (required)</param>
|
||||
/// <param name="NewLoginPassword">NewLoginPassword (required)</param>
|
||||
/// <returns>true if successful * Password was changed for the passed in LoginName *, false otherwise</returns>
|
||||
public static DBError LoginChangePassword(IConnectDb credential, string LoginName, string NewLoginPassword)
|
||||
{
|
||||
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(LoginName))
|
||||
return DBError.Create("Invalid LoginName Passed In");
|
||||
|
||||
if (!ValidationConsts.Generic.IsValidPassword(NewLoginPassword))
|
||||
return DBError.Create("Invalid NewLoginPassword Passed In");
|
||||
|
||||
// Execute the Query and Return
|
||||
string sql = string.Format("ALTER LOGIN [{0}] WITH PASSWORD = '{1}'", LoginName, NewLoginPassword);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteNonQuery(sql);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
318
Systems/SQLServer/Table.cs
Normal file
318
Systems/SQLServer/Table.cs
Normal file
@@ -0,0 +1,318 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
|
||||
namespace Sdaleo.Systems.SQLServer
|
||||
{
|
||||
#region SQLServer Table Enums
|
||||
|
||||
/// <summary>
|
||||
/// User Permissions on a Table
|
||||
/// </summary>
|
||||
public enum SQLServerTablePermission
|
||||
{
|
||||
SELECT,
|
||||
UPDATE,
|
||||
INSERT,
|
||||
DELETE,
|
||||
REFERENCES,
|
||||
// EXECUTE // <-- not a table permission
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Specific actions for SQL Server Tables in a Database
|
||||
/// </summary>
|
||||
public class SQLServerTable
|
||||
{
|
||||
#region Internal Table Helper Functions
|
||||
|
||||
/// <summary>
|
||||
/// We must strip out the '_' on the SQLTablePermission Enum to use it in an SQL Query
|
||||
/// </summary>
|
||||
internal static string SQLTablePermission_ToString(SQLServerTablePermission TablePermission)
|
||||
{
|
||||
return TablePermission.ToString().Replace('_', ' ');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quick Helper function to get an SQLTablePermission[] that has all Permissions defined
|
||||
/// </summary>
|
||||
internal static SQLServerTablePermission[] SQLServerTablePermission_ToArray()
|
||||
{
|
||||
return (SQLServerTablePermission[])Enum.GetValues(typeof(SQLServerTablePermission));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a generated SQL Table Permissions string for the specified Table,Username with the specified permissions
|
||||
/// </summary>
|
||||
/// <param name="TableName">Name of a Table(required)</param>
|
||||
/// <param name="Username">Name of an existing User that exists in that Database where the Table Resides (required)</param>
|
||||
/// <param name="Action">Permission Action to take</param>
|
||||
/// <param name="tablePermissions">array of permissions</param>
|
||||
/// <returns>a table permission string or empty string if error occured</returns>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Automatically grant,deny,revoke all permissions on the specified table for the specified user
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="Username">Specify the Username for the database (required)</param>
|
||||
/// <param name="TableName">Specify the TableName to set permissions on (required)</param>
|
||||
/// <param name="action">GRANT,DENY, or REVOKE 'Permission_All' Permission on that db</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows you to specify permissions to grant,deny,revoke on the specified table for the specified user
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="Username">Specify the Username for the database (required)</param>
|
||||
/// <param name="TableName">Specify the TableName to set permissions on (required)</param>
|
||||
/// <param name="permissions">an array of permissions to take action on on db</param>
|
||||
/// <param name="action">GRANT,DENY, or REVOKE specified Permissions on that db</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Reindexes all Indexes on the Specified Table.
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="TableName">Specify the TableName to set permissions on (required)</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs DBCC INDEXDEFRAG on the Specified Database, Table and Index
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="TableName">Name of Table (required)</param>
|
||||
/// <param name="Index">Name of Index (required)</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Returns all the Table Names for the specified Database
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="Tables">array of table names, or null if error occured</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
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<String> retList = new List<string>();
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
retList.Add(row["name"].ToString());
|
||||
Tables = retList.ToArray();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check to see if the Table Exists on the specified Database
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="TableName">Specify the TableName to check for (required)</param>
|
||||
/// <param name="bExists">true if exists, false otherwise</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the Table Name for the specified Table
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials with Database Info</param>
|
||||
/// <param name="TableName">Name of Table (required)</param>
|
||||
/// <param name="TableNameNew">Name of Table New (required)</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
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
|
||||
}
|
||||
}
|
||||
103
Systems/SQLServer/Utilities.cs
Normal file
103
Systems/SQLServer/Utilities.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Sdaleo.Systems.SQLServer
|
||||
{
|
||||
#region SQLServer Utility Enums
|
||||
|
||||
/// <summary>
|
||||
/// Default Databases that are usually part of an SQL Server
|
||||
/// </summary>
|
||||
internal enum SQLServerDefaultDatabase
|
||||
{
|
||||
master,
|
||||
model,
|
||||
msdb,
|
||||
tempdb,
|
||||
Northwind,
|
||||
pubs
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// SQLServer Helper Utilites
|
||||
/// </summary>
|
||||
public class SQLServerUtilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Splits a DataSource String to it's ServerAddress and InstanceName components
|
||||
/// </summary>
|
||||
/// <param name="ServerOrServerNInstance">a DataSource string containing either Server or Server And Instance</param>
|
||||
/// <param name="Server">Returns ServerAddress, if found</param>
|
||||
/// <param name="Instance">Returns Instance name, if found</param>
|
||||
/// <returns>True, if successfull, false otherwise</returns>
|
||||
public static bool SplitServerOrServerNInstance(string ServerOrServerNInstance, out string Server, out string Instance)
|
||||
{
|
||||
Server = String.Empty;
|
||||
Instance = String.Empty;
|
||||
|
||||
if (!string.IsNullOrEmpty(ServerOrServerNInstance) && (ServerOrServerNInstance.IndexOf('\\') >= 0))
|
||||
{
|
||||
string[] values = ServerOrServerNInstance.Split('\\');
|
||||
if (values.Length == 2)
|
||||
{
|
||||
if(ValidationConsts.Generic.IsValidServerName(values[0]))
|
||||
Server = values[0];
|
||||
if(ValidationConsts.Generic.IsValidInstanceName(values[1]))
|
||||
Instance = values[1];
|
||||
return (!String.IsNullOrEmpty(Server) && !String.IsNullOrEmpty(Instance));
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(ServerOrServerNInstance) && (ServerOrServerNInstance.IndexOf('\\') == 0))
|
||||
{
|
||||
if (ValidationConsts.Generic.IsValidServerName(ServerOrServerNInstance))
|
||||
Server = ServerOrServerNInstance;
|
||||
return (!String.IsNullOrEmpty(Server));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Easy Access to SQL Master Database
|
||||
public static string SQLServerMasterDatabaseName { get { return SQLServerDefaultDatabase.master.ToString(); } }
|
||||
public static bool IsSQLServerMasterDatabaseName(string strDatabaseName) { return (SQLServerMasterDatabaseName.ToUpper() == strDatabaseName.ToUpper()); }
|
||||
|
||||
/// <summary>
|
||||
/// Easy Check for Default Database * Any SQL Server Default Database *
|
||||
/// </summary>
|
||||
/// <param name="strDatabaseName">Name of Database to check for</param>
|
||||
/// <returns>true if this is an SQL Server Default Database, false otherwise</returns>
|
||||
public static bool IsDefaultDatabaseName(string strDatabaseName)
|
||||
{
|
||||
foreach (string strName in Enum.GetNames(typeof(SQLServerDefaultDatabase)))
|
||||
{
|
||||
if (strName.ToUpper() == strDatabaseName.ToUpper())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easy Check for System Database * Same as Default Database but does not inclue Northwind, or Pubs *
|
||||
/// </summary>
|
||||
/// <param name="strDatabaseName">Name of Database to check for</param>
|
||||
/// <returns>true if this is an SQL Server System Database, false otherwise</returns>
|
||||
public static bool IsSystemDatabaseName(string strDatabaseName)
|
||||
{
|
||||
foreach (string strName in Enum.GetNames(typeof(SQLServerDefaultDatabase)))
|
||||
{
|
||||
if (strName.ToUpper() == strDatabaseName.ToUpper() &&
|
||||
(strDatabaseName.ToUpper() != "NORTHWIND") &&
|
||||
(strDatabaseName.ToUpper() != "PUBS"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user