public void TypeAnalysis_CLRType_Int64() { // create syntax tree var syntaxTree = CSharpSyntaxTree.ParseText(@" public class Test { public long Id { get; set; } }"); // create compilation var compilation = RoslynTestHelpers.CreateTestCompilation(new[] { syntaxTree }); // extract symbol var typeSymbol = RoslynTestHelpers.ExtractPropertyType(compilation, syntaxTree); // analyze var context = new TestAnalysisContext(compilation); var analyzer = new TypeAnalyzer(context); var csTypeModel = analyzer.AnalyzeType(typeSymbol); // assert var expected = new CSharpTypeModel() { Name = "Int64", TypeKind = CSharpTypeKind.Struct, SpecialType = CSharpSpecialType.System_Int64 }; Assert.AreEqual(expected.Name, csTypeModel.Name); Assert.AreEqual(expected.TypeKind, csTypeModel.TypeKind); Assert.AreEqual(expected.SpecialType, csTypeModel.SpecialType); }
public virtual void ProcessDeleteRequest <T>(CommandDefinition <T> commandDefinition) where T : class { var type = CheckCommandConditions(commandDefinition, "delete"); var entityTypeResult = EntityCache.GetEntity(type) ?? TypeAnalyzer.AnalyzeType(type); var keyColumns = GetKeyColumns(type); if (!keyColumns.Any()) { throw new ArgumentException("At least one key column property must be defined."); } var sql = new StringBuilder(); var parameters = new List <KeyValuePair <string, object> >(); sql.Append("DELETE FROM "); sql.AppendLine(entityTypeResult.TableName); AppendWhereCondition(new WhereCondition { Query = sql, TableName = entityTypeResult.TableName, Parameters = parameters, Properties = keyColumns }, commandDefinition.Entity); commandDefinition.UpdateCommand(sql.ToString(), parameters); }
private object CreateEmptyInstance(Type type) { var entity = EntityCache.GetEntity(type) ?? TypeAnalyzer.AnalyzeType(type); var instance = Activator.CreateInstance(type); foreach (var property in entity.GetProperties()) { if (property.IsOwnsOne) { property.PropertyInfo.SetValue(instance, CreateEmptyInstance(property.Type)); } } return instance; }
public CSharpClassModel AnalyzeClassSymbol(INamedTypeSymbol classSymbol) { var classModel = new CSharpClassModel() { Name = classSymbol.Name }; var members = classSymbol.GetMembers().ToList(); HandleInheritance(classModel, classSymbol); HandleGenerics(classModel, classSymbol); HandleDependencies(classModel, classSymbol); var properties = members.Where(m => m.Kind == SymbolKind.Property).ToList(); foreach (var property in properties) { var propertySymbol = property as IPropertySymbol; // for generic types we want to generate the interface instead of the specific, substituted property types if (!propertySymbol.OriginalDefinition.Equals(propertySymbol)) { propertySymbol = propertySymbol.OriginalDefinition; } var propertyModel = new CSharpPropertyModel() { Name = propertySymbol.Name, Type = _typeAnalyzer.AnalyzeType(propertySymbol.Type) }; classModel.Properties.Add(propertyModel); } return(classModel); }
public virtual void ProcessInsertRequest <T>(CommandDefinition <T> commandDefinition) where T : class { var type = CheckCommandConditions(commandDefinition, "insert"); var entityTypeResult = EntityCache.GetEntity(type) ?? TypeAnalyzer.AnalyzeType(type); if (!entityTypeResult.HasPrimaryKey()) { throw new ArgumentException("At least one key column property must be defined."); } var properties = GetProperties(new PropertyRequest { Type = type, Entity = commandDefinition.Entity }); var sql = new StringBuilder(); var sqlColumns = new StringBuilder(); var sqlValues = new StringBuilder(); var parameters = new List <KeyValuePair <string, object> >(); var firstColumn = true; foreach (var property in properties) { if (firstColumn) { firstColumn = false; } else { sqlColumns.Append(","); sqlValues.Append(","); } sqlColumns.Append($"["); sqlValues.Append("@"); if (!property.Prefix.IsNullOrEmpty()) { sqlColumns.Append(property.Prefix); sqlValues.Append(property.Prefix); } sqlColumns.Append($"{property.ColumnName}]"); sqlValues.Append(property.PropertyInfo.Name); parameters.Add(new KeyValuePair <string, object>($"{property.Prefix}{property.PropertyInfo.Name}", property.PropertyInfo.GetValue(property.Entity))); } sql.Append("INSERT INTO "); sql.Append(entityTypeResult.TableName); sql.Append("("); sql.Append(sqlColumns.ToString()); sql.AppendLine(")"); sql.Append("VALUES ("); sql.Append(sqlValues.ToString()); sql.AppendLine(");"); if (entityTypeResult.HasAutoGeneratedPrimaryKey()) { sql.AppendLine(GetLastInsertedPrimaryKeyQuery()); } else { sql.Append("SELECT @"); sql.Append(entityTypeResult.GetFirstPrimaryKey().Name); sql.AppendLine(";"); } commandDefinition.UpdateCommand(sql.ToString(), parameters); }
public virtual void ProcessUpdateRequest <T>(CommandDefinition <T> commandDefinition, object partialEntity = null, IEnumerable <KeyValuePair <string, object> > patchProperties = null) where T : class { var type = CheckCommandConditions(commandDefinition, "update", partialEntity, patchProperties); var entityTypeResult = EntityCache.GetEntity(type) ?? TypeAnalyzer.AnalyzeType(type); var keyColumns = GetKeyColumns(type, partialEntity?.GetType(), patchProperties?.Select(p => p.Key).ToList()); if (!keyColumns.Any()) { throw new ArgumentException("At least one key column property must be defined."); } if (partialEntity != default || patchProperties != default) { commandDefinition.Entity = ObjectGenerator.CreateEmptyInstance <T>(); } var properties = GetProperties(new PropertyRequest { Type = type, Entity = commandDefinition.Entity, PartialEntity = partialEntity, PatchProperties = patchProperties }); var sql = new StringBuilder(); var parameters = new List <KeyValuePair <string, object> >(); sql.Append("UPDATE "); sql.AppendLine(entityTypeResult.TableName); sql.AppendLine(" SET"); var firstColumn = true; foreach (var property in properties) { if (SkipPropertyForUpdate(property, keyColumns)) { continue; } sql.Append("\t"); if (firstColumn) { firstColumn = false; sql.Append(" "); } else { sql.Append(","); } sql.Append($"["); if (!property.Prefix.IsNullOrEmpty()) { sql.Append(property.Prefix); } sql.Append($"{property.ColumnName}]"); sql.Append(" = @"); if (!property.Prefix.IsNullOrEmpty()) { sql.Append(property.Prefix); } if (property.PropertyInfo == default && property.Entity?.GetType() == _patchPropertyType) { sql.AppendLine(property.ColumnName); parameters.Add(new KeyValuePair <string, object>($"{property.Prefix}{property.ColumnName}", ((KeyValuePair <string, object>)property.Entity).Value)); continue; } sql.AppendLine(property.PropertyInfo?.Name); parameters.Add(new KeyValuePair <string, object>($"{property.Prefix}{property.PropertyInfo.Name}", property.PropertyInfo.GetValue(property.Entity))); } AppendWhereCondition(new WhereCondition { Query = sql, TableName = entityTypeResult.TableName, Parameters = parameters, Properties = keyColumns }, partialEntity ?? commandDefinition.Entity, patchProperties); commandDefinition.UpdateCommand(sql.ToString(), parameters); }
public CSharpControllerModel AnalyzeController(INamedTypeSymbol classSymbol, bool isDotNetCore) { var controllerModel = new CSharpControllerModel(); controllerModel.Name = ControllerHelper.ExtractControllerName(classSymbol.Name); var classAttributes = classSymbol.GetAttributes(); if (!classAttributes.IsDefaultOrEmpty) { // .net core projects use Route attribute on controllers instead of RoutePrefix var routePrefix = isDotNetCore ? AttributeHelper.GetRoute(classAttributes) : AttributeHelper.GetRoutePrefix(classAttributes); if (!string.IsNullOrEmpty(routePrefix)) { controllerModel.RoutePrefix = routePrefix; } } var methodSymbols = ControllerHelper.GetPublicMethods(classSymbol); foreach (var methodSymbol in methodSymbols) { var methodModel = new CSharpControllerMethodModel(); methodModel.Name = methodSymbol.Name; var methodAttributes = methodSymbol.GetAttributes(); if (!methodAttributes.IsDefaultOrEmpty) { var httpMethod = AttributeHelper.DetermineHttpMehod(methodAttributes); if (httpMethod.HasValue) { methodModel.HttpMethod = httpMethod.Value; } var route = AttributeHelper.GetRoute(methodAttributes); if (!string.IsNullOrEmpty(route)) { methodModel.Route = route; } } methodModel.ReturnType = _typeAnalyzer.AnalyzeType(methodSymbol.ReturnType); var parameters = methodSymbol.Parameters.ToList(); foreach (var parameter in parameters) { methodModel.Parameters.Add(new Tuple <CSharpTypeModel, string>(_typeAnalyzer.AnalyzeType(parameter.Type), parameter.Name)); } controllerModel.Methods.Add(methodModel); } var dependencies = GetDependencies(classSymbol); foreach (var dependency in dependencies) { controllerModel.Dependencies.Add(new CSharpDependencyModel() { Name = dependency.Name, Namespace = dependency.ContainingNamespace.ToString(), DependencyKind = dependency.TypeKind == TypeKind.Class ? DependencyKind.Model : DependencyKind.Enum }); } return(controllerModel); }
private void PreProcessProperties(PreProcessPropertyInformation information) { information.Entity = information.Entity ?? EntityCache.GetEntity(information.Instance.GetType()) ?? TypeAnalyzer.AnalyzeType(information.Instance.GetType()); foreach (var property in information.Entity.GetProperties()) { if (property.IsOwnsOne) { var ownsOneInstance = Activator.CreateInstance(property.Type); property.PropertyInfo.SetValue(information.Instance, ownsOneInstance); PreProcessProperties(new PreProcessPropertyInformation { ReaderAccessItems = information.ReaderAccessItems, Instance = ownsOneInstance, RequestedTableNames = information.RequestedTableNames, ColumnPrefix = property.ColumnName.ToLower() + "_", Entity = property.OwnsOne }); } var columnName = information.ColumnPrefix + property.ColumnName.ToLower(); CollectOrdinal(property, information, columnName); } }