Ejemplo n.º 1
0
        public bool VisitExprDerivedTableValues(ExprDerivedTableValues expr, TCtx arg)
        {
            var res = this.Visit(expr, "DerivedTableValues", arg, out var argOut) && this.Accept("Values", expr.Values, argOut) && this.Accept("Alias", expr.Alias, argOut) && this.Accept("Columns", expr.Columns, argOut);

            this._visitor.EndVisitExpr(expr, arg);
            return(res);
        }
Ejemplo n.º 2
0
        protected bool VisitExprDerivedTableValuesCommon(ExprDerivedTableValues derivedTableValues, IExpr?parent)
        {
            this.AcceptPar('(', derivedTableValues.Values, ')', derivedTableValues);
            derivedTableValues.Alias.Accept(this, derivedTableValues);
            derivedTableValues.Columns.AssertNotEmpty("List of columns in a derived table with values literals cannot be empty");
            this.AcceptListComaSeparatedPar('(', derivedTableValues.Columns, ')', derivedTableValues);

            return(true);
        }
Ejemplo n.º 3
0
        public static ExprList FromDerivedTableValuesInsert(ExprDerivedTableValues derivedTableValues, IReadOnlyList <ExprColumnName>?keys, out TempTableBase tempTable, Alias alias = default, string?name = null)
        {
            tempTable = FromDerivedTableValues(derivedTableValues, keys, alias, name);

            var insertData = derivedTableValues.Values.Items.SelectToReadOnlyList(r => new ExprInsertValueRow(r.Items));

            var insert = SqQueryBuilder.InsertInto(tempTable, derivedTableValues.Columns).Values(new ExprInsertValues(insertData));

            return(new ExprList(new IExprExec[] { new ExprStatement(tempTable.Script.Create()), insert }));
        }
Ejemplo n.º 4
0
 public static ExprDerivedTableValues WithColumns(this ExprDerivedTableValues original, IReadOnlyList <ExprColumnName> newColumns)
 => new ExprDerivedTableValues(values: original.Values, alias: original.Alias, columns: newColumns);
Ejemplo n.º 5
0
 public static ExprDerivedTableValues WithAlias(this ExprDerivedTableValues original, ExprTableAlias newAlias)
 => new ExprDerivedTableValues(values: original.Values, alias: newAlias, columns: original.Columns);
Ejemplo n.º 6
0
 public static ExprDerivedTableValues WithValues(this ExprDerivedTableValues original, ExprTableValueConstructor newValues)
 => new ExprDerivedTableValues(values: newValues, alias: original.Alias, columns: original.Columns);
Ejemplo n.º 7
0
        public ExprInsert Done()
        {
            var checkExistence = this._checkExistenceByColumns != null && this._checkExistenceByColumns.Count > 0;

            var useDerivedTable = this._targetInsertSelectMapping != null || checkExistence;

            var mapping = this._dataMapping.AssertFatalNotNull(nameof(this._dataMapping));

            int?capacity = this._data.TryToCheckLength(out var c) ? c : (int?)null;

            if (capacity != null && capacity.Value < 1)
            {
                throw new SqExpressException("Input data should not be empty");
            }


            List <ExprValueRow>?      recordsS = null;
            List <ExprInsertValueRow>?recordsI = null;

            if (useDerivedTable)
            {
                recordsS = capacity.HasValue ? new List <ExprValueRow>(capacity.Value) : new List <ExprValueRow>();
            }
            else
            {
                recordsI = capacity.HasValue ? new List <ExprInsertValueRow>(capacity.Value) : new List <ExprInsertValueRow>();
            }

            DataMapSetter <TTable, TItem>? dataMapSetter = null;
            IReadOnlyList <ExprColumnName>?columns       = null;

            foreach (var item in this._data)
            {
                dataMapSetter ??= new DataMapSetter <TTable, TItem>(this._target, item);

                dataMapSetter.NextItem(item, columns?.Count);
                mapping(dataMapSetter);

                columns ??= dataMapSetter.Columns;

                dataMapSetter.EnsureRecordLength();

                recordsS?.Add(new ExprValueRow(dataMapSetter.Record.AssertFatalNotNull(nameof(dataMapSetter.Record))));
                recordsI?.Add(new ExprInsertValueRow(dataMapSetter.Record.AssertFatalNotNull(nameof(dataMapSetter.Record))));
            }

            if ((recordsS?.Count ?? 0 + recordsI?.Count ?? 0) < 1 || columns == null)
            {
                //In case of empty IEnumerable
                throw new SqExpressException("Input data should not be empty");
            }

            IExprInsertSource insertSource;

            if (recordsI != null)
            {
                insertSource = new ExprInsertValues(recordsI);
            }
            else if (recordsS != null && useDerivedTable)
            {
                var valuesConstructor = new ExprTableValueConstructor(recordsS);
                var values            = new ExprDerivedTableValues(
                    valuesConstructor,
                    new ExprTableAlias(Alias.Auto.BuildAliasExpression().AssertNotNull("Alias cannot be null")),
                    columns);

                IReadOnlyList <ColumnValueInsertSelectMap>?additionalMaps = null;
                if (this._targetInsertSelectMapping != null)
                {
                    var targetUpdateSetter = new TargetInsertSelectSetter <TTable>(this._target);

                    this._targetInsertSelectMapping.Invoke(targetUpdateSetter);

                    additionalMaps = targetUpdateSetter.Maps;
                    if (additionalMaps.Count < 1)
                    {
                        throw new SqExpressException("Additional insertion cannot be null");
                    }
                }

                var selectValues = new List <IExprSelecting>(columns.Count + (additionalMaps?.Count ?? 0));

                foreach (var exprColumnName in values.Columns)
                {
                    selectValues.Add(exprColumnName);
                }

                if (additionalMaps != null)
                {
                    foreach (var m in additionalMaps)
                    {
                        selectValues.Add(m.Value);
                    }
                }

                IExprQuery query;
                var        queryBuilder = SqQueryBuilder.Select(selectValues).From(values);

                if (checkExistence && this._checkExistenceByColumns != null)
                {
                    var tbl = this._target.WithAlias(new ExprTableAlias(Alias.Auto.BuildAliasExpression() !));

                    var existsFilter = !SqQueryBuilder.Exists(SqQueryBuilder
                                                              .SelectOne()
                                                              .From(tbl)
                                                              .Where(this._checkExistenceByColumns
                                                                     .Select(column => column.WithSource(tbl.Alias) == column.WithSource(values.Alias))
                                                                     .JoinAsAnd()));

                    query = queryBuilder.Where(existsFilter).Done();
                }
                else
                {
                    query = queryBuilder.Done();
                }

                insertSource = new ExprInsertQuery(query);

                if (additionalMaps != null)
                {
                    var extraInsertCols = additionalMaps.SelectToReadOnlyList(m => m.Column);
                    columns = Helpers.Combine(columns, extraInsertCols);
                }
            }
            else
            {
                //Actually C# should have detected that this brunch cannot be invoked
                throw new SqExpressException("Fatal logic error!");
            }

            return(new ExprInsert(this._target.FullName, columns, insertSource));
        }
Ejemplo n.º 8
0
 public override bool VisitExprDerivedTableValues(ExprDerivedTableValues derivedTableValues, IExpr?parent)
 {
     return(this.VisitExprDerivedTableValuesCommon(derivedTableValues, parent));
 }
Ejemplo n.º 9
0
        public static TempTableData FromDerivedTableValues(ExprDerivedTableValues derivedTableValues, IReadOnlyList <ExprColumnName>?keys, Alias alias = default, string?name = null)
        {
            var result = new TempTableData(string.IsNullOrEmpty(name) || name == null ? GenerateName() : name, alias);

            derivedTableValues.Columns.AssertNotEmpty("Columns list cannot be empty");
            derivedTableValues.Values.Items.AssertNotEmpty("Rows list cannot be empty");

            TableColumn?[] tableColumns = new TableColumn?[derivedTableValues.Columns.Count];

            for (var rowIndex = 0; rowIndex < derivedTableValues.Values.Items.Count; rowIndex++)
            {
                var lastRow = rowIndex + 1 == derivedTableValues.Values.Items.Count;
                var row     = derivedTableValues.Values.Items[rowIndex];
                if (row.Items.Count != derivedTableValues.Columns.Count)
                {
                    throw new SqExpressException("Number of values in a row does not match number of columns");
                }

                for (var valueIndex = 0; valueIndex < row.Items.Count; valueIndex++)
                {
                    var value             = row.Items[valueIndex];
                    var previousColumn    = tableColumns[valueIndex];
                    var currentColumnName = derivedTableValues.Columns[valueIndex];
                    var res = value.Accept(ExprValueTypeAnalyzer <TableColumn?, TempTableBuilderCtx> .Instance,
                                           new ExprValueTypeAnalyzerCtx <TableColumn?, TempTableBuilderCtx>(
                                               new TempTableBuilderCtx(
                                                   currentColumnName,
                                                   previousColumn,
                                                   CheckIsPk(currentColumnName)),
                                               result));

                    tableColumns[valueIndex] = res;
                    if (lastRow)
                    {
                        if (ReferenceEquals(res, null))
                        {
                            throw new SqExpressException($"Could not evaluate column type at {valueIndex}");
                        }
                    }
                }
            }
            result.AddColumns(tableColumns !);

            return(result);

            bool CheckIsPk(ExprColumnName columnName)
            {
                if (keys == null || keys.Count < 1)
                {
                    return(false);
                }

                for (var index = 0; index < keys.Count; index++)
                {
                    var key = keys[index];

                    if (key.LowerInvariantName == columnName.LowerInvariantName)
                    {
                        return(true);
                    }
                }

                return(false);
            }
        }
Ejemplo n.º 10
0
 public abstract bool VisitExprDerivedTableValues(ExprDerivedTableValues derivedTableValues, IExpr?parent);
Ejemplo n.º 11
0
        public ExprMerge Done()
        {
            var records = this._data.TryToCheckLength(out var capacity)
                ? capacity > 0 ? new List <ExprValueRow>(capacity) : null
                : new List <ExprValueRow>();

            if (records == null)
            {
                throw new SqExpressException("Input data should not be empty");
            }

            var dataMapKeys = this._dataMapKeys.AssertNotNull("DataMapKeys should be initialized");
            var dataMap     = this._dataMap.AssertNotNull("DataMap should be initialized");


            DataMapSetter <TTable, TItem>? setter          = null;
            List <ExprColumnName>?         keys            = null;
            IReadOnlyList <ExprColumnName>?allTableColumns = null;
            IReadOnlyList <ExprColumnName>?totalColumns    = null;

            foreach (var item in this._data)
            {
                setter ??= new DataMapSetter <TTable, TItem>(this._table, item);

                setter.NextItem(item, totalColumns?.Count);
                dataMapKeys(setter);

                keys ??= new List <ExprColumnName>(setter.Columns);

                keys.AssertNotEmpty("There should be at least one key");

                dataMap(setter);

                totalColumns = allTableColumns ??= new List <ExprColumnName>(setter.Columns);

                if (this._extraDataMap != null)
                {
                    this._extraDataMap.Invoke(setter);
                    if (ReferenceEquals(totalColumns, allTableColumns))
                    {
                        totalColumns = new List <ExprColumnName>(setter.Columns);
                    }
                }

                setter.EnsureRecordLength();
                records.Add(new ExprValueRow(setter.Record.AssertFatalNotNull(nameof(setter.Record))));
            }

            if (records.Count < 1)
            {
                throw new SqExpressException("Input data should not be empty");
            }

            keys            = keys.AssertFatalNotNull(nameof(keys));
            allTableColumns = allTableColumns.AssertFatalNotNull(nameof(allTableColumns));
            totalColumns    = totalColumns.AssertFatalNotNull(nameof(allTableColumns));

            var exprValuesTable = new ExprDerivedTableValues(new ExprTableValueConstructor(records), this._sourceTableAlias, totalColumns);

            if (keys.Count >= allTableColumns.Count)
            {
                throw new SqExpressException("The number of keys exceeds the number of columns");
            }

            return(new ExprMerge(
                       this._table,
                       exprValuesTable,
                       this.GetOn(keys),
                       this.BuildWhenMatched(keys, allTableColumns),
                       this.BuildWhenNotMatchedByTarget(keys, allTableColumns),
                       this.BuildWhenNotMatchedBySource()));
        }
Ejemplo n.º 12
0
 public void Deconstruct(out List <ExprColumnName> keys, out IReadOnlyList <ExprColumnName> allTableColumns, out ExprDerivedTableValues exprValuesTable)
 {
     keys            = this.Keys;
     allTableColumns = this.AllTableColumns;
     exprValuesTable = this.ExprValuesTable;
 }
Ejemplo n.º 13
0
 public UpdateDataAnalysis(List <ExprColumnName> keys, IReadOnlyList <ExprColumnName> allTableColumns, ExprDerivedTableValues exprValuesTable)
 {
     this.Keys            = keys;
     this.AllTableColumns = allTableColumns;
     this.ExprValuesTable = exprValuesTable;
 }
Ejemplo n.º 14
0
        public static UpdateDataAnalysis AnalyzeUpdateData <TTable, TItem>
        (
            IEnumerable <TItem> data,
            TTable targetTable,
            DataMapping <TTable, TItem> dataMapKeys,
            DataMapping <TTable, TItem>?dataMap,
            IndexDataMapping?extraDataMap,
            ExprTableAlias sourceTableAlias
        )
        {
            var records = data.TryToCheckLength(out var capacity)
                ? capacity > 0 ? new List <ExprValueRow>(capacity) : null
                : new List <ExprValueRow>();

            if (records == null)
            {
                throw new SqExpressException("Input data should not be empty");
            }

            DataMapSetter <TTable, TItem>? setter          = null;
            List <ExprColumnName>?         keys            = null;
            IReadOnlyList <ExprColumnName>?allTableColumns = null;
            IReadOnlyList <ExprColumnName>?totalColumns    = null;

            foreach (var item in data)
            {
                setter ??= new DataMapSetter <TTable, TItem>(targetTable, item);

                setter.NextItem(item, totalColumns?.Count);
                dataMapKeys(setter);

                keys ??= new List <ExprColumnName>(setter.Columns);

                keys.AssertNotEmpty("There should be at least one key");

                dataMap?.Invoke(setter);

                totalColumns = allTableColumns ??= new List <ExprColumnName>(setter.Columns);

                if (extraDataMap != null)
                {
                    extraDataMap.Invoke(setter);
                    if (ReferenceEquals(totalColumns, allTableColumns))
                    {
                        totalColumns = new List <ExprColumnName>(setter.Columns);
                    }
                }

                setter.EnsureRecordLength();
                records.Add(new ExprValueRow(setter.Record.AssertFatalNotNull(nameof(setter.Record))));
            }

            if (records.Count < 1)
            {
                throw new SqExpressException("Input data should not be empty");
            }

            keys            = keys.AssertFatalNotNull(nameof(keys));
            allTableColumns = allTableColumns.AssertFatalNotNull(nameof(allTableColumns));
            totalColumns    = totalColumns.AssertFatalNotNull(nameof(allTableColumns));

            var exprValuesTable = new ExprDerivedTableValues(new ExprTableValueConstructor(records), sourceTableAlias, totalColumns);

            if (keys.Count > allTableColumns.Count)
            {
                throw new SqExpressException("The number of keys exceeds the number of columns");
            }

            return(new UpdateDataAnalysis(keys, allTableColumns, exprValuesTable));
        }