public void ReturnChannel( RmsChannelCollection channels, RmsChannel channel) { // channels.ReturnChannel(channel); this.Remove(channel); }
public void Initial(ServerCollection servers, RmsChannelCollection channels, DigitalPlatform.StopManager stopManager, string serverUrl, string strDatabaseObject) { this.Servers = servers; this.Channels = channels; this.stopManager = stopManager; this.ServerUrl = serverUrl; this.textBox_databaseObject.Text = strDatabaseObject; }
public void Initial(ServerCollection servers, RmsChannelCollection channels, DigitalPlatform.StopManager stopManager, string serverUrl, string strCfgFilePath) { this.Servers = servers; this.Channels = channels; this.stopManager = stopManager; this.ServerUrl = serverUrl; this.Path = strCfgFilePath; // this.textBox_path.Text = this.ServerUrl + "?" + this.Path; }
// 询问无法匹配的源路径如何处理 // return: // -1 出错 // 0 cancel全部处理 // 1 已经选择处理办法 public static int AskNotMatchOriginBox( IWin32Window owner, ApplicationInfo ap, ServerCollection Servers, RmsChannelCollection Channels, string strComment, string strSelectedLongPath, string strOrigin, DbNameMap map) { DbNameMapItemDlg dlg = new DbNameMapItemDlg(); dlg.Font = GuiUtil.GetDefaultFont(); dlg.Servers = Servers; dlg.Channels = Channels; dlg.Comment = strComment; dlg.AskMode = AskMode.AskNotMatchOrigin; dlg.Origin = strOrigin; dlg.Target = strSelectedLongPath; dlg.WriteMode = "append"; dlg.Text = "请指定映射关系"; if (ap != null) { ap.LinkFormState(dlg, "AskNotMatchOriginBox_state"); } dlg.ShowDialog(owner); if (ap != null) { ap.UnlinkFormState(dlg); } if (dlg.DialogResult != DialogResult.OK) { return(0); // cancel } string strError = ""; if (map.NewItem(dlg.Origin, dlg.Target, dlg.WriteMode, 0, // 插入最前面 out strError) == null) { MessageBox.Show(owner, strError); return(-1); } return(1); }
// parameters: // style 风格。如果为 GUI,表示会自动添加 Idle 事件,并在其中执行 Application.DoEvents public RmsChannel GetChannel( RmsChannelCollection channels, string strServerUrl) { if (_disabled) { return(null); } RmsChannel channel = channels.GetChannel(strServerUrl); this.Add(channel); // TODO: 检查数组是否溢出 return(channel); }
public RecordLoader( RmsChannelCollection channels, DigitalPlatform.Stop stop, List <string> paths, string resultsetName, string formatList, string lang = "zh") { this.Channels = channels; this.Stop = stop; this.ResultSetName = resultsetName; this.FormatList = formatList; this.Lang = lang; this.Paths = paths; }
public int Initial(ServerCollection servers, RmsChannelCollection channels, DigitalPlatform.StopManager stopManager, string serverUrl, out string strError) { this.Servers = servers; this.Channels = channels; this.stopManager = stopManager; this.ServerUrl = serverUrl; strError = ""; int nRet = Fill(this.Lang, out strError); if (nRet == -1) { return(-1); } return(0); }
// 初始化 // parameters: // userRightsDom 用户记录的dom对象。将直接引用这个对象 public void Initial(ServerCollection servers, RmsChannelCollection channels, DigitalPlatform.StopManager stopManager, string serverUrl, XmlDocument UserRightsDom) { this.Servers = servers; this.Channels = channels; this.stopManager = stopManager; this.ServerUrl = serverUrl; this.UserRightsDom = UserRightsDom; // 直接引用外界的dom对象 // 用服务器端获得的信息填充树 Cursor save = this.Cursor; this.Cursor = Cursors.WaitCursor; FillAll(null); InitialRightsParam(); this.Cursor = save; this.m_bChanged = false; }
/* foregift 创建押金记录 API: Foregift() <root> <operation>foregift</operation> 操作类型 <action>...</action> 具体动作 目前有foregift return (注: return操作时,overdue元素里面的price属性,可以使用宏 %return_foregift_price% 表示当前剩余的押金额) <readerBarcode>R0000002</readerBarcode> 读者证条码号 <operator>test</operator> 操作者 <operTime>Fri, 08 Dec 2006 04:17:45 GMT</operTime> 操作时间 <overdues>...</overdues> 押金信息 通常内容为一个字符串,为一个或多个<overdue>元素XML文本片断 <readerRecord recPath='...'>...</readerRecord> 最新读者记录 </root> * * */ public int RecoverForegift( RmsChannelCollection Channels, RecoverLevel level, XmlDocument domLog, out string strError) { strError = ""; // 暂时把Robust当作Logic处理 if (level == RecoverLevel.Robust) level = RecoverLevel.Logic; long lRet = 0; int nRet = 0; RmsChannel channel = Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } DO_SNAPSHOT: // 快照恢复 if (level == RecoverLevel.Snapshot) { XmlNode node = null; string strReaderXml = DomUtil.GetElementText(domLog.DocumentElement, "readerRecord", out node); if (node == null) { strError = "日志记录中缺<readerRecord>元素"; return -1; } string strReaderRecPath = DomUtil.GetAttr(node, "recPath"); byte[] timestamp = null; byte[] output_timestamp = null; string strOutputPath = ""; // 写读者记录 lRet = channel.DoSaveTextRes(strReaderRecPath, strReaderXml, false, "content,ignorechecktimestamp", timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "写入读者记录 '" + strReaderRecPath + "' 时发生错误: " + strError; return -1; } return 0; } // 逻辑恢复或者混合恢复 if (level == RecoverLevel.Logic || level == RecoverLevel.LogicAndSnapshot) { // string strRecoverComment = ""; string strAction = DomUtil.GetElementText(domLog.DocumentElement, "action"); string strReaderBarcode = DomUtil.GetElementText(domLog.DocumentElement, "readerBarcode"); /// if (String.IsNullOrEmpty(strReaderBarcode) == true) { strError = "日志记录中<readerBarcode>元素值为空"; goto ERROR1; } string strOperator = DomUtil.GetElementText(domLog.DocumentElement, "operator"); string strOperTime = DomUtil.GetElementText(domLog.DocumentElement, "operTime"); string strOverdues = DomUtil.GetElementText(domLog.DocumentElement, "overdues"); if (String.IsNullOrEmpty(strOverdues) == true) { strError = "日志记录中<overdues>元素值为空"; goto ERROR1; } // 从overdues字符串中分析出id XmlDocument tempdom = new XmlDocument(); tempdom.LoadXml("<root />"); XmlDocumentFragment fragment = tempdom.CreateDocumentFragment(); fragment.InnerXml = strOverdues; tempdom.DocumentElement.AppendChild(fragment); XmlNode tempnode = tempdom.DocumentElement.SelectSingleNode("overdue"); if (tempnode == null) { strError = "<overdues>元素内容有误,缺乏<overdue>元素"; goto ERROR1; } string strID = DomUtil.GetAttr(tempnode, "id"); if (String.IsNullOrEmpty(strID) == true) { strError = "日志记录中<overdues>内容中<overdue>元素中id属性值为空"; goto ERROR1; } // 读入读者记录 string strReaderXml = ""; string strOutputReaderRecPath = ""; byte[] reader_timestamp = null; nRet = this.GetReaderRecXml( // Channels, channel, strReaderBarcode, out strReaderXml, out strOutputReaderRecPath, out reader_timestamp, out strError); if (nRet == 0) { strError = "读者证条码号 '" + strReaderBarcode + "' 不存在"; goto ERROR1; } if (nRet == -1) { strError = "读入证条码号为 '" + strReaderBarcode + "' 的读者记录时发生错误: " + strError; goto ERROR1; } XmlDocument readerdom = null; nRet = LibraryApplication.LoadToDom(strReaderXml, out readerdom, out strError); if (nRet == -1) { strError = "装载读者记录进入XML DOM时发生错误: " + strError; goto ERROR1; } // string strOverdueString = ""; // 根据Foregift() API要求,修改readerdom nRet = DoForegift(strAction, readerdom, ref strID, strOperator, strOperTime, out strOverdueString, out strError); if (nRet == -1) goto ERROR1; // 写回读者、册记录 byte[] output_timestamp = null; string strOutputPath = ""; // 写回读者记录 lRet = channel.DoSaveTextRes(strOutputReaderRecPath, readerdom.OuterXml, false, "content,ignorechecktimestamp", reader_timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; } return 0; ERROR1: if (level == RecoverLevel.LogicAndSnapshot) { level = RecoverLevel.Snapshot; goto DO_SNAPSHOT; } return -1; }
// 通过特定检索途径获得读者记录的特定keys值 // return: // -1 error // >=0 命中个数 public int SearchAllIds( RmsChannelCollection channels, string strPatronDbName, string strFrom, out List<string> ids, out string strError) { strError = ""; ids = new List<string>(); Debug.Assert(String.IsNullOrEmpty(strPatronDbName) == false, ""); // 构造检索式 string strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strPatronDbName + ":" + strFrom) + "'><item><word></word><match>left</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang></target>"; RmsChannel channel = channels.GetChannel(this.App.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } string strOutputStyle = "keyid"; string strBrowseStyle = "keyid,key,id,cols"; long lRet = channel.DoSearch(strQueryXml, "default", strOutputStyle, out strError); if (lRet == -1) goto ERROR1; // not found if (lRet == 0) return 0; long lHitCount = lRet; long lStart = 0; for (; ; ) { #if NO // 2012/2/4 // 系统挂起的时候,不运行本线程 if (this.App.HangupReason == HangupReason.LogRecover) { strError = "因为系统挂起或暂停批处理而中断处理"; return -1; } #endif if (this.Stopped == true) { strError = "中断处理"; return -1; } Record[] records = null; lRet = channel.DoGetSearchResult( "default", lStart, -1, strBrowseStyle, "zh", null, out records, out strError); if (lRet == -1) goto ERROR1; foreach (Record record in records) { Debug.Assert(record.Keys != null && record.Keys.Length > 0, ""); if (record.Keys != null && record.Keys.Length > 0) ids.Add(record.Keys[0].Key); } lStart += records.Length; if (lStart >= lHitCount) break; } return (int)lHitCount; ERROR1: return -1; }
// 初始化所有数据库 public int ClearAllDbs( RmsChannelCollection Channels, out string strError) { strError = ""; string strTempError = ""; RmsChannel channel = Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "GetChannel error"; return -1; } long lRet = 0; // 大书目库 for (int i = 0; i < this.ItemDbs.Count; i++) { ItemDbCfg cfg = this.ItemDbs[i]; // 实体库 string strEntityDbName = cfg.DbName; if (String.IsNullOrEmpty(strEntityDbName) == false) { lRet = channel.DoInitialDB(strEntityDbName, out strTempError); if (lRet == -1) { strError += "清除实体库 '" + strEntityDbName + "' 内数据时候发生错误:" + strTempError + "; "; } } // 订购库 string strOrderDbName = cfg.OrderDbName; if (String.IsNullOrEmpty(strOrderDbName) == false) { lRet = channel.DoInitialDB(strOrderDbName, out strTempError); if (lRet == -1) { strError += "清除订购库 '" + strOrderDbName + "' 内数据时候发生错误:" + strTempError + "; "; } } // 期库 string strIssueDbName = cfg.IssueDbName; if (String.IsNullOrEmpty(strIssueDbName) == false) { lRet = channel.DoInitialDB(strIssueDbName, out strTempError); if (lRet == -1) { strError += "清除期库 '" + strIssueDbName + "' 内数据时候发生错误:" + strTempError + "; "; } } // 小书目库 string strBiblioDbName = cfg.BiblioDbName; if (String.IsNullOrEmpty(strBiblioDbName) == false) { lRet = channel.DoInitialDB(strBiblioDbName, out strTempError); if (lRet == -1) { strError += "清除小书目库 '" + strBiblioDbName + "' 内数据时候发生错误:" + strTempError + "; "; } } } // 读者库 for (int i = 0; i < this.ReaderDbs.Count; i++) { string strDbName = this.ReaderDbs[i].DbName; if (String.IsNullOrEmpty(strDbName) == false) { lRet = channel.DoInitialDB(strDbName, out strTempError); if (lRet == -1) { strError += "清除读者库 '" + strDbName + "' 内数据时候发生错误:" + strTempError + "; "; } } } // 预约到书队列库 if (String.IsNullOrEmpty(this.ArrivedDbName) == false) { string strDbName = this.ArrivedDbName; lRet = channel.DoInitialDB(strDbName, out strTempError); if (lRet == -1) { strError += "清除预约到书库 '" + strDbName + "' 内数据时候发生错误:" + strTempError + "; "; } } // 违约金库 if (String.IsNullOrEmpty(this.AmerceDbName) == false) { string strDbName = this.AmerceDbName; lRet = channel.DoInitialDB(strDbName, out strTempError); if (lRet == -1) { strError += "清除违约金库 '" + strDbName + "' 内数据时候发生错误:" + strTempError + "; "; } } // 发票库 if (String.IsNullOrEmpty(this.InvoiceDbName) == false) { string strDbName = this.InvoiceDbName; lRet = channel.DoInitialDB(strDbName, out strTempError); if (lRet == -1) { strError += "清除发票库 '" + strDbName + "' 内数据时候发生错误:" + strTempError + "; "; } } // 消息库 if (String.IsNullOrEmpty(this.MessageDbName) == false) { string strDbName = this.MessageDbName; lRet = channel.DoInitialDB(strDbName, out strTempError); if (lRet == -1) { strError += "清除消息库 '" + strDbName + "' 内数据时候发生错误:" + strTempError + "; "; } } // 实用库 XmlNodeList nodes = this.LibraryCfgDom.DocumentElement.SelectNodes("utilDb/database"); for (int i = 0; i < nodes.Count; i++) { XmlNode node = nodes[i]; string strDbName = DomUtil.GetAttr(node, "name"); string strType = DomUtil.GetAttr(node, "type"); if (String.IsNullOrEmpty(strDbName) == false) { lRet = channel.DoInitialDB(strDbName, out strTempError); if (lRet == -1) { strError += "清除类型为 "+strType+" 的实用库 '" + strDbName + "' 内数据时候发生错误:" + strTempError + "; "; } } } if (String.IsNullOrEmpty(strError) == false) return -1; return 0; }
// 创建数据库 // parameters: // strLibraryCodeList 当前用户的管辖分馆代码列表 // bRecreate 是否为重新创建?如果为重新创建,则允许已经存在定义;如果不是重新创建,即首次创建,则不允许已经存在定义 // 注: 重新创建的意思, 是 library.xml 中有定义,但 dp2kernel 中没有对应的数据库,要根据定义重新创建这些 dp2kernel 数据库 int CreateDatabase( RmsChannelCollection Channels, string strLibraryCodeList, string strDatabaseInfo, bool bRecreate, out string strOutputInfo, out string strError) { strOutputInfo = ""; strError = ""; int nRet = 0; List<string> created_dbnames = new List<string>(); // 过程中,已经创建的数据库名 bool bDbChanged = false; // 数据库名是否发生过改变?或者新创建过数据库? 如果发生过,需要重新初始化kdbs XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strDatabaseInfo); } catch (Exception ex) { strError = "strDatabaseInfo内容装入XMLDOM时出错: " + ex.Message; return -1; } RmsChannel channel = Channels.GetChannel(this.WsUrl); XmlNodeList nodes = dom.DocumentElement.SelectNodes("database"); for (int i = 0; i < nodes.Count; i++) { XmlNode node = nodes[i]; string strType = DomUtil.GetAttr(node, "type").ToLower(); string strName = DomUtil.GetAttr(node, "name"); // 创建书目数据库 if (strType == "biblio") { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许创建或重新创建书目库"; return -1; } if (this.TestMode == true) { XmlNodeList existing_nodes = this.LibraryCfgDom.DocumentElement.SelectNodes("itemdbgroup/database"); if (existing_nodes.Count >= 4) { strError = "dp2Library XE 评估模式下只能创建最多 4 个书目库"; goto ERROR1; } } // 2009/11/13 XmlNode exist_database_node = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@biblioDbName='"+strName+"']"); if (bRecreate == true && exist_database_node == null) { strError = "library.xml中并不存在书目库 '"+strName+"' 的定义,无法进行重新创建"; goto ERROR1; } string strSyntax = DomUtil.GetAttr(node, "syntax"); if (String.IsNullOrEmpty(strSyntax) == true) strSyntax = "unimarc"; // usage: book series string strUsage = DomUtil.GetAttr(node, "usage"); if (String.IsNullOrEmpty(strUsage) == true) strUsage = "book"; // 2009/10/23 string strRole = DomUtil.GetAttr(node, "role"); if (bRecreate == false) { // 检查cfgdom中是否已经存在同名的书目库 if (this.IsBiblioDbName(strName) == true) { strError = "书目库 '" + strName + "' 的定义已经存在,不能重复创建"; goto ERROR1; } } // 检查dp2kernel中是否有和书目库同名的数据库存在 { // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = IsDatabaseExist( channel, strName, out strError); if (nRet == -1) goto ERROR1; if (nRet >= 1) goto ERROR1; } string strEntityDbName = DomUtil.GetAttr(node, "entityDbName"); string strOrderDbName = DomUtil.GetAttr(node, "orderDbName"); string strIssueDbName = DomUtil.GetAttr(node, "issueDbName"); string strCommentDbName = DomUtil.GetAttr(node, "commentDbName"); if (strEntityDbName == "<default>") strEntityDbName = strName + "实体"; if (strOrderDbName == "<default>") strOrderDbName = strName + "订购"; if (strIssueDbName == "<default>") strIssueDbName = strName + "期"; if (strCommentDbName == "<default>") strCommentDbName = strName + "评注"; string strInCirculation = DomUtil.GetAttr(node, "inCirculation"); if (String.IsNullOrEmpty(strInCirculation) == true) strInCirculation = "true"; // 缺省为true string strUnionCatalogStyle = DomUtil.GetAttr(node, "unionCatalogStyle"); string strReplication = DomUtil.GetAttr(node, "replication"); if (String.IsNullOrEmpty(strEntityDbName) == false) { if (bRecreate == false) { // 检查cfgdom中是否已经存在同名的实体库 if (this.IsItemDbName(strEntityDbName) == true) { strError = "实体库 '" + strEntityDbName + "' 的定义已经存在,不能重复创建"; goto ERROR1; } } // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = IsDatabaseExist( channel, strEntityDbName, out strError); if (nRet == -1) goto ERROR1; if (nRet >= 1) goto ERROR1; } if (String.IsNullOrEmpty(strOrderDbName) == false) { if (bRecreate == false) { // 检查cfgdom中是否已经存在同名的订购库 if (this.IsOrderDbName(strOrderDbName) == true) { strError = "订购库 '" + strOrderDbName + "' 的定义已经存在,不能重复创建"; goto ERROR1; } } // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = IsDatabaseExist( channel, strOrderDbName, out strError); if (nRet == -1) goto ERROR1; if (nRet >= 1) goto ERROR1; } if (String.IsNullOrEmpty(strIssueDbName) == false) { if (bRecreate == false) { // 检查cfgdom中是否已经存在同名的期库 if (this.IsOrderDbName(strIssueDbName) == true) { strError = "期库 '" + strIssueDbName + "' 的定义已经存在,不能重复创建"; goto ERROR1; } } // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = IsDatabaseExist( channel, strIssueDbName, out strError); if (nRet == -1) goto ERROR1; if (nRet >= 1) goto ERROR1; } if (String.IsNullOrEmpty(strCommentDbName) == false) { if (bRecreate == false) { // 检查cfgdom中是否已经存在同名的评注库 if (this.IsCommentDbName(strCommentDbName) == true) { strError = "评注库 '" + strCommentDbName + "' 的定义已经存在,不能重复创建"; goto ERROR1; } } // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = IsDatabaseExist( channel, strCommentDbName, out strError); if (nRet == -1) goto ERROR1; if (nRet >= 1) goto ERROR1; } // 开始创建 // 创建书目库 string strTemplateDir = this.DataDir + "\\templates\\" + "biblio_" + strSyntax + "_" + strUsage; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strName); bDbChanged = true; // 创建实体库 if (String.IsNullOrEmpty(strEntityDbName) == false) { strTemplateDir = this.DataDir + "\\templates\\" + "item"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strEntityDbName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strEntityDbName); bDbChanged = true; } // 创建订购库 if (String.IsNullOrEmpty(strOrderDbName) == false) { strTemplateDir = this.DataDir + "\\templates\\" + "order"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strOrderDbName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strOrderDbName); bDbChanged = true; } // 创建期库 if (String.IsNullOrEmpty(strIssueDbName) == false) { strTemplateDir = this.DataDir + "\\templates\\" + "issue"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strIssueDbName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strIssueDbName); bDbChanged = true; } // 创建评注库 if (String.IsNullOrEmpty(strCommentDbName) == false) { strTemplateDir = this.DataDir + "\\templates\\" + "comment"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strCommentDbName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strCommentDbName); bDbChanged = true; } // 在CfgDom中增加相关的配置信息 XmlNode root = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup"); if (root == null) { root = this.LibraryCfgDom.CreateElement("itemdbgroup"); this.LibraryCfgDom.DocumentElement.AppendChild(root); } XmlNode nodeNewDatabase = null; if (bRecreate == false) { nodeNewDatabase = this.LibraryCfgDom.CreateElement("database"); root.AppendChild(nodeNewDatabase); } else { nodeNewDatabase = exist_database_node; } DomUtil.SetAttr(nodeNewDatabase, "name", strEntityDbName); DomUtil.SetAttr(nodeNewDatabase, "biblioDbName", strName); if (String.IsNullOrEmpty(strOrderDbName) == false) { DomUtil.SetAttr(nodeNewDatabase, "orderDbName", strOrderDbName); } if (String.IsNullOrEmpty(strIssueDbName) == false) { DomUtil.SetAttr(nodeNewDatabase, "issueDbName", strIssueDbName); } if (String.IsNullOrEmpty(strCommentDbName) == false) { DomUtil.SetAttr(nodeNewDatabase, "commentDbName", strCommentDbName); } DomUtil.SetAttr(nodeNewDatabase, "syntax", strSyntax); // 2009/10/23 DomUtil.SetAttr(nodeNewDatabase, "role", strRole); DomUtil.SetAttr(nodeNewDatabase, "inCirculation", strInCirculation); // 2012/4/30 if (string.IsNullOrEmpty(strUnionCatalogStyle) == false) DomUtil.SetAttr(nodeNewDatabase, "unionCatalogStyle", strUnionCatalogStyle); if (string.IsNullOrEmpty(strReplication) == false) DomUtil.SetAttr(nodeNewDatabase, "replication", strReplication); // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); goto ERROR1; } this.Changed = true; this.ActivateManagerThread(); created_dbnames.Clear(); continue; } // end of type biblio else if (strType == "entity") { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许创建或重新创建实体库"; return -1; } // TODO: 增加recreate能力 // 单独创建实体库 string strBiblioDbName = DomUtil.GetAttr(node, "biblioDbName"); if (String.IsNullOrEmpty(strBiblioDbName) == true) { strError = "请求创建实体库的<database>元素中,应包含biblioDbName属性"; goto ERROR1; } // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@biblioDbName='" + strBiblioDbName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strBiblioDbName + "' 的书目库(biblioDbName属性)相关<database>元素没有找到,无法在其下创建实体库 " + strName; goto ERROR1; } string strOldEntityDbName = DomUtil.GetAttr(nodeDatabase, "name"); if (strOldEntityDbName == strName) { strError = "从属于书目库 '" + strBiblioDbName + "' 的实体库 '" + strName + "' 定义已经存在,不能重复创建"; goto ERROR1; } if (String.IsNullOrEmpty(strOldEntityDbName) == false) { strError = "要创建从属于书目库 '" + strBiblioDbName + "' 的新实体库 '" + strName + "',必须先删除已经存在的实体库 '" + strOldEntityDbName + "'"; goto ERROR1; } string strTemplateDir = this.DataDir + "\\templates\\" + "item"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strName); bDbChanged = true; DomUtil.SetAttr(nodeDatabase, "name", strName); // 2008/12/4 // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); goto ERROR1; } this.Changed = true; } else if (strType == "order") { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许创建或重新创建订购库"; return -1; } // TODO: 增加recreate能力 // 单独创建订购库 string strBiblioDbName = DomUtil.GetAttr(node, "biblioDbName"); if (String.IsNullOrEmpty(strBiblioDbName) == true) { strError = "创建订购库的<database>元素中,应包含biblioDbName属性"; goto ERROR1; } // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@biblioDbName='" + strBiblioDbName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strBiblioDbName + "' 的书目库(biblioDbName属性)相关<database>元素没有找到,无法在其下创建订购库 " + strName; goto ERROR1; } string strOldOrderDbName = DomUtil.GetAttr(nodeDatabase, "orderDbName"); if (strOldOrderDbName == strName) { strError = "从属于书目库 '" + strBiblioDbName + "' 的订购库 '" + strName + "' 定义已经存在,不能重复创建"; goto ERROR1; } if (String.IsNullOrEmpty(strOldOrderDbName) == false) { strError = "要创建从属于书目库 '" + strBiblioDbName + "' 的新订购库 '" + strName + "',必须先删除已经存在的订购库 '" + strOldOrderDbName + "'"; goto ERROR1; } string strTemplateDir = this.DataDir + "\\templates\\" + "order"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strName); bDbChanged = true; DomUtil.SetAttr(nodeDatabase, "orderDbName", strName); // 2008/12/4 // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); goto ERROR1; } this.Changed = true; } else if (strType == "issue") { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许创建或重新创建期库"; return -1; } // TODO: 增加recreate能力 // 单独创建期库 string strBiblioDbName = DomUtil.GetAttr(node, "biblioDbName"); if (String.IsNullOrEmpty(strBiblioDbName) == true) { strError = "创建期库的<database>元素中,应包含biblioDbName属性"; goto ERROR1; } // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@biblioDbName='" + strBiblioDbName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strBiblioDbName + "' 的书目库(biblioDbName属性)相关<database>元素没有找到,无法在其下创建期库 " + strName; goto ERROR1; } string strOldIssueDbName = DomUtil.GetAttr(nodeDatabase, "issueDbName"); if (strOldIssueDbName == strName) { strError = "从属于书目库 '"+strBiblioDbName+"' 的期库 '" + strName + "' 定义已经存在,不能重复创建"; goto ERROR1; } if (String.IsNullOrEmpty(strOldIssueDbName) == false) { strError = "要创建从属于书目库 '" + strBiblioDbName + "' 的新期库 '" + strName + "',必须先删除已经存在的期库 '" +strOldIssueDbName+"'"; goto ERROR1; } string strTemplateDir = this.DataDir + "\\templates\\" + "issue"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strName); bDbChanged = true; DomUtil.SetAttr(nodeDatabase, "issueDbName", strName); // 2008/12/4 // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); goto ERROR1; } this.Changed = true; } else if (strType == "comment") { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许创建或重新创建评注库"; return -1; } // TODO: 增加recreate能力 // 单独创建评注库 string strBiblioDbName = DomUtil.GetAttr(node, "biblioDbName"); if (String.IsNullOrEmpty(strBiblioDbName) == true) { strError = "创建评注库的<database>元素中,应包含biblioDbName属性"; goto ERROR1; } // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@biblioDbName='" + strBiblioDbName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strBiblioDbName + "' 的书目库(biblioDbName属性)相关<database>元素没有找到,无法在其下创建评注库 " + strName; goto ERROR1; } string strOldCommentDbName = DomUtil.GetAttr(nodeDatabase, "commentDbName"); if (strOldCommentDbName == strName) { strError = "从属于书目库 '" + strBiblioDbName + "' 的评注库 '" + strName + "' 定义已经存在,不能重复创建"; goto ERROR1; } if (String.IsNullOrEmpty(strOldCommentDbName) == false) { strError = "要创建从属于书目库 '" + strBiblioDbName + "' 的新评注库 '" + strName + "',必须先删除已经存在的评注库 '" + strOldCommentDbName + "'"; goto ERROR1; } string strTemplateDir = this.DataDir + "\\templates\\" + "comment"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strName); bDbChanged = true; DomUtil.SetAttr(nodeDatabase, "commentDbName", strName); // 2008/12/4 // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); goto ERROR1; } this.Changed = true; } else if (strType == "reader") { // 创建读者库 // 2009/11/13 XmlNode exist_database_node = this.LibraryCfgDom.DocumentElement.SelectSingleNode("readerdbgroup/database[@name='" + strName + "']"); if (bRecreate == true && exist_database_node == null) { strError = "library.xml中并不存在读者库 '" + strName + "' 的定义,无法进行重新创建"; goto ERROR1; } if (bRecreate == false) { // 检查cfgdom中是否已经存在同名的读者库 if (this.IsReaderDbName(strName) == true) { strError = "读者库 '" + strName + "' 的定义已经存在,不能重复创建"; goto ERROR1; } } else { if (exist_database_node != null) { string strExistLibraryCode = DomUtil.GetAttr(exist_database_node, "libraryCode"); // 2012/9/9 // 分馆用户只允许修改馆代码属于管辖分馆的读者库 if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { if (string.IsNullOrEmpty(strExistLibraryCode) == true || StringUtil.IsInList(strExistLibraryCode, strLibraryCodeList) == false) { strError = "重新创建读者库 '"+strName+"' 被拒绝。当前用户只能重新创建图书馆代码完全完全属于 '" + strLibraryCodeList + "' 范围的读者库"; goto ERROR1; } } } } string strLibraryCode = DomUtil.GetAttr(node, "libraryCode"); // 2012/9/9 // 分馆用户只允许处理馆代码为特定范围的读者库 if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { if (string.IsNullOrEmpty(strLibraryCode) == true || IsListInList(strLibraryCode, strLibraryCodeList) == false) { strError = "当前用户只能创建馆代码完全属于 '" + strLibraryCodeList + "' 范围内的读者库"; return -1; } } // 检查dp2kernel中是否有和读者库同名的数据库存在 { // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = IsDatabaseExist( channel, strName, out strError); if (nRet == -1) goto ERROR1; if (nRet >= 1) goto ERROR1; } string strTemplateDir = this.DataDir + "\\templates\\" + "reader"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strName); bDbChanged = true; string strInCirculation = DomUtil.GetAttr(node, "inCirculation"); if (String.IsNullOrEmpty(strInCirculation) == true) strInCirculation = "true"; // 缺省为true // 检查一个单独的图书馆代码是否格式正确 // 要求不能为 '*',不能包含逗号 // return: // -1 校验函数本身出错了 // 0 校验正确 // 1 校验发现问题。strError中有描述 nRet = VerifySingleLibraryCode(strLibraryCode, out strError); if (nRet != 0) { strError = "图书馆代码 '" + strLibraryCode + "' 格式错误: " + strError; goto ERROR1; } // 在CfgDom中增加相关的配置信息 XmlNode root = this.LibraryCfgDom.DocumentElement.SelectSingleNode("readerdbgroup"); if (root == null) { root = this.LibraryCfgDom.CreateElement("readerdbgroup"); this.LibraryCfgDom.DocumentElement.AppendChild(root); } XmlNode nodeNewDatabase = null; if (bRecreate == false) { nodeNewDatabase = this.LibraryCfgDom.CreateElement("database"); root.AppendChild(nodeNewDatabase); } else { nodeNewDatabase = exist_database_node; } DomUtil.SetAttr(nodeNewDatabase, "name", strName); DomUtil.SetAttr(nodeNewDatabase, "inCirculation", strInCirculation); DomUtil.SetAttr(nodeNewDatabase, "libraryCode", strLibraryCode); // 2012/9/7 // <readerdbgroup>内容更新,刷新配套的内存结构 this.LoadReaderDbGroupParam(this.LibraryCfgDom); this.Changed = true; } else if (strType == "publisher" || strType == "zhongcihao" || strType == "dictionary" || strType == "inventory") { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许创建或重新创建出版者库、种次号库、字典库和盘点库"; return -1; } // 看看同名的 publisher/zhongcihao/dictionary/inventory 数据库是否已经存在? XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("utilDb/database[@name='" + strName + "']"); if (bRecreate == false) { if (nodeDatabase != null) { strError = strType + "库 '" + strName + "' 的定义已经存在,不能重复创建"; goto ERROR1; } } else { if (nodeDatabase == null) { strError = strType + "库 '" + strName + "' 的定义并不存在,无法进行重复创建"; goto ERROR1; } } // TODO: 是否限定publisher库只能创建一个? // 而zhongcihao库显然是可以创建多个的 // 检查dp2kernel中是否有和 publisher/zhongcihao/dictionary/inventory 库同名的数据库存在 { // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = IsDatabaseExist( channel, strName, out strError); if (nRet == -1) goto ERROR1; if (nRet >= 1) goto ERROR1; } string strTemplateDir = this.DataDir + "\\templates\\" + strType; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strName); bDbChanged = true; // 2012/12/12 // 在CfgDom中增加相关的配置信息 XmlNode root = this.LibraryCfgDom.DocumentElement.SelectSingleNode("utilDb"); if (root == null) { root = this.LibraryCfgDom.CreateElement("utilDb"); this.LibraryCfgDom.DocumentElement.AppendChild(root); } XmlNode nodeNewDatabase = null; if (bRecreate == false) { nodeNewDatabase = this.LibraryCfgDom.CreateElement("database"); root.AppendChild(nodeNewDatabase); } else { nodeNewDatabase = nodeDatabase; } DomUtil.SetAttr(nodeNewDatabase, "name", strName); DomUtil.SetAttr(nodeNewDatabase, "type", strType); this.Changed = true; } else if (strType == "arrived") { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许创建或重新创建预约到书库"; return -1; } // 看看同名的 arrived 数据库是否已经存在? if (bRecreate == false) { if (this.ArrivedDbName == strName) { strError = "预约到书库 '" + strName + "' 的定义已经存在,不能重复创建"; goto ERROR1; } } if (String.IsNullOrEmpty(this.ArrivedDbName) == false) { if (bRecreate == true) { if (this.ArrivedDbName != strName) { strError = "已经存在一个预约到书库 '" + this.ArrivedDbName + "' 定义,和您请求重新创建的预约到书库 '" + strName + "' 名字不同。无法直接进行重新创建。请先删除已存在的数据库再进行创建"; goto ERROR1; } } else { strError = "要创建新的预约到书库 '" + strName + "',必须先删除已经存在的预约到书库 '" + this.ArrivedDbName + "'"; goto ERROR1; } } // 检查dp2kernel中是否有和arrived库同名的数据库存在 { // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = IsDatabaseExist( channel, strName, out strError); if (nRet == -1) goto ERROR1; if (nRet >= 1) goto ERROR1; } string strTemplateDir = this.DataDir + "\\templates\\" + "arrived"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strName); bDbChanged = true; // 2012/12/12 // 在CfgDom中增加相关的配置信息 this.ArrivedDbName = strName; this.Changed = true; } else if (strType == "amerce") { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许创建或重新创建违约金库"; return -1; } // 看看同名的amerce数据库是否已经存在? if (bRecreate == false) { if (this.AmerceDbName == strName) { strError = "违约金库 '" + strName + "' 的定义已经存在,不能重复创建"; goto ERROR1; } } if (String.IsNullOrEmpty(this.AmerceDbName) == false) { if (bRecreate == true) { if (this.AmerceDbName != strName) { strError = "已经存在一个违约金库 '" + this.AmerceDbName + "' 定义,和您请求重新创建的违约金库 '" + strName + "' 名字不同。无法直接进行重新创建。请先删除已存在的数据库再进行创建"; goto ERROR1; } } else { strError = "要创建新的违约金库 '" + strName + "',必须先删除已经存在的违约金库 '" + this.AmerceDbName + "'"; goto ERROR1; } } // 检查dp2kernel中是否有和amerce库同名的数据库存在 { // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = IsDatabaseExist( channel, strName, out strError); if (nRet == -1) goto ERROR1; if (nRet >= 1) goto ERROR1; } string strTemplateDir = this.DataDir + "\\templates\\" + "amerce"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strName); bDbChanged = true; // 2012/12/12 // 在CfgDom中增加相关的配置信息 this.AmerceDbName = strName; this.Changed = true; } else if (strType == "message") { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许创建或重新创建消息库"; return -1; } // 看看同名的message数据库是否已经存在? if (bRecreate == false) { if (this.MessageDbName == strName) { strError = "消息库 '" + strName + "' 的定义已经存在,不能重复创建"; goto ERROR1; } } if (String.IsNullOrEmpty(this.MessageDbName) == false) { if (bRecreate == true) { if (this.MessageDbName != strName) { strError = "已经存在一个消息库 '" + this.MessageDbName + "' 定义,和您请求重新创建的消息库 '" + strName + "' 名字不同。无法直接进行重新创建。请先删除已存在的数据库再进行创建"; goto ERROR1; } } else { strError = "要创建新的消息库 '" + strName + "',必须先删除已经存在的消息库 '" + this.MessageDbName + "'"; goto ERROR1; } } // 检查dp2kernel中是否有和message库同名的数据库存在 { // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = IsDatabaseExist( channel, strName, out strError); if (nRet == -1) goto ERROR1; if (nRet >= 1) goto ERROR1; } string strTemplateDir = this.DataDir + "\\templates\\" + "message"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strName); bDbChanged = true; // 2012/12/12 // 在CfgDom中增加相关的配置信息 this.MessageDbName = strName; this.Changed = true; } else if (strType == "invoice") { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许创建或重新创建发票库"; return -1; } // 看看同名的invoice数据库是否已经存在? if (bRecreate == false) { if (this.InvoiceDbName == strName) { strError = "发票库 '" + strName + "' 的定义已经存在,不能重复创建"; goto ERROR1; } } if (String.IsNullOrEmpty(this.InvoiceDbName) == false) { if (bRecreate == true) { if (this.InvoiceDbName != strName) { strError = "已经存在一个发票库 '" + this.InvoiceDbName + "' 定义,和您请求重新创建的发票库 '" + strName + "' 名字不同。无法直接进行重新创建。请先删除已存在的数据库再进行创建"; goto ERROR1; } } else { strError = "要创建新的发票库 '" + strName + "',必须先删除已经存在的发票库 '" + this.InvoiceDbName + "'"; goto ERROR1; } } // 检查dp2kernel中是否有和invoice库同名的数据库存在 { // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = IsDatabaseExist( channel, strName, out strError); if (nRet == -1) goto ERROR1; if (nRet >= 1) goto ERROR1; } string strTemplateDir = this.DataDir + "\\templates\\" + "invoice"; // 根据预先的定义,创建一个数据库 nRet = CreateDatabase(channel, strTemplateDir, strName, out strError); if (nRet == -1) goto ERROR1; created_dbnames.Add(strName); bDbChanged = true; // 2012/12/12 // 在CfgDom中增加相关的配置信息 this.InvoiceDbName = strName; this.Changed = true; } else { strError = "未知的数据库类型 '" + strType + "'"; goto ERROR1; } if (this.Changed == true) this.ActivateManagerThread(); created_dbnames.Clear(); } Debug.Assert(created_dbnames.Count == 0, ""); if (bDbChanged == true) { nRet = InitialKdbs( Channels, out strError); if (nRet == -1) return -1; // 重新初始化虚拟库定义 this.vdbs = null; nRet = this.InitialVdbs(Channels, out strError); if (nRet == -1) return -1; } return 0; ERROR1: List<string> error_deleting_dbnames = new List<string>(); // 将本次已经创建的数据库在返回前删除掉 for (int i = 0; i < created_dbnames.Count; i++) { string strDbName = created_dbnames[i]; string strError_1 = ""; long lRet = channel.DoDeleteDB(strDbName, out strError_1); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) continue; if (lRet == -1) error_deleting_dbnames.Add(strDbName + "[错误:"+strError_1+"]"); } if (error_deleting_dbnames.Count > 0) { strError = strError + ";\r\n并在删除刚创建的数据库时发生错误,下列数据库未被删除:" + StringUtil.MakePathList(error_deleting_dbnames); return -1; } return -1; }
// 修改数据库 int ChangeDatabase( RmsChannelCollection Channels, string strLibraryCodeList, string strDatabaseNames, string strDatabaseInfo, out string strOutputInfo, out string strError) { strOutputInfo = ""; strError = ""; int nRet = 0; // long lRet = 0; bool bDbNameChanged = false; XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strDatabaseInfo); } catch (Exception ex) { strError = "strDatabaseInfo内容装入XMLDOM时出错: " + ex.Message; return -1; } // 核对strDatabaseNames中包含的数据库名数目是否和dom中的<database>元素数相等 string[] names = strDatabaseNames.Split(new char[] {','}); XmlNodeList nodes = dom.DocumentElement.SelectNodes("database"); if (names.Length != nodes.Count) { strError = "strDatabaseNames参数中包含的数据库名个数 "+names.Length.ToString()+" 和strDatabaseInfo参数中包含的<database>元素数 "+nodes.Count.ToString()+" 不等"; return -1; } RmsChannel channel = Channels.GetChannel(this.WsUrl); for (int i = 0; i < names.Length; i++) { string strName = names[i].Trim(); if (String.IsNullOrEmpty(strName) == true) { strError = "strDatabaseNames参数中不能包含空的名字"; return -1; } // 来自strDatabaseInfo XmlElement nodeNewDatabase = nodes[i] as XmlElement; // 修改书目库名、或者书目库从属的其他数据库名 if (this.IsBiblioDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@biblioDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的书目库(biblioDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许修改书目库定义"; return -1; } /* * <database>元素中的name/entityDbName/orderDbName/issueDbName * 传递了改名请求。如果属性值为空,不表明要删除数据库,而是该属性无效。 * 实际上这里不响应删除数据库的动作,只能改名 * 将来可以改造为响应删除数据库的请求,那么,只要属性具备,就有请求。如果不想请求,则不要包含那个属性 * */ { // 书目库名 string strOldBiblioDbName = strName; // 来自strDatabaseInfo string strNewBiblioDbName = DomUtil.GetAttr(nodeNewDatabase, "name"); // 如果strNewBiblioDbName为空,表示不想改变名字 if (String.IsNullOrEmpty(strNewBiblioDbName) == false && strOldBiblioDbName != strNewBiblioDbName) { if (String.IsNullOrEmpty(strOldBiblioDbName) == true && String.IsNullOrEmpty(strNewBiblioDbName) == false) { strError = "要创建书目库 '" + strNewBiblioDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldBiblioDbName, strNewBiblioDbName, () => { DomUtil.SetAttr(nodeDatabase, "biblioDbName", strNewBiblioDbName); bDbNameChanged = true; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "biblioDbName", strNewBiblioDbName); this.Changed = true; #endif } } { // 实体库名 string strOldEntityDbName = DomUtil.GetAttr(nodeDatabase, "name"); // 来自strDatabaseInfo string strNewEntityDbName = DomUtil.GetAttr(nodeNewDatabase, "entityDbName"); if (String.IsNullOrEmpty(strNewEntityDbName) == false && strOldEntityDbName != strNewEntityDbName) { if (String.IsNullOrEmpty(strOldEntityDbName) == true && String.IsNullOrEmpty(strNewEntityDbName) == false) { strError = "要创建实体库 '" + strNewEntityDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldEntityDbName, strNewEntityDbName, () => { DomUtil.SetAttr(nodeDatabase, "name", strNewEntityDbName); bDbNameChanged = true; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "name", strNewEntityDbName); this.Changed = true; #endif } } { // 订购库名 string strOldOrderDbName = DomUtil.GetAttr(nodeDatabase, "orderDbName"); // 来自strDatabaseInfo string strNewOrderDbName = DomUtil.GetAttr(nodeNewDatabase, "orderDbName"); if (String.IsNullOrEmpty(strNewOrderDbName) == false && strOldOrderDbName != strNewOrderDbName) { if (String.IsNullOrEmpty(strOldOrderDbName) == true && String.IsNullOrEmpty(strNewOrderDbName) == false) { strError = "要创建订购库 '" + strNewOrderDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldOrderDbName, strNewOrderDbName, () => { DomUtil.SetAttr(nodeDatabase, "orderDbName", strNewOrderDbName); bDbNameChanged = true; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "orderDbName", strNewOrderDbName); this.Changed = true; #endif } } { // 期库名 string strOldIssueDbName = DomUtil.GetAttr(nodeDatabase, "issueDbName"); // 来自strDatabaseInfo string strNewIssueDbName = DomUtil.GetAttr(nodeNewDatabase, "issueDbName"); if (String.IsNullOrEmpty(strNewIssueDbName) == false && strOldIssueDbName != strNewIssueDbName) { if (String.IsNullOrEmpty(strOldIssueDbName) == true && String.IsNullOrEmpty(strNewIssueDbName) == false) { strError = "要创建期库 '" + strNewIssueDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldIssueDbName, strNewIssueDbName, () => { DomUtil.SetAttr(nodeDatabase, "issueDbName", strNewIssueDbName); bDbNameChanged = true; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "issueDbName", strNewIssueDbName); this.Changed = true; #endif } } { // 评注库名 string strOldCommentDbName = DomUtil.GetAttr(nodeDatabase, "commentDbName"); // 来自strDatabaseInfo string strNewCommentDbName = DomUtil.GetAttr(nodeNewDatabase, "commentDbName"); if (String.IsNullOrEmpty(strNewCommentDbName) == false && strOldCommentDbName != strNewCommentDbName) { if (String.IsNullOrEmpty(strOldCommentDbName) == true && String.IsNullOrEmpty(strNewCommentDbName) == false) { strError = "要创建评注库 '" + strNewCommentDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldCommentDbName, strNewCommentDbName, () => { DomUtil.SetAttr(nodeDatabase, "commentDbName", strNewCommentDbName); bDbNameChanged = true; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "commentDbName", strNewCommentDbName); this.Changed = true; #endif } } // 是否参与流通 if (DomUtil.HasAttr(nodeNewDatabase, "inCirculation") == true) { string strOldInCirculation = DomUtil.GetAttr(nodeDatabase, "inCirculation"); if (String.IsNullOrEmpty(strOldInCirculation) == true) strOldInCirculation = "true"; string strNewInCirculation = DomUtil.GetAttr(nodeNewDatabase, "inCirculation"); if (String.IsNullOrEmpty(strNewInCirculation) == true) strNewInCirculation = "true"; if (strOldInCirculation != strNewInCirculation) { DomUtil.SetAttr(nodeDatabase, "inCirculation", strNewInCirculation); this.Changed = true; } } // 角色 // TODO: 是否要进行检查? if (DomUtil.HasAttr(nodeNewDatabase, "role") == true) { string strOldRole = DomUtil.GetAttr(nodeDatabase, "role"); string strNewRole = DomUtil.GetAttr(nodeNewDatabase, "role"); if (strOldRole != strNewRole) { DomUtil.SetAttr(nodeDatabase, "role", strNewRole); this.Changed = true; } } // 2012/4/30 // 联合编目特性 if (DomUtil.HasAttr(nodeNewDatabase, "unionCatalogStyle") == true) { string strOldUnionCatalogStyle = DomUtil.GetAttr(nodeDatabase, "unionCatalogStyle"); string strNewUnionCatalogStyle = DomUtil.GetAttr(nodeNewDatabase, "unionCatalogStyle"); if (strOldUnionCatalogStyle != strNewUnionCatalogStyle) { DomUtil.SetAttr(nodeDatabase, "unionCatalogStyle", strNewUnionCatalogStyle); this.Changed = true; } } // 复制 if (DomUtil.HasAttr(nodeNewDatabase, "replication") == true) { string strOldReplication = DomUtil.GetAttr(nodeDatabase, "replication"); string strNewReplication = DomUtil.GetAttr(nodeNewDatabase, "replication"); if (strOldReplication != strNewReplication) { DomUtil.SetAttr(nodeDatabase, "replication", strNewReplication); this.Changed = true; } } // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); return -1; } this.Changed = true; continue; } // end of if 书目库名 // 单独修改实体库名 // 能修改是否参与流通 if (this.IsItemDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的实体库(name属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许修改实体库定义"; return -1; } // 实体库名 string strOldEntityDbName = DomUtil.GetAttr(nodeDatabase, "name"); // 来自strDatabaseInfo string strNewEntityDbName = DomUtil.GetAttr(nodeNewDatabase, "name"); if (strOldEntityDbName != strNewEntityDbName) { if (String.IsNullOrEmpty(strOldEntityDbName) == true && String.IsNullOrEmpty(strNewEntityDbName) == false) { strError = "要创建实体库 '" + strNewEntityDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } if (String.IsNullOrEmpty(strOldEntityDbName) == false && String.IsNullOrEmpty(strNewEntityDbName) == true) { strError = "要删除实体库 '" + strNewEntityDbName + "',请使用delete功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldEntityDbName, strNewEntityDbName, () => { DomUtil.SetAttr(nodeDatabase, "name", strNewEntityDbName); bDbNameChanged = true; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "name", strNewEntityDbName); this.Changed = true; #endif } // 是否参与流通 { string strOldInCirculation = DomUtil.GetAttr(nodeDatabase, "inCirculation"); if (String.IsNullOrEmpty(strOldInCirculation) == true) strOldInCirculation = "true"; string strNewInCirculation = DomUtil.GetAttr(nodeNewDatabase, "inCirculation"); if (String.IsNullOrEmpty(strNewInCirculation) == true) strNewInCirculation = "true"; if (strOldInCirculation != strNewInCirculation) { DomUtil.SetAttr(nodeDatabase, "inCirculation", strNewInCirculation); this.Changed = true; } } // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); return -1; } this.Changed = true; continue; } // 单独修改订购库名 if (this.IsOrderDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@orderDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的订购库(orderDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许修改订购库定义"; return -1; } // 来自LibraryCfgDom string strOldOrderDbName = DomUtil.GetAttr(nodeDatabase, "orderDbName"); // 来自strDatabaseInfo string strNewOrderDbName = DomUtil.GetAttr(nodeNewDatabase, "name"); if (strOldOrderDbName != strNewOrderDbName) { if (String.IsNullOrEmpty(strOldOrderDbName) == true && String.IsNullOrEmpty(strNewOrderDbName) == false) { strError = "要创建订购库 '" + strNewOrderDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } if (String.IsNullOrEmpty(strOldOrderDbName) == false && String.IsNullOrEmpty(strNewOrderDbName) == true) { strError = "要删除订购库 '" + strNewOrderDbName + "',请使用delete功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldOrderDbName, strNewOrderDbName, () => { DomUtil.SetAttr(nodeDatabase, "orderDbName", strNewOrderDbName); bDbNameChanged = true; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "orderDbName", strNewOrderDbName); this.Changed = true; #endif } // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); return -1; } this.Changed = true; continue; } // 单独修改期库名 if (this.IsIssueDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@issueDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的期库(issueDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许修改期库定义"; return -1; } // 来自LibraryCfgDom string strOldIssueDbName = DomUtil.GetAttr(nodeDatabase, "issueDbName"); // 来自strDatabaseInfo string strNewIssueDbName = DomUtil.GetAttr(nodeNewDatabase, "name"); // 2012/4/30 changed if (strOldIssueDbName != strNewIssueDbName) { if (String.IsNullOrEmpty(strOldIssueDbName) == true && String.IsNullOrEmpty(strNewIssueDbName) == false) { strError = "要创建期库 '" + strNewIssueDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } if (String.IsNullOrEmpty(strOldIssueDbName) == false && String.IsNullOrEmpty(strNewIssueDbName) == true) { strError = "要删除期库 '" + strNewIssueDbName + "',请使用delete功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldIssueDbName, strNewIssueDbName, () => { DomUtil.SetAttr(nodeDatabase, "issueDbName", strNewIssueDbName); bDbNameChanged = true; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "issueDbName", strNewIssueDbName); this.Changed = true; #endif } // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); return -1; } this.Changed = true; continue; } // 单独修改评注库名 if (this.IsCommentDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@commentDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的评注库(commentDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许修改评注库定义"; return -1; } // 来自LibraryCfgDom string strOldCommentDbName = DomUtil.GetAttr(nodeDatabase, "commentDbName"); // 来自strDatabaseInfo string strNewCommentDbName = DomUtil.GetAttr(nodeNewDatabase, "name"); // 2012/4/30 changed if (strOldCommentDbName != strNewCommentDbName) { if (String.IsNullOrEmpty(strOldCommentDbName) == true && String.IsNullOrEmpty(strNewCommentDbName) == false) { strError = "要创建评注库 '" + strNewCommentDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } if (String.IsNullOrEmpty(strOldCommentDbName) == false && String.IsNullOrEmpty(strNewCommentDbName) == true) { strError = "要删除评注库 '" + strNewCommentDbName + "',请使用delete功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldCommentDbName, strNewCommentDbName, () => { DomUtil.SetAttr(nodeDatabase, "commentDbName", strNewCommentDbName); bDbNameChanged = true; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "commentDbName", strNewCommentDbName); this.Changed = true; #endif } // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); return -1; } this.Changed = true; continue; } // 修改读者库名 if (this.IsReaderDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("readerdbgroup/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的读者库(name属性)相关<database>元素没有找到"; return -1; } // 2012/9/9 // 分馆用户只允许修改属于管辖分馆的读者库 if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { string strExistLibraryCode = DomUtil.GetAttr(nodeDatabase, "libraryCode"); if (string.IsNullOrEmpty(strExistLibraryCode) == true || StringUtil.IsInList(strExistLibraryCode, strLibraryCodeList) == false) { strError = "修改读者库 '" + strName + "' 定义被拒绝。当前用户只能修改图书馆代码完全属于 '" + strLibraryCodeList + "' 范围的读者库"; return -1; } } // 来自LibraryCfgDom string strOldReaderDbName = DomUtil.GetAttr(nodeDatabase, "name"); // 来自strDatabaseInfo string strNewReaderDbName = DomUtil.GetAttr(nodeNewDatabase, "name"); if (strOldReaderDbName != strNewReaderDbName) { if (String.IsNullOrEmpty(strOldReaderDbName) == true && String.IsNullOrEmpty(strNewReaderDbName) == false) { strError = "要创建读者库 '" + strNewReaderDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } if (String.IsNullOrEmpty(strOldReaderDbName) == false && String.IsNullOrEmpty(strNewReaderDbName) == true) { strError = "要删除读者库 '" + strNewReaderDbName + "',请使用delete功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldReaderDbName, strNewReaderDbName, () => { DomUtil.SetAttr(nodeDatabase, "name", strNewReaderDbName); bDbNameChanged = true; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "name", strNewReaderDbName); this.Changed = true; #endif } // 是否参与流通 // 只有当提交的 XML 片断中具有 inCirculation 属性的时候,才会发生修改 if (nodeNewDatabase.GetAttributeNode("inCirculation") != null) { // 来自LibraryCfgDom string strOldInCirculation = DomUtil.GetAttr(nodeDatabase, "inCirculation"); if (String.IsNullOrEmpty(strOldInCirculation) == true) strOldInCirculation = "true"; // 来自strDatabaseInfo string strNewInCirculation = DomUtil.GetAttr(nodeNewDatabase, "inCirculation"); if (String.IsNullOrEmpty(strNewInCirculation) == true) strNewInCirculation = "true"; if (strOldInCirculation != strNewInCirculation) { DomUtil.SetAttr(nodeDatabase, "inCirculation", strNewInCirculation); this.Changed = true; } } // 2012/9/7 // 图书馆代码 // 只有当提交的 XML 片断中具有 libraryCode 属性的时候,才会发生修改 if (nodeNewDatabase.GetAttributeNode("libraryCode") != null) { // 来自LibraryCfgDom string strOldLibraryCode = DomUtil.GetAttr(nodeDatabase, "libraryCode"); // 来自strDatabaseInfo string strNewLibraryCode = DomUtil.GetAttr(nodeNewDatabase, "libraryCode"); if (strOldLibraryCode != strNewLibraryCode) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { if (string.IsNullOrEmpty(strNewLibraryCode) == true || StringUtil.IsInList(strNewLibraryCode, strLibraryCodeList) == false) { strError = "修改读者库 '" + strName + "' 定义被拒绝。修改后的新图书馆代码必须完全属于 '" + strLibraryCodeList + "' 范围"; return -1; } } // 检查一个单独的图书馆代码是否格式正确 // 要求不能为 '*',不能包含逗号 // return: // -1 校验函数本身出错了 // 0 校验正确 // 1 校验发现问题。strError中有描述 nRet = VerifySingleLibraryCode(strNewLibraryCode, out strError); if (nRet != 0) { strError = "图书馆代码 '" + strNewLibraryCode + "' 格式错误: " + strError; goto ERROR1; } DomUtil.SetAttr(nodeDatabase, "libraryCode", strNewLibraryCode); this.Changed = true; } } // <readerdbgroup>内容更新,刷新配套的内存结构 this.LoadReaderDbGroupParam(this.LibraryCfgDom); this.Changed = true; continue; } // 修改预约到书库名 if (this.ArrivedDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许修改预约到书库定义"; return -1; } string strOldArrivedDbName = this.ArrivedDbName; // 来自strDatabaseInfo string strNewArrivedDbName = DomUtil.GetAttr(nodeNewDatabase, "name"); if (strOldArrivedDbName != strNewArrivedDbName) { if (String.IsNullOrEmpty(strOldArrivedDbName) == true && String.IsNullOrEmpty(strNewArrivedDbName) == false) { strError = "要创建预约到书库 '" + strNewArrivedDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } if (String.IsNullOrEmpty(strOldArrivedDbName) == false && String.IsNullOrEmpty(strNewArrivedDbName) == true) { strError = "要删除预约到书库 '" + strNewArrivedDbName + "',请使用delete功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldArrivedDbName, strNewArrivedDbName, () => { this.ArrivedDbName = strNewArrivedDbName; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO this.Changed = true; this.ArrivedDbName = strNewArrivedDbName; #endif } continue; } // 修改违约金库名 if (this.AmerceDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许修改违约金库定义"; return -1; } string strOldAmerceDbName = this.AmerceDbName; // 来自strDatabaseInfo string strNewAmerceDbName = DomUtil.GetAttr(nodeNewDatabase, "name"); if (strOldAmerceDbName != strNewAmerceDbName) { if (String.IsNullOrEmpty(strOldAmerceDbName) == true && String.IsNullOrEmpty(strNewAmerceDbName) == false) { strError = "要创建违约金库 '" + strNewAmerceDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } if (String.IsNullOrEmpty(strOldAmerceDbName) == false && String.IsNullOrEmpty(strNewAmerceDbName) == true) { strError = "要删除违约金库 '" + strNewAmerceDbName + "',请使用delete功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldAmerceDbName, strNewAmerceDbName, () => { this.AmerceDbName = strNewAmerceDbName; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO this.Changed = true; this.AmerceDbName = strNewAmerceDbName; #endif } continue; } // 修改发票库名 if (this.InvoiceDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许修改发票库定义"; return -1; } string strOldInvoiceDbName = this.InvoiceDbName; // 来自strDatabaseInfo string strNewInvoiceDbName = DomUtil.GetAttr(nodeNewDatabase, "name"); if (strOldInvoiceDbName != strNewInvoiceDbName) { if (String.IsNullOrEmpty(strOldInvoiceDbName) == true && String.IsNullOrEmpty(strNewInvoiceDbName) == false) { strError = "要创建发票库 '" + strNewInvoiceDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } if (String.IsNullOrEmpty(strOldInvoiceDbName) == false && String.IsNullOrEmpty(strNewInvoiceDbName) == true) { strError = "要删除发票库 '" + strNewInvoiceDbName + "',请使用delete功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldInvoiceDbName, strNewInvoiceDbName, () => { this.InvoiceDbName = strNewInvoiceDbName; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO this.Changed = true; this.InvoiceDbName = strNewInvoiceDbName; #endif } continue; } // 修改消息库名 if (this.MessageDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许修改预约消息库定义"; return -1; } string strOldMessageDbName = this.MessageDbName; // 来自strDatabaseInfo string strNewMessageDbName = DomUtil.GetAttr(nodeNewDatabase, "name"); if (strOldMessageDbName != strNewMessageDbName) { if (String.IsNullOrEmpty(strOldMessageDbName) == true && String.IsNullOrEmpty(strNewMessageDbName) == false) { strError = "要创建消息库 '" + strNewMessageDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } if (String.IsNullOrEmpty(strOldMessageDbName) == false && String.IsNullOrEmpty(strNewMessageDbName) == true) { strError = "要删除消息库 '" + strNewMessageDbName + "',请使用delete功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldMessageDbName, strNewMessageDbName, () => { this.MessageDbName = strNewMessageDbName; this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO this.Changed = true; this.MessageDbName = strNewMessageDbName; #endif } continue; } // 修改实用库名 if (IsUtilDbName(strName) == true) { XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("utilDb/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "不存在name属性值为 '"+strName+"' 的<utilDb/database>的元素"; goto ERROR1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许修改实用库定义"; return -1; } string strOldUtilDbName = strName; // 来自strDatabaseInfo string strNewUtilDbName = DomUtil.GetAttr(nodeNewDatabase, "name"); if (strOldUtilDbName != strNewUtilDbName) { if (String.IsNullOrEmpty(strOldUtilDbName) == true && String.IsNullOrEmpty(strNewUtilDbName) == false) { strError = "要创建实用库 '" + strNewUtilDbName + "',请使用create功能,而不能使用change功能"; goto ERROR1; } if (String.IsNullOrEmpty(strOldUtilDbName) == false && String.IsNullOrEmpty(strNewUtilDbName) == true) { strError = "要删除实用库 '" + strNewUtilDbName + "',请使用delete功能,而不能使用change功能"; goto ERROR1; } nRet = ChangeDbName( channel, strOldUtilDbName, strNewUtilDbName, () => { DomUtil.SetAttr(nodeDatabase, "name", strNewUtilDbName); this.Changed = true; }, out strError); if (nRet == -1) goto ERROR1; #if NO this.Changed = true; DomUtil.SetAttr(nodeDatabase, "name", strNewUtilDbName); #endif } string strOldType = DomUtil.GetAttr(nodeDatabase, "type"); string strNewType = DomUtil.GetAttr(nodeNewDatabase, "type"); if (strOldType != strNewType) { DomUtil.SetAttr(nodeDatabase, "type", strNewType); this.Changed = true; // TODO: 类型修改后,是否要应用新的模板来修改数据库定义?这是个大问题 } continue; } strError = "数据库名 '" + strName + "' 不属于 dp2library 目前管辖的范围..."; return -1; } if (this.Changed == true) this.ActivateManagerThread(); if (bDbNameChanged == true) { nRet = InitialKdbs( Channels, out strError); if (nRet == -1) return -1; // 重新初始化虚拟库定义 this.vdbs = null; nRet = this.InitialVdbs(Channels, out strError); if (nRet == -1) return -1; } return 0; ERROR1: // 2015/1/29 if (this.Changed == true) this.ActivateManagerThread(); // 2015/1/29 if (bDbNameChanged == true) { { string strError1 = ""; nRet = InitialKdbs( Channels, out strError1); if (nRet == -1) strError += "; 在收尾的时候进行 InitialKdbs() 调用又出错:" + strError1; } { string strError1 = ""; // 重新初始化虚拟库定义 this.vdbs = null; nRet = this.InitialVdbs(Channels, out strError1); if (nRet == -1) strError += "; 在收尾的时候进行 InitialVdbs() 调用又出错:" + strError1; } } return -1; }
// 删除数据库 int DeleteDatabase( RmsChannelCollection Channels, string strLibraryCodeList, string strDatabaseNames, out string strOutputInfo, out string strError) { strOutputInfo = ""; strError = ""; int nRet = 0; // long lRet = 0; bool bDbNameChanged = false; RmsChannel channel = Channels.GetChannel(this.WsUrl); string[] names = strDatabaseNames.Split(new char[] { ',' }); for (int i = 0; i < names.Length; i++) { string strName = names[i].Trim(); if (String.IsNullOrEmpty(strName) == true) continue; // 书目库整体删除,也是可以的 // TODO: 将来可以考虑单独删除书目库而不删除组内相关库 if (this.IsBiblioDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@biblioDbName='"+strName+"']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的书目库(biblioDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许删除书目库"; return -1; } // 删除书目库 /* lRet = channel.DoDeleteDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除书目库 '" + strName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strName, out strError); if (nRet == -1) { strError = "删除书目库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; // 删除实体库 string strEntityDbName = DomUtil.GetAttr(nodeDatabase, "name"); if (String.IsNullOrEmpty(strEntityDbName) == false) { /* lRet = channel.DoDeleteDB(strEntityDbName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除书目库 '" + strName + "' 所从属的实体库 '" + strEntityDbName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strEntityDbName, out strError); if (nRet == -1) { strError = "删除书目库 '" + strName + "' 所从属的实体库 '" + strEntityDbName + "' 时发生错误: " + strError; return -1; } } // 删除订购库 string strOrderDbName = DomUtil.GetAttr(nodeDatabase, "orderDbName"); if (String.IsNullOrEmpty(strOrderDbName) == false) { /* lRet = channel.DoDeleteDB(strOrderDbName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除书目库 '" + strName + "' 所从属的订购库 '" + strOrderDbName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strOrderDbName, out strError); if (nRet == -1) { strError = "删除书目库 '" + strName + "' 所从属的订购库 '" + strOrderDbName + "' 时发生错误: " + strError; return -1; } } // 删除期库 string strIssueDbName = DomUtil.GetAttr(nodeDatabase, "issueDbName"); if (String.IsNullOrEmpty(strIssueDbName) == false) { /* lRet = channel.DoDeleteDB(strIssueDbName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除书目库 '" + strName + "' 所从属的期库 '" + strIssueDbName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strIssueDbName, out strError); if (nRet == -1) { strError = "删除书目库 '" + strName + "' 所从属的期库 '" + strIssueDbName + "' 时发生错误: " + strError; return -1; } } // 删除评注库 string strCommentDbName = DomUtil.GetAttr(nodeDatabase, "commentDbName"); if (String.IsNullOrEmpty(strCommentDbName) == false) { nRet = DeleteDatabase(channel, strCommentDbName, out strError); if (nRet == -1) { strError = "删除书目库 '" + strName + "' 所从属的评注库 '" + strCommentDbName + "' 时发生错误: " + strError; return -1; } } nodeDatabase.ParentNode.RemoveChild(nodeDatabase); // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); return -1; } /* // 删除一个数据库在OPAC可检索库中的定义 // return: // -1 error // 0 not change // 1 changed nRet = RemoveOpacDatabaseDef( Channels, strName, out strError); if (nRet == -1) { this.Changed = true; this.ActivateMangerThread(); return -1; }*/ this.Changed = true; this.ActivateManagerThread(); continue; } // 单独删除实体库 if (this.IsItemDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的实体库(name属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许删除实体库"; return -1; } // 删除实体库 /* lRet = channel.DoDeleteDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除实体库 '" + strName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strName, out strError); if (nRet == -1) { strError = "删除实体库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "name", null); // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); return -1; } this.Changed = true; this.ActivateManagerThread(); continue; } // 单独删除订购库 if (this.IsOrderDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@orderDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的订购库(orderDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许删除订购库"; return -1; } // 删除订购库 /* lRet = channel.DoDeleteDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除订购库 '" + strName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strName, out strError); if (nRet == -1) { strError = "删除订购库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "orderDbName", null); // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); return -1; } this.Changed = true; this.ActivateManagerThread(); continue; } // 单独删除期库 if (this.IsIssueDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@issueDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的期库(issueDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许删除期库"; return -1; } // 删除期库 /* lRet = channel.DoDeleteDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除期库 '" + strName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strName, out strError); if (nRet == -1) { strError = "删除期库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "issueDbName", null); // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); return -1; } this.Changed = true; this.ActivateManagerThread(); continue; } // 单独删除评注库 if (this.IsCommentDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@commentDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的评注库(commentDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许删除评注库"; return -1; } nRet = DeleteDatabase(channel, strName, out strError); if (nRet == -1) { strError = "删除评注库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; DomUtil.SetAttr(nodeDatabase, "commentDbName", null); // <itemdbgroup>内容更新,刷新配套的内存结构 nRet = this.LoadItemDbGroupParam(this.LibraryCfgDom, out strError); if (nRet == -1) { this.WriteErrorLog(strError); return -1; } this.Changed = true; this.ActivateManagerThread(); continue; } // 删除读者库 if (this.IsReaderDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("readerdbgroup/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的读者库(name属性)相关<database>元素没有找到"; return -1; } // 2012/9/9 // 分馆用户只允许删除属于管辖分馆的读者库 if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { string strExistLibraryCode = DomUtil.GetAttr(nodeDatabase, "libraryCode"); if (string.IsNullOrEmpty(strExistLibraryCode) == true || StringUtil.IsInList(strExistLibraryCode, strLibraryCodeList) == false) { strError = "删除读者库 '" + strName + "' 被拒绝。当前用户只能删除图书馆代码完全完全属于 '" + strLibraryCodeList + "' 范围的读者库"; return -1; } } // 删除读者库 /* lRet = channel.DoDeleteDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除读者库 '" + strName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strName, out strError); if (nRet == -1) { strError = "删除读者库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; nodeDatabase.ParentNode.RemoveChild(nodeDatabase); // <readerdbgroup>内容更新,刷新配套的内存结构 this.LoadReaderDbGroupParam(this.LibraryCfgDom); /* // 删除一个数据库在OPAC可检索库中的定义 // return: // -1 error // 0 not change // 1 changed nRet = RemoveOpacDatabaseDef( Channels, strName, out strError); if (nRet == -1) { this.Changed = true; this.ActivateMangerThread(); return -1; } * */ this.Changed = true; this.ActivateManagerThread(); continue; } // 删除预约到书库 if (this.ArrivedDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许删除预约到书库"; return -1; } // 删除预约到书库 /* lRet = channel.DoDeleteDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除预约到书库 '" + strName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strName, out strError); if (nRet == -1) { strError = "删除预约到书库 '" + strName + "' 时发生错误: " + strError; return -1; } this.ArrivedDbName = ""; /* // 删除一个数据库在OPAC可检索库中的定义 // return: // -1 error // 0 not change // 1 changed nRet = RemoveOpacDatabaseDef( Channels, strName, out strError); if (nRet == -1) { this.Changed = true; this.ActivateMangerThread(); return -1; } * */ this.Changed = true; this.ActivateManagerThread(); continue; } // 删除违约金库 if (this.AmerceDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许删除违约金库"; return -1; } // 删除违约金库 /* lRet = channel.DoDeleteDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除违约金库 '" + strName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strName, out strError); if (nRet == -1) { strError = "删除违约金库 '" + strName + "' 时发生错误: " + strError; return -1; } this.AmerceDbName = ""; /* // 删除一个数据库在OPAC可检索库中的定义 // return: // -1 error // 0 not change // 1 changed nRet = RemoveOpacDatabaseDef( Channels, strName, out strError); if (nRet == -1) { this.Changed = true; this.ActivateMangerThread(); return -1; }*/ this.Changed = true; this.ActivateManagerThread(); continue; } // 删除发票库 if (this.InvoiceDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许删除发票库"; return -1; } nRet = DeleteDatabase(channel, strName, out strError); if (nRet == -1) { strError = "删除发票库 '" + strName + "' 时发生错误: " + strError; return -1; } this.InvoiceDbName = ""; this.Changed = true; this.ActivateManagerThread(); continue; } // 删除消息库 if (this.MessageDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许删除消息库"; return -1; } // 删除消息库 /* lRet = channel.DoDeleteDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除消息库 '" + strName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strName, out strError); if (nRet == -1) { strError = "删除消息库 '" + strName + "' 时发生错误: " + strError; return -1; } this.MessageDbName = ""; /* // 删除一个数据库在OPAC可检索库中的定义 // return: // -1 error // 0 not change // 1 changed nRet = RemoveOpacDatabaseDef( Channels, strName, out strError); if (nRet == -1) { this.Changed = true; this.ActivateMangerThread(); return -1; } * */ this.Changed = true; this.ActivateManagerThread(); continue; } // 单独删除实用库 if (IsUtilDbName(strName) == true) { XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("utilDb/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "不存在name属性值为 '" + strName + "' 的<utilDb/database>的元素"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许删除实用库"; return -1; } // 删除实用库 /* lRet = channel.DoDeleteDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "删除实用库 '" + strName + "' 时发生错误: " + strError; return -1; } * */ nRet = DeleteDatabase(channel, strName, out strError); if (nRet == -1) { strError = "删除实用库 '" + strName + "' 时发生错误: " + strError; return -1; } nodeDatabase.ParentNode.RemoveChild(nodeDatabase); /* // 删除一个数据库在OPAC可检索库中的定义 // return: // -1 error // 0 not change // 1 changed nRet = RemoveOpacDatabaseDef( Channels, strName, out strError); if (nRet == -1) { this.Changed = true; this.ActivateMangerThread(); return -1; } * */ this.Changed = true; this.ActivateManagerThread(); continue; } strError = "数据库名 '" +strName+ "' 不属于 dp2library 目前管辖的范围..."; return -1; } if (bDbNameChanged == true) { nRet = InitialKdbs( Channels, out strError); if (nRet == -1) return -1; // 重新初始化虚拟库定义 this.vdbs = null; nRet = this.InitialVdbs(Channels, out strError); if (nRet == -1) return -1; } return 0; }
// 删除一个数据库在OPAC可检索库中的定义 // return: // -1 error // 0 not change // 1 changed int RemoveOpacDatabaseDef( RmsChannelCollection Channels, string strDatabaseName, out string strError) { strError = ""; bool bChanged = false; XmlNode root = this.LibraryCfgDom.DocumentElement.SelectSingleNode("virtualDatabases"); if (root != null) { // 虚拟成员库定义 XmlNodeList nodes = root.SelectNodes("virtualDatabase/database[@name='" + strDatabaseName + "']"); for (int i = 0; i < nodes.Count; i++) { XmlNode node = nodes[i]; node.ParentNode.RemoveChild(node); bChanged = true; } // 普通成员库定义 nodes = root.SelectNodes("database[@name='" + strDatabaseName + "']"); for (int i = 0; i < nodes.Count; i++) { XmlNode node = nodes[i]; node.ParentNode.RemoveChild(node); bChanged = true; } // 重新初始化虚拟库定义 this.vdbs = null; int nRet = this.InitialVdbs(Channels, out strError); if (nRet == -1) return -1; } root = this.LibraryCfgDom.DocumentElement.SelectSingleNode("browseformats"); if (root != null) { // 显示定义中的库名 XmlNodeList nodes = root.SelectNodes("database[@name='" + strDatabaseName + "']"); for (int i = 0; i < nodes.Count; i++) { XmlNode node = nodes[i]; node.ParentNode.RemoveChild(node); bChanged = true; } } if (bChanged == true) return 1; return 0; }
/* <root> <operation>devolveReaderInfo</operation> <sourceReaderBarcode>...</sourceReaderBarcode> 源读者证条码号 <targetReaderBarcode>...</targetReaderBarcode> 目标读者证条码号 <borrows>...</borrows> 移动过去的<borrows>内容,下级为<borrow>元素 <overdues>...</overdues> 移动过去的<overdue>内容,下级为<overdue>元素 <sourceReaderRecord recPath='...'>...</sourceReaderRecord> 最新源读者记录 <targetReaderRecord recPath='...'>...</targetReaderRecord> 最新目标读者记录 <changedEntityRecord recPath='...' attahchmentIndex='.'>...</changedEntityRecord> 所牵连到的发生了修改的实体记录。此元素的文本即是记录体,但注意为不透明的字符串(HtmlEncoding后的记录字符串)。如果存在attachmentIndex属性,则表明实体记录不在此元素文本中,而在日志记录的附件中 <operator>test</operator> <operTime>Fri, 08 Dec 2006 10:12:20 GMT</operTime> </root> * * */ public int RecoverDevolveReaderInfo( RmsChannelCollection Channels, RecoverLevel level, XmlDocument domLog, Stream attachmentLog, out string strError) { strError = ""; // 暂时把Robust当作Logic处理 if (level == RecoverLevel.Robust) level = RecoverLevel.Logic; long lRet = 0; int nRet = 0; RmsChannel channel = Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } DO_SNAPSHOT: // 快照恢复 if (level == RecoverLevel.Snapshot) { /* // 观察是否有<warning>元素 XmlNode nodeWarning = domLog.SelectSingleNode("warning"); if (nodeWarning != null) { // 如果<warning元素存在,表明只能采用逻辑恢复> strError = nodeWarning.InnerText; return -1; } */ // 获源读者记录 XmlNode node = null; string strSourceReaderXml = DomUtil.GetElementText( domLog.DocumentElement, "sourceReaderRecord", out node); if (node == null) { strError = "日志记录中缺<sourceReaderRecord>元素"; return -1; } string strSourceReaderRecPath = DomUtil.GetAttr(node, "recPath"); byte[] timestamp = null; string strOutputPath = ""; byte[] output_timestamp = null; // 写源读者记录 lRet = channel.DoSaveTextRes(strSourceReaderRecPath, strSourceReaderXml, false, "content,ignorechecktimestamp", timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "写入源读者记录 '" + strSourceReaderRecPath + "' 时发生错误: " + strError; return -1; } // 获目标读者记录 node = null; string strTargetReaderXml = DomUtil.GetElementText( domLog.DocumentElement, "targetReaderRecord", out node); if (node == null) { strError = "日志记录中缺<targetReaderRecord>元素"; return -1; } string strTargetReaderRecPath = DomUtil.GetAttr(node, "recPath"); // 写目标读者记录 lRet = channel.DoSaveTextRes(strTargetReaderRecPath, strTargetReaderXml, false, "content,ignorechecktimestamp", timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "写入目标读者记录 '" + strSourceReaderRecPath + "' 时发生错误: " + strError; return -1; } // 循环,写入相关的若干实体记录 XmlNodeList nodeEntities = domLog.DocumentElement.SelectNodes("changedEntityRecord"); for (int i = 0; i < nodeEntities.Count; i++) { XmlNode nodeEntity = nodeEntities[i]; string strItemRecPath = DomUtil.GetAttr(nodeEntity, "recPath"); string strAttachmentIndex = DomUtil.GetAttr(nodeEntity, "attachmentIndex"); string strItemXml = ""; if (String.IsNullOrEmpty(strAttachmentIndex) == true) { strItemXml = nodeEntity.InnerText; if (String.IsNullOrEmpty(strItemXml) == true) { strError = "<changedEntityRecord>元素缺乏文本内容。"; return -1; } } else { // 实体记录在附件中 int nAttachmentIndex = 0; try { nAttachmentIndex = Convert.ToInt32(strAttachmentIndex); } catch { strError = "<changedEntityRecord>元素的attachmentIndex属性值'"+strAttachmentIndex+"'格式不正确,应当为>=0的纯数字"; return -1; } byte[] baItem = null; nRet = GetAttachmentRecord( attachmentLog, nAttachmentIndex, out baItem, out strError); if (nRet == -1) { strError = "获得 index 为 "+nAttachmentIndex.ToString()+" 的日志附件记录时出错:" + strError; return -1; } strItemXml = Encoding.UTF8.GetString(baItem); } // 写册记录 lRet = channel.DoSaveTextRes(strItemRecPath, strItemXml, false, "content,ignorechecktimestamp", timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "写入册记录 '" + strItemRecPath + "' 时发生错误: " + strError; return -1; } } return 0; } // 逻辑恢复或者混合恢复 if (level == RecoverLevel.Logic || level == RecoverLevel.LogicAndSnapshot) { string strOperTimeString = DomUtil.GetElementText(domLog.DocumentElement, "operTime"); string strSourceReaderBarcode = DomUtil.GetElementText(domLog.DocumentElement, "sourceReaderBarcode"); if (String.IsNullOrEmpty(strSourceReaderBarcode) == true) { strError = "<sourceReaderBarcode>元素值为空"; goto ERROR1; } string strTargetReaderBarcode = DomUtil.GetElementText(domLog.DocumentElement, "targetReaderBarcode"); if (String.IsNullOrEmpty(strTargetReaderBarcode) == true) { strError = "<targetReaderBarcode>元素值为空"; goto ERROR1; } // 读入源读者记录 string strSourceReaderXml = ""; string strSourceOutputReaderRecPath = ""; byte[] source_reader_timestamp = null; nRet = this.GetReaderRecXml( // Channels, channel, strSourceReaderBarcode, out strSourceReaderXml, out strSourceOutputReaderRecPath, out source_reader_timestamp, out strError); if (nRet == 0) { strError = "源读者证条码号 '" + strSourceReaderBarcode + "' 不存在"; goto ERROR1; } if (nRet == -1) { strError = "读入证条码号为 '" + strSourceReaderBarcode + "' 的源读者记录时发生错误: " + strError; goto ERROR1; } XmlDocument source_readerdom = null; nRet = LibraryApplication.LoadToDom(strSourceReaderXml, out source_readerdom, out strError); if (nRet == -1) { strError = "装载源读者记录进入XML DOM时发生错误: " + strError; goto ERROR1; } // // 读入目标读者记录 string strTargetReaderXml = ""; string strTargetOutputReaderRecPath = ""; byte[] target_reader_timestamp = null; nRet = this.GetReaderRecXml( // Channels, channel, strTargetReaderBarcode, out strTargetReaderXml, out strTargetOutputReaderRecPath, out target_reader_timestamp, out strError); if (nRet == 0) { strError = "目标读者证条码号 '" + strTargetReaderBarcode + "' 不存在"; goto ERROR1; } if (nRet == -1) { strError = "读入证条码号为 '" + strTargetReaderBarcode + "' 的目标读者记录时发生错误: " + strError; goto ERROR1; } XmlDocument target_readerdom = null; nRet = LibraryApplication.LoadToDom(strTargetReaderXml, out target_readerdom, out strError); if (nRet == -1) { strError = "装载目标读者记录进入XML DOM时发生错误: " + strError; goto ERROR1; } Stream tempstream = null; // 移动信息 XmlDocument domTemp = null; // 移动借阅信息 -- <borrows>元素内容 // return: // -1 error // 0 not found brrowinfo // 1 found and moved nRet = DevolveBorrowInfo( // Channels, channel, strSourceReaderBarcode, strTargetReaderBarcode, strOperTimeString, ref source_readerdom, ref target_readerdom, ref domTemp, "", out tempstream, out strError); if (nRet == -1) goto ERROR1; // 移动超期违约金信息 -- <overdues>元素内容 // return: // -1 error // 0 not found overdueinfo // 1 found and moved nRet = DevolveOverdueInfo( strSourceReaderBarcode, strTargetReaderBarcode, strOperTimeString, ref source_readerdom, ref target_readerdom, ref domTemp, out strError); if (nRet == -1) goto ERROR1; // 写回读者记录 byte[] output_timestamp = null; string strOutputPath = ""; // 写回源读者记录 lRet = channel.DoSaveTextRes(strSourceOutputReaderRecPath, source_readerdom.OuterXml, false, "content,ignorechecktimestamp", source_reader_timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; // 写回目标读者记录 lRet = channel.DoSaveTextRes(strTargetOutputReaderRecPath, target_readerdom.OuterXml, false, "content,ignorechecktimestamp", source_reader_timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; } return 0; ERROR1: if (level == RecoverLevel.LogicAndSnapshot) { level = RecoverLevel.Snapshot; goto DO_SNAPSHOT; } return -1; }
// 删除应用服务器在dp2Kernel内核中创建的数据库 // parameters: // strXmlFileName library.xml 文件的全路径 // return: // -1 出错 // 0 用户放弃删除 // 1 已经删除 public static int DeleteKernelDatabases( IWin32Window owner, string strInstanceName, string strXmlFilename, out string strError) { strError = ""; int nRet = 0; DialogResult result = MessageBox.Show(owner == null ? ForegroundWindow.Instance : owner, "是否要删除应用服务器实例 '" + strInstanceName + "' 在数据库内核中创建过的全部数据库?\r\n\r\n(注:如果现在不删除,将来也可以用内核管理(dp2manager)工具进行删除)", "安装 dp2Library", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == DialogResult.No) return 0; XmlDocument dom = new XmlDocument(); try { dom.Load(strXmlFilename); } catch (Exception ex) { strError = "XML文件 '" + strXmlFilename + "' 装载到DOM时发生错误: " + ex.Message; return -1; } XmlNode rmsserver_node = dom.DocumentElement.SelectSingleNode("rmsserver"); if (rmsserver_node == null) { strError = "<rmsserver>元素没有找到"; return -1; } string strKernelUrl = DomUtil.GetAttr(rmsserver_node, "url"); if (String.IsNullOrEmpty(strKernelUrl) == true) { strError = "<rmsserver>元素的url属性为空"; return -1; } using (RmsChannelCollection channels = new RmsChannelCollection()) { RmsChannel channel = channels.GetChannel(strKernelUrl); if (channel == null) { strError = "channel == null"; return -1; } string strUserName = DomUtil.GetAttr(rmsserver_node, "username"); string strPassword = DomUtil.GetAttr(rmsserver_node, "password"); string EncryptKey = "dp2circulationpassword"; try { strPassword = Cryptography.Decrypt( strPassword, EncryptKey); } catch { strError = "<rmsserver>元素password属性中的密码设置不正确"; return -1; } nRet = channel.Login(strUserName, strPassword, out strError); if (nRet == -1) { strError = "以用户名 '" + strUserName + "' 和密码登录内核时失败: " + strError; return -1; } nRet = DeleteAllDatabase( channel, dom, out strError); if (nRet == -1) return -1; return 1; } }
public void Initial(ServerCollection servers, RmsChannelCollection channels, DigitalPlatform.StopManager stopManager, string serverUrl, string strDbName) { this.Servers = servers; this.Channels = channels; this.stopManager = stopManager; this.ServerUrl = serverUrl; this.DbName = strDbName; if (this.DbName != "") { // 获得数据库Style string strError = ""; this.DbStyle = this.GetDbStyle( this.DbName, out strError); if (this.DbStyle == -1) throw new Exception(strError); // 用服务器端获得的信息填充树 Cursor save = this.Cursor; this.Cursor = Cursors.WaitCursor; FillAll(null); this.Cursor = save; } }
/* <root> <operation>repairBorrowInfo</operation> <action>...</action> 具体动作 有 repairreaderside repairitemside <readerBarcode>...</readerBarcode> <itemBarcode>...</itemBarcode> <confirmItemRecPath>...</confirmItemRecPath> 辅助判断用的册记录路径 <operator>test</operator> <operTime>Fri, 08 Dec 2006 10:12:20 GMT</operTime> </root> * * * */ public int RecoverRepairBorrowInfo( RmsChannelCollection Channels, RecoverLevel level, XmlDocument domLog, Stream attachmentLog, out string strError) { strError = ""; int nRet = 0; // 暂时把Robust当作Logic处理 if (level == RecoverLevel.Robust) level = RecoverLevel.Logic; long lRet = 0; // int nRet = 0; RmsChannel channel = Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } bool bReuse = false; // 是否能够不顾RecorverLevel状态而重用部分代码 DO_SNAPSHOT: // 快照恢复 if (level == RecoverLevel.Snapshot || bReuse == true) { string strAction = DomUtil.GetElementText(domLog.DocumentElement, "action"); string strReaderBarcode = DomUtil.GetElementText(domLog.DocumentElement, "readerBarcode"); if (String.IsNullOrEmpty(strReaderBarcode) == true) { strError = "<readerBarcode>元素值为空"; goto ERROR1; } // 读入读者记录 string strReaderXml = ""; string strOutputReaderRecPath = ""; byte[] reader_timestamp = null; nRet = this.GetReaderRecXml( // Channels, channel, strReaderBarcode, out strReaderXml, out strOutputReaderRecPath, out reader_timestamp, out strError); if (nRet == 0) { if (strAction == "repairreaderside") { strError = "读者证条码号 '" + strReaderBarcode + "' 不存在"; goto ERROR1; } // 从实体侧恢复的时候,是允许读者记录不存在的 } if (nRet == -1) { strError = "读入证条码号为 '" + strReaderBarcode + "' 的读者记录时发生错误: " + strError; goto ERROR1; } XmlDocument readerdom = null; if (string.IsNullOrEmpty(strReaderXml) == false) { nRet = LibraryApplication.LoadToDom(strReaderXml, out readerdom, out strError); if (nRet == -1) { strError = "装载读者记录进入XML DOM时发生错误: " + strError; goto ERROR1; } } // 校验读者证条码号参数是否和XML记录中完全一致 if (readerdom != null) { string strTempBarcode = DomUtil.GetElementText(readerdom.DocumentElement, "barcode"); if (strReaderBarcode != strTempBarcode) { strError = "修复操作被拒绝。因读者证条码号参数 '" + strReaderBarcode + "' 和读者记录中<barcode>元素内的读者证条码号值 '" + strTempBarcode + "' 不一致。"; goto ERROR1; } } // 读入册记录 string strConfirmItemRecPath = DomUtil.GetElementText(domLog.DocumentElement, "confirmItemRecPath"); string strItemBarcode = DomUtil.GetElementText(domLog.DocumentElement, "itemBarcode"); if (String.IsNullOrEmpty(strItemBarcode) == true) { strError = "<strItemBarcode>元素值为空"; goto ERROR1; } string strItemXml = ""; string strOutputItemRecPath = ""; byte[] item_timestamp = null; // 如果已经有确定的册记录路径 if (String.IsNullOrEmpty(strConfirmItemRecPath) == false) { string strMetaData = ""; lRet = channel.GetRes(strConfirmItemRecPath, out strItemXml, out strMetaData, out item_timestamp, out strOutputItemRecPath, out strError); if (lRet == -1) { strError = "根据strConfirmItemRecPath '" + strConfirmItemRecPath + "' 获得册记录失败: " + strError; goto ERROR1; } // 需要检查记录中的<barcode>元素值是否匹配册条码号 // TODO: 如果记录路径所表达的记录不存在,或者其<barcode>元素值和要求的册条码号不匹配,那么都要改用逻辑方法,也就是利用册条码号来获得记录。 // 当然,这种情况下,非常要紧的是确保数据库的素质很好,本身没有重条码号的情况出现。 } else { // 从册条码号获得册记录 List<string> aPath = null; // 获得册记录 // return: // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条 nRet = this.GetItemRecXml( // Channels, channel, strItemBarcode, out strItemXml, 100, out aPath, out item_timestamp, out strError); if (nRet == 0) { if (strAction == "repairitemside") { strError = "册条码号 '" + strItemBarcode + "' 不存在"; goto ERROR1; } // 从读者侧恢复的时候,册条码号不存在是允许的 goto CONTINUE_REPAIR; } if (nRet == -1) { strError = "读入册条码号为 '" + strItemBarcode + "' 的册记录时发生错误: " + strError; goto ERROR1; } if (aPath.Count > 1) { strError = "册条码号为 '" + strItemBarcode + "' 的册记录有 " + aPath.Count.ToString() + " 条,但此时comfirmItemRecPath却为空"; goto ERROR1; } else { Debug.Assert(nRet == 1, ""); Debug.Assert(aPath.Count == 1, ""); if (nRet == 1) { strOutputItemRecPath = aPath[0]; } } } CONTINUE_REPAIR: XmlDocument itemdom = null; if (string.IsNullOrEmpty(strItemXml) == false) { nRet = LibraryApplication.LoadToDom(strItemXml, out itemdom, out strError); if (nRet == -1) { strError = "装载册记录进入XML DOM时发生错误: " + strError; goto ERROR1; } // 校验册条码号参数是否和XML记录中完全一致 string strTempItemBarcode = DomUtil.GetElementText(itemdom.DocumentElement, "barcode"); if (strItemBarcode != strTempItemBarcode) { strError = "修复操作被拒绝。因册条码号参数 '" + strItemBarcode + "' 和册记录中<barcode>元素内的册条码号值 '" + strTempItemBarcode + "' 不一致。"; goto ERROR1; } } if (strAction == "repairreaderside") { XmlNode nodeBorrow = readerdom.DocumentElement.SelectSingleNode("borrows/borrow[@barcode='" + strItemBarcode + "']"); if (nodeBorrow == null) { strError = "修复操作被拒绝。读者记录 " + strReaderBarcode + " 中并不存在有关册 " + strItemBarcode + " 的借阅信息。"; goto ERROR1; } if (itemdom != null) { // 看看册记录中是否有指回读者记录的链 string strBorrower = DomUtil.GetElementText(itemdom.DocumentElement, "borrower"); if (strBorrower == strReaderBarcode) { strError = "修复操作被拒绝。您所请求要修复的链,本是一条完整正确的链。可直接进行普通还书操作。"; goto ERROR1; } } // 移除读者记录侧的链 nodeBorrow.ParentNode.RemoveChild(nodeBorrow); byte[] output_timestamp = null; string strOutputPath = ""; // 写回读者记录 lRet = channel.DoSaveTextRes(strOutputReaderRecPath, readerdom.OuterXml, false, "content,ignorechecktimestamp", reader_timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; } else if (strAction == "repairitemside") { // 看看册记录中是否有指向读者记录的链 string strBorrower = DomUtil.GetElementText(itemdom.DocumentElement, "borrower"); if (String.IsNullOrEmpty(strBorrower) == true) { strError = "修复操作被拒绝。您所请求要修复的册记录中,本来就没有借阅信息,因此谈不上修复。"; goto ERROR1; } if (strBorrower != strReaderBarcode) { strError = "修复操作被拒绝。您所请求要修复的册记录中,并没有指明借阅者是读者 " + strReaderBarcode + "。"; goto ERROR1; } // 看看读者记录中是否有指回链条。 if (readerdom != null) { XmlNode nodeBorrow = readerdom.DocumentElement.SelectSingleNode("borrows/borrow[@barcode='" + strItemBarcode + "']"); if (nodeBorrow != null) { strError = "修复操作被拒绝。您所请求要修复的链,本是一条完整正确的链。可直接进行普通还书操作。"; goto ERROR1; } } // 移除册记录侧的链 DomUtil.SetElementText(itemdom.DocumentElement, "borrower", ""); DomUtil.SetElementText(itemdom.DocumentElement, "borrowDate", ""); DomUtil.SetElementText(itemdom.DocumentElement, "borrowPeriod", ""); byte[] output_timestamp = null; string strOutputPath = ""; // 写回册记录 lRet = channel.DoSaveTextRes(strOutputItemRecPath, itemdom.OuterXml, false, "content,ignorechecktimestamp", item_timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) goto ERROR1; } else { strError = "不可识别的strAction值 '"+strAction+"'"; goto ERROR1; } return 0; } // 逻辑恢复或者混合恢复 if (level == RecoverLevel.Logic || level == RecoverLevel.LogicAndSnapshot) { // 和SnapShot方式相同 bReuse = true; goto DO_SNAPSHOT; } return 0; ERROR1: if (level == RecoverLevel.LogicAndSnapshot) { level = RecoverLevel.Snapshot; goto DO_SNAPSHOT; } return -1; }
/* <root> <operation>writeRes</operation> <requestResPath>...</requestResPath> 资源路径参数。也就是请求API是的strResPath参数值。可能在路径中的记录ID部分包含问号,表示要追加创建新的记录 <resPath>...</resPath> 资源路径。资源的确定路径。 <ranges>...</ranges> 字节范围 <totalLength>...</totalLength> 总长度 <metadata>...</metadata> 此元素的文本即是记录体,但注意为不透明的字符串(HtmlEncoding后的记录字符串)。 <style>...</style> 当 style 中包含 delete 子串时表示要删除这个资源 <operator>test</operator> <operTime>Fri, 08 Dec 2006 10:12:20 GMT</operTime> </root> * 可能会有一个attachment * * */ public int RecoverWriteRes( RmsChannelCollection Channels, RecoverLevel level, XmlDocument domLog, Stream attachmentLog, out string strError) { strError = ""; // 暂时把Robust当作Logic处理 if (level == RecoverLevel.Robust) level = RecoverLevel.Logic; long lRet = 0; // int nRet = 0; RmsChannel channel = Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } bool bReuse = false; // 是否能够不顾RecorverLevel状态而重用部分代码 DO_SNAPSHOT: // 快照恢复 if (level == RecoverLevel.Snapshot || bReuse == true) { string strResPath = DomUtil.GetElementText( domLog.DocumentElement, "resPath"); if (string.IsNullOrEmpty(strResPath) == true) { strError = "日志记录中缺<resPath>元素"; return -1; } string strRanges = DomUtil.GetElementText( domLog.DocumentElement, "ranges"); if (string.IsNullOrEmpty(strRanges) == true) { strError = "日志记录中缺<ranges>元素"; return -1; } string strTotalLength = DomUtil.GetElementText( domLog.DocumentElement, "totalLength"); if (string.IsNullOrEmpty(strTotalLength) == true) { strError = "日志记录中缺<totalLength>元素"; return -1; } long lTotalLength = 0; try { lTotalLength = Convert.ToInt64(strTotalLength); } catch { strError = "lTotalLength值 '"+strTotalLength+"' 格式不正确"; return -1; } string strMetadata = DomUtil.GetElementText( domLog.DocumentElement, "metadata"); string strStyle = DomUtil.GetElementText( domLog.DocumentElement, "style"); // 读入记录内容 byte[] baRecord = null; if (attachmentLog != null && attachmentLog.Length > 0) { baRecord = new byte[(int)attachmentLog.Length]; attachmentLog.Seek(0, SeekOrigin.Begin); attachmentLog.Read(baRecord, 0, (int)attachmentLog.Length); } strStyle += ",ignorechecktimestamp"; byte[] timestamp = null; string strOutputResPath = ""; byte[] output_timestamp = null; if (StringUtil.IsInList("delete", strStyle) == true) { // 2015/9/3 增加 lRet = channel.DoDeleteRes(strResPath, timestamp, strStyle, out output_timestamp, out strError); } else { lRet = channel.WriteRes(strResPath, strRanges, lTotalLength, baRecord, strMetadata, strStyle, timestamp, out strOutputResPath, out output_timestamp, out strError); } if (lRet == -1) { strError = "WriteRes() '" + strResPath + "' 时发生错误: " + strError; return -1; } return 0; } // 逻辑恢复或者混合恢复 if (level == RecoverLevel.Logic || level == RecoverLevel.LogicAndSnapshot) { // 和SnapShot方式相同 bReuse = true; goto DO_SNAPSHOT; } return 0; ERROR1: if (level == RecoverLevel.LogicAndSnapshot) { level = RecoverLevel.Snapshot; goto DO_SNAPSHOT; } return -1; }
/* settlement 结算违约金 API: Settlement() <root> <operation>settlement</operation> 操作类型 <action>...</action> 具体动作 有settlement undosettlement delete 3种 <id>1234567-1</id> ID <operator>test</operator> 操作者 <operTime>Fri, 08 Dec 2006 04:17:45 GMT</operTime> 操作时间 <oldAmerceRecord recPath='...'>...</oldAmerceRecord> 旧违约金记录 <amerceRecord recPath='...'>...</amerceRecord> 新违约金记录 delete操作无此元素 </root> * */ public int RecoverSettlement( RmsChannelCollection Channels, RecoverLevel level, XmlDocument domLog, out string strError) { strError = ""; // 暂时把Robust当作Logic处理 if (level == RecoverLevel.Robust) level = RecoverLevel.Logic; long lRet = 0; int nRet = 0; RmsChannel channel = Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } DO_SNAPSHOT: // 快照恢复 if (level == RecoverLevel.Snapshot) { string strAction = DomUtil.GetElementText(domLog.DocumentElement, "action"); if (strAction == "settlement" || strAction == "undosettlement") { XmlNode node = null; string strAmerceXml = DomUtil.GetElementText(domLog.DocumentElement, "amerceRecord", out node); if (node == null) { strError = "日志记录中缺<amerceRecord>元素"; return -1; } string strAmerceRecPath = DomUtil.GetAttr(node, "recPath"); byte[] timestamp = null; byte[] output_timestamp = null; string strOutputPath = ""; // 写违约金记录 lRet = channel.DoSaveTextRes(strAmerceRecPath, strAmerceXml, false, "content,ignorechecktimestamp", timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "写入违约金记录 '" + strAmerceRecPath + "' 时发生错误: " + strError; return -1; } } else if (strAction == "delete") { XmlNode node = null; string strOldAmerceXml = DomUtil.GetElementText(domLog.DocumentElement, "oldAmerceRecord", out node); if (node == null) { strError = "日志记录中缺<oldAmerceRecord>元素"; return -1; } string strOldAmerceRecPath = DomUtil.GetAttr(node, "recPath"); // 删除违约金记录 int nRedoCount = 0; byte[] timestamp = null; byte[] output_timestamp = null; REDO_DELETE: lRet = channel.DoDeleteRes(strOldAmerceRecPath, timestamp, out output_timestamp, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) return 0; // 记录本来就不存在 if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { if (nRedoCount < 10) { timestamp = output_timestamp; nRedoCount++; goto REDO_DELETE; } } strError = "删除违约金记录 '" + strOldAmerceRecPath + "' 时发生错误: " + strError; return -1; } } else { strError = "未能识别的action值 '" + strAction + "'"; } return 0; } // 逻辑恢复或者混合恢复 if (level == RecoverLevel.Logic || level == RecoverLevel.LogicAndSnapshot) { string strAction = DomUtil.GetElementText(domLog.DocumentElement, "action"); string strID = DomUtil.GetElementText(domLog.DocumentElement, "id"); /// if (String.IsNullOrEmpty(strID) == true) { strError = "日志记录中<id>元素值为空"; goto ERROR1; } string strOperator = DomUtil.GetElementText(domLog.DocumentElement, "operator"); string strOperTime = DomUtil.GetElementText(domLog.DocumentElement, "operTime"); // 通过id获得违约金记录的路径 string strText = ""; string strCount = ""; strCount = "<maxCount>100</maxCount>"; strText = "<item><word>" + StringUtil.GetXmlStringSimple(strID) + "</word>" + strCount + "<match>exact</match><relation>=</relation><dataType>string</dataType>" + "</item>"; string strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(this.AmerceDbName + ":" + "ID") // 2007/9/14 + "'>" + strText + "<lang>zh</lang></target>"; lRet = channel.DoSearch(strQueryXml, "amerced", "", // strOuputStyle out strError); if (lRet == -1) { strError = "检索ID为 '" + strID + "' 的违约金记录出错: " + strError; goto ERROR1; } if (lRet == 0) { strError = "没有找到id为 '" + strID + "' 的违约金记录"; goto ERROR1; } List<string> aPath = null; lRet = channel.DoGetSearchResult( "amerced", // strResultSetName 0, 1, "zh", null, // stop out aPath, out strError); if (lRet == -1) goto ERROR1; if (lRet == 0) { strError = "获取结果集未命中"; goto ERROR1; } if (aPath.Count != 1) { strError = "aPath.Count != 1"; goto ERROR1; } string strAmerceRecPath = aPath[0]; // 结算一个交费记录 // parameters: // bCreateOperLog 是否创建日志 // strOperTime 结算的操作时间 // strOperator 结算的操作者 // return: // -2 致命出错,不宜再继续循环调用本函数 // -1 一般出错,可以继续循环调用本函数 // 0 正常 nRet = SettlementOneRecord( "", // 确保可以执行 false, // 不创建日志 channel, strAction, strAmerceRecPath, strOperTime, strOperator, "", // 表示本机触发 out strError); if (nRet == -1 || nRet == -2) goto ERROR1; } return 0; ERROR1: if (level == RecoverLevel.LogicAndSnapshot) { level = RecoverLevel.Snapshot; goto DO_SNAPSHOT; } return -1; }
// 初始化,在打开前调用 public void Initial(ServerCollection servers, RmsChannelCollection channels) { this.resTree.Servers = servers; this.resTree.Channels = channels; }
// 检索文章 // return: // -1 error // 其他 命中数 public int Search( string strServerUrl, string strQueryXml, RmsChannelCollection Channels, string strLang, out string strError) { strError = ""; string strMessage = ""; // 加写锁 this.m_lock.AcquireWriterLock(m_nLockTimeout); try { this.File.Clear(); // 清空集合 //if (page.Response.IsClientConnected == false) // 灵敏中断 // return -1; RmsChannel channel = Channels.GetChannel(strServerUrl); Debug.Assert(channel != null, "Channels.GetChannel 异常"); strMessage += "--- begin search ...\r\n"; DateTime time = DateTime.Now; //if (page.Response.IsClientConnected == false) // 灵敏中断 // return -1; long nRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (nRet == -1) { strError = "检索时出错: " + strError; return(-1); } TimeSpan delta = DateTime.Now - time; strMessage += "search end. time=" + delta.ToString() + "\r\n"; if (nRet == 0) { return(0); // not found } long lTotalCount = nRet; //if (page.Response.IsClientConnected == false) // 灵敏中断 // return -1; strMessage += "--- begin get search result ...\r\n"; time = DateTime.Now; long lStart = 0; long lPerCount = Math.Min(lTotalCount, 1000); for (; ;) { //if (page.Response.IsClientConnected == false) // 灵敏中断 // return -1; lPerCount = Math.Min((lTotalCount - lStart), 1000); nRet = channel.DoGetSearchResult( "default", lStart, lPerCount, strLang, null, // stop, out List <string> aPath, out strError); if (nRet == -1) { strError = "检索库时出错: " + strError; return(-1); } delta = DateTime.Now - time; strMessage += "get search result end. time=" + delta.ToString() + "\r\n"; if (aPath.Count == 0) { strError = "检索库时获取的检索结果为空"; return(-1); } //if (page.Response.IsClientConnected == false) // 灵敏中断 // return -1; strMessage += "--- begin build storage ...\r\n"; time = DateTime.Now; int i; // 加入新行对象。新行对象中,只初始化了m_strRecID参数 for (i = 0; i < aPath.Count; i++) { ClientRecordItem item = new ClientRecordItem(); item.Path = (string)aPath[i]; this.File.Add(item); if ((i % 100) == 0) { strMessage += "process " + Convert.ToString(i) + "\r\n"; } } delta = DateTime.Now - time; strMessage += "build storage end. time=" + delta.ToString() + "\r\n"; lStart += aPath.Count; if (lStart >= lTotalCount) { break; } } return(1); } finally { this.m_lock.ReleaseWriterLock(); } }
// 检测管理用户是否已经存在? // return: // -1 出错 // 0 不存在 // 1 存在, 且密码一致 // 2 存在, 但密码不一致 int DetectManageUser(out string strError) { strError = ""; if (this.textBox_kernelUrl.Text == "") { strError = "尚未指定dp2Kernel服务器URL"; return -1; } if (this.textBox_manageUserName.Text == "") { strError = "尚未指定代理帐户的用户名"; return -1; } if (this.textBox_managePassword.Text != this.textBox_confirmManagePassword.Text) { strError = "代理帐户 密码 和 再次输入密码 不一致。请重新输入。"; return -1; } RmsChannelCollection channels = new RmsChannelCollection(); RmsChannel channel = channels.GetChannel(this.textBox_kernelUrl.Text); if (channel == null) { strError = "channel == null"; return -1; } // Debug.Assert(false, ""); int nRet = channel.Login(this.textBox_manageUserName.Text, this.textBox_managePassword.Text, out strError); if (nRet == -1) { strError = "以用户名 '" + this.textBox_manageUserName.Text + "' 和密码登录失败: " + strError; return -1; } channel.DoLogout(out strError); if (nRet == 0) { channels.AskAccountInfo -= new AskAccountInfoEventHandle(channels_AskAccountInfo); channels.AskAccountInfo += new AskAccountInfoEventHandle(channels_AskAccountInfo); nRet = channel.UiLogin("为确认代理帐户是否存在, 请用root用户身份登录。", "", LoginStyle.None, out strError); if (nRet == -1 || nRet == 0) { strError = "以root用户身份登录失败: " + strError + "\r\n\r\n因此无法确定代理帐户是否存在"; return -1; } string strRecPath = ""; string strXml = ""; byte[] baTimeStamp = null; // 获得用户记录 // return: // -1 error // 0 not found // >=1 检索命中的条数 nRet = GetUserRecord( channel, this.textBox_manageUserName.Text, out strRecPath, out strXml, out baTimeStamp, out strError); if (nRet == -1) { strError = "获取用户 '" + this.textBox_manageUserName.Text + "' 信息时发生错误: " + strError + "\r\n\r\n因此无法确定代理帐户是否存在。"; return -1; } if (nRet == 1) { strError = "代理帐户 '" + this.textBox_manageUserName.Text + "' 已经存在, 但其密码和当前面板拟设置的密码不一致。"; return 2; } if (nRet >= 1) { strError = "以 '" + this.textBox_manageUserName.Text + "' 为用户名 的用户记录存在多条,这是一个严重错误,请利用root身份启用dp2manager尽快修正此错误。"; return -1; } strError = "代理帐户 '" + this.textBox_manageUserName.Text + "' 不存在。"; return 0; } strError = "代理帐户 '" + this.textBox_manageUserName.Text + "' 代理帐户经检验存在。"; return 1; }
// 修改一个数据库在OPAC可检索库中的定义的名字 // return: // -1 error // 0 not change // 1 changed int RenameOpacDatabaseDef( RmsChannelCollection Channels, string strOldDatabaseName, string strNewDatabaseName, out string strError) { strError = ""; bool bChanged = false; XmlNode root = this.LibraryCfgDom.DocumentElement.SelectSingleNode("virtualDatabases"); if (root != null) { // TODO: 是否需要检查一下新名字是否已经存在了? // 虚拟成员库定义 XmlNodeList nodes = root.SelectNodes("virtualDatabase/database[@name='" + strOldDatabaseName + "']"); for (int i = 0; i < nodes.Count; i++) { XmlNode node = nodes[i]; DomUtil.SetAttr(node, "name", strNewDatabaseName); bChanged = true; } // 普通成员库定义 nodes = root.SelectNodes("database[@name='" + strOldDatabaseName + "']"); for (int i = 0; i < nodes.Count; i++) { XmlNode node = nodes[i]; DomUtil.SetAttr(node, "name", strNewDatabaseName); bChanged = true; } // 重新初始化虚拟库定义 this.vdbs = null; // 强制初始化 int nRet = this.InitialVdbs(Channels, out strError); if (nRet == -1) return -1; } root = this.LibraryCfgDom.DocumentElement.SelectSingleNode("browseformats"); if (root != null) { // 显示定义中的库名 XmlNodeList nodes = root.SelectNodes("database[@name='" + strOldDatabaseName + "']"); for (int i = 0; i < nodes.Count; i++) { XmlNode node = nodes[i]; DomUtil.SetAttr(node, "name", strNewDatabaseName); bChanged = true; } } if (bChanged == true) return 1; return 0; }
// 重设置代理帐户密码 int ResetManageUserPassword(out string strError) { strError = ""; if (this.textBox_kernelUrl.Text == "") { strError = "尚未指定dp2Kernel服务器URL"; return -1; } if (this.textBox_manageUserName.Text == "") { strError = "尚未指定代理帐户的用户名"; return -1; } if (this.textBox_managePassword.Text != this.textBox_confirmManagePassword.Text) { strError = "代理帐户 密码 和 再次输入密码 不一致。请重新输入。"; return -1; } RmsChannelCollection channels = new RmsChannelCollection(); channels.AskAccountInfo -= new AskAccountInfoEventHandle(channels_AskAccountInfo); channels.AskAccountInfo += new AskAccountInfoEventHandle(channels_AskAccountInfo); RmsChannel channel = channels.GetChannel(this.textBox_kernelUrl.Text); if (channel == null) { strError = "channel == null"; return -1; } int nRet = channel.UiLogin("请用root用户身份登录,以便重设代理帐户密码。", "", LoginStyle.None, out strError); if (nRet == -1 || nRet == 0) { strError = "以root用户身份登录失败: " + strError; return -1; } // 获得用户库名 string strRecPath = ""; string strXml = ""; byte[] baTimeStamp = null; // 查重,看这个用户名是否已经存在 // 获得用户记录 // return: // -1 error // 0 not found // >=1 检索命中的条数 nRet = GetUserRecord( channel, this.textBox_manageUserName.Text, out strRecPath, out strXml, out baTimeStamp, out strError); if (nRet == -1) { strError = "获取用户 '" + this.textBox_manageUserName.Text + "' 信息时发生错误: " + strError; return -1; } if (nRet == 0) { strError = "用户 '" + this.textBox_manageUserName.Text + "' 尚不存在,因此无法重设其密码。请直接创建。"; return -1; } if (nRet > 1) { strError = "以 '" + this.textBox_manageUserName.Text + "' 为用户名 的用户记录存在多条,这是一个严重错误,请利用root身份启用dp2manager尽快修正此错误。"; return -1; } // 修改密码 nRet = ResetUserRecordPassword(ref strXml, out strError); if (nRet == -1) { strError = "构造用户记录时发生错误: " + strError; return -1; } string strOutputPath = ""; byte[] baOutputTimeStamp; if (strRecPath == "") { Debug.Assert(false, "不可能出现的情况。"); strRecPath = Defs.DefaultUserDb.Name + "/" + "?"; } long lRet = channel.DoSaveTextRes( strRecPath, strXml, false, // bInlucdePreamble "", // style baTimeStamp, // baTimeStamp, out baOutputTimeStamp, out strOutputPath, out strError); if (lRet == -1) { strError = "保存用户记录时发生错误: " + strError; return -1; } channel.DoLogout(out strError); return 0; }
// 刷新数据库定义 // parameters: // strDatabaseInfo 要刷新的下属文件特性。<refreshStyle include="keys,browse" exclude="">(表示只刷新keys和browse两个重要配置文件)或者<refreshStyle include="*" exclude="template">(表示刷新全部文件,但是不要刷新template) 如果参数值为空,表示全部刷新 // strOutputInfo 返回keys定义发生改变的数据库名。"<keysChanged dbpaths='http://*****:*****@biblioDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的书目库(biblioDbName属性)相关<database>元素没有找到"; goto ERROR1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许刷新书目库的定义"; goto ERROR1; } string strSyntax = DomUtil.GetAttr(nodeDatabase, "syntax"); if (String.IsNullOrEmpty(strSyntax) == true) strSyntax = "unimarc"; string strUsage = ""; string strIssueDbName = DomUtil.GetAttr(nodeDatabase, "issueDbName"); if (String.IsNullOrEmpty(strIssueDbName) == true) strUsage = "book"; else strUsage = "series"; // 刷新书目库 string strTemplateDir = this.DataDir + "\\templates\\" + "biblio_" + strSyntax + "_" + strUsage; nRet = RefreshDatabase(channel, strTemplateDir, strName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新小书目库 '" + strName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strName); // 刷新实体库 string strEntityDbName = DomUtil.GetAttr(nodeDatabase, "name"); if (String.IsNullOrEmpty(strEntityDbName) == false) { strTemplateDir = this.DataDir + "\\templates\\" + "item"; nRet = RefreshDatabase(channel, strTemplateDir, strEntityDbName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新书目库 '" + strName + "' 所从属的实体库 '" + strEntityDbName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strEntityDbName); } // 刷新订购库 string strOrderDbName = DomUtil.GetAttr(nodeDatabase, "orderDbName"); if (String.IsNullOrEmpty(strOrderDbName) == false) { strTemplateDir = this.DataDir + "\\templates\\" + "order"; nRet = RefreshDatabase(channel, strTemplateDir, strOrderDbName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新书目库 '" + strName + "' 所从属的订购库 '" + strOrderDbName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strOrderDbName); } // 刷新期库 if (String.IsNullOrEmpty(strIssueDbName) == false) { strTemplateDir = this.DataDir + "\\templates\\" + "issue"; nRet = RefreshDatabase(channel, strTemplateDir, strIssueDbName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新书目库 '" + strName + "' 所从属的期库 '" + strIssueDbName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strIssueDbName); } // 刷新评注库 string strCommentDbName = DomUtil.GetAttr(nodeDatabase, "commentDbName"); if (String.IsNullOrEmpty(strCommentDbName) == false) { strTemplateDir = this.DataDir + "\\templates\\" + "comment"; nRet = RefreshDatabase(channel, strTemplateDir, strCommentDbName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新书目库 '" + strName + "' 所从属的评注库 '" + strCommentDbName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strCommentDbName); } continue; } // 单独刷新实体库 if (this.IsItemDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的实体库(name属性)相关<database>元素没有找到"; goto ERROR1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许刷新实体库的定义"; goto ERROR1; } // 刷新实体库 string strTemplateDir = this.DataDir + "\\templates\\" + "item"; nRet = RefreshDatabase(channel, strTemplateDir, strName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新实体库 '" + strName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strName); continue; } // 单独刷新订购库 if (this.IsOrderDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@orderDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的订购库(orderDbName属性)相关<database>元素没有找到"; goto ERROR1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许刷新订购库的定义"; goto ERROR1; } // 刷新订购库 string strTemplateDir = this.DataDir + "\\templates\\" + "order"; nRet = RefreshDatabase(channel, strTemplateDir, strName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新订购库 '" + strName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strName); continue; } // 单独刷新期库 if (this.IsIssueDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@issueDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的期库(issueDbName属性)相关<database>元素没有找到"; goto ERROR1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许刷新期库的定义"; goto ERROR1; } // 刷新期库 string strTemplateDir = this.DataDir + "\\templates\\" + "issue"; nRet = RefreshDatabase(channel, strTemplateDir, strName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新期库 '" + strName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strName); continue; } // 单独刷新评注库 if (this.IsCommentDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@commentDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的评注库(commentDbName属性)相关<database>元素没有找到"; goto ERROR1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许刷新评注库的定义"; goto ERROR1; } // 刷新评注库 string strTemplateDir = this.DataDir + "\\templates\\" + "comment"; nRet = RefreshDatabase(channel, strTemplateDir, strName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新评注库 '" + strName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strName); continue; } // 刷新读者库 if (this.IsReaderDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("readerdbgroup/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的读者库(name属性)相关<database>元素没有找到"; goto ERROR1; } // 2012/9/9 // 分馆用户只允许刷新属于管辖分馆的读者库 if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { string strExistLibraryCode = DomUtil.GetAttr(nodeDatabase, "libraryCode"); if (string.IsNullOrEmpty(strExistLibraryCode) == true || StringUtil.IsInList(strExistLibraryCode, strLibraryCodeList) == false) { strError = "刷新读者库 '" + strName + "' 定义被拒绝。当前用户只能刷新图书馆代码完全完全属于 '" + strLibraryCodeList + "' 范围的读者库定义"; goto ERROR1; } } // 刷新读者库 string strTemplateDir = this.DataDir + "\\templates\\" + "reader"; nRet = RefreshDatabase(channel, strTemplateDir, strName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新读者库 '" + strName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strName); continue; } // 刷新预约到书库 if (this.ArrivedDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许刷新预约到书库的定义"; goto ERROR1; } // 刷新预约到书库 string strTemplateDir = this.DataDir + "\\templates\\" + "arrived"; nRet = RefreshDatabase(channel, strTemplateDir, strName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新预约到书库 '" + strName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strName); continue; } // 刷新违约金库 if (this.AmerceDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许刷新违约金库的定义"; goto ERROR1; } // 刷新违约金库 string strTemplateDir = this.DataDir + "\\templates\\" + "amerce"; nRet = RefreshDatabase(channel, strTemplateDir, strName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新违约金库 '" + strName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strName); continue; } // 刷新发票库 if (this.InvoiceDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许刷新发票库的定义"; goto ERROR1; } // 刷新发票库 string strTemplateDir = this.DataDir + "\\templates\\" + "invoice"; nRet = RefreshDatabase(channel, strTemplateDir, strName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新发票库 '" + strName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strName); continue; } // 刷新消息库 if (this.MessageDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许刷新消息库的定义"; goto ERROR1; } // 刷新消息库 string strTemplateDir = this.DataDir + "\\templates\\" + "message"; nRet = RefreshDatabase(channel, strTemplateDir, strName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新消息库 '" + strName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strName); continue; } // 刷新实用库 if (IsUtilDbName(strName) == true) { XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("utilDb/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "不存在name属性值为 '" + strName + "' 的<utilDb/database>的元素"; goto ERROR1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许刷新实用库的定义"; goto ERROR1; } string strType = DomUtil.GetAttr(nodeDatabase, "type").ToLower(); // 刷新实用库 string strTemplateDir = this.DataDir + "\\templates\\" + strType; nRet = RefreshDatabase(channel, strTemplateDir, strName, strInclude, strExclude, out strError); if (nRet == -1) { strError = "刷新实用库 '" + strName + "' 定义时发生错误: " + strError; goto ERROR1; } if (nRet == 1) keyschanged_dbnames.Add(strName); continue; } strError = "数据库名 '" + strName + "' 不属于 dp2library 目前管辖的范围..."; goto ERROR1; } // 2015/6/13 if (keyschanged_dbnames.Count > 0) { nRet = InitialKdbs( Channels, out strError); if (nRet == -1) return -1; // 重新初始化虚拟库定义 this.vdbs = null; nRet = this.InitialVdbs(Channels, out strError); if (nRet == -1) return -1; } if (bAutoRebuildKeys == true && keyschanged_dbnames.Count > 0) { nRet = StartRebuildKeysTask(StringUtil.MakePathList(keyschanged_dbnames, ","), out strError); if (nRet == -1) return -1; } { // 增加WebServiceUrl部分 for (int i = 0; i < keyschanged_dbnames.Count; i++) { keyschanged_dbnames[i] = this.WsUrl.ToLower() + "?" + keyschanged_dbnames[i]; } XmlDocument dom = new XmlDocument(); dom.LoadXml("<keysChanged />"); DomUtil.SetAttr(dom.DocumentElement, "dbpaths", StringUtil.MakePathList(keyschanged_dbnames, ";")); strOutputInfo = dom.OuterXml; } return 0; ERROR1: if (keyschanged_dbnames.Count > 0) { // 增加WebServiceUrl部分 for (int i = 0; i < keyschanged_dbnames.Count; i++) { keyschanged_dbnames[i] = this.WsUrl.ToLower() + "?" + keyschanged_dbnames[i]; } XmlDocument dom = new XmlDocument(); dom.LoadXml("<keysChanged />"); DomUtil.SetAttr(dom.DocumentElement, "dbpaths", StringUtil.MakePathList(keyschanged_dbnames, ";")); strOutputInfo = dom.OuterXml; } return -1; }
// text-level: 内部处理 // 获得和读者通知有关的信息 int GetReaderNotifyInfo( RmsChannelCollection channels, string strReaderBarcode, out string strName, out string strReaderEmailAddress, out string strError) { strError = ""; strReaderEmailAddress = ""; strName = ""; // 读入读者记录 string strReaderXml = ""; string strOutputReaderRecPath = ""; byte[] reader_timestamp = null; int nRet = this.GetReaderRecXml( channels, strReaderBarcode, out strReaderXml, out strOutputReaderRecPath, out reader_timestamp, out strError); if (nRet == 0) { strError = "读者记录 '" + strReaderBarcode + "' 没有找到。"; return -1; } if (nRet == -1) { strError = "读入读者记录时发生错误: " + strError; return -1; } XmlDocument readerdom = null; nRet = LibraryApplication.LoadToDom(strReaderXml, out readerdom, out strError); if (nRet == -1) { strError = "装载读者记录进入XML DOM时发生错误: " + strError; return -1; } strReaderEmailAddress = DomUtil.GetElementText(readerdom.DocumentElement, "email"); strName = DomUtil.GetElementText(readerdom.DocumentElement, "name"); return 0; }
// 初始化数据库 int InitializeDatabase( RmsChannelCollection Channels, string strLibraryCodeList, string strDatabaseNames, out string strOutputInfo, out string strError) { strOutputInfo = ""; strError = ""; int nRet = 0; long lRet = 0; bool bDbNameChanged = false; // 初始化后,检索途径名等都可能被改变 RmsChannel channel = Channels.GetChannel(this.WsUrl); string[] names = strDatabaseNames.Split(new char[] { ',' }); for (int i = 0; i < names.Length; i++) { string strName = names[i].Trim(); if (String.IsNullOrEmpty(strName) == true) continue; // 书目库整体初始化,也是可以的 // TODO: 将来可以考虑单独初始化书目库而不删除组内相关库 if (this.IsBiblioDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@biblioDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的书目库(biblioDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许初始化书目库"; return -1; } // 初始化书目库 lRet = channel.DoInitialDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化小书目库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; // 初始化实体库 string strEntityDbName = DomUtil.GetAttr(nodeDatabase, "name"); if (String.IsNullOrEmpty(strEntityDbName) == false) { lRet = channel.DoInitialDB(strEntityDbName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化书目库 '" + strName + "' 所从属的实体库 '" + strEntityDbName + "' 时发生错误: " + strError; return -1; } } // 初始化订购库 string strOrderDbName = DomUtil.GetAttr(nodeDatabase, "orderDbName"); if (String.IsNullOrEmpty(strOrderDbName) == false) { lRet = channel.DoInitialDB(strOrderDbName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化书目库 '" + strName + "' 所从属的订购库 '" + strOrderDbName + "' 时发生错误: " + strError; return -1; } } // 初始化期库 string strIssueDbName = DomUtil.GetAttr(nodeDatabase, "issueDbName"); if (String.IsNullOrEmpty(strIssueDbName) == false) { lRet = channel.DoInitialDB(strIssueDbName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化书目库 '" + strName + "' 所从属的期库 '" + strIssueDbName + "' 时发生错误: " + strError; return -1; } } // 初始化评注库 string strCommentDbName = DomUtil.GetAttr(nodeDatabase, "commentDbName"); if (String.IsNullOrEmpty(strCommentDbName) == false) { lRet = channel.DoInitialDB(strCommentDbName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化书目库 '" + strName + "' 所从属的评注库 '" + strCommentDbName + "' 时发生错误: " + strError; return -1; } } continue; } // 单独初始化实体库 if (this.IsItemDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的实体库(name属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许初始化实体库"; return -1; } // 初始化实体库 lRet = channel.DoInitialDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化实体库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; continue; } // 单独初始化订购库 if (this.IsOrderDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@orderDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的订购库(orderDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许初始化订购库"; return -1; } // 初始化订购库 lRet = channel.DoInitialDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化订购库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; continue; } // 单独初始化期库 if (this.IsIssueDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@issueDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的期库(issueDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许初始化期库"; return -1; } // 初始化期库 lRet = channel.DoInitialDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化期库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; continue; } // 单独初始化评注库 if (this.IsCommentDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("itemdbgroup/database[@commentDbName='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的评注库(commentDbName属性)相关<database>元素没有找到"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许初始化评注库"; return -1; } // 初始化评注库 lRet = channel.DoInitialDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化评注库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; continue; } // 初始化读者库 if (this.IsReaderDbName(strName) == true) { // 获得相关配置小节 XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("readerdbgroup/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "配置DOM中名字为 '" + strName + "' 的读者库(name属性)相关<database>元素没有找到"; return -1; } // 2012/9/9 // 分馆用户只允许初始化属于管辖分馆的读者库 if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { string strExistLibraryCode = DomUtil.GetAttr(nodeDatabase, "libraryCode"); if (string.IsNullOrEmpty(strExistLibraryCode) == true || StringUtil.IsInList(strExistLibraryCode, strLibraryCodeList) == false) { strError = "初始化读者库 '" + strName + "' 被拒绝。当前用户只能初始化图书馆代码完全完全属于 '" + strLibraryCodeList + "' 范围的读者库"; return -1; } } // 初始化读者库 lRet = channel.DoInitialDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化读者库 '" + strName + "' 时发生错误: " + strError; return -1; } bDbNameChanged = true; continue; } // 初始化预约到书库 if (this.ArrivedDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许初始化预约到书库"; return -1; } // 初始化预约到书库 lRet = channel.DoInitialDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化预约到书库 '" + strName + "' 时发生错误: " + strError; return -1; } continue; } // 初始化违约金库 if (this.AmerceDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许初始化违约金库"; return -1; } // 初始化违约金库 lRet = channel.DoInitialDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化违约金库 '" + strName + "' 时发生错误: " + strError; return -1; } continue; } // 初始化发票库 if (this.InvoiceDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许初始化发票库"; return -1; } // 初始化发票库 lRet = channel.DoInitialDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化发票库 '" + strName + "' 时发生错误: " + strError; return -1; } continue; } // 初始化消息库 if (this.MessageDbName == strName) { if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许初始化消息库"; return -1; } // 初始化消息库 lRet = channel.DoInitialDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化消息库 '" + strName + "' 时发生错误: " + strError; return -1; } continue; } // 初始化实用库 if (IsUtilDbName(strName) == true) { XmlNode nodeDatabase = this.LibraryCfgDom.DocumentElement.SelectSingleNode("utilDb/database[@name='" + strName + "']"); if (nodeDatabase == null) { strError = "不存在name属性值为 '" + strName + "' 的<utilDb/database>的元素"; return -1; } if (SessionInfo.IsGlobalUser(strLibraryCodeList) == false) { strError = "当前用户不是全局用户,不允许初始化实用库"; return -1; } // 初始化实用库 lRet = channel.DoInitialDB(strName, out strError); if (lRet == -1 && channel.ErrorCode != ChannelErrorCode.NotFound) { strError = "初始化实用库 '" + strName + "' 时发生错误: " + strError; return -1; } continue; } strError = "数据库名 '" + strName + "' 不属于 dp2library 目前管辖的范围..."; return -1; } if (bDbNameChanged == true) { nRet = InitialKdbs( Channels, out strError); if (nRet == -1) return -1; /* // 重新初始化虚拟库定义 this.vdbs = null; nRet = this.InitialVdbs(Channels, out strError); if (nRet == -1) return -1; * */ } return 0; }
/// <summary> /// 检索实用库 /// </summary> /// <param name="Channels"></param> /// <param name="strServerUrl"></param> /// <param name="strDbName"></param> /// <param name="strFrom"></param> /// <param name="strKey"></param> /// <param name="strXml"></param> /// <param name="strError"></param> /// <returns></returns> public static int SearchUtilDb( RmsChannelCollection Channels, string strServerUrl, string strDbName, string strFrom, string strKey, out string strXml, out string strError) { strError = ""; strXml = ""; RmsChannel channel = Channels.GetChannel(strServerUrl); if (channel == null) { strError = "get channel error"; return -1; } string[] paths = null; int nRet = SearchPath(channel, strDbName, strFrom, strKey, 1, out paths, out strError); if (nRet == -1) return -1; if (nRet == 0) return 0; string strPath = paths[0]; // 取记录 string strStyle = "content,data,timestamp"; string strMetaData; string strOutputPath; byte[] baTimeStamp = null; long lRet = channel.GetRes(strPath, strStyle, out strXml, out strMetaData, out baTimeStamp, out strOutputPath, out strError); if (lRet == -1) { strError = "检索 '" + strPath + "' 记录体时出错: " + strError; return -1; } return 1; }
// 管理数据库 // parameters: // strLibraryCodeList 当前用户的管辖分馆代码列表 // strAction 动作。getinfo create delete change initialize backup refresh public int ManageDatabase( RmsChannelCollection Channels, string strLibraryCodeList, string strAction, string strDatabaseNames, string strDatabaseInfo, out string strOutputInfo, out string strError) { strOutputInfo = ""; strError = ""; // 列出数据库名 if (strAction == "getinfo") { return GetDatabaseInfo( strLibraryCodeList, strDatabaseNames, out strOutputInfo, out strError); } // 创建数据库 if (strAction == "create") { return CreateDatabase( Channels, strLibraryCodeList, // strDatabaseNames, strDatabaseInfo, false, out strOutputInfo, out strError); } // 重新创建数据库 if (strAction == "recreate") { return CreateDatabase( Channels, strLibraryCodeList, // strDatabaseNames, strDatabaseInfo, true, out strOutputInfo, out strError); } // 删除数据库 if (strAction == "delete") { return DeleteDatabase( Channels, strLibraryCodeList, strDatabaseNames, out strOutputInfo, out strError); } if (strAction == "initialize") { return InitializeDatabase( Channels, strLibraryCodeList, strDatabaseNames, out strOutputInfo, out strError); } // 2008/11/16 if (strAction == "refresh") { return RefreshDatabaseDefs( Channels, strLibraryCodeList, strDatabaseNames, strDatabaseInfo, out strOutputInfo, out strError); } // 修改数据库 if (strAction == "change") { return ChangeDatabase( Channels, strLibraryCodeList, strDatabaseNames, strDatabaseInfo, out strOutputInfo, out strError); } strError = "未知的strAction值 '" + strAction + "'"; return -1; }
// TODO: 检查boxtype // 装入一个信箱的信息 public int LoadBox( RmsChannelCollection Channels, string strUserID, string strBoxType, out string strError) { // 首先默认控件的当前信箱 if (String.IsNullOrEmpty(strBoxType) == true) strBoxType = this.CurrentBoxType; // 若还是空, 则默认INBOX if (String.IsNullOrEmpty(strBoxType) == true) strBoxType = MessageCenter.INBOX; string strResultSetName = "messagelist_" + strBoxType; int nTotalCount = 0; List<MessageData> messages = null; int nRet = this.MessageCenter.GetMessage( Channels, strResultSetName, "search", // true, strUserID, strBoxType, MessageLevel.Summary, 0, 0, out nTotalCount, out messages, out strError); if (nRet == -1) { return -1; } this.ResultSetName = strResultSetName; this.ResultCount = nTotalCount; this.CurrentBoxType = strBoxType; /* this.CurrentBoxUntouchedCount = 0; // 获得信箱未读消息数 if (nTotalCount != 0) { int nUntouched = this.MessageCenter.GetUntouchedMessageCount( Channels, strUserID, strBox, out strError); if (nUntouched == -1) { return -1; } this.CurrentBoxUntouchedCount = nUntouched; } * */ return 0; }
public int Initial(ServerCollection servers, RmsChannelCollection channels, DigitalPlatform.StopManager stopManager, string serverUrl, out string strError) { this.Servers = servers; this.Channels = channels; this.stopManager = stopManager; this.ServerUrl = serverUrl; strError = ""; int nRet = Fill(this.Lang, out strError); if (nRet == -1) return -1; return 0; }
/// <summary> /// 检索实用库 /// </summary> /// <param name="Channels"></param> /// <param name="strServerUrl"></param> /// <param name="strDbName"></param> /// <param name="strFrom"></param> /// <param name="strKey"></param> /// <param name="strValueAttrName"></param> /// <param name="strValue"></param> /// <param name="strError"></param> /// <returns></returns> public static int SearchUtilDb( RmsChannelCollection Channels, string strServerUrl, string strDbName, string strFrom, string strKey, string strValueAttrName, out string strValue, out string strError) { strError = ""; strValue = ""; string strPath = ""; RmsChannel channel = Channels.GetChannel(strServerUrl); if (channel == null) { strError = "get channel error"; return -1; } int nRet = SearchOnePath(channel, strDbName, strFrom, strKey, out strPath, out strError); if (nRet == -1) return -1; if (nRet == 0) return 0; // 取记录 string strStyle = "content,data,timestamp"; string strMetaData; string strOutputPath; string strXml = ""; byte[] baTimeStamp = null; long lRet = channel.GetRes(strPath, strStyle, out strXml, out strMetaData, out baTimeStamp, out strOutputPath, out strError); if (lRet == -1) { strError = "检索 '" + strPath + "' 记录体时出错: " + strError; return -1; } XmlDocument domRecord = new XmlDocument(); try { domRecord.LoadXml(strXml); } catch (Exception ex) { strError = "装载路径为'" + strPath + "'的xml记录时出错: " + ex.Message; return -1; } strValue = DomUtil.GetAttr(domRecord.DocumentElement, strValueAttrName); return 1; }
// SetBiblioInfo() API 或CopyBiblioInfo() API 的恢复动作 // 函数内,使用return -1;还是goto ERROR1; 要看错误发生的时候,是否还有价值继续探索SnapShot重试。如果是,就用后者。 /* <root> <operation>setBiblioInfo</operation> <action>...</action> 具体动作 有 new/change/delete/onlydeletebiblio/onlydeletesubrecord 和 onlycopybiblio/onlymovebiblio/copy/move <record recPath='中文图书/3'>...</record> 记录体 动作为new/change/ *move* / *copy* 时具有此元素(即delete时没有此元素) <oldRecord recPath='中文图书/3'>...</oldRecord> 被覆盖、删除或者移动的记录 动作为change/ *delete* / *move* / *copy* 时具备此元素 <deletedEntityRecords> 被删除的实体记录(容器)。只有当<action>为delete时才有这个元素。 <record recPath='中文图书实体/100'>...</record> 这个元素可以重复。注意元素内文本内容目前为空。 ... </deletedEntityRecords> <copyEntityRecords> 被复制的实体记录(容器)。只有当<action>为*copy*时才有这个元素。 <record recPath='中文图书实体/100' targetRecPath='中文图书实体/110'>...</record> 这个元素可以重复。注意元素内文本内容目前为空。recPath属性为源记录路径,targetRecPath为目标记录路径 ... </copyEntityRecords> <moveEntityRecords> 被移动的实体记录(容器)。只有当<action>为*move*时才有这个元素。 <record recPath='中文图书实体/100' targetRecPath='中文图书实体/110'>...</record> 这个元素可以重复。注意元素内文本内容目前为空。recPath属性为源记录路径,targetRecPath为目标记录路径 ... </moveEntityRecords> <copyOrderRecords /> <moveOrderRecords /> <copyIssueRecords /> <moveIssueRecords /> <copyCommentRecords /> <moveCommentRecords /> <operator>test</operator> <operTime>Fri, 08 Dec 2006 10:12:20 GMT</operTime> </root> 逻辑恢复delete操作的时候,检索出全部下属的实体记录删除。 快照恢复的时候,可以根据operlogdom直接删除记录了path的那些实体记录 * */ public int RecoverSetBiblioInfo( RmsChannelCollection Channels, RecoverLevel level, XmlDocument domLog, out string strError) { strError = ""; // 暂时把Robust当作Logic处理 if (level == RecoverLevel.Robust) level = RecoverLevel.Logic; long lRet = 0; int nRet = 0; RmsChannel channel = Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; return -1; } bool bReuse = false; // 是否能够不顾RecorverLevel状态而重用部分代码 DO_SNAPSHOT: string strAction = DomUtil.GetElementText(domLog.DocumentElement, "action"); // 快照恢复 if (level == RecoverLevel.Snapshot || bReuse == true) { byte[] timestamp = null; byte[] output_timestamp = null; string strOutputPath = ""; if (strAction == "new" || strAction == "change") { XmlNode node = null; string strRecord = DomUtil.GetElementText(domLog.DocumentElement, "record", out node); if (node == null) { strError = "日志记录中缺<record>元素"; goto ERROR1; } string strRecPath = DomUtil.GetAttr(node, "recPath"); // 写书目记录 lRet = channel.DoSaveTextRes(strRecPath, strRecord, false, "content,ignorechecktimestamp", timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "写入书目记录 '" + strRecPath + "' 时发生错误: " + strError; return -1; } } else if (strAction == "onlymovebiblio" || strAction == "onlycopybiblio" || strAction == "move" || strAction == "copy") { XmlNode node = null; string strTargetRecord = DomUtil.GetElementText(domLog.DocumentElement, "record", out node); if (node == null) { strError = "日志记录中缺<record>元素"; goto ERROR1; } string strTargetRecPath = DomUtil.GetAttr(node, "recPath"); string strOldRecord = DomUtil.GetElementText(domLog.DocumentElement, "oldRecord", out node); if (node == null) { strError = "日志记录中缺<oldRecord>元素"; return -1; } string strOldRecPath = DomUtil.GetAttr(node, "recPath"); string strMergeStyle = DomUtil.GetElementText(domLog.DocumentElement, "mergeStyle"); bool bSourceExist = true; // 观察源记录是否存在 { string strMetaData = ""; string strXml = ""; byte[] temp_timestamp = null; lRet = channel.GetRes(strOldRecPath, out strXml, out strMetaData, out temp_timestamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) { bSourceExist = false; } } } if (bSourceExist == true) { string strIdChangeList = ""; // 复制书目记录 lRet = channel.DoCopyRecord(strOldRecPath, strTargetRecPath, strAction == "onlymovebiblio" ? true : false, // bDeleteSourceRecord strMergeStyle, out strIdChangeList, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "DoCopyRecord() error :" + strError; goto ERROR1; } } /* // 写书目记录 lRet = channel.DoSaveTextRes(strRecPath, strRecord, false, "content,ignorechecktimestamp", timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "复制书目记录 '" + strOldRecPath + "' 到 '" + strTargetRecPath + "' 时发生错误: " + strError; return -1; } * */ if (bSourceExist == false) { if (String.IsNullOrEmpty(strTargetRecord) == true) { if (String.IsNullOrEmpty(strOldRecord) == true) { strError = "源记录 '" + strOldRecPath + "' 不存在,并且<record>元素无文本内容,这时<oldRecord>元素也无文本内容,无法获得要写入的记录内容"; return -1; } strTargetRecord = strOldRecord; } } // 如果有“新记录”内容 if (String.IsNullOrEmpty(strTargetRecord) == false) { // 写书目记录 lRet = channel.DoSaveTextRes(strTargetRecPath, strTargetRecord, false, "content,ignorechecktimestamp", timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "写书目记录 '" + strTargetRecPath + "' 时发生错误: " + strError; return -1; } } // 复制或者移动下级子纪录 if (strAction == "move" || strAction == "copy") { string[] element_names = new string[] { "copyEntityRecords", "moveEntityRecords", "copyOrderRecords", "moveOrderRecords", "copyIssueRecords", "moveIssueRecords", "copyCommentRecords", "moveCommentRecords" }; for (int i = 0; i < element_names.Length; i++) { XmlNode node_subrecords = domLog.DocumentElement.SelectSingleNode( element_names[i]); if (node_subrecords != null) { nRet = CopySubRecords( channel, node_subrecords, strTargetRecPath, out strError); if (nRet == -1) return -1; } } } // 2011/12/12 if (bSourceExist == true && (strAction == "move" || strAction == "onlymovebiblio") ) { int nRedoCount = 0; REDO_DELETE: // 删除源书目记录 lRet = channel.DoDeleteRes(strOldRecPath, timestamp, out output_timestamp, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) { // 记录本来就不存在 } else if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { if (nRedoCount < 10) { timestamp = output_timestamp; nRedoCount++; goto REDO_DELETE; } } else { strError = "删除书目记录 '" + strOldRecPath + "' 时发生错误: " + strError; return -1; } } } } else if (strAction == "delete" || strAction == "onlydeletebiblio" || strAction == "onlydeletesubrecord") { XmlNode node = null; string strOldRecord = DomUtil.GetElementText(domLog.DocumentElement, "oldRecord", out node); if (node == null) { strError = "日志记录中缺<oldRecord>元素"; return -1; } string strRecPath = DomUtil.GetAttr(node, "recPath"); if (strAction != "onlydeletesubrecord") { int nRedoCount = 0; REDO: // 删除书目记录 lRet = channel.DoDeleteRes(strRecPath, timestamp, out output_timestamp, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) goto DO_DELETE_CHILD_ENTITYRECORDS; // 记录本来就不存在 if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { if (nRedoCount < 10) { timestamp = output_timestamp; nRedoCount++; goto REDO; } } strError = "删除书目记录 '" + strRecPath + "' 时发生错误: " + strError; return -1; } } DO_DELETE_CHILD_ENTITYRECORDS: if (strAction == "delete" || strAction == "onlydeletesubrecord") { XmlNodeList nodes = domLog.DocumentElement.SelectNodes("deletedEntityRecords/record"); for (int i = 0; i < nodes.Count; i++) { string strEntityRecPath = DomUtil.GetAttr(nodes[i], "recPath"); /* if (String.IsNullOrEmpty(strEntityRecPath) == true) continue; * */ int nRedoDeleteCount = 0; REDO_DELETE_ENTITY: // 删除实体记录 lRet = channel.DoDeleteRes(strEntityRecPath, timestamp, out output_timestamp, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) continue; // 记录本来就不存在 if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { if (nRedoDeleteCount < 10) { timestamp = output_timestamp; nRedoDeleteCount++; goto REDO_DELETE_ENTITY; } } strError = "删除实体记录 '" + strEntityRecPath + "' 时发生错误: " + strError; return -1; } } nodes = domLog.DocumentElement.SelectNodes("deletedOrderRecords/record"); for (int i = 0; i < nodes.Count; i++) { string strOrderRecPath = DomUtil.GetAttr(nodes[i], "recPath"); if (String.IsNullOrEmpty(strOrderRecPath) == true) continue; int nRedoDeleteCount = 0; REDO_DELETE_ORDER: // 删除订购记录 lRet = channel.DoDeleteRes(strOrderRecPath, timestamp, out output_timestamp, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) continue; // 记录本来就不存在 if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { if (nRedoDeleteCount < 10) { timestamp = output_timestamp; nRedoDeleteCount++; goto REDO_DELETE_ORDER; } } strError = "删除订购记录 '" + strOrderRecPath + "' 时发生错误: " + strError; return -1; } } nodes = domLog.DocumentElement.SelectNodes("deletedIssueRecords/record"); for (int i = 0; i < nodes.Count; i++) { string strIssueRecPath = DomUtil.GetAttr(nodes[i], "recPath"); if (String.IsNullOrEmpty(strIssueRecPath) == true) continue; int nRedoDeleteCount = 0; REDO_DELETE_ISSUE: // 删除期记录 lRet = channel.DoDeleteRes(strIssueRecPath, timestamp, out output_timestamp, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) continue; // 记录本来就不存在 if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { if (nRedoDeleteCount < 10) { timestamp = output_timestamp; nRedoDeleteCount++; goto REDO_DELETE_ISSUE; } } strError = "删除期记录 '" + strIssueRecPath + "' 时发生错误: " + strError; return -1; } } } // end if } return 0; } // 逻辑恢复或者混合恢复 if (level == RecoverLevel.Logic || level == RecoverLevel.LogicAndSnapshot) { // 和数据库中已有记录合并,然后保存 if (strAction == "new" || strAction == "change") { // 和SnapShot方式相同 bReuse = true; goto DO_SNAPSHOT; } else if (strAction == "onlymovebiblio" || strAction == "onlycopybiblio" || strAction == "move" || strAction == "copy") { // 和SnapShot方式相同 bReuse = true; goto DO_SNAPSHOT; } else if (strAction == "delete" || strAction == "onlydeletebiblio" || strAction == "onlydeletesubrecord") { XmlNode node = null; string strOldRecord = DomUtil.GetElementText(domLog.DocumentElement, "oldRecord", out node); if (node == null) { strError = "日志记录中缺<oldRecord>元素"; return -1; } string strRecPath = DomUtil.GetAttr(node, "recPath"); if (strAction != "onlydeletesubrecord") { int nRedoCount = 0; byte[] timestamp = null; byte[] output_timestamp = null; REDO: // 删除书目记录 lRet = channel.DoDeleteRes(strRecPath, timestamp, out output_timestamp, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) goto DO_DELETE_CHILD_ENTITYRECORDS; // 记录本来就不存在 if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { if (nRedoCount < 10) { timestamp = output_timestamp; nRedoCount++; goto REDO; } } strError = "删除书目记录 '" + strRecPath + "' 时发生错误: " + strError; goto ERROR1; } } DO_DELETE_CHILD_ENTITYRECORDS: if (strAction == "delete" || strAction == "onlydeletesubrecord") { // 删除属于同一书目记录的全部实体记录 // return: // -1 error // 0 没有找到属于书目记录的任何实体记录,因此也就无从删除 // >0 实际删除的实体记录数 nRet = DeleteBiblioChildEntities(channel, strRecPath, null, out strError); if (nRet == -1) { strError = "删除书目记录 '" + strRecPath + "' 下属的实体记录时出错: " + strError; goto ERROR1; } // return: // -1 error // 0 没有找到属于书目记录的任何实体记录,因此也就无从删除 // >0 实际删除的实体记录数 nRet = this.OrderItemDatabase.DeleteBiblioChildItems( // Channels, channel, strRecPath, null, out strError); if (nRet == -1) { strError = "删除书目记录 '" + strRecPath + "' 下属的订购记录时出错: " + strError; goto ERROR1; } // return: // -1 error // 0 没有找到属于书目记录的任何实体记录,因此也就无从删除 // >0 实际删除的实体记录数 nRet = this.IssueItemDatabase.DeleteBiblioChildItems( // Channels, channel, strRecPath, null, out strError); if (nRet == -1) { strError = "删除书目记录 '" + strRecPath + "' 下属的期记录时出错: " + strError; goto ERROR1; } } } else { strError = "无法识别的<action>内容 '" + strAction + "'"; return -1; } } return 0; ERROR1: if (level == RecoverLevel.LogicAndSnapshot) { level = RecoverLevel.Snapshot; goto DO_SNAPSHOT; } return -1; }
/// <summary> /// 写入实用库 /// </summary> /// <param name="Channels"></param> /// <param name="strServerUrl"></param> /// <param name="strDbName"></param> /// <param name="strFrom"></param> /// <param name="strRootElementName"></param> /// <param name="strKeyAttrName"></param> /// <param name="strValueAttrName"></param> /// <param name="strKey"></param> /// <param name="strValue"></param> /// <param name="strError"></param> /// <returns></returns> public static int WriteUtilDb( RmsChannelCollection Channels, string strServerUrl, string strDbName, string strFrom, string strRootElementName, string strKeyAttrName, string strValueAttrName, string strKey, string strValue, out string strError) { strError = ""; string strPath = ""; RmsChannel channel = Channels.GetChannel(strServerUrl); if (channel == null) { strError = "get channel error"; return -1; } int nRet = SearchOnePath(channel, strDbName, strFrom, strKey, out strPath, out strError); if (nRet == -1) return -1; string strXml = ""; if (nRet == 0) { strPath = strDbName + "/?"; strXml = "<" + strRootElementName + " " + strKeyAttrName + "='" + strKey + "' " + strValueAttrName + "='" + strValue + "'/>"; //bNewRecord = true; } else { string strPartXml = "/xpath/<locate>@" + strValueAttrName + "</locate><create>@" + strValueAttrName + "</create>"; strPath += strPartXml; strXml = strValue; //bNewRecord = false; } byte[] baTimestamp = null; byte[] baOutputTimeStamp = null; string strOutputPath = ""; REDO: channel = Channels.GetChannel(strServerUrl); if (channel == null) { strError = "get channel error"; return -1; } long lRet = channel.DoSaveTextRes(strPath, strXml, false, // bInlucdePreamble "ignorechecktimestamp", // style baTimestamp, out baOutputTimeStamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { baTimestamp = baOutputTimeStamp; goto REDO; } return -1; } return 1; }
// 检索文章 // return: // -1 error // 其他 命中数 public int Search( string strServerUrl, string strQueryXml, RmsChannelCollection Channels, string strLang, out string strError) { strError = ""; string strMessage = ""; // 加写锁 this.m_lock.AcquireWriterLock(m_nLockTimeout); try { this.File.Clear(); // 清空集合 //if (page.Response.IsClientConnected == false) // 灵敏中断 // return -1; RmsChannel channel = Channels.GetChannel(strServerUrl); Debug.Assert(channel != null, "Channels.GetChannel 异常"); strMessage += "--- begin search ...\r\n"; DateTime time = DateTime.Now; //if (page.Response.IsClientConnected == false) // 灵敏中断 // return -1; long nRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (nRet == -1) { strError = "检索时出错: " + strError; return -1; } TimeSpan delta = DateTime.Now - time; strMessage += "search end. time="+delta.ToString()+"\r\n"; if (nRet == 0) return 0; // not found long lTotalCount = nRet; //if (page.Response.IsClientConnected == false) // 灵敏中断 // return -1; strMessage += "--- begin get search result ...\r\n"; time = DateTime.Now; long lStart = 0; long lPerCount = Math.Min(lTotalCount, 1000); for(;;) { //if (page.Response.IsClientConnected == false) // 灵敏中断 // return -1; List<string> aPath = null; lPerCount = Math.Min((lTotalCount - lStart), 1000); nRet = channel.DoGetSearchResult( "default", lStart, lPerCount, strLang, null, // stop, out aPath, out strError); if (nRet == -1) { strError = "检索库时出错: " + strError; return -1; } delta = DateTime.Now - time; strMessage += "get search result end. time="+delta.ToString()+"\r\n"; if (aPath.Count == 0) { strError = "检索库时获取的检索结果为空"; return -1; } //if (page.Response.IsClientConnected == false) // 灵敏中断 // return -1; strMessage += "--- begin build storage ...\r\n"; time = DateTime.Now; int i; // 加入新行对象。新行对象中,只初始化了m_strRecID参数 for(i=0;i<aPath.Count;i++) { ClientRecordItem item = new ClientRecordItem(); item.Path = (string)aPath[i]; this.File.Add(item); if ((i % 100) == 0) { strMessage += "process " + Convert.ToString(i)+ "\r\n"; } } delta = DateTime.Now - time; strMessage += "build storage end. time="+delta.ToString()+"\r\n"; lStart += aPath.Count; if (lStart >= lTotalCount) break; } return 1; } finally { this.m_lock.ReleaseWriterLock(); } }