Пример #1
0
        public bool VisitExprInsertQuery(ExprInsertQuery expr, TCtx arg)
        {
            var res = this.Visit(expr, "InsertQuery", arg, out var argOut) && this.Accept("Query", expr.Query, argOut);

            this._visitor.EndVisitExpr(expr, arg);
            return(res);
        }
Пример #2
0
 public static ExprInsertQuery WithQuery(this ExprInsertQuery original, IExprQuery newQuery)
 => new ExprInsertQuery(query: newQuery);
Пример #3
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));
        }
Пример #4
0
 public override bool VisitExprInsertQuery(ExprInsertQuery exprInsertQuery, IExpr?parent)
 {
     return(this.VisitExprInsertQueryCommon(exprInsertQuery, parent));
 }
Пример #5
0
 protected bool VisitExprInsertQueryCommon(ExprInsertQuery exprInsertQuery, IExpr?parent)
 {
     exprInsertQuery.Query.Accept(this, exprInsertQuery);
     return(true);
 }
Пример #6
0
 public abstract bool VisitExprInsertQuery(ExprInsertQuery exprInsertQuery, IExpr?parent);