Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / SqlClient / SqlProviderUtilities.cs / 1305376 / SqlProviderUtilities.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Metadata.Edm;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data.Common.Utils;
namespace System.Data.SqlClient
{
class SqlProviderUtilities
{
///
/// Requires that the given connection is of type T.
/// Returns the connection or throws.
///
internal static SqlConnection GetRequiredSqlConnection(DbConnection connection)
{
var result = connection as SqlConnection;
if (null == result)
{
throw EntityUtil.Argument(Strings.Mapping_Provider_WrongConnectionType(typeof(SqlConnection)));
}
return result;
}
}
sealed class SqlDdlBuilder
{
private readonly StringBuilder unencodedStringBuilder = new StringBuilder();
private readonly HashSet ignoredEntitySets = new HashSet();
#region Pulblic Surface
internal static string CreateObjectsScript(StoreItemCollection itemCollection, bool createSchemas)
{
SqlDdlBuilder builder = new SqlDdlBuilder();
foreach (EntityContainer container in itemCollection.GetItems())
{
var entitySets = container.BaseEntitySets.OfType().OrderBy(s => s.Name);
if (createSchemas)
{
var schemas = new HashSet(entitySets.Select(s => GetSchemaName(s)));
foreach (string schema in schemas.OrderBy(s => s))
{
// don't bother creating default schema
if (schema != "dbo")
{
builder.AppendCreateSchema(schema);
}
}
}
foreach (EntitySet entitySet in container.BaseEntitySets.OfType().OrderBy(s => s.Name))
{
builder.AppendCreateTable(entitySet);
}
foreach (AssociationSet associationSet in container.BaseEntitySets.OfType().OrderBy(s => s.Name))
{
builder.AppendCreateForeignKeys(associationSet);
}
}
return builder.GetCommandText();
}
internal static string CreateDatabaseScript(string databaseName, string dataFileName, string logFileName)
{
var builder = new SqlDdlBuilder();
builder.AppendSql("create database ");
builder.AppendIdentifier(databaseName);
if (null != dataFileName)
{
Debug.Assert(logFileName != null, "must specify log file with data file");
builder.AppendSql(" on primary ");
builder.AppendFileName(dataFileName);
builder.AppendSql(" log on ");
builder.AppendFileName(logFileName);
}
return builder.unencodedStringBuilder.ToString();
}
internal static string CreateDatabaseExistsScript(string databaseName, bool useDeprecatedSystemTable)
{
var builder = new SqlDdlBuilder();
builder.AppendSql("SELECT Count(*) FROM ");
if (useDeprecatedSystemTable)
{
builder.AppendSql("sysdatabases");
}
else
{
builder.AppendSql("sys.databases");
}
builder.AppendSql(" WHERE [name]=");
builder.AppendStringLiteral(databaseName);
return builder.unencodedStringBuilder.ToString();
}
internal static string DropDatabaseScript(string databaseName)
{
var builder = new SqlDdlBuilder();
builder.AppendSql("drop database ");
builder.AppendIdentifier(databaseName);
return builder.unencodedStringBuilder.ToString();
}
internal string GetCommandText()
{
return this.unencodedStringBuilder.ToString();
}
#endregion
#region Private Methods
private static string GetSchemaName(EntitySet entitySet)
{
return entitySet.Schema ?? entitySet.EntityContainer.Name;
}
private static string GetTableName(EntitySet entitySet)
{
return entitySet.Table ?? entitySet.Name;
}
private void AppendCreateForeignKeys(AssociationSet associationSet)
{
var constraint = associationSet.ElementType.ReferentialConstraints.Single();
var principalEnd = associationSet.AssociationSetEnds[constraint.FromRole.Name];
var dependentEnd = associationSet.AssociationSetEnds[constraint.ToRole.Name];
// If any of the participating entity sets was skipped, skip the association too
if (ignoredEntitySets.Contains(principalEnd.EntitySet) || ignoredEntitySets.Contains(dependentEnd.EntitySet))
{
AppendSql("-- Ignoring association set with participating entity set with defining query: ");
AppendIdentifierEscapeNewLine(associationSet.Name);
}
else
{
AppendSql("alter table ");
AppendIdentifier(dependentEnd.EntitySet);
AppendSql(" add constraint ");
AppendIdentifier(associationSet.Name);
AppendSql(" foreign key (");
AppendIdentifiers(constraint.ToProperties);
AppendSql(") references ");
AppendIdentifier(principalEnd.EntitySet);
AppendSql("(");
AppendIdentifiers(constraint.FromProperties);
AppendSql(")");
if (principalEnd.CorrespondingAssociationEndMember.DeleteBehavior == OperationAction.Cascade)
{
AppendSql(" on delete cascade");
}
AppendSql(";");
}
AppendNewLine();
}
private void AppendCreateTable(EntitySet entitySet)
{
// If the entity set has defining query, skip it
if (entitySet.DefiningQuery != null)
{
AppendSql("-- Ignoring entity set with defining query: ");
AppendIdentifier(entitySet, AppendIdentifierEscapeNewLine);
ignoredEntitySets.Add(entitySet);
}
else
{
AppendSql("create table ");
AppendIdentifier(entitySet);
AppendSql(" (");
AppendNewLine();
foreach (EdmProperty column in entitySet.ElementType.Properties)
{
AppendSql(" ");
AppendIdentifier(column.Name);
AppendSql(" ");
AppendType(column);
AppendSql(",");
AppendNewLine();
}
AppendSql(" primary key (");
AppendJoin(entitySet.ElementType.KeyMembers, k => AppendIdentifier(k.Name), ", ");
AppendSql(")");
AppendNewLine();
AppendSql(");");
}
AppendNewLine();
}
private void AppendCreateSchema(string schema)
{
AppendSql("if (schema_id(");
AppendStringLiteral(schema);
AppendSql(") is null) exec(");
// need to create a sub-command and escape it as a string literal as well...
SqlDdlBuilder schemaBuilder = new SqlDdlBuilder();
schemaBuilder.AppendSql("create schema ");
schemaBuilder.AppendIdentifier(schema);
AppendStringLiteral(schemaBuilder.unencodedStringBuilder.ToString());
AppendSql(");");
AppendNewLine();
}
private void AppendIdentifier(EntitySet table)
{
AppendIdentifier(table, AppendIdentifier);
}
private void AppendIdentifier(EntitySet table, Action AppendIdentifierEscape)
{
string schemaName = GetSchemaName(table);
string tableName = GetTableName(table);
if (schemaName != null)
{
AppendIdentifierEscape(schemaName);
AppendSql(".");
}
AppendIdentifierEscape(tableName);
}
private void AppendStringLiteral(string literalValue)
{
AppendSql("N'" + literalValue.Replace("'", "''") + "'");
}
private void AppendIdentifiers(IEnumerable properties)
{
AppendJoin(properties, p => AppendIdentifier(p.Name), ", ");
}
private void AppendIdentifier(string identifier)
{
AppendSql("[" + identifier.Replace("]", "]]") + "]");
}
private void AppendIdentifierEscapeNewLine(string identifier)
{
AppendIdentifier(identifier.Replace("\r", "\r--").Replace("\n", "\n--"));
}
private void AppendFileName(string path)
{
AppendSql("(name=");
AppendStringLiteral(Path.GetFileName(path));
AppendSql(", filename=");
AppendStringLiteral(path);
AppendSql(")");
}
private void AppendJoin(IEnumerable elements, Action appendElement, string unencodedSeparator)
{
bool first = true;
foreach (T element in elements)
{
if (first)
{
first = false;
}
else
{
AppendSql(unencodedSeparator);
}
appendElement(element);
}
}
private void AppendType(EdmProperty column)
{
TypeUsage type = column.TypeUsage;
// check for rowversion-like configurations
Facet storeGenFacet;
bool isTimestamp = false;
if (type.EdmType.Name == "binary" &&
8 == type.GetMaxLength() &&
column.TypeUsage.Facets.TryGetValue("StoreGeneratedPattern", false, out storeGenFacet) &&
storeGenFacet.Value != null &&
StoreGeneratedPattern.Computed == (StoreGeneratedPattern)storeGenFacet.Value)
{
isTimestamp = true;
AppendIdentifier("rowversion");
}
else
{
string typeName = type.EdmType.Name;
// Special case: the EDM treats 'nvarchar(max)' as a type name, but SQL Server treats
// it as a type 'nvarchar' and a type qualifier. As such, we can't escape the entire
// type name as the EDM sees it.
const string maxSuffix = "(max)";
if (type.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType && typeName.EndsWith(maxSuffix, StringComparison.Ordinal))
{
Debug.Assert(new[] { "nvarchar(max)", "varchar(max)", "varbinary(max)" }.Contains(typeName),
"no other known SQL Server primitive types types accept (max)");
AppendIdentifier(typeName.Substring(0, typeName.Length - maxSuffix.Length));
AppendSql("(max)");
}
else
{
AppendIdentifier(typeName);
}
switch (type.EdmType.Name)
{
case "decimal":
case "numeric":
AppendSqlInvariantFormat("({0}, {1})", type.GetPrecision(), type.GetScale());
break;
case "datetime2":
case "datetimeoffset":
case "time":
AppendSqlInvariantFormat("({0})", type.GetPrecision());
break;
case "binary":
case "varbinary":
case "nvarchar":
case "varchar":
case "char":
case "nchar":
AppendSqlInvariantFormat("({0})", type.GetMaxLength());
break;
default:
break;
}
}
AppendSql(column.Nullable ? " null" : " not null");
if (!isTimestamp && column.TypeUsage.Facets.TryGetValue("StoreGeneratedPattern", false, out storeGenFacet) &&
storeGenFacet.Value != null)
{
StoreGeneratedPattern storeGenPattern = (StoreGeneratedPattern)storeGenFacet.Value;
if (storeGenPattern == StoreGeneratedPattern.Identity)
{
if (type.EdmType.Name == "uniqueidentifier")
{
AppendSql(" default newid()");
}
else
{
AppendSql(" identity");
}
}
else if (storeGenPattern == StoreGeneratedPattern.Computed)
{
if (type.EdmType.Name != "timestamp" && type.EdmType.Name != "rowversion")
{
// if "IsComputed" is applied to store types that are not intrinsically store generated, throw
throw EntityUtil.NotSupported(Strings.SqlProvider_DdlGeneration_StoreGeneratedPatternNotSupported(Enum.GetName(typeof(StoreGeneratedPattern), storeGenPattern)));
}
}
}
}
#region Access to underlying string builder
///
/// Appends raw SQL into the string builder.
///
/// Raw SQL string to append into the string builder.
private void AppendSql(string text)
{
unencodedStringBuilder.Append(text);
}
///
/// Appends new line for visual formatting or for ending a comment.
///
private void AppendNewLine()
{
unencodedStringBuilder.Append("\r\n");
}
///
/// Append raw SQL into the string builder with formatting options and invariant culture formatting.
///
/// A composite format string.
/// An array of objects to format.
private void AppendSqlInvariantFormat(string format, params object[] args)
{
unencodedStringBuilder.AppendFormat(CultureInfo.InvariantCulture, format, args);
}
#endregion
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PeerNameRecordCollection.cs
- TextServicesHost.cs
- DataRowChangeEvent.cs
- ResetableIterator.cs
- InheritanceRules.cs
- PathTooLongException.cs
- Cursors.cs
- ConnectionPointCookie.cs
- DllNotFoundException.cs
- ConnectionPointCookie.cs
- BinarySecretKeyIdentifierClause.cs
- TextServicesCompartmentEventSink.cs
- HtmlFormAdapter.cs
- EntityTypeBase.cs
- HostingEnvironmentException.cs
- LinearKeyFrames.cs
- ColumnHeaderConverter.cs
- DbConnectionPoolGroupProviderInfo.cs
- PersonalizationDictionary.cs
- KnownBoxes.cs
- TraceHandler.cs
- DragSelectionMessageFilter.cs
- ComponentEvent.cs
- Mappings.cs
- HttpCacheParams.cs
- RepeaterCommandEventArgs.cs
- Button.cs
- SvcMapFileSerializer.cs
- CheckBoxStandardAdapter.cs
- SupportsEventValidationAttribute.cs
- ExtentJoinTreeNode.cs
- DispatcherEventArgs.cs
- SecurityState.cs
- TextRangeEditTables.cs
- HierarchicalDataBoundControlAdapter.cs
- HttpCachePolicyBase.cs
- DoubleStorage.cs
- AvTraceFormat.cs
- SplineKeyFrames.cs
- BooleanExpr.cs
- WindowsSolidBrush.cs
- OleDbError.cs
- StrokeCollection2.cs
- HttpCachePolicy.cs
- Encoder.cs
- WindowsButton.cs
- Schedule.cs
- IBuiltInEvidence.cs
- xdrvalidator.cs
- CompModSwitches.cs
- HtmlControl.cs
- ResponseStream.cs
- GridErrorDlg.cs
- UnionCqlBlock.cs
- UrlRoutingModule.cs
- TreeNodeEventArgs.cs
- RegexCode.cs
- AddingNewEventArgs.cs
- SourceFileBuildProvider.cs
- LineBreakRecord.cs
- Binding.cs
- TransactionWaitAsyncResult.cs
- XslVisitor.cs
- MappingModelBuildProvider.cs
- COM2IProvidePropertyBuilderHandler.cs
- MarkupWriter.cs
- _UriSyntax.cs
- ActiveXSite.cs
- storagemappingitemcollection.viewdictionary.cs
- CatalogPartCollection.cs
- MinimizableAttributeTypeConverter.cs
- Comparer.cs
- CompositeCollectionView.cs
- NameValueSectionHandler.cs
- RuntimeEnvironment.cs
- BitmapEffectDrawingContextState.cs
- DBCommand.cs
- BookmarkTable.cs
- ThreadLocal.cs
- InvokePattern.cs
- ellipse.cs
- ReliableSession.cs
- CodeCommentStatement.cs
- Subtree.cs
- Matrix3D.cs
- WsatServiceAddress.cs
- DateTimeUtil.cs
- CompatibleIComparer.cs
- EventLogPermissionAttribute.cs
- ExtensionQuery.cs
- OpenTypeLayoutCache.cs
- InfoCardArgumentException.cs
- ComplexType.cs
- FormatControl.cs
- ScriptResourceHandler.cs
- Baml2006KnownTypes.cs
- DataServiceContext.cs
- GroupItem.cs
- XmlTextReader.cs
- PersonalizationStateInfo.cs