Exemplo n.º 1
0
        // 重建检索点
        // TODO: 需要改造为在不校准首位号的情况下进度条也要显示正确。可参考DoExportFile()
        // parameters:
        void DoRebuildKeys()
        {
            string strError = "";
            int nRet = 0;
            long lRet = 0;

            string strInfo = "";    // 汇总信息,在完成后显示

            //      bClearKeysAtBegin   批处理开始的时候清除了所有的keys表
            //      bDeleteOldKeysPerRecord 做每条记录的时候是否要先删除属于这条记录的旧的检索点。
            bool bClearKeysAtBegin = true;
            bool bDeleteOldKeysPerRecord = false;

            m_nRecordCount = -1;

            if (textBox_dbPath.Text == "")
            {
                MessageBox.Show(this, "尚未选择要重建检索点的数据库 ...");
                return;
            }

            DialogResult result = MessageBox.Show(this,
                "确实要对下列数据库\r\n---\r\n" + this.textBox_dbPath.Text.Replace(";", "\r\n") + "\r\n---\r\n进行重建检索点的操作?",
                "dp2batch",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question,
                MessageBoxDefaultButton.Button2);
            if (result == DialogResult.No)
                return;

            RebuildKeysDialog option_dlg = new RebuildKeysDialog();
            MainForm.SetControlFont(option_dlg, this.DefaultFont);
            option_dlg.StartPosition = FormStartPosition.CenterScreen;
            option_dlg.ShowDialog(this);
            if (option_dlg.DialogResult == DialogResult.Cancel)
                return;

            if (option_dlg.WholeMode == true)
            {
                bClearKeysAtBegin = true;
                bDeleteOldKeysPerRecord = false;
            }
            else
            {
                bClearKeysAtBegin = false;
                bDeleteOldKeysPerRecord = true;
            }

            string[] dbpaths = textBox_dbPath.Text.Split(new char[] { ';' });

            // 如果为单库输出
            if (dbpaths.Length == 1)
            {
                // 否则移到DoExportFile()函数里面去校验
                ResPath respath = new ResPath(dbpaths[0]);

                channel = this.Channels.GetChannel(respath.Url);

                string strDbName = respath.Path;

                // 校验起止号
                if (checkBox_verifyNumber.Checked == true)
                {
                    nRet = VerifyRange(channel,
                        strDbName,
                        out strError);
                    if (nRet == -1)
                        MessageBox.Show(this, strError);
                }
                else
                {
                    if (this.textBox_startNo.Text == "")
                    {
                        strError = "尚未指定起始号";
                        goto ERROR1;
                    }
                    if (this.textBox_endNo.Text == "")
                    {
                        strError = "尚未指定结束号";
                        goto ERROR1;
                    }
                }
            }
            else
            {
                Debug.Assert(dbpaths.Length > 1, "");

                // 多库输出。修改界面要素,表示针对每个库都是全库处理
                this.radioButton_all.Checked = true;
                this.textBox_startNo.Text = "1";
                this.textBox_endNo.Text = "9999999999";
            }


            stop.OnStop += new StopEventHandler(this.DoStop);
            stop.Initial("正在重建检索点");
            stop.BeginLoop();


            EnableControls(false);
            try
            {

                // TODO: 如果是多库输出,是否要对非“全部”的起止号范围进行警告? 因为后面是强迫按照全部来进行的

                for (int f = 0; f < dbpaths.Length; f++)
                {
                    string strOneDbPath = dbpaths[f];

                    ResPath respath = new ResPath(strOneDbPath);

                    channel = this.Channels.GetChannel(respath.Url);

                    string strDbName = respath.Path;

                    if (String.IsNullOrEmpty(strInfo) == false)
                        strInfo += "\r\n";

                    strInfo += "" + strDbName;

                    // 实际处理的首尾号
                    string strRealStartNo = "";
                    string strRealEndNo = "";
                    /*
                    DialogResult result;
                    if (checkBox_export_delete.Checked == true)
                    {
                        result = MessageBox.Show(this,
                            "确实要删除" + respath.Path + "内指定范围的记录?\r\n\r\n---------\r\n(是)删除 (否)放弃批处理",
                            "dp2batch",
                            MessageBoxButtons.YesNo,
                            MessageBoxIcon.Question,
                            MessageBoxDefaultButton.Button2);
                        if (result != DialogResult.Yes)
                            continue;
                    }*/

                    // 

                    // 如果为多库重建
                    if (dbpaths.Length > 1)
                    {
                        // 如果为全选
                        if (this.radioButton_all.Checked == true
                            || f > 0)
                        {
                            // 恢复为最大范围
                            this.textBox_startNo.Text = "1";
                            this.textBox_endNo.Text = "9999999999";
                        }

                        // 校验起止号
                        if (checkBox_verifyNumber.Checked == true)
                        {
                            nRet = VerifyRange(channel,
                                strDbName,
                                out strError);
                            if (nRet == -1)
                                MessageBox.Show(this, strError);

                            if (nRet == 0)
                            {
                                // 库中无记录
                                AutoCloseMessageBox.Show(this, "数据库 " + strDbName + " 中无记录。");
                                strInfo += "(无记录)";

                                /*
                                if (bClearKeysAtBegin == true)
                                {
                                    // 结束Refresh数据库定义
                                    lRet = channel.DoRefreshDB(
                                        "end",
                                        strDbName,
                                        false,  // 此参数此时无用
                                        out strError);
                                    if (lRet == -1)
                                        goto ERROR1;
                                }
                                 * */

                                continue;
                            }
                        }
                        else
                        {
                            if (this.textBox_startNo.Text == "")
                            {
                                strError = "尚未指定起始号";
                                goto ERROR1;
                            }
                            if (this.textBox_endNo.Text == "")
                            {
                                strError = "尚未指定结束号";
                                goto ERROR1;
                            }

                        }
                    }


                    Int64 nStart;
                    Int64 nEnd;
                    Int64 nCur;
                    bool bAsc = GetDirection(
                        this.textBox_startNo.Text,
                        this.textBox_endNo.Text,
                        out nStart,
                        out nEnd);

                    // 设置进度条范围
                    Int64 nMax = nEnd - nStart;
                    if (nMax < 0)
                        nMax *= -1;
                    nMax++;

                    /*
                    ProgressRatio = nMax / 10000;
                    if (ProgressRatio < 1.0)
                        ProgressRatio = 1.0;

                    progressBar_main.Minimum = 0;
                    progressBar_main.Maximum = (int)(nMax / ProgressRatio);
                    progressBar_main.Value = 0;
                     * */
                    stop.SetProgressRange(0, nMax);

                    // Refresh数据库定义
                    lRet = channel.DoRefreshDB(
                        "begin",
                        strDbName,
                        bClearKeysAtBegin == true ? true : false,
                        out strError);
                    if (lRet == -1)
                        goto ERROR1;


                    bool bFirst = true;	// 是否为第一次取记录

                    string strID = this.textBox_startNo.Text;

                    m_nRecordCount = 0;
                    // 循环
                    for (; ; )
                    {
                        Application.DoEvents();	// 出让界面控制权

                        if (stop.State != 0)
                        {
                            result = MessageBox.Show(this,
                                "确实要中断当前批处理操作?",
                                "dp2batch",
                                MessageBoxButtons.YesNo,
                                MessageBoxIcon.Question,
                                MessageBoxDefaultButton.Button2);
                            if (result == DialogResult.Yes)
                            {
                                strError = "用户中断";
                                goto ERROR1;
                            }
                            else
                            {
                                stop.Continue();
                            }
                        }

                        string strDirectionComment = "";

                        string strStyle = "";

                        strStyle = "timestamp,outputpath";	// 优化

                        if (bDeleteOldKeysPerRecord == true)
                            strStyle += ",forcedeleteoldkeys";


                        if (bFirst == true)
                        {
                            // 注:如果不校验首号,只有强制循环的情况下,才能不需要next风格
                            strStyle += "";
                        }
                        else
                        {
                            if (bAsc == true)
                            {
                                strStyle += ",next";
                                strDirectionComment = "的后一条记录";
                            }
                            else
                            {
                                strStyle += ",prev";
                                strDirectionComment = "的前一条记录";
                            }
                        }

                        string strPath = strDbName + "/" + strID;
                        string strOutputPath = "";

                        bool bFoundRecord = false;

                        bool bNeedRetry = true;

                    REDO_REBUILD:
                        // 获得资源
                        // return:
                        //		-1	出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。
                        //		0	成功
                        lRet = channel.DoRebuildResKeys(strPath,
                            strStyle,
                            out strOutputPath,
                            out strError);
                        if (lRet == -1)
                        {
                            if (channel.ErrorCode == ChannelErrorCode.NotFound)
                            {
                                if (bFirst == true)
                                {
                                    // 如果要强制循环
                                    if (checkBox_forceLoop.Checked == true)
                                    {
                                        AutoCloseMessageBox.Show(this, "您为数据库 " + strDbName + " 指定的首记录 " + strID + strDirectionComment + " 不存在。\r\n\r\n按 确认 继续向后找。");
                                        bFirst = false;
                                        goto CONTINUE;
                                    }
                                    else
                                    {
                                        // 如果不要强制循环,此时也不能结束,否则会让用户以为数据库里面根本没有数据
                                        AutoCloseMessageBox.Show(this, "您为数据库 " + strDbName + " 指定的首记录 " + strID + strDirectionComment + " 不存在。\r\n\r\n(注:为避免出现此提示,可在操作前勾选“校准首尾ID”)\r\n\r\n按 确认 继续向后找...");
                                        bFirst = false;
                                        goto CONTINUE;
                                    }
                                }
                                else
                                {
                                    Debug.Assert(bFirst == false, "");

                                    if (bFirst == true)
                                    {
                                        strError = "记录 " + strID + strDirectionComment + " 不存在。处理结束。";
                                    }
                                    else
                                    {
                                        if (bAsc == true)
                                            strError = "记录 " + strID + " 是最末一条记录。处理结束。";
                                        else
                                            strError = "记录 " + strID + " 是最前一条记录。处理结束。";
                                    }

                                    if (dbpaths.Length > 1)
                                        break;  // 多库情况,继续其它库循环
                                    else
                                    {
                                        bNeedRetry = false; // 单库情况,也没有必要出现重试对话框
                                        MessageBox.Show(this, strError);
                                        break;
                                    }
                                }

                            }
                            else if (channel.ErrorCode == ChannelErrorCode.EmptyRecord)
                            {
                                bFirst = false;
                                // bFoundRecord = false;
                                // 把id解析出来
                                strID = ResPath.GetRecordId(strOutputPath);
                                goto CONTINUE;

                            }

                            // 允许重试
                            if (bNeedRetry == true)
                            {
                                DialogResult redo_result = MessageBox.Show(this,
                                    "重建检索点 记录 '" + strPath + "' (style='" + strStyle + "')时出现错误: " + strError + "\r\n\r\n重试,还是中断当前批处理操作?\r\n(Retry 重试;Cancel 中断批处理)",
                                    "dp2batch",
                                    MessageBoxButtons.RetryCancel,
                                    MessageBoxIcon.Question,
                                    MessageBoxDefaultButton.Button1);
                                if (redo_result == DialogResult.Cancel)
                                    goto ERROR1;
                                goto
                                    REDO_REBUILD;
                            }
                            else
                            {
                                goto ERROR1;
                            }

                        } // end of nRet == -1

                        bFirst = false;

                        bFoundRecord = true;

                        // 把id解析出来
                        strID = ResPath.GetRecordId(strOutputPath);
                        stop.SetMessage("已重建检索点 记录 " + strOutputPath + "  " + m_nRecordCount.ToString());

                        if (String.IsNullOrEmpty(strRealStartNo) == true)
                        {
                            strRealStartNo = strID;
                        }

                        strRealEndNo = strID;

                    CONTINUE:

                        // 是否超过循环范围
                        try
                        {
                            nCur = Convert.ToInt64(strID);
                        }
                        catch
                        {
                            // ???
                            nCur = 0;
                        }

                        if (bAsc == true && nCur > nEnd)
                            break;
                        if (bAsc == false && nCur < nEnd)
                            break;

                        if (bFoundRecord == true)
                            m_nRecordCount++;

                        //
                        //

                        if (bAsc == true)
                        {
                            // progressBar_main.Value = (int)((nCur - nStart + 1) / ProgressRatio);
                            stop.SetProgressValue(nCur - nStart + 1);
                        }
                        else
                        {
                            // ?
                            // progressBar_main.Value = (int)((nStart - nCur + 1) / ProgressRatio);
                            stop.SetProgressValue(nStart - nCur + 1);
                        }


                        // 对已经作过的进行判断
                        if (bAsc == true && nCur >= nEnd)
                            break;
                        if (bAsc == false && nCur <= nEnd)
                            break;
                    }

                    if (bClearKeysAtBegin == true)
                    {
                        // 结束Refresh数据库定义
                        lRet = channel.DoRefreshDB(
                            "end",
                            strDbName,
                            false,  // 此参数此时无用
                            out strError);
                        if (lRet == -1)
                            goto ERROR1;
                    }

                    strInfo += " : " + m_nRecordCount.ToString() + "条 (ID " + strRealStartNo + "-" + strRealEndNo + ")";

                }   // end of dbpaths loop


            }   // end of try
            finally
            {
                EnableControls(true);

                stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
                stop.Initial("");
            }

            strError = "重建检索点完成。\r\n---\r\n" + strInfo;

            // END1:

            MessageBox.Show(this, strError);
            return;

        ERROR1:
            MessageBox.Show(this, strError);
        }