From 4ac502a3d7664e35fc1eaa68e53b2aadd45be526 Mon Sep 17 00:00:00 2001 From: Vasiliy Chernoivan Date: Thu, 24 May 2018 17:15:41 +0500 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B4?= =?UTF-8?q?=D0=B6=D0=BE=D0=B9=D0=BD=D1=8B=20=D0=BF=D0=BE=20=D0=BE=D0=B1?= =?UTF-8?q?=D0=BB=D0=B0=D1=81=D1=82=D0=B8=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D1=85.=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D1=8F=D0=B5?= =?UTF-8?q?=D0=BC=20=D0=92=D0=B5=D1=80=D1=81=D0=B8=D1=8E=D0=94=D0=B0=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D1=85=20=D0=BD=D0=B0=20=D0=BA=D0=B0=D0=B6=D0=B4?= =?UTF-8?q?=D1=8B=D0=B9=20inMemoryDataContext.Save?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Simple1C/Impl/InMemoryDataContext.cs | 12 ++ .../Sql/Translation/QueryToSqlTranslator.cs | 4 +- .../Visitors/AddAreaToJoinConditionVisitor.cs | 10 +- .../Visitors/QueryFunctionRewriter.cs | 121 +++++++++++------- Tests/Sql/BasicTest.cs | 26 ++++ 5 files changed, 118 insertions(+), 55 deletions(-) diff --git a/Simple1C/Impl/InMemoryDataContext.cs b/Simple1C/Impl/InMemoryDataContext.cs index 0049f32..75a62fa 100644 --- a/Simple1C/Impl/InMemoryDataContext.cs +++ b/Simple1C/Impl/InMemoryDataContext.cs @@ -67,6 +67,7 @@ private InMemoryEntity Save(Abstract1CEntity entity, bool isTableSection) { if (entity == null) return null; + var changed = entity.Controller.Changed; if (changed != null) { @@ -97,6 +98,11 @@ private InMemoryEntity Save(Abstract1CEntity entity, bool isTableSection) inMemoryEntity = inmemoryEntityRevision.inMemoryEntity; if (changed != null) { + var configurationName = ConfigurationName.Get(entity.GetType()); + if (configurationName.Scope == ConfigurationScope.Документы) + { + AssignNewGuid(entity, changed, "ВерсияДанных"); + } inMemoryEntity.revision = new InMemoryEntityRevision(inMemoryEntity, inmemoryEntityRevision, changed); Collection(entity.GetType()).revision++; } @@ -113,9 +119,15 @@ private InMemoryEntity Save(Abstract1CEntity entity, bool isTableSection) { var configurationName = ConfigurationName.Get(entity.GetType()); if (configurationName.Scope == ConfigurationScope.Справочники) + { AssignNewGuid(entity, changed, "Код"); + AssignNewGuid(entity, changed, "ВерсияДанных"); + } else if (configurationName.Scope == ConfigurationScope.Документы) + { AssignNewGuid(entity, changed, "Номер"); + AssignNewGuid(entity, changed, "ВерсияДанных"); + } if (entity.Controller.IsNew && configurationName.HasReference) { var idProperty = entity.GetType().GetProperty(EntityHelpers.idPropertyName); diff --git a/Simple1C/Impl/Sql/Translation/QueryToSqlTranslator.cs b/Simple1C/Impl/Sql/Translation/QueryToSqlTranslator.cs index c02653e..babdfb1 100644 --- a/Simple1C/Impl/Sql/Translation/QueryToSqlTranslator.cs +++ b/Simple1C/Impl/Sql/Translation/QueryToSqlTranslator.cs @@ -157,8 +157,8 @@ public override SelectClause VisitSelect(SelectClause clause) if (tableClause == null) return base.VisitSelect(clause); var tableMapping = mappingSource.ResolveTableByDbNameOrNull(tableClause.Name); - var property = tableMapping.GetByPropertyName("ОбластьДанныхОсновныеДанные"); - if (property == null) + PropertyMapping property; + if (!tableMapping.TryGetProperty("ОбластьДанныхОсновныеДанные",out property)) return base.VisitSelect(clause); var areaExpression = new InExpression { diff --git a/Simple1C/Impl/Sql/Translation/Visitors/AddAreaToJoinConditionVisitor.cs b/Simple1C/Impl/Sql/Translation/Visitors/AddAreaToJoinConditionVisitor.cs index c62032f..ef0c427 100644 --- a/Simple1C/Impl/Sql/Translation/Visitors/AddAreaToJoinConditionVisitor.cs +++ b/Simple1C/Impl/Sql/Translation/Visitors/AddAreaToJoinConditionVisitor.cs @@ -36,16 +36,12 @@ public override JoinClause VisitJoin(JoinClause clause) public override ISqlElement VisitTableDeclaration(TableDeclarationClause clause) { - contexts.Peek().MainTable = clause; + var context = contexts.Peek(); + if (context.MainTable == null) + context.MainTable = clause; return base.VisitTableDeclaration(clause); } - public override SubqueryTable VisitSubqueryTable(SubqueryTable subqueryTable) - { - contexts.Peek().MainTable = null; - return base.VisitSubqueryTable(subqueryTable); - } - public override SqlQuery VisitSqlQuery(SqlQuery sqlQuery) { contexts.Push(new Context()); diff --git a/Simple1C/Impl/Sql/Translation/Visitors/QueryFunctionRewriter.cs b/Simple1C/Impl/Sql/Translation/Visitors/QueryFunctionRewriter.cs index 3661dbb..9065032 100644 --- a/Simple1C/Impl/Sql/Translation/Visitors/QueryFunctionRewriter.cs +++ b/Simple1C/Impl/Sql/Translation/Visitors/QueryFunctionRewriter.cs @@ -157,68 +157,97 @@ public override ISqlElement VisitQueryFunction(QueryFunctionExpression expressio var tableDeclarationClause = columnReferenceExpression.Table as TableDeclarationClause; if (tableDeclarationClause == null) { - const string message = "[{0}] function not supported for subquery column reference, [{1}.{2}]. Table is of type [{3}]"; - throw new InvalidOperationException(string.Format(message, expression.KnownFunction, - columnReferenceExpression.Table.Alias, columnReferenceExpression.Name, columnReferenceExpression.Table.GetType().Name)); - } + var subqueryDeclaration = columnReferenceExpression.Table as SubqueryTable; + if (subqueryDeclaration == null) + { + const string message = + "[{0}] function not supported for a {1} " + + "column reference, [{2}.{3}]. Table is of type [{4}]"; + throw new InvalidOperationException(string.Format( + message, columnReferenceExpression.Table.GetType().Name, expression.KnownFunction, + columnReferenceExpression.Table.Alias, columnReferenceExpression.Name, + columnReferenceExpression.Table.GetType().Name)); + } - var resolvedTableMapping = mappingSource.ResolveTableByDbNameOrNull(tableDeclarationClause.Name); - if (resolvedTableMapping == null) - { - const string message = "can't find table [{0}] in column reference [{0}.{1}] for function [{2}]"; - throw new InvalidOperationException(string.Format(message, - columnReferenceExpression.Table.Alias, columnReferenceExpression.Name, - expression.KnownFunction)); - } + var columnAlias = columnReferenceExpression.Name + "_Type"; - foreach (var mapping in resolvedTableMapping.Properties) + foreach (var union in subqueryDeclaration.Query.Query.Unions) + { + AddTypeColumn(union, columnReferenceExpression, columnAlias); + } + return new ColumnReferenceExpression() + { + Name = columnAlias, + Table = columnReferenceExpression.Table + }; + } + else { - if (mapping.SingleLayout != null) + var resolvedTableMapping = mappingSource.ResolveTableByDbNameOrNull(tableDeclarationClause.Name); + if (resolvedTableMapping == null) + { + const string message = + "can't find table [{0}] in column reference [{0}.{1}] for function [{2}]"; + throw new InvalidOperationException(string.Format(message, + columnReferenceExpression.Table.Alias, columnReferenceExpression.Name, + expression.KnownFunction)); + } + + foreach (var mapping in resolvedTableMapping.Properties) { - if (mapping.SingleLayout.DbColumnName == columnReferenceExpression.Name) + if (mapping.SingleLayout != null) { - if (string.IsNullOrEmpty(mapping.SingleLayout.NestedTableName)) + if (mapping.SingleLayout.DbColumnName == columnReferenceExpression.Name) { - const string msgFormat = - "[{0}] function not supported for non-reference columns, [{1}.{2}]"; - throw new InvalidOperationException(string.Format(msgFormat, expression.KnownFunction, - columnReferenceExpression.Table.Alias, columnReferenceExpression.Name)); - } + if (string.IsNullOrEmpty(mapping.SingleLayout.NestedTableName)) + { + const string msgFormat = + "[{0}] function not supported for non-reference columns, [{1}.{2}]"; + throw new InvalidOperationException(string.Format(msgFormat, + expression.KnownFunction, + columnReferenceExpression.Table.Alias, columnReferenceExpression.Name)); + } - var byDbName = mappingSource.ResolveTableOrNull(mapping.SingleLayout.NestedTableName); - if (byDbName == null || !byDbName.Index.HasValue) - { - const string message = "can't find mapping for [{0}] following column reference " + - "[{1}.{2}] for function [{3}]"; - throw new InvalidOperationException(string.Format(message, - mapping.SingleLayout.NestedTableName, columnReferenceExpression.Table.Alias, - columnReferenceExpression.Name, expression.KnownFunction)); - } + var byDbName = mappingSource.ResolveTableOrNull(mapping.SingleLayout.NestedTableName); + if (byDbName == null || !byDbName.Index.HasValue) + { + const string message = "can't find mapping for [{0}] following column reference " + + "[{1}.{2}] for function [{3}]"; + throw new InvalidOperationException(string.Format(message, + mapping.SingleLayout.NestedTableName, columnReferenceExpression.Table.Alias, + columnReferenceExpression.Name, expression.KnownFunction)); + } - return new LiteralExpression() - { - SqlType = SqlType.ByteArray, - Value = byDbName.Index.Value - }; + return new LiteralExpression() + { + SqlType = SqlType.ByteArray, + Value = byDbName.Index.Value + }; + } } + else if (mapping.UnionLayout != null) + if (mapping.UnionLayout.ReferenceColumnName == columnReferenceExpression.Name) + return new ColumnReferenceExpression() + { + Name = mapping.UnionLayout.TableIndexColumnName, + Table = columnReferenceExpression.Table + }; } - else if (mapping.UnionLayout != null) - if (mapping.UnionLayout.ReferenceColumnName == columnReferenceExpression.Name) - return new ColumnReferenceExpression() - { - Name = mapping.UnionLayout.TableIndexColumnName, - Table = columnReferenceExpression.Table - }; - } - const string msg = "could not find columns [{1}.{2}] for function [{0}]"; - throw new InvalidOperationException(string.Format(msg, expression.KnownFunction, - columnReferenceExpression.Table.Alias, columnReferenceExpression.Name)); + const string msg = "could not find columns [{1}.{2}] for function [{0}]"; + throw new InvalidOperationException(string.Format(msg, expression.KnownFunction, + columnReferenceExpression.Table.Alias, columnReferenceExpression.Name)); + } } return expression; } + private void AddTypeColumn(UnionClause union, ColumnReferenceExpression columnReferenceExpression, string columnAlias) + { + throw new NotImplementedException(); + } + private static void ExpectArgumentCount(QueryFunctionExpression expression, int expectedCount, int? expectedCount2 = null) { diff --git a/Tests/Sql/BasicTest.cs b/Tests/Sql/BasicTest.cs index ea5b271..92c1ade 100644 --- a/Tests/Sql/BasicTest.cs +++ b/Tests/Sql/BasicTest.cs @@ -175,6 +175,32 @@ when sum > 300 then 2 CheckTranslate(mappings, sourceSql, expected); } + [Test] + public void AreaOnSeveralLeftJoin() + { + const string sourceSql = + @"select contractors2.НаименованиеПолное as ContractorFullname +FROM справочник.Контрагенты as contractors1 +LEFT JOIN справочник.Контрагенты as contractors ON contractors1.Ссылка = contractors.Ссылка +LEFT JOIN справочник.Контрагенты as contractors2 ON contractors1.Ссылка = contractors2.Ссылка"; + + const string mappings = @"Справочник.Контрагенты t1 Main + Ссылка Single id + наименованиеполное Single f1 + ОбластьДанныхОсновныеДанные Single area +"; + + const string expectedResult = + @"select + contractors2.f1 as ContractorFullname +from t1 as contractors1 +left join t1 as contractors on contractors1.area = contractors.area and contractors1.id = contractors.id +left join t1 as contractors2 on contractors1.area = contractors2.area and contractors1.id = contractors2.id + "; + + CheckTranslate(mappings, sourceSql, expectedResult); + } + [Test] public void CanUseRussianSyntax() {