public void AppendKeyWord_should_case_based_on_property() { var sqlStringBuilder = new SqlStringBuilder(); sqlStringBuilder.AppendKeyword("select"); Assert.Equal("select", sqlStringBuilder.ToString()); sqlStringBuilder.UpperCaseKeywords = true; sqlStringBuilder.AppendKeyword(" from"); Assert.Equal("select FROM", sqlStringBuilder.ToString()); }
public void Methods_should_delegate_to_underlying_string_builder() { var sqlStringBuilder = new SqlStringBuilder(); sqlStringBuilder.Append("foo"); sqlStringBuilder.AppendLine("bar"); sqlStringBuilder.AppendLine(); Assert.Equal(10, sqlStringBuilder.Length); sqlStringBuilder.Length = 0; Assert.Equal(0, sqlStringBuilder.Length); }
private static string HandlIdentity_adds_cast_for_identity_columns(PrimitiveTypeKind primitiveTypeKind) { var typeUsage = ProviderRegistry.SqlCe4_ProviderManifest.GetStoreType( TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(primitiveTypeKind))); var mockMember = new Mock<EdmMember>(); mockMember.Setup(m => m.TypeUsage).Returns(typeUsage); var mockTransalator = new Mock<DmlSqlGenerator.ExpressionTranslator>(); mockTransalator.Setup(m => m.MemberValues).Returns(new Dictionary<EdmMember, DbParameter>()); var builder = new SqlStringBuilder(); DmlSqlGenerator.HandleIdentity(builder, mockTransalator.Object, mockMember.Object, false, new Mock<EntitySetBase>().Object); return builder.ToString(); }
public void HandlIdentity_throws_for_unsupported_identity_type() { var typeUsage = ProviderRegistry.SqlCe4_ProviderManifest.GetStoreType( TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Guid))); var mockMember = new Mock<EdmMember>(); mockMember.Setup(m => m.TypeUsage).Returns(typeUsage); mockMember.Setup(m => m.Name).Returns("Cheese"); var mockTransalator = new Mock<DmlSqlGenerator.ExpressionTranslator>(); mockTransalator.Setup(m => m.MemberValues).Returns(new Dictionary<EdmMember, DbParameter>()); var builder = new SqlStringBuilder(); Assert.Equal( ADP1.Update_NotSupportedIdentityType("Cheese", "SqlServerCe.uniqueidentifier"), Assert.Throws<InvalidOperationException>( () => DmlSqlGenerator.HandleIdentity( builder, mockTransalator.Object, mockMember.Object, false, new Mock<EntitySetBase>().Object)).Message); }
public void HandlIdentity_does_not_add_cast_if_member_value_exists() { var typeUsage = ProviderRegistry.SqlCe4_ProviderManifest.GetStoreType( TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))); var mockMember = new Mock<EdmMember>(); mockMember.Setup(m => m.TypeUsage).Returns(typeUsage); var mockParameter = new Mock<DbParameter>(); mockParameter.Setup(m => m.ParameterName).Returns("A Compact Unicorn"); var mockTransalator = new Mock<DmlSqlGenerator.ExpressionTranslator>(); var members = new Dictionary<EdmMember, DbParameter> { { mockMember.Object, mockParameter.Object } }; mockTransalator.Setup(m => m.MemberValues).Returns(members); var builder = new SqlStringBuilder(); DmlSqlGenerator.HandleIdentity(builder, mockTransalator.Object, mockMember.Object, false, new Mock<EntitySetBase>().Object); Assert.Equal("A Compact Unicorn", builder.ToString()); }
internal static string[] GenerateUpdateSql( DbUpdateCommandTree tree, out List<DbParameter> parameters, bool isLocalProvider, bool upperCaseKeywords = true) { var commandTexts = new List<String>(); var commandText = new SqlStringBuilder(CommandTextBuilderInitialCapacity) { UpperCaseKeywords = upperCaseKeywords }; var translator = new ExpressionTranslator(commandText, tree, null != tree.Returning, isLocalProvider); // update [schemaName].[tableName] commandText.AppendKeyword("update "); tree.Target.Expression.Accept(translator); commandText.AppendLine(); // set c1 = ..., c2 = ..., ... var first = true; commandText.AppendKeyword("set "); foreach (DbSetClause setClause in tree.SetClauses) { if (first) { first = false; } else { commandText.Append(", "); } setClause.Property.Accept(translator); commandText.Append(" = "); setClause.Value.Accept(translator); } if (first) { // If first is still true, it indicates there were no set // clauses. // - we acquire the appropriate locks // - server-gen columns (e.g. timestamp) get recomputed // // Fix #13533 : A fake update DML updating some column item // with the same value as before to acquire the lock on the table // while updating some columns in another table. This happens when // both the table are dependent on an entity and the members of entity // which is mapped to one table is being updated and the other table // needs to be locked for consistency. string updatableColumnName; if (GetUpdatableColumn(tree, out updatableColumnName)) { commandText.Append("["); commandText.Append(CommonUtils.EscapeSquareBraceNames(updatableColumnName)); commandText.Append("] "); commandText.Append(" = "); commandText.Append("["); commandText.Append(CommonUtils.EscapeSquareBraceNames(updatableColumnName)); commandText.Append("] "); } else { // Throw some meaningful error throw ADP1.Update( EntityRes.GetString(EntityRes.UpdateStatementCannotBeGeneratedForAcquiringLock), null); } } commandText.AppendLine(); // where c1 = ..., c2 = ... commandText.AppendKeyword("where "); tree.Predicate.Accept(translator); commandText.AppendLine(); commandTexts.Add(commandText.ToString()); commandText.Length = 0; // generate returning sql GenerateReturningSql(commandText, tree, translator, tree.Returning); if (!String.IsNullOrEmpty(commandText.ToString())) { commandTexts.Add(commandText.ToString()); } parameters = translator.Parameters; return commandTexts.ToArray(); }
// <summary> // Initialize a new expression translator populating the given string builder // with command text. Command text builder and command tree must not be null. // </summary> // <param name="commandText"> Command text with which to populate commands </param> // <param name="commandTree"> Command tree generating SQL </param> // <param name="preserveMemberValues"> Indicates whether the translator should preserve member values while compiling t-SQL (only needed for server generation) </param> internal ExpressionTranslator( SqlStringBuilder commandText, DbModificationCommandTree commandTree, bool preserveMemberValues, bool isLocalProvider, bool createParameters = true) { DebugCheck.NotNull(commandText); DebugCheck.NotNull(commandTree); _commandText = commandText; _commandTree = commandTree; _parameters = new List<DbParameter>(); _sqlGenerator = new SqlGenerator(); _memberValues = preserveMemberValues ? new Dictionary<EdmMember, DbParameter>() : null; _isLocalProvider = isLocalProvider; _createParameters = createParameters; }
internal static bool HandleIdentity( SqlStringBuilder commandText, ExpressionTranslator translator, EdmMember member, bool flag, EntitySetBase target) { DebugCheck.NotNull(commandText); DebugCheck.NotNull(translator); DebugCheck.NotNull(member); DebugCheck.NotNull(target); DbParameter parameter; if (translator.MemberValues.TryGetValue(member, out parameter)) { commandText.Append(parameter.ParameterName); } else { if (flag) { throw ADP1.NotSupported(ADP1.Update_NotSupportedServerGenKey(target.Name)); } if (!IsValidIdentityColumnType(member.TypeUsage)) { throw ADP1.InvalidOperation(ADP1.Update_NotSupportedIdentityType(member.Name, member.TypeUsage.ToString())); } commandText.Append("CAST (@@IDENTITY AS ") .Append(member.TypeUsage.EdmType.Name) .Append(")"); flag = true; } return flag; }
// <summary> // Generates SQL fragment returning server-generated values. // Requires: translator knows about member values so that we can figure out // how to construct the key predicate. // <code>Sample SQL: // // select IdentityValue // from MyTable // where IdentityValue = @@identity // // NOTE: not scope_identity() because we don't support it.</code> // </summary> // <param name="commandText"> Builder containing command text </param> // <param name="tree"> Modification command tree </param> // <param name="translator"> Translator used to produce DML SQL statement for the tree </param> // <param name="returning"> Returning expression. If null, the method returns immediately without producing a SELECT statement. </param> private static void GenerateReturningSql( SqlStringBuilder commandText, DbModificationCommandTree tree, ExpressionTranslator translator, DbExpression returning) { if (returning != null) { commandText.AppendKeyword("select "); returning.Accept(translator); commandText.AppendLine(); commandText.AppendKeyword("from "); tree.Target.Expression.Accept(translator); commandText.AppendLine(); commandText.AppendKeyword("where "); var target = ((DbScanExpression)tree.Target.Expression).Target; var flag = false; var isFirst = true; foreach (var member in target.ElementType.KeyMembers) { if (!isFirst) { commandText.AppendKeyword(" and "); } else { isFirst = false; } commandText.Append(GenerateMemberTSql(member)); commandText.Append(" = "); flag = HandleIdentity(commandText, translator, member, flag, target); } } }
internal static string[] GenerateInsertSql( DbInsertCommandTree tree, out List<DbParameter> parameters, bool isLocalProvider, bool upperCaseKeywords = true, bool createParameters = true) { var commandTexts = new List<String>(); var commandText = new SqlStringBuilder(CommandTextBuilderInitialCapacity) { UpperCaseKeywords = upperCaseKeywords }; var translator = new ExpressionTranslator( commandText, tree, null != tree.Returning, isLocalProvider, createParameters); // insert [schemaName].[tableName] commandText.AppendKeyword("insert "); tree.Target.Expression.Accept(translator); if (0 < tree.SetClauses.Count) { // (c1, c2, c3, ...) commandText.Append("("); var first = true; foreach (DbSetClause setClause in tree.SetClauses) { if (first) { first = false; } else { commandText.Append(", "); } setClause.Property.Accept(translator); } commandText.AppendLine(")"); // values c1, c2, ... first = true; commandText.AppendKeyword("values ("); foreach (DbSetClause setClause in tree.SetClauses) { if (first) { first = false; } else { commandText.Append(", "); } setClause.Value.Accept(translator); translator.RegisterMemberValue(setClause.Property, setClause.Value); } commandText.AppendLine(")"); } else { // default values throw ADP1.NotSupported("Default values not supported"); } commandTexts.Add(commandText.ToString()); commandText.Length = 0; // generate returning sql GenerateReturningSql(commandText, tree, translator, tree.Returning); if (!String.IsNullOrEmpty(commandText.ToString())) { commandTexts.Add(commandText.ToString()); } parameters = translator.Parameters; return commandTexts.ToArray(); }
internal static string[] GenerateDeleteSql( DbDeleteCommandTree tree, out List<DbParameter> parameters, bool isLocalProvider, bool upperCaseKeywords = true, bool createParameters = true) { var commandTexts = new List<String>(); var commandText = new SqlStringBuilder(CommandTextBuilderInitialCapacity) { UpperCaseKeywords = upperCaseKeywords }; var translator = new ExpressionTranslator( commandText, tree, false, isLocalProvider, createParameters); // delete [schemaName].[tableName] commandText.AppendKeyword("delete "); tree.Target.Expression.Accept(translator); commandText.AppendLine(); // where c1 = ... AND c2 = ... commandText.AppendKeyword("where "); tree.Predicate.Accept(translator); commandTexts.Add(commandText.ToString()); commandText.Length = 0; parameters = translator.Parameters; return commandTexts.ToArray(); }
public void HandlIdentity_throws_for_multiple_identity_type() { var typeUsage = ProviderRegistry.SqlCe4_ProviderManifest.GetStoreType( TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))); var mockMember = new Mock<EdmMember>(); mockMember.Setup(m => m.TypeUsage).Returns(typeUsage); var mockTransalator = new Mock<DmlSqlGenerator.ExpressionTranslator>(); mockTransalator.Setup(m => m.MemberValues).Returns(new Dictionary<EdmMember, DbParameter>()); var builder = new SqlStringBuilder(); var mockSet = new Mock<EntitySetBase>(); mockSet.Setup(m => m.Name).Returns("Pickle"); Assert.Equal( ADP1.Update_NotSupportedServerGenKey("Pickle"), Assert.Throws<NotSupportedException>( () => DmlSqlGenerator.HandleIdentity( builder, mockTransalator.Object, mockMember.Object, true, mockSet.Object)).Message); }