protected override string GetDbProviderManifestToken(DbConnection connection) { EntityUtil.CheckArgumentNull(connection, "connection"); SqlConnection sqlConnection = SqlProviderUtilities.GetRequiredSqlConnection(connection); if (string.IsNullOrEmpty(sqlConnection.ConnectionString)) { throw EntityUtil.Argument(Strings.UnableToDetermineStoreVersion); } string providerManifestToken = null; // Try to get the provider manifest token from the database connection // That failing, try using connection to master database (in case the database doesn't exist yet) try { UsingConnection(sqlConnection, conn => { providerManifestToken = SqlVersionUtils.GetVersionHint(SqlVersionUtils.GetSqlVersion(conn)); }); } catch { UsingMasterConnection(sqlConnection, conn => { providerManifestToken = SqlVersionUtils.GetVersionHint(SqlVersionUtils.GetSqlVersion(conn)); }); } return(providerManifestToken); }
protected override string DbCreateDatabaseScript(string providerManifestToken, StoreItemCollection storeItemCollection) { EntityUtil.CheckArgumentNull(providerManifestToken, "providerManifestToken"); EntityUtil.CheckArgumentNull(storeItemCollection, "storeItemCollection"); SqlVersion version = SqlVersionUtils.GetSqlVersion(providerManifestToken); return(CreateObjectsScript(version, storeItemCollection)); }
/// <summary> /// Determines whether the database for the given connection exists. /// There are three cases: /// 1. Initial Catalog = X, AttachDBFilename = null: (SELECT Count(*) FROM sys.databases WHERE [name]= X) > 0 /// 2. Initial Catalog = X, AttachDBFilename = F: if (SELECT Count(*) FROM sys.databases WHERE [name]= X) > true, /// if not, try to open the connection and then return (SELECT Count(*) FROM sys.databases WHERE [name]= X) > 0 /// 3. Initial Catalog = null, AttachDBFilename = F: Try to open the connection. If that succeeds the result is true, otherwise /// if the there are no databases corresponding to the given file return false, otherwise throw. /// /// Note: We open the connection to cover the scenario when the mdf exists, but is not attached. /// Given that opening the connection would auto-attach it, it would not be appropriate to return false in this case. /// Also note that checking for the existence of the file does not work for a remote server. (Dev11 #290487) /// For further details on the behavior when AttachDBFilename is specified see Dev10# 188936 /// </summary> protected override bool DbDatabaseExists(DbConnection connection, int?commandTimeout, StoreItemCollection storeItemCollection) { EntityUtil.CheckArgumentNull(connection, "connection"); EntityUtil.CheckArgumentNull(storeItemCollection, "storeItemCollection"); SqlConnection sqlConnection = SqlProviderUtilities.GetRequiredSqlConnection(connection); var connectionBuilder = new SqlConnectionStringBuilder(sqlConnection.ConnectionString); if (string.IsNullOrEmpty(connectionBuilder.InitialCatalog) && string.IsNullOrEmpty(connectionBuilder.AttachDBFilename)) { throw EntityUtil.InvalidOperation(Strings.SqlProvider_DdlGeneration_MissingInitialCatalog); } if (!string.IsNullOrEmpty(connectionBuilder.InitialCatalog)) { if (CheckDatabaseExists(sqlConnection, commandTimeout, connectionBuilder.InitialCatalog)) { //Avoid further processing return(true); } } if (!string.IsNullOrEmpty(connectionBuilder.AttachDBFilename)) { try { UsingConnection(sqlConnection, (SqlConnection con) => { }); return(true); } catch (SqlException e) { if (!string.IsNullOrEmpty(connectionBuilder.InitialCatalog)) { return(CheckDatabaseExists(sqlConnection, commandTimeout, connectionBuilder.InitialCatalog)); } // Initial catalog not specified string fileName = GetMdfFileName(connectionBuilder.AttachDBFilename); bool databaseDoesNotExistInSysTables = false; UsingMasterConnection(sqlConnection, conn => { SqlVersion sqlVersion = SqlVersionUtils.GetSqlVersion(conn); string databaseExistsScript = SqlDdlBuilder.CreateCountDatabasesBasedOnFileNameScript(fileName, useDeprecatedSystemTable: sqlVersion == SqlVersion.Sql8); int result = (int)CreateCommand(conn, databaseExistsScript, commandTimeout).ExecuteScalar(); databaseDoesNotExistInSysTables = (result == 0); }); if (databaseDoesNotExistInSysTables) { return(false); } throw EntityUtil.InvalidOperation(Strings.SqlProvider_DdlGeneration_CannotTellIfDatabaseExists, e); } } // CheckDatabaseExists returned false and no AttachDBFilename is specified return(false); }
/// <summary> /// Delete the database for the given connection. /// There are three cases: /// 1. If Initial Catalog is specified (X) drop database X /// 2. Else if AttachDBFilename is specified (F) drop all the databases corresponding to F /// if none throw /// 3. If niether the catalog not the file name is specified - throw /// /// Note that directly deleting the files does not work for a remote server. However, even for not attached /// databases the current logic would work assuming the user does: if (DatabaseExists) DeleteDatabase /// </summary> /// <param name="connection"></param> /// <param name="commandTimeout"></param> /// <param name="storeItemCollection"></param> protected override void DbDeleteDatabase(DbConnection connection, int?commandTimeout, StoreItemCollection storeItemCollection) { EntityUtil.CheckArgumentNull(connection, "connection"); EntityUtil.CheckArgumentNull(storeItemCollection, "storeItemCollection"); SqlConnection sqlConnection = SqlProviderUtilities.GetRequiredSqlConnection(connection); var connectionBuilder = new SqlConnectionStringBuilder(sqlConnection.ConnectionString); string initialCatalog = connectionBuilder.InitialCatalog; string attachDBFile = connectionBuilder.AttachDBFilename; if (!string.IsNullOrEmpty(initialCatalog)) { DropDatabase(sqlConnection, commandTimeout, initialCatalog); } // initial catalog not specified else if (!string.IsNullOrEmpty(attachDBFile)) { string fullFileName = GetMdfFileName(attachDBFile); List <string> databaseNames = new List <string>(); UsingMasterConnection(sqlConnection, conn => { SqlVersion sqlVersion = SqlVersionUtils.GetSqlVersion(conn); string getDatabaseNamesScript = SqlDdlBuilder.CreateGetDatabaseNamesBasedOnFileNameScript(fullFileName, sqlVersion == SqlVersion.Sql8); var command = CreateCommand(conn, getDatabaseNamesScript, commandTimeout); using (var reader = command.ExecuteReader()) { while (reader.Read()) { databaseNames.Add(reader.GetString(0)); } } }); if (databaseNames.Count > 0) { foreach (var databaseName in databaseNames) { DropDatabase(sqlConnection, commandTimeout, databaseName); } } else { throw EntityUtil.InvalidOperation(Strings.SqlProvider_DdlGeneration_CannotDeleteDatabaseNoInitialCatalog); } } // neither initial catalog nor attachDB file name are specified else { throw EntityUtil.InvalidOperation(Strings.SqlProvider_DdlGeneration_MissingInitialCatalog); } }
private static bool CheckDatabaseExists(SqlConnection sqlConnection, int?commandTimeout, string databaseName) { bool databaseExistsInSysTables = false; UsingMasterConnection(sqlConnection, conn => { SqlVersion sqlVersion = SqlVersionUtils.GetSqlVersion(conn); string databaseExistsScript = SqlDdlBuilder.CreateDatabaseExistsScript(databaseName, useDeprecatedSystemTable: sqlVersion == SqlVersion.Sql8); int result = (int)CreateCommand(conn, databaseExistsScript, commandTimeout).ExecuteScalar(); databaseExistsInSysTables = (result > 0); }); return(databaseExistsInSysTables); }
void ValidateVersionHint(string versionHint) { if (string.IsNullOrEmpty(versionHint)) { throw EntityUtil.Argument(Strings.UnableToDetermineStoreVersion); } // GetSqlVersion will throw ArgumentException if manifestToken is null, empty, or not recognized. SqlVersion tokenVersion = SqlVersionUtils.GetSqlVersion(versionHint); // SQL spatial support is only available for SQL Server 2008 and later if (tokenVersion < SqlVersion.Sql10) { throw EntityUtil.ProviderIncompatible(Strings.SqlProvider_Sql2008RequiredForSpatial); } }
/// <summary> /// Constructor /// </summary> /// <param name="manifestToken">A token used to infer the capabilities of the store</param> public SqlProviderManifest(string manifestToken) : base(SqlProviderManifest.GetProviderManifest()) { // GetSqlVersion will throw ArgumentException if manifestToken is null, empty, or not recognized. _version = SqlVersionUtils.GetSqlVersion(manifestToken); }