/// <summary> /// Formata o texto de uma <see cref="QueryInfo" /> /// </summary> /// <param name="queryInfo"></param> /// <param name="ignoreContainerFormat">Identifica que é para ignorar a formatação de de container para a consulta.</param> /// <returns></returns> private DefaultSqlQueryParser Format(QueryInfo queryInfo, bool ignoreContainerFormat = false) { var parser = new DefaultSqlQueryParser(this.Translator, this.TypeSchema, _takeParametersParser) { Owner = this, UseTakeParameter = true }; parser.Query = queryInfo; foreach (var parameter in queryInfo.Parameters) { if (!this.Query.Parameters.Any(f => f.Name == parameter.Name)) { this.Query.Parameters.Add(parameter); } } if (!ignoreContainerFormat) { Append('('); } Append(parser.GetText()); if (!ignoreContainerFormat) { Append(')'); } return(this); }
/// <summary> /// Adiciona ao campo string builder o texto correspondente a parte SELECT da query /// </summary> /// <returns>Retorna o próprio objeto</returns> private DefaultSqlQueryParser SelectParser() { if (Query.IsSelectDistinct) { Append("SELECT DISTINCT "); } else { Append("SELECT "); } if (Query.Entities == null) { throw new InvalidOperationException(string.Format("Not found entities in query '{0}'", Query)); } ITypeMetadata mainTypeMetadata = null; for (int i = 0; i < Query.Entities.Length; i++) { if (string.IsNullOrEmpty(Query.Entities[i].FullName)) { continue; } ITypeMetadata typeMetadata = null; if (!Query.IgnoreTypeSchema) { typeMetadata = TypeSchema.GetTypeMetadata(Query.Entities[i].FullName); if (typeMetadata == null) { throw new InvalidOperationException(ResourceMessageFormatter.Create(() => Properties.Resources.InvalidOperationException_TypeMetadataNotFoundByFullName, Query.Entities[i].FullName).Format()); } } if (i == 0) { mainTypeMetadata = typeMetadata; if (string.IsNullOrEmpty(Query.Entities[i].Alias)) { Query.Entities[i].Alias = "main"; } } else if (string.IsNullOrEmpty(Query.Entities[i].Alias)) { Query.Entities[i].Alias = "main" + i.ToString(); } } EntityInfo entity = Query.Entities[0]; if (!string.IsNullOrEmpty(entity.FullName)) { if (Query.Projection == null) { if (mainTypeMetadata != null && mainTypeMetadata.IsVersioned) { Query.HasRowVersion = true; } var properties = mainTypeMetadata != null?mainTypeMetadata.Where(f => f.Direction == Data.Schema.DirectionParameter.Input || f.Direction == Data.Schema.DirectionParameter.InputOutput).ToArray() : new IPropertyMetadata[0]; if (properties.Length == 0) { throw new InvalidOperationException(ResourceMessageFormatter.Create(() => Properties.Resources.InvalidOperationException_NotFoundPropertiesForTypeMetadata, entity.FullName).Format()); } Query.Projection = new Projection(); for (var i = 0; i < properties.Length; i++) { var prop = properties[i]; Query.Projection.Add(new ProjectionEntry(string.Format("{0}.{1}", entity.Alias, prop.Name), prop.Name)); var translateName = Translator.GetName(entity, prop.Name, Query.IgnoreTypeSchema); var translateColumnName = translateName as TranslatedColumnName; if (translateColumnName != null) { if (!string.IsNullOrEmpty(translateColumnName.TableAlias)) { AppendQuoteExpression(translateColumnName.TableAlias).Append('.'); } AppendQuoteExpression(translateColumnName.Name); } if (prop.ColumnName != prop.Name) { Append(" AS ").AppendQuoteExpression(FormatProjectionAlias(prop.Name)); } if (i + 1 < properties.Length) { Append(','); } } Append(' '); } else { ProjectionParser(); } if (Query.HasRowVersion) { Append(", ").Append("CAST(").Append(Query.Entities[0].Alias).Append(".[").Append(DataAccessConstants.RowVersionColumnName).Append("] AS BIGINT) AS [").Append(DataAccessConstants.RowVersionColumnName).Append("] "); } var tableName = Translator.GetName(entity, Query.IgnoreTypeSchema); if (tableName == null) { throw new InvalidOperationException(string.Format("Not found table name for entity '{0}'", entity.FullName)); } Append("FROM ").AppendTranslatedName(tableName).Append(' ').AppendQuoteExpression(entity.Alias).Append(' '); } else { var sqlParser = new DefaultSqlQueryParser(Translator, TypeSchema, _takeParametersParser) { Query = entity.SubQuery, UseTakeParameter = true }; var subQueryText = sqlParser.GetText(); if (Query.Projection == null) { Query.Projection = new Projection(); foreach (var column in entity.SubQuery.Projection) { Query.Projection.Add(new ProjectionEntry(!string.IsNullOrEmpty(entity.Alias) ? string.Format("{0}.{1}", entity.Alias, string.IsNullOrEmpty(column.Alias) ? (string.IsNullOrEmpty(column.GetColumnInfo().Alias) ? column.GetColumnInfo().Name : column.GetColumnInfo().Alias) : column.Alias) : column.Alias, column.Alias)); } } ProjectionParser(); Append("FROM (").Append(subQueryText).Append(") ").AppendQuoteExpression(entity.Alias); } return(this); }
/// <summary> /// Método responsável por gerar comandos de atualização /// </summary> private string UpdateParser() { var sqlCommand = new StringBuilder(); var typeMetadata = TypeSchema.GetTypeMetadata(Action.EntityFullName); var keyProperties = typeMetadata.GetKeyProperties(); var wherePart = new StringBuilder(); var setPart = new StringBuilder(); EntityInfo info = null; if (Action.Query != null) { info = Action.Query.Entities.FirstOrDefault(); QueryParser = new Colosoft.Query.Database.DefaultSqlQueryParser(Translator, TypeSchema, TakeParametersParser); QueryParser.Query = Action.Query; Append("UPDATE ", sqlCommand).AppendTranslatedName(Translator.GetName(info), sqlCommand).Append(' ', sqlCommand).AppendQuoteExpression(info.Alias, sqlCommand).Append(' ', sqlCommand).Append(QueryParser.GetText(SqlQueryPart.Joins | SqlQueryPart.Joins), sqlCommand).Append(" SET ", sqlCommand); foreach (var parameter in Query.QueryParameter.GetParameters(Action.Query, true)) { if (!this.Action.Parameters.Any(f => f.Name == parameter.Name)) { this.Action.Parameters.Add(new PersistenceParameter(parameter.Name, parameter.Value, parameter.Direction)); } } } else { info = GetEntityInfo(Action.EntityFullName); Append("UPDATE ", sqlCommand).AppendTranslatedName(Translator.GetName(info), sqlCommand).Append(" SET ", sqlCommand); } bool isFirstWhere = true; bool isFirstSet = true; Tuple <int, IPropertyMetadata> identityKeyIndex = null; var keysIndex = new List <Tuple <int, IPropertyMetadata> >(); for (int i = 0; i < Action.Parameters.Count; i++) { var parameter = Action.Parameters[i]; if (string.IsNullOrEmpty(parameter.Name) || parameter.Name.StartsWith("?")) { continue; } var propertyMetadata = typeMetadata[parameter.Name]; if (propertyMetadata == null) { throw new Exception(string.Format("Property {0} not found", parameter.Name)); } var translatedName = Translator.GetName(info, propertyMetadata.Name); SetParameterType(propertyMetadata, parameter); if (propertyMetadata.ParameterType == PersistenceParameterType.IdentityKey || propertyMetadata.ParameterType == PersistenceParameterType.Key) { if (Action.Conditional != null) { continue; } if (propertyMetadata.ParameterType == PersistenceParameterType.IdentityKey) { identityKeyIndex = new Tuple <int, IPropertyMetadata>(i, propertyMetadata); } else if (propertyMetadata.ParameterType == PersistenceParameterType.Key) { keysIndex.Add(new Tuple <int, IPropertyMetadata>(i, propertyMetadata)); } if (!isFirstWhere) { Append(" AND ", wherePart); } else { isFirstWhere = false; } if (translatedName is TranslatedColumnName) { if (!string.IsNullOrEmpty(info.Alias)) { AppendQuoteExpression(info.Alias, sqlCommand).Append('.', sqlCommand); } AppendTranslatedName(translatedName, wherePart); } else if (propertyMetadata.Name == Query.DataAccessConstants.RowVersionPropertyName) { AppendQuoteExpression(Query.DataAccessConstants.RowVersionColumnName, wherePart); } else { throw new InvalidOperationException("Expected ColumnName for property \"" + propertyMetadata.Name + "\""); } Append("=?", wherePart).Append(propertyMetadata.Name, wherePart); continue; } if (!isFirstSet) { Append(',', setPart); } else { isFirstSet = false; } if (translatedName is TranslatedColumnName) { if (!string.IsNullOrEmpty(info.Alias)) { AppendQuoteExpression(info.Alias, sqlCommand).Append('.', sqlCommand); } AppendTranslatedName(translatedName, setPart); } else if (propertyMetadata.Name == Query.DataAccessConstants.RowVersionPropertyName) { AppendQuoteExpression(Query.DataAccessConstants.RowVersionColumnName, setPart); } else { throw new InvalidOperationException("Expected ColumnName for property \"" + propertyMetadata.Name + "\""); } Append("=", setPart); if (parameter.Value is PropertyReference) { var propertyReference = (PropertyReference)parameter.Value; var propertyTranslateName = Translator.GetName(info, propertyReference.PropertyName); if (translatedName is TranslatedColumnName) { AppendTranslatedName(translatedName, setPart); } else { throw new InvalidOperationException("Expected ColumnName for property \"" + propertyReference.PropertyName + "\""); } } else if (parameter.Value is ExpressionParameter) { var expressionParameter = (ExpressionParameter)parameter.Value; var expressionContainer = Colosoft.Query.ConditionalContainer.Parse(expressionParameter.Expression, expressionParameter.Parameters.Select(f => new QueryParameter(f.Name, f.Value)).ToArray()); Format(expressionContainer, setPart); } else if (parameter.Value is Colosoft.Query.Queryable) { var queryInfo = ((Colosoft.Query.Queryable)parameter.Value).CreateQueryInfo(); Format(queryInfo, setPart); } else if (parameter.Value is QueryInfo) { var queryInfo = (QueryInfo)parameter.Value; Format(queryInfo, setPart); } else { Append("?", setPart).Append(propertyMetadata.Name, setPart); } } if (Action.Conditional != null) { Format(Action.Conditional, wherePart); } else if (Action.Query != null) { Format(Action.Query.WhereClause, wherePart); } Append(' ', setPart); if (Action.Query != null) { Append(setPart, sqlCommand).Append(QueryParser.GetText(SqlQueryPart.Where), sqlCommand).Append(wherePart, sqlCommand); } else { Append(setPart, sqlCommand).Append(" WHERE ", sqlCommand).Append(wherePart, sqlCommand); } if (Action.Conditional == null && Action.Query == null) { if (identityKeyIndex != null) { keysIndex.Clear(); keysIndex.Add(identityKeyIndex); } if (typeMetadata.IsVersioned && keysIndex.Count > 0) { AppendVerifyRowVersionExpression(sqlCommand); } AppendGetRowVersionAndVolatilePropertiesExpression(info, keysIndex, typeMetadata, sqlCommand); } return(sqlCommand.ToString()); }