// 检索 // parameters: // searchItem SearchItem对象,存放检索词等信息 // isConnected 连接对象 // resultSet 结果集对象,存放命中记录 // strLang 语言版本, // return: // -1 出错 // 0 成功 internal override int SearchByUnion(SearchItem searchItem, Delegate_isConnected isConnected, DpResultSet resultSet, int nWarningLevel, out string strError, out string strWarning) { strError = ""; strWarning = ""; //**********对数据库加读锁************** m_lock.AcquireReaderLock(m_nTimeOut); #if DEBUG_LOCK_SQLDATABASE this.container.WriteDebugInfo("SearchByUnion(),对'" + this.GetCaption("zh-cn") + "'数据库加读锁。"); #endif try { bool bHasID; List<TableInfo> aTableInfo = null; int nRet = this.TableNames2aTableInfo(searchItem.TargetTables, out bHasID, out aTableInfo, out strError); if (nRet == -1) return -1; if (bHasID == true) { nRet = SearchByID(searchItem, isConnected, resultSet, out strError); if (nRet == -1) return -1; } // 对sql库来说,通过ID检索后,记录已排序,去重 if (aTableInfo == null || aTableInfo.Count == 0) return 0; string strCommand = ""; // Sql命令参数数组 List<SqlParameter> aSqlParameter = new List<SqlParameter>(); string strSelectKeystring = ""; if (searchItem.KeyOrder != "") { if (aTableInfo.Count > 1) strSelectKeystring = ",keystring"; } // 循环每一个检索途径 for (int i = 0; i < aTableInfo.Count; i++) { TableInfo tableInfo = aTableInfo[i]; // 参数名的后缀 string strPostfix = Convert.ToString(i); string strConditionAboutKey = ""; try { nRet = GetKeyCondition( searchItem, tableInfo.nodeConvertQueryString, tableInfo.nodeConvertQueryNumber, strPostfix, ref aSqlParameter, out strConditionAboutKey, out strError); if (nRet == -1) return -1; } catch (NoMatchException ex) { strWarning = ex.Message; strError = strWarning; return -1; } // 如果限制了一个最大数,则按每个途径都是这个最大数算 string strTop = ""; if (searchItem.MaxCount != -1) //限制的最大数 strTop = " TOP " + Convert.ToString(searchItem.MaxCount) + " "; string strWhere = ""; if (strConditionAboutKey != "") strWhere = " WHERE " + strConditionAboutKey; string strOneCommand = ""; if (i == 0)// 第一个表 { strOneCommand = "use " + this.m_strSqlDbName + " " + " SELECT " + " DISTINCT " + strTop + " idstring" + strSelectKeystring + " " + " FROM " + tableInfo.SqlTableName + " " + strWhere; } else { strOneCommand = " union SELECT " + " DISTINCT " + strTop + " idstring" + strSelectKeystring + " " //DISTINCT 去重 + " FROM " + tableInfo.SqlTableName + " " + strWhere; } strCommand += strOneCommand; } string strOrderBy = ""; if (searchItem.OrderBy != "") strOrderBy = "ORDER BY " + searchItem.OrderBy + " "; strCommand += strOrderBy; strCommand += " use master " + "\n"; if (aSqlParameter == null) { strError = "一个参数也没是不可能的情况"; return -1; } SqlCommand command = null; SqlConnection connection = new SqlConnection(this.m_strConnString); connection.Open(); try { command = new SqlCommand(strCommand, connection); foreach (SqlParameter sqlParameter in aSqlParameter) { command.Parameters.Add(sqlParameter); } command.CommandTimeout = 20 * 60; // 把检索时间变大 // 调新线程处理 DatabaseCommandTask task = new DatabaseCommandTask(command); try { if (task == null) { strError = "test为null"; return -1; } Thread t1 = new Thread(new ThreadStart(task.ThreadMain)); t1.Start(); bool bRet; while (true) { if (isConnected != null) { if (isConnected() == false) { strError = "用户中断"; return -1; } } bRet = task.m_event.WaitOne(100, false); //1/10秒看一次 if (bRet == true) break; } if (task.DataReader == null || task.DataReader.HasRows == false) { return 0; } int nGetedCount = 0; while (task.DataReader.Read()) { if (isConnected != null && (nGetedCount % 10000) == 0) { if (isConnected() == false) { strError = "用户中断"; return -1; } } string strId = this.FullID + "/" + (string)task.DataReader[0]; // 记录格式为:库id/记录号 resultSet.Add(new DpRecord(strId)); nGetedCount++; // 超过最大数了 if (searchItem.MaxCount != -1 && nGetedCount >= searchItem.MaxCount) break; Thread.Sleep(0); } } finally { if (task.DataReader != null) task.DataReader.Close(); } } catch (SqlException sqlEx) { if (sqlEx.Errors is SqlErrorCollection) strError = "数据库'" + this.GetCaption("zh") + "'尚未初始化。"; else strError = sqlEx.Message; return -1; } catch (Exception ex) { strError = ex.Message; return -1; } finally // 连接 { connection.Close(); } } catch (Exception ex) { strError = ex.Message; return -1; } finally { //*****************对数据库解读锁*************** m_lock.ReleaseReaderLock(); #if DEBUG_LOCK_SQLDATABASE this.container.WriteDebugInfo("SearchByUnion(),对'" + this.GetCaption("zh-cn") + "'数据库解读锁。"); #endif } return 0; }
// 按ID检索记录 // parameter: // searchItem SearchItem对象,包括检索信息 // isConnected 连接对象的delegate // resultSet 结果集对象,存放命中记录 // return: // -1 出错 // 0 成功 // 线:不安全 private int SearchByID(SearchItem searchItem, Delegate_isConnected isConnected, DpResultSet resultSet, out string strError) { strError = ""; Debug.Assert(searchItem != null, "SearchByID()调用错误,searchItem参数值不能为null。"); Debug.Assert(isConnected != null, "SearchByID()调用错误,isConnected参数值不能为null。"); Debug.Assert(resultSet != null, "SearchByID()调用错误,resultSet参数值不能为null。"); SqlConnection connection = new SqlConnection(this.m_strConnString); connection.Open(); try { List<SqlParameter> aSqlParameter = new List<SqlParameter>(); string strWhere = ""; if (searchItem.Match == "left" || searchItem.Match == "") { strWhere = " WHERE id LIKE @id and id like N'[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' "; SqlParameter temp = new SqlParameter("@id", SqlDbType.NVarChar); temp.Value = searchItem.Word + "%"; aSqlParameter.Add(temp); } else if (searchItem.Match == "middle") { strWhere = " WHERE id LIKE @id and id like N'[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' "; SqlParameter temp = new SqlParameter("@id", SqlDbType.NVarChar); temp.Value = "%" + searchItem.Word + "%"; aSqlParameter.Add(temp); } else if (searchItem.Match == "right") { strWhere = " WHERE id LIKE @id and id like N'[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' "; SqlParameter temp = new SqlParameter("@id", SqlDbType.NVarChar); temp.Value = "%" + searchItem.Word; aSqlParameter.Add(temp); } else if (searchItem.Match == "exact") { if (searchItem.DataType == "string") searchItem.Word = DbPath.GetID10(searchItem.Word); if (searchItem.Relation == "draw") { int nPosition; nPosition = searchItem.Word.IndexOf("-"); if (nPosition >= 0) { string strStartID; string strEndID; StringUtil.SplitRange(searchItem.Word, out strStartID, out strEndID); strStartID = DbPath.GetID10(strStartID); strEndID = DbPath.GetID10(strEndID); strWhere = " WHERE @idMin <=id and id<= @idMax and id like N'[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' "; SqlParameter temp = new SqlParameter("@idMin", SqlDbType.NVarChar); temp.Value = strStartID; aSqlParameter.Add(temp); temp = new SqlParameter("@idMax", SqlDbType.NVarChar); temp.Value = strEndID; aSqlParameter.Add(temp); } else { string strOperator; string strRealText; StringUtil.GetPartCondition(searchItem.Word, out strOperator, out strRealText); strRealText = DbPath.GetID10(strRealText); strWhere = " WHERE id " + strOperator + " @id and id like N'[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' "; SqlParameter temp = new SqlParameter("@id", SqlDbType.NVarChar); temp.Value = strRealText; aSqlParameter.Add(temp); } } else { searchItem.Word = DbPath.GetID10(searchItem.Word); strWhere = " WHERE id " + searchItem.Relation + " @id and id like N'[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' "; SqlParameter temp = new SqlParameter("@id", SqlDbType.NVarChar); temp.Value = searchItem.Word; aSqlParameter.Add(temp); } } string strTop = ""; if (searchItem.MaxCount != -1) // 只命中指定的条数 strTop = " TOP " + Convert.ToString(searchItem.MaxCount) + " "; string strOrderBy = ""; if (searchItem.IdOrder != "") strOrderBy = "ORDER BY id " + searchItem.IdOrder + " "; string strCommand = "use " + this.m_strSqlDbName + " SELECT " + " DISTINCT " + strTop + " id " + " FROM records " + strWhere + " " + strOrderBy + "\n"; strCommand += " use master " + "\n"; SqlCommand command = new SqlCommand(strCommand, connection); command.CommandTimeout = 20 * 60; // 把检索时间变大 foreach (SqlParameter sqlParameter in aSqlParameter) { command.Parameters.Add(sqlParameter); } DatabaseCommandTask task = new DatabaseCommandTask(command); try { Thread t1 = new Thread(new ThreadStart(task.ThreadMain)); t1.Start(); bool bRet; while (true) { if (isConnected != null) //只是不再检索了 { if (isConnected() == false) { strError = "用户中断"; return -1; } } bRet = task.m_event.WaitOne(100, false); //millisecondsTimeout if (bRet == true) break; } if (task.bError == true) { strError = task.ErrorString; return -1; } if (task.DataReader == null) return 0; if (task.DataReader.HasRows == false) { return 0; } int nLoopCount = 0; while (task.DataReader.Read()) { if (nLoopCount % 10000 == 0) { if (isConnected != null) { if (isConnected() == false) { strError = "用户中断"; return -1; } } } string strID = ((string)task.DataReader[0]); if (strID.Length != 10) { strError = "结果集中出现了长度不是10位的记录号,不正常"; return -1; } string strId = this.FullID + "/" + strID; //记录路径格式:库ID/记录号 resultSet.Add(new DpRecord(strId)); nLoopCount++; Thread.Sleep(0); } } finally { if (task != null && task.DataReader != null) task.DataReader.Close(); } } catch (SqlException sqlEx) { if (sqlEx.Errors is SqlErrorCollection) strError = "数据库'" + this.GetCaption("zh") + "'尚未初始化。"; else strError = sqlEx.Message; return -1; } catch (Exception ex) { strError = ex.Message; return -1; } finally // 连接 { connection.Close(); } return 0; }
// 运算逆波兰表,得到结果集 // parameter: // rpn 逆波兰表 // oResultSet 结果集 // 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(ArrayList rpn, DpResultSet resultSet, Delegate_isConnected isConnected, out string strError) { strError = ""; //???要搞清楚用不用清空 //应该清空,后面的运算使用的结果集是堆栈变量,最后把运算结果拷贝到该结果集 //DoQuery处,也应该先清空 //doItem处,一进去先清空,但再对数据库循环检索时,千万不清空 resultSet.Clear(); if (rpn == null) { strError = "rpn不能为null"; return(-1); } if (resultSet == null) { strError = "resultSet不能为null"; return(-1); } 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++) { XmlNode node = (XmlNode)rpn[i]; if (node.Name != "operator") //操作数直接push到栈里 { oReversePolandStack.PushNode(node); } else { string strOpreator = DomUtil.GetAttr(node, "value"); //三个输出用于输入的参数,因为是指针,所以不用out DpResultSet oTargetLeft = new DpResultSet(); DpResultSet oTargetMiddle = new DpResultSet(); DpResultSet oTargetRight = new DpResultSet(); //做一个两个成员的ArrayList, //成员类型为DpResultSet, //存放从栈里pop出的(如果是node,需要进行计算)的结果集 ArrayList oSource = new ArrayList(); oSource.Add(new DpResultSet()); oSource.Add(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) { XmlNode nodePop; nodePop = oReversePolandStack.PopNode(); if (nodePop == null) { strError = "nodePop不为又能为null"; return(-1); } // return: // -1 出错 // -6 无权限 // 0 成功 ret = this.DoQuery(nodePop, (DpResultSet)oSource[j], isConnected, out strError); if (ret <= -1) { return(ret); } } else { oSource[j] = oReversePolandStack.PopResultSet(); if (oSource[j] == null) { return(-1); } } } } catch (StackUnderflowException) { return(-1); } string strDebugInfo; //OR,AND,SUB运算都是调的DpResultSetManager.Merge()函数, //注意参数的使用 if (strOpreator == "OR") { DpResultSet left = (DpResultSet)oSource[0]; left.EnsureCreateIndex(); // 确保创建了索引? // ?????? //left.Sort(); DpResultSet right = (DpResultSet)oSource[1]; right.EnsureCreateIndex(); //right.Sort(); /* * // new * oTargetMiddle.EnsureCreateIndex(); */ ret = DpResultSetManager.Merge("OR", left, right, null, oTargetMiddle, null, false, out strDebugInfo, out strError); if (ret == -1) { return(-1); } oReversePolandStack.PushResultSet(oTargetMiddle); continue; } if (strOpreator == "AND") { DpResultSet left = (DpResultSet)oSource[0]; left.EnsureCreateIndex(); DpResultSet right = (DpResultSet)oSource[1]; right.EnsureCreateIndex(); /* * // new * oTargetMiddle.EnsureCreateIndex(); */ ret = DpResultSetManager.Merge("AND", left, right, null, //oTargetLeft oTargetMiddle, null, //oTargetRight false, out strDebugInfo, out strError); if (ret == -1) { return(-1); } oReversePolandStack.PushResultSet(oTargetMiddle); continue; } if (strOpreator == "SUB") { //因为使用从栈里pop,所以第0个是后面的,第1个是前面的 DpResultSet left = (DpResultSet)oSource[1]; left.EnsureCreateIndex(); DpResultSet right = (DpResultSet)oSource[0]; right.EnsureCreateIndex(); /* * // new * oTargetLeft.EnsureCreateIndex(); */ ret = DpResultSetManager.Merge("SUB", left, right, oTargetLeft, oTargetMiddle, //oTargetMiddle oTargetRight, //oTargetRight false, out strDebugInfo, out strError); if (ret == -1) { return(-1); } oReversePolandStack.PushResultSet(oTargetLeft); continue; } } } if (oReversePolandStack.Count > 1) { strError = "逆波兰出错"; return(-1); } try { int nTemp = oReversePolandStack.PeekType(); //如果类型为0,表示存放的是节点 if (nTemp == 0) { XmlNode node = oReversePolandStack.PopNode(); // return: // -1 出错 // -6 无权限 // 0 成功 ret = this.DoQuery(node, resultSet, isConnected, out strError); if (ret <= -1) { return(ret); } } else if (nTemp == 1) { //调DpResultSet的copy函数 resultSet.Copy((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); }
// 检索 // parameter: // strQuery 检索式XML字符串 // resultSet 结果集,用于存放检索结果 // oUser 帐户对象,用于检索该帐户对某库是否有读权限 // 为null,则不进行权限的检查,即按有权限算 // isConnected delegate对象,用于通讯是否连接正常 // 为null,则不调delegate函数 // strError out参数,返回出错信息 // return: // -1 出错 // -6 权限不够 // 0 成功 // 线: 安全的 public int Search(string strQuery, DpResultSet resultSet, User oUser, Delegate_isConnected isConnected, out string strError) { strError = ""; //对库集合加读锁********************************* m_lock.AcquireReaderLock(m_nTimeOut); #if DEBUG_LOCK this.WriteDebugInfo("Search(),对库集合加读锁。"); #endif try { if (String.IsNullOrEmpty(strQuery) == true) { strError = "Search()调用错误,strQuery不能为null或空字符串"; return -1; } // 一进来先给结果集的m_strQuery成员赋值, // 不管是否是合法的XML,在用结果集的时候再判断 resultSet.m_strQuery = strQuery; XmlDocument dom = new XmlDocument(); dom.PreserveWhitespace = true; //设PreserveWhitespace为true try { dom.LoadXml(strQuery); } catch (Exception ex) { strError += "检索式字符串加载到dom出错,原因:" + ex.Message + "\r\n" + "检索式字符串如下:\r\n" + strQuery; return -1; } //创建Query对象 Query query = new Query(this, oUser, dom); //进行检索 // return: // -1 出错 // -6 无权限 // 0 成功 int nRet = query.DoQuery(dom.DocumentElement, resultSet, isConnected, out strError); if (nRet <= -1) return nRet; } finally { //****************对库集合解读锁************** m_lock.ReleaseReaderLock(); #if DEBUG_LOCK this.WriteDebugInfo("Search(),对库集合解读锁。"); #endif } return 0; }
// 递归函数,得一个节点的集合,外面doSearch调该函数 // parameter: // nodeRoot 当前根节点 // oResult 结果集 // return: // -1 出错 // -6 无权限 // 0 成功 public int DoQuery(XmlNode nodeRoot, DpResultSet resultSet, Delegate_isConnected isConnected, out string strError) { strError = ""; if (nodeRoot == null) { strError = "DoQuery() nodeRoot参数不能为null。"; return(-1); } if (resultSet == null) { strError = "DoQuery() resultSet参数不能为null。"; return(-1); } //先清空一下 resultSet.Clear(); //到item时不再继续递归 if (nodeRoot.Name == "item") { // return: // -1 出错 // -6 无足够的权限 // 0 成功 return(doItem(nodeRoot, resultSet, isConnected, out strError)); } //如果为扩展节点,则不递归 if (nodeRoot.Name == "operator" || nodeRoot.Name == "lang") { return(0); } //将正常顺利变成逆波兰表序 ArrayList rpn; int nRet = Infix2RPN(nodeRoot, out rpn, out strError); if (nRet == -1) { strError = "逆波兰表错误:" + strError; return(-1); } //属于正常情况 if (rpn.Count == 0) { return(0); } // return: // -1 出错 // -6 无足够的权限 // 0 成功 nRet = ProceedRPN(rpn, resultSet, isConnected, out strError); if (nRet <= -1) { return(nRet); } return(0); }
// 检索单元item的信息,对库进行检索 // parameter: // nodeItem item节点 // resultSet 传进结果集,????????每次清空,既然每次清空,那还不如返回一个结果集呢 // isConnected 是否连接 // strError out参数,返回出错信息 // return: // -1 出错 // -6 无足够的权限 // 0 成功 public int doItem(XmlNode nodeItem, DpResultSet resultSet, 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); } //先清空一下 resultSet.Clear(); int nRet; //调processRelation对检索单元的成员检查是否存在矛盾 //如果返回0,则可能对item的成员进行了修改,所以后面重新提取内容 nRet = ProcessRelation(nodeItem); if (nRet == -1) { strError = "doItem()里调processRelation出错"; return(-1); } // 根据nodeItem得到检索信息 string strTarget; string strWord; string strMatch; string strRelation; string strDataType; string strIdOrder; string strKeyOrder; string strOrderBy; int nMaxCount; nRet = QueryUtil.GetSearchInfo(nodeItem, out strTarget, out strWord, out strMatch, out strRelation, out strDataType, out strIdOrder, out strKeyOrder, out strOrderBy, out nMaxCount, out strError); if (nRet == -1) { return(-1); } //将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); } 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 = ""; nRet = db.SearchByUnion(searchItem, isConnected, resultSet, this.m_nWarningLevel, out strError, out strWarningInfo); if (nRet == -1) { return(-1); } // 多个库的排序去重功能暂不做 //resultSet.Sort(); //按具体的风格排序 //resultSet.RemoveDup(); } return(0); }
// 检索 internal override int SearchByUnion(SearchItem searchItem, Delegate_isConnected isConnected, DpResultSet resultSet, int nWarningLevel, out string strError, out string strWarning) { strError = ""; strWarning = ""; //************对数据库加读锁************** m_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, 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 = DomUtil.GetNodeText(listIdstring[j]).Trim(); string strId = this.FullID + "/" + strIdstring; resultSet.Add(new DpRecord(strId)); } } //排序 resultSet.Sort(); //去重 resultSet.RemoveDup(); return 0; } finally { //*********对数据库解读锁************ m_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, 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") { foreach (string recordID in records) { int nPosition = searchItem.Word.IndexOf("-"); if (nPosition >= 0) { string strStartID; string strEndID; StringUtil.SplitRange(searchItem.Word, out strStartID, out strEndID); 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; }
// 检索 // parameter: // searchItem SearchItem对象 // isConnected IsConnection对象,用于判断通讯是否连接 // resultSet 存入检索结果的结果集 // nWarningLevel 处理警告级别 0:表示特别强烈,出现警告也当作出错;1:表示不强烈,不返回出错,继续执行 // strError out参数,返回出错信息 // strWarning out参数,返回警告信息 // return: // -1 出错 // >=0 命中记录数 // 线: 安全的 internal virtual int SearchByUnion(SearchItem searchItem, Delegate_isConnected isConnected, DpResultSet resultSet, int nWarningLevel, out string strError, out string strWarning) { strError = ""; strWarning = ""; return 0; }