public void DoSimpleSearch(bool bOutputKeyID) { textBox_simpleQuery_comment.Text = ""; // 第一阶段 TargetItemCollection targets = treeView_simpleQueryResTree. GetSearchTarget(); Debug.Assert(targets != null, "GetSearchTarget() 异常"); int i; // 第二阶段 for(i=0;i<targets.Count;i++) { TargetItem item = (TargetItem)targets[i]; item.Words = textBox_simpleQueryWord.Text; } targets.MakeWordPhrases( Convert.ToBoolean(MainForm.AppInfo.GetInt("simple_query_property", "auto_split_words", 1)), Convert.ToBoolean( MainForm.AppInfo.GetInt("simple_query_property", "auto_detect_range", 0) ), Convert.ToBoolean( MainForm.AppInfo.GetInt("simple_query_property", "auto_detect_relation", 0) ) ); // 参数 for(i=0;i<targets.Count;i++) { TargetItem item = (TargetItem)targets[i]; item.MaxCount = MainForm.AppInfo.GetInt("simple_query_property", "maxcount", -1); } // 第三阶段 targets.MakeXml(); // 正式检索 string strError; if (bOutputKeyID == true) this.m_bFirstColumnIsKey = true; else this.m_bFirstColumnIsKey = false; this.ClearListViewPropertyCache(); this.ClearListViewItems(); stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在检索 ..."); stop.BeginLoop(); EnableControlsInSearching(true); long lTotalCount = 0; // 命中记录总数 for(i=0;i<targets.Count;i++) { if (stop.State >= 1) break; TargetItem item = (TargetItem)targets[i]; channel = Channels.GetChannel(item.Url); Debug.Assert(channel != null, "Channels.GetChannel 异常"); textBox_simpleQuery_comment.Text += "检索式XML:\r\n" + DomUtil.GetIndentXml(item.Xml) + "\r\n"; // 2010/5/18 string strBrowseStyle = "id,cols"; string strOutputStyle = ""; if (bOutputKeyID == true) { strOutputStyle = "keyid"; strBrowseStyle = "keyid,id,key,cols"; } // MessageBox.Show(this, item.Xml); long nRet = channel.DoSearch(item.Xml, "default", strOutputStyle, out strError); if (nRet == -1) { textBox_simpleQuery_comment.Text += "出错: " + strError + "\r\n"; MessageBox.Show(this, strError); continue; } lTotalCount += nRet; textBox_simpleQuery_comment.Text += "命中记录数: " + Convert.ToString(nRet) + "\r\n"; if (nRet == 0) continue; // 获取结果集 nRet = channel.DoBrowse(listView_browse, listView_browse.Lang, stop, "default", strBrowseStyle, out strError); if (nRet == -1) { textBox_simpleQuery_comment.Text += "装载浏览信息时出错: " + strError + "\r\n"; MessageBox.Show(this, strError); continue; } } if (targets.Count > 1) { textBox_simpleQuery_comment.Text += "命中总条数: " + Convert.ToString(lTotalCount) + "\r\n"; } stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); if (lTotalCount == 0) { MessageBox.Show(this, "未命中"); } EnableControlsInSearching(false); channel = null; }
/// <summary> /// 检索得到若干命中结果 /// </summary> /// <param name="strServerUrl">服务器URL</param> /// <param name="strQueryXml">检索式XML</param> /// <param name="nMax">最大结果数</param> /// <param name="aPath">返回的记录路径数组</param> /// <param name="strError">返回的错误信息</param> /// <returns>-1 一般错误;0 not found;1 found;>1 命中多于一条</returns> public int SearchMultiPath( string strServerUrl, string strQueryXml, int nMax, out List<string> aPath, out string strError) { aPath = null; strError = ""; if (String.IsNullOrEmpty(strServerUrl) == true) strServerUrl = this.ServerUrl; RmsChannel channelSave = channel; channel = Channels.GetChannel(strServerUrl); if (channel == null) { strError = "get channel error"; return -1; } try { long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) return -1; if (lRet == 0) { return 0; // 没有找到 } long lCount = lRet; lCount = Math.Min(lCount, nMax); if (lRet > 1) { strError = "命中 " + Convert.ToString(lRet) + " 条。"; } lRet = channel.DoGetSearchResult( "default", 0, lCount, "zh", this.stop, out aPath, out strError); if (lRet == -1) { strError = "获取检索结果时出错: " + strError; return -1; } return (int)lCount; } finally { channel = channelSave; } }
// TODO: 是否检查流通信息,需要可以通过参数控制 // 检索书目记录下属的事项记录,返回少量必要的信息,可以提供后面实做删除时使用 // parameters: // strStyle return_record_xml 要在DeleteEntityInfo结构中返回OldRecord内容 // check_circulation_info 检查是否具有流通信息。如果具有则会报错 2012/12/19 把缺省行为变为此参数 // 当包含 limit: 时,定义最多取得记录的个数。例如希望最多取得 10 条,可以定义 limit:10 // return: // -1 error // 0 not exist item dbname // 1 exist item dbname public int SearchChildItems(RmsChannel channel, string strBiblioRecPath, string strStyle, DigitalPlatform.LibraryServer.LibraryApplication.Delegate_checkRecord procCheckRecord, object param, out long lHitCount, out List<DeleteEntityInfo> entityinfos, out string strError) { strError = ""; lHitCount = 0; entityinfos = new List<DeleteEntityInfo>(); int nRet = 0; bool bReturnRecordXml = StringUtil.IsInList("return_record_xml", strStyle); bool bCheckCirculationInfo = StringUtil.IsInList("check_circulation_info", strStyle); bool bOnlyGetCount = StringUtil.IsInList("only_getcount", strStyle); string strLimit = StringUtil.GetParameterByPrefix(strStyle, "limit", ":"); string strBiblioDbName = ResPath.GetDbName(strBiblioRecPath); string strBiblioRecId = ResPath.GetRecordId(strBiblioRecPath); // 获得书目库对应的事项库名 string strItemDbName = ""; nRet = this.GetItemDbName(strBiblioDbName, out strItemDbName, out strError); if (nRet == -1) goto ERROR1; if (String.IsNullOrEmpty(strItemDbName) == true) return 0; // 检索实体库中全部从属于特定id的记录 string strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strItemDbName + ":" + "父记录") + "'><item><word>" + strBiblioRecId + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>" + "zh" + "</lang></target>"; long lRet = channel.DoSearch(strQueryXml, "entities", "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; if (lRet == 0) { strError = "没有找到属于书目记录 '" + strBiblioRecPath + "' 的任何" + this.ItemName + "记录"; return 0; } lHitCount = lRet; // 仅返回命中条数 if (bOnlyGetCount == true) return 0; int nResultCount = (int)lRet; int nMaxCount = 10000; if (nResultCount > nMaxCount) { strError = "命中" + this.ItemName + "记录数 " + nResultCount.ToString() + " 超过 " + nMaxCount.ToString() + ", 暂时不支持针对它们的删除操作"; goto ERROR1; } string strColumnStyle = "id,xml,timestamp"; int nLimit = -1; if (string.IsNullOrEmpty(strLimit) == false) Int32.TryParse(strLimit, out nLimit); int nStart = 0; int nPerCount = 100; if (nLimit != -1 && nPerCount > nLimit) nPerCount = nLimit; for (; ; ) { #if NO List<string> aPath = null; lRet = channel.DoGetSearchResult( "entities", nStart, nPerCount, "zh", null, out aPath, out strError); if (lRet == -1) goto ERROR1; if (aPath.Count == 0) { strError = "aPath.Count == 0"; goto ERROR1; } #endif Record[] searchresults = null; lRet = channel.DoGetSearchResult( "entities", nStart, nPerCount, strColumnStyle, "zh", null, out searchresults, out strError); if (lRet == -1) goto ERROR1; if (searchresults == null) { strError = "searchresults == null"; goto ERROR1; } if (searchresults.Length == 0) { strError = "searchresults.Length == 0"; goto ERROR1; } // 获得每条记录 // for (int i = 0; i < aPath.Count; i++) int i = 0; foreach (Record record in searchresults) { string strMetaData = ""; string strXml = ""; byte[] timestamp = null; string strOutputPath = ""; DeleteEntityInfo entityinfo = new DeleteEntityInfo(); if (record.RecordBody == null || string.IsNullOrEmpty(record.RecordBody.Xml) == true) { // TODO: 这里需要改造为直接从结果集中获取 xml,timestamp lRet = channel.GetRes(record.Path, out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) continue; strError = "获取" + this.ItemName + "记录 '" + record.Path + "' 时发生错误: " + strError; goto ERROR1; // goto CONTINUE; } } else { strXml = record.RecordBody.Xml; strOutputPath = record.Path; timestamp = record.RecordBody.Timestamp; } entityinfo.RecPath = strOutputPath; entityinfo.OldTimestamp = timestamp; if (bReturnRecordXml == true) entityinfo.OldRecord = strXml; if (bCheckCirculationInfo == true || procCheckRecord != null) { // 检查是否有借阅信息 // 把记录装入DOM XmlDocument domExist = new XmlDocument(); try { domExist.LoadXml(strXml); } catch (Exception ex) { strError = this.ItemName + "记录 '" + record.Path + "' 装载进入DOM时发生错误: " + ex.Message; goto ERROR1; } // 2016/11/15 if (procCheckRecord != null) { nRet = procCheckRecord( nStart + i, strOutputPath, domExist, timestamp, param, out strError); if (nRet != 0) return nRet; } /* entityinfo.ItemBarcode = DomUtil.GetElementText(domExist.DocumentElement, "barcode"); * */ // TODO: 在日志恢复阶段调用本函数时,是否还有必要检查是否具有流通信息?似乎这时应强制删除为好 // 观察已经存在的记录是否有流通信息 // return: // -1 出错 // 0 没有 // 1 有。报错信息在strError中 nRet = this.HasCirculationInfo(domExist, out strError); if (nRet == -1) goto ERROR1; if (nRet == 1) { strError = "拟删除的" + this.ItemName + "记录 '" + entityinfo.RecPath + "' 中" + strError + "(此种情况可能不限于这一条),不能删除。因此全部删除操作均被放弃。"; goto ERROR1; } } // CONTINUE: entityinfos.Add(entityinfo); i++; } nStart += searchresults.Length; if (nStart >= nResultCount) break; if (nLimit != -1 && nStart >= nLimit) break; } return 1; ERROR1: return -1; }
// 获得一个汉字的拼音 // 所获得的拼音, 是一个分号间隔的字符串, 表示对应于这个汉字的多音 // return: // -1 error // 1 found // 0 not found int GetOnePinyin(string strOneHanzi, out string strPinyin, out string strError) { strPinyin = ""; strError = ""; // 拼音库路径 string strPinyinDbPath = MainForm.AppInfo.GetString("pinyin", "pinyin_db_path", ""); if (String.IsNullOrEmpty(strPinyinDbPath) == true) { strError = "拼音库路径尚未配置。请先用菜单“帮助/系统参数设置”功能配置适当的拼音库路径。"; return -1; } ResPath respath = new ResPath(strPinyinDbPath); string strDbName = respath.Path; // 2007/4/5 改造 加上了 GetXmlStringSimple() string strQueryXml = "<target list='" + strDbName + ":" + "汉字'><item><word>" + StringUtil.GetXmlStringSimple(strOneHanzi) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>10</maxCount></item><lang>chi</lang></target>"; // 使用Channel RmsChannel channelSave = channel; channel = Channels.GetChannel(respath.Url); Debug.Assert(channel != null, "Channels.GetChannel 异常"); try { stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在检索拼音 '" + strOneHanzi + "'"); stop.BeginLoop(); try { long nRet = channel.DoSearch(strQueryXml, "default", out strError); if (nRet == -1) { strError = "检索拼音库时出错: " + strError; return -1; } if (nRet == 0) return 0; // not found List<string> aPath = null; nRet = channel.DoGetSearchResult( "default", 1, this.Lang, stop, out aPath, out strError); if (nRet == -1) { strError = "检索拼音库获取检索结果时出错: " + strError; return -1; } if (aPath.Count == 0) { strError = "检索拼音库获取的检索结果为空"; return -1; } string strStyle = "content,data"; string strContent; string strMetaData; byte[] baTimeStamp; string strOutputPath; nRet = channel.GetRes((string)aPath[0], strStyle, // this.eventClose, out strContent, out strMetaData, out baTimeStamp, out strOutputPath, out strError); if (nRet == -1) { strError = "获取拼音记录体时出错: " + strError; return -1; } // 取出拼音字符串 XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strContent); } catch (Exception ex) { strError = "汉字 '" + strOneHanzi + "' 所获取的拼音记录 " + strContent + " XML数据装载出错: " + ex.Message; return -1; } strPinyin = DomUtil.GetAttr(dom.DocumentElement, "p"); return 1; } finally { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); } } finally { channel = channelSave; } }
// 针对一个from进行检索 // parameters: // strExcludeBiblioRecPath 要排除掉的记录路径 // return: // -1 error // 0 not found // 1 found int SearchOneFrom( // RmsChannelCollection Channels, RmsChannel channel, string strDbName, string strFrom, string strKey, string strSearchStyle, int nWeight, int nThreshold, long nMax, string strExcludeBiblioRecPath, out DupResultSet dupset, out string strError) { strError = ""; dupset = null; long lRet = 0; if (strSearchStyle == "") strSearchStyle = "exact"; string strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strDbName + ":" + strFrom) // 2007/9/14 + "'><item><word>" + StringUtil.GetXmlStringSimple(strKey) + "</word><match>" + strSearchStyle + "</match><relation>=</relation><dataType>string</dataType><maxCount>" + nMax.ToString() + "</maxCount></item><lang>zh</lang></target>"; string strSearchReason = "key='" + strKey + "', from='" + strFrom + "', weight=" + Convert.ToString(nWeight); /* RmsChannel channel = Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; goto ERROR1; } * */ Debug.Assert(channel != null, ""); lRet = channel.DoSearch(strQueryXml, "dup", "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; if (lRet == 0) return 0; // not found long lHitCount = lRet; long lStart = 0; long lPerCount = Math.Min(50, lHitCount); List<string> aPath = null; dupset = new DupResultSet(); dupset.Open(false, getTempFileName); // 获得结果集,对逐个记录进行处理 for (; ; ) { // TODO: 中间要可以中断 lRet = channel.DoGetSearchResult( "dup", // strResultSetName lStart, lPerCount, "zh", null, // stop out aPath, out strError); if (lRet == -1) goto ERROR1; if (lRet == 0) { strError = "未命中"; break; // ?? } // TODO: 要判断 aPath.Count == 0 跳出循环。否则容易进入死循环 // 处理浏览结果 for (int i = 0; i < aPath.Count; i++) { string strPath = aPath[i]; // 忽略发起记录的路径 if (strPath == strExcludeBiblioRecPath) continue; DupLineItem item = new DupLineItem(); item.Path = strPath; item.Weight = nWeight; item.Threshold = nThreshold; dupset.Add(item); } lStart += aPath.Count; if (lStart >= lHitCount || lPerCount <= 0) break; } return 1; ERROR1: return -1; }
// 获得用户记录 // return: // -1 error // 0 not found // >=1 检索命中的条数 public static int GetUserRecord( RmsChannel channel, string strUserName, out string strRecPath, out string strXml, out byte[] baTimeStamp, out string strError) { strError = ""; strXml = ""; strRecPath = ""; baTimeStamp = null; if (strUserName == "") { strError = "用户名为空"; return -1; } string strQueryXml = "<target list='" + Defs.DefaultUserDb.Name + ":" + Defs.DefaultUserDb.SearchPath.UserName + "'><item><word>" + strUserName + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>10</maxCount></item><lang>chi</lang></target>"; long nRet = channel.DoSearch(strQueryXml, "default", "", // strOutputStyle out strError); if (nRet == -1) { strError = "检索帐户库时出错: " + strError; return -1; } if (nRet == 0) return 0; // not found long nSearchCount = nRet; List<string> aPath = null; nRet = channel.DoGetSearchResult( "default", 1, "zh", null, // stop, out aPath, out strError); if (nRet == -1) { strError = "检索注册用户库获取检索结果时出错: " + strError; return -1; } if (aPath.Count == 0) { strError = "检索注册用户库获取的检索结果为空"; return -1; } // strRecID = ResPath.GetRecordId((string)aPath[0]); strRecPath = (string)aPath[0]; string strStyle = "content,data,timestamp,withresmetadata"; string strMetaData; string strOutputPath; nRet = channel.GetRes((string)aPath[0], strStyle, out strXml, out strMetaData, out baTimeStamp, out strOutputPath, out strError); if (nRet == -1) { strError = "获取注册用户库记录体时出错: " + strError; return -1; } return (int)nSearchCount; }
// 获得事项记录 // 本函数可获得超过1条以上的路径 // parameters: // timestamp 返回命中的第一条的timestamp // strStyle 如果包含 withresmetadata ,表示要在XML记录中返回<dprms:file>元素内的 __xxx 属性 // return: // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条 public int GetItemRecXml( // RmsChannelCollection channels, RmsChannel channel, List<string> locateParams, string strStyle, out string strXml, int nMax, out List<string> aPath, out byte[] timestamp, out string strError) { aPath = null; strXml = ""; strError = ""; timestamp = null; // 构造检索式 /* string strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strIssueDbName + ":" + "出版时间") + "'><item><word>" + StringUtil.GetXmlStringSimple(strPublishTime) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang></target>"; strQueryXml += "<operator value='AND'/>"; strQueryXml += "<target list='" + StringUtil.GetXmlStringSimple(strIssueDbName + ":" + "父记录") + "'><item><word>" + StringUtil.GetXmlStringSimple(strParentID) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang></target>"; strQueryXml = "<group>" + strQueryXml + "</group>"; * */ // 构造用于获取事项记录的XML检索式 string strQueryXml = ""; int nRet = MakeGetItemRecXmlSearchQuery( locateParams, nMax, out strQueryXml, out strError); if (nRet == -1) goto ERROR1; #if NO RmsChannel channel = channels.GetChannel(this.App.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } #endif long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; // not found if (lRet == 0) { string strText = ""; // 构造定位提示信息。用于报错。 nRet = GetLocateText( locateParams, out strText, out strError); if (nRet == -1) { strError = "定位信息没有找到。并且GetLocateText()函数报错: " + strError; return 0; } strError = strText + " 的事项没有找到"; return 0; } long lHitCount = lRet; // List<string> aPath = null; lRet = channel.DoGetSearchResult( "default", 0, Math.Min(nMax, lHitCount), "zh", null, out aPath, out strError); if (lRet == -1) goto ERROR1; Debug.Assert(aPath != null, ""); if (aPath.Count == 0) { strError = "DoGetSearchResult aPath error"; goto ERROR1; } string strMetaData = ""; string strOutputPath = ""; string strGetStyle = "content,data,metadata,timestamp,outputpath"; if (StringUtil.IsInList("withresmetadata", strStyle) == true) strGetStyle += ",withresmetadata"; lRet = channel.GetRes(aPath[0], strGetStyle, out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; return (int)lHitCount; ERROR1: return -1; }
// TODO:判断strRedID是否为空 // 获得评注记录 // 本函数为了执行效率方面的原因, 不去获得超过1条以上的路径 // return: // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条(即便在这种情况下, strOutputPath也返回了第一条的路径) public int GetCommentRecXml( // RmsChannelCollection channels, RmsChannel channel, string strRefID, out string strXml, out string strOutputPath, out byte[] timestamp, out string strError) { strOutputPath = ""; strXml = ""; strError = ""; timestamp = null; LibraryApplication app = this; // 构造检索式 string strQueryXml = ""; int nDbCount = 0; for (int i = 0; i < app.ItemDbs.Count; i++) { string strDbName = app.ItemDbs[i].CommentDbName; if (String.IsNullOrEmpty(strDbName) == true) continue; string strOneDbQuery = "<target list='" + StringUtil.GetXmlStringSimple(strDbName + ":" + "参考ID") + "'><item><word>" + StringUtil.GetXmlStringSimple(strRefID) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>1000</maxCount></item><lang>zh</lang></target>"; if (nDbCount > 0) { Debug.Assert(String.IsNullOrEmpty(strQueryXml) == false, ""); strQueryXml += "<operator value='OR'/>"; } strQueryXml += strOneDbQuery; nDbCount++; } if (nDbCount > 0) { strQueryXml = "<group>" + strQueryXml + "</group>"; } #if NO RmsChannel channel = channels.GetChannel(app.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } #endif long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; // not found if (lRet == 0) { strError = "参考ID '" + strRefID + "' 没有找到"; return 0; } long lHitCount = lRet; List<string> aPath = null; lRet = channel.DoGetSearchResult( "default", 0, 1, "zh", null, out aPath, out strError); if (lRet == -1) goto ERROR1; if (aPath.Count == 0) { strError = "DoGetSearchResult aPath error"; goto ERROR1; } string strMetaData = ""; lRet = channel.GetRes(aPath[0], out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; return (int)lHitCount; ERROR1: return -1; }
// TODO: 判断strBarcode是否为空 // 根据册条码号对实体库进行查重 // 本函数只负责查重, 并不获得记录体 // return: // -1 error // 其他 命中记录条数(不超过nMax规定的极限) public int SearchItemRecDup( // RmsChannelCollection channels, RmsChannel channel, string strBarcode, int nMax, out List<string> aPath, out string strError) { strError = ""; aPath = null; LibraryApplication app = this; /* 导致内核出问题但是没有strError内容的式子 <group> <operator value='OR'/> <target list='图书编目实体:册条码'> <item><word>0000001</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item> <lang>zh</lang> </target> </group> * */ // 构造检索式 string strQueryXml = ""; int nDbCount = 0; for (int i = 0; i < app.ItemDbs.Count; i++) { string strDbName = app.ItemDbs[i].DbName; // 2008/10/16 if (String.IsNullOrEmpty(strDbName) == true) continue; // 2007/4/5 改造 加上了 GetXmlStringSimple() string strOneDbQuery = "<target list='" + StringUtil.GetXmlStringSimple(strDbName + ":" + "册条码") // 2007/9/14 + "'><item><word>" + StringUtil.GetXmlStringSimple(strBarcode) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>" + nMax.ToString() + "</maxCount></item><lang>zh</lang></target>"; if (nDbCount > 0) { Debug.Assert(String.IsNullOrEmpty(strQueryXml) == false, ""); strQueryXml += "<operator value='OR'/>"; } strQueryXml += strOneDbQuery; nDbCount++; } if (nDbCount > 0) { strQueryXml = "<group>" + strQueryXml + "</group>"; } /* RmsChannel channel = channels.GetChannel(app.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } * */ Debug.Assert(channel != null, ""); long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) { // TODO: 为了跟踪问题的方便,可以在strError中加上strQueryXml内容 strError = "SearchItemRecDup() DoSearch() error: " + strError; goto ERROR1; } // not found if (lRet == 0) { strError = "册条码号 '" + strBarcode + "' 没有找到"; return 0; } long lHitCount = lRet; lRet = channel.DoGetSearchResult( "default", 0, nMax, "zh", null, out aPath, out strError); if (lRet == -1) { strError = "SearchItemRecDup() DoGetSearchResult() error: " + strError; goto ERROR1; } if (aPath.Count == 0) { strError = "DoGetSearchResult aPath error 和前面已经命中的条件矛盾"; goto ERROR1; } return (int)lHitCount; ERROR1: return -1; }
// TODO: 判断strDisplayName是否为空 // 根据显示名对读者库进行查重 // 本函数只负责查重, 并不获得记录体 // parameters: // strBarcode 读者证条码号 // return: // -1 error // 其他 命中记录条数(不超过nMax规定的极限) public int SearchReaderDisplayNameDup( // RmsChannelCollection channels, RmsChannel channel, string strDisplayName, int nMax, out List<string> aPath, out string strError) { strError = ""; aPath = null; LibraryApplication app = this; Debug.Assert(String.IsNullOrEmpty(strDisplayName) == false, ""); // 构造检索式 // 查重要针对全部读者库进行 string strQueryXml = ""; int nCount = 0; for (int i = 0; i < app.ReaderDbs.Count; i++) { string strDbName = app.ReaderDbs[i].DbName; Debug.Assert(String.IsNullOrEmpty(strDbName) == false, ""); if (nCount > 0) { Debug.Assert(String.IsNullOrEmpty(strQueryXml) == false, ""); strQueryXml += "<operator value='OR'/>"; } string strOneDbQuery = "<target list='" + StringUtil.GetXmlStringSimple(strDbName + ":" + "显示名") + "'><item><word>" + StringUtil.GetXmlStringSimple(strDisplayName) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>" + nMax.ToString() + "</maxCount></item><lang>zh</lang></target>"; nCount++; strQueryXml += strOneDbQuery; } if (nCount > 0) { strQueryXml = "<group>" + strQueryXml + "</group>"; } #if NO RmsChannel channel = channels.GetChannel(app.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } #endif string strResultSetName = "search_reader_dup_001"; // TODO: 两种检索点的结果不会产生重复吧,需要测试验证 long lRet = channel.DoSearch(strQueryXml, strResultSetName, "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; // not found if (lRet == 0) { strError = "显示名 '" + strDisplayName + "' 没有找到"; return 0; } long lHitCount = lRet; lRet = channel.DoGetSearchResult( strResultSetName, 0, nMax, "zh", null, out aPath, out strError); if (lRet == -1) goto ERROR1; if (aPath.Count == 0) { strError = "DoGetSearchResult aPath error 和前面已经命中的条件矛盾"; goto ERROR1; } return (int)lHitCount; ERROR1: return -1; }
// 根据读者证状态对读者库进行检索 // parameters: // strMatchStyle 匹配方式 left exact right middle // strState 读者证状态 // bOnlyIncirculation 是否仅仅包括参与流通的数据库? true :仅仅包括; false : 包括全部 // bGetPath == true 获得path; == false 获得barcode // return: // -1 error // 其他 命中记录条数(不超过nMax规定的极限) public int SearchReaderState( // RmsChannelCollection channels, RmsChannel channel, string strState, string strMatchStyle, bool bOnlyIncirculation, bool bGetPath, int nMax, out List<string> aPathOrBarcode, out string strError) { strError = ""; aPathOrBarcode = null; LibraryApplication app = this; // 构造检索式 string strQueryXml = ""; int nDbCount = 0; for (int i = 0; i < app.ReaderDbs.Count; i++) { string strDbName = app.ReaderDbs[i].DbName; if (bOnlyIncirculation == true) { if (app.ReaderDbs[i].InCirculation == false) continue; } Debug.Assert(String.IsNullOrEmpty(strDbName) == false, ""); string strOneDbQuery = "<target list='" + StringUtil.GetXmlStringSimple(strDbName + ":" + "状态") + "'><item><word>" + StringUtil.GetXmlStringSimple(strState) + "</word><match>" + strMatchStyle + "</match><relation>=</relation><dataType>string</dataType><maxCount>" + nMax.ToString() + "</maxCount></item><lang>zh</lang></target>"; if (nDbCount > 0) { Debug.Assert(String.IsNullOrEmpty(strQueryXml) == false, ""); strQueryXml += "<operator value='OR'/>"; } strQueryXml += strOneDbQuery; nDbCount++; } if (nDbCount > 0) { strQueryXml = "<group>" + strQueryXml + "</group>"; } else { strError = "目前尚没有参与流通的读者库"; return -1; } #if NO RmsChannel channel = channels.GetChannel(app.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } #endif string strResultSetName = "search_reader_state_001"; long lRet = channel.DoSearch(strQueryXml, strResultSetName, "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; // not found if (lRet == 0) { strError = "读者证状态 '" + strState + "' (匹配方式: " + strMatchStyle + ") 没有命中"; return 0; } long lHitCount = lRet; if (bGetPath == true) { lRet = channel.DoGetSearchResult( strResultSetName, 0, nMax, "zh", null, out aPathOrBarcode, out strError); if (lRet == -1) goto ERROR1; } else { // 获取检索命中结果 // 获得某一列信息的版本 lRet = channel.DoGetSearchResultOneColumn( strResultSetName, 0, nMax, "zh", null, 0, // nColumn, out aPathOrBarcode, out strError); } if (aPathOrBarcode.Count == 0) { strError = "DoGetSearchResult aPath error 和前面已经命中的条件矛盾"; goto ERROR1; } return (int)lHitCount; ERROR1: return -1; }
// TODO: 判断strBorrowItemBarcode是否为空 // 通过“所借册条码号”获得读者记录 // 本函数可获得超过1条以上的路径 // return: // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条 public int GetReaderRecXml( // RmsChannelCollection channels, RmsChannel channel, string strBorrowItemBarcode, out string strXml, int nMax, out List<string> aPath, out byte[] timestamp, out string strError) { aPath = null; strXml = ""; strError = ""; timestamp = null; LibraryApplication app = this; // 构造检索式 string strQueryXml = ""; for (int i = 0; i < app.ReaderDbs.Count; i++) { string strDbName = app.ReaderDbs[i].DbName; Debug.Assert(String.IsNullOrEmpty(strDbName) == false, ""); string strOneDbQuery = "<target list='" + StringUtil.GetXmlStringSimple(strDbName + ":" + "所借册条码") + "'><item><word>" + StringUtil.GetXmlStringSimple(strBorrowItemBarcode) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>" + nMax.ToString() + "</maxCount></item><lang>zh</lang></target>"; if (i > 0) strQueryXml += "<operator value='OR'/>"; strQueryXml += strOneDbQuery; } if (app.ReaderDbs.Count > 0) { strQueryXml = "<group>" + strQueryXml + "</group>"; } #if NO RmsChannel channel = channels.GetChannel(app.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } #endif long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; // not found if (lRet == 0) { strError = "所借册条码号 '" + strBorrowItemBarcode + "' 没有找到"; return 0; } long lHitCount = lRet; // List<string> aPath = null; lRet = channel.DoGetSearchResult( "default", 0, Math.Min(nMax, lHitCount), "zh", null, out aPath, out strError); if (lRet == -1) goto ERROR1; Debug.Assert(aPath != null, ""); if (aPath.Count == 0) { strError = "DoGetSearchResult aPath error"; goto ERROR1; } string strMetaData = ""; // byte[] timestamp = null; string strOutputPath = ""; lRet = channel.GetRes(aPath[0], out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; return (int)lHitCount; ERROR1: return -1; }
// 2007/6/27 // 获得通用记录 // 本函数可获得超过1条以上的路径 // return: // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条 public int GetRecXml( // RmsChannelCollection channels, RmsChannel channel, string strQueryXml, out string strXml, int nMax, out List<string> aPath, out byte[] timestamp, out string strError) { aPath = null; strXml = ""; strError = ""; timestamp = null; LibraryApplication app = this; #if NO RmsChannel channel = channels.GetChannel(app.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } #endif long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; // not found if (lRet == 0) { strError = "没有命中记录"; return 0; } long lHitCount = lRet; // List<string> aPath = null; lRet = channel.DoGetSearchResult( "default", 0, Math.Min(nMax, lHitCount), "zh", null, out aPath, out strError); if (lRet == -1) goto ERROR1; Debug.Assert(aPath != null, ""); if (aPath.Count == 0) { strError = "DoGetSearchResult aPath error"; goto ERROR1; } string strMetaData = ""; string strOutputPath = ""; lRet = channel.GetRes(aPath[0], out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; return (int)lHitCount; ERROR1: return -1; }
// TODO:判断strItemBarcode是否为空 // 获得预约到书队列记录 // parameters: // strItemBarcodeParam 册条码号。可以使用 @refID: 前缀 // return: // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条 public int GetArrivedQueueRecXml( // RmsChannelCollection channels, RmsChannel channel, string strItemBarcodeParam, out string strXml, out byte[] timestamp, out string strOutputPath, out string strError) { strOutputPath = ""; strXml = ""; strError = ""; timestamp = null; LibraryApplication app = this; string strFrom = "册条码"; // 注:旧的,也就是 2015/5/7 以前的 预约到书队列库里面并没有 参考ID 检索点,所以直接用带着 @refID 前缀的字符串进行检索即可。 // 等队列库普遍刷新检索点以后,改为使用下面一段代码 if (this.ArrivedDbKeysContainsRefIDKey() == true) { string strHead = "@refID:"; if (StringUtil.HasHead(strItemBarcodeParam, strHead, true) == true) { strFrom = "册参考ID"; strItemBarcodeParam = strItemBarcodeParam.Substring(strHead.Length).Trim(); if (string.IsNullOrEmpty(strItemBarcodeParam) == true) { strError = "参数 strItemBarcodeParam 值中参考ID部分不应为空"; return -1; } } } // 构造检索式 // 2007/4/5 改造 加上了 GetXmlStringSimple() string strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(app.ArrivedDbName + ":" + strFrom) + "'><item><word>" + StringUtil.GetXmlStringSimple(strItemBarcodeParam) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>1000</maxCount></item><lang>zh</lang></target>"; #if NO RmsChannel channel = channels.GetChannel(app.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } #endif long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; if (lRet == 0) { strError = "没有找到"; return 0; } long lHitCount = lRet; List<string> aPath = null; lRet = channel.DoGetSearchResult( "default", 0, 1, "zh", null, out aPath, out strError); if (lRet == -1) goto ERROR1; if (aPath.Count == 0) { strError = "DoGetSearchResult aPath error"; goto ERROR1; } string strMetaData = ""; lRet = channel.GetRes(aPath[0], out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; return (int)lHitCount; ERROR1: return -1; }
public void DoXmlSearch(bool bOutputKeyID) { textBox_xmlQuery_comment.Text = ""; // 第一阶段 TargetItemCollection targets = treeView_simpleQueryResTree. GetSearchTarget(); Debug.Assert(targets != null, "GetSearchTarget() 异常"); // 正式检索 string strError; if (bOutputKeyID == true) this.m_bFirstColumnIsKey = true; else this.m_bFirstColumnIsKey = false; this.ClearListViewPropertyCache(); this.ClearListViewItems(); stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在检索 ..."); stop.BeginLoop(); EnableControlsInSearching(true); // 2010/5/18 string strBrowseStyle = "id,cols"; string strOutputStyle = ""; if (bOutputKeyID == true) { strOutputStyle = "keyid"; strBrowseStyle = "keyid,id,key,cols"; } long lTotalCount = 0; // 命中记录总数 for(int i=0;i<targets.Count;i++) { if (stop.State >= 1) break; TargetItem item = (TargetItem)targets[i]; channel = Channels.GetChannel(item.Url); Debug.Assert(channel != null, "Channels.GetChannel 异常"); // MessageBox.Show(this, item.Xml); long nRet = channel.DoSearch(textBox_xmlQueryString.Text, "default", strOutputStyle, out strError); if (nRet == -1) { textBox_xmlQuery_comment.Text += "出错: " + strError + "\r\n"; MessageBox.Show(this, strError); continue; } lTotalCount += nRet; textBox_xmlQuery_comment.Text += "命中记录数: " + Convert.ToString(nRet) + "\r\n"; if (nRet == 0) continue; // 获取结果集 nRet = channel.DoBrowse(listView_browse, listView_browse.Lang, stop, "default", strBrowseStyle, out strError); if (nRet == -1) { textBox_xmlQuery_comment.Text += "装载浏览信息时出错: " + strError + "\r\n"; MessageBox.Show(this, strError); continue; } } if (targets.Count > 1) { textBox_xmlQuery_comment.Text += "命中总条数: " + Convert.ToString(lTotalCount) + "\r\n"; } stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); if (lTotalCount == 0) { MessageBox.Show(this, "未命中"); } EnableControlsInSearching(false); channel = null; }
// 根据馆代码、批次号和册条码号对盘点库进行查重 // 本函数只负责查重, 并不获得记录体 // return: // -1 error // 其他 命中记录条数(不超过nMax规定的极限) public int SearchInventoryRecDup( RmsChannel channel, string strLibraryCode, string strBatchNo, string strBarcode, string strRefID, int nMax, out List<string> aPath, out string strError) { strError = ""; aPath = null; string strInventoryDbName = GetInventoryDbName(); if (string.IsNullOrEmpty(strInventoryDbName) == true) { strError = "当前尚未配置盘点库,因此无法对盘点库进行查重"; return -1; } string strKey = ""; if (string.IsNullOrEmpty(strBarcode) == false) strKey = strLibraryCode + "|" + strBatchNo + "|" + strBarcode; else strKey = strLibraryCode + "|" + strBatchNo + "|@refID:" + strRefID; // 构造检索式 string strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strInventoryDbName + ":" + "查重键") + "'><item><word>" + StringUtil.GetXmlStringSimple(strKey) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>" + nMax.ToString() + "</maxCount></item><lang>zh</lang></target>"; Debug.Assert(channel != null, ""); long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) { // TODO: 为了跟踪问题的方便,可以在strError中加上strQueryXml内容 strError = "SearchInventoryRecDup() DoSearch() error: " + strError; goto ERROR1; } // not found if (lRet == 0) { strError = "查重键 '" + strKey + "' 没有找到"; return 0; } long lHitCount = lRet; lRet = channel.DoGetSearchResult( "default", 0, nMax, "zh", null, out aPath, out strError); if (lRet == -1) { strError = "SearchInventoryRecDup() DoGetSearchResult() error: " + strError; goto ERROR1; } if (aPath.Count == 0) { strError = "DoGetSearchResult aPath error 和前面已经命中的条件矛盾"; goto ERROR1; } return (int)lHitCount; ERROR1: return -1; }
// 复杂检索 public void DoComplexSearch(bool bOutputKeyID) { textBox_complexQuery_comment.Text = ""; ArrayList aServer = null; ArrayList aQueryXml = null; string strError = ""; long nRet = BuildQueryXml( out aServer, out aQueryXml, out strError); if (nRet == -1) { MessageBox.Show(strError); return; } if (aServer.Count == 0) { MessageBox.Show("因没有选定任何服务器地址,无法进行检索"); return; } // 正式检索 // string strError; if (bOutputKeyID == true) this.m_bFirstColumnIsKey = true; else this.m_bFirstColumnIsKey = false; this.ClearListViewPropertyCache(); this.ClearListViewItems(); stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在检索 ..."); stop.BeginLoop(); EnableControlsInSearching(true); // 2010/5/18 string strBrowseStyle = "id,cols"; string strOutputStyle = ""; if (bOutputKeyID == true) { strOutputStyle = "keyid"; strBrowseStyle = "keyid,id,key,cols"; } long lTotalCount = 0; // 命中记录总数 int i=0; for(i=0;i<aServer.Count;i++) { if (stop.State >= 1) break; string strServer = (string)aServer[i]; string strQueryXml = (string)aQueryXml[i]; channel = Channels.GetChannel(strServer); Debug.Assert(channel != null, "Channels.GetChannel 异常"); textBox_complexQuery_comment.Text += "目标服务器:\t" + strServer + "\r\n"; textBox_complexQuery_comment.Text += "检索式XML:\r\n" + DomUtil.GetIndentXml(strQueryXml) + "\r\n"; // MessageBox.Show(this, item.Xml); nRet = channel.DoSearch(strQueryXml, "default", strOutputStyle, out strError); if (nRet == -1) { textBox_complexQuery_comment.Text += "出错: " + strError + "\r\n"; MessageBox.Show(this, strError); continue; } lTotalCount += nRet; textBox_complexQuery_comment.Text += "命中记录数: " + Convert.ToString(nRet) + "\r\n"; if (nRet == 0) continue; // 获取结果集 nRet = channel.DoBrowse(listView_browse, listView_browse.Lang, stop, "default", strBrowseStyle, out strError); if (nRet == -1) { textBox_complexQuery_comment.Text += "装载浏览信息时出错: " + strError + "\r\n"; MessageBox.Show(this, strError); continue; } } if (aServer.Count > 1) { textBox_complexQuery_comment.Text += "命中总条数: " + Convert.ToString(lTotalCount) + "\r\n"; } stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); if (lTotalCount == 0) { MessageBox.Show(this, "未命中"); } EnableControlsInSearching(false); channel = null; }
// 获得读者记录, 为登录用途。注意,本函数不检查是否符合。 // 该函数的特殊性在于,它可以用多种检索入口,而不仅仅是条码号 // parameters: // strQueryWord 登录名 // 0) 如果以"RI:"开头,表示利用 参考ID 进行检索 // 1) 如果以"NB:"开头,表示利用姓名生日进行检索。姓名和生日之间间隔以'|'。姓名必须完整,生日为8字符形式 // 2) 如果以"EM:"开头,表示利用email地址进行检索。注意 email 本身应该是 email:xxxx 这样的形态。也就是说,整个加起来是 EM:email:xxxxx // 3) 如果以"TP:"开头,表示利用电话号码进行检索 // 4) 如果以"ID:"开头,表示利用身份证号进行检索 // 5) 如果以"CN:"开头,表示利用证件号码进行检索 // 6) 否则用证条码号进行检索 // return: // -2 当前没有配置任何读者库,或者可以操作的读者库 // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条 int GetReaderRecXmlForLogin( RmsChannel channel, string strLibraryCodeList, string strQueryWord, int nMaxHitCount, string strFormatList, out List<KernelRecord> records, out string strError) { strError = ""; records = new List<KernelRecord>(); int nRet = 0; LibraryApplication app = this; string strFrom = "证条码"; string strMatch = "exact"; // 构造检索式 string strQueryXml = ""; strQueryWord = strQueryWord.Trim(); string strPrefix = ""; string strName = ""; SplitLoginName(strQueryWord, out strPrefix, out strName); bool bBarcode = false; // 注意如果这里增补新的prefix, 函数 SplitLoginName() 也要同步修改 // 没有前缀 if (strPrefix == "") { bBarcode = true; strFrom = "证条码"; strMatch = "exact"; } else if (strPrefix == "NB:") { bBarcode = false; strFrom = "姓名生日"; strMatch = "left"; strQueryWord = strName; } else if (strPrefix == "EM:") { bBarcode = false; strFrom = "Email"; strMatch = "exact"; strQueryWord = strName; // 2016/4/11 注 strName 内容应为 email:xxxxx } else if (strPrefix == "TP:") { bBarcode = false; strFrom = "电话"; strMatch = "exact"; strQueryWord = strName; } else if (strPrefix == "ID:") { bBarcode = false; strFrom = "身份证号"; strMatch = "exact"; strQueryWord = strName; } else if (strPrefix == "CN:") { bBarcode = false; strFrom = "证号"; strMatch = "exact"; strQueryWord = strName; } else if (strPrefix == "RI:") { bBarcode = false; strFrom = "参考ID"; strMatch = "exact"; strQueryWord = strName; } else { strError = "未知的登录名前缀 '" + strPrefix + "'"; return -1; } List<string> dbnames = new List<string>(); // 获得读者库名列表 // parameters: // strReaderDbNames 库名列表字符串。如果为空,则表示全部读者库 // return: // -1 出错 // >=0 dbnames 中包含的读者库名数量 nRet = GetDbNameList("", strLibraryCodeList, out dbnames, out strError); if (nRet == -1) return -1; if (dbnames.Count == 0) { if (app.ReaderDbs.Count == 0) strError = "当前尚没有配置读者库"; else strError = "当前没有可以操作的读者库"; return -2; } { int i = 0; foreach (string strDbName in dbnames) { if (string.IsNullOrEmpty(strDbName) == true) continue; Debug.Assert(String.IsNullOrEmpty(strDbName) == false, ""); // 最多100条 // 2007/4/5 改造 加上了 GetXmlStringSimple() string strOneDbQuery = "<target list='" + StringUtil.GetXmlStringSimple(strDbName + ":" + strFrom) // 2007/9/14 + "'><item><word>" + StringUtil.GetXmlStringSimple(strQueryWord) + "</word><match>" + strMatch + "</match><relation>=</relation><dataType>string</dataType><maxCount>" + nMaxHitCount + "</maxCount></item><lang>zh</lang></target>"; if (string.IsNullOrEmpty(strQueryXml) == false) { Debug.Assert(String.IsNullOrEmpty(strQueryXml) == false, ""); strQueryXml += "<operator value='OR'/>"; } strQueryXml += strOneDbQuery; i++; } if (i > 1) { strQueryXml = "<group>" + strQueryXml + "</group>"; } } if (String.IsNullOrEmpty(strQueryXml) == true) { strError = "尚未配置读者库"; return -1; } long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) { strError = "channel.DoSearch() error : " + strError; return -1; } // not found if (lRet == 0) { strError = "没有找到"; return 0; } long lHitCount = lRet; if (lHitCount > 1 && bBarcode == true) { strError = "系统错误: 证条码号为 '" + strQueryWord + "' 的读者记录多于一个"; return -1; } try { SearchResultLoader loader = new SearchResultLoader(channel, null, "default", strFormatList); foreach (KernelRecord record in loader) { records.Add(record); if (nMaxHitCount >= 0 && records.Count >= nMaxHitCount) break; } return records.Count; } catch (Exception ex) { strError = ex.Message; return -1; } }
// TODO: 是否检查流通信息,需要可以通过参数控制 // 检索书目记录下属的事项记录,返回少量必要的信息,可以提供后面实做删除时使用 // parameters: // strStyle return_record_xml 要在DeleteEntityInfo结构中返回OldRecord内容 // check_circulation_info 检查是否具有流通信息。如果具有则会报错 2012/12/19 把缺省行为变为此参数 // return: // -1 error // 0 not exist item dbname // 1 exist item dbname public int SearchChildItems(RmsChannel channel, string strBiblioRecPath, string strStyle, out long lHitCount, out List<DeleteEntityInfo> entityinfos, out string strError) { strError = ""; lHitCount = 0; entityinfos = new List<DeleteEntityInfo>(); int nRet = 0; bool bReturnRecordXml = StringUtil.IsInList("return_record_xml", strStyle); bool bCheckCirculationInfo = StringUtil.IsInList("check_circulation_info", strStyle); bool bOnlyGetCount = StringUtil.IsInList("only_getcount", strStyle); string strBiblioDbName = ResPath.GetDbName(strBiblioRecPath); string strBiblioRecId = ResPath.GetRecordId(strBiblioRecPath); // 获得书目库对应的事项库名 string strItemDbName = ""; nRet = this.GetItemDbName(strBiblioDbName, out strItemDbName, out strError); if (nRet == -1) goto ERROR1; if (String.IsNullOrEmpty(strItemDbName) == true) return 0; // 检索实体库中全部从属于特定id的记录 string strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strItemDbName + ":" + "父记录") + "'><item><word>" + strBiblioRecId + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>" + "zh" + "</lang></target>"; long lRet = channel.DoSearch(strQueryXml, "entities", "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; if (lRet == 0) { strError = "没有找到属于书目记录 '" + strBiblioRecPath + "' 的任何"+this.ItemName+"记录"; return 0; } lHitCount = lRet; // 仅返回命中条数 if (bOnlyGetCount == true) return 0; int nResultCount = (int)lRet; int nMaxCount = 10000; if (nResultCount > nMaxCount) { strError = "命中"+this.ItemName+"记录数 " + nResultCount.ToString() + " 超过 "+nMaxCount.ToString()+", 暂时不支持针对它们的删除操作"; goto ERROR1; } int nStart = 0; int nPerCount = 100; for (; ; ) { List<string> aPath = null; lRet = channel.DoGetSearchResult( "entities", nStart, nPerCount, "zh", null, out aPath, out strError); if (lRet == -1) goto ERROR1; if (aPath.Count == 0) { strError = "aPath.Count == 0"; goto ERROR1; } // 获得每条记录 for (int i = 0; i < aPath.Count; i++) { string strMetaData = ""; string strXml = ""; byte[] timestamp = null; string strOutputPath = ""; lRet = channel.GetRes(aPath[i], out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); DeleteEntityInfo entityinfo = new DeleteEntityInfo(); if (lRet == -1) { /* entityinfo.RecPath = aPath[i]; entityinfo.ErrorCode = channel.OriginErrorCode; entityinfo.ErrorInfo = channel.ErrorInfo; entityinfo.OldRecord = ""; entityinfo.OldTimestamp = null; entityinfo.NewRecord = ""; entityinfo.NewTimestamp = null; entityinfo.Action = ""; * */ if (channel.ErrorCode == ChannelErrorCode.NotFound) continue; strError = "获取"+this.ItemName+"记录 '" + aPath[i] + "' 时发生错误: " + strError; goto ERROR1; // goto CONTINUE; } entityinfo.RecPath = strOutputPath; entityinfo.OldTimestamp = timestamp; if (bReturnRecordXml == true) entityinfo.OldRecord = strXml; if (bCheckCirculationInfo == true) { // 检查是否有借阅信息 // 把记录装入DOM XmlDocument domExist = new XmlDocument(); try { domExist.LoadXml(strXml); } catch (Exception ex) { strError = this.ItemName + "记录 '" + aPath[i] + "' 装载进入DOM时发生错误: " + ex.Message; goto ERROR1; } /* entityinfo.ItemBarcode = DomUtil.GetElementText(domExist.DocumentElement, "barcode"); * */ // TODO: 在日志恢复阶段调用本函数时,是否还有必要检查是否具有流通信息?似乎这时应强制删除为好 // 观察已经存在的记录是否有流通信息 // return: // -1 出错 // 0 没有 // 1 有。报错信息在strError中 nRet = this.HasCirculationInfo(domExist, out strError); if (nRet == -1) goto ERROR1; if (nRet == 1) { strError = "拟删除的" + this.ItemName + "记录 '" + entityinfo.RecPath + "' 中" + strError + "(此种情况可能不限于这一条),不能删除。因此全部删除操作均被放弃。"; goto ERROR1; } } // CONTINUE: entityinfos.Add(entityinfo); } nStart += aPath.Count; if (nStart >= nResultCount) break; } return 1; ERROR1: return -1; }
// 获得读者记录, 并检查密码是否符合。为登录用途 // 该函数的特殊性在于,它可以用多种检索入口,而不仅仅是条码号 // parameters: // strQueryWord 登录名 // 0) 如果以"RI:"开头,表示利用 参考ID 进行检索 // 1) 如果以"NB:"开头,表示利用姓名生日进行检索。姓名和生日之间间隔以'|'。姓名必须完整,生日为8字符形式 // 2) 如果以"EM:"开头,表示利用email地址进行检索。注意 email 本身应该是 email:xxxx 这样的形态。也就是说,整个加起来是 EM:email:xxxxx // 3) 如果以"TP:"开头,表示利用电话号码进行检索 // 4) 如果以"ID:"开头,表示利用身份证号进行检索 // 5) 如果以"CN:"开头,表示利用证件号码进行检索 // 6) 否则用证条码号进行检索 // strPassword 密码。如果为null,表示不进行密码判断。注意,不是"" // return: // -2 当前没有配置任何读者库,或者可以操作的读者库 // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条 int GetReaderRecXmlForLogin( // RmsChannelCollection channels, RmsChannel channel, string strLibraryCodeList, string strQueryWord, string strPassword, int nIndex, string strClientIP, string strGetToken, out bool bTempPassword, out string strXml, out string strOutputPath, out byte[] output_timestamp, out string strToken, out string strError) { strOutputPath = ""; strXml = ""; strError = ""; output_timestamp = null; bTempPassword = false; strToken = ""; int nRet = 0; LibraryApplication app = this; string strFrom = "证条码"; string strMatch = "exact"; // 构造检索式 string strQueryXml = ""; // int nRet = 0; strQueryWord = strQueryWord.Trim(); string strPrefix = ""; string strName = ""; SplitLoginName(strQueryWord, out strPrefix, out strName); bool bBarcode = false; // 注意如果这里增补新的prefix, 函数 SplitLoginName() 也要同步修改 // 没有前缀 if (strPrefix == "") { bBarcode = true; strFrom = "证条码"; strMatch = "exact"; } else if (strPrefix == "NB:") { bBarcode = false; strFrom = "姓名生日"; strMatch = "left"; strQueryWord = strName; } else if (strPrefix == "EM:") { bBarcode = false; strFrom = "Email"; strMatch = "exact"; strQueryWord = strName; // 2016/4/11 注 strName 内容应为 email:xxxxx } else if (strPrefix == "TP:") { bBarcode = false; strFrom = "电话"; strMatch = "exact"; strQueryWord = strName; } else if (strPrefix == "ID:") { bBarcode = false; strFrom = "身份证号"; strMatch = "exact"; strQueryWord = strName; } else if (strPrefix == "CN:") { bBarcode = false; strFrom = "证号"; strMatch = "exact"; strQueryWord = strName; } else if (strPrefix == "RI:") { // 2016/4/11 bBarcode = false; strFrom = "参考ID"; strMatch = "exact"; strQueryWord = strName; } else { strError = "未知的登录名前缀 '" + strPrefix + "'"; return -1; } List<string> dbnames = new List<string>(); // 获得读者库名列表 // parameters: // strReaderDbNames 库名列表字符串。如果为空,则表示全部读者库 // return: // -1 出错 // >=0 dbnames 中包含的读者库名数量 nRet = GetDbNameList("", strLibraryCodeList, out dbnames, out strError); if (nRet == -1) return -1; if (dbnames.Count == 0) { if (app.ReaderDbs.Count == 0) strError = "当前尚没有配置读者库"; else strError = "当前没有可以操作的读者库"; return -2; } { int i = 0; foreach (string strDbName in dbnames) { if (string.IsNullOrEmpty(strDbName) == true) continue; Debug.Assert(String.IsNullOrEmpty(strDbName) == false, ""); // 最多100条 // 2007/4/5 改造 加上了 GetXmlStringSimple() string strOneDbQuery = "<target list='" + StringUtil.GetXmlStringSimple(strDbName + ":" + strFrom) // 2007/9/14 + "'><item><word>" + StringUtil.GetXmlStringSimple(strQueryWord) + "</word><match>" + strMatch + "</match><relation>=</relation><dataType>string</dataType><maxCount>100</maxCount></item><lang>zh</lang></target>"; if (string.IsNullOrEmpty(strQueryXml) == false) { Debug.Assert(String.IsNullOrEmpty(strQueryXml) == false, ""); strQueryXml += "<operator value='OR'/>"; } strQueryXml += strOneDbQuery; i++; } if (i > 1) { strQueryXml = "<group>" + strQueryXml + "</group>"; } } #if NO if (app.ReaderDbs.Count == 0) { strError = "尚未配置读者库"; return -1; } { for (int i = 0; i < app.ReaderDbs.Count; i++) { string strDbName = app.ReaderDbs[i].DbName; Debug.Assert(String.IsNullOrEmpty(strDbName) == false, ""); // 最多100条 // 2007/4/5 改造 加上了 GetXmlStringSimple() string strOneDbQuery = "<target list='" + StringUtil.GetXmlStringSimple(strDbName + ":" + strFrom) // 2007/9/14 + "'><item><word>" + StringUtil.GetXmlStringSimple(strQueryWord) + "</word><match>"+strMatch+"</match><relation>=</relation><dataType>string</dataType><maxCount>100</maxCount></item><lang>zh</lang></target>"; if (i > 0) { Debug.Assert(String.IsNullOrEmpty(strQueryXml) == false, ""); strQueryXml += "<operator value='OR'/>"; } strQueryXml += strOneDbQuery; } if (app.ReaderDbs.Count > 0) { strQueryXml = "<group>" + strQueryXml + "</group>"; } } #endif if (String.IsNullOrEmpty(strQueryXml) == true) { strError = "尚未配置读者库"; return -1; } #if NO RmsChannel channel = channels.GetChannel(app.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } #endif long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) { strError = "channel.DoSearch() error : " + strError; goto ERROR1; } // not found if (lRet == 0) { strError = "没有找到"; return 0; } long lHitCount = lRet; if (lHitCount > 1 && bBarcode == true) { strError = "系统错误: 证条码号为 '" + strQueryWord + "' 的读者记录多于一个"; return -1; } lHitCount = Math.Min(lHitCount, 100); List<string> aPath = null; lRet = channel.DoGetSearchResult( "default", 0, lHitCount, "zh", null, out aPath, out strError); if (lRet == -1) goto ERROR1; if (aPath.Count == 0) { strError = "DoGetSearchResult aPath error"; goto ERROR1; } /* // 只命中一个 if (aPath.Count == 1) goto LOADONE; * */ // 排除掉证状态挂失的那些 List<string> aPathNew = new List<string>(); List<string> aXml = new List<string>(); List<string> aOutputPath = new List<string>(); List<byte[]> aTimestamp = new List<byte[]>(); for (int i = 0; i < aPath.Count; i++) { string strMetaData = ""; byte[] timestamp = null; lRet = channel.GetRes(aPath[i], out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; if (strPassword != null) { XmlDocument readerdom = null; nRet = LibraryApplication.LoadToDom(strXml, out readerdom, out strError); if (nRet == -1) { strError = "装载读者记录 '" + aPath[i] + "' 进入XML DOM时发生错误: " + strError; return -1; } /* string strState = DomUtil.GetElementText(readerdom.DocumentElement, "state"); * */ if (strPassword != null) // 2009/9/22 { // 验证读者密码 // return: // -1 error // 0 密码不正确 // 1 密码正确 nRet = VerifyReaderPassword( strClientIP, readerdom, strPassword, this.Clock.Now, out bTempPassword, out strError); if (nRet == -1) return -1; if (nRet == 0) continue; if (string.IsNullOrEmpty(strGetToken) == false) { string strHashedPassword = DomUtil.GetElementInnerText(readerdom.DocumentElement, "password"); nRet = MakeToken(strClientIP, GetTimeRangeByStyle(strGetToken), strHashedPassword, out strToken, out strError); if (nRet == -1) return -1; } } } aPathNew.Add(aPath[i]); aXml.Add(strXml); aOutputPath.Add(strOutputPath); aTimestamp.Add(timestamp); } // 过滤后,却又发现一个都没有了。凑合着给过滤前的第一个? if (aPathNew.Count == 0) { /* aPathNew.Add(aPath[0]); aPath = aPathNew; lHitCount = 1; goto LOADONE; * */ return 0; } if (nIndex >= aXml.Count) { strError = "选择索引值 " + nIndex.ToString() + " 越过范围。"; return -1; } if (aXml.Count == 1 && nIndex == -1) nIndex = 0; if (nIndex != -1) { strXml = aXml[nIndex]; strOutputPath = aOutputPath[nIndex]; output_timestamp = aTimestamp[nIndex]; } return aPathNew.Count; ERROR1: return -1; /* LOADONE: { string strMetaData = ""; byte[] timestamp = null; lRet = channel.GetRes(aPath[0], out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; } return (int)lHitCount; * */ }
// 根据 定位信息 对事项库进行查重 // 本函数只负责查重, 并不获得记录体 // return: // -1 error // 其他 命中记录条数(不超过nMax规定的极限) public int SearchItemRecDup( // RmsChannelCollection channels, RmsChannel channel, List<string> locateParams, /* string strIssueDbName, string strParentID, string strPublishTime, * */ int nMax, out List<string> aPath, out string strError) { strError = ""; aPath = null; // 构造检索式 string strQueryXml = ""; int nRet = MakeGetItemRecXmlSearchQuery( locateParams, 100, out strQueryXml, out strError); if (nRet == -1) goto ERROR1; /* RmsChannel channel = channels.GetChannel(this.App.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } * */ Debug.Assert(channel != null, ""); long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; // not found if (lRet == 0) { string strText = ""; // 构造定位提示信息。用于报错。 nRet = GetLocateText( locateParams, out strText, out strError); if (nRet == -1) { strError = "定位信息没有找到。并且GetLocateText()函数报错: " + strError; return 0; } strError = strText + " 的事项没有找到"; return 0; } long lHitCount = lRet; lRet = channel.DoGetSearchResult( "default", 0, nMax, "zh", null, out aPath, out strError); if (lRet == -1) goto ERROR1; if (aPath.Count == 0) { strError = "DoGetSearchResult aPath error 和前面已经命中的条件矛盾"; goto ERROR1; } return (int)lHitCount; ERROR1: return -1; }
/// <summary> /// 检索并获取浏览结果 /// </summary> /// <param name="strServerUrl">服务器URL。如果==""或者==null,表示用this.ServerUrl</param> /// <param name="strQueryXml"></param> /// <param name="bGetBrowseCols">是否要获得浏览列</param> /// <param name="strError"></param> /// <returns>-2 用户中断;-1 一般错误;0 未命中; >=1 正常结束,返回命中条数</returns> public long SearchAndBrowse( string strServerUrl, string strQueryXml, bool bGetBrowseCols, out string strError) { strError = ""; if (strServerUrl == null || strServerUrl == null) strServerUrl = this.ServerUrl; RmsChannel channelSave = channel; channel = Channels.GetChannel(strServerUrl); if (channel == null) { strError = "get channel error"; return -1; } try { // 检索 long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) return -1; if (lRet == 0) return 0; // 循环获取结果 long nHitCount = lRet; long nStart = 0; long nCount = 10; long nIndex = 0; for(;;) { Application.DoEvents(); // 出让界面控制权 if (stop != null) { if (stop.State != 0) { strError = "用户中断"; return -2; } } List<string> aPath = null; ArrayList aLine = null; if (bGetBrowseCols == false) { lRet = channel.DoGetSearchResult( "default", nStart, nCount, "zh", this.stop, out aPath, out strError); } else { lRet = channel.DoGetSearchFullResult( "default", nStart, nCount, "zh", this.stop, out aLine, out strError); } if (lRet == -1) { strError = "获取检索结果时出错: " + strError; return -1; } if (bGetBrowseCols == false) nStart += aPath.Count; else nStart += aLine.Count; // 触发事件 if (this.BrowseRecord != null) { int nThisCount = 0; if (bGetBrowseCols == false) nThisCount = aPath.Count; else nThisCount = aLine.Count; for (int j = 0; j < nThisCount; j++) { BrowseRecordEventArgs e = new BrowseRecordEventArgs(); e.SearchCount = nHitCount; e.Index = nIndex ++; if (bGetBrowseCols == false) { e.FullPath = strServerUrl + "?" + (string)aPath[j]; } else { string[] cols = (string[])aLine[j]; e.FullPath = strServerUrl + "?" + cols[0]; // 丢掉第一列 e.Cols = new string[Math.Max(cols.Length - 1, 0)]; Array.Copy(cols, 1, e.Cols, 0, cols.Length - 1); } this.BrowseRecord(this, e); if (e.Cancel == true) { if (e.ErrorInfo == "") strError = "用户中断"; else strError = e.ErrorInfo; return -2; } } } if (nStart >= nHitCount) break; // 2006/9/24 add 防止nStart + nCount越界 if (nStart + nCount > nHitCount) nCount = nHitCount - nStart; else nCount = 10; } return nHitCount; } finally { channel = channelSave; } }
/// <summary> /// 检索获得若干路径 /// </summary> /// <param name="channel"></param> /// <param name="strDbName"></param> /// <param name="strFrom"></param> /// <param name="strKey"></param> /// <param name="nMax"></param> /// <param name="paths"></param> /// <param name="strError"></param> /// <returns>-1 error;0 not found;>=1 found</returns> static int SearchPath(RmsChannel channel, string strDbName, string strFrom, string strKey, long nMax, out string[] paths, out string strError) { paths = null; strError = ""; // 2007/4/5 改造 加上了 GetXmlStringSimple() string strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strDbName + ":" + strFrom) // 2007/9/14 + "'><item><word>" + StringUtil.GetXmlStringSimple(strKey) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>" + Convert.ToString(nMax) + "</maxCount></item><lang>zh</lang></target>"; long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) { strError = "检索库 '" + strDbName + "/" + strFrom + "' 时出错: " + strError; return -1; } if (lRet == 0) { return 0; // 没有找到 } if (lRet > 1) { strError = "以Key '" + strKey + "' 检索库 '" + strDbName + "' 时命中 " + Convert.ToString(lRet) + " 条,属于不正常情况。请修改库 '" + strDbName + "' 中相应记录,确保同一Key只有一条对应的记录。"; return -1; } List<string> aPath = null; lRet = channel.DoGetSearchResult( "default", 0, -1, "zh", null, // this.stop, out aPath, out strError); if (lRet == -1) { strError = "检索库 '" + strDbName + "' 获取检索结果时出错: " + strError; return -1; } paths = new string[aPath.Count]; for (int i = 0; i < aPath.Count; i++) { paths[i] = (string)aPath[i]; } return paths.Length; }
// 2016/11/15 改造为不用 GetRes() 获取记录 // 检索书目记录下属的实体记录,返回少量必要的信息,可以提供后面实做删除时使用 // parameters: // strStyle check_borrow_info,count_borrow_info,return_record_xml // 当包含 check_borrow_info 时,发现第一个流通信息,本函数就立即返回-1 // 当包含 count_borrow_info 时,函数要统计全部流通信息的个数 // 当包含 libraryCodes: 时,表示仅获得所列分馆代码的册记录。注意多个馆代码之间用竖线分隔 // 当包含 limit: 时,定义最多取得记录的个数。例如希望最多取得 10 条,可以定义 limit:10 // return: // -2 not exist entity dbname // -1 error // >=0 含有流通信息的实体记录个数, 当strStyle包含count_borrow_info时。 public int SearchChildEntities(RmsChannel channel, string strBiblioRecPath, string strStyle, Delegate_checkRecord procCheckRecord, object param, out long lHitCount, out List<DeleteEntityInfo> entityinfos, out string strError) { strError = ""; lHitCount = 0; entityinfos = new List<DeleteEntityInfo>(); int nRet = 0; bool bCheckBorrowInfo = StringUtil.IsInList("check_borrow_info", strStyle); bool bCountBorrowInfo = StringUtil.IsInList("count_borrow_info", strStyle); bool bReturnRecordXml = StringUtil.IsInList("return_record_xml", strStyle); bool bOnlyGetCount = StringUtil.IsInList("only_getcount", strStyle); if (bCheckBorrowInfo == true && bCountBorrowInfo == true) { strError = "strStyle中check_borrow_info和count_borrow_info不能同时具备"; return -1; } string strLibraryCodeParam = StringUtil.GetParameterByPrefix(strStyle, "libraryCodes", ":"); string strLimit = StringUtil.GetParameterByPrefix(strStyle, "limit", ":"); string strBiblioDbName = ResPath.GetDbName(strBiblioRecPath); string strBiblioRecId = ResPath.GetRecordId(strBiblioRecPath); // 获得书目库对应的实体库名 string strItemDbName = ""; nRet = this.GetItemDbName(strBiblioDbName, out strItemDbName, out strError); if (nRet == -1) goto ERROR1; // 2008/12/5 if (String.IsNullOrEmpty(strItemDbName) == true) return 0; // 检索实体库中全部从属于特定id的记录 string strQueryXml = ""; if (string.IsNullOrEmpty(strLibraryCodeParam) == true) { strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strItemDbName + ":" + "父记录") // 2007/9/14 + "'><item><word>" + strBiblioRecId + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>" + "zh" + "</lang></target>"; } else { // 仅仅取得当前用户管辖的分馆的册记录 List<string> codes = StringUtil.SplitList(strLibraryCodeParam, '|'); // sessioninfo.LibraryCodeList foreach (string strCode in codes) { string strOneQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strItemDbName + ":" + "父记录+馆藏地点") + "'><item><word>" + StringUtil.GetXmlStringSimple(strBiblioRecId + "|" + strCode + "/") + "</word><match>left</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>" + "zh" + "</lang></target>"; if (string.IsNullOrEmpty(strQueryXml) == false) { Debug.Assert(String.IsNullOrEmpty(strQueryXml) == false, ""); strQueryXml += "<operator value='OR'/>"; } strQueryXml += strOneQueryXml; } if (codes.Count > 0) { strQueryXml = "<group>" + strQueryXml + "</group>"; } } long lRet = channel.DoSearch(strQueryXml, "entities", "", // strOuputStyle out strError); if (lRet == -1) goto ERROR1; if (lRet == 0) { strError = "没有找到属于书目记录 '" + strBiblioRecPath + "' 的任何实体记录"; return 0; } lHitCount = lRet; // 仅返回命中条数 if (bOnlyGetCount == true) return 0; int nResultCount = (int)lRet; if (nResultCount > 10000) { strError = "命中册记录数 " + nResultCount.ToString() + " 超过 10000, 暂时不支持针对它们的删除操作"; goto ERROR1; } string strColumnStyle = "id,xml,timestamp"; int nLimit = -1; if (string.IsNullOrEmpty(strLimit) == false) Int32.TryParse(strLimit, out nLimit); int nBorrowInfoCount = 0; int nStart = 0; int nPerCount = 100; if (nLimit != -1 && nPerCount > nLimit) nPerCount = nLimit; for (; ; ) { #if NO List<string> aPath = null; lRet = channel.DoGetSearchResult( "entities", nStart, nPerCount, "zh", null, out aPath, out strError); if (lRet == -1) goto ERROR1; if (aPath.Count == 0) { strError = "aPath.Count == 0"; goto ERROR1; } #endif Record[] searchresults = null; lRet = channel.DoGetSearchResult( "entities", nStart, nPerCount, strColumnStyle, "zh", null, out searchresults, out strError); if (lRet == -1) goto ERROR1; if (searchresults == null) { strError = "searchresults == null"; goto ERROR1; } if (searchresults.Length == 0) { strError = "searchresults.Length == 0"; goto ERROR1; } // 获得每条记录 // for (int i = 0; i < aPath.Count; i++) int i = 0; foreach (Record record in searchresults) { // EntityInfo info = new EntityInfo(); // info.OldRecPath = record.Path; string strMetaData = ""; string strXml = ""; byte[] timestamp = null; string strOutputPath = ""; DeleteEntityInfo entityinfo = new DeleteEntityInfo(); if (record.RecordBody == null || string.IsNullOrEmpty(record.RecordBody.Xml) == true) { lRet = channel.GetRes(record.Path, out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) continue; strError = "获取实体记录 '" + record.Path + "' 时发生错误: " + strError; goto ERROR1; } } else { strXml = record.RecordBody.Xml; strOutputPath = record.Path; timestamp = record.RecordBody.Timestamp; } entityinfo.RecPath = strOutputPath; entityinfo.OldTimestamp = timestamp; if (bReturnRecordXml == true) entityinfo.OldRecord = strXml; if (bCheckBorrowInfo == true || bCountBorrowInfo == true || procCheckRecord != null) { // 检查是否有借阅信息 // 把记录装入DOM XmlDocument domExist = new XmlDocument(); try { domExist.LoadXml(strXml); } catch (Exception ex) { strError = "实体记录 '" + strOutputPath + "' 装载进入DOM时发生错误: " + ex.Message; goto ERROR1; } if (procCheckRecord != null) { nRet = procCheckRecord( nStart + i, strOutputPath, domExist, timestamp, param, out strError); if (nRet != 0) return nRet; } entityinfo.ItemBarcode = DomUtil.GetElementText(domExist.DocumentElement, "barcode"); // TODO: 在日志恢复阶段调用本函数时,是否还有必要检查是否具有流通信息?似乎这时应强制删除为好 // 观察已经存在的记录是否有流通信息 string strDetail = ""; bool bHasCirculationInfo = IsEntityHasCirculationInfo(domExist, out strDetail); if (bHasCirculationInfo == true) { if (bCheckBorrowInfo == true) { strError = "拟删除的册记录 '" + entityinfo.RecPath + "' 中包含有流通信息(" + strDetail + ")(此种情况可能不限于这一条),不能删除。因此全部删除操作均被放弃。"; goto ERROR1; } if (bCountBorrowInfo == true) nBorrowInfoCount++; } } // CONTINUE: entityinfos.Add(entityinfo); i++; } nStart += searchresults.Length; if (nStart >= nResultCount) break; if (nLimit != -1 && nStart >= nLimit) break; } return nBorrowInfoCount; ERROR1: return -1; }