// 根据数据库定义文件,创建若干数据库 // 注: 如果发现同名数据库已经存在,先删除再创建 // parameters: // strTempDir 临时目录路径。调用前要创建好这个临时目录。调用后需要删除这个临时目录 public static int CreateDatabases( Stop stop, RmsChannel channel, string strDbDefFileName, string strTempDir, out string strError) { strError = ""; int nRet = 0; // 展开压缩文件 if (stop != null) { stop.SetMessage("正在展开压缩文件 " + strDbDefFileName); } try { using (ZipFile zip = ZipFile.Read(strDbDefFileName)) { foreach (ZipEntry e in zip) { Debug.WriteLine(e.ToString()); e.Extract(strTempDir, ExtractExistingFileAction.OverwriteSilently); } } } catch (Exception ex) { strError = "展开压缩文件 '" + strDbDefFileName + "' 到目录 '" + strTempDir + "' 时出现异常: " + ExceptionUtil.GetAutoText(ex); return(-1); } DirectoryInfo di = new DirectoryInfo(strTempDir); DirectoryInfo[] dis = di.GetDirectories(); int i = 0; foreach (DirectoryInfo info in dis) { // 跳过 '_datadir' if (info.Name == "_datadir") { continue; } string strTemplateDir = Path.Combine(info.FullName, "cfgs"); string strDatabaseName = info.Name; // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = DatabaseUtility.IsDatabaseExist( channel, strDatabaseName, out strError); if (nRet == -1) { return(-1); } if (nRet == 1) { if (stop != null) { stop.SetMessage("正在删除数据库 " + strDatabaseName); } // 如果发现同名数据库已经存在,先删除 long lRet = channel.DoDeleteDB(strDatabaseName, out strError); if (lRet == -1) { if (channel.ErrorCode != ChannelErrorCode.NotFound) { return(-1); } } } if (stop != null) { stop.SetMessage("正在创建数据库 " + strDatabaseName + " (" + (i + 1) + ")"); } // 根据数据库模板的定义,创建一个数据库 // parameters: // strTempDir 将创建数据库过程中,用到的配置文件会自动汇集拷贝到此目录。如果 == null,则不拷贝 nRet = DatabaseUtility.CreateDatabase(channel, strTemplateDir, strDatabaseName, null, out strError); if (nRet == -1) { return(-1); } i++; } return(0); }
// 获得用户记录 // return: // -1 error // 0 not found // >=1 检索命中的条数 public static int GetUserRecord( RmsChannel channel, string strUserName, out string strRecPath, out string strXml, out byte[] baTimeStamp, out string strError) { strError = ""; strXml = ""; strRecPath = ""; baTimeStamp = null; if (strUserName == "") { strError = "用户名为空"; return -1; } string strQueryXml = "<target list='" + Defs.DefaultUserDb.Name + ":" + Defs.DefaultUserDb.SearchPath.UserName + "'><item><word>" + strUserName + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>10</maxCount></item><lang>chi</lang></target>"; long nRet = channel.DoSearch(strQueryXml, "default", "", // strOutputStyle out strError); if (nRet == -1) { strError = "检索帐户库时出错: " + strError; return -1; } if (nRet == 0) return 0; // not found long nSearchCount = nRet; List<string> aPath = null; nRet = channel.DoGetSearchResult( "default", 1, "zh", null, // stop, out aPath, out strError); if (nRet == -1) { strError = "检索注册用户库获取检索结果时出错: " + strError; return -1; } if (aPath.Count == 0) { strError = "检索注册用户库获取的检索结果为空"; return -1; } // strRecID = ResPath.GetRecordId((string)aPath[0]); strRecPath = (string)aPath[0]; string strStyle = "content,data,timestamp,withresmetadata"; string strMetaData; string strOutputPath; nRet = channel.GetRes((string)aPath[0], strStyle, out strXml, out strMetaData, out baTimeStamp, out strOutputPath, out strError); if (nRet == -1) { strError = "获取注册用户库记录体时出错: " + strError; return -1; } return (int)nSearchCount; }
private void button_OK_Click(object sender, System.EventArgs e) { string strMetaData = ""; // TODO: 一旦遇到问题,可以放开注释试验 // this.textBox_content.Text = RemoveSingle0a(this.textBox_content.Text); if (this.Obj != null) { if (this.IsText == true) { byte[] baContent = StringUtil.GetUtf8Bytes(this.textBox_content.Text, true); this.Obj.Content = baContent; } else { if (this.Stream != null) { this.Obj.Content = new byte[this.Stream.Length]; this.Stream.Seek(0, SeekOrigin.Begin); this.Stream.Read(this.Obj.Content, 0, (int)this.Stream.Length); } else { this.Obj.Content = null; } } StringUtil.ChangeMetaData(ref strMetaData, null, // string strID, this.LocalPath, // string strLocalPath, this.Mime, // string strMimeType, null, // string strLastModified, null, // string strPath, null); // string strTimestamp) this.Obj.Metadata = strMetaData; this.Obj.Changed = true; this.DialogResult = DialogResult.OK; this.Close(); return; } this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在保存配置文件: " + this.Path); stop.BeginLoop(); } if (this.IsText == true) { // 更新stream对象内容 byte[] baContent = StringUtil.GetUtf8Bytes(this.textBox_content.Text, true); this.Stream = new MemoryStream(baContent); // !!! 什么时候释放? /* * this.Stream.SetLength(0); * StreamWriter sw = new StreamWriter(this.Stream, Encoding.UTF8); * sw.Write(this.textBox_content.Text); */ } if (this.Stream != null) { this.Stream.Seek(0, SeekOrigin.Begin); } // 保存配置文件 string strError = ""; byte[] baOutputTimestamp = null; string strOutputPath = ""; string strStyle = ""; if (this.checkBox_autoCreate.Checked == true) { if (strStyle != "") { strStyle += ","; } strStyle += "autocreatedir"; } StringUtil.ChangeMetaData(ref strMetaData, null, // string strID, this.LocalPath, // string strLocalPath, this.Mime, // string strMimeType, null, // string strLastModified, null, // string strPath, null); // string strTimestamp) string strRange = ""; if (this.Stream != null && this.Stream.Length != 0) { Debug.Assert(this.Stream.Length != 0, "test"); strRange = "0-" + Convert.ToString(this.Stream.Length - 1); } long lRet = channel.DoSaveResObject(this.Path, this.Stream, (this.Stream != null && this.Stream.Length != 0) ? this.Stream.Length : 0, strStyle, strMetaData, // strMetadata, strRange, true, this.TimeStamp, // timestamp, out baOutputTimestamp, out strOutputPath, out strError); /* * // 保存配置文件 * byte[] baOutputTimeStamp = null; * string strOutputPath = ""; * string strError = ""; * * * long lRet = channel.DoSaveTextRes(this.Path, * this.textBox_content.Text, * true, // bInlucdePreamble * "", // style * this.TimeStamp, * out baOutputTimeStamp, * out strOutputPath, * out strError); */ if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); } if (lRet == -1) { MessageBox.Show(this, strError); goto FINISH; } this.TimeStamp = baOutputTimestamp; MessageBox.Show(this, "配置文件 '" + this.Path + "' 保存成功"); ///////////// FINISH: if (stopManager != null && stop != null) { stop.Unregister(); // 和容器关联 stop = null; } this.channel = null; this.DialogResult = DialogResult.OK; this.Close(); }
protected override void Render(HtmlTextWriter output) { int nRet = 0; long lRet = 0; string strError = ""; string strOutputPath = ""; string strItemXml = ""; LibraryApplication app = (LibraryApplication)this.Page.Application["app"]; SessionInfo sessioninfo = (SessionInfo)this.Page.Session["sessioninfo"]; string strItemRecPath = ""; RmsChannel channel = sessioninfo.Channels.GetChannel(app.WsUrl); if (channel == null) { strError = "channel == null"; goto ERROR1; } if (String.IsNullOrEmpty(this.Barcode) == false) { // 获得册记录 // return: // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条 nRet = app.GetItemRecXml( channel, this.Barcode, out strItemXml, out strOutputPath, out strError); if (nRet == 0) { strError = "册条码号为 '" + this.Barcode + "' 的册记录没有找到"; goto ERROR1; } if (nRet == -1) { goto ERROR1; } strItemRecPath = strOutputPath; } string strItemDbName = ""; string strBiblioRecID = ""; string strBiblioDbName = ""; // 若需要同时取得种记录 if ((this.DispStyle & DispStyle.Biblio) == DispStyle.Biblio) { string strBiblioRecPath = ""; if (String.IsNullOrEmpty(this.BiblioRecPath) == true) { /* * // 准备工作: 映射数据库名 * nRet = app.GetGlobalCfg(sessioninfo.Channels, * out strError); * if (nRet == -1) * goto ERROR1; * */ strItemDbName = ResPath.GetDbName(strOutputPath); // string strBiblioDbName = ""; // 根据实体库名, 找到对应的书目库名 // return: // -1 出错 // 0 没有找到 // 1 找到 nRet = app.GetBiblioDbNameByItemDbName(strItemDbName, out strBiblioDbName, out strError); if (nRet == -1) { goto ERROR1; } if (nRet == 0) { strError = "实体库名 '" + strItemDbName + "' 没有找到对应的书目库名"; goto ERROR1; } XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strItemXml); } catch (Exception ex) { strError = "册记录XML装载到DOM出错:" + ex.Message; goto ERROR1; } strBiblioRecID = DomUtil.GetElementText(dom.DocumentElement, "parent"); // if (String.IsNullOrEmpty(strBiblioRecID) == true) { strError = "册记录XML中<parent>元素缺乏或者值为空, 因此无法定位种记录"; goto ERROR1; } strBiblioRecPath = strBiblioDbName + "/" + strBiblioRecID; } else { strBiblioRecPath = this.BiblioRecPath; strBiblioDbName = ResPath.GetDbName(this.BiblioRecPath); if (String.IsNullOrEmpty(strItemDbName) == true) { // 根据书目库名, 找到对应的实体库名 // return: // -1 出错 // 0 没有找到 // 1 找到 nRet = app.GetItemDbName(strBiblioDbName, out strItemDbName, out strError); if (nRet == -1) { goto ERROR1; } } strBiblioRecID = ResPath.GetRecordId(this.BiblioRecPath); } string strBiblioXml = ""; string strMetaData = ""; byte[] timestamp = null; lRet = channel.GetRes(strBiblioRecPath, out strBiblioXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "获得种记录 '" + strBiblioRecPath + "' 时出错: " + strError; goto ERROR1; } // 需要从内核映射过来文件 string strLocalPath = ""; nRet = app.MapKernelScriptFile( sessioninfo, strBiblioDbName, "./cfgs/loan_biblio.fltx", out strLocalPath, out strError); if (nRet == -1) { goto ERROR1; } // 将种记录数据从XML格式转换为HTML格式 string strBiblio = ""; // 2006/11/28 changed string strFilterFileName = strLocalPath; // app.CfgDir + "\\biblio.fltx"; if (string.IsNullOrEmpty(strBiblioXml) == false) { nRet = app.ConvertBiblioXmlToHtml( strFilterFileName, strBiblioXml, strBiblioRecPath, out strBiblio, out strError); if (nRet == -1) { goto ERROR1; } } else { strBiblio = ""; } // output.Write(strBiblio); LiteralControl literal = (LiteralControl)FindControl("biblio"); literal.Text = strBiblio; } if ((this.DispStyle & DispStyle.Items) == DispStyle.Items) { this.ItemConverter = app.NewItemConverter( app.CfgDir + "\\itemopac.cs", app.CfgDir + "\\itemopac.cs.ref", out strError); if (this.ItemConverter == null) { goto ERROR1; } this.ItemConverter.App = app; // 检索出该种的所有册 sessioninfo.ItemLoad += new ItemLoadEventHandler(SessionInfo_ItemLoad); tempOutput = ""; // tempOutput = output; try { nRet = sessioninfo.SearchItems( app, strItemDbName, strBiblioRecID, out strError); if (nRet == -1) { goto ERROR1; } } finally { sessioninfo.ItemLoad -= new ItemLoadEventHandler(SessionInfo_ItemLoad); //tempOutput = null; this.ItemConverter = null; } LiteralControl literal = (LiteralControl)FindControl("items"); literal.Text = tempOutput; tempOutput = ""; } else if ((this.DispStyle & DispStyle.Item) == DispStyle.Item) { string strResult = ""; // 取得册信息 // 将册记录数据从XML格式转换为HTML格式 nRet = app.ConvertItemXmlToHtml( app.CfgDir + "\\itemxml2html.cs", app.CfgDir + "\\itemxml2html.cs.ref", strItemXml, strItemRecPath, // 2009/10/18 out strResult, out strError); if (nRet == -1) { goto ERROR1; } // output.Write(strResult); LiteralControl literal = (LiteralControl)FindControl("items"); literal.Text = strResult; } base.Render(output); return; ERROR1: output.Write(strError); }
// 设置实用库信息 // strRootElementName 根元素名。如果为空,系统自会用<r>作为根元素 // strKeyAttrName key属性名。如果为空,系统自动会用k // strValueAttrName value属性名。如果为空,系统自动会用v public LibraryServerResult SetUtilInfo( SessionInfo sessioninfo, string strAction, string strDbName, string strFrom, string strRootElementName, string strKeyAttrName, string strValueAttrName, string strKey, string strValue) { string strError = ""; int nRet = 0; LibraryServerResult result = new LibraryServerResult(); string strPath = ""; string strXml = ""; byte[] timestamp = null; bool bRedo = false; if (String.IsNullOrEmpty(strRootElementName) == true) { strRootElementName = "r"; // 最简单的缺省模式 } if (String.IsNullOrEmpty(strKeyAttrName) == true) { strKeyAttrName = "k"; } if (String.IsNullOrEmpty(strValueAttrName) == true) { strValueAttrName = "v"; } RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; goto ERROR1; } // 检索实用库记录的路径和记录体 // return: // -1 error(注:检索命中多条情况被当作错误返回) // 0 not found // 1 found nRet = SearchUtilPathAndRecord( // sessioninfo.Channels, channel, strDbName, strKey, strFrom, out strPath, out strXml, out timestamp, out strError); if (nRet == -1) { goto ERROR1; } // 如果动作为直接设置整个记录 if (strAction == "setrecord") { if (nRet == 0) { strPath = strDbName + "/?"; } strXml = strValue; } else { // 根据若干信息构造出记录 if (nRet == 0) { strPath = strDbName + "/?"; // strXml = "<" + strRootElementName + " " + strKeyAttrName + "='" + strKey + "' " + strValueAttrName + "='" + strValue + "'/>"; // 2011/12/11 XmlDocument dom = new XmlDocument(); dom.LoadXml("<" + strRootElementName + "/>"); DomUtil.SetAttr(dom.DocumentElement, strKeyAttrName, strKey); DomUtil.SetAttr(dom.DocumentElement, strValueAttrName, strValue); strXml = dom.DocumentElement.OuterXml; } else { string strPartXml = "/xpath/<locate>@" + strValueAttrName + "</locate><create>@" + strValueAttrName + "</create>"; strPath += strPartXml; strXml = strValue; } } #if NO RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; goto ERROR1; } #endif byte[] baOutputTimeStamp = null; string strOutputPath = ""; int nRedoCount = 0; REDO: long lRet = channel.DoSaveTextRes(strPath, strXml, false, // bInlucdePreamble "ignorechecktimestamp", // style timestamp, out baOutputTimeStamp, out strOutputPath, out strError); if (lRet == -1) { if (bRedo == true) { if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch && nRedoCount < 10) { timestamp = baOutputTimeStamp; nRedoCount++; goto REDO; } } goto ERROR1; } result.Value = 1; return(result); ERROR1: result.Value = -1; result.ErrorCode = ErrorCode.SystemError; result.ErrorInfo = strError; return(result); }
// 处理一条记录 // parameters: // strQueueRecPath 预约到书队列记录的路径 int DoOneRecord( // Calendar calendar, string strQueueRecPath, string strQueueRecXml, byte[] baQueueRecTimeStamp, out string strError) { strError = ""; int nRet = 0; XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strQueueRecXml); } catch (Exception ex) { strError = "装载队列记录 XML 到 DOM 出错: " + ex.Message; return(-1); } string strState = DomUtil.GetElementText(dom.DocumentElement, "state"); // 对通知完成后的记录, 循环中不必处理 if (StringUtil.IsInList("outof", strState) == true) { return(0); } // TODO: 读者的馆代码 string strLibraryCode = DomUtil.GetElementText(dom.DocumentElement, "libraryCode"); string strReaderBarcode = DomUtil.GetElementText(dom.DocumentElement, "readerBarcode"); // 2015/5/20 // 通过读者证条码号获得读者类型 string strReaderType = ""; // 获得读者类型 // return: // -1 出错 // 0 没有找到读者记录 // 1 找到 nRet = GetReaderType(strReaderBarcode, out strReaderType, out strError); if (nRet == -1) { strReaderType = ""; } string strKey = strLibraryCode + "|" + strReaderType; Calendar calendar = (Calendar)_calendarTable[strKey]; if (calendar == null) { // return: // -1 出错 // 0 没有找到日历 // 1 找到日历 nRet = this.App.GetReaderCalendar(strReaderType, strLibraryCode, out calendar, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { calendar = null; } if (calendar != null && _calendarTable.Count < 10000) { _calendarTable[strKey] = calendar; } } #if NO if (this.m_calendar == null || this.m_strCalendarLibraryCode != strLibraryCode ) { // return: // -1 出错 // 0 没有找到日历 // 1 找到日历 nRet = this.App.GetReaderCalendar(null, strLibraryCode, out m_calendar, out strError); if (nRet == -1) { return(-1); } if (nRet == 1) { this.m_strCalendarLibraryCode = strLibraryCode; } else { m_calendar = null; this.m_strCalendarLibraryCode = ""; } } #endif // 判断是否超过保留期限 // return: // -1 error // 0 没有超过 // 1 已经超过 nRet = CheckeOutOfReservation( calendar, dom, out strError); if (nRet == -1) { return(-1); } RmsChannel channel = this.RmsChannels.GetChannel(this.App.WsUrl); if (channel == null) { strError = "get channel error"; return(-1); } if (nRet == 1) { string strItemBarcode = DomUtil.GetElementText(dom.DocumentElement, "itemBarcode"); // 通知当前读者,他超过了取书的保留期限 string strNotifyDate = DomUtil.GetElementText(dom.DocumentElement, "notifyDate"); nRet = AddReaderOutOfReservationInfo( // this.RmsChannels, channel, strReaderBarcode, strItemBarcode, strNotifyDate, out strError); if (nRet == -1) { this.App.WriteErrorLog("AddReaderOutOfReservationInfo() error: " + strError); } // 已经超过保留期限,要通知下一位预约者 nRet = this.App.DoNotifyNext( null, channel, strQueueRecPath, dom, baQueueRecTimeStamp, out strError); if (nRet == -1) { return(-1); } if (nRet == 1) { // 需要归架 // 册记录中<location>需要去掉#reservation,相关<request>元素也需要删除 nRet = RemoveEntityReservationInfo(strItemBarcode, strReaderBarcode, out strError); if (nRet == -1) { strError = "RemoveEntityReservationInfo() error: " + strError; return(-1); } } } return(0); }
// 去除册记录中过时的预约信息 // 册记录中<location>需要去掉#reservation,相关<request>元素也需要删除 // 锁定:本函数对EntityLocks加了锁定 int RemoveEntityReservationInfo(string strItemBarcode, string strReaderBarcode, out string strError) { strError = ""; int nRet = 0; if (String.IsNullOrEmpty(strItemBarcode) == true) { strError = "册条码号不能为空。"; return(-1); } if (String.IsNullOrEmpty(strReaderBarcode) == true) { strError = "读者证条码号不能为空。"; return(-1); } RmsChannel channel = this.RmsChannels.GetChannel(this.App.WsUrl); if (channel == null) { // text-level: 内部错误 strError = "get channel error"; return(-1); } // 加册记录锁 this.App.EntityLocks.LockForWrite(strItemBarcode); try // 册记录锁定范围开始 { // 从册条码号获得册记录 int nRedoCount = 0; REDO_CHANGE: List <string> aPath = null; string strItemXml = ""; byte[] item_timestamp = null; string strOutputItemRecPath = ""; // 获得册记录 // return: // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条 nRet = this.App.GetItemRecXml( // this.RmsChannels, channel, strItemBarcode, out strItemXml, 100, out aPath, out item_timestamp, out strError); if (nRet == 0) { strError = "册条码号 '" + strItemBarcode + "' 不存在"; return(-1); } if (nRet == -1) { strError = "读入册记录时发生错误: " + strError; return(-1); } if (aPath.Count > 1) { strError = "册条码号为 '" + strItemBarcode + "' 的册记录有 " + aPath.Count.ToString() + " 条,无法进行修改册记录的操作。"; return(-1); } else { Debug.Assert(nRet == 1, ""); Debug.Assert(aPath.Count == 1, ""); if (nRet == 1) { strOutputItemRecPath = aPath[0]; } } XmlDocument itemdom = null; nRet = LibraryApplication.LoadToDom(strItemXml, out itemdom, out strError); if (nRet == -1) { strError = "装载册记录进入XML DOM时发生错误: " + strError; return(-1); } // 修改册记录 // 册记录中<location>需要去掉#reservation,相关<request>元素也需要删除 string strLocation = DomUtil.GetElementText(itemdom.DocumentElement, "location"); // StringUtil.RemoveFromInList("#reservation", true, ref strLocation); strLocation = StringUtil.GetPureLocationString(strLocation); DomUtil.SetElementText(itemdom.DocumentElement, "location", strLocation); XmlNode nodeRequest = itemdom.DocumentElement.SelectSingleNode("reservations/request[@reader='" + strReaderBarcode + "']"); if (nodeRequest != null) { nodeRequest.ParentNode.RemoveChild(nodeRequest); } #if NO RmsChannel channel = this.RmsChannels.GetChannel(this.App.WsUrl); #endif // 写回册记录 byte[] output_timestamp = null; string strOutputPath = ""; long lRet = channel.DoSaveTextRes(strOutputItemRecPath, itemdom.OuterXml, false, "content", // ,ignorechecktimestamp item_timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { nRedoCount++; if (nRedoCount > 10) { strError = "写回册记录的时候,遇到时间戳冲突,并因此重试10次,仍失败..."; return(-1); } goto REDO_CHANGE; } } } // 册记录锁定范围结束 finally { // 解册记录锁 this.App.EntityLocks.UnlockForWrite(strItemBarcode); } return(0); }
// 设置种次号尾号 public LibraryServerResult SetOneClassTailNumber( SessionInfo sessioninfo, string strAction, string strArrangeGroupName, string strClass, string strTestNumber, out string strOutputNumber) { strOutputNumber = ""; string strError = ""; LibraryServerResult result = new LibraryServerResult(); RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; goto ERROR1; } string strPath = ""; string strXml = ""; byte[] timestamp = null; // 检索尾号记录的路径和记录体 // return: // -1 error // 0 not found // 1 found int nRet = SearchOneClassTailNumberPathAndRecord( // sessioninfo.Channels, channel, strArrangeGroupName, strClass, out strPath, out strXml, out timestamp, out strError); if (nRet == -1) { goto ERROR1; } string strZhongcihaoDbName = GetTailDbName(strArrangeGroupName); if (String.IsNullOrEmpty(strZhongcihaoDbName) == true) { // TODO: 这里报错还需要精确一些,对于带有'!'的馆藏地点名 strError = "无法通过排架体系名 '" + strArrangeGroupName + "' 获得种次号库名"; goto ERROR1; } // byte[] baOutputTimestamp = null; bool bNewRecord = false; long lRet = 0; #if NO RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; goto ERROR1; } #endif byte[] output_timestamp = null; string strOutputPath = ""; if (strAction == "conditionalpush") { if (nRet == 0) { // 新创建记录 strPath = strZhongcihaoDbName + "/?"; strXml = "<r c='" + strClass + "' v='" + strTestNumber + "'/>"; bNewRecord = true; } else { string strPartXml = "/xpath/<locate>@v</locate><action>Push</action>"; strPath += strPartXml; strXml = strTestNumber; bNewRecord = false; } lRet = channel.DoSaveTextRes(strPath, strXml, false, "content", timestamp, // timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "保存尾号记录时出错: " + strError; goto ERROR1; } if (bNewRecord == true) { strOutputNumber = strTestNumber; } else { strOutputNumber = strError; } goto END1; } else if (strAction == "increase") { string strDefaultNumber = strTestNumber; if (nRet == 0) { // 新创建记录 strPath = strZhongcihaoDbName + "/?"; strXml = "<r c='" + strClass + "' v='" + strDefaultNumber + "'/>"; bNewRecord = true; } else { string strPartXml = "/xpath/<locate>@v</locate><action>+AddInteger</action>"; strPath += strPartXml; strXml = "1"; bNewRecord = false; } // lRet = channel.DoSaveTextRes(strPath, strXml, false, "content", timestamp, // timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { strError = "保存尾号记录时出错: " + strError; goto ERROR1; } if (bNewRecord == true) { strOutputNumber = strDefaultNumber; } else { strOutputNumber = strError; } goto END1; } else if (strAction == "save") { string strTailNumber = strTestNumber; if (nRet == 0) { strPath = strZhongcihaoDbName + "/?"; } else { // 覆盖记录 if (String.IsNullOrEmpty(strPath) == true) { strError = "记录存在时strPath居然为空"; goto ERROR1; } } strXml = "<r c='" + strClass + "' v='" + strTailNumber + "'/>"; lRet = channel.DoSaveTextRes(strPath, strXml, false, "content", timestamp, // timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { strError = "尾号记录时间戳不匹配,说明可能被他人修改过。详细原因: " + strError; goto ERROR1; } strError = "保存尾号记录时出错: " + strError; goto ERROR1; } } else { strError = "无法识别的strAction参数值 '" + strAction + "'"; goto ERROR1; } END1: result.Value = 1; return(result); ERROR1: result.Value = -1; result.ErrorCode = ErrorCode.SystemError; result.ErrorInfo = strError; return(result); }
// 检索尾号记录的路径和记录体 // return: // -1 error(注:检索命中多条情况被当作错误返回) // 0 not found // 1 found public int SearchOneClassTailNumberPathAndRecord( // RmsChannelCollection Channels, RmsChannel channel, string strArrangeGroupName, string strClass, out string strPath, out string strXml, out byte[] timestamp, out string strError) { strError = ""; strPath = ""; strXml = ""; timestamp = null; if (strClass == "") { strError = "尚未指定分类号"; return(-1); } if (strArrangeGroupName == "") { strError = "尚未指定排架体系名"; return(-1); } string strZhongcihaoDbName = GetTailDbName(strArrangeGroupName); if (String.IsNullOrEmpty(strZhongcihaoDbName) == true) { strError = "无法通过排架体系名 '" + strArrangeGroupName + "' 获得种次号库名"; return(-1); } string strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strZhongcihaoDbName + ":" + "分类号") // 2007/9/14 + "'><item><word>" + StringUtil.GetXmlStringSimple(strClass) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang></target>"; List <string> aPath = null; // 获得通用记录 // 本函数可获得超过1条以上的路径 // return: // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条 int nRet = GetRecXml( // Channels, channel, strQueryXml, out strXml, 2, out aPath, out timestamp, out strError); if (nRet == -1) { strError = "检索库 " + strZhongcihaoDbName + " 时出错: " + strError; return(-1); } if (nRet == 0) { return(0); // 没有找到 } if (nRet > 1) { strError = "以分类号'" + strClass + "'检索库 " + strZhongcihaoDbName + " 时命中 " + Convert.ToString(nRet) + " 条,无法取得尾号。请修改库 '" + strZhongcihaoDbName + "' 中相应记录,确保同一类目只有一条对应的记录。"; return(-1); } Debug.Assert(aPath.Count >= 1, ""); strPath = aPath[0]; return(1); }
// parameters: // strBrowseInfoStyle 返回的特性。cols 返回实体记录的浏览列 public LibraryServerResult GetCallNumberSearchResult( SessionInfo sessioninfo, string strArrangeGroupName, string strResultSetName, long lStart, long lCount, string strBrowseInfoStyle, string strLang, out CallNumberSearchResult[] searchresults) { string strError = ""; searchresults = null; LibraryServerResult result = new LibraryServerResult(); // int nRet = 0; long lRet = 0; if (String.IsNullOrEmpty(strArrangeGroupName) == true) { strError = "strArrangeGroupName参数值不能为空"; goto ERROR1; } if (strArrangeGroupName[0] == '!') { string strTemp = GetArrangeGroupName(strArrangeGroupName.Substring(1)); if (strTemp == null) { strError = "馆藏地点名 " + strArrangeGroupName.Substring(1) + " 没有找到对应的排架体系名"; goto ERROR1; } strArrangeGroupName = strTemp; } RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl); if (channel == null) { result.Value = -1; result.ErrorInfo = "get channel error"; result.ErrorCode = ErrorCode.SystemError; return(result); } if (String.IsNullOrEmpty(strResultSetName) == true) { strResultSetName = "default"; } bool bCols = StringUtil.IsInList("cols", strBrowseInfoStyle); string strBrowseStyle = "keyid,id,key"; if (bCols == true) { strBrowseStyle += ",cols,format:cfgs/browse_callnumber"; } Record[] origin_searchresults = null; // lRet = channel.DoGetSearchResult( strResultSetName, lStart, lCount, strBrowseStyle, // "id", strLang, null, out origin_searchresults, out strError); if (lRet == -1) { goto ERROR1; } long lResultCount = lRet; searchresults = new CallNumberSearchResult[origin_searchresults.Length]; for (int i = 0; i < origin_searchresults.Length; i++) { CallNumberSearchResult item = new CallNumberSearchResult(); Record record = origin_searchresults[i]; item.ItemRecPath = record.Path; searchresults[i] = item; string strLocation = ""; item.CallNumber = BuildAccessNoKeyString(record.Keys, out strLocation); if (bCols == true && record.Cols != null) { if (record.Cols.Length > 0) { item.ParentID = record.Cols[0]; } if (record.Cols.Length > 1) { item.Location = record.Cols[1]; } if (record.Cols.Length > 2) { item.Barcode = record.Cols[2]; } } if (string.IsNullOrEmpty(item.Location) == true) { item.Location = strLocation; // 用从keys中得来的代替。可能有大小写的差异 --- keys中都是大写 } #if NO if (bCols == true) { // 继续填充其余成员 string strXml = ""; string strMetaData = ""; byte[] timestamp = null; string strOutputPath = ""; lRet = channel.GetRes(item.ItemRecPath, out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) { item.ErrorInfo = "获取记录 '" + item.ItemRecPath + "' 出错: " + strError; continue; } XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXml); } catch (Exception ex) { item.ErrorInfo = "记录 '" + item.ItemRecPath + "' XML装载到DOM时出错: " + ex.Message; continue; } /* * item.CallNumber = DomUtil.GetElementText(dom.DocumentElement, * "accessNo"); * */ item.ParentID = DomUtil.GetElementText(dom.DocumentElement, "parent"); item.Location = DomUtil.GetElementText(dom.DocumentElement, "location"); item.Barcode = DomUtil.GetElementText(dom.DocumentElement, "barcode"); } #endif } result.Value = lResultCount; return(result); ERROR1: result.Value = -1; result.ErrorCode = ErrorCode.SystemError; result.ErrorInfo = strError; return(result); }
// 获得种次号尾号 public LibraryServerResult GetOneClassTailNumber( SessionInfo sessioninfo, string strArrangeGroupName, string strClass, out string strTailNumber) { strTailNumber = ""; string strError = ""; LibraryServerResult result = new LibraryServerResult(); if (String.IsNullOrEmpty(strArrangeGroupName) == true) { strError = "strArrangeGroupName参数值不能为空"; goto ERROR1; } RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; goto ERROR1; } string strPath = ""; string strXml = ""; byte[] timestamp = null; // 检索尾号记录的路径和记录体 // return: // -1 error // 0 not found // 1 found int nRet = SearchOneClassTailNumberPathAndRecord( // sessioninfo.Channels, channel, strArrangeGroupName, strClass, out strPath, out strXml, out timestamp, out strError); if (nRet == -1) { goto ERROR1; } if (nRet == 0) { result.ErrorCode = ErrorCode.NotFound; result.ErrorInfo = strError; result.Value = 0; return(result); } XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXml); } catch (Exception ex) { strError = "尾号记录 '" + strPath + "' XML装入DOM时发生错误: " + ex.Message; goto ERROR1; } strTailNumber = DomUtil.GetAttr(dom.DocumentElement, "v"); result.Value = 1; return(result); ERROR1: result.Value = -1; result.ErrorCode = ErrorCode.SystemError; result.ErrorInfo = strError; return(result); }
/// <summary> /// 保存记录 /// </summary> /// <param name="strServerUrl">服务器URL</param> /// <param name="strPath"></param> /// <param name="strXml"></param> /// <param name="baTimestamp"></param> /// <param name="bForceSaveOnTimestampMismatch"></param> /// <param name="baOutputTimestamp"></param> /// <param name="strError"></param> /// <returns>-2 时间戳不匹配;-1 一般出错;0 正常</returns> public int SaveRecord( string strServerUrl, string strPath, string strXml, byte[] baTimestamp, bool bForceSaveOnTimestampMismatch, out byte[] baOutputTimestamp, out string strError) { strError = ""; baOutputTimestamp = null; if (String.IsNullOrEmpty(strServerUrl) == true) { strServerUrl = this.ServerUrl; } RmsChannel channelSave = channel; channel = Channels.GetChannel(strServerUrl); if (channel == null) { strError = "get channel error"; return(-1); } try { string strOutputPath = ""; REDO: long lRet = channel.DoSaveTextRes(strPath, strXml, false, // bInlucdePreamble "", // style baTimestamp, out baOutputTimestamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { if (bForceSaveOnTimestampMismatch == true) { baTimestamp = baOutputTimestamp; goto REDO; } else { return(-2); } } return(-1); } strError = channel.ErrorInfo; // 特殊API风格 return(0); } finally { channel = channelSave; } }
/// <summary> /// 获取记录 /// </summary> /// <param name="strServerUrl">服务器URL。如果==null,表示用SearchPannel自己的ServerUrl</param> /// <param name="strPath"></param> /// <param name="strXml"></param> /// <param name="baTimeStamp"></param> /// <param name="strError"></param> /// <returns>-1 error;0 not found;1 found</returns> public int GetRecord( string strServerUrl, string strPath, out string strXml, out byte[] baTimeStamp, out string strError) { strError = ""; baTimeStamp = null; strXml = ""; if (String.IsNullOrEmpty(strServerUrl) == true) { strServerUrl = this.ServerUrl; } RmsChannel channelSave = channel; channel = Channels.GetChannel(strServerUrl); if (channel == null) { strError = "get channel error"; return(-1); } try { // 取记录 string strStyle = "content,data,timestamp"; string strMetaData; string strOutputPath; long lRet = channel.GetRes(strPath, strStyle, out strXml, out strMetaData, out baTimeStamp, out strOutputPath, out strError); if (lRet == -1) { strError = "获取 '" + strPath + "' 记录体时出错: " + strError; if (channel.ErrorCode == ChannelErrorCode.NotFound) { return(0); } return(-1); } return(1); } finally { channel = channelSave; } }
/// <summary> /// 检索得到若干命中结果 /// </summary> /// <param name="strServerUrl">服务器URL</param> /// <param name="strQueryXml">检索式XML</param> /// <param name="nMax">最大结果数</param> /// <param name="aPath">返回的记录路径数组</param> /// <param name="strError">返回的错误信息</param> /// <returns>-1 一般错误;0 not found;1 found;>1 命中多于一条</returns> public int SearchMultiPath( string strServerUrl, string strQueryXml, int nMax, out List <string> aPath, out string strError) { aPath = null; strError = ""; if (String.IsNullOrEmpty(strServerUrl) == true) { strServerUrl = this.ServerUrl; } RmsChannel channelSave = channel; channel = Channels.GetChannel(strServerUrl); if (channel == null) { strError = "get channel error"; return(-1); } try { long lRet = channel.DoSearch(strQueryXml, "default", "", // strOuputStyle out strError); if (lRet == -1) { return(-1); } if (lRet == 0) { return(0); // 没有找到 } long lCount = lRet; lCount = Math.Min(lCount, nMax); if (lRet > 1) { strError = "命中 " + Convert.ToString(lRet) + " 条。"; } lRet = channel.DoGetSearchResult( "default", 0, lCount, "zh", this.stop, out aPath, out strError); if (lRet == -1) { strError = "获取检索结果时出错: " + strError; return(-1); } return((int)lCount); } finally { channel = channelSave; } }
/// <summary> /// 获得配置文件 /// </summary> /// <param name="strServerUrl">服务器URL。如果为null,则自动使用this.ServerUrl</param> /// <param name="strCfgFilePath">配置文件纯路径,不包含ServerUrl部分</param> /// <param name="strContent">返回配置文件内容</param> /// <param name="strError">返回错误信息</param> /// <returns>-1出错;0没有找到;1找到</returns> public int GetCfgFile( string strServerUrl, string strCfgFilePath, out string strContent, out string strError) { strError = ""; strContent = ""; if (strServerUrl == "" || strServerUrl == null) { strServerUrl = this.ServerUrl; } if (strServerUrl == "") { strError = "尚未指定服务器URL"; return(-1); } RmsChannel channelSave = channel; channel = Channels.GetChannel(strServerUrl); if (channel == null) { strError = "get channel error"; return(-1); } try { this.BeginLoop("正在下载文件" + strCfgFilePath); byte[] baTimeStamp = null; string strMetaData; string strOutputPath; long lRet = channel.GetRes( this.cfgCache, strCfgFilePath, out strContent, out strMetaData, out baTimeStamp, out strOutputPath, out strError); this.EndLoop(); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) { return(0); // not found } return(-1); } return(1); // found } finally { this.channel = channelSave; } }
// (根据一定排架体系)检索出某一类的同类书的索取号 // parameters: // strArrangeGroupName 排架体系名。如果为"!xxx"形式,表示通过馆藏地点名来暗示排架体系名 public LibraryServerResult SearchOneClassCallNumber( SessionInfo sessioninfo, string strArrangeGroupName, string strClass, string strResultSetName, out string strQueryXml) { strQueryXml = ""; string strError = ""; LibraryServerResult result = new LibraryServerResult(); if (String.IsNullOrEmpty(strArrangeGroupName) == true) { strError = "strArrangeGroupName参数值不能为空"; goto ERROR1; } if (strArrangeGroupName[0] == '!') { string strTemp = GetArrangeGroupName(strArrangeGroupName.Substring(1)); if (strTemp == null) { strError = "馆藏地点名 " + strArrangeGroupName.Substring(1) + " 没有找到对应的排架体系名"; goto ERROR1; } strArrangeGroupName = strTemp; } // <location>元素数组 XmlNodeList nodes = this.LibraryCfgDom.DocumentElement.SelectNodes("//callNumber/group[@name='" + strArrangeGroupName + "']/location"); if (nodes.Count == 0) { strError = "library.xml中尚未配置有关 '" + strArrangeGroupName + "' 的<callNumber>/<group>/<location>相关参数"; goto ERROR1; } string strTargetList = ""; // 遍历所有实体库 for (int i = 0; i < this.ItemDbs.Count; i++) { string strItemDbName = this.ItemDbs[i].DbName; if (String.IsNullOrEmpty(strItemDbName) == true) { continue; } if (String.IsNullOrEmpty(strTargetList) == false) { strTargetList += ";"; } strTargetList += strItemDbName + ":索取类号"; } int nCount = 0; // 构造检索式 for (int i = 0; i < nodes.Count; i++) { XmlNode node = nodes[i]; string strLocationName = DomUtil.GetAttr(node, "name"); if (String.IsNullOrEmpty(strLocationName) == true) { continue; } if (nCount > 0) { Debug.Assert(String.IsNullOrEmpty(strQueryXml) == false, ""); strQueryXml += "<operator value='OR'/>"; } strLocationName = strLocationName.Replace("*", "%"); /* * strQueryXml += "<item><word>" + StringUtil.GetXmlStringSimple(strLocationName + "|" + strClass) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang>"; * */ strQueryXml += "<item><word>" + StringUtil.GetXmlStringSimple(strLocationName + "|" + strClass + "/") + "</word><match>left</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang>"; nCount++; } strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strTargetList) // 2007/9/14 + "'>" + strQueryXml + "</target>"; RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; goto ERROR1; } long lRet = channel.DoSearch(strQueryXml, strResultSetName, // "default", "keyid", // "", // strOuputStyle out strError); if (lRet == -1) { goto ERROR1; } if (lRet == 0) { result.Value = 0; result.ErrorInfo = "not found"; result.ErrorCode = ErrorCode.NotFound; return(result); } result.Value = lRet; return(result); ERROR1: result.Value = -1; result.ErrorCode = ErrorCode.SystemError; result.ErrorInfo = strError; return(result); }
// 获得读者类型 // return: // -1 出错 // 0 没有找到读者记录 // 1 找到 int GetReaderType(string strReaderBarcode, out string strReaderType, out string strError) { strError = ""; strReaderType = ""; if (string.IsNullOrEmpty(strReaderBarcode) == true) { strError = "strReaderBarcode 不能为空"; return(-1); } RmsChannel channel = this.RmsChannels.GetChannel(this.App.WsUrl); if (channel == null) { strError = "get channel error"; return(-1); } // 读入读者记录 string strReaderXml = ""; string strOutputReaderRecPath = ""; byte[] reader_timestamp = null; int nRet = this.App.GetReaderRecXml( // this.RmsChannels, channel, strReaderBarcode, out strReaderXml, out strOutputReaderRecPath, out reader_timestamp, out strError); if (nRet == 0) { strError = "读者证条码号 '" + strReaderBarcode + "' 不存在"; return(0); } 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); } strReaderType = DomUtil.GetElementText(readerdom.DocumentElement, "readerType"); return(1); }
// 获得缺省帐户信息 // return: // 2 already login succeed // 1 dialog return OK // 0 dialog return Cancel // -1 other error public void OnAskAccountInfo(object sender, AskAccountInfoEventArgs e) { bool bFirst = true; bool bAutoLogin = (e.LoginStyle & LoginStyle.AutoLogin) == LoginStyle.AutoLogin; bool bFillDefault = (e.LoginStyle & LoginStyle.FillDefaultInfo) == LoginStyle.FillDefaultInfo; e.Owner = this.ownerForm; e.UserName = ""; e.Password = ""; LoginDlg dlg = new LoginDlg(); dlg.Font = GuiUtil.GetDefaultFont(); Server server = this[e.Url]; dlg.textBox_serverAddr.Text = e.Url; if (bFillDefault == true) { if (server != null) { dlg.textBox_userName.Text = (server.DefaultUserName == "" ? "public" : server.DefaultUserName); dlg.textBox_password.Text = server.DefaultPassword; dlg.checkBox_savePassword.Checked = server.SavePassword; } else { dlg.textBox_userName.Text = "public"; dlg.textBox_password.Text = ""; dlg.checkBox_savePassword.Checked = false; } } if (e.Comment != null) { dlg.textBox_comment.Text = e.Comment; } DOLOGIN: if (e.Channels != null) { if (bAutoLogin == false && bFirst == true) { goto REDOINPUT; } // 找到Channel RmsChannel channel = e.Channel; // 2013/2/14 if (channel == null) { channel = e.Channels.GetChannel(dlg.textBox_serverAddr.Text); } Debug.Assert(channel != null, "Channels.GetChannel()异常..."); string strError; // 登录 int nRet = channel.Login(dlg.textBox_userName.Text, dlg.textBox_password.Text, out strError); if (nRet != 1) { strError = "以用户名 '" + dlg.textBox_userName.Text + "' 登录到 '" + dlg.textBox_serverAddr.Text + "' 失败: " + strError; if (this.ownerForm != null) { MessageBox.Show(this.ownerForm, strError); } else { e.ErrorInfo = strError; e.Result = -1; } goto REDOINPUT; } else // 登录成功 { if (String.Compare(e.Url, dlg.textBox_serverAddr.Text, true) != 0) { // 创建一个新的Server对象 // return: // -1 出错 // 0 加入了 // 1 发现重复,没有加入 nRet = this.NewServer(dlg.textBox_serverAddr.Text, -1); if (nRet == 0) { e.Url = channel.Url; } } server = this[dlg.textBox_serverAddr.Text]; if (server == null) // 2006/8/19 add { // 创建一个新的Server对象 // return: // -1 出错 // 0 加入了 // 1 发现重复,没有加入 nRet = this.NewServer(dlg.textBox_serverAddr.Text, -1); if (nRet == 0) { e.Url = channel.Url; } server = this[dlg.textBox_serverAddr.Text]; } Debug.Assert(server != null, "此时server不可能为null"); server.DefaultUserName = dlg.textBox_userName.Text; server.DefaultPassword = dlg.textBox_password.Text; server.SavePassword = dlg.checkBox_savePassword.Checked; this.m_bChanged = true; e.Result = 2; return; } } REDOINPUT: bFirst = false; dlg.ShowDialog(ownerForm); if (dlg.DialogResult != DialogResult.OK) { e.Result = 0; return; } if (e.Channels == null) { e.UserName = dlg.textBox_userName.Text; e.Password = dlg.textBox_password.Text; e.Result = 1; return; } goto DOLOGIN; }
// 给读者记录里加上预约到书后超期不取的状态 int AddReaderOutOfReservationInfo( // RmsChannelCollection channels, RmsChannel channel, string strReaderBarcode, string strItemBarcode, string strNotifyDate, out string strError) { strError = ""; int nRet = 0; long lRet = 0; int nRedoCount = 0; REDO_MEMO: // 加读者记录锁 #if DEBUG_LOCK_READER this.App.WriteErrorLog("AddReaderOutOfReservationInfo 开始为读者加写锁 '" + strReaderBarcode + "'"); #endif this.App.ReaderLocks.LockForWrite(strReaderBarcode); try // 读者记录锁定范围开始 { // 读入读者记录 string strReaderXml = ""; string strOutputReaderRecPath = ""; byte[] reader_timestamp = null; nRet = this.App.GetReaderRecXml( // channels, channel, 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); } XmlNode root = readerdom.DocumentElement.SelectSingleNode("outofReservations"); if (root == null) { root = readerdom.CreateElement("outofReservations"); readerdom.DocumentElement.AppendChild(root); } // 累计次数 string strCount = DomUtil.GetAttr(root, "count"); if (String.IsNullOrEmpty(strCount) == true) { strCount = "0"; } int nCount = 0; try { nCount = Convert.ToInt32(strCount); } catch { } nCount++; DomUtil.SetAttr(root, "count", nCount.ToString()); // 追加<request>元素 XmlNode request = readerdom.CreateElement("request"); root.AppendChild(request); DomUtil.SetAttr(request, "itemBarcode", strItemBarcode); DomUtil.SetAttr(request, "notifyDate", strNotifyDate); byte[] output_timestamp = null; string strOutputPath = ""; #if NO RmsChannel channel = channels.GetChannel(this.App.WsUrl); if (channel == null) { strError = "get channel error"; return(-1); } #endif // 写回读者记录 lRet = channel.DoSaveTextRes(strOutputReaderRecPath, readerdom.OuterXml, false, "content", // ,ignorechecktimestamp reader_timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { nRedoCount++; if (nRedoCount > 10) { strError = "写回读者记录的时候,遇到时间戳冲突,并因此重试10次,仍失败..."; return(-1); } goto REDO_MEMO; } return(-1); } } // 读者记录锁定范围结束 finally { this.App.ReaderLocks.UnlockForWrite(strReaderBarcode); #if DEBUG_LOCK_READER this.App.WriteErrorLog("AddReaderOutOfReservationInfo 结束为读者加写锁 '" + strReaderBarcode + "'"); #endif } return(0); }
// 将内核网络配置文件映射到本地 // return: // -1 出错 // 0 不存在 // 1 找到 public int MapFileToLocal( RmsChannel channel, string strPath, out string strLocalPath, out string strError) { strLocalPath = ""; strError = ""; strLocalPath = this.RootDir + "/" + strPath; // 确保目录存在 PathUtil.TryCreateDir(Path.GetDirectoryName(strLocalPath)); this.locks.LockForRead(strLocalPath); try { // 看看物理文件是否存在 FileInfo fi = new FileInfo(strLocalPath); if (fi.Exists == true) { if (fi.Length == 0) { return(0); // not exist } return(1); } } finally { this.locks.UnlockForRead(strLocalPath); } // 确保目录存在 PathUtil.TryCreateDir(Path.GetDirectoryName(strLocalPath)); this.locks.LockForWrite(strLocalPath); try { #if NO RmsChannel channel = Channels.GetChannel(this.ServerUrl); if (channel == null) { strError = "GetChannel error"; return(-1); } #endif string strMetaData = ""; byte[] baOutputTimestamp = null; string strOutputPath = ""; long lRet = channel.GetRes(strPath, strLocalPath, (Stop)null, out strMetaData, out baOutputTimestamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) { // 为了避免以后再次从网络获取耗费时间, 需要在本地写一个0字节的文件 using (FileStream fs = File.Create(strLocalPath)) { } return(0); } return(-1); } return(1); } finally { this.locks.UnlockForWrite(strLocalPath); } }
// 检索顶层文章 // return: // -1 error // 其他 命中数 private int SearchTopLevelArticles( SessionInfo sessioninfo, System.Web.UI.Page page, out string strError) { strError = ""; if (page != null && page.Response.IsClientConnected == false) // 灵敏中断 { strError = "中断"; return(-1); } // 检索全部评注文章 一定时间范围内的? List <string> dbnames = new List <string>(); for (int i = 0; i < this.ItemDbs.Count; i++) { ItemDbCfg cfg = this.ItemDbs[i]; string strDbName = cfg.CommentDbName; if (String.IsNullOrEmpty(strDbName) == true) { continue; } dbnames.Add(strDbName); } DateTime now = DateTime.Now; DateTime oneyearbefore = now - new TimeSpan(365, 0, 0, 0); string strTime = DateTimeUtil.Rfc1123DateTimeString(oneyearbefore.ToUniversalTime()); string strQueryXml = ""; for (int i = 0; i < dbnames.Count; i++) { string strDbName = dbnames[i]; string strOneQueryXml = "<target list='" + strDbName + ":" + "最后修改时间'><item><word>" // <order>DESC</order> + strTime + "</word><match>exact</match><relation>" + StringUtil.GetXmlStringSimple(">=") + "</relation><dataType>number</dataType><maxCount>" + "-1" // Convert.ToString(m_nMaxLineCount) + "</maxCount></item><lang>zh</lang></target>"; if (i > 0) { strQueryXml += "<operator value='OR' />"; } strQueryXml += strOneQueryXml; } if (dbnames.Count > 0) { strQueryXml = "<group>" + strQueryXml + "</group>"; } RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl); Debug.Assert(channel != null, "Channels.GetChannel 异常"); if (page != null) { page.Response.Write("--- begin search ...<br/>"); page.Response.Flush(); } DateTime time = DateTime.Now; long nRet = channel.DoSearch(strQueryXml, "default", out strError); if (nRet == -1) { strError = "检索时出错: " + strError; return(-1); } TimeSpan delta = DateTime.Now - time; if (page != null) { page.Response.Write("search end. hitcount=" + nRet.ToString() + ", time=" + delta.ToString() + "<br/>"); page.Response.Flush(); } if (nRet == 0) { return(0); // not found } if (page != null && page.Response.IsClientConnected == false) // 灵敏中断 { strError = "中断"; return(-1); } if (page != null) { page.Response.Write("--- begin get search result ...<br/>"); page.Response.Flush(); } time = DateTime.Now; List <string> aPath = null; nRet = channel.DoGetSearchResult( "default", -1, "zh", null, // stop, out aPath, out strError); if (nRet == -1) { strError = "获得检索结果时出错: " + strError; return(-1); } if (page != null) { delta = DateTime.Now - time; page.Response.Write("get search result end. lines=" + aPath.Count.ToString() + ", time=" + delta.ToString() + "<br/>"); page.Response.Flush(); } if (aPath.Count == 0) { strError = "获取的检索结果为空"; return(-1); } if (page != null && page.Response.IsClientConnected == false) // 灵敏中断 { strError = "中断"; return(-1); } if (page != null) { page.Response.Write("--- begin build storage ...<br/>"); page.Response.Flush(); } time = DateTime.Now; this.CommentColumn.Clear(); // 清空集合 // 加入新行对象。新行对象中,只初始化了m_strRecPath参数 for (int i = 0; i < Math.Min(aPath.Count, 1000000); i++) // <Math.Min(aPath.Count, 10) { Line line = new Line(); // line.Container = this; line.m_strRecPath = aPath[i]; nRet = line.InitialInfo( page, channel, out strError); if (nRet == -1) { return(-1); } if (nRet == 1) { return(-1); // 灵敏中断 } TopArticleItem item = new TopArticleItem(); item.Line = line; this.CommentColumn.Add(item); if (page != null && (i % 100) == 0) { page.Response.Write("process " + Convert.ToString(i) + "<br/>"); page.Response.Flush(); } } if (page != null) { delta = DateTime.Now - time; page.Response.Write("build storage end. time=" + delta.ToString() + "<br/>"); page.Response.Flush(); } return(1); }
int BuildTemplates(out TemplateCollection templates, out string strError) { strError = ""; templates = new TemplateCollection(); for (int i = 0; i < this.listView_objects.Items.Count; i++) { ListViewItem item = this.listView_objects.Items[i]; if (item.Checked == false) { continue; } if (item.ImageIndex == ResTree.RESTYPE_FOLDER || item.ImageIndex == ResTree.RESTYPE_FILE) { continue; } string strDbName = item.Text; string strUrl = item.SubItems[1].Text; DatabaseObjectTree tree = new DatabaseObjectTree(); tree.Initial(MainForm.Servers, MainForm.Channels, MainForm.stopManager, strUrl, strDbName); // RmsChannel channel = MainForm.Channels.GetChannel(strUrl); if (channel == null) { goto ERROR1; } List <string[]> logicNames = null; string strType; string strSqlDbName; string strKeysDef; string strBrowseDef; long nRet = channel.DoGetDBInfo( strDbName, "all", out logicNames, out strType, out strSqlDbName, out strKeysDef, out strBrowseDef, out strError); if (nRet == -1) { goto ERROR1; } Template template = new Template(); template.LogicNames = logicNames; template.Type = strType; template.SqlDbName = strSqlDbName; template.KeysDef = strKeysDef; template.BrowseDef = strBrowseDef; template.Object = tree.Root; templates.Add(template); } return(0); ERROR1: return(-1); }
// 获得实用库信息 public LibraryServerResult GetUtilInfo( SessionInfo sessioninfo, string strAction, string strDbName, string strFrom, string strKey, string strValueAttrName, out string strValue) { string strError = ""; strValue = ""; int nRet = 0; LibraryServerResult result = new LibraryServerResult(); /* * if (String.IsNullOrEmpty(strKeyAttrName) == true) * strKeyAttrName = "k"; * */ if (String.IsNullOrEmpty(strValueAttrName) == true) { strValueAttrName = "v"; } RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; goto ERROR1; } string strPath = ""; string strXml = ""; byte[] timestamp = null; // 检索实用库记录的路径和记录体 // return: // -1 error(注:检索命中多条情况被当作错误返回) // 0 not found // 1 found nRet = SearchUtilPathAndRecord( // sessioninfo.Channels, channel, strDbName, strKey, strFrom, out strPath, out strXml, out timestamp, out strError); if (nRet == -1) { goto ERROR1; } if (nRet == 0) { result.ErrorCode = ErrorCode.NotFound; result.ErrorInfo = "库名为 '" + strDbName + "' 途径为 '" + strFrom + "' 键值为 '" + strKey + "' 的记录没有找到"; result.Value = 0; return(result); } // 如果动作为获得整个记录 if (strAction == "getrecord") { strValue = strXml; result.Value = 1; return(result); } XmlDocument domRecord = new XmlDocument(); try { domRecord.LoadXml(strXml); } catch (Exception ex) { strError = "装载路径为'" + strPath + "'的xml记录时出错: " + ex.Message; goto ERROR1; } strValue = DomUtil.GetAttr(domRecord.DocumentElement, strValueAttrName); result.Value = 1; return(result); ERROR1: result.Value = -1; result.ErrorCode = ErrorCode.SystemError; result.ErrorInfo = strError; return(result); }
// 把实体记录借阅信息详细化 // parameters: // strEntityRecPath 册记录路径。如果本参数值为空,则表示希望通过strItemBarcode参数来找到册记录 // return: // -1 error // 0 册条码号没有找到对应的册记录 // 1 成功 int ModifyEntityRecord( // RmsChannelCollection Channels, RmsChannel channel, string strEntityRecPath, string strItemBarcode, string strReaderBarcode, string strBorrowDate, string strBorrowPeriod, out string strError) { strError = ""; int nRet = 0; long lRet = 0; int nRedoCount = 0; if (String.IsNullOrEmpty(strItemBarcode) == true) { strError = "strItemBarcode参数不能为空"; return(-1); } // RmsChannel channel = null; REDO_CHANGE: string strOutputItemRecPath = ""; byte[] item_timestamp = null; string strItemXml = ""; List <string> aPath = null; #if NO if (channel == null) { channel = Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; return(-1); } } #endif if (String.IsNullOrEmpty(strEntityRecPath) == false) { string strStyle = "content,data,metadata,timestamp,outputpath"; string strMetaData = ""; lRet = channel.GetRes(strEntityRecPath, strStyle, out strItemXml, out strMetaData, out item_timestamp, out strOutputItemRecPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) { return(0); } strError = "ModifyEntityRecord()通过册记录路径 '" + strEntityRecPath + "' 读入册记录时发生错误: " + strError; return(-1); } } else { // 从册条码号获得册记录 // 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) { // 册条码号不存在也是需要修复的情况之一。 return(0); } if (nRet == -1) { strError = "ModifyEntityRecord()读入册记录时发生错误: " + strError; return(-1); } if (aPath.Count > 1) { // TODO: 需要将入围的记录全部提取出来,然后看borrower符合读者证条码号的那一条(或者多条?) // 可以参考UpgradeDt1000Loan中的SearchEntityRecord()函数 /* * strError = "因册条码号 '" + strItemBarcode + "' 检索命中多条册记录: " + StringUtil.MakePathList(aPath) + ",修改册记录的操作ModifyEntityRecord()无法进行"; * return -1; * */ int nSuccessCount = 0; string strTempError = ""; // 递归 for (int i = 0; i < aPath.Count; i++) { string strTempPath = aPath[i]; if (String.IsNullOrEmpty(strTempPath) == true) { Debug.Assert(false, ""); continue; } // return: // -1 error // 0 册条码号没有找到对应的册记录 // 1 成功 nRet = ModifyEntityRecord( // Channels, channel, strTempPath, strItemBarcode, strReaderBarcode, strBorrowDate, strBorrowPeriod, out strError); if (nRet == -1 && nSuccessCount == 0) { if (String.IsNullOrEmpty(strTempError) == false) { strTempError += "; "; } strTempError += "试探册记录 '" + strTempPath + "' 时发生错误: " + strError; } if (nRet == 1) { // 改为存储成功信息 if (nSuccessCount == 0) { strTempError = ""; } if (String.IsNullOrEmpty(strTempError) == false) { strTempError += "; "; } strTempError += strTempPath; nSuccessCount++; } } if (nSuccessCount > 0) { strError = "册条码号 '" + strItemBarcode + "' 检索命中" + aPath.Count.ToString() + "条册记录: " + StringUtil.MakePathList(aPath) + ",后面对它们进行了逐条试探,有 " + nSuccessCount.ToString() + " 条记录符合预期的要求,册中借阅信息得到增强。借阅信息得到增强的册记录路径如下: " + strTempError; return(1); } else { strError = "册条码号 '" + strItemBarcode + "' 检索命中" + aPath.Count.ToString() + "条册记录: " + StringUtil.MakePathList(aPath) + ",后面对它们进行了逐条试探,但是没有一条记录符合预期的要求。试探过程报错如下: " + strTempError; return(-1); } /* * result.Value = -1; * result.ErrorInfo = "册条码号为 '" + strItemBarcode + "' 的册记录有 " + aPath.Count.ToString() + " 条,无法进行修复操作。请在附加册记录路径后重新提交修复操作。"; * result.ErrorCode = ErrorCode.ItemBarcodeDup; * * aDupPath = new string[aPath.Count]; * aPath.CopyTo(aDupPath); * return result; * */ } else { Debug.Assert(nRet == 1, ""); Debug.Assert(aPath.Count == 1, ""); if (nRet == 1) { strOutputItemRecPath = aPath[0]; } } } XmlDocument itemdom = null; nRet = LibraryApplication.LoadToDom(strItemXml, out itemdom, out strError); if (nRet == -1) { strError = "装载册记录进入XML DOM时发生错误: " + strError; return(-1); } // 校验册条码号参数是否和XML记录中完全一致 string strTempItemBarcode = DomUtil.GetElementText(itemdom.DocumentElement, "barcode"); if (strItemBarcode != strTempItemBarcode) { strError = "修改册记录ModifyEntityRecord()操作被拒绝。因册条码号参数 '" + strItemBarcode + "' 和册记录中<barcode>元素内的册条码号值 '" + strTempItemBarcode + "' 不一致。"; return(-1); } // 看看册记录中是否有指回读者记录的链 string strBorrower = DomUtil.GetElementText(itemdom.DocumentElement, "borrower"); if (strBorrower != strReaderBarcode) { // strError = "ModifyEntityRecord()操作被拒绝。您所请求要修复的链,本是一条完整正确的链。可直接进行普通还书操作。"; strError = "修改册记录ModifyEntityRecord()操作被拒绝。因册记录 " + strOutputItemRecPath + " 中的[borrower]值 '" + strBorrower + "' 和发源(来找册条码号 '" + strItemBarcode + "')的读者证条码号 '" + strReaderBarcode + "' 不一致,不能构成一条完整正确的链。请及时排除此故障。"; return(-1); } // 2007/1/1注:应当看看记录中<borrower>元素是否有内容才改写<borrowDate>和<borrowPeriod>元素。 DomUtil.SetElementText(itemdom.DocumentElement, "borrowDate", strBorrowDate); DomUtil.SetElementText(itemdom.DocumentElement, "borrowPeriod", strBorrowPeriod); #if NO if (channel == null) { channel = Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; return(-1); } } #endif 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) { if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { nRedoCount++; if (nRedoCount > 10) { strError = "ModifyEntityRecord()写回册记录的时候,遇到时间戳冲突,并因此重试10次,仍失败..."; return(-1); } goto REDO_CHANGE; } return(-1); } // end of 写回册记录失败 return(1); }
// 检索实用库记录的路径和记录体 // return: // -1 error(注:检索命中多条情况被当作错误返回) // 0 not found // 1 found public int SearchUtilPathAndRecord( // RmsChannelCollection Channels, RmsChannel channel, string strDbName, string strKey, string strFrom, out string strPath, out string strXml, out byte[] timestamp, out string strError) { strError = ""; strPath = ""; strXml = ""; timestamp = null; if (String.IsNullOrEmpty(strDbName) == true) { strError = "尚未指定库名"; return(-1); } string strQueryXml = "<target list='" + StringUtil.GetXmlStringSimple(strDbName + ":" + strFrom) // 2007/9/14 + "'><item><word>" + StringUtil.GetXmlStringSimple(strKey) + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang></target>"; // 获得通用记录 // 本函数可获得超过1条以上的路径 // return: // -1 error // 0 not found // 1 命中1条 // >1 命中多于1条 int nRet = GetRecXml( // Channels, channel, strQueryXml, out strXml, 2, out List <string> aPath, out timestamp, out strError); if (nRet == -1) { strError = "检索库 " + strDbName + " 时出错: " + strError; return(-1); } if (nRet == 0) { return(0); // 没有找到 } /* * if (nRet > 1) * { * strError = "以检索键 '" + strKey + "' 检索库 " + strDbName + " 时命中 " + Convert.ToString(nRet) + " 条,属于不正常情况。请修改库 '" + strDbName + "' 中相应记录,确保同一键值只有一条对应的记录。"; * return -1; * } * */ Debug.Assert(aPath.Count >= 1, ""); strPath = aPath[0]; return(1); }
// 将刚从dt1000升级上来的读者和实体记录进行交叉处理 // parameters: // nStart 从第几个借阅的册事项开始处理 // nCount 共处理几个借阅的册事项 // nProcessedBorrowItems [out]本次处理了多少个借阅册事项 // nTotalBorrowItems [out]当前读者一共包含有多少个借阅册事项 // result.Value // -1 错误。 // 0 成功。 // 1 有警告 public LibraryServerResult CrossRefBorrowInfo( // RmsChannelCollection Channels, RmsChannel channel, string strReaderBarcode, int nStart, int nCount, out int nProcessedBorrowItems, out int nTotalBorrowItems) { string strError = ""; nTotalBorrowItems = 0; nProcessedBorrowItems = 0; int nRet = 0; string strWarning = ""; int nRedoCount = 0; // string strCheckError = ""; LibraryServerResult result = new LibraryServerResult(); // int nErrorCount = 0; REDO_CHANGE_READERREC: // 加读者记录锁 #if DEBUG_LOCK_READER this.WriteErrorLog("CrossRefBorrowInfo 开始为读者加写锁 '" + strReaderBarcode + "'"); #endif this.ReaderLocks.LockForWrite(strReaderBarcode); try // 读者记录锁定范围开始 { // 读入读者记录 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) { result.Value = -1; result.ErrorInfo = "读者证条码号 '" + strReaderBarcode + "' 不存在"; result.ErrorCode = ErrorCode.ReaderBarcodeNotFound; return(result); } if (nRet == -1) { strError = "读入读者记录时发生错误: " + strError; goto ERROR1; } XmlDocument readerdom = null; nRet = LibraryApplication.LoadToDom(strReaderXml, out readerdom, out strError); if (nRet == -1) { strError = "装载读者记录进入XML DOM时发生错误: " + strError; goto ERROR1; } bool bReaderRecChanged = false; // 修改读者记录中overdues/overdue中的价格单位,并加入id // return: // -1 error // 0 not changed // 1 changed nRet = ModifyReaderRecord( ref readerdom, out strWarning, out strError); if (nRet == -1) { goto ERROR1; } if (nRet == 1) { bReaderRecChanged = true; } // TODO: strWarning内容如何处理? XmlNodeList nodesBorrow = readerdom.DocumentElement.SelectNodes("borrows/borrow"); nTotalBorrowItems = nodesBorrow.Count; if (nTotalBorrowItems == 0) { result.Value = 0; result.ErrorInfo = "读者记录中没有借还信息。"; return(result); } if (nStart >= nTotalBorrowItems) { strError = "nStart参数值" + nStart.ToString() + "大于当前读者记录中的借阅册个数" + nTotalBorrowItems.ToString(); goto ERROR1; } nProcessedBorrowItems = 0; for (int i = nStart; i < nTotalBorrowItems; i++) { if (nCount != -1 && nProcessedBorrowItems >= nCount) { break; } // 一个API最多做10条 if (nProcessedBorrowItems >= 10) { break; } XmlNode nodeBorrow = nodesBorrow[i]; string strItemBarcode = DomUtil.GetAttr(nodeBorrow, "barcode"); nProcessedBorrowItems++; if (String.IsNullOrEmpty(strItemBarcode) == true) { strWarning += "读者记录中<borrow>元素barcode属性值不能为空; "; continue; } string strBorrowDate = DomUtil.GetAttr(nodeBorrow, "borrowDate"); string strBorrowPeriod = DomUtil.GetAttr(nodeBorrow, "borrowPeriod"); if (String.IsNullOrEmpty(strBorrowDate) == true) { strWarning += "读者记录中<borrow>元素borrowDate属性不能为空; "; continue; } if (String.IsNullOrEmpty(strBorrowPeriod) == true) { strWarning += "读者记录中<borrow>元素borrowPeriod属性不能为空; "; continue; } // 把实体记录借阅信息详细化 // return: // 0 册条码号没有找到对应的册记录 // 1 成功 nRet = ModifyEntityRecord( // Channels, channel, null, // strEntityRecPath strItemBarcode, strReaderBarcode, strBorrowDate, strBorrowPeriod, out strError); if (nRet == -1) { strWarning += "ModifyEntityRecord() [strItemBarcode='" + strItemBarcode + "' strReaderBarcode='" + strReaderBarcode + "'] error : " + strError + "; "; continue; } // 2008/10/7 if (nRet == 0) { strWarning += "册条码号 '" + strItemBarcode + "' 对应的记录不存在; "; continue; } } if (bReaderRecChanged == true) { byte[] output_timestamp = null; string strOutputPath = ""; #if NO RmsChannel channel = Channels.GetChannel(this.WsUrl); if (channel == null) { strError = "get channel error"; goto ERROR1; } #endif // 写回读者记录 long lRet = channel.DoSaveTextRes(strOutputReaderRecPath, readerdom.OuterXml, false, "content", // ,ignorechecktimestamp reader_timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { nRedoCount++; if (nRedoCount > 10) { strError = "写回读者记录的时候,遇到时间戳冲突,并因此重试10次,仍失败..."; goto ERROR1; } goto REDO_CHANGE_READERREC; } goto ERROR1; } // 及时更新时间戳 reader_timestamp = output_timestamp; } } finally { this.ReaderLocks.UnlockForWrite(strReaderBarcode); #if DEBUG_LOCK_READER this.WriteErrorLog("CrossRefBorrowInfo 结束为读者加写锁 '" + strReaderBarcode + "'"); #endif } if (String.IsNullOrEmpty(strWarning) == false) { result.Value = 1; result.ErrorInfo = strWarning; } else { result.Value = 0; } return(result); ERROR1: result.Value = -1; result.ErrorInfo = strError; result.ErrorCode = ErrorCode.SystemError; return(result); }
private void CfgFileEditDlg_Load(object sender, System.EventArgs e) { button_export.Enabled = false; MemoryStream stream = null; string strMetaData; string strError = ""; string strMime = ""; Hashtable values = null; if (Obj != null) { if (this.Obj.Content != null) { stream = new MemoryStream(this.Obj.Content); this.Stream = stream; this.Stream.Seek(0, SeekOrigin.Begin); button_export.Enabled = true; } this.TimeStamp = this.Obj.TimeStamp; strMetaData = this.Obj.Metadata; // 观察mime // 取metadata values = StringUtil.ParseMetaDataXml(strMetaData, out strError); if (values == null) { MessageBox.Show(this, strError); return; } strMime = (string)values["mimetype"]; if (strMime == null || strMime == "") { strMime = "text"; } this.Mime = strMime; this.LocalPath = (string)values["localpath"]; if (this.LocalPath == null) { this.LocalPath = ""; } this.textBox_content.Text = ""; // string strFirstPart = StringUtil.GetFirstPartPath(ref strMime); if (this.IsText == true) { if (this.Stream != null) { this.Stream.Seek(0, SeekOrigin.Begin); using (StreamReader sr = new StreamReader(this.Stream, Encoding.UTF8)) { this.textBox_content.Text = ConvertCrLf(sr.ReadToEnd()); } } } else { } ////// button_OK.Enabled = false; this.textBox_content.SelectionStart = 0; this.textBox_content.SelectionLength = 0; return; } this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在下载配置文件: " + this.Path); stop.BeginLoop(); } // string strContent = ""; byte[] baTimeStamp = null; string strOutputPath; string strStyle = "content,data,metadata,timestamp,outputpath"; // string strStyle = "attachment,data,metadata,timestamp,outputpath"; stream = new MemoryStream(); long lRet = channel.GetRes( this.Path, stream, stop, // stop, strStyle, null, // byte [] input_timestamp, out strMetaData, out baTimeStamp, out strOutputPath, out strError); /* * long lRet = channel.GetRes(( * this.Path, * out strContent, * out strMetaData, * out baTimeStamp, * out strOutputPath, * out strError); */ if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); } if (lRet == -1) { MessageBox.Show(this, strError); goto FINISH; } this.Stream = stream; this.Stream.Seek(0, SeekOrigin.Begin); button_export.Enabled = true; this.TimeStamp = baTimeStamp; // 观察mime // 取metadata values = StringUtil.ParseMetaDataXml(strMetaData, out strError); if (values == null) { MessageBox.Show(this, strError); goto FINISH; } strMime = (string)values["mimetype"]; if (strMime == null || strMime == "") { strMime = "text"; } this.Mime = strMime; this.LocalPath = (string)values["localpath"]; if (this.LocalPath == null) { this.LocalPath = ""; } // string strFirstPart = StringUtil.GetFirstPartPath(ref strMime); if (this.IsText == true) { this.Stream.Seek(0, SeekOrigin.Begin); using (StreamReader sr = new StreamReader(this.Stream, Encoding.UTF8)) { this.textBox_content.Text = ConvertCrLf(sr.ReadToEnd()); } // 注意,此后 this.Stream 被关闭 } else { //this.textBox_content.Text = "<二进制内容无法直接编辑>"; //this.textBox_content.ReadOnly = true; //this.button_format.Enabled = false; } ////// button_OK.Enabled = false; FINISH: if (stopManager != null && stop != null) { stop.Unregister(); // 和容器关联 stop = null; } this.channel = null; this.textBox_content.SelectionStart = 0; this.textBox_content.SelectionLength = 0; }
// parameters: // cfg_dom 装入了 library.xml 的 XmlDocument 对象 // strDbName 被删除的数据库名 // return: // -1 验证过程出现错误(也就是说验证过程没有来的及完成) // 0 验证发现不正确 // 1 验证发现正确 public int VerifyDatabaseDelete( RmsChannel channel, string strDbType, string strDbName, out string strError) { int nRet = ServerDatabaseUtility.VerifyDatabaseDelete(this.LibraryCfgDom, strDbType, strDbName, out strError); if (nRet == -1) { return(-1); } if (string.IsNullOrEmpty(strDbType) == true) { strError = "strDbType 参数值不应为空"; return(-1); } if (string.IsNullOrEmpty(strDbName) == true) { strError = "strDbName 参数值不应为空"; return(-1); } // 实用库 // 不用再验证。因为数据库名信息都在 LibraryCfgDom 里面了,上面已经验证过了 string strDbTypeCaption = ServerDatabaseUtility.GetTypeCaption(strDbType); // 单个数据库 if (ServerDatabaseUtility.IsSingleDbType(strDbType)) { string dbname = GetSingleDbName(strDbType); if (string.IsNullOrEmpty(dbname) == false) { strError = "删除完成后," + strDbTypeCaption + "库名 '" + strDbName + "' 在 LibraryApplication 的 相应成员(.???DbName)内没有清理干净"; return(0); } } // 书目库 if (strDbType == "biblio") { // TODO: 在内存结构里面验证 } // 单个书目库下属库 if (ServerDatabaseUtility.IsBiblioSubType(strDbType) == true) { // TODO: 在内存结构里面验证 } if (strDbType == "reader") { // TODO: 在内存结构里面验证 } // 验证 dp2kernel 一端数据库是否被删除 if (channel != null) { // 数据库是否已经存在? // return: // -1 error // 0 not exist // 1 exist // 2 其他类型的同名对象已经存在 nRet = DatabaseUtility.IsDatabaseExist( channel, strDbName, out strError); if (nRet == -1) { strError = "验证物理数据库 '" + strDbName + "' 在 dp2kernel 一端是否成功删除时发生错误: " + strError; return(-1); } if (nRet >= 1) { strError = "物理数据库 '" + strDbName + "' 在 dp2kernel 一端未被删除: " + strError; return(-1); } } return(1); }
// 根据数据库模板的定义,创建一个数据库 // parameters: // strTempDir 将创建数据库过程中,用到的配置文件会自动汇集拷贝到此目录。如果 == null,则不拷贝 public static int CreateDatabase(RmsChannel channel, string strTemplateDir, string strDatabaseName, string strTempDir, out string strError) { strError = ""; int nRet = 0; List <string[]> logicNames = new List <string[]>(); string[] cols = new string[2]; cols[1] = "zh"; cols[0] = strDatabaseName; logicNames.Add(cols); string strKeysDefFileName = PathUtil.MergePath(strTemplateDir, "keys"); string strBrowseDefFileName = PathUtil.MergePath(strTemplateDir, "browse"); nRet = FileUtil.ConvertGb2312TextfileToUtf8(strKeysDefFileName, out strError); if (nRet == -1) { return(-1); } CopyTempFile(strKeysDefFileName, strTempDir, strDatabaseName); nRet = FileUtil.ConvertGb2312TextfileToUtf8(strBrowseDefFileName, out strError); if (nRet == -1) { return(-1); } CopyTempFile(strBrowseDefFileName, strTempDir, strDatabaseName); string strKeysDef = ""; string strBrowseDef = ""; try { using (StreamReader sr = new StreamReader(strKeysDefFileName, Encoding.UTF8)) { strKeysDef = sr.ReadToEnd(); } } catch (Exception ex) { strError = "装载文件 " + strKeysDefFileName + " 时发生错误: " + ex.Message; return(-1); } try { using (StreamReader sr = new StreamReader(strBrowseDefFileName, Encoding.UTF8)) { strBrowseDef = sr.ReadToEnd(); } } catch (Exception ex) { strError = "装载文件 " + strBrowseDefFileName + " 时发生错误: " + ex.Message; return(-1); } long lRet = channel.DoCreateDB(logicNames, "", // strType, "", // strSqlDbName, strKeysDef, strBrowseDef, out strError); if (lRet == -1) { strError = "创建数据库 " + strDatabaseName + " 时发生错误: " + strError; return(-1); } lRet = channel.DoInitialDB(strDatabaseName, out strError); if (lRet == -1) { strError = "初始化数据库 " + strDatabaseName + " 时发生错误: " + strError; return(-1); } // 增补其他数据从属对象 /* * List<string> subdirs = new List<string>(); * // 创建所有目录对象 * GetSubdirs(strTemplateDir, ref subdirs); * for (int i = 0; i < subdirs.Count; i++) * { * string strDiskPath = subdirs[i]; * * // 反过来推算为逻辑路径 * // 或者预先在获得的数组中就存放为部分(逻辑)路径? * string strPath = ""; * * // 在服务器端创建对象 * // parameters: * // strStyle 风格。当创建目录的时候,为"createdir",否则为空 * // return: * // -1 错误 * // 1 以及存在同名对象 * // 0 正常返回 * nRet = NewServerSideObject( * channel, * strPath, * "createdir", * null, * null, * out strError); * if (nRet == -1) * return -1; * } * // 列出每个目录中的文件,并在服务器端创建之 * // 注意模板目录下的文件,被当作cfgs中的文件来创建 * */ DirectoryInfo di = new DirectoryInfo(strTemplateDir); FileInfo[] fis = di.GetFiles(); // 创建所有文件对象 for (int i = 0; i < fis.Length; i++) { string strName = fis[i].Name; if (strName == "." || strName == "..") { continue; } if (strName.ToLower() == "keys" || strName.ToLower() == "browse") { continue; } string strFullPath = fis[i].FullName; nRet = FileUtil.ConvertGb2312TextfileToUtf8(strFullPath, out strError); if (nRet == -1) { return(-1); } CopyTempFile(strFullPath, strTempDir, strDatabaseName); using (Stream s = new FileStream(strFullPath, FileMode.Open)) { string strPath = strDatabaseName + "/cfgs/" + strName; // 在服务器端创建对象 // parameters: // strStyle 风格。当创建目录的时候,为"createdir",否则为空 // return: // -1 错误 // 1 以及存在同名对象 // 0 正常返回 nRet = NewServerSideObject( channel, strPath, "", s, null, out strError); if (nRet == -1) { return(-1); } } } return(0); }
// 一次操作循环 public override void Worker() { // 系统挂起的时候,不运行本线程 // 2007/12/18 if (this.App.ContainsHangup("LogRecover") == true) { return; } // 2012/2/4 if (this.App.PauseBatchTask == true) { return; } if (string.IsNullOrEmpty(this.App.ArrivedDbName)) { this.AppendResultText("启动失败: 当前 library.xml 中没有配置预约到书库参数\r\n"); return; } bool bFirst = true; string strError = ""; int nRet = 0; BatchTaskStartInfo startinfo = this.StartInfo; if (startinfo == null) { startinfo = new BatchTaskStartInfo(); // 按照缺省值来 } // 通用启动参数 nRet = ParseArriveMonitorParam(startinfo.Param, out bool bLoop, out strError); if (nRet == -1) { this.AppendResultText("启动失败: " + strError + "\r\n"); return; } this.Loop = bLoop; string strID = ""; nRet = ParseArriveMonitorStart(startinfo.Start, out strID, out strError); if (nRet == -1) { this.AppendResultText("启动失败: " + strError + "\r\n"); this.Loop = false; return; } //// // bool bPerDayStart = false; // 是否为每日一次启动模式 string strMonitorName = "arriveMonitor"; { string strLastTime = ""; nRet = ReadLastTime( strMonitorName, out strLastTime, out strError); if (nRet == -1) { string strErrorText = "从文件中获取 " + strMonitorName + " 每日启动时间时发生错误: " + strError; this.AppendResultText(strErrorText + "\r\n"); this.App.WriteErrorLog(strErrorText); return; } string strStartTimeDef = ""; // bRet 是否到了每日启动时间 bool bRet = false; string strOldLastTime = strLastTime; // return: // -2 strLastTime 格式错误 // -1 一般错误 // 0 没有找到startTime配置参数 // 1 找到了startTime配置参数 nRet = IsNowAfterPerDayStart( strMonitorName, ref strLastTime, out bRet, out strStartTimeDef, out strError); if (nRet == -1 || nRet == -2) { string strErrorText = "获取 " + strMonitorName + " 每日启动时间时发生错误: " + strError; this.AppendResultText(strErrorText + "\r\n"); this.App.WriteErrorLog(strErrorText); if (nRet == -2) { WriteLastTime(strMonitorName, ""); } return; } // 如果nRet == 0,表示没有配置相关参数,则兼容原来的习惯,每次都作 if (nRet == 0) { } else if (nRet == 1) { if (bRet == false) { if (this.ManualStart == true) { this.AppendResultText("已试探启动任务 '" + this.Name + "',但因没有到每日启动时间 " + strStartTimeDef + " 而未能启动。(上次任务处理结束时间为 " + DateTimeUtil.LocalTime(strLastTime) + ")\r\n"); } // 2014/3/31 if (string.IsNullOrEmpty(strOldLastTime) == true && string.IsNullOrEmpty(strLastTime) == false) { this.AppendResultText("史上首次启动此任务。已把当前时间当作上次任务处理结束时间 " + DateTimeUtil.LocalTime(strLastTime) + " 写入了断点记忆文件\r\n"); WriteLastTime(strMonitorName, strLastTime); } return; // 还没有到每日时间 } bPerDayStart = true; } this.App.WriteErrorLog((bPerDayStart == true ? "(定时)" : "(不定时)") + strMonitorName + " 启动。"); } this.AppendResultText("开始新一轮循环\r\n"); RmsChannel channel = this.RmsChannels.GetChannel(this.App.WsUrl); this._calendarTable.Clear(); int nRecCount = 0; for (; ; nRecCount++) { #if NO // 系统挂起的时候,不运行本线程 // 2008/2/4 if (this.App.HangupReason == HangupReason.LogRecover) { break; } #endif if (this.Stopped == true) { break; } string strStyle = ""; strStyle = "data,content,timestamp,outputpath"; if (bFirst == true) { strStyle += ""; } else { strStyle += ",next"; } string strPath = this.App.ArrivedDbName + "/" + strID; string strXmlBody = ""; string strMetaData = ""; string strOutputPath = ""; byte[] baOutputTimeStamp = null; // this.SetProgressText((nRecCount + 1).ToString() + " " + strPath); this.AppendResultText("正在处理 " + (nRecCount + 1).ToString() + " " + strPath + "\r\n"); // 获得资源 // return: // -1 出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。 // 0 成功 long lRet = channel.GetRes(strPath, strStyle, out strXmlBody, out strMetaData, out baOutputTimeStamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) { if (bFirst == true) { // 第一条没有找到, 但是要强制循环进行 bFirst = false; goto CONTINUE; } else { if (bFirst == true) { strError = "记录 " + strID + " 不存在。处理结束。"; } else { strError = "记录 " + strID + " 是最末一条记录。处理结束。"; } break; } } else if (channel.ErrorCode == ChannelErrorCode.EmptyRecord) { bFirst = false; // 把id解析出来 strID = ResPath.GetRecordId(strOutputPath); goto CONTINUE; } goto ERROR1; } #if NO string strLibraryCode = ""; nRet = this.App.GetLibraryCode(strOutputPath, // ???? BUG out strLibraryCode, out strError); if (nRet == -1) { goto ERROR1; } #endif bFirst = false; // 把id解析出来 strID = ResPath.GetRecordId(strOutputPath); // 处理 nRet = DoOneRecord( // calendar, strOutputPath, strXmlBody, baOutputTimeStamp, out strError); if (nRet == -1) { goto ERROR1; } CONTINUE: continue; } // end of for this.AppendResultText("循环结束。共处理 " + nRecCount.ToString() + " 条记录。\r\n"); { Debug.Assert(this.App != null); // 写入文件,记忆已经做过的当日时间 string strLastTime = DateTimeUtil.Rfc1123DateTimeStringEx(this.App.Clock.UtcNow.ToLocalTime()); // 2007/12/17 changed // DateTime.UtcNow // 2012/5/27 WriteLastTime(strMonitorName, strLastTime); string strErrorText = (bPerDayStart == true ? "(定时)" : "(不定时)") + strMonitorName + "结束。共处理记录 " + nRecCount.ToString() + " 个。"; this.App.WriteErrorLog(strErrorText); } return; ERROR1: this.AppendResultText("预约到书管理 后台任务出错: " + strError + "\r\n"); this.App.WriteErrorLog("预约到书管理 后台任务出错: " + strError); return; }
int RebuildDatabase(BreakPointInfo info, out string strError) { strError = ""; RmsChannel channel = RmsChannels.GetChannel(this.App.WsUrl); if (channel == null) { strError = "get channel error"; return(-1); } // 恢复为最大范围 string strStartNo = "1"; string strEndNo = "9999999999"; string strOutputStartNo = ""; string strOutputEndNo = ""; if (string.IsNullOrEmpty(info.RecID) == false) { strStartNo = info.RecID; } // 校验起止号 // return: // 0 不存在记录 // 1 存在记录 int nRet = VerifyRange(channel, info.DbName, strStartNo, strEndNo, out strOutputStartNo, out strOutputEndNo, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { return(0); } strStartNo = strOutputStartNo; strEndNo = strOutputEndNo; Int64 nStart; Int64 nEnd; Int64 nCur; if (Int64.TryParse(strStartNo, out nStart) == false) { strError = "数据库 '" + info.DbName + "' 起始记录 ID '" + strStartNo + "' 不合法"; return(-1); } if (Int64.TryParse(strEndNo, out nEnd) == false) { strError = "数据库 '" + info.DbName + "' 结束记录 ID '" + strEndNo + "' 不合法"; return(-1); } // Refresh数据库定义 long lRet = channel.DoRefreshDB( "begin", info.DbName, false, // bClearKeysAtBegin == true ? true : false, out strError); if (lRet == -1) { return(-1); } string strID = strStartNo; try { bool bFirst = true; // 是否为第一次取记录 // 循环 for (; ;) { if (this.Stopped == true) { strError = "中断"; return(-1); } // string strDirectionComment = ""; string strStyle = ""; strStyle = "timestamp,outputpath"; // 优化 strStyle += ",forcedeleteoldkeys"; if (bFirst == true) { // 注:如果不校验首号,只有强制循环的情况下,才能不需要next风格 strStyle += ""; } else { strStyle += ",next"; // strDirectionComment = "的后一条记录"; } string strPath = info.DbName + "/" + strID; string strOutputPath = ""; bool bFoundRecord = false; bool bNeedRetry = true; int nRedoCount = 0; REDO_REBUILD: // 获得资源 // return: // -1 出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。 // 0 成功 lRet = channel.DoRebuildResKeys(strPath, strStyle, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.NotFound) { if (bFirst == true) { // 如果不要强制循环,此时也不能结束,否则会让用户以为数据库里面根本没有数据 // AutoCloseMessageBox.Show(this, "您为数据库 " + info.DbName + " 指定的首记录 " + strID + strDirectionComment + " 不存在。\r\n\r\n(注:为避免出现此提示,可在操作前勾选“校准首尾ID”)\r\n\r\n按 确认 继续向后找..."); bFirst = false; goto CONTINUE; } else { Debug.Assert(bFirst == false, ""); if (bFirst == true) { strError = "记录 " + strID + "(后一条) 不存在。处理结束。"; } else { strError = "记录 " + strID + " 是最末一条记录。处理结束。"; } return(0); } } else if (channel.ErrorCode == ChannelErrorCode.EmptyRecord) { bFirst = false; // bFoundRecord = false; // 把id解析出来 strID = ResPath.GetRecordId(strOutputPath); goto CONTINUE; } // 允许重试 if (bNeedRetry == true) { if (nRedoCount < 10) { nRedoCount++; goto REDO_REBUILD; } } else { return(-1); } } // end of nRet == -1 bFirst = false; bFoundRecord = true; // 把id解析出来 strID = ResPath.GetRecordId(strOutputPath); info.RecID = strID; // 记忆 // 每 100 条显示一行 if ((m_nRecordCount % 100) == 0) { this.AppendResultText("已重建检索点 记录 " + strOutputPath + " " + (m_nRecordCount + 1).ToString() + "\r\n"); } #if NO if (String.IsNullOrEmpty(strRealStartNo) == true) { strRealStartNo = strID; } strRealEndNo = strID; #endif CONTINUE: // 是否超过循环范围 if (Int64.TryParse(strID, out nCur) == false) { strError = "数据库 '" + info.DbName + "' 当前记录 ID '" + strID + "' 不合法"; return(-1); } #if NO try { nCur = Convert.ToInt64(strID); } catch { // ??? nCur = 0; } #endif if (nCur > nEnd) { break; } if (bFoundRecord == true) { m_nRecordCount++; } // // SetProgressText((nCur - nStart + 1).ToString()); // 对已经作过的进行判断 if (nCur >= nEnd) { break; } } } finally { #if NO if (bClearKeysAtBegin == true) { // 结束Refresh数据库定义 lRet = channel.DoRefreshDB( "end", info.DbName, false, // 此参数此时无用 out strError); if (lRet == -1) { return(-1); } } #endif } return(0); }
// 获得一行信息 int GetLineInfo( RmsChannel channel, string strPath, out string strSender, out string strRecipient, out string strSubject, out string strDate, out string strSize, out bool bTouched, out string strError) { strSender = ""; strRecipient = ""; strSubject = ""; strDate = ""; strSize = ""; bTouched = false; strError = ""; // 将种记录数据从XML格式转换为HTML格式 string strMetaData = ""; byte[] timestamp = null; string strXml = ""; string strOutputPath = ""; long lRet = channel.GetRes(strPath, out strXml, out strMetaData, out timestamp, out strOutputPath, out strError); if (lRet == -1) { // text-level: 内部错误 strError = "获得消息记录 '" + strPath + "' 时出错: " + strError; return -1; } XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXml); } catch (Exception ex) { // text-level: 内部错误 strError = "装载XML记录进入DOM时出错: " + ex.Message; return -1; } strSender = DomUtil.GetElementText(dom.DocumentElement, "sender"); strRecipient = DomUtil.GetElementText(dom.DocumentElement, "recipient"); strSubject = DomUtil.GetElementText(dom.DocumentElement, "subject"); strDate = DomUtil.GetElementText(dom.DocumentElement, "date"); strDate = DateTimeUtil.LocalTime(strDate); strSize = DomUtil.GetElementText(dom.DocumentElement, "size"); string strTouched = DomUtil.GetElementText(dom.DocumentElement, "touched"); if (strTouched == "1") bTouched = true; else bTouched = false; return 0; }