예제 #1
0
    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))
예제 #2
0
    def handleScan(self, session, data):
        if (hasattr(data, 'stepSize')):
            step = data.stepSize
        else:
            step = 0
        resp = ScanResponse()
        resp.stepSize = step
        resp.scanStatus = 1
        resp.numberOfEntriesReturned = 0
        resp.positionOfTerm = 0

        try:
            dbs = data.databaseNames
            if len(dbs) != 1:
                # Can only scan one db at once? (XXX)
                raise ValueError
            nt = data.numberOfTermsRequested
            rp = data.preferredPositionInResponse
            if (rp < 0 or rp > (nt + 1)):
                # Busted numbers (XXX)
                raise ValueError
            dbname = dbs[0]
            cfg = self.session.configs.get(dbname, None)
            db = cfg.parent
            session.database = db.id
            where = data.termListAndStartPoint
            # Make it look like part of an RPN query...
            w = ('op', ('attrTerm', where))
            clause = CQLUtils.rpn2cql(w, cfg)
            if not clause.term.value:
                clause.term.value = 'a'
            nstms = nt * (step + 1)
            terms = []
            clause = cqlParser.parse(clause.toCQL())
            if (rp == 1):
                data = db.scan(session, clause, nstms, direction=">=")
            elif (rp == 0):
                data = db.scan(session, clause, nstms, direction=">")
            elif (rp == mt):
                data = db.scan(session, clause, nstms, direction="<=")
                data.reverse()
            elif (rp == mt + 1):
                data = db.scan(session, clause, nstms, direction="<")
                data.reverse()
            else:
                # Need to go up and down
                data1 = db.scan(session, clause, nt - rp + 1, direction=">=")
                data = db.scan(session, clause, rp, direction="<=")
                if data1[0][0] == data[0][0]:
                    data = data[1:]
                data.reverse()
                data.extend(data1)

            for d in data[::step + 1]:
                t = TermInfo()
                t.term = ('general', d[0])
                t.globalOccurrences = d[1][1]
                terms.append(('termInfo', t))
            resp.positionOfTerm = rp
            resp.numberOfEntriesReturned = len(terms)
            resp.scanStatus = 0
            l = ListEntries()
            l.entries = terms
            resp.entries = l
        except Exception, err:
            l = ListEntries()
            d = self.generate_diagnostic(err)
            d.condition = 123
            diag = [('defaultFormat', d)]
            l.nonsurrogateDiagnostics = diag
            resp.entries = l
            resp.numberOfEntriesReturned = 0
            resp.scanStatus = 6
예제 #3
0
    def handleScan(self, session, data):
        if (hasattr(data, 'stepSize')):
            step = data.stepSize
        else:
            step = 0
        resp = ScanResponse()
        resp.stepSize = step
        resp.scanStatus = 1
        resp.numberOfEntriesReturned = 0
        resp.positionOfTerm = 0

        try:
            dbs = data.databaseNames
            if len(dbs) != 1:
                # Can only scan one db at once? (XXX)
                raise ValueError
            nt = data.numberOfTermsRequested
            rp = data.preferredPositionInResponse
            if (rp < 0 or rp > (nt+1)):
                # Busted numbers (XXX)
                raise ValueError
            dbname = dbs[0]
            cfg = self.session.configs.get(dbname, None)
            db = cfg.parent
            session.database = db.id
            where = data.termListAndStartPoint
            # Make it look like part of an RPN query...
            w = ('op', ('attrTerm', where))
            clause = CQLUtils.rpn2cql(w, cfg)                     
            if not clause.term.value:
                clause.term.value = 'a'
            nstms = nt * (step + 1)
            terms = []
            clause = cqlParser.parse(clause.toCQL())
            if (rp == 1):
                data = db.scan(session, clause, nstms, direction=">=")
            elif (rp == 0):
                data = db.scan(session, clause, nstms, direction=">")
            elif (rp == mt):
                data = db.scan(session, clause, nstms, direction="<=")
                data.reverse()
            elif (rp == mt+1):
                data = db.scan(session, clause, nstms, direction="<")
                data.reverse()
            else:
                # Need to go up and down
                data1 = db.scan(session, clause, nt-rp+1, direction=">=")
                data = db.scan(session, clause, rp, direction="<=")
                if data1[0][0] == data[0][0]:
                    data = data[1:]
                data.reverse()
                data.extend(data1)
            
            for d in data[::step+1]:
                t = TermInfo()
                t.term = ('general', d[0])
                t.globalOccurrences = d[1][1]
                terms.append(('termInfo', t))
            resp.positionOfTerm = rp
            resp.numberOfEntriesReturned = len(terms)
            resp.scanStatus = 0
            l = ListEntries()
            l.entries = terms
            resp.entries = l
        except Exception, err:
            l = ListEntries()
            d = self.generate_diagnostic(err)
            d.condition = 123
            diag = [('defaultFormat', d)]
            l.nonsurrogateDiagnostics = diag
            resp.entries = l
            resp.numberOfEntriesReturned = 0
            resp.scanStatus = 6
예제 #4
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
예제 #5
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