/// <summary> /// Analyse the AST /// </summary> /// <param name="node">the parsed AST / transformed.</param> /// <param name="modelDatabase">the model</param> /// <returns>think of</returns> public List <AnalyseResult> Analyse(SqlNode node, ModelSqlDatabase modelDatabase) { var scopeNameResolverContext = new ScopeNameResolverContext(modelDatabase); var dbScope = SqlCodeScope.CreateRoot(scopeNameResolverContext); var bindVisitor = new AnalyseVisitor(dbScope); bindVisitor.Logger = this.Logger; var result = bindVisitor.Run(node); return(result); }
/// <summary> /// Analyse the sql Code /// </summary> /// <param name="sqlCode">the sql code to analyse.</param> /// <param name="modelDatabase">The model datavase</param> /// <returns>the analyse results</returns> public List <AnalyseResult> Analyse(string sqlCode, ModelSqlDatabase modelDatabase) { var astUtiltiy = (new OfaSchlupfer.MSSQLReflection.AST.AstUtility() { ParserVersion = this.ParserVersion, InitialQuotedIdentifiers = this.InitialQuotedIdentifiers }); var fragment = astUtiltiy.Parse(sqlCode); if (fragment == null) { return(null); } var node = astUtiltiy.Transport(fragment); return(this.Analyse(node, modelDatabase)); }
public void BuildModelSqlDatabase( ModelSchema modelSchema, ModelSqlDatabase modelDatabase, MetaModelBuilder metaModelBuilder, ModelErrors errors) { foreach (var modelEntitySource in modelSchema.Entities) { var modelEntityTypeSource = modelEntitySource.EntityType; if (modelEntityTypeSource is null) { #warning SOON add error } else { var tableNameTarget = modelEntitySource.ExternalName ?? modelEntitySource.Name; var sqlTableNameTarget = SqlName.Parse(tableNameTarget, ObjectLevel.Object); var tableTarget = ModelSqlTable.Ensure(modelDatabase, sqlTableNameTarget); foreach (var property in modelEntityTypeSource.Properties) { var sqlColumnNameTarget = SqlName.Parse(property.ExternalName ?? property.Name, ObjectLevel.Object); ModelSqlColumn column = ModelSqlColumn.Ensure(tableTarget, sqlColumnNameTarget.Name); if (property.Type is ModelScalarType propertyScalarType) { var clrTypeSource = property.GetClrType(); var typeName = propertyScalarType.Name; #warning TODO SOON better Scalar Type Handling this is ugly if (!(clrTypeSource is null)) { var innerNullableClrTypeSource = ((clrTypeSource.IsValueType) ? Nullable.GetUnderlyingType(clrTypeSource) : null) ?? clrTypeSource; if (!(column.SqlType is null)) { var clrScalarTypeTarget = column.SqlType.GetScalarType()?.GetClrType(); var innerNullableClrScalarTypeTarget = ((clrScalarTypeTarget.IsValueType) ? Nullable.GetUnderlyingType(clrScalarTypeTarget) : null) ?? clrScalarTypeTarget; if (!(clrScalarTypeTarget is null) && (clrScalarTypeTarget.IsAssignableFrom(innerNullableClrScalarTypeTarget))) { // ok } else { column.SqlType = null; } } } if (column.SqlType is null) { var sqlTypeTarget = modelDatabase.Types.GetValueOrDefault(SqlName.Parse(typeName, ObjectLevel.Object)); if (!(sqlTypeTarget is null)) { column.SqlType = sqlTypeTarget; } else { if (!(clrTypeSource is null)) { var innerNullableClrTypeSource = ((clrTypeSource.IsValueType) ? Nullable.GetUnderlyingType(clrTypeSource) : null) ?? clrTypeSource; var lstTypes = new List <ModelSqlType>(); foreach (var type in modelDatabase.Types) { var clrScalarTypeTarget = type.GetScalarType()?.GetClrType(); if (clrScalarTypeTarget is null) { continue; } var innerNullableClrScalarTypeTarget = ((clrScalarTypeTarget.IsValueType) ? Nullable.GetUnderlyingType(clrScalarTypeTarget) : null) ?? clrScalarTypeTarget; if (innerNullableClrTypeSource.Equals(innerNullableClrScalarTypeTarget)) { lstTypes.Add(type); } else if (innerNullableClrTypeSource.IsAssignableFrom(innerNullableClrScalarTypeTarget)) { lstTypes.Add(type); } } if (lstTypes.Count == 1) { sqlTypeTarget = lstTypes[0]; column.SqlType = sqlTypeTarget; } else if (lstTypes.Count > 1) { sqlTypeTarget = null; if (clrTypeSource == typeof(string)) { sqlTypeTarget = modelDatabase.Types.GetValueOrDefault(SqlName.Parse("[sys].[nvarchar]", ObjectLevel.Object)); } else if (clrTypeSource == typeof(DateTime)) { sqlTypeTarget = modelDatabase.Types.GetValueOrDefault(SqlName.Parse("[sys].[datetime2]", ObjectLevel.Object)); } else if (clrTypeSource == typeof(DateTime?)) { sqlTypeTarget = modelDatabase.Types.GetValueOrDefault(SqlName.Parse("[sys].[datetime2]", ObjectLevel.Object)); } if (sqlTypeTarget is null) { sqlTypeTarget = lstTypes[0]; } column.SqlType = sqlTypeTarget; } else { errors.Add(new ModelErrorInfo($"Unknown mapping for {typeName} - {clrTypeSource}.", column.NameSql)); sqlTypeTarget = modelDatabase.Types.GetValueOrDefault(SqlName.Parse("[sys].[nvarchar]", ObjectLevel.Object)); column.SqlType = sqlTypeTarget; } } } sqlTypeTarget = column.SqlType; if (sqlTypeTarget is null) { errors.Add(new ModelErrorInfo($"column.SqlType is null.", column.NameSql)); } else { sqlTypeTarget.Nullable = propertyScalarType.Nullable.GetValueOrDefault(true); if (propertyScalarType.MaxLength.HasValue) { sqlTypeTarget.MaxLength = propertyScalarType.MaxLength; } else { //if (typeof(string).Equals(sqlTypeTarget.GetScalarType().GetClrType())) { // sqlTypeTarget.MaxLength = -1; //} } } } // if (column.SqlType is null) }
public void BuildModelSchema( ModelSqlDatabase modelDatabase, ModelSchema modelSchema, MetaModelBuilder metaModelBuilder, ModelErrors errors) { if (modelSchema == null) { modelSchema = new ModelSchema(); } if (metaModelBuilder == null) { metaModelBuilder = new MetaModelBuilder(); } // modelDatabase.Freeze(); foreach (var table in modelDatabase.Tables) { var entityTypeModelName = table.Name.GetQFullName(null, 2); var entityTypeModelFullName = table.Name.GetQFullName("[", 2); var modelComplexType = metaModelBuilder.CreateModelComplexType( entityTypeModelName, entityTypeModelFullName, errors); if (modelComplexType.Owner == null) { modelSchema.ComplexTypes.Add(modelComplexType); } foreach (var column in table.Columns) { ModelScalarType modelScalarType = null; ModelScalarType suggestedType = column.SuggestType(metaModelBuilder); modelScalarType = metaModelBuilder.CreateModelScalarType( entityTypeModelName, entityTypeModelFullName, column.Name.GetQName(), null, column.SqlType.Name.GetQFullName(), suggestedType, column.MaxLength, column.FixedLength, column.Nullable, column.Precision, column.Scale, errors ); var columnName = column.Name.GetQFullName(null, 1); var columnExternalName = column.Name.GetQFullName("[", 1); var modelProperty = metaModelBuilder.CreateModelProperty( entityTypeModelName, entityTypeModelFullName, columnName, columnExternalName, errors ); if (modelProperty.Type == null) { modelProperty.Type = modelScalarType; } if (modelProperty.Owner == null) { modelComplexType.Properties.Add(modelProperty); } } var tableIndexes = table.Indexes.ToList(); var lstPrimaryIndex = tableIndexes.Where(sqlIndex => sqlIndex.IsPrimaryKey).ToList(); var primaryIndex = lstPrimaryIndex.FirstOrDefault(); if (lstPrimaryIndex.Count == 1) { //var sqlIndex = lstPrimaryIndex[0]; // OK } else if (lstPrimaryIndex.Count > 1) { errors.AddErrorOrThrow($"More than one ({lstPrimaryIndex.Count}) primary key.", table.NameSql); } else { #warning think of no primary key } foreach (var sqlIndex in tableIndexes) { #warning have indexes a schema?? var modelIndex = metaModelBuilder.CreateModelIndex(entityTypeModelName, entityTypeModelFullName, sqlIndex.Name.Name, sqlIndex.Name.Name, errors); //modelIndex.IsPrimaryKey = sqlIndex.IsPrimaryKey; modelIndex.IsPrimaryKey = ReferenceEquals(sqlIndex, primaryIndex); modelComplexType.Indexes.Add(modelIndex); foreach (var column in sqlIndex.Columns) { var modelIndexProperty = metaModelBuilder.CreateModelIndexProperty( entityTypeModelName, entityTypeModelFullName, sqlIndex.Name.Name, sqlIndex.Name.Name, column.Name.Name, null, errors ); modelIndex.Properties.Add(modelIndexProperty); } } var entitySetName = table.Name.GetQFullName(null, 2); var modelEntity = metaModelBuilder.CreateModelEntity( entitySetName, ModelEntityKind.EntitySet, errors); if (modelEntity.Owner == null) { modelSchema.Entities.Add(modelEntity); } modelEntity.EntityType = modelComplexType; } }