def handleSearch(self, data):

        self.log(repr(data))

        queryType = data.query[0]
        query = None
        queryString = ""
        if (queryType in ['type_1', 'type_101']):
            zQuery = data.query[1]
            attrset = zQuery.attributeSet
            rpn = zQuery.rpn
            query = CQLUtils.rpn2cql(rpn)
        elif (queryType == 'type_0'):
            # A Priori external
            queryString = data.query[1]
        elif (queryType == 'type_2'):
            # ISO8777  (CCL)
            queryString = data.query[1]
        elif (queryType == 'type_104'):
            # Look for CQL or SQL
            type104 = data.query[1].direct_reference

            if (type104 == Z3950_QUERY_CQL_ov):
                queryString = data.query[1].encoding[1]
                # Native CQL query
                # Looks like:  ((0,27) 'query', 0)
                query = cql.parse(queryString)
            elif (type104 == Z3950_QUERY_SQL_ov):
                # Hopefully just pass off to Postgres
                # Grab directly out of structure??
                sqlQ = data.query[1].encoding[1]
                queryString = sqlQ.queryExpression
            else:
                # Undefined query type
                raise NotImplementedError

        elif (queryType in ['type_102', 'type_100']):
            # 102: Ranked List, not yet /defined/ let alone implemented
            # 100: Z39.58 query (Standard was withdrawn)
            raise NotImplementedError

        if query:
            self.log(query.toXCQL())
        elif queryString:
            self.log("type:  " + queryType)
            self.log("query: " + queryString)

        rsetname = data.resultSetName
        dbs = data.databaseNames

        if len(dbs) == 1 and dbs[0].lower() == "ir-explain-1":
            self.search_explain(query)

        resp = SearchResponse()
        resp.resultCount = 0

        if len(dbs) == 1 and dbs[0].lower() == 'l5r':
            rs = l5r.handle_search(None, query)
            if (rs):
                resp.resultCount = len(rs)
                # Put it into our DB
                rsid = rss.create_resultSet(None, rs)
                rsidmap[data.resultSetName] = rsid
            
        resp.numberOfRecordsReturned = 0
        resp.nextResultSetPosition = 1
        resp.searchStatus = 1
        resp.resultSetStatus = 1
        resp.presentStatus = PresentStatus.get_num_from_name('failure')
        return self.encode(('searchResponse', resp))
def processQuery(self, req):
    """ Send off search query to Z target and handle results """

    if (not req.version):
        diag = Diagnostic7()
        diag.message = "Mandatory 'version' parameter not supplied"
        diag.details = 'version'
        raise diag

    # Get our config based on URL
    config = SRWConfig.configURLHash[req.calledAt]

    # Setup for processing

    if (req.query != ""):
        req.queryStructure = CQLParser.parse(req.query)
    else:
        # No Query, Request is seriously Broken
        f = Diagnostic7()
        f.message = 'Request must include a query'
        f.details = 'query'
        raise f
    req.queryStructure.config = config

    req.xQuery = req.queryStructure.toXCQL()
    self.echoedSearchRetrieveRequest = req

    req.parseSortKeys()

    if (req.diagnostics):
        self.diagnostics = req.diagnostics
        return

    # Check if we recognise the record Schema
    schema = req.get('recordSchema')
    # Redirect to full value
    if (config.recordNamespaces.has_key(schema)):
        schema = config.recordNamespaces[schema]
    if (not schema in config.recordNamespaces.values()):
        diag = Diagnostic66()
        diag.details = schema
        raise diag

    recordPacking = req.get('recordPacking')
    if not recordPacking  in ["string", "xml"]:
        diag = Diagnostic71()
        diag.details = req.recordPacking;
        raise diag

    startRecord = req.get('startRecord')
    maximumRecords = req.get('maximumRecords')

    # Is the query a 'present' special case
    nsk = len(req.sortStructure)   # If sorted, we need a temp result set
    rsn =  req.queryStructure.getResultSetId()

    # Otherwise does the client want a resultSet?
    ttl = req.get('resultSetTTL')
    if ttl > config.maxTTL or ttl < 0:
        # TTL is non fatal
        diag = Diagnostic51()
        diag.uri = diag.uri
        diag.details = "TTL Requested (%s) is negative or greater than maximum of %d" % (req.resultSetTTL, config.maxTTL)
        diag.message = diag.details
        self.diagnostics = [diag]
        ttl = 0

    # Query for result set and no connection. Fail now.
    if rsn and not config.conn:
        diag = Diagnostic51()
        diag.details = rsn
        raise diag

    if (nsk or not (config.conn and rsn)):
        req.queryStructure.config = config
        try:
            qo = zoom.Query('CQL-TREE', req.queryStructure)
        except SRWDiagnostic, err:
            raise err

        if config.logLevel > 1:
            # Need convenient short form.
            config.log("Built Query: %s"  % ( pqf.rpn2pqf(qo.query) ))

        # Connect
        if config.conn == None:
            config.zconnect()
def scanProcessQuery(self, req):
    # Process a scan query

    self.terms = []
    config = SRWConfig.configURLHash[req.calledAt]

    if (not req.version):
        diag = Diagnostic7()
        diag.message = "Mandatory 'version' parameter not supplied"
        diag.details = 'version'
        raise diag

    if req.scanClause:
        #convert clause into SearchClause object
        clause = CQLParser.parse(req.scanClause)
        # Stupid schema.
        xsc = []
        xsc.append(clause.index.toXCQL())
        xsc.append(clause.relation.toXCQL())
        xsc.append(clause.term.toXCQL())
        req.xScanClause = "".join(xsc)
    else:
        # Seriously broken request.
        f = Diagnostic7()
        f.message = 'Request must include a query'
        f.details = 'scanClause'
        raise f

    self.echoedScanRequest = req
    if (req.diagnostics):
        self.diagnostics = req.diagnostics
        return

    if (not clause.term.value):
	clause.term.value = 'a'
    clause.config = config
    qo = zoom.Query('CQL-TREE', clause)

    if config.logLevel > 1:
        # Need convenient short form.
        config.log("Built Query: %s"  % ( pqf.rpn2pqf(qo.query) ))    

    if config.conn == None:
        config.zconnect()

    # Set up Z connection for scan
    config.conn.stepSize = 0

    mt = req.get('maximumTerms')
    rp = req.get('responsePosition')
    config.conn.numberOfEntries = mt
    config.conn.responsePosition = rp
    ss = []

    retries = 0
    while retries < 3:
        try:
            ss = config.conn.scan(qo)
            retries = 3
        except zoom.ConnectionError:
            retries +=1
            config.zconnect()
            config.conn.stepSize = 0
            config.conn.numberOfEntries = mt
            config.conn.responsePosition = rp
        except zoom.Bib1Err, bib1:
            if bib1.condition == 9:
                # No term found
                diag = Diagnostic2()
                diag.details = "No Terms Found."
                raise diag
            else:
                diag = Diagnostic2()
                diag.details = str(bib1)
                raise diag
    def handleSearch(self, session, data):
        # Must return a response no matter what
        resp = SearchResponse()
        resp.resultCount = 0
        resp.numberOfRecordsReturned = 0
        resp.nextResultSetPosition = 1
        resp.searchStatus = 1
        resp.resultSetStatus = 1
        resp.presentStatus = PresentStatus.get_num_from_name('failure')

        try:
            queryType = data.query[0]
            query = ["", ""]
            if (queryType in ['type_1', 'type_101']):
                zQuery = data.query[1]
                attrset = zQuery.attributeSet
                query = ['rpn', zQuery.rpn]
            elif (queryType == 'type_0'):
                # A Priori external. We assume CQL
                query = ['cql', data.query[1]]
            elif (queryType == 'type_2'):
                # ISO8777  (CCL)
                rpn = ccl.mk_rpn_query(data.query[1])
                query = ['rpn', rpn]
            elif (queryType == 'type_104'):
                # Look for CQL or SQL
                type104 = data.query[1].direct_reference
                if (type104 == Z3950_QUERY_CQL_ov):
                    query = ['cql', data.query[1].encoding[1]]
                elif (type104 == Z3950_QUERY_SQL_ov):
                    query = ['sql', data.query[1].encoding[1].queryExpression]
                    # XXX Implement direct to postgres
                    raise NotImplementedError
                else:
                    # Undefined query type
                    raise NotImplementedError
            elif (queryType in ['type_102', 'type_100']):
                # 102: Ranked List, not yet /defined/ let alone implemented
                # 100: Z39.58 query (Standard was withdrawn)
                raise NotImplementedError

            rsetname = data.resultSetName
            dbs = data.databaseNames
            resultSets = []
            if query[0] == 'cql':
                q = CQLParser.parse(query[1])
            for dbname in dbs:
                cfg = self.session.configs.get(dbname, None)
                if cfg is not None:
                    db = cfg.parent
                    if query[0] == 'rpn':
                        self.log("Trying to convert: %s" % (repr(query[1])))
                        q = CQLUtils.rpn2cql(query[1], cfg)
                        self.log("--> " + q.toCQL())
                    session.database = db.id
                    q = cqlParser.parse(q.toCQL())
                    resultSets.append(db.search(session, q))
                else:
                    raise ValueError("%s not in %r" %
                                     (dbname, self.session.configs.keys()))
            if len(resultSets) > 1:
                rs = resultSets[0]
                for r in resultSets[1:]:
                    rs.combine(r)
            elif len(resultSets) == 1:
                rs = resultSets[0]
            else:
                # No resultset.
                return self.encode(('searchResponse', resp))

            resp.resultCount = len(rs)
            # Maybe put it into our DB
            if session.resultSets.has_key(rsetname):
                rsid = session.resultSets[rsetname]
                rs.id = rsid
                session.resultSetStore.store_resultSet(session, rs)
            else:
                rsid = session.resultSetStore.create_resultSet(session, rs)
                session.resultSets[rsetname] = rsid
            # only keep 4 at once
            keys = session.resultSetCache.keys()
            if len(keys) > 3:
                # delete one at random
                r = rand.randint(0, 3)
                del session.resultSetCache[keys[r]]
            session.resultSetCache[rsid] = rs

        except Exception, err:
            # XXX add -correct- diagnostic
            resp.numberOfRecordsReturned = 1
            resp.nextResultSetPosition = 0
            resp.resultSetStatus = 3
            d = self.generate_diagnostic(err)
            diag = ('nonSurrogateDiagnostic', d)
            resp.records = diag
Exemple #5
0
     except ccl.QuerySyntaxError, err:
         print "zoom raising", str(err), " for", query
         raise QuerySyntaxError(str(err))
 elif typ == 'S-CCL':  # server-side ccl
     self.typ = typ
     self.query = ('type-2', query)
 elif typ == 'S-CQL':  # server-side cql
     self.typ = typ
     xq = asn1.EXTERNAL()
     xq.direct_reference = oids.Z3950_QUERY_CQL_ov
     xq.encoding = ('single-ASN1-type', query)
     self.query = ('type_104', xq)
 elif typ == 'CQL':  # CQL to RPN transformation
     self.typ = 'RPN'
     try:
         q = CQLParser.parse(query)
         rpnq = z3950.RPNQuery()
         # XXX Allow Attribute Architecture somehow?
         rpnq.attributeSet = oids.Z3950_ATTRS_BIB1_ov
         rpnq.rpn = q.toRPN()
         self.query = ('type_1', rpnq)
     except SRWDiagnostics.SRWDiagnostic, err:
         raise err
     except:
         raise QuerySyntaxError
 elif typ == 'PQF':  # PQF to RPN transformation
     self.typ = 'RPN'
     try:
         self.query = pqf.parse(query)
     except:
         raise QuerySyntaxError
Exemple #6
0
     except ccl.QuerySyntaxError, err:
         print "zoom raising", str(err), " for", query
         raise QuerySyntaxError(str(err))
 elif typ == "S-CCL":  # server-side ccl
     self.typ = typ
     self.query = ("type-2", query)
 elif typ == "S-CQL":  # server-side cql
     self.typ = typ
     xq = asn1.EXTERNAL()
     xq.direct_reference = oids.Z3950_QUERY_CQL_ov
     xq.encoding = ("single-ASN1-type", query)
     self.query = ("type_104", xq)
 elif typ == "CQL":  # CQL to RPN transformation
     self.typ = "RPN"
     try:
         q = CQLParser.parse(query)
         rpnq = z3950.RPNQuery()
         # XXX Allow Attribute Architecture somehow?
         rpnq.attributeSet = oids.Z3950_ATTRS_BIB1_ov
         rpnq.rpn = q.toRPN()
         self.query = ("type_1", rpnq)
     except SRWDiagnostics.SRWDiagnostic, err:
         raise err
     except:
         raise QuerySyntaxError
 elif typ == "PQF":  # PQF to RPN transformation
     self.typ = "RPN"
     try:
         self.query = pqf.parse(query)
     except:
         raise QuerySyntaxError
Exemple #7
0
    def __init__ (self, typ, query):
        """Creates Query object.
Supported query types:  CCL, S-CCL, CQL, S-CQL, PQF, C2, ZSQL, CQL-TREE
"""
        typ = typ.upper()
# XXX maybe replace if ... elif ...  with dict mapping querytype to func
        if typ == 'CCL':
           self.typ = 'RPN'
           try:
               self.query = ccl.mk_rpn_query (query)
           except ccl.QuerySyntaxError as err:
               raise QuerySyntaxError (str(err))
        elif typ == 'S-CCL': # server-side ccl
            self.typ = typ
            self.query =  ('type-2', query)
        elif typ == 'S-CQL': # server-side cql
            self.typ = typ
            xq = asn1.EXTERNAL()
            xq.direct_reference = oids.Z3950_QUERY_CQL_ov
            xq.encoding = ('single-ASN1-type', query)
            self.query = ('type_104', xq)
        elif typ == 'CQL': # CQL to RPN transformation
            self.typ = 'RPN'
            try:
                q = CQLParser.parse(query)
                rpnq = z3950.RPNQuery()
                # XXX Allow Attribute Architecture somehow?
                rpnq.attributeSet = oids.Z3950_ATTRS_BIB1_ov
                rpnq.rpn = q.toRPN()
                self.query = ('type_1', rpnq)
            except SRWDiagnostics.SRWDiagnostic as err:
                raise err
            except:
                raise QuerySyntaxError
        elif typ == 'PQF':  # PQF to RPN transformation
            self.typ = 'RPN'
            try:
                self.query = pqf.parse(query)
            except:
                raise QuerySyntaxError

        elif typ == 'C2': # Cheshire2 Syntax
            self.typ = 'RPN'
            try:
                q = c2.parse(query)
                self.query = q[0]
            except:
                raise QuerySyntaxError
        elif typ == 'ZSQL': # External SQL
            self.typ = typ
            xq = asn1.EXTERNAL()
            xq.direct_reference = oids.Z3950_QUERY_SQL_ov
            q = z3950.SQLQuery()
            q.queryExpression = query
            xq.encoding = ('single-ASN1-type', q)
            self.query = ('type_104', xq)
        elif typ == 'CQL-TREE': # Tree to RPN
            self.typ = 'RPN'
            try:
                rpnq = z3950.RPNQuery()
                # XXX Allow Attribute Architecture
                rpnq.attributeSet = oids.Z3950_ATTRS_BIB1_ov
                rpnq.rpn = query.toRPN()
                self.query = ('type_1', rpnq)
            except SRWDiagnostics.SRWDiagnostic as err:
                raise err
            except:
                raise QuerySyntaxError
        else:
            raise ClientNotImplError ('%s queries not supported' % typ)
Exemple #8
0
    def handleSearch(self, session, data):
        # Must return a response no matter what
        resp = SearchResponse()
        resp.resultCount = 0
        resp.numberOfRecordsReturned = 0
        resp.nextResultSetPosition = 1
        resp.searchStatus = 1
        resp.resultSetStatus = 1
        resp.presentStatus = PresentStatus.get_num_from_name('failure')

        try:
            queryType = data.query[0]
            query = ["", ""]
            if (queryType in ['type_1', 'type_101']):
                zQuery = data.query[1]
                attrset = zQuery.attributeSet
                query = ['rpn', zQuery.rpn]
            elif (queryType == 'type_0'):
                # A Priori external. We assume CQL
                query = ['cql', data.query[1]]
            elif (queryType == 'type_2'):
                # ISO8777  (CCL)
                rpn = ccl.mk_rpn_query(data.query[1])
                query = ['rpn', rpn]           
            elif (queryType == 'type_104'):
                # Look for CQL or SQL
                type104 = data.query[1].direct_reference
                if (type104 == Z3950_QUERY_CQL_ov):
                    query = ['cql', data.query[1].encoding[1]]
                elif (type104 == Z3950_QUERY_SQL_ov):
                    query = ['sql', data.query[1].encoding[1].queryExpression]
                    # XXX Implement direct to postgres
                    raise NotImplementedError
                else:
                    # Undefined query type
                    raise NotImplementedError
            elif (queryType in ['type_102', 'type_100']):
                # 102: Ranked List, not yet /defined/ let alone implemented
                # 100: Z39.58 query (Standard was withdrawn)
                raise NotImplementedError

            rsetname = data.resultSetName
            dbs = data.databaseNames
            resultSets = []
            if query[0] == 'cql':
                q = CQLParser.parse(query[1])
            for dbname in dbs:
                cfg = self.session.configs.get(dbname, None)
                if cfg is not None:
                    db = cfg.parent
                    if query[0] == 'rpn':
                        self.log("Trying to convert: %s" % (repr(query[1])))
                        q = CQLUtils.rpn2cql(query[1], cfg)               
                        self.log("--> " + q.toCQL())
                    session.database = db.id
                    q = cqlParser.parse(q.toCQL())
                    resultSets.append(db.search(session, q))
                else:
                    raise ValueError("%s not in %r" % (dbname, self.session.configs.keys()))
            if len(resultSets) > 1:
                rs = resultSets[0]
                for r in resultSets[1:]:
                    rs.combine(r)
            elif len(resultSets) == 1:
                rs = resultSets[0]
            else:
                # No resultset.
                return self.encode(('searchResponse', resp))

            resp.resultCount = len(rs)
            # Maybe put it into our DB
            if session.resultSets.has_key(rsetname):
                rsid = session.resultSets[rsetname]
                rs.id = rsid
                session.resultSetStore.store_resultSet(session, rs)
            else:
                rsid = session.resultSetStore.create_resultSet(session, rs)
                session.resultSets[rsetname] = rsid
            # only keep 4 at once
            keys = session.resultSetCache.keys()
            if len(keys) > 3:
                # delete one at random
                r = rand.randint(0,3)
                del session.resultSetCache[keys[r]]
            session.resultSetCache[rsid] = rs

        except Exception, err:
            # XXX add -correct- diagnostic
            resp.numberOfRecordsReturned = 1
            resp.nextResultSetPosition = 0
            resp.resultSetStatus = 3           
            d = self.generate_diagnostic(err)
            diag = ('nonSurrogateDiagnostic', d)
            resp.records = diag