/// <summary> /// Executes the scalar function returning the value of a specified type. /// </summary> /// <typeparam name="T">The type of a value to return.</typeparam> /// <param name="client">A client assembly.</param> /// <param name="arguments">Are the arguments to pass.</param> protected T GoFunc <T>(System.Reflection.Assembly client, params ParameterArgument[] arguments) { return(PublicInvoker.Call <T>(() => { var root = Mapper.GetRoot(); DbMapping.CreateParams(root, this); var parameters = String.Join(",", root.AllParams.Select(p => p.Name).ToArray()); // build string sql = Text.GenerateSql(100) .NewLine(Text.Select).S() .Append(Map.Name.Sql) .EncloseLeft() .Append(parameters) .EncloseRight() .Append(Text._As_) .Append(Text.LeftSquareBracket) .Append(Text.SingleColumnName) .Append(Text.RightSquareBracket) .Terminate() .ToString(); Mapper.SetSql(sql); var cpass = new PassChainer(Mapper, arguments); var connectable = Reader.GetConnectable(client, cpass); return Reader.LoadTable <Row <T> >(connectable, null, true).ToValue <T>(); })); }
internal ElseIfChainer(Chainer prev, IOpenView openView, bool sign) : base(prev) { chainMethod = Text.Method.ElseIfExists; CheckNullAndThrow(Arg(() => openView, openView)); IOpenView query; if (openView is ISemantic) { query = DbMapping.SelectFromSemantic((ISemantic)openView); } else { query = openView; } var view = new View(query); if (Exception != null) { Exception.Extra = String.Format("Check {0} method.", Exception.Method); TryThrow(); } Build = BuildViewMethod(view, sign); }
internal static void CheckQuantifierAndThrow(DbNode currentNode, DbNode innerNode, DbNode intermediate, Predicate predicate) { if (currentNode == null || innerNode == null) { return; } Relation relation; if (intermediate != null) { relation = DbMapping.GetRelation(intermediate.NodeID, currentNode.SynonymOrThis.NodeID, intermediate.GetFK()); } else { relation = DbMapping.GetRelation(innerNode.SynonymOrThis.NodeID, currentNode.SynonymOrThis.NodeID, innerNode.SynonymOrThis.GetFK()); } // one-to-many is ok if (relation.IsRefTable(currentNode.SynonymOrThis.NodeID)) { return; } // many-to-one is not ok if a predicate type is not existential if (!predicate.HasDefaultQuantifier()) { ThrowInvalidQuantifierException(predicate, currentNode, (ISemantic)innerNode, intermediate, null); } }
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)); }
private static Expression _GetMappedExpression(TableChainer source, TableChainer target, DB3 foreignKey) { if (foreignKey.IsDefault) { foreignKey = source.Node.GetFK(); } var joinRelation = DbMapping.GetRelation(target.Node.Root.SynonymOrThis.NodeID, source.Node.Root.SynonymOrThis.NodeID, foreignKey, Text.Method.By); if (foreignKey.IsDefault) { foreignKey = joinRelation.ForeignKey; } // determine join operator (for .Join method only) if (source is SemqJoinChainer && !joinRelation.IsInnerJoin(target.Node.Root.SynonymOrThis.NodeID)) { ((SemqJoinChainer)source).IsLeftOuterJoin = true; } // foreign key table = this if (foreignKey.TableID.Equals(source.Node.NodeID.TableID)) { return(joinRelation.BuildRelation(foreignKey, source.Alias.Name, target.Alias.Name).E()); } // foreign key table = target else { return(joinRelation.BuildRelation(foreignKey, target.Alias.Name, source.Alias.Name).E()); } }
Chainer ISemantic.Translate(SemqContext context, DbNode predecessor) { if (context == null) { throw new QueryTalkException(this, QueryTalkExceptionType.NullArgumentInnerException, "context = null", "InternalNode.ISemantic.Translate"); } if (predecessor == null) { throw new QueryTalkException(this, QueryTalkExceptionType.NullArgumentInnerException, "predecessor = null", "InternalNode.ISemantic.Translate"); } context.SetIndex(this); var from = GetDesigner().From(new Table(Map.Name, new AliasAs(Index))); if (!((IPredicate)this).HasPredicate) { return(from); } var predicate = ((IPredicate)this).Predicates[0]; var relation = DbMapping.GetRelation(predecessor.SynonymOrThis.NodeID, NodeID, DB3.Default); var relationExpression = relation.BuildRelation(predecessor.SynonymOrThis.NodeID, predecessor.Index, Index).E(); if (predicate.PredicateType == PredicateType.Cartesian) { var innerNode = ((ISemantic)predicate).Subject; context.SetIndex(innerNode); innerNode.QueryRoot = context.Subject; var innerJoinAs = from .InnerJoin((IOpenView)innerNode) .As(innerNode.Index); var joinRelation = DbMapping.GetRelation(NodeID, innerNode.SynonymOrThis.NodeID, DB3.Default); var joinExpression = joinRelation.BuildRelation(NodeID, Index, innerNode.Index).E(); var on = innerJoinAs .On(joinExpression); if (IsFinalizeable) { return(on.Where(relationExpression)); } else { return(on); } } else { return((Chainer)from.WhereExists( (INonSelectView) ((ISemantic)predicate).Translate(context, this), true) .AndWhere(relationExpression, true)); } }
internal bool IsInnerJoin(DB3 firstTable) { if (IsRefTable(firstTable)) { return(true); } return(!DbMapping.GetColumnMap(FKColumns[0]).IsNullable); }
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); }
internal Column[] GetFK(int alias) { List <Column> columns = new List <Column>(); foreach (var columnID in FKColumns) { columns.Add(Designer.Identifier(alias.ToString(), DbMapping.GetColumnMap(columnID).Name.Part1)); } return(columns.ToArray()); }
// 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; } }
// builds the delete query recursively (with a zero-based root node) private static Chainer BuildQuery( List <NodeTree> tree, // collection of all related nodes NodeTree leaf, // leaf node NodeTree node, // current node int level, // current node's level Chainer workingProc, // proc in building progress Expression where, // where clause bool isLeaf // is leaf level ) { if (level == 0 || node == null) { return(workingProc); } var link = DbMapping.TryFindLink(node.Child, node.Parent, Text.Method.DeleteCascadeGo); foreach (var relation in link.Relations) { if (isLeaf) { workingProc = ((IFrom)workingProc) .From(node.Child.GetNodeName()) .As(level); } // get on condition var joinConditionSql = relation.BuildRelation(relation.FKTable, level, level - 1); // build join workingProc = ((IInnerJoin)workingProc) .InnerJoin(relation.RefTable.GetNodeName()).As(level - 1) .On(joinConditionSql.E()); // move up along the parent chain var parent = tree.Where(a => a.Child.Equals(node.Parent) && a.Level == level - 1).FirstOrDefault(); if (parent == null && level - 1 != 0) { throw new QueryTalkException("DeleteCascadeGo.BuildQuery", QueryTalkExceptionType.DeleteCascadeInnerException, null); } workingProc = BuildQuery(tree, leaf, parent, level - 1, workingProc, where, false); if (level - 1 == 0) { workingProc = ((IWhere)workingProc) .Where(where) .Delete(leaf.Level) .Comment(""); } } return(workingProc); }
internal static void CheckWithAndThrow(this DbNode node, string argument, string method) { if (node == null) { throw new QueryTalkException("Common.CheckTable", QueryTalkExceptionType.ArgumentNull, String.Format("{0} = null", argument), method); } if (!(node is ITable)) { throw new QueryTalkException("Common.CheckTable", QueryTalkExceptionType.InvalidWith, String.Format("{0} = {1}", argument, DbMapping.GetNodeName(node.NodeID)), method); } }
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)); } } } }
internal void BuildProc(ParameterArgument[] arguments) { Arguments = arguments; var root = Mapper.GetRoot(); DbMapping.CreateParams(root, this); string parameters = null; if (arguments != null && arguments.Length > 0) { var i = 0; parameters = String.Join(",", root.AllParams .Select(p => { var s = p.Name; if (arguments[i] == null) { arguments[i] = Designer.Null; } if (arguments[i].IsArgumentOutput) { s = String.Format("{0} {1}", s, Text.Output); } ++i; return(s); } )); } string sql = Text.GenerateSql(100) .NewLine(Text.Exec).S() .Append(Text.Reserved.ReturnValueOuterParam).Append(Text._Equal_) .Append(Map.Name.Sql).S() .Append(parameters).Terminate() .NewLine(Text.Set).S() // SET @_ri = @_ro; .Append(Text.Reserved.ReturnValueInnerParam) .Append(Text._Equal_) .Append(Text.Reserved.ReturnValueOuterParam) .Terminate() .ToString(); Mapper.SetSql(sql); }
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 static Result <T> InsertGo <T>(Assembly client, DbRow row, bool identityInsert, ConnectBy connectBy) where T : DbRow { var name = Text.NotAvailable; try { var connectable = GetInsertBody <T>(client, row, identityInsert, connectBy, Text.Method.InsertGo, ref name); var result = connectable.Go <T>(); if (result.RowCount > 0) { PropertyAccessor.SetValues(row, PropertyAccessor.GetValues(result.First())); row.SetStatus(DbRowStatus.Loaded); // has rowversion & it is not RK if (row.HasNonRKRowversion) { Crud.ReloadGo <T>(client, row, false, connectBy, true); } else { // rowversion column is null: var map = DbMapping.TryGetNodeMap(row); if (map.HasRowversion && row.GetRowversionValue() == null) { row.SetStatus(DbRowStatus.Faulted); } else { row.SetStatus(DbRowStatus.Loaded); } } } result.FinalizeCrud(); return(result); } catch (QueryTalkException) { throw; } catch (System.Exception ex) { throw Crud.ClrException(ex, name, Text.Method.InsertGo); } }
// ctor: Maximized internal Predicate( DbNode subject, MaximizationType maximizationType, bool sign, LogicalOperator logicalOperator, OrderingArgument maximizedExpression, long top = 1) { DbMapping.CheckNullAndThrow(subject); if (maximizedExpression == null) { throw new QueryTalkException("Predicate.ctor", QueryTalkExceptionType.ArgumentNull, "maximized expression = null", Text.Method.HavingMaxMin); } // check expression DbColumn type if (maximizedExpression.ArgType == typeof(DbColumn)) { var column = (DbColumn)maximizedExpression.Original; if (column.Parent != null && column.Parent.Prev != null) { throw new QueryTalkException("Predicate.ctor", QueryTalkExceptionType.InvalidHavingPredicateArgument, String.Format("node = {0}", column.Parent), Text.Method.HavingMaxMin); } // column parent must be the same as the subject if (!column.Parent.Equals(subject)) { throw new QueryTalkException("Predicate.ctor", QueryTalkExceptionType.InvalidHavingPredicateArgument, String.Format("node = {0}{1} subject = {2}", column.Parent, Environment.NewLine, subject), Text.Method.HavingMaxMin); } } Subject = subject; Sign = sign; LogicalOperator = logicalOperator; PredicateType = Wall.PredicateType.Maximized; MaximizedType = maximizationType; MaximizedExpression = maximizedExpression; MaximizedTop = top; IsFinalizeable = true; subject.IsFinalizeable = true; }
private static bool CheckAutoTarget(TableChainer source, TableChainer target) { // skip the non-mapped tables if (!target.HasNode) { return(false); } var link = DbMapping.GetLink(source.Node.SynonymOrThis.NodeID, target.Node.SynonymOrThis.NodeID); if (link == null || !link.Intermediate.IsDefault) // intermediate links are not allowed { return(false); } return(true); }
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 Result <T> InsertCascadeGo <T>(Assembly client, DbRow row, ConnectBy connectBy) where T : DbRow { var name = Text.NotAvailable; if (row == null) { throw new QueryTalkException("Crud", QueryTalkExceptionType.ArgumentNull, "row = null", Text.Method.InsertCascadeGo); } Crud.CheckTable(row, Text.Method.InsertCascadeGo); try { var map = DbMapping.TryGetNodeMap(row); name = map.Name.Sql; var scopeOption = GetTransactionScopeOption(client, map, connectBy); if (Transaction.Current != null) { scopeOption.IsolationLevel = Transaction.Current.IsolationLevel; } using (var scope = new TransactionScope(TransactionScopeOption.Required, scopeOption)) { Crud.InsertGo <T>(client, row, false, connectBy); ((INode)row).InsertGraph(client, connectBy); scope.Complete(); } return(new Result <T>(true, -1)); } catch (QueryTalkException) { throw; } catch (System.Exception ex) { throw Crud.ClrException(ex, name, Text.Method.InsertCascadeGo); } }
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); }
internal static void ThrowInvalidQuantifierException( Predicate predicate, DbNode subject, ISemantic predicateSentence, DbNode intermediate, string predicateExpression) { DbNode predicateNode = null; if (predicateSentence != null) { predicateNode = (predicateSentence.Subject != null) ? predicateSentence.Subject : null; } if (intermediate != null) { throw new QueryTalkException("Translate.ThrowInvalidQuantifierException", QueryTalkExceptionType.QuantifierDisallowed, String.Format("subject = {0}{1} predicate node (intermediate) = {5}{1} given predicate node = {2}{1} predicate expression = {3}{1} quantifier = {4}", subject != null ? DbMapping.GetNodeName(subject.NodeID).Sql : Text.NotAvailable, Environment.NewLine, predicateNode != null ? DbMapping.GetNodeName(predicateNode.NodeID).Sql : Text.NotAvailable, predicateExpression != null ? predicateExpression : Text.NotAvailable, predicate.Quantifier != null ? predicate.Quantifier.QuantifierType.ToString() : Text.NotAvailable, intermediate.Name), Text.Method.PredicateMethod).SetExtra("Pay attention to the intermediate predicate node which was provided by the library since the subject and the given predicate node are not related directly to each other."); } else { throw new QueryTalkException("Translate.ThrowInvalidQuantifierException", QueryTalkExceptionType.QuantifierDisallowed, String.Format("subject = {0}{1} predicate node = {2}{1} predicate expression = {3}{1} quantifier = {4}", subject != null ? DbMapping.GetNodeName(subject.NodeID).Sql : Text.NotAvailable, Environment.NewLine, predicateNode != null ? DbMapping.GetNodeName(predicateNode.NodeID).Sql : Text.NotAvailable, predicateExpression != null ? predicateExpression : Text.NotAvailable, predicate.Quantifier != null ? predicate.Quantifier.QuantifierType.ToString() : Text.NotAvailable), Text.Method.PredicateMethod); } }
internal static void Finalize(DbNode predecessor, DbNode currentNode, ref Chainer query) { if (!currentNode.IsFinalizeable) { return; } predecessor = predecessor.SetSynonymOrThis(); currentNode = currentNode.SetSynonymOrThis(); var foreignKey = currentNode.GetFK(); var relation = DbMapping.GetRelation(currentNode.NodeID, predecessor.NodeID, foreignKey); var relationExpression = relation.BuildRelation(currentNode.NodeID, currentNode.Index, predecessor.Index).E(); if (query is ConditionChainer) { query = ((ConditionChainer)query).AndWhere(relationExpression, true); } else { query = ((IWhere)query).Where(relationExpression, true); } }
internal string BuildRelation(DB3 table1, string alias1, string alias2) { string aliasA, aliasB; if (table1.TableID.Equals(ID.TableID) && !IsSelfRelation) { aliasA = alias1; aliasB = alias2; } else { aliasA = alias2; aliasB = alias1; } var sql = Text.GenerateSql(70); for (int i = 0; i < FKColumns.Count(); ++i) { if (i > 0) { sql.Append(Text._And_); } var columnA = DbMapping.GetColumnMap(FKColumns[i]); var columnB = DbMapping.GetColumnMap(RefColumns[i]); sql .AppendFormat("[{0}].{1} = [{2}].{3}", aliasA, columnA.Name.Sql, aliasB, columnB.Name.Sql); } return(sql.ToString()); }
/// <summary> /// Adds a graph invoker to the mapping data. /// </summary> /// <param name="invoker">A mapping object of a graph invoker.</param> public static void AddGraphInvoker(GraphInvoker invoker) { DbMapping.AddGraphInvoker(invoker); }
/// <summary> /// Adds a node invoker to the mapping data. /// </summary> /// <param name="invoker">A mapping object of an invoker.</param> public static void AddNodeInvoker(NodeInvoker invoker) { DbMapping.AddNodeInvoker(invoker); }
/// <summary> /// Adds a link to the mapping data. /// </summary> /// <param name="link">A link mapping object.</param> public static Link AddLink(Link link) { return(DbMapping.AddLink(link)); }
/// <summary> /// Adds a node to the mapping data. /// </summary> /// <param name="map">A node mapping object.</param> public static void AddNode(NodeMap map) { DbMapping.AddNode(map); }
/// <summary> /// Adds a row type to the mapping data. /// </summary> /// <param name="type">A type of the row.</param> /// <param name="nodeID">A node mapping identifier that row belongs to.</param> public static void AddRowType(Type type, DB3 nodeID) { DbMapping.AddRowType(type, nodeID); }
/// <summary> /// Adds a database to the mapping data. /// </summary> /// <param name="map">A database mapping object.</param> public static DatabaseMap AddDatabase(DatabaseMap map) { return(DbMapping.AddDatabase(map)); }