protected void AddFilterToChannel(FrequencyFilter filter, ChannelHandle channel) { if (channel.isRightChannel) { m_filtersRight.Add(filter); m_channelIndicesRight.Add(channel.channelIndex); } else { m_filtersLeft.Add(filter); m_channelIndicesLeft.Add(channel.channelIndex); } }
// 检索 internal override int SearchByUnion( string strOutputStyle, SearchItem searchItem, ChannelHandle handle, // Delegate_isConnected isConnected, DpResultSet resultSet, int nWarningLevel, out string strError, out string strWarning) { strError = ""; strWarning = ""; //************对数据库加读锁************** m_db_lock.AcquireReaderLock(m_nTimeOut); #if DEBUG_LOCK this.container.WriteDebugInfo("SearchByUnion(),对'" + this.GetCaption("zh-CN") + "'数据库加读锁。"); #endif try { int nRet; bool bHasID; List<TableInfo> aTableInfo = null; nRet = this.TableNames2aTableInfo(searchItem.TargetTables, out bHasID, out aTableInfo, out strError); if (nRet == -1) return -1; if (bHasID == true) { nRet = SearchByID(searchItem, handle, // isConnected, resultSet, out strError); if (nRet == -1) return -1; } if (aTableInfo == null || aTableInfo.Count == 0) { return 0; } for (int i = 0; i < aTableInfo.Count; i++) { TableInfo tableInfo = aTableInfo[i]; ; string strTiaoJian = ""; try { nRet = GetKeyCondition( searchItem, tableInfo.nodeConvertQueryString, tableInfo.nodeConvertQueryNumber, out strTiaoJian, out strError); if (nRet == -1) return -1; } catch (NoMatchException ex) { strWarning += ex.Message; if (nWarningLevel == 0) return -1; } XmlDocument dom = new XmlDocument(); dom.PreserveWhitespace = true; //设PreserveWhitespace为true string strTablePath = this.TableName2TableFileName(tableInfo.SqlTableName); try { dom.Load(strTablePath); } catch (Exception ex) { strError = "加载检索点表'" + tableInfo.SqlTableName + "'到dom出错:" + ex.Message; return -1; } string strXpath = "/root/key[" + strTiaoJian + "]/idstring"; XmlNodeList listIdstring; try { listIdstring = dom.SelectNodes(strXpath); } catch (System.Xml.XPath.XPathException ex) { strError += "Xpath出错:" + strXpath + "-------" + ex.Message + "<br/>"; return -1; } for (int j = 0; j < listIdstring.Count; j++) { string strIdstring = listIdstring[j].InnerText.Trim(); // 2012/2/16 string strId = this.FullID + "/" + strIdstring; resultSet.Add(new DpRecord(strId)); } } //排序 resultSet.Sort(); //去重 resultSet.RemoveDup(); return 0; } finally { //*********对数据库解读锁************ m_db_lock.ReleaseReaderLock(); #if DEBUG_LOCK this.container.WriteDebugInfo("SearchByUnion(),对'" + this.GetCaption("zh-CN") + "'数据库解读锁。"); #endif } }
// 按ID检索记录 // parameter: // searchItem SearchItem对象,包括检索信息 // isConnected 连接对象的delegate // resultSet 结果集对象,存放命中记录 // return: // -1 出错 // 0 成功 // 线:不安全 private int SearchByID(SearchItem searchItem, ChannelHandle handle, // Delegate_isConnected isConnected, DpResultSet resultSet, out string strError) { strError = ""; // 从库目录里得到所有似记录文件 string[] files = Directory.GetFiles(this.m_strSourceFullPath, "??????????.xml"); ArrayList records = new ArrayList(); foreach (string fileName in files) { FileInfo fileInfo = new FileInfo(fileName); string strFileName = fileInfo.Name; if (this.IsRecord(strFileName) == false) continue; records.Add(this.XmlFileName2RecordID(strFileName)); } //前方一致 if (searchItem.Match == "left" || searchItem.Match == "") { foreach (string recordID in records) { if (recordID.Length < searchItem.Word.Length) continue; string strFirstPart = recordID.Substring(0, searchItem.Word.Length); if (strFirstPart == searchItem.Word) { string strRecPath = this.FullID + "/" + recordID; resultSet.Add(new DpRecord(strRecPath)); } } } else if (searchItem.Match == "exact") { // 从检索词时分析出来关系 if (searchItem.Relation == "draw" || searchItem.Relation == "range") { foreach (string recordID in records) { string strStartID; string strEndID; bool bRet = StringUtil.SplitRangeEx(searchItem.Word, out strStartID, out strEndID); if (bRet == true) { strStartID = DbPath.GetID10(strStartID); strEndID = DbPath.GetID10(strEndID); if (String.Compare(recordID, strStartID, true) >= 0 && String.Compare(recordID, strEndID, true) <= 0) { string strRecPath = this.FullID + "/" + recordID; resultSet.Add(new DpRecord(strRecPath)); continue; } } else { string strOperator; string strCanKaoID; StringUtil.GetPartCondition(searchItem.Word, out strOperator, out strCanKaoID); strCanKaoID = DbPath.GetID10(strCanKaoID); if (StringUtil.CompareByOperator(recordID, strOperator, strCanKaoID) == true) { string strRecPath = this.FullID + "/" + recordID; resultSet.Add(new DpRecord(strRecPath)); continue; } } } } else { foreach (string recordID in records) { searchItem.Word = DbPath.GetID10(searchItem.Word); if (StringUtil.CompareByOperator(recordID, searchItem.Relation, searchItem.Word) == true) { string strRecPath = this.FullID + "/" + recordID; resultSet.Add(new DpRecord(strRecPath)); continue; } } } } return 0; }
internal Channel(ChannelHandle handle) : base(handle) { }
// 检索 // parameter: // strOutpuStyle 输出的风格。如果为keycount,则输出归并统计后的key+count;否则,或者缺省,为传统的输出记录id // searchItem SearchItem对象 // isConnected IsConnection对象,用于判断通讯是否连接 // resultSet 结果集对象,存放命中记录。本函数并不在检索前清空结果集,因此,对同一结果集对象多次执行本函数,则可以把命中结果追加在一起 // nWarningLevel 处理警告级别 0:表示特别强烈,出现警告也当作出错;1:表示不强烈,不返回出错,继续执行 // strError out参数,返回出错信息 // strWarning out参数,返回警告信息 // return: // -1 出错 // >=0 命中记录数 // 线: 安全的 internal virtual int SearchByUnion( string strOutputStyle, SearchItem searchItem, ChannelHandle handle, // Delegate_isConnected isConnected, DpResultSet resultSet, int nWarningLevel, out string strError, out string strWarning) { strError = ""; strWarning = ""; return 0; }
// 运算逆波兰表,得到结果集 // parameter: // rpn 逆波兰表 // resultSet 结果集 // return: // 0 成功 // -1 出错 原因可能如下: // 1)rpn参数为null // 2)oResultSet参数为null // 3)栈里的某成员出错(node和result都为null) // 4)从栈中pop()或peek()元素时,出现栈空 // 5)pop的类型,不是实际存在的类型 // 6)通过一个节点,得到结果集,即调DoQuery()函数出错 // 7)做运算时,调DpResultSetManager.Merge()函数出错 // 8)最后栈里的元素多于1,则逆波兰表出错 // 9)最后结果集为空 // -6 无足够的权限 public int ProceedRPN( SessionInfo sessioninfo, string strOutputStyle, ArrayList rpn, ref DpResultSet resultSet, ChannelHandle handle, // Delegate_isConnected isConnected, out string strError) { DateTime start_time = DateTime.Now; Debug.WriteLine("Begin ProceedRPN()"); try { strError = ""; //???要搞清楚用不用清空 //应该清空,后面的运算使用的结果集是堆栈变量,最后把运算结果拷贝到该结果集 //DoQuery处,也应该先清空 //doItem处,一进去先清空,但再对数据库循环检索时,千万不清空 if (resultSet != null) resultSet.Clear(); if (rpn == null) { strError = "rpn不能为null"; return -1; } #if NO if (resultSet == null) { strError = "resultSet不能为null"; return -1; } #endif if (rpn.Count == 0) return 0; int ret; // 声明栈,ReversePolishStack栈是自定义的类 // 决定用一个栈做运算,如果遇到遇到操作数,就直接push到栈里 // 遇到操作符,如果是双目,从栈里pop两项,进行运算 // 注意SUB运算是,用后一次pop的对象减前一次pop的对象 // // oReversePolandStack的成员为ReversePolishItem, // ReversePolishItem是一个复杂对象, // 包含m_int(类型),m_node(节点),m_resultSet. // 实际运用中,m_node和m_resultSet只有一项值有效,另一顶是null // m_int用于判断哪个值有效, // 0表示node有效,1表示resultSet有效 ReversePolishStack oReversePolandStack = new ReversePolishStack(); //做循环 for (int i = 0; i < rpn.Count; i++) { XmlElement node = (XmlElement)rpn[i]; if (node.Name != "operator") //操作数直接push到栈里 { oReversePolandStack.PushNode(node); } else { string strOpreator = DomUtil.GetAttr(node, "value"); #if NO //三个输出用于输入的参数,因为是指针,所以不用out DpResultSet oTargetLeft = sessioninfo.NewResultSet(); // new DpResultSet(); DpResultSet oTargetMiddle = sessioninfo.NewResultSet(); // new DpResultSet(); DpResultSet oTargetRight = sessioninfo.NewResultSet(); // new DpResultSet(); #endif //做一个两个成员的ArrayList, //成员类型为DpResultSet, //存放从栈里pop出的(如果是node,需要进行计算)的结果集 List<DpResultSet> oSource = new List<DpResultSet>(); oSource.Add(sessioninfo.NewResultSet()); // new DpResultSet() oSource.Add(sessioninfo.NewResultSet()); // new DpResultSet() try { for (int j = 0; j < 2; j++) { //类型为-1,表示node和resultSet都为null,出现错误 if (oReversePolandStack.PeekType() == -1) { strError = strOpreator + "时,PeekType()等于-1,则表示两项都是null,出错,返回-1<br/>"; return -1; } //表示放得是node if (oReversePolandStack.PeekType() == 0) { XmlElement nodePop; nodePop = oReversePolandStack.PopNode(); if (nodePop == null) { strError = "nodePop不为又能为null"; return -1; } DpResultSet temp = oSource[j]; // return: // -1 出错 // -6 无权限 // 0 成功 ret = this.DoQuery( sessioninfo, strOutputStyle, nodePop, ref temp, handle, // isConnected, out strError); if (ret <= -1) return ret; if (temp != oSource[j]) { // 2014/3/11 if (oSource[j] != null) oSource[j].Close(); oSource[j] = temp; } } else { DpResultSet temp = oReversePolandStack.PopResultSet(); Debug.Assert(temp != oSource[j], ""); // 2014/3/11 if (oSource[j] != null) oSource[j].Close(); oSource[j] = temp; if (oSource[j] == null) { strError = "PopResultSet() return null"; return -1; } } } } catch (StackUnderflowException /*ex*/) { // 2008/12/4 string strOutXml = ""; if (node.ParentNode != null) { int nRet = DomUtil.GetIndentXml(node.ParentNode.OuterXml, out strOutXml, out strError); } strError = strOpreator + " 是二元操作符,它缺乏操作数。"; if (String.IsNullOrEmpty(strOutXml) == false) strError += "\r\n" + strOutXml; // strError = "StackUnderflowException :" + ex.Message; return -1; } // string strDebugInfo; //OR,AND,SUB运算都是调的DpResultSetManager.Merge()函数, //注意参数的使用 if (strOpreator == "OR") { bool bOutputKeyCount = StringUtil.IsInList("keycount", strOutputStyle); bool bOutputKeyID = StringUtil.IsInList("keyid", strOutputStyle); DpResultSet left = oSource[1]; DpResultSet right = oSource[0]; #if DEBUG Debug.Assert(left.IsClosed == false, ""); Debug.Assert(right.IsClosed == false, ""); #endif { // 直接相加 if (left.Count == 0) { oReversePolandStack.PushResultSet( right ); // 2014/3/11 Debug.Assert(left != right, ""); left.Close(); } else if (right.Count == 0) { oReversePolandStack.PushResultSet( left ); // 2014/3/11 Debug.Assert(left != right, ""); right.Close(); } else { if (EnsureSorted(left, handle, out strError) == -1) return -1; if (EnsureSorted(right, handle, out strError) == -1) return -1; // return: // -1 出错 // 0 没有交叉部分 // 1 有交叉部分 ret = DpResultSetManager.IsCross(left, right, out strError); if (ret == -1) return -1; if (ret == 0) { DpResultSet left_save = left; // 注意:函数执行过程,可能交换 left 和 right。也就是说返回后, left == right ret = DpResultSetManager.AddResults(ref left, right, out strError); if (ret == -1) return -1; oReversePolandStack.PushResultSet( left ); // 2014/3/11 if (left != right) { Debug.Assert(left_save == left, ""); right.Close(); } else { Debug.Assert(left_save != left, ""); left_save.Close(); } } else { if (left.Asc != right.Asc) { right.Asc = left.Asc; right.Sorted = false; } if (EnsureSorted(left, handle, out strError) == -1) return -1; if (EnsureSorted(right, handle, out strError) == -1) return -1; { DpResultSet oTargetMiddle = sessioninfo.NewResultSet(); // new DpResultSet(); StringBuilder debugInfo = null; ret = DpResultSetManager.Merge(LogicOper.OR, left, right, strOutputStyle, null, oTargetMiddle, null, // false, querystop, handle, ref debugInfo, out strError); if (ret == -1) return -1; oReversePolandStack.PushResultSet(oTargetMiddle); // 2014/3/11 Debug.Assert(left != oTargetMiddle, ""); Debug.Assert(right != oTargetMiddle, ""); left.Close(); right.Close(); } } } } continue; } if (strOpreator == "AND") { DpResultSet left = oSource[1]; DpResultSet right = oSource[0]; #if DEBUG Debug.Assert(left.IsClosed == false, ""); Debug.Assert(right.IsClosed == false, ""); #endif if (left.Asc != right.Asc) { right.Asc = left.Asc; right.Sorted = false; } if (EnsureSorted(left, handle, out strError) == -1) return -1; if (EnsureSorted(right, handle, out strError) == -1) return -1; // 优化 if (left.Count == 0) { oReversePolandStack.PushResultSet( left ); // 2014/3/11 Debug.Assert(left != right, ""); right.Close(); } else if (right.Count == 0) { oReversePolandStack.PushResultSet( right ); // 2014/3/11 Debug.Assert(left != right, ""); left.Close(); } else { DpResultSet oTargetMiddle = sessioninfo.NewResultSet(); // new DpResultSet(); StringBuilder debugInfo = null; ret = DpResultSetManager.Merge(LogicOper.AND, left, right, strOutputStyle, null, //oTargetLeft oTargetMiddle, null, //oTargetRight // false, querystop, handle, ref debugInfo, out strError); if (ret == -1) return -1; oReversePolandStack.PushResultSet(oTargetMiddle); // 2014/3/11 Debug.Assert(left != oTargetMiddle, ""); Debug.Assert(right != oTargetMiddle, ""); left.Close(); right.Close(); } continue; } if (strOpreator == "SUB") { //因为使用从栈里pop,所以第0个是后面的,第1个是前面的 DpResultSet left = oSource[1]; DpResultSet right = oSource[0]; #if DEBUG Debug.Assert(left.IsClosed == false, ""); Debug.Assert(right.IsClosed == false, ""); #endif if (left.Asc != right.Asc) { right.Asc = left.Asc; right.Sorted = false; } if (EnsureSorted(left, handle, out strError) == -1) return -1; if (EnsureSorted(right, handle, out strError) == -1) return -1; // 优化 if (left.Count == 0) { oReversePolandStack.PushResultSet( left ); // 2014/3/11 Debug.Assert(left != right, ""); right.Close(); } else if (right.Count == 0) { oReversePolandStack.PushResultSet( left ); // 2014/3/11 Debug.Assert(left != right, ""); right.Close(); } else { DpResultSet oTargetLeft = sessioninfo.NewResultSet(); // new DpResultSet(); StringBuilder debugInfo = null; ret = DpResultSetManager.Merge(LogicOper.SUB, left, right, strOutputStyle, oTargetLeft, null, //oTargetMiddle null, //oTargetRight // false, querystop, handle, ref debugInfo, out strError); if (ret == -1) { return -1; } oReversePolandStack.PushResultSet(oTargetLeft); // 2014/3/11 Debug.Assert(left != oTargetLeft, ""); Debug.Assert(right != oTargetLeft, ""); left.Close(); right.Close(); } continue; } } } if (oReversePolandStack.Count > 1) { strError = "逆波兰出错"; return -1; } try { int nTemp = oReversePolandStack.PeekType(); //如果类型为0,表示存放的是节点 if (nTemp == 0) { XmlElement node = oReversePolandStack.PopNode(); // return: // -1 出错 // -6 无权限 // 0 成功 ret = this.DoQuery( sessioninfo, strOutputStyle, node, ref resultSet, handle, // isConnected, out strError); if (ret <= -1) return ret; } else if (nTemp == 1) { // 调DpResultSet的copy函数 // TODO: 测算这个Copy所花费的时间。 // resultSet.Copy((DpResultSet)(oReversePolandStack.PopResultSet())); resultSet = (DpResultSet)(oReversePolandStack.PopResultSet()); } else { strError = "oReversePolandStack的类型不可能为" + Convert.ToString(nTemp); return -1; } } catch (StackUnderflowException) { strError = "peek或pop时,抛出StackUnderflowException异常"; return -1; } //最后结果集为null,返回出错 if (resultSet == null) { strError = "运算结束后PopResultSet为null" + Convert.ToString(oReversePolandStack.PeekType()); return -1; } return 0; } finally { TimeSpan delta = DateTime.Now - start_time; Debug.WriteLine("End ProceedRPN() 耗时 " + delta.ToString()); } }
static int EnsureSorted(DpResultSet resultset, ChannelHandle handle, out string strError) { strError = ""; resultset.EnsureCreateIndex(); // 确保创建了索引 if (resultset.Sorted == false) { if (DoSort(resultset, handle/*isConnected*/) == true) { strError = "前端中断"; return -1; } Debug.Assert(resultset.Sorted == true, ""); } return 0; }
// 递归函数,得一个节点的集合,外面doSearch调该函数 // parameter: // nodeRoot 当前根节点 // resultSet 结果集。返回时不能确保结果集已经排序。需要看resultset.Sorted成员 // return: // -1 出错 // -6 无权限 // 0 成功 public int DoQuery( SessionInfo sessioninfo, string strOutputStyle, XmlElement nodeRoot, ref DpResultSet resultSet, ChannelHandle handle, // Delegate_isConnected isConnected, out string strError) { DateTime start_time = DateTime.Now; Debug.WriteLine("Begin DoQuery()"); try { strError = ""; if (nodeRoot == null) { strError = "DoQuery() nodeRoot参数不能为null。"; return -1; } #if NO if (resultSet == null) { strError = "DoQuery() resultSet参数不能为null。"; return -1; } #endif if (resultSet != null) { // 先清空一下 resultSet.Clear(); } // 到item时不再继续递归 if (nodeRoot.Name == "item") { if (resultSet == null) resultSet = sessioninfo.NewResultSet(); // 延迟创建 // return: // -1 出错 // -6 无足够的权限 // 0 成功 return doItem( sessioninfo, strOutputStyle, nodeRoot, ref resultSet, handle, // isConnected, out strError); } //如果为扩展节点,则不递归 if (nodeRoot.Name == "operator" || nodeRoot.Name == "lang") { return 0; } //将正常顺序变成逆波兰表序 ArrayList rpn; // return: // -1 出错 例如:括号不匹配;找不到某操作符的优先级 // 0 可用节点数为 0。等于没有任何可检索的必要 // 1 成功 int nRet = Infix2RPN(nodeRoot, out rpn, out strError); if (nRet == -1) { strError = "逆波兰表错误:" + strError; return -1; } if (nRet == 0) return -1; //属于正常情况 if (rpn.Count == 0) return 0; // return: // -1 出错 // -6 无足够的权限 // 0 成功 nRet = ProceedRPN( sessioninfo, strOutputStyle, rpn, ref resultSet, handle, // isConnected, out strError); if (nRet <= -1) return nRet; return 0; } finally { TimeSpan delta = DateTime.Now - start_time; Debug.WriteLine("End DoQuery() 耗时 " + delta.ToString()); } }
// return: // fasle 正常完成 // true 中断 static bool DoSort(DpResultSet resultset, ChannelHandle handle // Delegate_isConnected isConnected ) { resultset.Idle += new IdleEventHandler(sort_Idle); resultset.Param = handle; // isConnected; try { resultset.Sort(); } catch (InterruptException /*ex*/) { return true; // 中断 } finally { resultset.Idle -= new IdleEventHandler(sort_Idle); resultset.Param = null; } return false; }
// 检索单元item的信息,对库进行检索 // parameter: // nodeItem item节点 // resultSet 结果集。返回时不能确保结果集已经排序。需要看resultset.Sorted成员 // 传进结果集,????????每次清空,既然每次清空,那还不如返回一个结果集呢 // isConnected 是否连接 // strError out参数,返回出错信息 // return: // -1 出错 // -6 无足够的权限 // 0 成功 public int doItem( SessionInfo sessioninfo, string strOutputStyle, XmlElement nodeItem, ref DpResultSet resultSet, ChannelHandle handle, // Delegate_isConnected isConnected, out string strError) { strError = ""; if (nodeItem == null) { strError = "doItem() nodeItem参数为null."; return -1; } if (resultSet == null) { strError = "doItem() oResult参数为null."; return -1; } string strResultSetName = nodeItem.GetAttribute("resultset"); if (string.IsNullOrEmpty(strResultSetName) == false) { resultSet.Close(); resultSet = null; DpResultSet source = null; if (KernelApplication.IsGlobalResultSetName(strResultSetName) == true) { source = this.m_dbColl.KernelApplication.ResultSets.GetResultSet(strResultSetName.Substring(1), false); } else { source = sessioninfo.GetResultSet(strResultSetName, false); } if (source == null) { strError = "没有找到名为 '" + strResultSetName + "' 的结果集对象"; return -1; } resultSet = source.Clone("handle"); resultSet.ReadOnly = true; return 0; } //先清空一下 resultSet.Clear(); int nRet; //调processRelation对检索单元的成员检查是否存在矛盾 //如果返回0,则可能对item的成员进行了修改,所以后面重新提取内容 nRet = ProcessRelation(nodeItem); if (nRet == -1) { // strError = "doItem()里调processRelation出错"; strError = "检索式局部有错: " + nodeItem.OuterXml; return -1; } // 根据nodeItem得到检索信息 string strTarget; string strWord; string strMatch; string strRelation; string strDataType; string strIdOrder; string strKeyOrder; string strOrderBy; string strHint = ""; int nMaxCount; nRet = QueryUtil.GetSearchInfo(nodeItem, strOutputStyle, out strTarget, out strWord, out strMatch, out strRelation, out strDataType, out strIdOrder, out strKeyOrder, out strOrderBy, out nMaxCount, out strHint, out strError); if (nRet == -1) return -1; bool bSearched = false; bool bNeedSort = false; bool bFirst = StringUtil.IsInList("first", strHint); // 是否为 命中则停止继续检索 // 将 target 以 ; 号分成多个库 string[] aDatabase = strTarget.Split(new Char[] { ';' }); foreach (string strOneDatabase in aDatabase) { if (strOneDatabase == "") continue; string strDbName; string strTableList; // 拆分库名与途径 nRet = DatabaseUtil.SplitToDbNameAndForm(strOneDatabase, out strDbName, out strTableList, out strError); if (nRet == -1) return -1; // 得到库 Database db = m_dbColl.GetDatabase(strDbName); if (db == null) { strError = "未找到'" + strDbName + "'库"; return -1; } // 2009/7/19 if (db.InRebuildingKey == true) { strError = "数据库 '" + db.GetCaption(null) + "' 正处在重建检索点状态,不能进行检索..."; return -1; } string strTempRecordPath = db.GetCaption("zh-CN") + "/" + "record"; string strExistRights = ""; bool bHasRight = this.m_oUser.HasRights(strTempRecordPath, ResType.Record, "read", out strExistRights); if (bHasRight == false) { strError = "您的帐户名为'" + m_oUser.Name + "'" + ",对'" + strDbName + "'" + "数据库中的记录没有'读(read)'权限,目前的权限为'" + strExistRights + "'。"; return -6; } SearchItem searchItem = new SearchItem(); searchItem.TargetTables = strTableList; searchItem.Word = strWord; searchItem.Match = strMatch; searchItem.Relation = strRelation; searchItem.DataType = strDataType; searchItem.IdOrder = strIdOrder; searchItem.KeyOrder = strKeyOrder; searchItem.OrderBy = strOrderBy; searchItem.MaxCount = nMaxCount; // 注: SearchByUnion不清空resultSet,从而使多个库的结果集放在一起 string strWarningInfo = ""; // -1 出错 // 0 成功 // 1 成功,但resultset需要再行排序一次 nRet = db.SearchByUnion( strOutputStyle, searchItem, handle, // isConnected, resultSet, this.m_nWarningLevel, out strError, out strWarningInfo); if (nRet == -1) return -1; bSearched = true; if (nRet == 1) bNeedSort = true; if (nRet >= 1 && bFirst == true) break; } // 2010/5/17 if (bSearched == true) { // 2010/5/11 resultSet.EnsureCreateIndex(); // 确保创建了索引 // 排序 // TODO: 其实可以使用EnsureSorted()函数 if (bNeedSort == true) { if (DoSort(resultSet, handle/*isConnected*/) == true) { strError = "前端中断"; return -1; } } // TODO: 也可以延迟排序,本函数返回一个值表希望排序。等到最后不得不排序时候再排序最好了 //resultSet.RemoveDup(); } return 0; }
protected ChannelControl(ChannelHandle handle) { Debug.Assert(this is Channel); Handle = handle.Handle; }