// 初始化用户集合对象 // parameters: // userDbs 帐户库集合 // strError out参数,返回出错信息 // return: // -1 出错 // 0 成功 // 线:安全的 public int Initial( KernelApplication app, //DatabaseCollection dbs, out string strError) { strError = ""; // this.m_dbs = dbs; this.KernelApplication = app; //*********对帐户集合加写锁**************** m_lock.AcquireWriterLock(m_nTimeOut); #if DEBUG_LOCK this.m_dbs.WriteDebugInfo("Initial(),对用户集合加写锁。"); #endif try { // 清空成员 this.Clear(); } finally { m_lock.ReleaseWriterLock(); //解写锁 #if DEBUG_LOCK this.m_dbs.WriteDebugInfo("Initial(),对用户集合解写锁。"); #endif } return(0); }
// 初始化用户对象 // parameters: // strError out参数,返回出错信息 // return: // -1 出错 // 0 成功 public int Initial(KernelApplication app, string strSessionID, string strIP, string strVia, out string strError) { strError = ""; this.app = app; this.ClientIP = strIP; this.UserName = ""; Debug.Assert(string.IsNullOrEmpty(app.SessionDir) == false, ""); #if USE_TEMPDIR this.m_strTempDir = PathUtil.MergePath(app.SessionDir, this.GetHashCode().ToString()); PathUtil.CreateDirIfNeed(this.m_strTempDir); #endif return(0); }
public BatchTask(KernelApplication app, string strName) { if (String.IsNullOrEmpty(strName) == true) { this.Name = this.DefaultName; } else { this.Name = strName; } this.ID = Guid.NewGuid().ToString(); this.App = app; // TODO: 在指定目录中获得临时文件 this.ProgressFileName = Path.GetTempFileName(); // TODO: 改为在指定目录创建临时文件 try { // 如果文件存在,就打开,如果文件不存在,就创建一个新的 m_stream = File.Open( this.ProgressFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); this.ProgressFileVersion = DateTime.Now.Ticks; } catch (Exception ex) { string strError = "打开或创建文件 '" + this.ProgressFileName + "' 发生错误: " + ex.Message; throw new Exception(strError); } m_stream.Seek(0, SeekOrigin.End); }
// 从结果集中提取指定范围的记录 // parameter: // strRanges 范围 // strStyle 样式,以逗号分隔,id:表示取id,cols表示取浏览格式,xml表示取xml记录体 // strLang 语言版本,用来获得记录路径 // richRecords 得到的记录数组,成员为类型为Record // result: // -1 出错 // >=0 结果集的总数 public long API_GetRichRecords( DpResultSet resultset, string strRanges, string strLang, string strStyle, out RichRecord[] richRecords, out string strError) { strError = ""; richRecords = null; int nCurCount = 0; List <RichRecord> aRichRecord = new List <RichRecord>(); string strFormat = StringUtil.GetStyleParam(strStyle, "format"); RangeList rangeList = new RangeList(strRanges); for (int i = 0; i < rangeList.Count; i++) { RangeItem rangeItem = (RangeItem)rangeList[i]; int nStart = (int)rangeItem.lStart; int nLength = (int)rangeItem.lLength; if (nLength == 0) { continue; } // long lPos = 0; // 应该用快速方式,不应用[]??? 2006/3/29 for (int j = 0; j < nLength; j++) { int nRet = 0; DpRecord dpRecord = resultset[j + nStart]; RichRecord richRecord = new RichRecord(); DbPath dbpath = new DbPath(dpRecord.ID); Database db = this.app.Dbs.GetDatabaseSafety(dbpath.Name); if (db == null) //也应放到本条的记录出错信息里 { strError = "没有找到数据库'" + dbpath.Name + "',换语言版本时出错"; richRecord.Result.Value = -1; richRecord.Result.ErrorCode = KernelApplication.Ret2ErrorCode(nRet); richRecord.Result.ErrorString = strError; } else { // 记录路径 if (StringUtil.IsInList("id", strStyle, true) == true || StringUtil.IsInList("path", strStyle, true) == true) { richRecord.Path = db.GetCaptionSafety(strLang) + "/" + dbpath.CompressedID; } // 浏览列 if (StringUtil.IsInList("cols", strStyle, true) == true) { string[] cols = null; nRet = db.GetCols( strFormat, dbpath.ID10, "", 0, out cols); // 2013/1/14 if (nRet == -1) { if (cols != null && cols.Length > 0) { strError = cols[0]; } else { strError = "GetCols() error"; } return(-1); } richRecord.Cols = cols; } bool bXml = false; bool bTimestamp = false; if (StringUtil.IsInList("xml", strStyle, true) == true) { bXml = true; } if (StringUtil.IsInList("timestamp", strStyle, true) == true) { bTimestamp = true; } if (bXml == true || bTimestamp == true) { string strGetStyle = ""; //"data,timestamp"; // ,outputpath, metadata if (bTimestamp == true) { StringUtil.SetInList(ref strGetStyle, "timestamp", true); } if (bXml == true) { StringUtil.SetInList(ref strGetStyle, "data", true); } int nStart0 = 0; int nLength0 = -1; int nMaxLength = 300 * 1024; // 每次最多获取300K int nTotalLength = 0; string strOutputID = ""; byte[] baTotal = null; byte[] baOutputTimestamp = null; int nAdditionError = 0; string strMetadata = ""; for (; ;) { byte[] baData = null; long lRet = db.GetXml(dbpath.ID, "", // strXPath, nStart0, nLength0, nMaxLength, strGetStyle, out baData, out strMetadata, out strOutputID, out baOutputTimestamp, true, out nAdditionError, out strError); if (lRet <= -1) { richRecord.Result.Value = -1; richRecord.Result.ErrorCode = KernelApplication.Ret2ErrorCode(nAdditionError); // nRet? richRecord.Result.ErrorString = strError; goto CONTINUE; } nTotalLength = (int)lRet; // 如果数据体太大 if (nTotalLength > QUOTA_SIZE) { richRecord.Result.Value = -1; richRecord.Result.ErrorCode = ErrorCodeValue.CommonError; richRecord.Result.ErrorString = "数据超过1M"; goto CONTINUE; } baTotal = ByteArray.Add(baTotal, baData); nStart0 += baData.Length; if (nStart0 >= nTotalLength) { break; } } // 记录体 // 转换成字符串 if (StringUtil.IsInList("xml", strStyle, true) == true) { richRecord.Xml = ByteArray.ToString(baTotal); } // 时间戳? if (StringUtil.IsInList("timestamp", strStyle, true) == true) { richRecord.baTimestamp = baOutputTimestamp; } // string strOutputPath = strDbName + "/" + strOutputID; } // 记录体 if (StringUtil.IsInList("xml", strStyle, true) == true) { /* * nRet = db.GetXmlDataSafety(dbpath.ID, * out richRecord.Xml, * out strError); * if (nRet <= -1) * { * richRecord.Result.Value = -1; * richRecord.Result.ErrorCode = RmswsApplication.Ret2ErrorCode(nRet); * richRecord.Result.ErrorString = strError; * } * */ } } CONTINUE: aRichRecord.Add(richRecord); Thread.Sleep(0); nCurCount++; // 如果超出最大范围,则停止 if (nCurCount >= SessionInfo.MaxRecordsCountPerApi) { break; } } } richRecords = new RichRecord[aRichRecord.Count]; for (int i = 0; i < richRecords.Length; i++) { richRecords[i] = aRichRecord[i]; } return(resultset.Count); }
// 从结果集中提取指定范围的记录 // parameter: // lStart 开始序号 // lLength 长度. -1表示从lStart到末尾 // strLang 语言 // strStyle 样式,以逗号分隔,id:表示取id,cols表示取浏览格式 // 如果包含 format:cfgs/browse 这样的子串,表示指定浏览格式 // aRecord 得到的记录数组,成员为类型为Record // strError out参数,返回出错信息 // result: // -1 出错 // >=0 结果集的总数 public long API_GetRecords( DpResultSet resultSet, long lStart, long lLength, string strLang, string strStyle, out Record[] records, out string strError) { records = null; strError = ""; // DpResultSet resultSet = this.DefaultResultSet; if (resultSet == null) { strError = "GetRecords()出错, resultSet 为 null"; return(-1); } long lTotalPackageLength = 0; // 累计计算要输出的XML记录占据的空间 long lOutputLength; // 检查lStart lLength和resultset.Count之间的关系, // 和每批返回最大元素数限制, 综合得出一个合适的尺寸 // return: // -1 出错 // 0 成功 int nRet = ConvertUtil.GetRealLength((int)lStart, (int)lLength, (int)resultSet.Count, SessionInfo.MaxRecordsCountPerApi,//nMaxCount, out lOutputLength, out strError); if (nRet == -1) { return(-1); } bool bKeyCount = StringUtil.IsInList("keycount", strStyle, true); bool bKeyID = StringUtil.IsInList("keyid", strStyle, true); bool bHasID = StringUtil.IsInList("id", strStyle, true); bool bHasCols = StringUtil.IsInList("cols", strStyle, true); bool bHasKey = StringUtil.IsInList("key", strStyle, true); if (bKeyID == true && bHasID == false && bHasCols == false && bHasKey == false) { strError = "strStyle包含了keyid但是没有包含id/key/cols中任何一个,导致API不返回任何内容,操作无意义"; return(-1); } bool bXml = StringUtil.IsInList("xml", strStyle, true); bool bWithResMetadata = StringUtil.IsInList("withresmetadata", strStyle, true); bool bTimestamp = StringUtil.IsInList("timestamp", strStyle, true); bool bMetadata = StringUtil.IsInList("metadata", strStyle, true); string strFormat = StringUtil.GetStyleParam(strStyle, "format"); List <Record> results = new List <Record>(100); long lPos = -1; // 中间保持不透明的值 for (long i = 0; i < lOutputLength; i++) { DpRecord dpRecord = null; long lIndex = lStart + i; if (lIndex == lStart) { dpRecord = resultSet.GetFirstRecord( lIndex, false, out lPos); } else { // 取元素比[]操作速度快 dpRecord = resultSet.GetNextRecord( ref lPos); } if (dpRecord == null) { break; } Record record = new Record(); if (bKeyCount == true) { record.Path = dpRecord.ID; record.Cols = new string[1]; record.Cols[0] = dpRecord.Index.ToString(); #if NO lTotalPackageLength += record.Path.Length; lTotalPackageLength += record.Cols[0].Length; if (lTotalPackageLength > QUOTA_SIZE && i > 0) { // 响应包的尺寸已经超过 1M,并且已经至少包含了一条记录 break; } #endif goto CONTINUE; } DbPath path = new DbPath(dpRecord.ID); Database db = this.app.Dbs.GetDatabaseSafety(path.Name); if (db == null) { strError = "GetDatabaseSafety()从库id '" + path.Name + "' 找数据库对象失败"; return(-1); } // 如果有必要获得记录体 string strXml = ""; string strMetadata = ""; byte[] baTimestamp = null; if (bXml == true || bTimestamp == true || bMetadata == true) { // 获得一条记录的 XML 字符串 // return: // -1 出错 // -4 未找到记录 // -10 记录局部未找到 // 0 成功 long lRet = GetXmlBody( db, path.ID, bXml, bTimestamp, bMetadata, bWithResMetadata, out strXml, out strMetadata, out baTimestamp, out strError); if (lRet <= -1) { record.RecordBody = new RecordBody(); record.RecordBody.Xml = strXml; record.RecordBody.Metadata = strMetadata; record.RecordBody.Timestamp = baTimestamp; Result result = new Result(); result.Value = -1; result.ErrorCode = KernelApplication.Ret2ErrorCode((int)lRet); result.ErrorString = strError; record.RecordBody.Result = result; goto CONTINUE; // return lRet; } #if NO lTotalPackageLength += strXml.Length; if (string.IsNullOrEmpty(strMetadata) == false) { lTotalPackageLength += strMetadata.Length; } if (baTimestamp != null) { lTotalPackageLength += baTimestamp.Length * 2; } if (lTotalPackageLength > QUOTA_SIZE && i > 0) { // 响应包的尺寸已经超过 1M,并且已经至少包含了一条记录 break; } #endif record.RecordBody = new RecordBody(); record.RecordBody.Xml = strXml; record.RecordBody.Metadata = strMetadata; record.RecordBody.Timestamp = baTimestamp; } if (bKeyID == true) { // string strID = ""; string strKey = ""; // strID = dpRecord.ID; strKey = dpRecord.BrowseText; /* * string strText = dpRecord.ID; * nRet = strText.LastIndexOf(","); * if (nRet != -1) * { * strKey = strText.Substring(0, nRet); * strID = strText.Substring(nRet + 1); * } * else * strID = strText; * */ if (bHasID == true) { // GetCaptionSafety()函数先找到指定语言的库名; // 如果没有找到,就找截短形态的语言的库名; // 再找不到,就用第一种语言的库名。 // 如果连一种语言也没有,则返回库id record.Path = db.GetCaptionSafety(strLang) + "/" + path.CompressedID; // lTotalPackageLength += record.Path.Length; } if (bHasKey == true) { record.Keys = BuildKeyFromArray(strKey); // lTotalPackageLength += GetLength(record.Keys); } if (bHasCols == true) { string[] cols; nRet = db.GetCols( strFormat, path.ID10, strXml, 0, out cols); // 2013/1/14 if (nRet == -1) { if (cols != null && cols.Length > 0) { strError = cols[0]; } else { strError = "GetCols() error"; } return(-1); } record.Cols = cols; // lTotalPackageLength += nRet; } goto CONTINUE; } { if (bHasID == true) { // GetCaptionSafety()函数先找到指定语言的库名; // 如果没有找到,就找截短形态的语言的库名; // 再找不到,就用第一种语言的库名。 // 如果连一种语言也没有,则返回库id record.Path = db.GetCaptionSafety(strLang) + "/" + path.CompressedID; // lTotalPackageLength += record.Path.Length; } // 在不是keyid的风格下(例如keycount,空),cols全部是浏览列 if (bHasCols == true) { string[] cols; nRet = db.GetCols( strFormat, path.ID10, strXml, 0, out cols); // 2013/1/14 if (nRet == -1) { if (cols != null && cols.Length > 0) { strError = cols[0]; } else { strError = "GetCols() error"; } return(-1); } record.Cols = cols; // lTotalPackageLength += nRet; } } CONTINUE: lTotalPackageLength += GetLength(record); if (lTotalPackageLength > QUOTA_SIZE && i > 0) { // 响应包的尺寸已经超过 1M,并且已经至少包含了一条记录 break; } // records[i] = record; results.Add(record); Thread.Sleep(0); // 降低CPU耗用? } records = new Record[results.Count]; results.CopyTo(records); return(resultSet.Count); }
// 关闭 public void Close() { string strError = ""; int nRet = 0; #if NO if (this.DelayTables != null && this.DelayTables.Count != 0) { try { List <RecordBody> results = null; nRet = app.Dbs.API_WriteRecords( this, null, null, "flushkeys", out results, out strError); if (nRet == -1) { this.app.Dbs.KernelApplication.WriteErrorLog("SessionInfo.Close() flushkeys 出错:" + strError); } } catch (Exception ex) { this.app.Dbs.KernelApplication.WriteErrorLog("SessionInfo.Close() flushkeys 抛出异常:" + ex.Message); } } #endif nRet = this.CloseUser(out strError); if (nRet == -1) { try { this.app.Dbs.KernelApplication.WriteErrorLog("SessionInfo.Close()出错:" + strError); } catch { } } this.UserName = ""; // this.DefaultResultSet = null; this.ClearResultSets(); #if USE_TEMPDIR if (String.IsNullOrEmpty(this.m_strTempDir) == false) { try { DirectoryInfo di = new DirectoryInfo(this.m_strTempDir); if (di.Exists == true) { di.Delete(true); } } catch { } } #endif this.app = null; }
// 获得一批记录的浏览格式 // 目前情况是:除了数据库名出错以外,其他小错不会终止循环。浏览的第一列放了表示错误的字符串。 // parameter: // paths 记录路径数组 // strStyle 风格 // aRecord 得到的记录数组,成员为类型为Record // result: // -1 出错 // 0 成功 public int API_GetBrowse(string[] paths, string strStyle, out Record[] records, out string strError) { records = null; strError = ""; int nRet = 0; if (paths == null) { strError = "API_GetBrowse() paths == null"; return(-1); } //定义一个最大数量 ,应该是用尺寸,这里暂时用数组个数计算 //int nMaxCount = 100; bool bHasID = StringUtil.IsInList("id", strStyle); bool bHasCols = StringUtil.IsInList("cols", strStyle); bool bXml = StringUtil.IsInList("xml", strStyle, true); bool bWithResMetadata = StringUtil.IsInList("withresmetadata", strStyle, true); bool bTimestamp = StringUtil.IsInList("timestamp", strStyle, true); bool bMetadata = StringUtil.IsInList("metadata", strStyle, true); string strFormat = StringUtil.GetStyleParam(strStyle, "format"); long lTotalPackageLength = 0; // 累计计算要输出的XML记录占据的空间 List <Record> results = new List <Record>(100); for (long i = 0; i < paths.Length; i++) { Record record = new Record(); string strPath = paths[i]; #if NO DbPath path = new DbPath(strPath); Database db = this.app.Dbs.GetDatabaseSafety(path.Name); if (db == null) { strError = "没有找到数据库'" + path.Name + "',换语言版本时出错"; return(-1); } #endif DatabaseCollection.PathInfo info = null; // 解析资源路径 // return: // -1 一般性错误 // -5 未找到数据库 // -7 路径不合法 // 0 成功 nRet = this.app.Dbs.ParsePath(strPath, out info, out strError); if (nRet < 0) { return(-1); } if (info == null) { strError = "ParsePath() (strPath='" + strPath + "') error, info == null"; return(-1); } if (info.IsConfigFilePath == true) { strError = "路径 '" + strPath + "' 不是记录型的路径"; return(-1); } if (bHasID == true) { record.Path = strPath; } if (bHasCols == true && info.IsObjectPath == false) { if (info.Database == null) { strError = "ParsePath() (strPath='" + strPath + "') error, info.Database == null"; return(-1); } string[] cols; nRet = info.Database.GetCols( strFormat, info.RecordID10, // path.ID10, "", 0, out cols); if (nRet == -1) { if (cols != null && cols.Length > 0) { strError = cols[0]; } else { strError = "GetCols() error"; } return(-1); } record.Cols = cols; } // 如果有必要获得记录体 string strXml = ""; string strMetadata = ""; byte[] baTimestamp = null; if (info.IsObjectPath == false && (bXml == true || bTimestamp == true || bMetadata == true) ) { long lRet = GetXmlBody( info.Database, // db, info.RecordID, // path.ID, bXml, bTimestamp, bMetadata, bWithResMetadata, out strXml, out strMetadata, out baTimestamp, out strError); record.RecordBody = new RecordBody(); record.RecordBody.Xml = strXml; record.RecordBody.Metadata = strMetadata; record.RecordBody.Timestamp = baTimestamp; if (lRet <= -1) { Result result = new Result(); result.Value = -1; result.ErrorCode = KernelApplication.Ret2ErrorCode((int)lRet); result.ErrorString = strError; record.RecordBody.Result = result; // return (int)lRet; } } // 2015/11/14 if (info.IsObjectPath == true && (bTimestamp == true || bMetadata == true) ) { if (info.Database == null) { strError = "ParsePath() (strPath='" + strPath + "') error, info.Database == null"; return(-1); } byte[] buffer = new byte[10]; // return: // -1 出错 // -4 记录不存在 // >=0 资源总长度 long lRet = info.Database.GetObject(info.RecordID, info.ObjectID, 0, 0, -1, strStyle, out buffer, out strMetadata, out baTimestamp, out strError); record.RecordBody = new RecordBody(); record.RecordBody.Xml = ""; record.RecordBody.Metadata = strMetadata; record.RecordBody.Timestamp = baTimestamp; if (lRet <= -1) { Result result = new Result(); result.Value = -1; result.ErrorCode = KernelApplication.Ret2ErrorCode((int)lRet); result.ErrorString = strError; record.RecordBody.Result = result; // return (int)lRet; } } lTotalPackageLength += GetLength(record); if (lTotalPackageLength > QUOTA_SIZE && i > 0) { // 响应包的尺寸已经超过 1M,并且已经至少包含了一条记录 break; } results.Add(record); Thread.Sleep(0); // 降低CPU耗用? } /* * if (paths.Length <= SessionInfo.MaxRecordsCountPerApi) * records = new Record[paths.Length]; * else * records = new Record[SessionInfo.MaxRecordsCountPerApi]; * */ records = new Record[results.Count]; results.CopyTo(records); return(0); }
// 工作线程 public virtual void ThreadMain() { try { WaitHandle[] events = new WaitHandle[2]; events[0] = eventClose; events[1] = eventActive; while (true) { int index = 0; try { index = WaitHandle.WaitAny(events, PerTime, false); } catch (System.Threading.ThreadAbortException /*ex*/) { // this.App.Save(null, false); // 触发保存 // this.App.WriteErrorLog("刚才是ThreadAbortException触发了配置文件保存"); break; } if (index == WaitHandle.WaitTimeout) { // 超时 eventActive.Reset(); Worker(); } else if (index == 0) { break; } else { // 得到激活信号 eventActive.Reset(); Worker(); } // 是否循环? if (this.Loop == false) { break; } } this.ManualStart = false; // 这个变量只在一轮处理中管用 } catch (Exception ex) { string strErrorText = "BatchTask工作线程出现异常: " + ExceptionUtil.GetDebugText(ex); try { this.App.WriteErrorLog(strErrorText); } catch { KernelApplication.WriteWindowsLog(strErrorText); } } finally { eventFinished.Set(); this.m_bClosed = true; } }
// 初始化用户对象 // parameters: // strError out参数,返回出错信息 // return: // -1 出错 // 0 成功 public int Initial(KernelApplication app, string strSessionID, string strIP, string strVia, out string strError) { strError = ""; this.app = app; this.ClientIP = strIP; this.UserName = ""; Debug.Assert(string.IsNullOrEmpty(app.SessionDir) == false, ""); #if USE_TEMPDIR this.m_strTempDir = PathUtil.MergePath(app.SessionDir, this.GetHashCode().ToString()); PathUtil.CreateDirIfNeed(this.m_strTempDir); #endif return 0; }
// 关闭 public void Close() { string strError = ""; int nRet = 0; #if NO if (this.DelayTables != null && this.DelayTables.Count != 0) { try { List<RecordBody> results = null; nRet = app.Dbs.API_WriteRecords( this, null, null, "flushkeys", out results, out strError); if (nRet == -1) { this.app.Dbs.KernelApplication.WriteErrorLog("SessionInfo.Close() flushkeys 出错:" + strError); } } catch (Exception ex) { this.app.Dbs.KernelApplication.WriteErrorLog("SessionInfo.Close() flushkeys 抛出异常:" + ex.Message); } } #endif nRet = this.CloseUser(out strError); if (nRet == -1) { try { this.app.Dbs.KernelApplication.WriteErrorLog("SessionInfo.Close()出错:" + strError); } catch { } } this.UserName = ""; // this.DefaultResultSet = null; this.ClearResultSets(); #if USE_TEMPDIR if (String.IsNullOrEmpty(this.m_strTempDir) == false) { try { DirectoryInfo di = new DirectoryInfo(this.m_strTempDir); if (di.Exists == true) di.Delete(true); } catch { } } #endif this.app = null; }
public RebuildKeysTask(KernelApplication app, string strName) : base(app, strName) { this.Loop = false; }
public RebuildKeysTask(KernelApplication app, string strName) : base(app, strName) { this.Loop = false; }