private static void InsertionSort(ONOrderCriteria comparer, long l, long r, ONInstance[] a, long[] p) { long lLp; long lRp; long lTmp; ONInstance lT; //RP points to the first unsorted key. for (lRp = l + 1; lRp <= r; lRp++) { //Get the new value. lTmp = p[lRp]; lT = a[lTmp]; //Compare it back thru the sorted part as long as it's bigger. for (lLp = lRp; lLp <= l + 1; lLp--) { if (comparer.Compare(lT, a[p[lLp - 1]]) < 0) { p[lLp] = p[lLp - 1]; } else { break; } } //It's bigger than all keys to the left, so insert it here. p[lLp] = lTmp; } }
/// <summary> /// Sorts the instances of the collection atending to a comparer /// </summary> /// <param name="comparer">Element needed to compare the instances of the collection</param> public void Sort(IComparer comparer) { ONOrderCriteria lComparer = comparer as ONOrderCriteria; // Only SQL sort if ((lComparer == null) || !lComparer.InMemory) { return; } // Initialize Temp variables ONInstance[] lA = Array; long[] lP = new long[Count]; for (long i = 0; i < Count; i++) { lP[i] = i; } long[] lQ = new long[Count]; // Initialize ONComparer if ((lComparer == null) || !lComparer.InDataIni) { Sort(comparer as ONOrderCriteria, 0, Count - 1, lA, lP, lQ); } else { // Sort if there's SQL optimization long lIni = 0; long lEnd = 0; ONInstance lInstanceIni = null; foreach (ONInstance lInstanceEnd in this) { if (lComparer.CompareSql(lInstanceEnd, lInstanceIni) != 0) { if (lIni < lEnd - 1) { Sort(lComparer, lIni, lEnd - 1, lA, lP, lQ); } lIni = lEnd; lInstanceIni = lInstanceEnd; } lEnd++; } if (lIni < lEnd - 1) { Sort(lComparer, lIni, lEnd - 1, lA, lP, lQ); } } // Update the list Clear(); for (long i = 0; i < lA.Length; i++) { Add(lA[lP[i]]); } }
///<summary> This method adds the order criteria to the SQL statement </summary> ///<param name = "onSql"> This parameter represents the SQL component </param> ///<param name = "comparer"> This parameter has all the information refering to the order criteria to add to SQL statement</param> /// <param name="startRowOid">This parameter has the OID necessary to start the search</param> /// <param name="blockSize">This parameter represents the number of instances to be returned</param> protected override void AddOrderCriteria(ONSqlSelect onSql, ONOrderCriteria comparer, ONOid startRowOid, int blockSize, ONPath initialPath) { //Initilizate StartRow AeronaveInstance lInstance = null; if (startRowOid != null) { lInstance = new AeronaveInstance(OnContext); lInstance.Oid = startRowOid as AeronaveOid; } //Default OrderCriteria if (comparer == null) { string lAlias = onSql.GetAlias("Aeronave", initialPath); if (lInstance != null) { onSql.AddOrderBy(lAlias, CtesBD.FLD_AERONAVE_ID_AERONAVE, OrderByTypeEnumerator.Asc, lInstance.Oid.Id_AeronaveAttr); } else { onSql.AddOrderBy(lAlias, CtesBD.FLD_AERONAVE_ID_AERONAVE, OrderByTypeEnumerator.Asc, null); } return; } //Add OrderCriteria bool lUseStartRow = (!comparer.InMemory); foreach (ONOrderCriteriaItem lOrderCriteriaItem in comparer.OrderCriteriaSqlItem) { ONPath lPath = new ONPath(lOrderCriteriaItem.OnPath); if ((lInstance != null) && (lUseStartRow)) { ONSimpleType lAttrStartRow = null; if (lPath.Path == "") { lAttrStartRow = lInstance[lOrderCriteriaItem.Attribute] as ONSimpleType; } else { ONCollection lCollection = (lInstance[lPath.Path] as ONCollection); if ((lCollection != null) && (lCollection.Count > 0)) { lAttrStartRow = lCollection[0][lOrderCriteriaItem.Attribute] as ONSimpleType; } } onSql.AddOrderBy(AeronaveData.AddPath(onSql, JoinType.LeftJoin, lOrderCriteriaItem.Facet, lPath, null, lOrderCriteriaItem.DomainArgument, false), lOrderCriteriaItem.Attribute, lOrderCriteriaItem.Type, lAttrStartRow); lUseStartRow = (lAttrStartRow != null); } else { onSql.AddOrderBy(AeronaveData.AddPath(onSql, JoinType.LeftJoin, lOrderCriteriaItem.Facet, lPath, null, lOrderCriteriaItem.DomainArgument, false), lOrderCriteriaItem.Attribute, lOrderCriteriaItem.Type, null); } } return; }
// InsertionSort. A simple routine with minimal overhead. Should never be used // to sort long lists because of its O(N^2) behavior, // but is the method of choice for sorting short (5-50 key) lists or long lists // that have been mostly sorted by a faster algorithm. InsertionSort is faster // than either Bubble or SelectionSort and should be used anywhere you would // consider using those. Sorts in place (no extra memory needed) and is stable // (preserves the original order of records with equal keys). Works by creating // a sorted list at the beginning of the array of keys. As each unsorted key to // the right is examined, it is compared back thru the sorted list until the // right position to insert it is found. Two versions are given. pInsertS is // an indirect (pointerized) version for strings, // which can be adapted to doubles by changing the declaration of A(). InsertL // is a direct version for longs, which can be adapted to integers. // // Speed: Abysmally slow for anything but short lists. // // Bottom line: should be used only to finish up for faster sorts with higher // overhead; for that purpose, this is the sort to choose. public void InsertionSort(ONOrderCriteria comparer, long l, long r) { long[] lP = new long[r + 1]; for (int i = 0; i < r; i++) { lP[i] = i; } InsertionSort(comparer, l, r, Array, lP); }
// 2/4/03. The previous version of ShuttleMergeSort failed on very short lists. // The code below corrects the problem and eliminates a couple of unnecessary // variables. Sorting times for one million random longs, // double or strings are 67, 90 and 95 seconds (Excel 2001 / 800 mhz PowerBook / // MacOS 10.2.3). // 1/7/03. Here is a 20-25% faster version of MergeSort. The old version // merged into an auxiliary array, and copied the result back to the primary // array at the end of each pass. This version plans ahead for an even number // of passes, and alternates direction each time, first merging to the auxiliary // array and then back to the primary array. It also replaces recursive calls // with an explicit stack, and calls to a separate InsertionSort with in-line // code. Because of the back and forth merging, // I call this version "ShuttleMergeSort". // Another frequently proposed optimization for MergeSort is to set runs up in // alternating directions (low to high, then high to low). This allows // replacing separate boundary tests for LP and RP with a single test for LP // crossing RP. I tried this, and it wasn//t faster in practice. Probably the // gain from fewer loop tests was offset by time spent in extra comparisons; in // the simpler version, when one run is used up, the rest of the other run is // copied to the output array with no further comparisons. Also, // the run-alternating version was significantly slower on presorted inputs, // which often occur in practice. // QuickSort is still faster for strings (64 sec vs. 95), // but MergeSort is faster for doubles (90 sec vs. 162) and longs (67 sec vs. // 116). Given that MergeSort is stable and guaranteed NlogN, // while QuickSort is unstable and always has an N^2 worst case, // MergeSort is my choice for a single all-purpose sort. // The first example below is a pointerized version for strings. It can be // adapted to doubles by changing the declaration of A() and T. The second // example is a direct version for longs that can be adapted to integers. public void ShuttleMergeSort(ONOrderCriteria comparer, long l, long r) { long[] lP = new long[r + 1]; for (long i = l; i <= r; i++) { lP[i] = i; } long[] lQ = new long[r + 1]; ONInstance[] lA = Array; // Sort ShuttleMergeSort(comparer, l, r, lA, lP, lQ); // Update the list Clear(); for (long i = l; i <= r; i++) { Add(lA[lP[i]]); } }
/// <summary> This method adds the order criteria to the SQL statement </summary> /// <param name="onSql"> This parameter represents the SQL component </param> /// <param name="comparer"> This parameter has all the information refering to the order criteria to add to SQL statement</param> /// <param name="startRowOid">This parameter has the OID necessary to start the search</param> /// <param name="blockSize">This parameter represents the number of instances to be returned</param> /// <param name="initialPath"> This parameter has the path of the instances reached in a For All</param> protected virtual void AddOrderCriteria(ONSqlSelect onSql, ONOrderCriteria comparer, ONOid startRowOid, int blockSize, ONPath initialPath) { }
/// <summary> This method adds the order criteria to the SQL statement </summary> /// <param name="onSql"> This parameter represents the SQL component </param> /// <param name="comparer"> This parameter has all the information refering to the order criteria to add to SQL statement</param> /// <param name="startRowOid">This parameter has the OID necessary to start the search</param> /// <param name="blockSize">This parameter represents the number of instances to be returned</param> public void AddOrderCriteria(ONSqlSelect onSql, ONOrderCriteria comparer, ONOid startRowOid, int blockSize) { AddOrderCriteria(onSql, comparer, startRowOid, blockSize, null); }
/// <summary> /// Retrieve all the instances of a determinate class that fulfil a determinate formula of searching /// </summary> /// <param name="linkedTo">List to reach the class to retrieve the related instance</param> /// <param name="filters">Formula to search concrete instances</param> /// <param name="comparer">Order Criteria that must be followed by the query</param> /// <param name="startRowOid">OID frontier</param> /// <param name="blockSize">Number of instances to be returned</param> /// <returns>Instances that check the filter list</returns> protected virtual ONCollection SolveQuery(ONLinkedToList linkedTo, ONFilterList onFilterList, ONDisplaySet displaySet, ONOrderCriteria comparer, ONOid startRowOid, int blockSize) { ONSqlSelect lOnSql = new ONSqlSelect(); try { // Create select and first table InhRetrieveInstances(lOnSql, displaySet, null, OnContext); // Fix related instance if (!AddLinkedTo(lOnSql, linkedTo)) { return(ONContext.GetComponent_Collection(ClassName, OnContext)); } // Add filter formula if (onFilterList != null) { onFilterList.FilterInData(lOnSql, this); } // Retrieve query instance number int lTotalNumInstances = -1; if (OnContext.CalculateQueryInstancesNumber) { if ((onFilterList == null) || (!onFilterList.InMemory)) { ArrayList lSqlParameters; string lNumInstancesSqlSentence = ONSqlSelect.GenerateSQLAsCount(lOnSql, out lSqlParameters); lTotalNumInstances = Convert.ToInt32(ExecuteScalar(lNumInstancesSqlSentence, lSqlParameters)); } OnContext.CalculateQueryInstancesNumber = false; } // OrderCriteria AddOrderCriteria(lOnSql, comparer, startRowOid, blockSize); // Execute ONCollection lONCollection = ExecuteSql(lOnSql, onFilterList, displaySet, comparer, startRowOid, blockSize); // Set Query instance number if (lTotalNumInstances > -1) { lONCollection.totalNumInstances = lTotalNumInstances; } return(lONCollection); } catch (Exception e) { string ltraceItem = "Method: SolveQuery, Component: ONDBData"; if (e is ONSystemException) { ONSystemException lException = e as ONSystemException; lException.addTraceInformation(ltraceItem); throw lException; } throw new ONSystemException(e, ltraceItem); } }
/// <summary> /// Retrieve all the instances of a determinate class that fulfil a determinate formula of searching /// </summary> /// <param name="linkedTo">List to reach the class to retrieve the related instance</param> /// <param name="filters">Formula to search concrete instances</param> /// <param name="comparer">Order Criteria that must be followed by the query</param> /// <param name="startRowOID">OID frontier</param> /// <param name="blockSize">Number of instances to be returned</param> public override ONCollection ExecuteQuery(ONLinkedToList linkedTo, ONFilterList filters, ONDisplaySet displaySet, ONOrderCriteria comparer, ONOid startRowOid, int blockSize) { try { ONCollection lInstances = null; Type lTypeInstance = ONContext.GetType_Instance(ClassName); Type lTypeQuery = ONContext.GetType_Query(ClassName); // Initialize the list of related queries if (linkedTo == null) { linkedTo = new ONLinkedToList(); } // Initialize the filter list if (filters == null) { filters = new ONFilterList(); } ONLinkedToList lLinkedToLegacy = new ONLinkedToList(); ONLinkedToList lLinkedToLocal = new ONLinkedToList(); ONLinkedToList lLinkedToMixed = new ONLinkedToList(); #region Treatment of LinkedTo foreach (KeyValuePair <ONPath, ONOid> lDictionaryEntry in linkedTo) { ONPath lPath = lDictionaryEntry.Key as ONPath; ONOid lOid = lDictionaryEntry.Value as ONOid; ONPath lInversePath = new ONPath(ONInstance.InversePath(lTypeInstance, lPath)); Type lTypeTargetClassInstance = ONContext.GetType_Instance(ONInstance.GetTargetClass(OnContext, lTypeInstance, lPath)); if ((lInversePath.Count == 0) || (!ONInstance.IsVisible(lTypeTargetClassInstance, lInversePath, OnContext))) { return(ONContext.GetComponent_Collection(ClassName, OnContext)); } bool lexistLV = false; ONData lData = ONContext.GetComponent_Data(InhGetTargetClassName(lPath), OnContext); if (lData.GetType().BaseType == typeof(ONLVData)) { if (!lOid.Exist(OnContext, null)) { return(ONContext.GetComponent_Collection(ClassName, OnContext)); } } foreach (string lRole in lInversePath.Roles) { lData = ONContext.GetComponent_Data(lData.InhGetTargetClassName(new ONPath(lRole)), OnContext); if (lData.GetType().BaseType == typeof(ONLVData)) { lexistLV = true; } } if (!lexistLV) { lLinkedToLocal.mLinkedToList.Add(lPath, lOid); } else { lLinkedToMixed.mLinkedToList.Add(lPath, lOid); } } #endregion #region displaySet if (!filters.PreloadRelatedAttributes) { displaySet = null; } #endregion displaySet #region No link item if ((linkedTo.mLinkedToList.Count == 0) || (lLinkedToMixed.mLinkedToList.Count > 0)) { if ((GetType().BaseType != typeof(ONLVData)) || (filters.InData)) { lInstances = SolveQuery(new ONLinkedToList(), filters, displaySet, comparer, startRowOid, blockSize); } } #endregion #region Local Link if (lLinkedToLocal.mLinkedToList.Count > 0) { ONCollection lInstancesAux = SolveQuery(lLinkedToLocal, filters, displaySet, comparer, startRowOid, blockSize); if (lInstances != null) { lInstances.Intersection(lInstancesAux); } else { lInstances = lInstancesAux; } } #endregion #region Hybrid Link if (lLinkedToMixed.mLinkedToList.Count > 0) { ONCollection lInstancesAux = null; foreach (KeyValuePair <ONPath, ONOid> lDictionaryEntry in lLinkedToMixed) { ONPath lPath = lDictionaryEntry.Key as ONPath; ONOid lOid = lDictionaryEntry.Value as ONOid; if (lPath.Roles.Count == 1) { ONLinkedToList lLinked = new ONLinkedToList(); lLinked[lPath] = lOid; ONCollection lInstanceColl = SolveQuery(lLinked, filters, displaySet, comparer, startRowOid, blockSize); if (lInstances != null) { lInstances.Intersection(lInstanceColl); } else { lInstances = lInstanceColl; } continue; } #region Optimized Path ONLinkedToList linkedToOptimized = new ONLinkedToList(); ONPath lInversePath = new ONPath(ONInstance.InversePath(lTypeInstance, lPath)); ONPath lOptimizedRole = new ONPath(lInversePath.RemoveHead() as string); Type lTypeInstanceDestiny = ONContext.GetType_Instance(InhGetTargetClassName(lPath)); bool lBeginIsLegacy = (ONInstance.IsLegacy(lTypeInstanceDestiny, lOptimizedRole)); bool lEnterLoop = true; ONData lData = ONContext.GetComponent_Data(InhGetTargetClassName(lPath), OnContext); if (lData.GetType().BaseType != typeof(ONLVData)) { if (ONContext.GetType_Data(lData.InhGetTargetClassName(lOptimizedRole)).BaseType == typeof(ONLVData)) { lEnterLoop = false; } } lPath.RemoveTail(); if (lEnterLoop) { while (lInversePath.Roles.Count > 0) { lData = ONContext.GetComponent_Data(InhGetTargetClassName(lPath), OnContext); if ((!lBeginIsLegacy) && (ONContext.GetType_Data(lData.InhGetTargetClassName(new ONPath(lInversePath.Roles[0]))).BaseType == typeof(ONLVData))) { break; } if ((lBeginIsLegacy) && (ONContext.GetType_Data(lData.InhGetTargetClassName(new ONPath(lInversePath.Roles[0]))).BaseType != typeof(ONLVData))) { break; } lOptimizedRole.Roles.Add(lInversePath.RemoveHead()); lPath.RemoveTail(); } } linkedToOptimized[ONInstance.InversePath(lTypeInstanceDestiny, lOptimizedRole)] = lOid; if ((lPath.Count > 0) || (lBeginIsLegacy)) { // It is not the last role or it is leged lInstancesAux = ONContext.GetComponent_Data(InhGetTargetClassName(lPath), OnContext).ExecuteQuery(linkedToOptimized, null, null, comparer, startRowOid, blockSize); } else { // It is the last role and it is local lInstancesAux = ONContext.GetComponent_Data(InhGetTargetClassName(lPath), OnContext).ExecuteQuery(linkedToOptimized, null, displaySet, comparer, startRowOid, blockSize); } #endregion #region Rest of the path lInstancesAux = lInstancesAux[lInversePath] as ONCollection; #endregion if (lInstances != null) { lInstances.Intersection(lInstancesAux); } else { lInstances = lInstancesAux; } } } #endregion return(lInstances); } catch (Exception e) { string ltraceItem = "Method: SolveQuery, Component: ONDBData"; if (e is ONSystemException) { ONSystemException lException = e as ONSystemException; lException.addTraceInformation(ltraceItem); throw lException; } throw new ONSystemException(e, ltraceItem); } }
/// <summary> /// Execution of a sql /// </summary> /// <param name="onSql">Sentence SQL to be executed</param> /// <param name="onFilterList">List of filters to check</param> /// <param name="comparer">Order Criteria that must be followed by the query</param> /// <param name="startRowOID">OID frontier</param> /// <param name="blockSize">Number of instances to be returned</param> public virtual ONCollection ExecuteSql(ONSql onSql, ONFilterList onFilterList, ONDisplaySet displaySet, ONOrderCriteria comparer, ONOid startRowOID, int blockSize) { return(null); }
private static void ShuttleMergeSort(ONOrderCriteria comparer, long lO, long hI, ONInstance[] a, long[] p, long[] q) { //lO and hI point to first and last keys; a() is the buffer of string keys. //p() and q() are buffers of pointers to the keys in a() double lLength; //length of initial runs to be made by InsertionSort long lNRuns; //the number of runs at each stage long[] lStack; //bookkeeping stack for merge passes long lI; long lL; //left limit long lR; //right limit long lLp; //left pointer long lRp; //right pointer long lOp; //other pointer ONInstance lTmp; long lLongTmp; bool lForward; //toggle for direction of alternate merge passes //Calculate how many merge passes will be needed. //Each back & forth pair of merges will convert 4N sublists into N. lLength = 1 + hI - lO; lNRuns = 1; while (lLength > 20) { lLength = lLength / 4; lNRuns = lNRuns * 4; } //Set up stack to keep track of sublists being merged. lStack = new long[lNRuns]; for (lI = 0; lI < lNRuns - 1; lI++) { lStack[lI] = lO + Convert.ToInt64(lLength * (lI + 1)); } lStack[lNRuns - 1] = hI; //Build short runs using low overhead InsertionSort. lL = lO; for (lI = 0; lI < lNRuns; lI++) { lR = lStack[lI]; for (lRp = lL + 1; lRp <= lR; lRp++) { lOp = p[lRp]; lTmp = a[lOp]; for (lLp = lRp; lLp >= lL + 1; lLp--) { if (comparer.Compare(lTmp, a[p[lLp - 1]]) < 0) { p[lLp] = p[lLp - 1]; } else { break; } } p[lLp] = lOp; } lL = lR + 1; } //Make back & forth passes of MergeSort until all runs are merged. lForward = true; while (lNRuns > 1) { lR = lO - 1; if (lForward) { //Half the passes are forward, merging from p() into q(). for (lI = 1; lI < lNRuns; lI += 2) { lLp = lR + 1; lOp = lLp; lL = lStack[lI - 1]; lRp = lL + 1; lR = lStack[lI]; do { if (comparer.Compare(a[p[lLp]], a[p[lRp]]) <= 0) { q[lOp] = p[lLp]; lOp = lOp + 1; lLp = lLp + 1; if (lLp > lL) { do { q[lOp] = p[lRp]; lOp = lOp + 1; lRp = lRp + 1; } while (!(lRp > lR)); break; } } else { q[lOp] = p[lRp]; lOp = lOp + 1; lRp = lRp + 1; if (lRp > lR) { do { q[lOp] = p[lLp]; lOp = lOp + 1; lLp = lLp + 1; } while (!(lLp > lL)); break; } } } while (true); lStack[Math.DivRem(lI + 1, 2, out lLongTmp) - 1] = lR; } } else { //Half the passes are backward, merging from q() into p(). for (lI = 1; lI < lNRuns; lI += 2) { lLp = lR + 1; lOp = lLp; lL = lStack[lI - 1]; lRp = lL + 1; lR = lStack[lI]; do { if (comparer.Compare(a[q[lLp]], a[q[lRp]]) <= 0) { p[lOp] = q[lLp]; lOp = lOp + 1; lLp = lLp + 1; if (lLp > lL) { do { p[lOp] = q[lRp]; lOp = lOp + 1; lRp = lRp + 1; } while (!(lRp > lR)); break; } } else { p[lOp] = q[lRp]; lOp = lOp + 1; lRp = lRp + 1; if (lRp > lR) { do { p[lOp] = q[lLp]; lOp = lOp + 1; lLp = lLp + 1; } while (!(lLp > lL)); break; } } } while (true); lStack[Math.DivRem(lI + 1, 2, out lLongTmp) - 1] = lR; } } //After each merge, we have half as many runs and we switch direction. lNRuns = Math.DivRem(lNRuns, 2, out lLongTmp); lForward = !lForward; } }
public virtual ONCollection ExecuteQuery(ONSql onSql, ONFilterList onFilterList, ONOrderCriteria comparer, ONOid startRowOID, int blockSize, ONInstance instance) { return(null); }
/// <summary> /// Adds an instance to the collection in the order that the Order Criteria sets. /// </summary> /// <param name="instance">Instance to add</param> /// <param name="comparer">Order criteria to apply</param> /// <param name="onContext">context of the query</param> public void AddOrdered(ONInstance instance, ONOrderCriteria comparer, ONContext onContext) { // Empty lists if (Count == 0) { Add(instance); return; } int i = 0; int j = 0; int lComparation = 0; // Clone and clear collection ONCollection lList = Clone() as ONCollection; this.Clear(); // Create data component for default comparation ONData lData = null; if (comparer == null) { lData = ONContext.GetComponent_Data(ClassName, onContext); } ONInstance lInstance1 = lList.Array[i]; while ((i < lList.Count) && (j < 1)) { if (comparer != null) { lComparation = comparer.CompareUnion(lInstance1, instance); } else { lComparation = lData.CompareUnionOID(lInstance1, instance); } if (lComparation < 0) { Add(lInstance1); i += 1; if (lList.Count > i) { lInstance1 = lList.Array[i]; } } else if (lComparation > 0) { Add(instance); j += 1; } else { Add(lInstance1); Add(instance); i += 1; j += 1; } } AddRange(lList); if (j == 0) { Add(instance); } }
/// <summary> /// Sorts the instances of the collection atending to a comparer /// </summary> /// <param name="comparer">Element needed to compare the instances of the collection</param> /// <param name="ini">Initial instance to start the sort of the instances</param> /// <param name="end">Final innstace to delimit the sort of the instances</param> /// <param name="A"></param> /// <param name="P"></param> /// <param name="Q"></param> public void Sort(ONOrderCriteria comparer, long ini, long end, ONInstance[] A, long[] P, long[] Q) { ShuttleMergeSort(comparer, ini, end, A, P, Q); }
public override ONCollection ExecuteQuery(ONLinkedToList linkedTo, ONFilterList filters, ONDisplaySet displaySet, ONOrderCriteria comparer, ONOid startRowOid, int blockSize) { ONCollection lInstances = null; Type lTypeInstance = ONContext.GetType_Instance(ClassName); ONLinkedToList lLinkedToLegacy = new ONLinkedToList(); ONLinkedToList lLinkedToLocal = new ONLinkedToList(); if (linkedTo == null) { linkedTo = new ONLinkedToList(); } if (filters == null) { filters = new ONFilterList(); } #region Treatment of LinkedTo foreach (KeyValuePair <ONPath, ONOid> lDictionaryEntry in linkedTo) { ONPath lPath = lDictionaryEntry.Key as ONPath; ONOid lOid = lDictionaryEntry.Value as ONOid; if (ONInstance.IsLegacy(lTypeInstance, lPath)) { lLinkedToLegacy.mLinkedToList.Add(lPath, lOid); } else { lLinkedToLocal.mLinkedToList.Add(lPath, lOid); } } #endregion Treatment of LinkedTo ONFilterList lFiltersToLegacy = new ONFilterList(); ONFilterList lFiltersToLocal = new ONFilterList(); #region Treatment of Filters ONFilterList lFiltersToMixed = new ONFilterList(); foreach (ONFilter lFilter in filters.Values) { if (lFilter.InLegacy) { lFiltersToLegacy.Add(lFilter.FilterName, lFilter); } else { lFiltersToLocal.Add(lFilter.FilterName, lFilter); } } #endregion Treatment of Filters if ((lFiltersToLegacy.Count <= 1) && (lFiltersToLocal.Count == 0) && (lLinkedToLocal.mLinkedToList.Count == 0)) { #region No leged filters if (lFiltersToLegacy.Count == 0) { QueryByRelatedFilter lFilter = new QueryByRelatedFilter(ClassName, null, null); lInstances = lFilter.FilterInLegacy(OnContext, lLinkedToLegacy, comparer, startRowOid, (blockSize == 0 ? 0 : blockSize + 1)); } #endregion No leged filters #region Solve leged filters foreach (ONFilter lFilter in lFiltersToLegacy.Values) { ONCollection lInstancesAux = lFilter.FilterInLegacy(OnContext, lLinkedToLegacy, comparer, startRowOid, (blockSize == 0 ? 0 : blockSize + 1)); if (lInstances == null) { lInstances = lInstancesAux; } else { lInstances.Intersection(lInstancesAux); } } #endregion Solve leged filters if ((lInstances.totalNumInstances == -1) && (lInstances.Count <= blockSize) && ((startRowOid == null).TypedValue)) { lInstances.totalNumInstances = lInstances.Count; } } else { #region Solve leged filters foreach (ONFilter lFilter in lFiltersToLegacy.Values) { ONCollection lInstancesAux = lFilter.FilterInLegacy(OnContext, lLinkedToLegacy, comparer, null, 0); if (lInstances == null) { lInstances = lInstancesAux; } else { lInstances.Intersection(lInstancesAux); } } #endregion Solve leged filters #region Solve local filters in data if ((lFiltersToLocal.InData) || (lLinkedToLocal.mLinkedToList.Count > 0)) { ONCollection lInstancesAux = base.ExecuteQuery(lLinkedToLocal, lFiltersToLocal, displaySet, null, null, 0); if (lInstances == null) { lInstances = lInstancesAux; } else { lInstances.Intersection(lInstancesAux); } } #endregion Solve local filters in data #region No leged filters if (lFiltersToLegacy.Count == 0) { int maxNumberQueries = Convert.ToInt32(ONContext.GetType_LV(ClassName).GetField("maxNumberQueries").GetValue(null)); if ((lInstances == null || lInstances.Count > maxNumberQueries) || (lLinkedToLegacy.mLinkedToList.Count > 0) || (comparer != null)) { ONCollection lInstancesAux = lInstances; QueryByRelatedFilter lFilter = new QueryByRelatedFilter(ClassName, null, null); lInstances = lFilter.FilterInLegacy(OnContext, lLinkedToLegacy, comparer, null, 0); if (lInstancesAux != null) { lInstances.Intersection(lInstancesAux); } } else { ONCollection lInstancesAux = ONContext.GetComponent_Collection(ClassName, OnContext); foreach (object lobject in lInstances) { ONInstance lInstance = lobject as ONInstance; QueryByOidFilter lFilter = new QueryByOidFilter(lInstance.Oid); lInstancesAux.AddRange(lFilter.FilterInLegacy(OnContext, null, null, null, 0)); } lInstances = lInstancesAux.Clone() as ONCollection; } } #endregion No leged filters #region Solve local filters in memory if ((lInstances != null) && (lFiltersToLocal.InMemory)) { ONCollection lInstancesAux = lInstances; lInstances = ONContext.GetComponent_Collection(ClassName, OnContext); foreach (ONInstance lInstance in lInstancesAux) { if (lFiltersToLocal.FilterInMemory(lInstance)) { lInstances.Add(lInstance); } } } #endregion Solve local filters in memory lInstances.totalNumInstances = lInstances.Count; } return(lInstances); }
/// <summary> /// Executes the SQL statment over the Data Base connected /// </summary> /// <param name="onSql">This parameter has the current SQL statment</param> /// <param name="onFilterList">List of filters to check</param> /// <param name="comparer">This parameter has all the information refering to the order criteria to add to SQL statment</param> /// <param name="startRowOid">This parameter has the OID necessary to start the search</param> /// <param name="blockSize">This parameter represents the number of instances to be returned</param> public override ONCollection ExecuteSql(ONSql onSql, ONFilterList onFilterList, ONDisplaySet displaySet, ONOrderCriteria orderCriteria, ONOid startRowOid, int blockSize) { AeronaveCollection lQuery = null; bool lWithStartRow = (startRowOid != null).TypedValue; long lCount = -1; if (!lWithStartRow) { lCount = 0; } IDataReader lDataReader = null; ONSQLConnection lOnSQLConnection = null; try { lDataReader = Execute(onSql) as IDataReader; AeronaveInstance lInstance = null; AeronaveInstance lAntInstance = null; if (lDataReader != null) { object[] lColumns; if (displaySet == null) { lColumns = new object[4]; } else { lColumns = new object[displaySet.ElementsInData]; } lQuery = new AeronaveCollection(OnContext); bool lFoundStartRow = false; while (lDataReader.Read()) { lAntInstance = lInstance; // Read Columns lDataReader.GetValues(lColumns); // Read Instance int lIndex = 0; lInstance = LoadFacet(OnContext, displaySet, lColumns, ref lIndex); // Read related attributes if (displaySet != null) { LoadRelated(OnContext, displaySet, lColumns, lIndex, lInstance); } if (lCount >= 0) // Add the load instance { if ((onFilterList == null) || (!onFilterList.InMemory)) { // Add to the Instance list lQuery.Add(lInstance); lCount++; } else { ONSQLConnection lSQLConnectionOld = (ONSQLConnection)lInstance.OnContext.SqlConnection; // Set another connection because it is imposible to use // the same connection that is used in the DataReader if (lOnSQLConnection == null) { lOnSQLConnection = GetConnection(); } lInstance.OnContext.SqlConnection = lOnSQLConnection; if (onFilterList.FilterInMemory(lInstance)) { // Add to the Instance list lQuery.Add(lInstance); lCount++; } lInstance.OnContext.SqlConnection = lSQLConnectionOld; } } else { if ((orderCriteria != null) && (orderCriteria.InMemory)) // Need to load for ordering in memory after loading { if (lAntInstance != null) { // Set another connection because it is imposible to use // the same connection that is used in the DataReader ONSQLConnection lOnSQLConnectionOld = lInstance.OnContext.SqlConnection as ONSQLConnection; if (lOnSQLConnection == null) { lOnSQLConnection = GetConnection(); } lInstance.OnContext.SqlConnection = lOnSQLConnection; int lCompare = orderCriteria.CompareSql(lInstance, lAntInstance); if (lCompare != 0) { if (lFoundStartRow) { lCount = 1; } else { lQuery.Clear(); } } // Restores the old connection lInstance.OnContext.SqlConnection = lOnSQLConnectionOld; } if ((onFilterList == null) || (!onFilterList.InMemory)) { // Add to the Instance list lQuery.Add(lInstance); } else { ONSQLConnection lSQLConnectionOld = (ONSQLConnection)lInstance.OnContext.SqlConnection; // Set another connection because it is imposible to use // the same connection that is used in the DataReader if (lOnSQLConnection == null) { lOnSQLConnection = GetConnection(); } lInstance.OnContext.SqlConnection = lOnSQLConnection; if (onFilterList.FilterInMemory(lInstance)) { // Add to the Instance list lQuery.Add(lInstance); } else { lCount--; } lInstance.OnContext.SqlConnection = lSQLConnectionOld; } if (lInstance.Oid.Equals(startRowOid)) { lFoundStartRow = true; } } else if (lInstance.Oid.Equals(startRowOid)) // Search the start row { lCount = 0; } } // Stop loading if ((blockSize != 0) && (lCount > blockSize)) { if (orderCriteria == null) { break; } else { // Set another connection because it is imposible to use // the same connection that is used in the DataReader ONSQLConnection lOnSQLConnectionOld = lInstance.OnContext.SqlConnection as ONSQLConnection; if (lOnSQLConnection == null) { lOnSQLConnection = GetConnection(); } lInstance.OnContext.SqlConnection = lOnSQLConnection; int lCompare = orderCriteria.CompareSql(lInstance, lAntInstance); // Restores the old connection lInstance.OnContext.SqlConnection = lOnSQLConnectionOld; if (lCompare > 0) { break; } } } } } } catch (Exception e) { string ltraceItem = "Method: ExecuteSql, Component: AeronaveData"; if (e is ONSystemException) { ONSystemException lException = e as ONSystemException; lException.addTraceInformation(ltraceItem); throw lException; } throw new ONSystemException(e, ltraceItem); } finally { if (lOnSQLConnection != null) { ONDBData.CloseConnection(lOnSQLConnection); } if (lDataReader != null) { if (mSqlCommand != null) { mSqlCommand.Cancel(); } lDataReader.Close(); } Close(); if ((onFilterList != null) && (onFilterList.InMemory) && !lWithStartRow && (lCount <= blockSize)) { lQuery.totalNumInstances = lQuery.Count; } } return(lQuery); }
/// <summary> /// Retrieve all the instances of a determinate class that fulfil a determinate formula of searching /// </summary> /// <param name="linkedTo">List to reach the class to retrieve the related instance</param> /// <param name="filters">Formula to search concrete instances</param> /// <param name="comparer">Order Criteria that must be followed by the query</param> /// <param name="startRowOID">OID frontier</param> /// <param name="blockSize">Number of instances to be returned</param> public abstract ONCollection ExecuteQuery(ONLinkedToList linkedTo, ONFilterList filters, ONDisplaySet displaySet, ONOrderCriteria comparer, ONOid startRowOid, int blockSize);