Exemplo n.º 1
0
 void loader_Prompt(object sender, MessagePromptEventArgs e)
 {
     if (this.Prompt != null)
     {
         this.Prompt(sender, e);
     }
 }
Exemplo n.º 2
0
        Task <GetMd5Result> GetRemoteMd5(CancellationToken token)
        {
            return(Task.Run <GetMd5Result>(() =>
            {
                REDO_MD5:
                int nRet = GetServerFileMD5ByTask(
                    this.Channel,
                    this.Stop,
                    this.ServerFilePath,
                    this.Prompt,
                    token,
                    out byte[] server_md5,
                    out string strError);
                if (nRet != 1)
                {
                    if (nRet == -1)
                    {
                        if (token.IsCancellationRequested)
                        {
                            goto ERROR1;
                        }
                        if (this.Prompt != null &&
                            !(this.Stop != null && this.Stop.IsStopped == true))
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            e.MessageText = "获得服务器文件 '" + this.ServerFilePath + "' 的 MD5 时发生错误: " + strError;
                            e.Actions = "yes,no,cancel";
                            this.Prompt(this, e);
                            if (e.ResultAction == "cancel")
                            {
                                goto ERROR1;
                            }
                            else if (e.ResultAction == "yes")
                            {
                                goto REDO_MD5;
                            }
                            else
                            {
                                goto ERROR1;
                            }
                        }
                        else
                        {
                            goto ERROR1;
                        }
                    }
                    strError = "探测服务器端文件 '" + this.ServerFilePath + "' MD5 时出错: " + strError;
                    goto ERROR1;
                }
                return new GetMd5Result {
                    Value = 0, MD5 = server_md5
                };

                ERROR1:
                return new GetMd5Result {
                    Value = -1, ErrorInfo = strError
                };
            }));
        }
Exemplo n.º 3
0
        long DetectFileLength(long lStart,
                              out string strError)
        {
            byte[] baContent     = null;
            string strMetadata   = "";
            string strOutputPath = "";
            string strStyle      = "content,data";

            byte[] timestamp = null;

REDO:
            long lRet = this.Channel.GetRes(
                this.Stop,
                this.ServerFilePath,
                lStart,
                0,  // nPerLength,
                strStyle,
                out baContent,
                out strMetadata,
                out strOutputPath,
                out timestamp,
                out strError);

            if (lRet == -1)
            {
                if (this.Prompt != null &&
                    !(this.Stop != null && this.Stop.IsStopped == true))
                {
                    MessagePromptEventArgs e = new MessagePromptEventArgs();
                    e.MessageText = "探测服务器文件 '" + this.ServerFilePath + "' 长度时发生错误: " + strError;
                    e.Actions     = "yes,no,cancel";
                    this.Prompt(this, e);
                    if (e.ResultAction == "cancel")
                    {
                        return(-1);
                    }
                    else if (e.ResultAction == "yes")
                    {
                        goto REDO;
                    }
                    else
                    {
                        return(-1);
                    }
                }
                else
                {
                    return(-1);
                }
            }

            return(lRet);
        }
Exemplo n.º 4
0
        // 探测下载状态
        // return:
        //      -1  出错
        //      0   文件没有找到
        //      1   文件找到
        int DetectDownloadState(string strServerPath,
                                out string strResult,
                                out string strError)
        {
            strError  = "";
            strResult = "";

            string strPath = strServerPath + ".~state"; // LibraryServerUtil.STATE_EXTENSION

            string strStyle    = "content,data";
            string strMetadata = "";

            byte[] baOutputTimestamp = null;
            string strOutputPath     = "";

REDO:
            // 获得资源。包装版本 -- 返回字符串版本。
            // return:
            //		strStyle	一般设置为"content,data,metadata,timestamp,outputpath";
            //		-1	出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。
            //		>=0	成功
            long lRet = this.Channel.GetRes(
                this.Stop,
                strPath,
                strStyle,
                out strResult,
                out strMetadata,
                out baOutputTimestamp,
                out strOutputPath,
                out strError);

            if (lRet == -1)
            {
                if (this.Channel.ErrorCode == localhost.ErrorCode.NotFound)
                {
                    return(0);
                }

                if (this.Prompt != null &&
                    !(this.Stop != null && this.Stop.IsStopped == true))
                {
                    MessagePromptEventArgs e = new MessagePromptEventArgs();
                    e.MessageText = "获得服务器文件 '" + strPath + "' 时发生错误: " + strError;
                    e.Actions     = "yes,no,cancel";
                    this.Prompt(this, e);
                    if (e.ResultAction == "cancel")
                    {
                        return(-1);
                    }
                    else if (e.ResultAction == "yes")
                    {
                        goto REDO;
                    }
                    else
                    {
                        return(-1);
                    }
                }
                else
                {
                    return(-1);
                }
            }

            return(1);
        }
Exemplo n.º 5
0
        // TODO: 遇到出错,要删除已经下载的临时文件; 如果是中断,临时文件要保留
        // parameters:
        //      getMd5NewStyle  获得服务器文件 MD5 的时候是否使用新轮询风格? (注:只能对 dp2library 本地文件用新轮询风格)
        void Download(bool getMd5NewStyle)
        {
            string strError = "";

            TimeSpan old_timeout = this.Channel.Timeout;

            this.Channel.Timeout = TimeSpan.FromSeconds(60);
            try
            {
                bool   bNotFound = false;
                string strPath   = this.ServerFilePath;
                string strStyle  = "content,data,metadata,timestamp,outputpath,gzip";

                byte[] baContent = null;

                long lStart     = _stream.Length;
                int  nPerLength = -1;

                // byte[] old_timestamp = null;
                byte[] timestamp = null;

                long lTotalLength = -1;

                for (; ;)
                {
#if NO
                    if (_token.IsCancellationRequested)
                    {
                        strError = "中断";
                        goto ERROR1;
                    }
#endif

                    if (_cancel.IsCancellationRequested)
                    {
                        strError = "中断";
                        goto ERROR1;
                    }

                    if (this.Stop != null && this.Stop.State != 0)
                    {
                        strError = "用户中断";
                        goto ERROR1;
                    }

                    // REDO:

                    string strMessage = "";

                    string strPercent = "";
                    if (lTotalLength != -1)
                    {
                        double ratio = (double)lStart / (double)lTotalLength;
                        strPercent = String.Format("{0,3:N}", ratio * (double)100) + "%";
                    }

                    if (this.Stop != null)
                    {
                        strMessage = "正在下载 " + StringUtil.GetLengthText(lStart) + " / "
                                     + (lTotalLength == -1 ? "?" : StringUtil.GetLengthText(lTotalLength))
                                     + " " + strPercent + " "
                                     + strPath;
                        this.Stop.SetMessage(strMessage);
                    }

REDO:
                    string strMetadata = "";
                    long lRet = this.Channel.GetRes(
                        this.Stop,
                        this.ServerFilePath,
                        lStart,
                        nPerLength,
                        strStyle,
                        out baContent,
                        out strMetadata,
                        out string strOutputPath,
                        out timestamp,
                        out strError);
                    if (lRet == -1)
                    {
                        if (this.Channel.ErrorCode == localhost.ErrorCode.NotFound)
                        {
                            bNotFound = true;
                            goto DETECT_STATE;
                        }

                        if (this.Prompt != null &&
                            !(this.Stop != null && this.Stop.IsStopped == true))
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            e.MessageText = "获得服务器文件 '" + this.ServerFilePath + "' 时发生错误: " + strError + "\r\nstart=" + lStart + ", length=" + nPerLength + ")";
                            e.Actions     = "yes,no,cancel";
                            this.Prompt(this, e);
                            if (e.ResultAction == "cancel")
                            {
                                goto ERROR1;
                            }
                            else if (e.ResultAction == "yes")
                            {
                                goto REDO;
                            }
                            else
                            {
                                goto ERROR1;
                            }
                        }
                        else
                        {
                            goto ERROR1;
                        }
                    }

                    bNotFound = false;

#if NO
                    if (bHasMetadataStyle == true)
                    {
                        StringUtil.RemoveFromInList("metadata",
                                                    true,
                                                    ref strStyle);
                        bHasMetadataStyle = false;
                    }
#endif
                    if (lTotalLength != -1 && lTotalLength > lRet)
                    {
                        strError = "下载被前端放弃。因下载中途文件尺寸变小(曾经的尺寸=" + lTotalLength + ",当前尺寸=" + lRet + ")";
                        goto ERROR1;
                    }

                    lTotalLength = lRet;

#if NO
                    if (StringUtil.IsInList("timestamp", strStyle) == true)
                    {
                        if (input_timestamp != null)
                        {
                            if (ByteArray.Compare(input_timestamp, timestamp) != 0)
                            {
                                strError = "下载过程中发现时间戳和input_timestamp参数中的时间戳不一致,下载失败 ...";
                                return(-1);
                            }
                        }
                        if (old_timestamp != null)
                        {
                            if (ByteArray.Compare(old_timestamp, timestamp) != 0)
                            {
                                strError = "下载过程中发现时间戳变化,下载失败 ...";
                                return(-1);
                            }
                        }
                    }

                    old_timestamp = timestamp;

                    if (fileTarget == null)
                    {
                        break;
                    }
#endif

                    // 写入文件
                    if (StringUtil.IsInList("attachment", strStyle) == true)
                    {
                        Debug.Assert(false, "attachment style暂时不能使用");
                    }
                    else
                    {
                        if (_cancel.IsCancellationRequested)
                        {
                            strError = "中断";
                            goto ERROR1;
                        }

                        Debug.Assert(StringUtil.IsInList("content", strStyle) == true,
                                     "不是attachment风格,就应是content风格");

                        Debug.Assert(baContent != null, "返回的baContent不能为null");
                        Debug.Assert(baContent.Length <= lRet, "每次返回的包尺寸[" + Convert.ToString(baContent.Length) + "]应当小于result.Value[" + Convert.ToString(lRet) + "]");

                        if (baContent.Length > 0)
                        {
                            _stream.Write(baContent, 0, baContent.Length);
                            _stream.Flush(); // 2013/5/17
                            lStart += baContent.Length;

                            var func = this.ProgressChanged;
                            if (func != null)
                            {
                                try
                                {
                                    DownloadProgressChangedEventArgs e = new DownloadProgressChangedEventArgs(lStart, lTotalLength);
                                    func(this, e);
                                }
                                catch (ObjectDisposedException)
                                {
                                }
                            }
                        }
                    }

DETECT_STATE:
                    if (lStart >= lRet || bNotFound == true)
                    {
                        // 探测文件状态。
                        // 探测下载状态
                        // return:
                        //      -1  出错
                        //      0   文件没有找到
                        //      1   文件找到
                        int nRet = DetectDownloadState(this.ServerFilePath,
                                                       out string strState,
                                                       out strError);
                        if (nRet == -1)
                        {
                            strError = "探测状态文件过程出错: " + strError;
                            goto ERROR1;
                        }

                        if (nRet == 0 && bNotFound)
                        {
                            strError = "文件 '" + this.ServerFilePath + "' 没有找到";
                            goto ERROR1;
                        }

                        if (nRet == 0 || // 状态文件没有找到,说明不是动态下载情形,要结束下载
                            strState != "creating")
                        {
                            // 需要再次确认一下文件最大尺寸
                            long lTempLength = DetectFileLength(lTotalLength,
                                                                out strError);
                            if (lTempLength == -1)
                            {
                                strError = "文件 '" + this.ServerFilePath + "' finish 之前探测文件尺寸发生错误: " + strError;
                                goto ERROR1;
                            }

                            // 如果发现文件尺寸又变大了,则继续循环
                            if (lTempLength > lTotalLength)
                            {
                                continue;
                            }

                            if (strState != "finish" && nRet != 0)
                            {
                                this.ErrorInfo = "下载文件 '" + this.ServerFilePath + "' 时遭遇(服务器端)状态出错: " + strState;
                            }
                            else if (this.ServerFilePath.StartsWith("!"))
                            {
#if NO
                                DisplayMessage("正在获得服务器文件 " + this.ServerFilePath + " 的 MD5 ...");

                                // 检查 MD5
                                byte[] server_md5 = null;
REDO_MD5:
                                // return:
                                //      -1  出错
                                //      0   文件没有找到
                                //      1   文件找到
                                if (getMd5NewStyle && this.ServerFilePath.StartsWith("!") == true)
                                {
                                    nRet = GetServerFileMD5ByTask(
                                        this.Channel,
                                        this.Stop,
                                        this.ServerFilePath,
                                        this.Prompt,
                                        new CancellationToken(),
                                        out server_md5,
                                        out strError);
                                }
                                else
                                {
                                    nRet = GetServerFileMD5_old(
                                        this.Channel,
                                        this.Stop,
                                        this.ServerFilePath,
                                        out server_md5,
                                        out strError);
                                }
                                if (nRet != 1)
                                {
                                    if (nRet == -1)
                                    {
                                        if (this.Prompt != null &&
                                            !(this.Stop != null && this.Stop.IsStopped == true))
                                        {
                                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                                            e.MessageText = "获得服务器文件 '" + this.ServerFilePath + "' 的 MD5 时发生错误: " + strError;
                                            e.Actions     = "yes,no,cancel";
                                            this.Prompt(this, e);
                                            if (e.ResultAction == "cancel")
                                            {
                                                goto ERROR1;
                                            }
                                            else if (e.ResultAction == "yes")
                                            {
                                                goto REDO_MD5;
                                            }
                                            else
                                            {
                                                goto ERROR1;
                                            }
                                        }
                                        else
                                        {
                                            goto ERROR1;
                                        }
                                    }
                                    strError = "探测服务器端文件 '" + this.ServerFilePath + "' MD5 时出错: " + strError;
                                    goto ERROR1;
                                }

                                DisplayMessage("正在获得本地文件 " + this.LocalFilePath + " 的 MD5 ...");

                                _stream.Seek(0, SeekOrigin.Begin);
                                byte[] local_md5 = GetFileMd5(_stream);
                                if (ByteArray.Compare(server_md5, local_md5) != 0)
                                {
                                    strError = "服务器端文件 '" + this.ServerFilePath + "' 和刚下载的本地文件 MD5 不匹配";
                                    goto ERROR1;
                                }
#endif
                                // 让两个任务并行执行
                                var task1 = GetRemoteMd5(this._cancel.Token);
                                var task2 = GetLocalMd5(this._cancel.Token);

                                DisplayMessage($"正在对比 MD5 {this.ServerFilePath} <--> {this.LocalFilePath} ...");

                                Task.WaitAll(new Task[] { task1, task2 },
                                             this._cancel.Token);

                                if (task1.Result.Value != 0)
                                {
                                    strError = "探测服务器端文件 '" + this.ServerFilePath + "' MD5 时出错: " + task1.Result.ErrorInfo;
                                    goto ERROR1;
                                }
                                var server_md5 = task1.Result.MD5;

                                if (task2.Result.Value != 0)
                                {
                                    strError = "探测本地文件 '" + this.LocalFilePath + "' MD5 时出错: " + task2.Result.ErrorInfo;
                                    goto ERROR1;
                                }
                                var local_md5 = task2.Result.MD5;

                                if (ByteArray.Compare(server_md5, local_md5) != 0)
                                {
                                    strError = "服务器端文件 '" + this.ServerFilePath + "' 和刚下载的本地文件 MD5 不匹配";
                                    goto ERROR1;
                                }
                            }
                            this.State = "finish:" + strState;
                            TriggerClosedEvent();
                            this._timestamp = timestamp;
                            return;
                        }

                        // 休眠一段时间后重试下载
                        Thread.Sleep(1000);
                    }
                } // end of for

                this.State = "end";
                TriggerClosedEvent();
                return;

ERROR1:
                this.State     = "error";
                this.ErrorInfo = strError;
                TriggerClosedEvent();
            }
            catch (Exception ex)
            {
                this.State     = "error";
                this.ErrorInfo = ExceptionUtil.GetDebugText(ex);
                TriggerClosedEvent();
            }
            finally
            {
                this.Channel.Timeout = old_timeout;

                if (_stream != null)
                {
                    _stream.Close();
                    _stream = null;
                }

                if (string.IsNullOrEmpty(this.ErrorInfo))
                {
                    RenameTempFile();
                }
            }
        }
Exemplo n.º 6
0
        public IEnumerator GetEnumerator()
        {
            string strError = "";

            long lPerCount = this.BatchSize; // 每批获得多少个

            if (lPerCount == 0)
            {
                lPerCount = DefaultBatchSize;
            }
            long lStart       = 0;
            long lResultCount = 0;
            long lCount       = -1;

            TimeSpan old_timeout = this.Channel.Timeout;

            this.Channel.Timeout = new TimeSpan(0, 5, 0);

            try
            {
                for (; ;)
                {
                    if (this.Stop != null && this.Stop.State != 0)
                    {
                        throw new InterruptException("用户中断");
                    }

                    int nRedoCount = 0;
REDO:
                    EntityInfo[] entities = null;

                    long lRet = 0;

                    if (this.DbType == "item")
                    {
                        lRet = this.Channel.GetEntities(
                            this.Stop,
                            this.BiblioRecPath,
                            lStart,
                            lCount,
                            this.Format == null ? "" : this.Format,     // 为了回避 dp2library 2.102 以前版本的一个 bug
                            "zh",
                            out entities,
                            out strError);
                    }
                    else if (this.DbType == "order")
                    {
                        lRet = this.Channel.GetOrders(
                            this.Stop,
                            this.BiblioRecPath,
                            lStart,
                            lCount,
                            this.Format == null ? "" : this.Format,
                            "zh",
                            out entities,
                            out strError);
                    }
                    else if (this.DbType == "issue")
                    {
                        lRet = this.Channel.GetIssues(
                            this.Stop,
                            this.BiblioRecPath,
                            lStart,
                            lCount,
                            this.Format == null ? "" : this.Format,
                            "zh",
                            out entities,
                            out strError);
                    }
                    else if (this.DbType == "comment")
                    {
                        lRet = this.Channel.GetComments(
                            this.Stop,
                            this.BiblioRecPath,
                            lStart,
                            lCount,
                            this.Format == null ? "" : this.Format,
                            "zh",
                            out entities,
                            out strError);
                    }
                    else
                    {
                        throw new Exception("未知的 this.DbType '" + this.DbType + "'");
                    }

                    if (lRet == -1)
                    {
                        if (this.Stop != null && this.Stop.State != 0)
                        {
                            throw new InterruptException("用户中断");
                        }

                        if (this.Prompt != null)
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            e.MessageText = "获得书目记录 '" + this.BiblioRecPath + "' 的下级 " + this.DbType + " 记录时发生错误: " + strError;
                            e.Actions     = "yes,no,cancel";
                            this.Prompt(this, e);
                            if (e.ResultAction == "cancel")
                            {
                                throw new ChannelException(Channel.ErrorCode, strError);
                            }
                            else if (e.ResultAction == "yes")
                            {
                                goto REDO;
                            }
                            else
                            {
                                // no 也是抛出异常。因为继续下一批代价太大
                                throw new ChannelException(Channel.ErrorCode, strError);
                            }
                        }
                        else
                        {
                            throw new ChannelException(Channel.ErrorCode, strError);
                        }
                    }

                    // 发现 dp2library GetEntities() API 非常偶然地会在 entities 数组中返回一个 info.OldRecPath 为空的元素。这里试图重试获取
                    // 2017/6/5
                    // return:
                    //      true    出现了反常的情况
                    //      false   没有发现反常的情况
                    if (VerifyItems(entities) == true &&
                        nRedoCount < 2)
                    {
                        nRedoCount++;
                        goto REDO;
                    }

                    lResultCount    = lRet;
                    this.TotalCount = lRet; // 记载下级记录总数

                    if (lRet == 0)
                    {
                        yield break;
                    }

                    Debug.Assert(entities != null, "");

                    foreach (EntityInfo info in entities)
                    {
                        if (info.ErrorCode != ErrorCodeValue.NoError)
                        {
                            strError = "路径为 '" + info.OldRecPath + "' 的册记录装载中发生错误: " + info.ErrorInfo;
                            throw new Exception(strError);
                        }

                        yield return(info);
                    }

                    lStart += entities.Length;
                    if (lStart >= lResultCount)
                    {
                        yield break;
                    }

                    if (lCount == -1)
                    {
                        lCount = lPerCount;
                    }

                    if (lStart + lCount > lResultCount)
                    {
                        lCount = lResultCount - lStart;
                    }
                }
            }
            finally
            {
                this.Channel.Timeout = old_timeout;
            }
        }
Exemplo n.º 7
0
        public IEnumerator GetEnumerator()
        {
            string strError = "";

            if ((this.LogType & LogType.AccessLog) != 0 &&
                (this.LogType & LogType.OperLog) != 0)
            {
                throw new ArgumentException("OperLogLoader 的 LogType 只能使用一种类型");
            }

            List <string> filter_dates = null;

            if (this.FilterDates != null)
            {
                // 丢弃文件扩展名部分
                filter_dates = new List <string>();
                foreach (string date in this.FilterDates)
                {
                    filter_dates.Add(date.Substring(0, 8));
                }
            }

            long lStart    = 0;
            int  nPerCount = -1;
            long lHitCount = 0;

            for (; ;)
            {
                if (this.Stop != null && this.Stop.State != 0)
                {
                    strError = "用户中断";
                    throw new InterruptException(strError);
                }

REDO:
                OperLogInfo[] records = null;
                long          lRet    = this.Channel.GetOperLogs(this.Stop,
                                                                 "",
                                                                 lStart,
                                                                 -1,
                                                                 nPerCount,
                                                                 "getfilenames",
                                                                 "",
                                                                 out records,
                                                                 out strError);
                if (lRet == -1)
                {
                    if (this.Prompt != null)
                    {
                        MessagePromptEventArgs e = new MessagePromptEventArgs();
                        e.MessageText = "获取日志文件名的操作发生错误: " + strError;
                        e.Actions     = "yes,no,cancel";
                        this.Prompt(this, e);
                        if (e.ResultAction == "cancel")
                        {
                            throw new InterruptException(strError);
                        }
                        else if (e.ResultAction == "yes")
                        {
                            if (this.Stop != null)
                            {
                                this.Stop.Continue();
                            }
                            goto REDO;
                        }
                        else
                        {
                            // 还没有得到文件名,通讯就失败,所以操作无法进行了,只能抛出异常
                            throw new ChannelException(this.Channel.ErrorCode, strError);
                            // continue;
                        }
                    }
                    else
                    {
                        throw new ChannelException(this.Channel.ErrorCode, strError);
                    }
                }

                lHitCount = lRet;

                foreach (OperLogInfo info in records)
                {
                    string strDate = info.Xml.Substring(0, 8);
                    if (filter_dates != null &&
                        filter_dates.IndexOf(strDate) == -1)
                    {
                        continue;
                    }

                    OperLogDateItem item = new OperLogDateItem();
                    item.Date   = strDate;
                    item.Length = info.AttachmentLength;
                    yield return(item);
                }
                if (lStart + records.Length >= lHitCount)
                {
                    yield break;
                }
                lStart += records.Length;
            }
        }
Exemplo n.º 8
0
        public IEnumerator GetEnumerator()
        {
            string strError = "";

            long lHitCount = -1;
            long lStart    = this.Start;
            long nPerCount = this.BatchSize == 0 ? -1 : this.BatchSize;

            // nPerCount = 1;  // test
            for (; ;)
            {
                Record[] searchresults = null;

REDO:
                long lRet = this.Channel.GetSearchResult(
                    // this.Stop,
                    this.ResultSetName, // "default",
                    lStart,
                    nPerCount,
                    this.FormatList,  // "id,xml,timestamp,metadata",
                    string.IsNullOrEmpty(this.Lang) ? "zh" : this.Lang,
                    out searchresults,
                    out strError);
                if (lRet == -1)
                {
                    if (this.Prompt != null)
                    {
                        MessagePromptEventArgs e = new MessagePromptEventArgs();
                        e.MessageText = "获得数据库记录时发生错误: " + strError;
                        e.Actions     = "yes,no,cancel";
                        this.Prompt(this, e);
                        if (e.ResultAction == "cancel")
                        {
                            throw new ChannelException(Channel.ErrorCode, strError);
                        }
                        else if (e.ResultAction == "yes")
                        {
                            goto REDO;
                        }
                        else
                        {
                            // no 也是抛出异常。因为继续下一批代价太大
                            throw new ChannelException(Channel.ErrorCode, strError);
                        }
                    }
                    else
                    {
                        throw new ChannelException(Channel.ErrorCode, strError);
                    }
                }

                this.TotalCount = lRet;

                if (lRet == 0)
                {
                    yield break;
                }
                if (searchresults == null)
                {
                    strError = "searchresults == null";
                    throw new Exception(strError);
                }
                if (searchresults.Length == 0)
                {
                    strError = "searchresults.Length == 0";
                    throw new Exception(strError);
                }
                lHitCount = lRet;

                foreach (Record record in searchresults)
                {
                    yield return(record);
                }

                lStart += searchresults.Length;
                if (lStart >= lHitCount)
                {
                    yield break;
                }
            }
        }
Exemplo n.º 9
0
        public IEnumerator GetEnumerator()
        {
            string strError = "";
            int nRet = 0;

            if ((this.LogType & dp2Circulation.LogType.AccessLog) != 0
    && (this.LogType & dp2Circulation.LogType.OperLog) != 0)
                throw new ArgumentException("OperLogLoader 的 LogType 只能使用一种类型");

            if (string.IsNullOrEmpty(this.CacheDir) == false)
                PathUtil.CreateDirIfNeed(this.CacheDir);

            // ProgressEstimate estimate = new ProgressEstimate();
            bool bAutoCache = this.AutoCache;

            if (bAutoCache == true)
            {
                long lServerFileSize = 0;
                long lCacheFileSize = 0;
                // 象征性获得一个日志文件的尺寸,主要目的是为了触发一次通道登录
                // return:
                //      -2  此类型的日志尚未启用
                //      -1  error
                //      0   file not found
                //      1   found
                nRet = GetFileSize(
                    this.Stop,
                    this.Channel,
                    this.CacheDir,
                    "20121001.log",
                    this.LogType,
                    out lServerFileSize,
                    out lCacheFileSize,
                    out strError);
                if (nRet == -1)
                    throw new Exception(strError);
                // 2015/11/25
                if (nRet == -2)
                    yield break;    // 此类型的日志尚未启用

                // 检查日志文件缓存目录的版本是否和当前用户的信息一致
                // return:
                //      -1  出错
                //      0   一致
                //      1   不一致
                nRet = DetectCacheVersionFile(
                    this.CacheDir,
                    "version.xml",
                    this.Channel.LibraryCodeList,
                    this.Channel.Url,
                    out strError);
                if (nRet == -1)
                    throw new Exception(strError);
                if (nRet == 1)
                {
                REDO:
                    // 清空当前缓存目录
                    nRet = Global.DeleteDataDir(
                        null, // owner,
                        this.CacheDir,
                        out strError);
                    if (nRet == -1)
                    {
                        if (this.Prompt != null)
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            e.MessageText = "清空当前缓存目录时发生错误: " + strError;
                            e.Actions = "yes,no,cancel";
                            this.Prompt(this, e);
                            if (e.ResultAction == "cancel")
                                throw new Exception(strError);
                            else if (e.ResultAction == "yes")
                                goto REDO;
                            else
                            {
                            }
                        }
                        else
                            throw new Exception(strError);
                    }
#if NO
                    if (nRet == -1)
                        throw new Exception(strError);
#endif

                    PathUtil.CreateDirIfNeed(this.CacheDir);  // 重新创建目录

                    // 创建版本文件
                    nRet = CreateCacheVersionFile(
                        this.CacheDir,
                        "version.xml",
                        this.Channel.LibraryCodeList,
                        this.Channel.Url,
                        out strError);
                    if (nRet == -1)
                        throw new Exception(strError);
                }
            }

            long lTotalSize = 0;
            List<string> lines = new List<string>();    // 经过处理后排除了不存在的文件名
            List<string> ranges = new List<string>();
            List<long> sizes = new List<long>();

            this.Stop.SetMessage("正在准备获得日志文件尺寸 ...");
            foreach (string strLine in this.FileNames)
            {
                Application.DoEvents();

                if (this.Stop != null && this.Stop.State != 0)
                {
                    strError = "用户中断";
                    throw new Exception(strError);
                    // yield break; ?
                }

                if (String.IsNullOrEmpty(strLine) == true)
                    continue;

                string strFilename = strLine.Trim();
                // 去掉注释
                nRet = strFilename.IndexOf("#");
                if (nRet != -1)
                    strFilename = strFilename.Substring(0, nRet).Trim();

                if (String.IsNullOrEmpty(strFilename) == true)
                    continue;

                string strLogFilename = "";
                string strRange = "";

                nRet = strFilename.IndexOf(":");
                if (nRet != -1)
                {
                    strLogFilename = strFilename.Substring(0, nRet).Trim();
                    strRange = strFilename.Substring(nRet + 1).Trim();
                }
                else
                {
                    strLogFilename = strFilename.Trim();
                    strRange = "";
                }

                if (strLogFilename.Length == 8)
                    strLogFilename += ".log";
            REDO_GETSIZE:
                long lServerFileSize = 0;
                long lCacheFileSize = 0;
                // 获得一个日志文件的尺寸
                //      -2  此类型的日志尚未启用
                //      -1  error
                //      0   file not found
                //      1   found
                nRet = GetFileSize(
                    this.Stop,
                    this.Channel,
                    this.CacheDir,
                    strLogFilename,
                    this.LogType,
                    out lServerFileSize,
                    out lCacheFileSize,
                    out strError);
                if (nRet == -1)
                {
                    // throw new Exception(strError);

                    if (this.Prompt != null)
                    {
                        MessagePromptEventArgs e = new MessagePromptEventArgs();
                        e.MessageText = "获取日志文件 " + strLogFilename + " 尺寸的操作发生错误: " + strError;
                        e.Actions = "yes,no,cancel";
                        this.Prompt(this, e);
                        if (e.ResultAction == "cancel")
                            throw new Exception(strError);
                        else if (e.ResultAction == "yes")
                        {
                            if (this.Stop != null)
                                this.Stop.Continue();
                            goto REDO_GETSIZE;
                        }
                        else
                        {
                            // ??
                            continue;
                        }
                    }
                    else
                        throw new Exception(strError);
                }

                if (nRet == 0)
                    continue;

                if (lServerFileSize == 0)
                    continue;   // 0字节的文件当作不存在处理
                // 2015/11/25
                if (lServerFileSize == -1)
                    yield break;    // 此类型的日志尚未启用

                Debug.Assert(lServerFileSize >= 0, "");

                if (bAutoCache == true)
                {
                    if (lCacheFileSize > 0)
                        lTotalSize += lCacheFileSize;
                    else
                        lTotalSize += lServerFileSize;
                }
                else
                {
                    lTotalSize += lServerFileSize;
                }

                // lines.Add(strFilename);
                lines.Add(strLogFilename);
                ranges.Add(strRange);

                // 记忆每个文件的尺寸,后面就不用获取了?
                sizes.Add(lServerFileSize);
            }

            long lDoneSize = 0;

            if (this.ProgressStart == -1)
                lDoneSize = lTotalSize;
            else
                lDoneSize = this.ProgressStart;

            lTotalSize += lDoneSize;

            if (this.Stop != null)
            {
                this.Stop.SetProgressRange(0, lTotalSize);
            }

            estimate.SetRange(lDoneSize, lTotalSize);
            estimate.StartEstimate();

            for (int i = 0; i < lines.Count; i++)
            {
                Application.DoEvents();

                if (this.Stop != null && this.Stop.State != 0)
                {
                    strError = "用户中断";
                    throw new Exception(strError);
                    // yield break; ?
                }

                string strLine = lines[i];
                string strRange = ranges[i];

                string strLogFilename = strLine;
#if NO
                string strLogFilename = "";
                string strRange = "";

                nRet = strLine.IndexOf(":");
                if (nRet != -1)
                {
                    strLogFilename = strLine.Substring(0, nRet).Trim();
                    strRange = strLine.Substring(nRet + 1).Trim();
                }
                else
                {
                    strLogFilename = strLine.Trim();
                    strRange = "";
                }
#endif

                {
                    OperLogItemLoader loader = new OperLogItemLoader();
                    loader.Stop = this.Stop;
                    loader.Channel = this.Channel;
                    // loader.owner = this.owner;
                    loader.estimate = this.estimate;
                    loader.FileName = strLogFilename;
                    loader.Level = this.Level;
                    loader.lServerFileSize = sizes[i];
                    loader.Range = strRange;
                    loader.AutoCache = this.AutoCache;
                    loader.lProgressValue = lDoneSize;
                    loader.lSize = lTotalSize;
                    loader.Filter = this.Filter;
                    loader.LogType = this.LogType;

                    loader.Prompt -= new MessagePromptEventHandler(loader_Prompt);
                    loader.Prompt += new MessagePromptEventHandler(loader_Prompt);

                    foreach (OperLogItem item in loader)
                    {
                        yield return item;
                    }

                    lDoneSize = loader.lProgressValue;
                    lTotalSize = loader.lSize;
                }
            }
        }
Exemplo n.º 10
0
        void loader_Prompt(object sender, MessagePromptEventArgs e)
        {
            // TODO: 不再出现此对话框。不过重试有个次数限制,同一位置失败多次后总要出现对话框才好
            if (e.Actions == "yes,no,cancel")
            {
#if NO
                DialogResult result = MessageBox.Show(this,
    e.MessageText + "\r\n\r\n是否重试操作?\r\n\r\n(是: 重试;  否: 跳过本次操作,继续后面的操作; 取消: 停止全部操作)",
    "ReportForm",
    MessageBoxButtons.YesNoCancel,
    MessageBoxIcon.Question,
    MessageBoxDefaultButton.Button1);
                if (result == DialogResult.Yes)
                    e.ResultAction = "yes";
                else if (result == DialogResult.Cancel)
                    e.ResultAction = "cancel";
                else
                    e.ResultAction = "no";
#endif
                DialogResult result = AutoCloseMessageBox.Show(this,
    e.MessageText + "\r\n\r\n将自动重试操作\r\n\r\n(点右上角关闭按钮可以中断批处理)",
    20 * 1000,
    "BiblioSearchForm");
                if (result == DialogResult.Cancel)
                    e.ResultAction = "no";
                else
                    e.ResultAction = "yes";
            }
        }
Exemplo n.º 11
0
        public IEnumerator GetEnumerator()
        {
            List<string> format_list = new List<string>();
            int nContentIndex = format_list.Count;
            int nTimestampIndex = -1;
            int nMetadataIndex = -1;
            format_list.Add(this.Format);
            // if ((this.GetBiblioInfoStyle & dp2Circulation.GetBiblioInfoStyle.Timestamp) != 0)
            if (this.GetBiblioInfoStyle.HasFlag(GetBiblioInfoStyle.Timestamp) == true)  // 新用法
            {
                nTimestampIndex = format_list.Count;
                format_list.Add("timestamp");
            }
            if ((this.GetBiblioInfoStyle & GetBiblioInfoStyle.Metadata) != 0)
            {
                nMetadataIndex = format_list.Count;
                format_list.Add("metadata");
            }

            string[] formats = new string[format_list.Count];
            format_list.CopyTo(formats);

            List<string> batch = new List<string>();
            for (int index = 0; index < m_recpaths.Count; index++)
            {
                string s = m_recpaths[index];
                batch.Add(s);

                // 每100个一批,或者最后一次
                if (batch.Count >= 100 ||
                    (index == m_recpaths.Count - 1 && batch.Count > 0))
                {
                REDO:
                    string strCommand = "@path-list:" + StringUtil.MakePathList(batch);

                    string[] results = null;
                    byte[] timestamp = null;
                    string strError = "";
                    // Channel.Timeout = new TimeSpan(0, 0, 5); 应该让调主设置这个值
                    long lRet = Channel.GetBiblioInfos(
                        this.Stop,
                        strCommand,
                        "",
                        formats,
                        out results,
                        out timestamp,
                        out strError);
                    if (lRet == -1)
                    {
                        if (this.Prompt != null)
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            e.MessageText = "获得书目记录 '"+strCommand+"' ("+StringUtil.MakePathList(format_list)+") 时发生错误: " + strError;
                            e.Actions = "yes,no,cancel";
                            this.Prompt(this, e);
                            if (e.ResultAction == "cancel")
                                throw new ChannelException(Channel.ErrorCode, strError);
                            else if (e.ResultAction == "yes")
                                goto REDO;
                            else
                            {
                                // no 也是抛出异常。因为继续下一批代价太大
                                throw new ChannelException(Channel.ErrorCode, strError);
                            }
                        }
                        else
                            throw new ChannelException(Channel.ErrorCode, strError);
                    }

                    if (lRet == 0)
                    {
                        if (lRet == 0 && String.IsNullOrEmpty(strError) == true)
                        {
                            foreach (string path in batch)
                            {
                                BiblioItem item = new BiblioItem();
                                item.RecPath = path;
                                item.ErrorCode = ErrorCode.NotFound;
                                item.ErrorInfo = "书目记录 '" + path + "' 不存在";
                                yield return item;
                            }
                            goto CONTINUE;
                        }


                        // 如果results.Length表现正常,其实还可以继续处理
                        if (results != null && results.Length > 0)
                        {
                        }
                        else
                        {
                            // 2014/1/15
                            if (Channel.ErrorCode == ErrorCode.NotFound)
                            {
                                foreach (string path in batch)
                                {
                                    BiblioItem item = new BiblioItem();
                                    item.RecPath = path;
                                    item.ErrorCode = ErrorCode.NotFound;
                                    item.ErrorInfo = "书目记录 '" + path + "' 不存在";
                                    yield return item;
                                }
                                goto CONTINUE;
                            }
                            strError = "获得书目记录 '" + StringUtil.MakePathList(batch) + "' 时发生错误: " + strError;
                            throw new Exception(strError);
                        }
                    }

                    if (results == null)
                    {
                        strError = "results == null";
                        throw new Exception(strError);
                    }

                    for (int i = 0; i < results.Length / formats.Length; i++)
                    {
                        BiblioItem item = new BiblioItem();
                        item.RecPath = batch[i];
                        if (nContentIndex != -1)
                            item.Content = results[i * formats.Length + nContentIndex];
                        if (nTimestampIndex != -1)
                            item.Timestamp = ByteArray.GetTimeStampByteArray(results[i * formats.Length + nTimestampIndex]);
                        if (nMetadataIndex != -1)
                            item.Metadata = results[i * formats.Length + nMetadataIndex];
                        if (string.IsNullOrEmpty(item.Content) == true)
                        {
                            item.ErrorCode = ErrorCode.NotFound;
                            item.ErrorInfo = "书目记录 '" + item.RecPath + "' 不存在";
                        }
                        yield return item;

                    }

                CONTINUE:
                    if (batch.Count > results.Length / formats.Length)
                    {
                        // 有本次没有获取到的记录
                        batch.RemoveRange(0, results.Length / formats.Length);
                        if (index == m_recpaths.Count - 1)
                            goto REDO;  // 当前已经是最后一轮了,需要继续做完

                        // 否则可以留给下一轮处理
                    }
                    else
                        batch.Clear();
                }
            }
        }
Exemplo n.º 12
0
        public IEnumerator GetEnumerator()
        {
            List <string> batch = new List <string>();

            for (int index = 0; index < m_recpaths.Count; index++)
            {
                string s = m_recpaths[index];
                batch.Add(s);

                // 每100个一批,或者最后一次
                if (batch.Count >= 100 ||
                    (index == m_recpaths.Count - 1 && batch.Count > 0))
                {
REDO:
#if NO
                    string[] paths = new string[batch.Count];
                    batch.CopyTo(paths);
#endif
                    string[] paths = batch.ToArray();

                    DigitalPlatform.LibraryClient.localhost.Record[] searchresults = null;
                    string strError = "";

                    long lRet = Channel.GetBrowseRecords(
                        this.Stop,
                        paths,
                        this.Format,    // "id,cols",
                        out searchresults,
                        out strError);
                    if (lRet == -1)
                    {
                        // throw new Exception(strError);

                        if (this.Prompt != null)
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            e.MessageText = "获得浏览记录时发生错误: " + strError + "\r\npaths='" + StringUtil.MakePathList(paths) + "' (" + this.Format + ")";
                            e.Actions     = "yes,no,cancel";
                            this.Prompt(this, e);
                            if (e.ResultAction == "cancel")
                            {
                                throw new ChannelException(Channel.ErrorCode, strError);
                            }
                            else if (e.ResultAction == "yes")
                            {
                                goto REDO;
                            }
                            else
                            {
                                // no 也是抛出异常。因为继续下一批代价太大
                                throw new ChannelException(Channel.ErrorCode, strError);
                            }
                        }
                        else
                        {
                            throw new ChannelException(Channel.ErrorCode, strError);
                        }
                    }

                    if (searchresults == null)
                    {
                        strError = "searchresults == null";
                        throw new Exception(strError);
                    }

                    for (int i = 0; i < searchresults.Length; i++)
                    {
                        DigitalPlatform.LibraryClient.localhost.Record record = searchresults[i];
                        if (batch[i] != record.Path)
                        {
                            throw new Exception("下标 " + i + " 的 batch 元素 '" + batch[i] + "' 和返回的该下标位置 GetBrowseRecords() 结果路径 '" + record.Path + "' 不匹配");
                        }
                        Debug.Assert(batch[i] == record.Path, "");
                        yield return(record);
                    }

                    // CONTINUE:
                    if (batch.Count > searchresults.Length)
                    {
                        // 有本次没有获取到的记录
                        batch.RemoveRange(0, searchresults.Length);
                        if (index == m_recpaths.Count - 1)
                        {
                            goto REDO;  // 当前已经是最后一轮了,需要继续做完
                        }
                        // 否则可以留给下一轮处理
                    }
                    else
                    {
                        batch.Clear();
                    }
                }
            }
        }
Exemplo n.º 13
0
        public IEnumerator GetEnumerator()
        {
            string strError = "";

            long lHitCount     = -1;
            long lStart        = this.Start;
            long nBasePerCount = this.BatchSize == 0 ? -1 : this.BatchSize;

            // nPerCount = 1;  // test
            for (; ;)
            {
                if (this.Stop != null && this.Stop.State != 0)
                {
                    throw new InterruptException($"用户中断");
                }

                Record[] searchresults = null;

                long nPerCount = nBasePerCount;
                if (nPerCount != -1 && IsMaxResultCountValid() &&
                    nPerCount > this.MaxResultCount)
                {
                    nPerCount = this.MaxResultCount;
                }
                else if (nPerCount == -1 && IsMaxResultCountValid() &&
                         this.MaxResultCount > this.BatchSize)
                {
                    nPerCount = this.MaxResultCount;
                }

                // 限制 nPerCount,不要超过余下的记录数
                if (nPerCount != -1 && lHitCount != -1 &&
                    nPerCount > lHitCount - lStart)
                {
                    nPerCount = lHitCount - lStart;
                }

REDO:
                var e1 = new GettingEventArgs
                {
                    Start         = lStart,
                    PerCount      = nPerCount,
                    ResultSetName = this.ResultSetName
                };
                this.Getting?.Invoke(this, e1);
                if (e1.Cancelled == true)
                {
                    throw new InterruptException($"用户中断");
                }

                long lRet = this.Channel.GetSearchResult(
                    this.Stop,
                    this.ResultSetName, // "default",
                    lStart,
                    nPerCount,
                    this.FormatList,  // "id,xml,timestamp,metadata",
                    string.IsNullOrEmpty(this.Lang) ? "zh" : this.Lang,
                    out searchresults,
                    out strError);

                var e2 = new GettedEventArgs
                {
                    Count     = lRet,
                    ErrorInfo = strError,
                    ErrorCode = Channel.ErrorCode
                };
                this.Getted?.Invoke(this, e2);
                if (e2.Cancelled == true)
                {
                    throw new InterruptException($"用户中断");
                }

                if (lRet == -1)
                {
                    if (this.Prompt != null)
                    {
                        MessagePromptEventArgs e = new MessagePromptEventArgs();
                        e.MessageText = "获得数据库记录时发生错误: " + strError;
                        e.Actions     = "yes,no,cancel";
                        this.Prompt(this, e);
                        if (e.ResultAction == "cancel")
                        {
                            throw new ChannelException(Channel.ErrorCode, strError);
                        }
                        else if (e.ResultAction == "yes")
                        {
                            goto REDO;
                        }
                        else
                        {
                            // no 也是抛出异常。因为继续下一批代价太大
                            throw new ChannelException(Channel.ErrorCode, strError);
                        }
                    }
                    else
                    {
                        throw new ChannelException(Channel.ErrorCode, strError);
                    }
                }

                if (lRet == 0)
                {
                    yield break;
                }
                if (searchresults == null)
                {
                    strError = "searchresults == null";
                    throw new Exception(strError);
                }
                if (searchresults.Length == 0)
                {
                    strError = "searchresults.Length == 0";
                    throw new Exception(strError);
                }

                if (IsMaxResultCountValid() == false)
                {
                    lHitCount = lRet;
                }
                else
                {
                    lHitCount = lRet == -1 ? -1 : Math.Min(MaxResultCount, lRet);
                }

                long i = 0;
                foreach (Record record in searchresults)
                {
                    if (lStart + i >= lHitCount)
                    {
                        yield break;
                    }
                    yield return(record);

                    i++;
                }

                lStart += searchresults.Length;
                if (lStart >= lHitCount)
                {
                    yield break;
                }
            }
        }
Exemplo n.º 14
0
        public IEnumerator GetEnumerator()
        {
            string strError = "";
            int nRet = 0;

            long lRet = 0;

            if ((this.LogType & dp2Circulation.LogType.AccessLog) != 0
                && (this.LogType & dp2Circulation.LogType.OperLog) != 0)
                throw new ArgumentException("OperLogItemLoader 的 LogType 只能使用一种类型");

            if (this.Stop != null && this.estimate != null)
                this.Stop.SetMessage("正在装入日志文件 " + this.FileName + " 中的记录。"
                    + "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(lProgressValue)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed));

            string strXml = "";
            long lAttachmentTotalLength = 0;
            byte[] attachment_data = null;

            long lFileSize = 0;
            if (lServerFileSize == -1)
            {
                long _lServerFileSize = 0;

                string strStyle = "level-" + Level.ToString();
                if ((this.LogType & dp2Circulation.LogType.AccessLog) != 0)
                    strStyle += ",accessLog";

                // 获得服务器端日志文件尺寸
                lRet = this.Channel.GetOperLog(
                    this.Stop,
                    this.FileName,
                    -1,    // lIndex,
                    -1, // lHint,
                    strStyle,
                    "", // strFilter
                    out strXml,
                    out _lServerFileSize,
                    0,  // lAttachmentFragmentStart,
                    0,  // nAttachmentFramengLength,
                    out attachment_data,
                    out lAttachmentTotalLength,
                    out strError);
                // 2015/11/25
                if (lRet == -1)
                    throw new Exception(strError);
                this.lServerFileSize = _lServerFileSize;

                if (lRet == 0)
                    yield break;
                // 2015/11/25
                if (_lServerFileSize == -1)
                    yield break;    // 此类型的日志尚未启用
            }

            Stream stream = null;
            bool bCacheFileExist = false;
            bool bRemoveCacheFile = false;  // 是否要自动删除未全部完成的本地缓存文件

            bool bAutoCache = this.AutoCache;

            if (bAutoCache == true)
            {
                string strFileName = this.FileName;
                if ((this.LogType & dp2Circulation.LogType.AccessLog) != 0)
                    strFileName = this.FileName + ".a";

                nRet = PrepareCacheFile(
                    this.CacheDir,
                    strFileName,    // this.FileName,
                    lServerFileSize,
                    out bCacheFileExist,
                    out stream,
                    out strError);
                if (nRet == -1)
                    throw new Exception(strError);

                if (bCacheFileExist == false && stream != null)
                    bRemoveCacheFile = true;
            }

            try
            {
                if (bCacheFileExist == true)
                    lFileSize = stream.Length;
                else
                    lFileSize = lServerFileSize;

                // stop.SetProgressRange(0, lTotalSize);

                if (String.IsNullOrEmpty(Range) == true)
                    Range = "0-" + (long.MaxValue - 1).ToString();    // "0-9999999999";

                RangeList rl = new RangeList(Range);

                for (int i = 0; i < rl.Count; i++)
                {
                    RangeItem ri = (RangeItem)rl[i];

                    // 让 100- 这样的 range 可以使用
                    if (ri.lLength == -1)
                        ri.lLength = long.MaxValue - ri.lStart;

                    OperLogInfo[] records = null;
                    long lStartRecords = 0;

                    long lHint = -1;
                    long lHintNext = -1;
                    for (long lIndex = ri.lStart; lIndex < ri.lStart + ri.lLength; lIndex++)
                    {
                        Application.DoEvents();

                        if (this.Stop != null && this.Stop.State != 0)
                        {
                            strError = "用户中断";
                            throw new Exception(strError);
                            // yield break; ?
                        }

                        if (lIndex == ri.lStart)
                            lHint = -1;
                        else
                            lHint = lHintNext;

                        if (bCacheFileExist == true)
                        {
                            if (lHint == -1)
                            {
                                // return:
                                //      -1  error
                                //      0   成功
                                //      1   到达文件末尾或者超出
                                nRet = LocationRecord(stream,
                    lIndex,
                    out strError);
                                if (nRet == -1)
                                    throw new Exception(strError);
                            }
                            else
                            {
                                // 根据暗示找到
                                if (lHint == stream.Length)
                                    break;

                                if (lHint > stream.Length)
                                {
                                    strError = "lHint参数值不正确";
                                    throw new Exception(strError);
                                }
                                if (stream.Position != lHint)
                                    stream.Seek(lHint, SeekOrigin.Begin);
                            }

                            nRet = ReadCachedEnventLog(
                                stream,
                                out strXml,
                                out lAttachmentTotalLength,
                                out strError);
                            if (nRet == -1)
                                throw new Exception(strError);
                            lHintNext = stream.Position;
                        }
                        else
                        {
                            if (records == null || lIndex /*- ri.lStart*/ >= lStartRecords + records.Length)
                            {
                                int nCount = -1;
                                if (ri.lLength >= Int32.MaxValue)
                                    nCount = -1;    // 500;   // -1;
                                else
                                    nCount = (int)ri.lLength;   // Math.Min(500, (int)ri.lLength);

                                string strStyle = "level-" + Level.ToString();
                                if ((this.LogType & dp2Circulation.LogType.AccessLog) != 0)
                                    strStyle += ",accessLog";
                            REDO:
                                // 获得日志
                                // return:
                                //      -1  error
                                //      0   file not found
                                //      1   succeed
                                //      2   超过范围,本次调用无效
                                lRet = this.Channel.GetOperLogs(
                                    this.Stop,
                                    this.FileName,
                                    lIndex,
                                    lHint,
                                    nCount,
                                    strStyle,
                                    this.Filter, // strFilter
                                    out records,
                                    out strError);
                                if (lRet == -1)
                                {
#if NO
                                    DialogResult result = MessageBox.Show(owner,
    "获取日志信息 ("+this.FileName + " " +lIndex.ToString() + ") 的操作发生错误: " + strError + "\r\n\r\n是否重试操作?\r\n\r\n(是: 重试;  否: 跳过本次操作,继续后面的操作; 放弃: 停止全部操作)",
    "OperLogItemLoader",
    MessageBoxButtons.YesNoCancel,
    MessageBoxIcon.Question,
    MessageBoxDefaultButton.Button1);
                                    if (result == DialogResult.Yes)
                                        goto REDO;
                                    if (result == DialogResult.Cancel)
                                        throw new Exception(strError);
                                    else
                                    {
                                        // TODO: 是否要在listview中装入一条表示出错的行?
                                        lHintNext = -1;
                                        continue;
                                    }
#endif
                                    if (this.Prompt != null)
                                    {
                                        MessagePromptEventArgs e = new MessagePromptEventArgs();
                                        e.MessageText = "获取 " + this._logType.ToString() + " 日志信息 (" + this.FileName + " " + lIndex.ToString() + ") 的操作发生错误: " + strError;
                                        e.Actions = "yes,no,cancel";
                                        this.Prompt(this, e);
                                        if (e.ResultAction == "cancel")
                                            throw new Exception(strError);
                                        else if (e.ResultAction == "yes")
                                        {
                                            if (this.Stop != null)
                                                this.Stop.Continue();
                                            goto REDO;
                                        }
                                        else
                                        {
                                            lHintNext = -1;
                                            continue;
                                        }
                                    }
                                    else
                                        throw new Exception(strError);
                                }
                                if (lRet == 0)
                                    yield break;

                                if (lRet == 2)
                                    break;

                                // records数组表示的起点位置
                                lStartRecords = lIndex /* - ri.lStart*/;
                            }
                            OperLogInfo info = records[lIndex - lStartRecords];

                            strXml = info.Xml;
                            lHintNext = info.HintNext;
                            lAttachmentTotalLength = info.AttachmentLength;

                            // 写入本地缓存的日志文件
                            if (stream != null)
                            {
                                try
                                {
                                    WriteCachedEnventLog(
                                        stream,
                                        strXml,
                                        lAttachmentTotalLength);
                                }
                                catch (Exception ex)
                                {
                                    strError = "写入本地缓存文件的时候出错: " + ex.Message;
                                    throw new Exception(strError);
                                }
                            }
                        }

#if NO
                            // 2011/12/30
                            // 日志记录可能动态地增加了,超过了原先为ProgressBar设置的范围
                            if (lFizeTotalSize < (int)lHintNext)
                            {
                                lFizeTotalSize = lHintNext;

                                stop.SetProgressRange(0, lFizeTotalSize);
                            }
#endif
                        if (lHintNext >= 0)
                        {
                            // 校正
                            if (lProgressValue + lHintNext > lSize)
                            {
                                lSize = lProgressValue + lHintNext;

                                if (this.Stop != null && this.estimate != null)
                                {
                                    this.Stop.SetProgressRange(0, lSize);
                                    estimate.SetRange(0, lSize);
                                }
                            }

                            this.Stop.SetProgressValue(lProgressValue + lHintNext);
                        }

                        if (lIndex % 100 == 0)
                        {
                            if (this.Stop != null && this.estimate != null)
                            {
                                estimate.Text = "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(lProgressValue + lHintNext)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed);
                                this.Stop.SetMessage("正在装入日志文件 " + this.FileName + " 中的记录 " + lIndex.ToString() + " 。"
                                    + estimate.Text);
                            }
                        }

                        {
                            OperLogItem item = new OperLogItem();
                            item.Xml = strXml;
                            item.Index = lIndex;
                            item.Date = this.FileName.Substring(0, 8);
                            yield return item;
                        }

                    }
                }

                // 创建本地缓存的日志文件的metadata文件
                if (bCacheFileExist == false && stream != null)
                {
                    string strFileName = this.FileName;
                    if ((this.LogType & dp2Circulation.LogType.AccessLog) != 0)
                        strFileName = this.FileName + ".a";

                    nRet = CreateCacheMetadataFile(
                        this.CacheDir,
                        strFileName,    // this.FileName,
                        lServerFileSize,
                        out strError);
                    if (nRet == -1)
                        throw new Exception(strError);
                }

                bRemoveCacheFile = false;   // 不删除
            }
            finally
            {
                if (stream != null)
                    stream.Close();

                if (bRemoveCacheFile == true)
                {
                    string strFileName = this.FileName;
                    if ((this.LogType & dp2Circulation.LogType.AccessLog) != 0)
                        strFileName = this.FileName + ".a";

                    string strError1 = "";
                    nRet = DeleteCacheFile(
                        this.CacheDir,
                        strFileName,    // this.FileName,
                        out strError1);
                    if (nRet == -1)
                    {
                        // MessageBox.Show(owner, strError1);
                        if (this.Prompt != null)
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            e.MessageText = strError1;
                            e.Actions = "ok";
                            this.Prompt(this, e);
                        }
                    }
                }
            }

            lProgressValue += lFileSize;
        }
Exemplo n.º 15
0
 void loader_Prompt(object sender, MessagePromptEventArgs e)
 {
     // TODO: 不再出现此对话框。不过重试有个次数限制,同一位置失败多次后总要出现对话框才好
     if (e.Actions == "yes,no,cancel")
     {
         this.Invoke((Action)(() =>
         {
             DialogResult result = MessageBox.Show(this,
 e.MessageText + "\r\n\r\n是否重试操作?\r\n\r\n(是: 重试;  否: 跳过本次操作,继续后面的操作; 取消: 停止全部操作)",
 "ReportForm",
 MessageBoxButtons.YesNoCancel,
 MessageBoxIcon.Question,
 MessageBoxDefaultButton.Button1);
             if (result == DialogResult.Yes)
                 e.ResultAction = "yes";
             else if (result == DialogResult.Cancel)
                 e.ResultAction = "cancel";
             else
                 e.ResultAction = "no";
         }));
     }
 }
Exemplo n.º 16
0
        // static CancellationToken _token;

        // 探测 MD5 (用轮询任务法)
        // return:
        //      -1  出错
        //      0   文件没有找到
        //      1   文件找到
        public static int GetServerFileMD5ByTask(
            LibraryChannel channel,
            Stop stop,
            string strServerPath,
            MessagePromptEventHandler prompt,
            CancellationToken token,
            out byte[] md5,
            out string strError)
        {
            strError = "";
            md5      = null;

            // 对于 dp2Kernel 内的资源只能用以前的非 Task 方式
            if (strServerPath.StartsWith("!") == false)
            {
                return(GetServerFileMD5_old(
                           channel,
                           stop,
                           strServerPath,
                           out md5,
                           out strError));
            }

            /*
             * string strStyle = "md5";
             * string strMetadata = "";
             * byte[] baContent = null;
             * string strOutputPath = "";
             */

            TimeSpan old_timeout = channel.Timeout;

            channel.Timeout = TimeSpan.FromSeconds(10);
            try
            {
                // 检查 dp2library 版本号
REDO_GETVERSION:
                long lRet = channel.GetVersion(stop,
                                               out string version,
                                               out string uid,
                                               out strError);
                if (lRet == -1)
                {
                    if (prompt != null &&
                        !(stop != null && stop.IsStopped == true))
                    {
                        MessagePromptEventArgs e = new MessagePromptEventArgs();
                        e.MessageText = $"获得 dp2library 服务器 {channel.Url} 版本号时发生错误: {strError}";
                        e.Actions     = "yes,no,cancel";
                        prompt(null, e);
                        if (e.ResultAction == "yes")
                        {
                            goto REDO_GETVERSION;
                        }
                    }

                    strError = "检查 dp2library 服务器版本号时出错: " + strError;
                    return(-1);
                }

                string base_version = "3.23";
                if (StringUtil.CompareVersion(version, base_version) < 0)
                {
                    // strError = "获得服务器文件 MD5 的功能需要 dp2library 服务器版本为 {base_version} 以上";
                    // return -1;

                    // 改用旧功能
                    return(GetServerFileMD5_old(
                               channel,
                               stop,
                               strServerPath,
                               out md5,
                               out strError));
                }

                // TODO: 如果此请求出现通讯错误,再次重试请求的时候记得 removeTask 前一次的 task
                // 启动任务
                // return:
                //		strStyle	一般设置为"content,data,metadata,timestamp,outputpath";
                //		-1	出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。
                //		0	成功
                lRet = channel.GetRes(
                    stop,
                    strServerPath,
                    0,
                    0,
                    "md5,beginTask",
                    out byte[] baContent,
                    out string strMetadata,
                    out string strOutputPath,
                    out md5,
                    out strError);
                if (lRet == -1)
                {
                    if (channel.ErrorCode == localhost.ErrorCode.NotFound)
                    {
                        return(0);
                    }

                    // TODO: 遇到通讯出错,需要重试操作



                    return(-1);
                }

                string taskID = Encoding.UTF8.GetString(md5);

                // 轮询,获得任务结果
                while (true)
                {
                    if (token.IsCancellationRequested)
                    {
                        strError = "前端请求中断";
                        return(-1);
                    }

                    if (stop != null && stop.IsStopped)
                    {
                        strError = "前端请求中断";
                        return(-1);
                    }

REDO_CHECKTASK:
                    lRet = channel.GetRes(
                        stop,
                        strServerPath,
                        0,
                        0,
                        $"md5,getTaskResult,taskID:{taskID}",
                        out baContent,
                        out strMetadata,
                        out strOutputPath,
                        out md5,
                        out strError);
                    // TODO: 如果遇到通讯出错,需要重试操作
                    if (lRet == -1)
                    {
                        if (prompt != null &&
                            !(stop != null && stop.IsStopped == true))
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            e.MessageText = $"检查文件 {strServerPath} MD5 任务状态时发生错误: {strError}";
                            e.Actions     = "yes,no,cancel";
                            prompt(null, e);
                            if (e.ResultAction == "yes")
                            {
                                goto REDO_CHECKTASK;
                            }
                        }

                        return(-1);
                    }
                    if (lRet == 1)
                    {
                        return(1);
                    }

                    Task.Delay(TimeSpan.FromSeconds(1), token).Wait();
                }
            }
            catch (Exception ex)
            {
                strError = "GetServerFileMD5ByTask() 出现异常: " + ex.Message;
                return(-1);
            }
            finally
            {
                channel.Timeout = old_timeout;
            }
        }
Exemplo n.º 17
0
        public IEnumerator GetEnumerator()
        {
            string strError = "";
            int    nRet     = 0;

            long lRet = 0;

            if (this.Date.Length != 8)
            {
                throw new ArgumentException("FileName 成员值的长度应该是 8 字符");
            }

            if ((this.LogType & LogType.AccessLog) != 0 &&
                (this.LogType & LogType.OperLog) != 0)
            {
                throw new ArgumentException("OperLogItemLoader 的 LogType 只能使用一种类型");
            }

            if (this.Stop != null && this.Estimate != null)
            {
                this.Stop.SetMessage("正在装入日志文件 " + this.Date + " 中的记录。"
                                     + "剩余时间 " + ProgressEstimate.Format(Estimate.Estimate(lProgressValue)) + " 已经过时间 " + ProgressEstimate.Format(Estimate.delta_passed));
            }

            string strXml = "";
            long   lAttachmentTotalLength = 0;

            byte[] attachment_data = null;

            long lFileSize = 0;

            if (lServerFileSize == -1)
            {
                long _lServerFileSize = 0;

                string strStyle = "level-" + Level.ToString();
                if ((this.LogType & LogType.AccessLog) != 0)
                {
                    strStyle += ",accessLog";
                }

                // 获得服务器端日志文件尺寸
                lRet = this.Channel.GetOperLog(
                    this.Stop,
                    this.Date,
                    -1, // lIndex,
                    -1, // lHint,
                    strStyle,
                    "", // strFilter
                    out strXml,
                    out _lServerFileSize,
                    0,  // lAttachmentFragmentStart,
                    0,  // nAttachmentFramengLength,
                    out attachment_data,
                    out lAttachmentTotalLength,
                    out strError);
                // 2015/11/25
                if (lRet == -1)
                {
                    throw new ChannelException(this.Channel.ErrorCode, strError);
                }

                this.lServerFileSize = _lServerFileSize;

                if (lRet == 0)
                {
                    yield break;
                }
                // 2015/11/25
                if (_lServerFileSize == -1)
                {
                    yield break;    // 此类型的日志尚未启用
                }
            }

            Stream stream           = null;
            bool   bCacheFileExist  = false;
            bool   bRemoveCacheFile = false; // 是否要自动删除未全部完成的本地缓存文件

            bool bAutoCache = this.AutoCache;

            if (bAutoCache == true)
            {
                string strFileName = this.Date;
                if ((this.LogType & LogType.AccessLog) != 0)
                {
                    strFileName = this.Date + ".a";
                }

                nRet = PrepareCacheFile(
                    this.CacheDir,
                    strFileName,    // this.FileName,
                    lServerFileSize,
                    out bCacheFileExist,
                    out stream,
                    out strError);
                if (nRet == -1)
                {
                    throw new Exception(strError);
                }

                if (bCacheFileExist == false && stream != null)
                {
                    bRemoveCacheFile = true;
                }
            }

            try
            {
                if (bCacheFileExist == true)
                {
                    lFileSize = stream.Length;
                }
                else
                {
                    lFileSize = lServerFileSize;
                }

                // stop.SetProgressRange(0, lTotalSize);

                if (String.IsNullOrEmpty(Range) == true)
                {
                    Range = "0-" + (long.MaxValue - 1).ToString();    // "0-9999999999";
                }
                RangeList rl = new RangeList(Range);

                for (int i = 0; i < rl.Count; i++)
                {
                    RangeItem ri = (RangeItem)rl[i];

                    // 让 100- 这样的 range 可以使用
                    if (ri.lLength == -1)
                    {
                        ri.lLength = long.MaxValue - ri.lStart;
                    }

                    OperLogInfo[] records       = null;
                    long          lStartRecords = 0;

                    long lHint     = -1;
                    long lHintNext = -1;
                    for (long lIndex = ri.lStart; lIndex < ri.lStart + ri.lLength; lIndex++)
                    {
                        // Application.DoEvents();

                        if (this.Stop != null && this.Stop.State != 0)
                        {
                            strError = "用户中断";
                            throw new InterruptException(strError);
                            // yield break; ?
                        }

                        if (lIndex == ri.lStart)
                        {
                            lHint = -1;
                        }
                        else
                        {
                            lHint = lHintNext;
                        }

                        if (bCacheFileExist == true)
                        {
                            if (lHint == -1)
                            {
                                // return:
                                //      -1  error
                                //      0   成功
                                //      1   到达文件末尾或者超出
                                nRet = LocationRecord(stream,
                                                      lIndex,
                                                      out strError);
                                if (nRet == -1)
                                {
                                    throw new Exception(strError);
                                }
                            }
                            else
                            {
                                // 根据暗示找到
                                if (lHint == stream.Length)
                                {
                                    break;
                                }

                                if (lHint > stream.Length)
                                {
                                    strError = "lHint参数值不正确";
                                    throw new Exception(strError);
                                }
                                if (stream.Position != lHint)
                                {
                                    stream.Seek(lHint, SeekOrigin.Begin);
                                }
                            }

                            nRet = ReadCachedEnventLog(
                                stream,
                                out strXml,
                                out lAttachmentTotalLength,
                                out strError);
                            if (nRet == -1)
                            {
                                throw new Exception(strError);
                            }
                            lHintNext = stream.Position;
                        }
                        else
                        {
                            if (records == null || lIndex /*- ri.lStart*/ >= lStartRecords + records.Length)
                            {
                                int nCount = -1;
                                if (ri.lLength >= Int32.MaxValue)
                                {
                                    nCount = -1;    // 500;   // -1;
                                }
                                else
                                {
                                    nCount = (int)ri.lLength;   // Math.Min(500, (int)ri.lLength);
                                }
                                string strStyle = "level-" + Level.ToString();
                                if ((this.LogType & LogType.AccessLog) != 0)
                                {
                                    strStyle += ",accessLog";
                                }

                                // 2017/10/9
                                if (this.ReplicationLevel == true)
                                {
                                    strStyle += ",supervisor";  // 注:当前账户中还应该包含 replicatoin 权限才能真正获得日志记录中的密码字段
                                }
                                if (string.IsNullOrEmpty(this.ServerVersion) == false &&
                                    StringUtil.CompareVersion(this.ServerVersion, "3.17") >= 0)
                                {
                                    strStyle += ",wait";
                                }

REDO:
                                // 获得日志
                                // return:
                                //      -1  error
                                //      0   file not found
                                //      1   succeed
                                //      2   超过范围,本次调用无效
                                lRet = this.Channel.GetOperLogs(
                                    this.Stop,
                                    this.Date + ".log",
                                    lIndex,
                                    lHint,
                                    nCount,
                                    strStyle,
                                    this.Filter, // strFilter
                                    out records,
                                    out strError);
                                if (lRet == -1)
                                {
#if NO
                                    DialogResult result = MessageBox.Show(owner,
                                                                          "获取日志信息 (" + this.FileName + " " + lIndex.ToString() + ") 的操作发生错误: " + strError + "\r\n\r\n是否重试操作?\r\n\r\n(是: 重试;  否: 跳过本次操作,继续后面的操作; 放弃: 停止全部操作)",
                                                                          "OperLogItemLoader",
                                                                          MessageBoxButtons.YesNoCancel,
                                                                          MessageBoxIcon.Question,
                                                                          MessageBoxDefaultButton.Button1);
                                    if (result == DialogResult.Yes)
                                    {
                                        goto REDO;
                                    }
                                    if (result == DialogResult.Cancel)
                                    {
                                        throw new Exception(strError);
                                    }
                                    else
                                    {
                                        // TODO: 是否要在listview中装入一条表示出错的行?
                                        lHintNext = -1;
                                        continue;
                                    }
#endif
                                    if (this.Prompt != null)
                                    {
                                        MessagePromptEventArgs e = new MessagePromptEventArgs();
                                        e.MessageText = "获取 " + this._logType.ToString() + " 日志信息 (" + this.Date + " " + lIndex.ToString() + ") 的操作发生错误: " + strError;
                                        e.Actions     = "yes,no,cancel";
                                        this.Prompt(this, e);
                                        if (e.ResultAction == "cancel")
                                        {
                                            throw new InterruptException(strError);
                                        }
                                        else if (e.ResultAction == "yes")
                                        {
                                            if (this.Stop != null)
                                            {
                                                this.Stop.Continue();
                                            }
                                            goto REDO;
                                        }
                                        else
                                        {
                                            lHintNext = -1;
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        throw new ChannelException(this.Channel.ErrorCode, strError);
                                    }
                                }
                                if (lRet == 0)
                                {
                                    yield break;
                                }

                                if (lRet == 2)
                                {
                                    break;
                                }

                                // records数组表示的起点位置
                                lStartRecords = lIndex /* - ri.lStart*/;
                            }

                            OperLogInfo info = records[lIndex - lStartRecords];

                            strXml    = info.Xml;
                            lHintNext = info.HintNext;
                            lAttachmentTotalLength = info.AttachmentLength;

                            // 写入本地缓存的日志文件
                            if (stream != null)
                            {
                                try
                                {
                                    WriteCachedEnventLog(
                                        stream,
                                        strXml,
                                        lAttachmentTotalLength);
                                }
                                catch (Exception ex)
                                {
                                    strError = "写入本地缓存文件的时候出错: " + ex.Message;
                                    throw new Exception(strError);
                                }
                            }
                        }

#if NO
                        // 2011/12/30
                        // 日志记录可能动态地增加了,超过了原先为ProgressBar设置的范围
                        if (lFizeTotalSize < (int)lHintNext)
                        {
                            lFizeTotalSize = lHintNext;

                            stop.SetProgressRange(0, lFizeTotalSize);
                        }
#endif
                        if (lHintNext >= 0)
                        {
                            // 校正
                            if (lProgressValue + lHintNext >= lSize)    // > 2017/12/4 修改为 >=
                            {
                                lSize = lProgressValue + lHintNext;

                                if (this.Stop != null)
                                {
                                    this.Stop.SetProgressRange(0, lSize);
                                }
                                if (this.Estimate != null)
                                {
                                    Estimate.SetRange(0, lSize);
                                }
                            }

                            this.Stop?.SetProgressValue(lProgressValue + lHintNext);
                        }

                        if (lIndex % 100 == 0)
                        {
                            if (this.Stop != null && this.Estimate != null)
                            {
                                Estimate.Text = "剩余时间 " + ProgressEstimate.Format(Estimate.Estimate(lProgressValue + lHintNext)) + " 已经过时间 " + ProgressEstimate.Format(Estimate.delta_passed);
                                this.Stop.SetMessage("正在装入日志文件 " + this.Date + " 中的记录 " + lIndex.ToString() + " 。"
                                                     + Estimate.Text);
                            }
                        }

                        {
                            OperLogItem item = new OperLogItem
                            {
                                Xml              = strXml,
                                Index            = lIndex,
                                Date             = this.Date.Substring(0, 8),
                                AttachmentLength = lAttachmentTotalLength
                            };
                            yield return(item);
                        }
                    }
                }

                // 创建本地缓存的日志文件的 metadata 文件
                if (bCacheFileExist == false && stream != null)
                {
                    string strFileName = this.Date;
                    if ((this.LogType & LogType.AccessLog) != 0)
                    {
                        strFileName = this.Date + ".a";
                    }

                    nRet = CreateCacheMetadataFile(
                        this.CacheDir,
                        strFileName,    // this.FileName,
                        lServerFileSize,
                        out strError);
                    if (nRet == -1)
                    {
                        throw new Exception(strError);
                    }
                }

                bRemoveCacheFile = false;   // 不删除
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }

                if (bRemoveCacheFile == true)
                {
                    string strFileName = this.Date;
                    if ((this.LogType & LogType.AccessLog) != 0)
                    {
                        strFileName = this.Date + ".a";
                    }

                    string strError1 = "";
                    nRet = DeleteCacheFile(
                        this.CacheDir,
                        strFileName,    // this.FileName,
                        out strError1);
                    if (nRet == -1)
                    {
                        // MessageBox.Show(owner, strError1);
                        if (this.Prompt != null)
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            e.MessageText = strError1;
                            e.Actions     = "ok";
                            this.Prompt(this, e);
                        }
                    }
                }
            }

            lProgressValue += lFileSize;
        }
Exemplo n.º 18
0
 void loader_Prompt(object sender, MessagePromptEventArgs e)
 {
     if (this.Prompt != null)
         this.Prompt(sender, e);
 }
Exemplo n.º 19
0
        public IEnumerator GetEnumerator()
        {
            string strError = "";
            int    nRet     = 0;

            if ((this.LogType & LogType.AccessLog) != 0 &&
                (this.LogType & LogType.OperLog) != 0)
            {
                throw new ArgumentException("OperLogLoader 的 LogType 只能使用一种类型");
            }

            if (string.IsNullOrEmpty(this.CacheDir) == false)
            {
                TryCreateDir(this.CacheDir);
            }

            // ProgressEstimate estimate = new ProgressEstimate();
            bool bAutoCache = this.AutoCache;

            if (bAutoCache == true)
            {
                // 象征性获得一个日志文件的尺寸,主要目的是为了触发一次通道登录
                // return:
                //      -2  此类型的日志尚未启用
                //      -1  error
                //      0   file not found
                //      1   found
                nRet = GetFileSize(
                    this.Stop,
                    this.Channel,
                    this.CacheDir,
                    "20121001.log",
                    this.LogType,
                    out long lServerFileSize,
                    out long lCacheFileSize,
                    out strError);
                if (nRet == -1)
                {
                    throw new ChannelException(this.Channel.ErrorCode, strError);
                }
                // 2015/11/25
                if (nRet == -2)
                {
                    yield break;    // 此类型的日志尚未启用
                }
                // 检查日志文件缓存目录的版本是否和当前用户的信息一致
                // return:
                //      -1  出错
                //      0   一致
                //      1   不一致
                nRet = DetectCacheVersionFile(
                    this.CacheDir,
                    "version.xml",
                    this.Channel.LibraryCodeList,
                    this.Channel.Url,
                    out strError);
                if (nRet == -1)
                {
                    throw new Exception(strError);
                }
                if (nRet == 1)
                {
REDO:
                    // 清空当前缓存目录
                    nRet = DeleteDataDir(
                        this.CacheDir,
                        out strError);
                    if (nRet == -1)
                    {
                        if (this.Prompt != null)
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            e.MessageText = "清空当前缓存目录时发生错误: " + strError;
                            e.Actions     = "yes,no,cancel";
                            this.Prompt(this, e);
                            if (e.ResultAction == "cancel")
                            {
                                throw new InterruptException(strError);
                            }
                            else if (e.ResultAction == "yes")
                            {
                                goto REDO;
                            }
                            else
                            {
                            }
                        }
                        else
                        {
                            throw new Exception(strError);
                        }
                    }
#if NO
                    if (nRet == -1)
                    {
                        throw new Exception(strError);
                    }
#endif

                    TryCreateDir(this.CacheDir);  // 重新创建目录

                    // 创建版本文件
                    nRet = CreateCacheVersionFile(
                        this.CacheDir,
                        "version.xml",
                        this.Channel.LibraryCodeList,
                        this.Channel.Url,
                        out strError);
                    if (nRet == -1)
                    {
                        throw new Exception(strError);
                    }
                }
            }

            long          lTotalSize = 0;
            List <string> lines      = new List <string>(); // 经过处理后排除了不存在的文件名
            List <string> ranges     = new List <string>(); // 日期后面的偏移部分
            List <long>   sizes      = new List <long>();   // 服务器日志文件的尺寸

#if NO
            this.Stop.SetMessage("正在准备获得日志文件尺寸 ...");
            foreach (string strLine in this.FileNames)
            {
                // Application.DoEvents();

                if (this.Stop != null && this.Stop.State != 0)
                {
                    strError = "用户中断";
                    throw new InterruptException(strError);
                    // yield break; ?
                }

                if (String.IsNullOrEmpty(strLine) == true)
                {
                    continue;
                }

                string strFilename = strLine.Trim();
                // 去掉注释
                nRet = strFilename.IndexOf("#");
                if (nRet != -1)
                {
                    strFilename = strFilename.Substring(0, nRet).Trim();
                }

                if (String.IsNullOrEmpty(strFilename) == true)
                {
                    continue;
                }

                string strLogFilename = "";
                string strRange       = "";

                nRet = strFilename.IndexOf(":");
                if (nRet != -1)
                {
                    strLogFilename = strFilename.Substring(0, nRet).Trim();
                    strRange       = strFilename.Substring(nRet + 1).Trim();
                }
                else
                {
                    strLogFilename = strFilename.Trim();
                    strRange       = "";
                }

                if (strLogFilename.Length == 8)
                {
                    strLogFilename += ".log";
                }
REDO_GETSIZE:
                long lServerFileSize = 0;
                long lCacheFileSize = 0;
                // 获得一个日志文件的尺寸
                //      -2  此类型的日志尚未启用
                //      -1  error
                //      0   file not found
                //      1   found
                nRet = GetFileSize(
                    this.Stop,
                    this.Channel,
                    this.CacheDir,
                    strLogFilename,
                    this.LogType,
                    out lServerFileSize,
                    out lCacheFileSize,
                    out strError);
                if (nRet == -1)
                {
                    // throw new Exception(strError);

                    if (this.Prompt != null)
                    {
                        MessagePromptEventArgs e = new MessagePromptEventArgs();
                        e.MessageText = "获取日志文件 " + strLogFilename + " 尺寸的操作发生错误: " + strError;
                        e.Actions     = "yes,no,cancel";
                        this.Prompt(this, e);
                        if (e.ResultAction == "cancel")
                        {
                            throw new InterruptException(strError);
                        }
                        else if (e.ResultAction == "yes")
                        {
                            if (this.Stop != null)
                            {
                                this.Stop.Continue();
                            }
                            goto REDO_GETSIZE;
                        }
                        else
                        {
                            // ??
                            continue;
                        }
                    }
                    else
                    {
                        throw new ChannelException(this.Channel.ErrorCode, strError);
                    }
                }

                if (nRet == 0)
                {
                    continue;
                }

                if (lServerFileSize == 0)
                {
                    continue;   // 0字节的文件当作不存在处理
                }
                // 2015/11/25
                if (lServerFileSize == -1)
                {
                    yield break;    // 此类型的日志尚未启用
                }
                Debug.Assert(lServerFileSize >= 0, "");

                if (bAutoCache == true)
                {
                    if (lCacheFileSize > 0)
                    {
                        lTotalSize += lCacheFileSize;
                    }
                    else
                    {
                        lTotalSize += lServerFileSize;
                    }
                }
                else
                {
                    lTotalSize += lServerFileSize;
                }

                // lines.Add(strFilename);
                lines.Add(strLogFilename);
                ranges.Add(strRange);

                // 记忆每个文件的尺寸,后面就不用获取了?
                sizes.Add(lServerFileSize);
            }
#endif
            // 预先处理一下文件名
            List <string> filenames = new List <string>();
            foreach (string strLine in this.Dates)
            {
                if (this.Stop != null && this.Stop.State != 0)
                {
                    strError = "用户中断";
                    throw new InterruptException(strError);
                }

                if (String.IsNullOrEmpty(strLine) == true)
                {
                    continue;
                }

                string strFilename = strLine.Trim();
                // 去掉注释
                nRet = strFilename.IndexOf("#");
                if (nRet != -1)
                {
                    strFilename = strFilename.Substring(0, nRet).Trim();
                }

                if (String.IsNullOrEmpty(strFilename) == true)
                {
                    continue;
                }

#if NO
                List <string> parts    = StringUtil.ParseTwoPart(strFilename, ":");
                string        strRange = parts[1];

                strFilename = parts[0].Substring(0, 8);

                if (string.IsNullOrEmpty(strRange) == false)
                {
                    range_table[strFilename] = strRange;    // TODO: 如何防范文件名重复?
                }
#endif
                filenames.Add(strFilename);
                Debug.Assert(strFilename.Length >= 8, "");
            }

            // 准备查找表
            Hashtable length_table = new Hashtable();
            {
                List <FileSize> size_pairs = GetFilesLength(
                    // filenames
                    );
                foreach (FileSize size_pair in size_pairs)
                {
                    length_table[size_pair.Date] = size_pair;
                }
            }

            foreach (string filename in filenames)
            {
                FileSize size_pair = length_table[filename.Substring(0, 8)] as FileSize;
                if (size_pair == null)
                {
                    continue;
                }
                Debug.Assert(size_pair != null, "");

                lines.Add(filename);
                sizes.Add(size_pair.ServerFileSize);

                if (size_pair.ServerFileSize == -1)
                {
                    yield break;    // 此类型的日志尚未启用
                }
                Debug.Assert(size_pair.ServerFileSize >= 0, "");

                if (bAutoCache == true)
                {
                    if (size_pair.CacheFileSize > 0)
                    {
                        lTotalSize += size_pair.CacheFileSize;
                    }
                    else
                    {
                        lTotalSize += size_pair.ServerFileSize;
                    }
                }
                else
                {
                    lTotalSize += size_pair.ServerFileSize;
                }
            }

            long lDoneSize = 0;

            if (this.ProgressStart == -1)
            {
                lDoneSize = lTotalSize;
            }
            else
            {
                lDoneSize = this.ProgressStart;
            }

            lTotalSize += lDoneSize;

            if (this.Stop != null)
            {
                this.Stop.SetProgressRange(0, lTotalSize);
            }

            if (Estimate != null)
            {
                Estimate.SetRange(lDoneSize, lTotalSize);
                Estimate.StartEstimate();
            }

            for (int i = 0; i < lines.Count; i++)
            {
                // Application.DoEvents();

                if (this.Stop != null && this.Stop.State != 0)
                {
                    strError = "用户中断";
                    throw new InterruptException(strError);
                    // yield break; ?
                }

                string strLine = lines[i];
                Debug.Assert(strLine.Length >= 8, "");

                // string strRange = ranges[i];

                // 2017/10/9
                List <string> parts    = StringUtil.ParseTwoPart(strLine, ":");
                string        strRange = parts[1];

                strLine = parts[0];

                string strLogFilename = strLine;
#if NO
                string strLogFilename = "";
                string strRange       = "";

                nRet = strLine.IndexOf(":");
                if (nRet != -1)
                {
                    strLogFilename = strLine.Substring(0, nRet).Trim();
                    strRange       = strLine.Substring(nRet + 1).Trim();
                }
                else
                {
                    strLogFilename = strLine.Trim();
                    strRange       = "";
                }
#endif

                {
                    OperLogItemLoader loader = new OperLogItemLoader
                    {
                        Stop    = this.Stop,
                        Channel = this.Channel,
                        // loader.owner = this.owner;
                        Estimate         = this.Estimate,
                        Date             = strLogFilename,
                        Level            = this.Level,
                        ReplicationLevel = this.ReplicationLevel,
                        lServerFileSize  = sizes[i],
                        Range            = strRange,
                        AutoCache        = this.AutoCache,
                        lProgressValue   = lDoneSize,
                        lSize            = lTotalSize,
                        Filter           = this.Filter,
                        LogType          = this.LogType,
                        ServerVersion    = this.ServerVersion
                    };

                    if (this.Prompt != null)
                    {
                        loader.Prompt += new MessagePromptEventHandler(loader_Prompt);
                    }
                    try
                    {
                        foreach (OperLogItem item in loader)
                        {
                            yield return(item);
                        }
                    }
                    finally
                    {
                        if (this.Prompt != null)
                        {
                            loader.Prompt -= new MessagePromptEventHandler(loader_Prompt);
                        }
                    }

                    lDoneSize  = loader.lProgressValue;
                    lTotalSize = loader.lSize;
                }
            }
        }
Exemplo n.º 20
0
        public IEnumerator GetEnumerator()
        {
            List <string> format_list     = new List <string>();
            int           nContentIndex   = format_list.Count;
            int           nTimestampIndex = -1;
            int           nMetadataIndex  = -1;

            format_list.Add(this.Format);
            // if ((this.GetBiblioInfoStyle & dp2Circulation.GetBiblioInfoStyle.Timestamp) != 0)
            if (this.GetBiblioInfoStyle.HasFlag(GetBiblioInfoStyle.Timestamp) == true)  // 新用法
            {
                nTimestampIndex = format_list.Count;
                format_list.Add("timestamp");
            }
            if ((this.GetBiblioInfoStyle & GetBiblioInfoStyle.Metadata) != 0)
            {
                nMetadataIndex = format_list.Count;
                format_list.Add("metadata");
            }

            string[] formats = new string[format_list.Count];
            format_list.CopyTo(formats);

            List <string> batch = new List <string>();

            for (int index = 0; index < m_recpaths.Count; index++)
            {
                string s = m_recpaths[index];
                batch.Add(s);

                // 每100个一批,或者最后一次
                if (batch.Count >= 100 ||
                    (index == m_recpaths.Count - 1 && batch.Count > 0))
                {
REDO:
                    string strCommand = "@path-list:" + StringUtil.MakePathList(batch);

                    string[] results   = null;
                    byte[]   timestamp = null;
                    string   strError  = "";
                    // Channel.Timeout = new TimeSpan(0, 0, 5); 应该让调主设置这个值
                    long lRet = Channel.GetBiblioInfos(
                        this.Stop,
                        strCommand,
                        "",
                        formats,
                        out results,
                        out timestamp,
                        out strError);
                    if (lRet == -1)
                    {
                        if (this.Prompt != null)
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            // e.MessageText = "获得书目记录 '"+strCommand+"' ("+StringUtil.MakePathList(format_list)+") 时发生错误: " + strError;
                            e.MessageText = "获得书目记录时发生错误: " + strError + "\r\ncommand='" + strCommand + "' (" + StringUtil.MakePathList(format_list) + ")";
                            e.Actions     = "yes,no,cancel";
                            this.Prompt(this, e);
                            if (e.ResultAction == "cancel")
                            {
                                throw new ChannelException(Channel.ErrorCode, strError);
                            }
                            else if (e.ResultAction == "yes")
                            {
                                goto REDO;
                            }
                            else
                            {
                                // no 也是抛出异常。因为继续下一批代价太大
                                throw new ChannelException(Channel.ErrorCode, strError);
                            }
                        }
                        else
                        {
                            throw new ChannelException(Channel.ErrorCode, strError);
                        }
                    }

                    if (lRet == 0)
                    {
                        if (lRet == 0 && String.IsNullOrEmpty(strError) == true)
                        {
                            foreach (string path in batch)
                            {
                                BiblioItem item = new BiblioItem();
                                item.RecPath   = path;
                                item.ErrorCode = ErrorCode.NotFound;
                                item.ErrorInfo = "书目记录 '" + path + "' 不存在";
                                yield return(item);
                            }
                            goto CONTINUE;
                        }


                        // 如果results.Length表现正常,其实还可以继续处理
                        if (results != null && results.Length > 0)
                        {
                        }
                        else
                        {
                            // 2014/1/15
                            if (Channel.ErrorCode == ErrorCode.NotFound)
                            {
                                foreach (string path in batch)
                                {
                                    BiblioItem item = new BiblioItem();
                                    item.RecPath   = path;
                                    item.ErrorCode = ErrorCode.NotFound;
                                    item.ErrorInfo = "书目记录 '" + path + "' 不存在";
                                    yield return(item);
                                }
                                goto CONTINUE;
                            }
                            strError = "获得书目记录 '" + StringUtil.MakePathList(batch) + "' 时发生错误: " + strError;
                            throw new Exception(strError);
                        }
                    }

                    if (results == null)
                    {
                        strError = "results == null";
                        throw new Exception(strError);
                    }

                    for (int i = 0; i < results.Length / formats.Length; i++)
                    {
                        BiblioItem item = new BiblioItem();
                        item.RecPath = batch[i];
                        if (nContentIndex != -1)
                        {
                            item.Content = results[i * formats.Length + nContentIndex];
                        }
                        if (nTimestampIndex != -1)
                        {
                            item.Timestamp = ByteArray.GetTimeStampByteArray(results[i * formats.Length + nTimestampIndex]);
                        }
                        if (nMetadataIndex != -1)
                        {
                            item.Metadata = results[i * formats.Length + nMetadataIndex];
                        }
                        if (string.IsNullOrEmpty(item.Content) == true)
                        {
                            item.ErrorCode = ErrorCode.NotFound;
                            item.ErrorInfo = "书目记录 '" + item.RecPath + "' 不存在";
                        }
                        yield return(item);
                    }

CONTINUE:
                    if (batch.Count > results.Length / formats.Length)
                    {
                        // 有本次没有获取到的记录
                        batch.RemoveRange(0, results.Length / formats.Length);
                        if (index == m_recpaths.Count - 1)
                        {
                            goto REDO;  // 当前已经是最后一轮了,需要继续做完
                        }
                        // 否则可以留给下一轮处理
                    }
                    else
                    {
                        batch.Clear();
                    }
                }
            }
        }
Exemplo n.º 21
0
        public IEnumerator GetEnumerator()
        {
            List<string> batch = new List<string>();
            for (int index = 0; index < m_barcodes.Count; index++)
            {
                string s = m_barcodes[index];

                if (string.IsNullOrEmpty(s) == true)
                    throw new Exception("册条码号字符串不允许为空 (index=" + index.ToString() + ")");

                batch.Add(s);

                // 每100个一批,或者最后一次
                if (batch.Count >= 100 ||
                    (index == m_barcodes.Count - 1 && batch.Count > 0))
                {
                REDO_GETITEMINFO:
                    string strBiblio = "";
                    string strResult = "";
                    string strError = "";
                    long lRet = this.Channel.GetItemInfo(
                        this.Stop,
                        "@barcode-list:" + StringUtil.MakePathList(batch),
                        "get-path-list",
                        out strResult,
                        "", // strBiblioType,
                        out strBiblio,
                        out strError);
                    if (lRet == -1)
                    {
                        if (this.Prompt != null)
                        {
                            MessagePromptEventArgs e = new MessagePromptEventArgs();
                            e.MessageText = "通过册条码号获得记录路径时发生错误: " + strError;
                            e.Actions = "yes,no,cancel";
                            this.Prompt(this, e);
                            if (e.ResultAction == "cancel")
                                throw new Exception(strError);
                            else if (e.ResultAction == "yes")
                            {
                                if (this.Stop != null)
                                    this.Stop.Continue();
                                goto REDO_GETITEMINFO;
                            }
                            else
                            {
                            }
                        }
                        else
                            throw new ChannelException(Channel.ErrorCode, strError);
                    }

                    List<string> recpaths = StringUtil.SplitList(strResult);

                    if (batch.Count != recpaths.Count)
                    {
                        strError = "batch.Count != recpaths.Count";
                        throw new Exception(strError);
                    }
                    Debug.Assert(batch.Count == recpaths.Count, "");

                    int i = 0;
                    foreach (string recpath in recpaths)
                    {
                        EntityItem item = new EntityItem();
                        item.Barcode = batch[i];

                        if (string.IsNullOrEmpty(recpath) == false
                            && recpath[0] == '!')
                            item.ErrorInfo = recpath.Substring(1);
                        else
                            item.RecPath = recpath;
                        i++;

                        yield return item;
                    }

                    batch.Clear();
                }
            }
        }