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
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
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
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)
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