void FillDbNameList() { this.listView_dbnames.Items.Clear(); if (this.MainForm.BiblioDbProperties != null) { for (int i = 0; i < this.MainForm.BiblioDbProperties.Count; i++) { BiblioDbProperty prop = this.MainForm.BiblioDbProperties[i]; if (String.IsNullOrEmpty(prop.ItemDbName) == true) { continue; } if (String.IsNullOrEmpty(this.MarcSyntax) == false) { if (prop.Syntax.ToLower() != this.MarcSyntax.ToLower()) { continue; } } // 2008/12/29 if (this.SeriesMode == true) { if (String.IsNullOrEmpty(prop.IssueDbName) == true) { continue; } } else { if (String.IsNullOrEmpty(prop.IssueDbName) == false) { continue; } } string strDbName = prop.DbName; ListViewItem item = new ListViewItem(); item.Text = strDbName; this.listView_dbnames.Items.Add(item); if (item.Text == this.DbName) { item.Selected = true; } } } }
// return: // null strBiblioRecPath 不是书目库名 public static string GetPublicationType(string strBiblioRecPath) { string strBiblioDbName = Global.GetDbName(strBiblioRecPath); BiblioDbProperty prop = Program.MainForm.GetBiblioDbProperty(strBiblioDbName); if (prop == null) { return(null); } if (string.IsNullOrEmpty(prop.IssueDbName) == true) { return("book"); } return("series"); }
public string CompareTwoBiblioDbDef(string strSourceDbName, string strTargetDbName) { BiblioDbProperty source = this.GetBiblioDbProperty(strSourceDbName); BiblioDbProperty target = this.GetBiblioDbProperty(strTargetDbName); if (source == null) { return("源书目库名 '" + strSourceDbName + "' 不存在"); } if (target == null) { return("目标书目库名 '" + strTargetDbName + "' 不存在"); } List <string> errors = new List <string>(); if (string.IsNullOrEmpty(source.ItemDbName) == false && string.IsNullOrEmpty(target.ItemDbName) == true) { errors.Add("实体库 '" + source.ItemDbName + "' "); // 左边大于右边 } if (string.IsNullOrEmpty(source.OrderDbName) == false && string.IsNullOrEmpty(target.OrderDbName) == true) { errors.Add("订购库 '" + source.OrderDbName + "' "); // 左边大于右边 } if (string.IsNullOrEmpty(source.IssueDbName) == false && string.IsNullOrEmpty(target.IssueDbName) == true) { errors.Add("期库 '" + source.IssueDbName + "' "); // 左边大于右边 } if (string.IsNullOrEmpty(source.CommentDbName) == false && string.IsNullOrEmpty(target.CommentDbName) == true) { errors.Add("评注库 '" + source.CommentDbName + "' "); // 左边大于右边 } if (errors.Count == 0) { return(null); } return("源书目库 '" + strSourceDbName + "' 具有下属的" + StringUtil.MakePathList(errors, "、") + ",而目标书目库 '" + strTargetDbName + "' 缺乏"); }
public int InitialBiblioDbProperties( out string strError) { strError = ""; int nRet = 0; this.BiblioDbProperties = new List <BiblioDbProperty>(); if (this.AllDatabaseDom == null) { return(0); } XmlNodeList nodes = this.AllDatabaseDom.DocumentElement.SelectNodes("database[@type='biblio']"); foreach (XmlNode node in nodes) { string strName = DomUtil.GetAttr(node, "name"); string strType = DomUtil.GetAttr(node, "type"); // string strRole = DomUtil.GetAttr(node, "role"); // string strLibraryCode = DomUtil.GetAttr(node, "libraryCode"); BiblioDbProperty property = new BiblioDbProperty(); this.BiblioDbProperties.Add(property); property.DbName = DomUtil.GetAttr(node, "name"); property.ItemDbName = DomUtil.GetAttr(node, "entityDbName"); property.Syntax = DomUtil.GetAttr(node, "syntax"); property.IssueDbName = DomUtil.GetAttr(node, "issueDbName"); property.OrderDbName = DomUtil.GetAttr(node, "orderDbName"); property.CommentDbName = DomUtil.GetAttr(node, "commentDbName"); property.Role = DomUtil.GetAttr(node, "role"); bool bValue = true; nRet = DomUtil.GetBooleanParam(node, "inCirculation", true, out bValue, out strError); property.InCirculation = bValue; } return(0); }
// 2009/10/24 // /// <summary> /// 是否为采购工作库? /// </summary> /// <param name="strBiblioDbName">书目库名</param> /// <returns>是否为采购工作裤</returns> public bool IsOrderWorkDb(string strBiblioDbName) { if (this.BiblioDbProperties != null) { for (int i = 0; i < this.BiblioDbProperties.Count; i++) { BiblioDbProperty prop = this.BiblioDbProperties[i]; if (prop.DbName == strBiblioDbName) { if (StringUtil.IsInList("orderWork", prop.Role) == true) { return(true); } } } } return(false); }
private void comboBox_biblioDbName_DropDown(object sender, EventArgs e) { if (this.comboBox_biblioDbName.Items.Count > 0) { return; } if (Program.MainForm.BiblioDbProperties == null) { return; } for (int i = 0; i < Program.MainForm.BiblioDbProperties.Count; i++) { BiblioDbProperty property = Program.MainForm.BiblioDbProperties[i]; // 只允许特定的 MARC 格式 if (string.IsNullOrEmpty(this.MarcSyntax) == false && property.Syntax != this.MarcSyntax) { continue; } this.comboBox_biblioDbName.Items.Add(property.DbName); } }
// 构造一个检索词的XML检索式局部 // 本函数不递归 // return: // -1 出错 // 0 数据库没有找到 // 1 成功 static int BuildOneXml( ZHostInfo zhost, List <string> dbnames, string strTerm, long lAttritueValue, out string strQueryXml, out string strError) { strQueryXml = ""; try { strError = ""; if (dbnames.Count == 0) { strError = "一个数据库名也未曾指定"; return(-1); } // string strFrom = ""; // 根据nAttributeType nAttributeValue得到检索途径名 // 先评估一下,是不是每个数据库都有一样的maxResultCount参数。 // 如果是,则可以把这些数据库都组合为一个<target>; // 如果不是,则把相同的挑选出来成为一个<target>,然后多个<target>用OR组合起来 // 为此,可以先把数据库属性对象按照maxResultCount参数排序,以便聚合是用<target>。 // 但是这带来一个问题:最后发生的检索库的先后顺序,就不是用户要求的那个顺序了。 // 看来,还得按照用户指定的数据库顺序来构造<item>。那么,就不得不降低聚合的可能, // 而仅仅聚合相邻的、maxResultCount值相同的那些 int nPrevMaxResultCount = -1; // 前一个MaxResultCount参数值 List <List <BiblioDbProperty> > prop_groups = new List <List <BiblioDbProperty> >(); List <BiblioDbProperty> props = new List <BiblioDbProperty>(); for (int i = 0; i < dbnames.Count; i++) { string strDbName = dbnames[i]; BiblioDbProperty prop = zhost.GetDbProperty(strDbName, true); if (prop == null) { strError = "数据库 '" + strDbName + "' 不存在"; return(0); } // 如果当前库的MaxResultCount参数和前面紧邻的不一样了,则需要推入当前正在使用的props,新起一个props if (prop.MaxResultCount != nPrevMaxResultCount && props.Count != 0) { Debug.Assert(props.Count > 0, "不为空的props才能推入 (1)"); prop_groups.Add(props); props = new List <BiblioDbProperty>(); // 新增加一个props } props.Add(prop); nPrevMaxResultCount = prop.MaxResultCount; } Debug.Assert(props.Count > 0, "不为空的props才能推入 (2)"); prop_groups.Add(props); // 将最后一个props加入到group数组中 for (int i = 0; i < prop_groups.Count; i++) { props = prop_groups[i]; string strTargetListValue = ""; int nMaxResultCount = -1; for (int j = 0; j < props.Count; j++) { BiblioDbProperty prop = props[j]; string strDbName = prop.DbName; #if DEBUG if (j != 0) { Debug.Assert(prop.MaxResultCount == nMaxResultCount, "props内的每个数据库都应当有相同的MaxResultCount参数值"); } #endif if (j == 0) { nMaxResultCount = prop.MaxResultCount; // 只取第一个prop的值即可 } string strFrom = zhost.GetFromName(strDbName, lAttritueValue, out string strOutputDbName, out strError); if (strFrom == null) { return(-1); // 寻找from名的过程发生错误 } if (strTargetListValue != "") { strTargetListValue += ";"; } Debug.Assert(strOutputDbName != "", ""); strTargetListValue += strOutputDbName + ":" + strFrom; } if (i != 0) { strQueryXml += "<operator value='OR' />"; } strQueryXml += "<target list='" + strTargetListValue + "'>" + "<item><word>" + SecurityElement.Escape(strTerm) + "</word><match>left</match><relation>=</relation><dataType>string</dataType>" + "<maxCount>" + nMaxResultCount.ToString() + "</maxCount></item>" + "<lang>zh</lang></target>"; } // 如果有多个props,则需要在检索XML外面包裹一个<target>元素,以作为一个整体和其他部件进行逻辑操作 if (prop_groups.Count > 1) { strQueryXml = "<target>" + strQueryXml + "</target>"; } return(1); } catch (Exception ex) { strError = ex.Message; return(-1); } }
public int InitialBiblioDbProperties( out string strError) { strError = ""; int nRet = 0; this.BiblioDbProperties = new List<BiblioDbProperty>(); if (this.AllDatabaseDom == null) return 0; XmlNodeList nodes = this.AllDatabaseDom.DocumentElement.SelectNodes("database[@type='biblio']"); foreach (XmlNode node in nodes) { string strName = DomUtil.GetAttr(node, "name"); string strType = DomUtil.GetAttr(node, "type"); // string strRole = DomUtil.GetAttr(node, "role"); // string strLibraryCode = DomUtil.GetAttr(node, "libraryCode"); BiblioDbProperty property = new BiblioDbProperty(); this.BiblioDbProperties.Add(property); property.DbName = DomUtil.GetAttr(node, "name"); property.ItemDbName = DomUtil.GetAttr(node, "entityDbName"); property.Syntax = DomUtil.GetAttr(node, "syntax"); property.IssueDbName = DomUtil.GetAttr(node, "issueDbName"); property.OrderDbName = DomUtil.GetAttr(node, "orderDbName"); property.CommentDbName = DomUtil.GetAttr(node, "commentDbName"); property.Role = DomUtil.GetAttr(node, "role"); bool bValue = true; nRet = DomUtil.GetBooleanParam(node, "inCirculation", true, out bValue, out strError); property.InCirculation = bValue; } return 0; }
/* * 检查两条记录是否适合建立目标关系 * 1) 源库,应当是采购工作库 * 2) 源库和目标库,不是一个库 * 3) 源库的syntax和目标库的syntax,是一样的 * 4) 目标库不应该是外源角色 * */ // parameters: // strSourceRecPath 记录ID可以为问号 // strTargetRecPath 记录ID可以为问号,仅当bCheckTargetWenhao==false时 // return: // -1 出错 // 0 不适合建立目标关系 (这种情况是没有什么错,但是不适合建立) // 1 适合建立目标关系 internal int CheckBuildLinkCondition(string strSourceBiblioRecPath, string strTargetBiblioRecPath, bool bCheckTargetWenhao, out string strError) { strError = ""; // TODO: 最好检查一下这个路径的格式。合法的书目库名可以在MainForm中找到 // 检查是不是书目库名。MARC格式是否和当前数据库一致。不能是当前记录自己 string strTargetDbName = Global.GetDbName(strTargetBiblioRecPath); string strTargetRecordID = Global.GetRecordID(strTargetBiblioRecPath); if (String.IsNullOrEmpty(strTargetDbName) == true || String.IsNullOrEmpty(strTargetRecordID) == true) { strError = "目标记录路径 '" + strTargetBiblioRecPath + "' 不是合法的记录路径"; goto ERROR1; } // 2009/11/25 if (this.IsBiblioSourceDb(strTargetDbName) == true) { strError = "库 '" + strTargetDbName + "' 是 外源书目库 角色,不能作为目标库"; return(0); } // 2011/11/29 if (this.IsOrderWorkDb(strTargetDbName) == true) { strError = "库 '" + strTargetDbName + "' 是 采购工作库 角色,不能作为目标库"; return(0); } string strSourceDbName = Global.GetDbName(strSourceBiblioRecPath); string strSourceRecordID = Global.GetRecordID(strSourceBiblioRecPath); if (String.IsNullOrEmpty(strSourceDbName) == true || String.IsNullOrEmpty(strSourceRecordID) == true) { strError = "源记录路径 '" + strSourceBiblioRecPath + "' 不是合法的记录路径"; goto ERROR1; } /* * if (this.IsOrderWorkDb(strSourceDbName) == false) * { * strError = "源库 '" + strSourceDbName + "' 不具备 采购工作库 角色"; * return 0; * }*/ // 根据书目库名获得MARC格式语法名 // return: // null 没有找到指定的书目库名 string strSourceSyntax = this.GetBiblioSyntax(strSourceDbName); if (String.IsNullOrEmpty(strSourceSyntax) == true) { strSourceSyntax = "unimarc"; } string strSourceIssueDbName = this.GetIssueDbName(strSourceDbName); bool bFound = false; if (this.BiblioDbProperties != null) { for (int i = 0; i < this.BiblioDbProperties.Count; i++) { BiblioDbProperty prop = this.BiblioDbProperties[i]; if (prop.DbName == strTargetDbName) { bFound = true; string strTargetSyntax = prop.Syntax; if (String.IsNullOrEmpty(strTargetSyntax) == true) { strTargetSyntax = "unimarc"; } if (strTargetSyntax != strSourceSyntax) { strError = "拟设置的目标记录因其书目数据格式为 '" + strTargetSyntax + "',与源记录的书目数据格式 '" + strSourceSyntax + "' 不一致,因此操作被拒绝"; return(0); } if (String.IsNullOrEmpty(prop.IssueDbName) != String.IsNullOrEmpty(strSourceIssueDbName)) { strError = "拟设置的目标记录因其书目库 '" + strTargetDbName + "' 文献类型(期刊还是图书)和源记录的书目库 '" + strSourceDbName + "' 不一致,因此操作被拒绝"; return(0); } } } } if (bFound == false) { strError = "'" + strTargetDbName + "' 不是合法的书目库名"; goto ERROR1; } // source if (this.IsBiblioDbName(strSourceDbName) == false) { strError = "'" + strSourceDbName + "' 不是合法的书目库名"; goto ERROR1; } if (strSourceRecordID == "?") { /* 源记录ID可以为问号,因为这不妨碍建立连接关系 * strError = "源记录 '"+strSourceBiblioRecPath+"' 路径中ID不能为问号"; * return 0; * */ } else { // 如果不是问号,就要检查一下了,没坏处 if (Global.IsPureNumber(strSourceRecordID) == false) { strError = "源记录 '" + strSourceBiblioRecPath + "' 路径中ID部分必须为纯数字"; goto ERROR1; } } // target if (strTargetRecordID == "?") { if (bCheckTargetWenhao == true) { strError = "目标记录 '" + strTargetBiblioRecPath + "' 路径中ID不能为问号"; return(0); } } else { if (Global.IsPureNumber(strTargetRecordID) == false) { strError = "目标记录 '" + strTargetBiblioRecPath + "' 路径中ID部分必须为纯数字"; goto ERROR1; } } if (strTargetDbName == strSourceDbName) { strError = "目标记录和源记录不能属于同一个书目库 '" + strTargetBiblioRecPath + "'"; return(0); // 注:这样就不用检查目标是否源记录了 } return(1); ERROR1: return(-1); }
// 构造一个检索词的XML检索式局部 // 本函数不递归 // return: // -1 出错 // 0 数据库没有找到 // 1 成功 static int BuildOneXml( ZHostInfo zhost, List <string> dbnames, string strTerm, long lAttritueValue, out string strQueryXml, out string strError) { strQueryXml = ""; try { strError = ""; if (dbnames.Count == 0) { strError = "一个数据库名也未曾指定"; return(-1); } // string strFrom = ""; // 根据nAttributeType nAttributeValue得到检索途径名 // 先评估一下,是不是每个数据库都有一样的maxResultCount参数。 // 如果是,则可以把这些数据库都组合为一个<target>; // 如果不是,则把相同的挑选出来成为一个<target>,然后多个<target>用OR组合起来 // 为此,可以先把数据库属性对象按照maxResultCount参数排序,以便聚合是用<target>。 // 但是这带来一个问题:最后发生的检索库的先后顺序,就不是用户要求的那个顺序了。 // 看来,还得按照用户指定的数据库顺序来构造<item>。那么,就不得不降低聚合的可能, // 而仅仅聚合相邻的、maxResultCount值相同的那些 int nPrevMaxResultCount = -1; // 前一个MaxResultCount参数值 List <List <BiblioDbProperty> > prop_groups = new List <List <BiblioDbProperty> >(); List <BiblioDbProperty> props = new List <BiblioDbProperty>(); for (int i = 0; i < dbnames.Count; i++) { string strDbName = dbnames[i]; BiblioDbProperty prop = zhost.GetDbProperty(strDbName, true); if (prop == null) { strError = "数据库 '" + strDbName + "' 不存在"; return(0); } // 如果当前库的MaxResultCount参数和前面紧邻的不一样了,则需要推入当前正在使用的props,新起一个props if (prop.MaxResultCount != nPrevMaxResultCount && props.Count != 0) { Debug.Assert(props.Count > 0, "不为空的props才能推入 (1)"); prop_groups.Add(props); props = new List <BiblioDbProperty>(); // 新增加一个props } props.Add(prop); nPrevMaxResultCount = prop.MaxResultCount; } Debug.Assert(props.Count > 0, "不为空的props才能推入 (2)"); prop_groups.Add(props); // 将最后一个props加入到group数组中 // 没有找到 From 的列表 // use编号 --> 关于没有找到的报错字符串 Hashtable notFoundTable = new Hashtable(); for (int i = 0; i < prop_groups.Count; i++) { props = prop_groups[i]; string strTargetListValue = ""; int nMaxResultCount = -1; for (int j = 0; j < props.Count; j++) { BiblioDbProperty prop = props[j]; string strDbName = prop.DbName; #if DEBUG if (j != 0) { Debug.Assert(prop.MaxResultCount == nMaxResultCount, "props内的每个数据库都应当有相同的MaxResultCount参数值"); } #endif if (j == 0) { nMaxResultCount = prop.MaxResultCount; // 只取第一个prop的值即可 } /* * string strFrom = zhost.GetFromName(strDbName, * lAttritueValue, * out string strOutputDbName, * out strError); * if (strFrom == null) * return -1; // 寻找from名的过程发生错误 */ var result = zhost.GetFromName(strDbName, lAttritueValue); if (result.Value == -1) { // 2020/5/23 // 如果是 use 没有找到,这里暂时不急于判断。如果后面找到了至少一次,就不报错;否则(就是说一次都没有找到)就要报错 if (result.ErrorCode == "useNotFound") { notFoundTable[$"{lAttritueValue}"] = result.ErrorInfo; continue; } strError = result.ErrorInfo; return(-1); } if (strTargetListValue != "") { strTargetListValue += ";"; } Debug.Assert(string.IsNullOrEmpty(result.DbName) == false, ""); Debug.Assert(string.IsNullOrEmpty(result.From) == false, ""); strTargetListValue += result.DbName + ":" + result.From; } if (string.IsNullOrEmpty(strTargetListValue)) { continue; } if (i != 0) { strQueryXml += "<operator value='OR' />"; } strQueryXml += "<target list='" + strTargetListValue + "'>" + "<item><word>" + SecurityElement.Escape(strTerm) + "</word><match>left</match><relation>=</relation><dataType>string</dataType>" + "<maxCount>" + nMaxResultCount.ToString() + "</maxCount></item>" + "<lang>zh</lang></target>"; } if (string.IsNullOrEmpty(strQueryXml) == true) { List <string> keys = new List <string>(); foreach (string key in notFoundTable.Keys) { keys.Add(key); } strError = $"use '{StringUtil.MakePathList(keys)}' 没有定义"; return(-1); } // 如果有多个props,则需要在检索XML外面包裹一个<target>元素,以作为一个整体和其他部件进行逻辑操作 if (prop_groups.Count > 1) { strQueryXml = "<target>" + strQueryXml + "</target>"; } return(1); } catch (Exception ex) { strError = ex.Message; return(-1); } }
private static void Zserver_PresentGetRecords(object sender, PresentGetRecordsEventArgs e) { string strError = ""; int nCondition = 100; // (unspecified)error ZServerChannel zserver_channel = (ZServerChannel)sender; if (zserver_channel == null) { throw new ArgumentException("zserver_channel 为空"); } string strInstanceName = zserver_channel.EnsureProperty().GetKeyValue("i_n"); if (strInstanceName == null) { strError = "通道中 实例名 'i_n' 尚未初始化"; // ?? bug LibraryManager.Log?.Error(strError); goto ERROR1; } Instance instance = FindZ3950Instance(strInstanceName, out strError); if (instance == null) { if (string.IsNullOrEmpty(strError)) { strError = "实例名 '" + strInstanceName + "' 不存在(或实例没有启用 Z39.50 服务)"; } goto ERROR1; } if (instance.Running == false) { strError = "实例 '" + instance.Name + "' 正在维护中,暂时不能访问"; nCondition = 1019; // Init/AC: System not available due to maintenance goto ERROR1; } string strResultSetName = e.Request.m_strResultSetID; if (String.IsNullOrEmpty(strResultSetName) == true) { strResultSetName = "default"; } long lStart = e.Request.m_lResultSetStartPoint - 1; long lNumber = e.Request.m_lNumberOfRecordsRequested; int MAX_PRESENT_RECORD = 100; // 限制每次 present 的记录数量 if (lNumber > MAX_PRESENT_RECORD) { lNumber = MAX_PRESENT_RECORD; } DiagFormat diag = null; List <RetrivalRecord> records = new List <RetrivalRecord>(); string strUserName = zserver_channel.EnsureProperty().GetKeyValue("i_u"); string strPassword = zserver_channel.EnsureProperty().GetKeyValue("i_p"); LoginInfo login_info = BuildLoginInfo(strUserName, strPassword); LibraryChannel library_channel = instance.MessageConnection.GetChannel(login_info); zserver_channel.Tag = library_channel; try { // 全局结果集名 string resultset_name = MakeGlobalResultSetName(zserver_channel, strResultSetName); // TODO: timestamp 有必要获取么? ResultSetLoader loader = new ResultSetLoader(library_channel, resultset_name, "id,xml,timestamp") { Start = lStart, BatchSize = Math.Min(10, lNumber) }; int i = 0; int nSize = 0; foreach (DigitalPlatform.LibraryClient.localhost.Record dp2library_record in loader) { if (i >= lNumber) { break; } // 判断请求边界是否合法。放到循环里面的 i==0 时刻来做,是因为枚举器(loader)需要请求 dp2library 之后才能知道结果集大小 if (i == 0) { e.TotalCount = loader.TotalCount; if (lStart >= loader.TotalCount) { DiagFormat diag1 = null; ZProcessor.SetPresentDiagRecord(ref diag1, 13, // Present request out-of-range "Present 所请求的起始偏移位置 " + lStart + " 超过结果集中记录总数 " + loader.TotalCount); e.Diag = diag1; return; } if (lStart + lNumber > loader.TotalCount) { DiagFormat diag1 = null; ZProcessor.SetPresentDiagRecord(ref diag1, 13, // Present request out-of-range "Present 所请求的结束偏移位置 " + (lStart + lNumber) + " 超过结果集中记录总数 " + loader.TotalCount); e.Diag = diag1; return; } } { // 解析出数据库名和ID string strDbName = dp2StringUtil.GetDbName(dp2library_record.Path); string strRecID = dp2StringUtil.GetRecordID(dp2library_record.Path); // 如果取得的是xml记录,则根元素可以看出记录的marc syntax,进一步可以获得oid; // 如果取得的是MARC格式记录,则需要根据数据库预定义的marc syntax来看出oid了 // string strMarcSyntaxOID = GetMarcSyntaxOID(instance, strDbName); // string strMarcSyntaxOID = GetMarcSyntaxOID(dp2library_record); RetrivalRecord record = new RetrivalRecord { m_strDatabaseName = strDbName }; // 根据书目库名获得书目库属性对象 // TODO: 这里可以考虑 cache BiblioDbProperty prop = instance.zhost.GetDbProperty( strDbName, false); int nRet = GetIso2709Record(dp2library_record, e.Request.m_elementSetNames, prop != null ? prop.AddField901 : false, prop != null ? prop.RemoveFields : "997", zserver_channel.EnsureProperty().MarcRecordEncoding, out string strMarcSyntaxOID, out byte[] baIso2709, out strError); /* * // 测试记录群中包含诊断记录 * if (i == 1) * { * nRet = -1; * strError = "测试获取记录错误"; * } */ if (nRet == -1) { record.m_surrogateDiagnostic = new DiagFormat { m_strDiagSetID = "1.2.840.10003.4.1", m_nDiagCondition = 14, // system error in presenting records m_strAddInfo = strError }; } else if (nRet == 0) { record.m_surrogateDiagnostic = new DiagFormat { m_strDiagSetID = "1.2.840.10003.4.1", m_nDiagCondition = 1028, // record deleted m_strAddInfo = strError }; } else if (String.IsNullOrEmpty(strMarcSyntaxOID) == true) { // 根据数据库名无法获得marc syntax oid。可能是虚拟库检索命中记录所在的物理库没有在 capo.xml 中配置。 record.m_surrogateDiagnostic = new DiagFormat { m_strDiagSetID = "1.2.840.10003.4.1", m_nDiagCondition = 227, // No data available in requested record syntax // 239? // m_strAddInfo = "根据数据库名 '" + strDbName + "' 无法获得 marc syntax oid" m_strAddInfo = "根据书目记录 '" + dp2library_record.Path + "' 的 MARCXML 无法获得 marc syntax oid" }; } else { record.m_external = new External { m_strDirectRefenerce = strMarcSyntaxOID, m_octectAligned = baIso2709 }; } // TODO: 测试观察这里的 size 增长情况 nSize += record.GetPackageSize(); if (i == 0) { // 连一条记录也放不下 if (nSize > zserver_channel.EnsureProperty().ExceptionalRecordSize) { Debug.Assert(diag == null, ""); ZProcessor.SetPresentDiagRecord(ref diag, 17, // record exceeds Exceptional_record_size "记录尺寸 " + nSize.ToString() + " 超过 Exceptional_record_size " + zserver_channel.EnsureProperty().ExceptionalRecordSize.ToString()); lNumber = 0; break; } } else { if (nSize >= zserver_channel.EnsureProperty().PreferredMessageSize) { // TODO: 记入日志? // 调整返回的记录数 lNumber = i; break; } } records.Add(record); } i++; // 2018/9/28 // 防范性编程 // TODO: 还可以通过时间长度来控制。超过一定时间,就抛出异常 if (i > MAX_PRESENT_RECORD) { throw new Exception("Zserver_PresentGetRecords() 中获取记录的循环超过极限数量 " + MAX_PRESENT_RECORD + "(此时 lNumber=" + lNumber + ")"); } } } catch (ChannelException ex) { // 指定的结果集没有找到 if (ex.ErrorCode == DigitalPlatform.LibraryClient.localhost.ErrorCode.NotFound) { nCondition = 30; // Specified result set does not exist strError = ex.Message; goto ERROR1; } strError = "获取结果集时出现异常(ChannelException): " + ex.Message; goto ERROR1; } catch (Exception ex) { strError = "获取结果集时出现异常: " + ex.Message; goto ERROR1; } finally { zserver_channel.Tag = null; instance.MessageConnection.ReturnChannel(library_channel); } e.Records = records; e.Diag = diag; return; ERROR1: { DiagFormat diag1 = null; ZProcessor.SetPresentDiagRecord(ref diag1, nCondition, strError); e.Diag = diag1; return; } }
// 只填充和SourceBiblioDbName具有相同syntax的、相同出版物类型的书目库名 // SourceBiblioDbName自己被排除在外 int FillDbNames(out string strError) { strError = ""; string strSourceSyntax = ""; bool bSourceIsIssueDb = false; if (String.IsNullOrEmpty(this.SourceBiblioDbName) == false) { strSourceSyntax = Program.MainForm.GetBiblioSyntax(this.SourceBiblioDbName); if (strSourceSyntax == null) { strError = "源书目库名 '" + this.SourceBiblioDbName + "' 居然不存在"; return(-1); } if (String.IsNullOrEmpty(strSourceSyntax) == true) { strSourceSyntax = "unimarc"; } string strSourceIssueDbName = Program.MainForm.GetIssueDbName(this.SourceBiblioDbName); if (String.IsNullOrEmpty(strSourceIssueDbName) == false) { bSourceIsIssueDb = true; } else { bSourceIsIssueDb = false; } } if (Program.MainForm.BiblioDbProperties != null) { for (int i = 0; i < Program.MainForm.BiblioDbProperties.Count; i++) { BiblioDbProperty prop = Program.MainForm.BiblioDbProperties[i]; // 需要具备实体库 if (String.IsNullOrEmpty(prop.ItemDbName) == true) { continue; } // 排除this.SourcBibliDbName if (prop.DbName == this.SourceBiblioDbName) { continue; } // 判断syntax if (String.IsNullOrEmpty(strSourceSyntax) == false) { string strTempSyntax = prop.Syntax; if (String.IsNullOrEmpty(strTempSyntax) == true) { strTempSyntax = "unimarc"; } if (prop.Syntax != strSourceSyntax) { continue; } } // 判断出版类型 if (String.IsNullOrEmpty(prop.IssueDbName) == false && bSourceIsIssueDb == false) { continue; // 出版物类型不一致 } ListViewItem item = new ListViewItem(); item.Text = prop.DbName; this.listView_dbNames.Items.Add(item); } } ListViewItem selected_item = ListViewUtil.FindItem(this.listView_dbNames, this.textBox_dbName.Text, 0); if (selected_item != null) { selected_item.Selected = true; } return(0); }
private static void Zserver_PresentGetRecords(object sender, PresentGetRecordsEventArgs e) { string strError = ""; ZServerChannel zserver_channel = (ZServerChannel)sender; string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n"); if (strInstanceName == null) { strError = "通道中 实例名 '" + strInstanceName + "' 尚未初始化"; ZManager.Log.Error(strError); goto ERROR1; } Instance instance = FindInstance(strInstanceName); if (instance == null) { strError = "实例名 '" + strInstanceName + "' 不存在"; goto ERROR1; } string strResultSetName = e.Request.m_strResultSetID; if (String.IsNullOrEmpty(strResultSetName) == true) { strResultSetName = "default"; } long lStart = e.Request.m_lResultSetStartPoint - 1; long lNumber = e.Request.m_lNumberOfRecordsRequested; int MAX_PRESENT_RECORD = 100; // 限制每次 present 的记录数量 if (lNumber > MAX_PRESENT_RECORD) { lNumber = MAX_PRESENT_RECORD; } DiagFormat diag = null; List <RetrivalRecord> records = new List <RetrivalRecord>(); string strUserName = zserver_channel.SetProperty().GetKeyValue("i_u"); string strPassword = zserver_channel.SetProperty().GetKeyValue("i_p"); LoginInfo login_info = new LoginInfo { UserName = strUserName, Password = strPassword }; LibraryChannel library_channel = instance.MessageConnection.GetChannel(login_info); try { // 全局结果集名 string resultset_name = MakeGlobalResultSetName(zserver_channel, strResultSetName); ResultSetLoader loader = new ResultSetLoader(library_channel, resultset_name, "id,xml,timestamp") { Start = lStart, BatchSize = Math.Min(10, lNumber) }; int i = 0; int nSize = 0; foreach (DigitalPlatform.LibraryClient.localhost.Record dp2library_record in loader) { if (i >= lNumber) { break; } if (i == 0) { e.TotalCount = loader.TotalCount; if (lStart >= loader.TotalCount) { DiagFormat diag1 = null; ZProcessor.SetPresentDiagRecord(ref diag1, 13, // Present request out-of-range "Present 所请求的起始偏移位置 " + lStart + " 超过结果集中记录总数 " + loader.TotalCount); e.Diag = diag1; return; } } { // 解析出数据库名和ID string strDbName = dp2StringUtil.GetDbName(dp2library_record.Path); string strRecID = dp2StringUtil.GetRecordID(dp2library_record.Path); // 如果取得的是xml记录,则根元素可以看出记录的marc syntax,进一步可以获得oid; // 如果取得的是MARC格式记录,则需要根据数据库预定义的marc syntax来看出oid了 string strMarcSyntaxOID = GetMarcSyntaxOID(instance, strDbName); RetrivalRecord record = new RetrivalRecord { m_strDatabaseName = strDbName }; // 根据书目库名获得书目库属性对象 BiblioDbProperty prop = instance.zhost.GetDbProperty( strDbName, false); int nRet = GetIso2709Record(dp2library_record, e.Request.m_elementSetNames, prop != null ? prop.AddField901 : false, prop != null ? prop.RemoveFields : "997", zserver_channel.SetProperty().MarcRecordEncoding, out byte[] baIso2709, out strError); /* * // 测试记录群中包含诊断记录 * if (i == 1) * { * nRet = -1; * strError = "测试获取记录错误"; * } */ if (nRet == -1) { record.m_surrogateDiagnostic = new DiagFormat { m_strDiagSetID = "1.2.840.10003.4.1", m_nDiagCondition = 14, // system error in presenting records m_strAddInfo = strError }; } else if (nRet == 0) { record.m_surrogateDiagnostic = new DiagFormat { m_strDiagSetID = "1.2.840.10003.4.1", m_nDiagCondition = 1028, // record deleted m_strAddInfo = strError }; } else if (String.IsNullOrEmpty(strMarcSyntaxOID) == true) { // 根据数据库名无法获得marc syntax oid。可能是虚拟库检索命中记录所在的物理库没有在 capo.xml 中配置。 record.m_surrogateDiagnostic = new DiagFormat { m_strDiagSetID = "1.2.840.10003.4.1", m_nDiagCondition = 109, // database unavailable // 似乎235:database dos not exist也可以 m_strAddInfo = "根据数据库名 '" + strDbName + "' 无法获得 marc syntax oid" }; } else { record.m_external = new External { m_strDirectRefenerce = strMarcSyntaxOID, m_octectAligned = baIso2709 }; } nSize += record.GetPackageSize(); if (i == 0) { // 连一条记录也放不下 if (nSize > zserver_channel.SetProperty().ExceptionalRecordSize) { Debug.Assert(diag == null, ""); ZProcessor.SetPresentDiagRecord(ref diag, 17, // record exceeds Exceptional_record_size "记录尺寸 " + nSize.ToString() + " 超过 Exceptional_record_size " + zserver_channel.SetProperty().ExceptionalRecordSize.ToString()); lNumber = 0; break; } } else { if (nSize >= zserver_channel.SetProperty().PreferredMessageSize) { // 调整返回的记录数 lNumber = i; break; } } records.Add(record); } i++; } } catch (Exception ex) { strError = "获取结果集时出现异常: " + ex.Message; goto ERROR1; } finally { instance.MessageConnection.ReturnChannel(library_channel); } e.Records = records; e.Diag = diag; return; ERROR1: { DiagFormat diag1 = null; ZProcessor.SetPresentDiagRecord(ref diag1, 2, // temporary system error strError); e.Diag = diag1; // e.Result = new ZClient.SearchResult { Value = -1, ErrorInfo = strError }; return; } }
// // return: // -1 出错,不希望继续以后的操作 // 0 成功 // 1 出错,但希望继续后面的操作 /// <summary> /// 获得编目库属性列表 /// </summary> /// <returns>-1: 出错,不希望继续以后的操作; 0: 成功; 1: 出错,但希望继续后面的操作</returns> public int InitialBiblioDbProperties() { REDO: int nRet = PrepareSearch(); if (nRet == 0) return -1; // this.Update(); string strError = ""; Stop.OnStop += new StopEventHandler(this.DoStop); Stop.Initial("正在获得书目库属性列表 ..."); Stop.BeginLoop(); try { string strValue = ""; long lRet = 0; this.BiblioDbProperties = new List<BiblioDbProperty>(); // 新用法:一次性获得全部参数 lRet = Channel.GetSystemParameter(Stop, "system", "biblioDbGroup", out strValue, out strError); if (lRet == -1) { strError = "针对服务器 " + Channel.Url + " 获得书目库信息过程发生错误:" + strError; goto ERROR1; } if (String.IsNullOrEmpty(strValue) == true) { // 还是用旧方法 lRet = Channel.GetSystemParameter(Stop, "biblio", "dbnames", out strValue, out strError); if (lRet == -1) { strError = "针对服务器 " + Channel.Url + " 获得编目库名列表过程发生错误:" + strError; goto ERROR1; } string[] biblioDbNames = strValue.Split(new char[] { ',' }); for (int i = 0; i < biblioDbNames.Length; i++) { BiblioDbProperty property = new BiblioDbProperty(); property.DbName = biblioDbNames[i]; this.BiblioDbProperties.Add(property); } // 获得语法格式 lRet = Channel.GetSystemParameter(Stop, "biblio", "syntaxs", out strValue, out strError); if (lRet == -1) { strError = "针对服务器 " + Channel.Url + " 获得编目库数据格式列表过程发生错误:" + strError; goto ERROR1; } string[] syntaxs = strValue.Split(new char[] { ',' }); if (syntaxs.Length != this.BiblioDbProperties.Count) { strError = "针对服务器 " + Channel.Url + " 获得编目库名为 " + this.BiblioDbProperties.Count.ToString() + " 个,而数据格式为 " + syntaxs.Length.ToString() + " 个,数量不一致"; goto ERROR1; } // 增补数据格式 for (int i = 0; i < this.BiblioDbProperties.Count; i++) { this.BiblioDbProperties[i].Syntax = syntaxs[i]; } { // 获得对应的实体库名 lRet = Channel.GetSystemParameter(Stop, "item", "dbnames", out strValue, out strError); if (lRet == -1) { strError = "针对服务器 " + Channel.Url + " 获得实体库名列表过程发生错误:" + strError; goto ERROR1; } string[] itemdbnames = strValue.Split(new char[] { ',' }); if (itemdbnames.Length != this.BiblioDbProperties.Count) { strError = "针对服务器 " + Channel.Url + " 获得编目库名为 " + this.BiblioDbProperties.Count.ToString() + " 个,而实体库名为 " + itemdbnames.Length.ToString() + " 个,数量不一致"; goto ERROR1; } // 增补数据格式 for (int i = 0; i < this.BiblioDbProperties.Count; i++) { this.BiblioDbProperties[i].ItemDbName = itemdbnames[i]; } } { // 获得对应的期库名 lRet = Channel.GetSystemParameter(Stop, "issue", "dbnames", out strValue, out strError); if (lRet == -1) { strError = "针对服务器 " + Channel.Url + " 获得期库名列表过程发生错误:" + strError; goto ERROR1; } string[] issuedbnames = strValue.Split(new char[] { ',' }); if (issuedbnames.Length != this.BiblioDbProperties.Count) { return 0; // TODO: 暂时不警告。等将来所有用户都更换了dp2libraryws 2007/10/19以后的版本后,这里再警告 /* strError = "针对服务器 " + Channel.Url + " 获得编目库名为 " + this.BiblioDbProperties.Count.ToString() + " 个,而期库名为 " + issuedbnames.Length.ToString() + " 个,数量不一致"; goto ERROR1; * */ } // 增补数据格式 for (int i = 0; i < this.BiblioDbProperties.Count; i++) { this.BiblioDbProperties[i].IssueDbName = issuedbnames[i]; } } /////// { // 获得对应的订购库名 lRet = Channel.GetSystemParameter(Stop, "order", "dbnames", out strValue, out strError); if (lRet == -1) { strError = "针对服务器 " + Channel.Url + " 获得订购库名列表过程发生错误:" + strError; goto ERROR1; } string[] orderdbnames = strValue.Split(new char[] { ',' }); if (orderdbnames.Length != this.BiblioDbProperties.Count) { return 0; // TODO: 暂时不警告。等将来所有用户都更换了dp2libraryws 2007/11/30以后的版本后,这里再警告 /* strError = "针对服务器 " + Channel.Url + " 获得编目库名为 " + this.BiblioDbProperties.Count.ToString() + " 个,而订购库名为 " + orderdbnames.Length.ToString() + " 个,数量不一致"; goto ERROR1; * */ } // 增补数据格式 for (int i = 0; i < this.BiblioDbProperties.Count; i++) { this.BiblioDbProperties[i].OrderDbName = orderdbnames[i]; } } } else { // 新方法 XmlDocument dom = new XmlDocument(); dom.LoadXml("<root />"); try { dom.DocumentElement.InnerXml = strValue; } catch (Exception ex) { strError = "category=system,name=biblioDbGroup所返回的XML片段在装入InnerXml时出错: " + ex.Message; goto ERROR1; } XmlNodeList nodes = dom.DocumentElement.SelectNodes("database"); for (int i = 0; i < nodes.Count; i++) { XmlNode node = nodes[i]; BiblioDbProperty property = new BiblioDbProperty(); this.BiblioDbProperties.Add(property); property.DbName = DomUtil.GetAttr(node, "biblioDbName"); property.ItemDbName = DomUtil.GetAttr(node, "itemDbName"); property.Syntax = DomUtil.GetAttr(node, "syntax"); property.IssueDbName = DomUtil.GetAttr(node, "issueDbName"); property.OrderDbName = DomUtil.GetAttr(node, "orderDbName"); property.CommentDbName = DomUtil.GetAttr(node, "commentDbName"); property.Role = DomUtil.GetAttr(node, "role"); bool bValue = true; nRet = DomUtil.GetBooleanParam(node, "inCirculation", true, out bValue, out strError); property.InCirculation = bValue; } } // MessageBox.Show(this, Convert.ToString(lRet) + " : " + strError); } finally { Stop.EndLoop(); Stop.OnStop -= new StopEventHandler(this.DoStop); Stop.Initial(""); EndSearch(); } return 0; ERROR1: DialogResult result = MessageBox.Show(this, strError + "\r\n\r\n是否重试?", "dp2Circulation", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == System.Windows.Forms.DialogResult.Yes) goto REDO; if (result == DialogResult.No) return 1; // 出错,但希望继续后面的操作 return -1; // 出错,不希望继续以后的操作 }
// // return: // -1 出错,不希望继续以后的操作 // 0 成功 // 1 出错,但希望继续后面的操作 /// <summary> /// 获得编目库属性列表 /// </summary> /// <param name="bPrepareSearch">是否要准备通道</param> /// <returns>-1: 出错,不希望继续以后的操作; 0: 成功; 1: 出错,但希望继续后面的操作</returns> public int InitialBiblioDbProperties(bool bPrepareSearch = true) { REDO: if (bPrepareSearch == true) { if (PrepareSearch() == 0) return -1; } // this.Update(); string strError = ""; int nRet = 0; Stop.OnStop += new StopEventHandler(this.DoStop); Stop.Initial("正在初始化书目库属性列表 ..."); Stop.BeginLoop(); try { this.BiblioDbProperties = new List<BiblioDbProperty>(); if (this.AllDatabaseDom == null) return 0; XmlNodeList nodes = this.AllDatabaseDom.DocumentElement.SelectNodes("database[@type='biblio']"); foreach (XmlNode node in nodes) { string strName = DomUtil.GetAttr(node, "name"); string strType = DomUtil.GetAttr(node, "type"); // string strRole = DomUtil.GetAttr(node, "role"); // string strLibraryCode = DomUtil.GetAttr(node, "libraryCode"); BiblioDbProperty property = new BiblioDbProperty(); this.BiblioDbProperties.Add(property); property.DbName = DomUtil.GetAttr(node, "name"); property.ItemDbName = DomUtil.GetAttr(node, "entityDbName"); property.Syntax = DomUtil.GetAttr(node, "syntax"); property.IssueDbName = DomUtil.GetAttr(node, "issueDbName"); property.OrderDbName = DomUtil.GetAttr(node, "orderDbName"); property.CommentDbName = DomUtil.GetAttr(node, "commentDbName"); property.Role = DomUtil.GetAttr(node, "role"); bool bValue = true; nRet = DomUtil.GetBooleanParam(node, "inCirculation", true, out bValue, out strError); property.InCirculation = bValue; } // MessageBox.Show(this, Convert.ToString(lRet) + " : " + strError); } finally { Stop.EndLoop(); Stop.OnStop -= new StopEventHandler(this.DoStop); Stop.Initial(""); if (bPrepareSearch == true) EndSearch(); } return 0; #if NO ERROR1: DialogResult result = MessageBox.Show(this, strError + "\r\n\r\n是否重试?", "dp2Circulation", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == System.Windows.Forms.DialogResult.Yes) goto REDO; if (result == DialogResult.No) return 1; // 出错,但希望继续后面的操作 return -1; // 出错,不希望继续以后的操作 #endif }