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)); }
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); }
// 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; } }
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)); } } } }
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(); }
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); }
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); }
// 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); }
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)); }
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; } }