示例#1
0
        internal static DataParamChainer AddNodeColumns(Chainer prev, DB3 nodeID, ColumnSelector selector, string prefix)
        {
            var node = DbMapping.GetNodeMap(nodeID);

            ColumnMap[] columns;

            if (selector == ColumnSelector.All)
            {
                if (node.HasRowversion)
                {
                    return(((IParam)prev).Param(prefix.AsParam(1), node.RowversionColumn.DataType));
                }

                columns = node.SortedColumns;
            }
            else if (selector == ColumnSelector.RK)
            {
                columns = node.SortedRKColumns;
            }
            else if (selector == ColumnSelector.InsertableWithIdentity)
            {
                columns = node.GetInsertableColumns(true);
            }
            else
            {
                columns = node.GetInsertableColumns(false);
            }

            return(AddNodeColumns(prev, columns, prefix));
        }
示例#2
0
        internal static void ThrowForeignKeyNotFoundException(DB3 foreignKey, DB3 table)
        {
            var foreignKeyFullName = DbMapping.GetForeignKeyName(foreignKey);

            throw new QueryTalkException("Link.TryGetRelation", QueryTalkExceptionType.ForeignKeyNotFound,
                                         String.Format("table = {0}{1}   foreign key = {2}",
                                                       DbMapping.GetNodeMap(table).Name.Sql,
                                                       Environment.NewLine,
                                                       foreignKeyFullName), Text.Method.By);
        }
示例#3
0
        // mapped bulk insert
        internal static Result <T> ExecuteBulkInsert <T>(Assembly client, IEnumerable <T> rows, ConnectBy connectBy)
            where T : DbRow
        {
            if (rows == null)
            {
                throw new QueryTalkException("Importer.ExecuteBulkInsert<T>",
                                             QueryTalkExceptionType.ArgumentNull, "rows = null", Text.Method.BulkInsertGo);
            }

            if (rows.Count() == 0)
            {
                return(new Result <T>(false, 0));
            }

            Crud.CheckTable(rows.First(), Text.Method.BulkInsertGo);

            var first   = rows.First();
            var nodeID  = ((DbRow)first).NodeID;
            var nodeMap = DbMapping.GetNodeMap(nodeID);
            var table   = nodeMap.Name.ToString();
            var data    = rows.ToDataTable();

            try
            {
                ConnectionKey connKey = null;
                if (connectBy != null)
                {
                    connKey = ((IConnectable)connectBy).ConnectionKey;
                }

                var connectionString = ConnectionManager.InvokeConnectionFunc(client, connKey).ConnectionString;
                using (SqlConnection cn = new SqlConnection(connectionString))
                {
                    cn.Open();

                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(cn))
                    {
                        bulkCopy.DestinationTableName = table;
                        foreach (var column in nodeMap.GetInsertableColumns(false))
                        {
                            bulkCopy.ColumnMappings.Add(column.Name.Part1, column.Name.Part1);
                        }

                        bulkCopy.WriteToServer(data);
                    }
                }

                return(new Result <T>(true, rows.Count()));
            }
            catch (QueryTalkException ex)
            {
                ex.Method = Text.Method.BulkInsertGo;
                throw;
            }
        }
示例#4
0
        internal static Chainer CreateQueryFromSubject(DbNode currentNode)
        {
            if (currentNode is IFunction)
            {
                var arguments = ((IFunction)currentNode).Arguments;

                DbMapping.PrepareFunctionArguments(arguments, currentNode);

                return(currentNode.GetDesigner()
                       .From(currentNode.Map.Name.PassUdf(
                                 ((IFunction)currentNode).Arguments), currentNode)
                       .As(currentNode.Index));
            }
            // table
            else
            {
                if (currentNode.IsSynonym)
                {
                    if (currentNode.SynonymQuery is IOpenView)
                    {
                        return(currentNode.GetDesigner().From((IOpenView)currentNode.SynonymQuery, currentNode)
                               .As(currentNode.Index));
                    }
                    // View
                    else
                    {
                        return(currentNode.GetDesigner().From((View)currentNode.SynonymQuery, currentNode)
                               .As(currentNode.Index));
                    }
                }
                else
                {
                    if (currentNode.Row != null)
                    {
                        var row = currentNode.Row;
                        return(currentNode.GetDesigner()
                               .From(currentNode.Map.Name, currentNode).As(currentNode.Index)
                               .Where(DbMapping.GetNodeMap(row.NodeID)
                                      .BuildRKExpression(row.GetOriginalRKValues(), currentNode.Index)));
                    }
                    else
                    {
                        return(currentNode.GetDesigner()
                               .From(currentNode.Map.Name, currentNode)
                               .As(currentNode.Index));
                    }
                }
            }
        }
示例#5
0
        private void TryAddAsteriskColumns()
        {
            List <Column> columns = new List <Column>();

            foreach (var column in _columns)
            {
                string alias;
                if (!DetectAsterisk(column, out alias))
                {
                    columns.Add(column);
                    continue;
                }

                // we found the asterisk:

                var ctable = GetTarget(ref alias);

                if (column.Original is DbColumns)
                {
                    var dbColumns = (DbColumns)column.Original;

                    string dbColumnsAlias = dbColumns.Alias;

                    columns.AddRange(
                        DbMapping.GetNodeMap(dbColumns.Parent.NodeID)
                        .GetColumnsByDatabaseOrder(dbColumnsAlias, dbColumns.Parent));

                    continue;
                }

                // if ctable is found check if it contains node
                if (ctable != null && ctable.Node != null &&
                    !ctable.Node.IsSynonym         // if node has a query synonym
                                                   // than use the asterix (*)
                                                   // since the columns are not mapped to the node
                    )
                {
                    var allColumns = DbMapping.GetNodeMap(ctable.Node.NodeID).GetColumnsByDatabaseOrder(alias);
                    columns.AddRange(allColumns);
                    continue;
                }

                columns.Add(column);
            }

            _columns = columns.ToArray();
        }
示例#6
0
        internal Relation TryGetRelation(DB3 foreignKey, string method = null)
        {
            if (HasIntermediate)
            {
                throw new QueryTalkException("Link.TryGetRelation", QueryTalkExceptionType.IntermediateTableDisallowed,
                                             String.Format("linked tables = {0}:{1}{2}   intermediate table = {3}",
                                                           DbMapping.GetNodeMap(TableA).Name.Sql,
                                                           DbMapping.GetNodeMap(TableB).Name.Sql,
                                                           Environment.NewLine, DbMapping.GetNodeMap(Intermediate).Name.Sql),
                                             method);
            }

            Relation relation = null;

            if (foreignKey.Equals(DB3.Default))
            {
                // single relation
                if (_relations.Count == 1)
                {
                    return(_relations.First());
                }
                // many relations - missing FK
                else
                {
                    throw new QueryTalkException("Link.TryGetRelation", QueryTalkExceptionType.MissingForeignKey,
                                                 String.Format("linked tables = {0}:{1}",
                                                               DbMapping.GetNodeMap(TableA).Name.Sql,
                                                               DbMapping.GetNodeMap(TableB).Name.Sql), method);
                }
            }
            // foreign key is defined:
            else
            {
                relation = _relations.Where(a => a.FKColumns.Contains(foreignKey))
                           .FirstOrDefault();

                if (relation == null)
                {
                    DbMapping.ThrowForeignKeyNotFoundException(foreignKey, TableA);
                }
            }

            return(relation);
        }
示例#7
0
        internal static Link TryFindLink(DB3 tableA, DB3 tableB, string method = null)
        {
            var link = GetLink(tableA, tableB);

            if (link == null && !tableA.Equals(tableB))
            {
                link = TryFindIntermediate(tableA, tableB, method);
            }

            // second check
            if (link == null)
            {
                throw new QueryTalkException("DbMapping.TryFindLink", QueryTalkExceptionType.LinkNotFound,
                                             String.Format("table A = {0}{1}   table B = {2}",
                                                           DbMapping.GetNodeMap(tableA).Name.Sql, Environment.NewLine,
                                                           DbMapping.GetNodeMap(tableB).Name.Sql),
                                             method);
            }

            return(link);
        }
示例#8
0
        // try find intermediate table & cache it
        private static Link TryFindIntermediate(DB3 tableA, DB3 tableB, string method = null)
        {
            // do not seek for link between the equal tables
            if (!tableA.Equals(tableB))
            {
                // find all (ordered) links of tableA
                var linksA = _orderedLinks.Where(a => a.TableA.Equals(tableA));

                // find all (ordered) links of tableB
                var linksB = _orderedLinks.Where(a => a.TableA.Equals(tableB));

                // find all intermediate tables
                var intermediates =
                    (from a in linksA
                     join b in linksB on a.TableB equals b.TableB
                     select a.TableB).ToList();

                // enumerate through each intermediate table and evaluate it
                DB3 c  = DB3.Default;   // first intermediate
                DB3 c2 = DB3.Default;   // superfluous intermediate (should not exists)
                foreach (var intermediate in intermediates)
                {
                    // make sure that the table has been initialized
                    _Invoke(intermediate);

                    // get link C to A
                    var linkToA = _orderedLinks
                                  .Where(a => a.TableA.Equals(intermediate) &&
                                         a.TableB.Equals(tableA))
                                  .Select(a => a.Link)
                                  .Distinct()
                                  .FirstOrDefault();

                    // get link C to B
                    var linkToB = _orderedLinks
                                  .Where(a => a.TableA.Equals(intermediate) &&
                                         a.TableB.Equals(tableB))
                                  .Select(a => a.Link)
                                  .Distinct()
                                  .FirstOrDefault();

                    // exclude intermediates that have links with many relations
                    if (linkToA.HasManyRelations || linkToB.HasManyRelations)
                    {
                        continue;
                    }

                    // There are 4 combinations of A.C.B relationship:
                    // --------------------------------------------------
                    //   A << C >> B    (allowed)
                    //   A << C << B    (allowed)
                    //   A >> C >> B    (allowed)
                    //   A >> C << B    (disallowed)
                    // -------------------------------------------------------------------------
                    // The intermediate tables that on ONE side of both relations are excluded.
                    // -------------------------------------------------------------------------
                    if (linkToA.IsRefTable(intermediate) && linkToB.IsRefTable(intermediate))
                    {
                        continue;
                    }

                    if (c.IsDefault)
                    {
                        c = intermediate;
                    }
                    else
                    {
                        c2 = intermediate;
                    }
                }

                // hit
                if (!c.IsDefault)
                {
                    // only a single intermediate table is allowed
                    if (c2.IsDefault)
                    {
                        // create and cache the link A:B
                        var link = new Link(tableA, tableB, c);
                        _links.Add(link);
                        return(link);
                    }
                    else
                    {
                        // link ambiguity
                        throw new QueryTalkException("DbMapping.TryFindIntermediate", QueryTalkExceptionType.LinkAmbiguity,
                                                     String.Format("table A = {0}{1}   table B = {2}{3}   intermediate 1 = {4}{5}   intermediate 2 = {6}",
                                                                   GetNodeMap(tableA).Name.Sql, Environment.NewLine,
                                                                   GetNodeMap(tableB).Name.Sql, Environment.NewLine,
                                                                   GetNodeMap(c).Name.Sql, Environment.NewLine,
                                                                   GetNodeMap(c2).Name.Sql),
                                                     method).SetObjectName(DbMapping.GetNodeMap(tableA).Name.Sql);
                    }
                }
            }

            // link has not been found
            throw new QueryTalkException("DbMapping.TryFindIntermediate",
                                         QueryTalkExceptionType.LinkNotFound,
                                         String.Format("table A = {0}{1}   table B = {2}",
                                                       GetNodeMap(tableA).Name.Sql, Environment.NewLine, GetNodeMap(tableB).Name.Sql),
                                         method).SetObjectName(DbMapping.GetNodeMap(tableA).Name.Sql);
        }
示例#9
0
        internal static View ConvertDbRowData(IEnumerable <DbRow> rows, bool rkOnly = false, bool withRowID = false)
        {
            var first = rows.Where(row => row != null).First();

            var nodeMap = DbMapping.GetNodeMap(first.NodeID);

            if (nodeMap.ID.Equals(DB3.Default))
            {
                DbRow.ThrowInvalidDbRowException(first.GetType());
            }

            var rowCount   = 0;
            var columns    = new List <ViewColumnInfo>();
            var type       = first.GetType();
            var properties = type.GetSortedWritableProperties(withRowID);

            var numberOfProperties = properties.Length;

            if (numberOfProperties == 0)
            {
                throw new QueryTalkException("ViewConverter.ToView<T>", QueryTalkExceptionType.InvalidDataClass,
                                             String.Format("data class = {0}", type));
            }

            List <IPropertyAccessor> getters;
            bool cached;

            if (withRowID)
            {
                cached = Cache.IRowAccessors.TryGetValue(type, out getters);
            }
            else
            {
                cached = Cache.PropertyAccessors.TryGetValue(type, out getters);
            }

            if (!cached)
            {
                getters = _GetDbRowsGetters(withRowID, type, properties);
            }

            var sql = Text.GenerateSql(500)
                      .Append(Text.Select).S();

            int i = 0;

            i = _BuildDbRowsOuterSelect(rkOnly, withRowID, nodeMap, columns, sql, i);

            if (withRowID)
            {
                sql.NewLineIndent(Text.Comma);
                AppendColumn(sql,
                             String.Format("CAST({0} AS [int])", Filter.DelimitNonAsterix(String.Format("{0}{1}", Text.ColumnShortName, i + 1))),
                             Text.Reserved.QtRowIDColumnName);
            }

            sql.S()
            .NewLine(Text.From).S()
            .Append(Text.LeftBracket).S();

            bool firstRow = true;

            foreach (var row in rows)
            {
                if (row == null)
                {
                    continue;
                }

                if (!firstRow)
                {
                    sql.NewLineIndent(Text.UnionAll).S()
                    .Append(Text.Select).S();
                }
                else
                {
                    sql.NewLineIndent(Text.Select).S();
                }

                var originalValues = row.GetOriginalRKValues();
                var gi             = 0; // getter index
                int j = 0;
                _BuildDbRowsValues(rkOnly, withRowID, nodeMap, getters, sql, firstRow, row, originalValues, ref j,
                                   ref gi);

                if (withRowID)
                {
                    var value = getters[gi].GetValue(row);
                    sql.Append(Text.Comma);
                    AppendColumnValue(sql, value, j + 1);
                }

                firstRow = false;
                ++rowCount;
            }

            sql.NewLine(Text.RightBracket).S()
            .Append(Text.As).S()
            .Append(Text.DelimitedTargetAlias);

            return(new View(sql.ToString(), typeof(DbRow), columns.ToArray(), rowCount));
        }
示例#10
0
        private static void _BuildClassOuterSelect(Type type, ref Type clrType, ref QueryTalkException exception, List <ViewColumnInfo> columns,
                                                   bool isEmpty, PropertyInfo[] properties, out List <IPropertyAccessor> getters, out int numberOfProperties,
                                                   StringBuilder sqlOuter, StringBuilder sqlEmpty)
        {
            numberOfProperties = properties.Length;
            if (numberOfProperties == 0)
            {
                throw new QueryTalkException("ViewConverter.ToView<T>", QueryTalkExceptionType.InvalidDataClass,
                                             String.Format("data class = {0}", type));
            }

            bool cached = Cache.PropertyAccessors.TryGetValue(type, out getters);

            if (!cached)
            {
                getters = new List <IPropertyAccessor>();
            }

            NodeMap rowMap  = null;
            bool    isDbRow = type.IsDbRow();

            if (isDbRow)
            {
                rowMap = DbMapping.GetNodeMap(type);
                if (rowMap.ID.Equals(DB3.Default))
                {
                    DbRow.ThrowInvalidDbRowException(type);
                }
            }

            // outer select:
            int i = 0;

            foreach (var property in properties)
            {
                string column;

                var clrTypeMatch = Mapping.CheckClrCompliance(property.PropertyType, out clrType, out exception);
                if (clrTypeMatch != Mapping.ClrTypeMatch.ClrMatch)
                {
                    continue;
                }

                ViewColumnInfo columnInfo;
                if (isDbRow)
                {
                    var rowColumn = rowMap.Columns.Where(a => a.ID.ColumnZ == i + 1).First();
                    column     = rowColumn.Name.Part1;
                    columnInfo = new ViewColumnInfo(column, rowColumn.DataType, rowColumn.IsNullable);
                    columns.Add(columnInfo);
                }
                else
                {
                    column     = property.Name;
                    columnInfo = new ViewColumnInfo(column, property.PropertyType, clrType);
                    columns.Add(columnInfo);
                }

                if (i != 0)
                {
                    sqlOuter.NewLineIndent(Text.Comma);
                    sqlEmpty.Append(Text.Comma);
                }

                var dataType = Mapping.ProvideDataType(columnInfo.DataType, clrType);
                AppendOuterColumn(sqlOuter, dataType, i + 1, column);

                if (isEmpty)
                {
                    AppendNullValueColumn(sqlEmpty, i + 1);
                }

                if (!cached)
                {
                    getters.Add(PropertyAccessor.Create(type, property));
                }

                ++i;
            }

            numberOfProperties = i;
            if (numberOfProperties == 0)
            {
                ThrowInvalidDataClassException(type);
            }

            if (!cached)
            {
                Cache.PropertyAccessors[type] = getters;
            }
        }