コード例 #1
0
ファイル: Z3950Processor.cs プロジェクト: keji56/chord
        private static void Zserver_SearchSearch(object sender, SearchSearchEventArgs e)
        {
            string strError   = "";
            int    nCondition = 100;

            ZServerChannel zserver_channel = (ZServerChannel)sender;

            if (zserver_channel == null)
            {
                throw new ArgumentException("zserver_channel 为空");
            }

            string strInstanceName = zserver_channel.EnsureProperty().GetKeyValue("i_n");

            if (strInstanceName == null)
            {
                string strErrorText = "通道中 实例名 'i_n' 尚未初始化";    // ?? bug
                LibraryManager.Log?.Error(strErrorText);
                e.Result = new DigitalPlatform.Z3950.ZClient.SearchResult {
                    Value = -1, ErrorInfo = strErrorText
                };
                return;
            }
            Instance instance = FindZ3950Instance(strInstanceName, out strError);

            if (instance == null)
            {
                if (string.IsNullOrEmpty(strError))
                {
                    strError = "实例名 '" + strInstanceName + "' 不存在(或实例没有启用 Z39.50 服务)";
                }
                e.Result = new DigitalPlatform.Z3950.ZClient.SearchResult {
                    Value = -1, ErrorInfo = strError
                };
                return;
            }
            if (instance.Running == false)
            {
                strError   = "实例 '" + instance.Name + "' 正在维护中,暂时不能访问";
                nCondition = 1019;  // Init/AC: System not available due to maintenance
                goto ERROR1;
            }

            // 检查实例是否有至少一个可用数据库
            if (instance.zhost.GetDbCount() == 0)
            {
#if NO
                string     strErrorText = "实例 '" + strInstanceName + "' 没有提供可检索的数据库";
                DiagFormat diag         = null;
                ZProcessor.SetPresentDiagRecord(ref diag,
                                                1017, // Init/AC: No databases available for specified userId
                                                strErrorText);
                e.Diag   = diag;
                e.Result = new ZClient.SearchResult {
                    Value = -1, ErrorInfo = strErrorText
                };
                return;
#endif
                strError   = "实例 '" + instance.Name + "' 没有提供可检索的数据库";
                nCondition = 1017;// Init/AC: No databases available for specified userId
                goto ERROR1;
            }

            // 根据逆波兰表构造出 dp2 系统检索式
            // return:
            //      -1  出错
            //      0   数据库没有找到
            //      1   成功
            int nRet = Z3950Utility.BuildQueryXml(
                instance.zhost,
                e.Request.m_dbnames,
                e.Request.m_rpnRoot,
                zserver_channel.EnsureProperty().SearchTermEncoding,
                out string strQueryXml,
                out strError);
            if (nRet == -1 || nRet == 0)
            {
#if NO
                DiagFormat diag = null;
                ZProcessor.SetPresentDiagRecord(ref diag,
                                                nRet == -1 ? 2 : 235, // 2:temporary system error; 235:Database does not exist (database name)
                                                strError);
                e.Diag   = diag;
                e.Result = new ZClient.SearchResult {
                    Value = -1, ErrorInfo = strError
                };
                return;
#endif
                nCondition = nRet == -1 ? 2 : 235;  // 2:temporary system error; 235:Database does not exist (database name)
                goto ERROR1;
            }

            string strUserName = zserver_channel.EnsureProperty().GetKeyValue("i_u");
            string strPassword = zserver_channel.EnsureProperty().GetKeyValue("i_p");

            LoginInfo      login_info      = BuildLoginInfo(strUserName, strPassword);
            LibraryChannel library_channel = instance.MessageConnection.GetChannel(login_info);
            try
            {
                // TODO: 附加到 Abort 事件。这样当事件被触发的时候,能执行 library_channel.Abort

                // 全局结果集名
                string resultset_name = MakeGlobalResultSetName(zserver_channel, e.Request.m_strResultSetName);

                DateTime start = DateTime.Now;
                // 进行检索
                long lRet = 0;

                zserver_channel.Tag = library_channel;
                try
                {
                    lRet = library_channel.Search(
                        strQueryXml,
                        resultset_name,
                        "", // strOutputStyle
                        out strError);
                }
                finally
                {
                    zserver_channel.Tag = null;
                }

                // testing System.Threading.Thread.Sleep(TimeSpan.FromSeconds(6));
                TimeSpan length = DateTime.Now - start;
                if (length >= slow_length)
                {
                    // TODO: TcpClient 可能为 null, 表示通道已经被切断
                    //string ip = TcpServer.GetClientIP(zserver_channel.TcpClient);
                    //string strChannelName = "ip:" + ip + ",channel:" + zserver_channel.GetHashCode();

                    LibraryManager.Log?.Info("通道 " + zserver_channel.GetDebugName(zserver_channel.TcpClient) + " 检索式 '" + strQueryXml + "' 检索耗时 " + length.ToString() + " (命中记录 " + lRet + "),超过慢速阈值");
                }

                if (lRet == -1)
                {
                    LibraryManager.Log?.Error("通道 " + zserver_channel.GetDebugName(zserver_channel.TcpClient) + " 检索式 '" + strQueryXml + "' 检索出错: " + strError);
                }


                /*
                 * // 测试检索失败
                 * lRet = -1;
                 * strError = "测试检索失败";
                 * */

                if (lRet == -1)
                {
#if NO
                    DiagFormat diag = null;
                    ZProcessor.SetPresentDiagRecord(ref diag,
                                                    2, // temporary system error
                                                    strError);
                    e.Diag   = diag;
                    e.Result = new ZClient.SearchResult {
                        Value = -1, ErrorInfo = strError
                    };
                    return;
#endif
                    goto ERROR1;
                }
                else
                {
                    // 记忆结果集名
                    // return:
                    //      false   正常
                    //      true    结果集数量超过 MAX_RESULTSET_COUNT,返回前已经开始释放所有结果集
                    if (MemoryResultSetName(zserver_channel, resultset_name) == true)
                    {
#if NO
                        DiagFormat diag = null;
                        ZProcessor.SetPresentDiagRecord(ref diag,
                                                        112,       // Too many result sets created (maximum)
                                                        strError); // TODO: 应为 MAX_RESULTSET_COUNT
                        e.Diag   = diag;
                        e.Result = new ZClient.SearchResult {
                            Value = -1, ErrorInfo = strError
                        };
                        return;
#endif
                        nCondition = 112;  // Too many result sets created (maximum)
                        goto ERROR1;
                    }

                    e.Result = new ZClient.SearchResult {
                        ResultCount = lRet
                    };
                }
                return;
            }
            finally
            {
                instance.MessageConnection.ReturnChannel(library_channel);
            }
ERROR1:
            {
                DiagFormat diag = null;
                ZProcessor.SetPresentDiagRecord(ref diag,
                                                nCondition,
                                                strError);
                e.Diag   = diag;
                e.Result = new ZClient.SearchResult {
                    Value = -1, ErrorInfo = strError
                };
                return;
            }
        }
コード例 #2
0
        private static void Zserver_SearchSearch(object sender, SearchSearchEventArgs e)
        {
            ZServerChannel zserver_channel = (ZServerChannel)sender;

            string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n");

            if (strInstanceName == null)
            {
                string strErrorText = "通道中 实例名 '" + strInstanceName + "' 尚未初始化";
                ZManager.Log?.Error(strErrorText);
                e.Result = new DigitalPlatform.Z3950.ZClient.SearchResult {
                    Value = -1, ErrorInfo = strErrorText
                };
                return;
            }
            Instance instance = FindInstance(strInstanceName);

            if (instance == null)
            {
                e.Result = new DigitalPlatform.Z3950.ZClient.SearchResult {
                    Value = -1, ErrorInfo = "实例名 '" + strInstanceName + "' 不存在"
                };
                return;
            }

            // 根据逆波兰表构造出 dp2 系统检索式

            // return:
            //      -1  error
            //      0   succeed
            int nRet = Z3950Utility.BuildQueryXml(
                instance.zhost,
                e.Request.m_dbnames,
                e.Request.m_rpnRoot,
                zserver_channel.SetProperty().SearchTermEncoding,
                out string strQueryXml,
                out string strError);

            if (nRet == -1)
            {
                DiagFormat diag = null;
                ZProcessor.SetPresentDiagRecord(ref diag,
                                                2, // temporary system error
                                                strError);
                e.Diag   = diag;
                e.Result = new ZClient.SearchResult {
                    Value = -1, ErrorInfo = strError
                };
                return;
            }

            string strUserName = zserver_channel.SetProperty().GetKeyValue("i_u");
            string strPassword = zserver_channel.SetProperty().GetKeyValue("i_p");

            LoginInfo login_info = new LoginInfo {
                UserName = strUserName, Password = strPassword
            };

            LibraryChannel library_channel = instance.MessageConnection.GetChannel(login_info);

            try
            {
                // 全局结果集名
                string resultset_name = MakeGlobalResultSetName(zserver_channel, e.Request.m_strResultSetName);
                // 进行检索
                long lRet = library_channel.Search(
                    strQueryXml,
                    resultset_name,
                    "", // strOutputStyle
                    out strError);

                /*
                 * // 测试检索失败
                 * lRet = -1;
                 * strError = "测试检索失败";
                 * */

                if (lRet == -1)
                {
                    DiagFormat diag = null;
                    ZProcessor.SetPresentDiagRecord(ref diag,
                                                    2, // temporary system error
                                                    strError);
                    e.Diag   = diag;
                    e.Result = new ZClient.SearchResult {
                        Value = -1, ErrorInfo = strError
                    };
                    return;
                }
                else
                {
                    // 记忆结果集名
                    MemoryResultSetName(zserver_channel, resultset_name);

                    e.Result = new ZClient.SearchResult {
                        ResultCount = lRet
                    };
                }
            }
            finally
            {
                instance.MessageConnection.ReturnChannel(library_channel);
            }
        }