def query_struct(self): self.fetch_token() if (self.currentToken == '@attr'): attrs = [] while self.currentToken == '@attr': attrs.append(self.attr_spec()) self.fetch_token() t = self.term() # Now we have attrs + term clause = z3950.AttributesPlusTerm() clause.attributes = [make_attr(*e) for e in attrs] clause.term = t return ('op', ('attrTerm', clause)) elif (self.is_boolean()): # @operator query query return self.complex() elif (self.currentToken == '@set'): return self.result_set() elif (self.currentToken == "{"): # Parens s = self.query_struct() if (self.nextToken <> "}"): raise(ValueError) else: self.fetch_token() return s else: t = self.term() return self.defaultClause(t)
def query_struct(self): self.fetch_token() if (self.currentToken == '@attr'): attrs = [] while self.currentToken == '@attr': attrs.append(self.attr_spec()) self.fetch_token() t = self.term() # Now we have attrs + term clause = z3950.AttributesPlusTerm() clause.attributes = [make_attr(*e) for e in attrs] clause.term = t return ('op', ('attrTerm', clause)) elif (self.is_boolean()): # @operator query query return self.complex() elif (self.currentToken == '@set'): return self.result_set() elif (self.currentToken == "{"): # Parens s = self.query_struct() if (self.nextToken <> "}"): raise (ValueError) else: self.fetch_token() return s else: t = self.term() return self.defaultClause(t)
def defaultClause(self, t): # Assign a default clause: anywhere = clause = z3950.AttributesPlusTerm() attrs = [(oids.Z3950_ATTRS_BIB1, 1, 1016), (oids.Z3950_ATTRS_BIB1, 2, 3)] clause.attributes = [make_attr(*e) for e in attrs] clause.term = t return ('op', ('attrTerm', clause))
def toRPN(self, top=None): if not top: top = self if (self.relation.value in ['any', 'all']): # Need to split this into and/or tree if (self.relation.value == 'any'): bool = " or " else: bool = " and " words = self.term.value.split() self.relation.value = '=' # Add 'word' relationModifier self.relation.modifiers.append(CModifierClause('cql.word')) # Create CQL, parse it, walk new tree idxrel = "%s %s" % (self.index.toCQL(), self.relation.toCQL()) text = [] for w in words: text.append('%s "%s"' % (idxrel, w)) cql = bool.join(text) tree = parse(cql) tree.prefixes = self.prefixes tree.parent = self.parent tree.config = self.config return tree.toRPN(top) else: # attributes, term # AttributeElement: attributeType, attributeValue # attributeValue ('numeric', n) or ('complex', struct) if (self.index.value == 'resultsetid'): return ('op', ('resultSet', self.term.value)) clause = z3950.AttributesPlusTerm() attrs = self.index.toRPN(top) if (self.term.value.isdigit()): self.relation.modifiers.append(CModifierClause('cql.number')) relattrs = self.relation.toRPN(top) attrs.update(relattrs) butes = [] for e in attrs.iteritems(): butes.append((e[0][0], e[0][1], e[1])) clause.attributes = [make_attr(*e) for e in butes] clause.term = self.term.toRPN(top) return ('op', ('attrTerm', clause))
def toRPN(self, top=None): if not top: top = self if (self.relation.value in ['any', 'all']): # Need to split this into and/or tree if (self.relation.value == 'any'): bool = " or " else: bool = " and " words = self.term.value.split() self.relation.value = '=' # Add 'word' relationModifier self.relation.modifiers.append(CModifierClause('cql.word')) # Create CQL, parse it, walk new tree idxrel = "%s %s" % (self.index.toCQL(), self.relation.toCQL()) text = [] for w in words: text.append('%s "%s"' % (idxrel, w)) cql = bool.join(text) tree = parse(cql) tree.prefixes = self.prefixes tree.parent = self.parent tree.config = self.config return tree.toRPN(top) else: # attributes, term # AttributeElement: attributeType, attributeValue # attributeValue ('numeric', n) or ('complex', struct) if (self.index.value == 'resultsetid'): return ('op', ('resultSet', self.term.value)) clause = z3950.AttributesPlusTerm() attrs = self.index.toRPN(top) if (self.term.value.isdigit()): self.relation.modifiers.append(CModifierClause('cql.number')) relattrs = self.relation.toRPN(top) attrs.update(relattrs) butes =[] for e in attrs.iteritems(): butes.append((e[0][0], e[0][1], e[1])) clause.attributes = [make_attr(*e) for e in butes] clause.term = self.term.toRPN(top) return ('op', ('attrTerm', clause))
def clause(self): if (self.is_boolean(self.nextToken) or not self.nextToken or self.nextToken.lower() == 'resultsetid' or self.nextToken == ")"): # Must be a resultset tok = self.currentToken self.fetch_token() return ('op', ('resultSet', tok)) elif (self.currentToken == '['): # List of attributes attrs = [] oidHash = oids.oids['Z3950']['ATTRS'] while (1): self.fetch_token() if (self.currentToken == ']'): break if (self.currentToken in oidHash): attrSet = oidHash[self.currentToken]['ov'] self.fetch_token() elif (self.currentToken[:8] == '1.2.840.'): attrSet = asn1.OidVal( list(map(int, self.currentToken.split('.')))) self.fetch_token() else: attrSet = None if (self.currentToken[-1] == ','): tok = self.currentToken[:-1] else: tok = self.currentToken if (tok.isdigit()): # 1 = foo atype = int(tok) self.fetch_token() if (self.currentToken == '='): # = foo self.fetch_token() if (self.currentToken[0] == '='): # =foo tok = self.currentToken[1:] else: tok = self.currentToken if (tok[-1] == ','): tok = tok[:-1] if (tok.isdigit()): val = int(tok) else: val = tok if (val[0] == "'" and val[-1] == "'"): val = val[1:-1] elif (tok[-1] == '='): #1= foo tok = tok[:-1] if (tok.isdigit()): atype = int(tok) self.fetch_token() if (self.currentToken[-1] == ","): tok = self.currentToken[:-1] else: tok = self.currentToken if (tok.isdigit()): val = int(self.currentToken) else: val = tok if (val[0] == "'" and val[-1] == "'"): val = val[1:-1] elif (tok.find('=') > -1): # 1=foo (atype, val) = self.currentToken.split('=') atype = int(atype) if (val[-1] == ","): val = val[:-1] if (val.isdigit()): val = int(val) elif (val[0] == "'" and val[-1] == "'"): val = val[1:-1] else: # ??? raise ValueError attrs.append([attrSet, atype, val]) else: # Check for named index if (self.currentToken.lower() in zconfig.bib1): attrs = [[ oids.Z3950_ATTRS_BIB1_ov, 1, zconfig.bib1[self.currentToken.lower()] ]] else: # Just pass through the name attrs = [[oids.Z3950_ATTRS_BIB1_ov, 1, self.currentToken]] self.fetch_token() # Check for relation tok = self.currentToken.upper() if (tok in relations): val = relations[tok] found = 0 for a in attrs: if (a[0] in [oids.Z3950_ATTRS_BIB1, None] and a[1] == 2): found = 1 a[2] = val break if (not found): attrs.append([None, 2, val]) self.fetch_token() elif (tok in geoRelations): val = geoRelations[tok] found = 0 for a in attrs: if (a[0] in [oids.Z3950_ATTRS_BIB1, oids.Z3950_ATTRS_GEO, None] and a[1] == 2): found = 1 a[2] = val break if (not found): attrs.append([oids.Z3950_ATTRS_GEO, 2, val]) self.fetch_token() if (self.currentToken.find(' ')): # Already quoted term = self.currentToken else: # Accumulate term = [] while (self.currentToken and not self.is_boolean(self.currentToken) and self.currentToken.lower() != 'resultsetid'): term.append(self.currenToken) term = ' '.join(term) self.fetch_token() # Phew. Now build AttributesPlusTerm clause = z3950.AttributesPlusTerm() clause.attributes = [make_attr(*e) for e in attrs] clause.term = ('general', term) return ('op', ('attrTerm', clause))
def clause(self): if (self.is_boolean(self.nextToken) or not self.nextToken or self.nextToken.lower() == 'resultsetid' or self.nextToken == ")"): # Must be a resultset tok = self.currentToken self.fetch_token() return ('op', ('resultSet', tok)) elif (self.currentToken == '['): # List of attributes attrs = [] oidHash = oids.oids['Z3950']['ATTRS'] while (1): self.fetch_token() if (self.currentToken == ']'): break if (oidHash.has_key(self.currentToken)): attrSet = oidHash[self.currentToken]['ov'] self.fetch_token() elif (self.currentToken[:8] == '1.2.840.'): attrSet = asn1.OidVal(map(int, self.currentToken.split('.'))) self.fetch_token() else: attrSet = None if (self.currentToken[-1] == ','): tok = self.currentToken[:-1] else: tok = self.currentToken if (tok.isdigit()): # 1 = foo atype = int(tok) self.fetch_token() if (self.currentToken == '='): # = foo self.fetch_token() if (self.currentToken[0] == '='): # =foo tok = self.currentToken[1:] else: tok = self.currentToken if (tok[-1] == ','): tok = tok[:-1] if (tok.isdigit()): val = int(tok) else: val = tok if (val[0] == "'" and val[-1] == "'"): val = val[1:-1] elif (tok[-1] == '='): #1= foo tok = tok[:-1] if (tok.isdigit()): atype = int(tok) self.fetch_token() if (self.currentToken[-1] == ","): tok = self.currentToken[:-1] else: tok = self.currentToken if (tok.isdigit()): val = int(self.currentToken) else: val = tok if (val[0] == "'" and val[-1] == "'"): val = val[1:-1] elif (tok.find('=') > -1): # 1=foo (atype, val) = self.currentToken.split('=') atype = int(atype) if (val[-1] == ","): val = val[:-1] if (val.isdigit()): val = int(val) elif (val[0] == "'" and val[-1] == "'"): val = val[1:-1] else: # ??? raise ValueError attrs.append([attrSet, atype, val]) else: # Check for named index if (zconfig.BIB1.has_key(self.currentToken.lower())): attrs = [[oids.Z3950_ATTRS_BIB1_ov, 1, zconfig.BIB1[self.currentToken.lower()]]] else: # Just pass through the name attrs = [[oids.Z3950_ATTRS_BIB1_ov, 1, self.currentToken]] self.fetch_token() # Check for relation tok = self.currentToken.upper() if (relations.has_key(tok)): val = relations[tok] found = 0 for a in attrs: if (a[0] in [oids.Z3950_ATTRS_BIB1, None] and a[1] == 2): found =1 a[2] = val break if (not found): attrs.append([None, 2, val]) self.fetch_token() elif (geoRelations.has_key(tok)): val = geoRelations[tok] found = 0 for a in attrs: if (a[0] in [oids.Z3950_ATTRS_BIB1, oids.Z3950_ATTRS_GEO, None] and a[1] == 2): found = 1 a[2] = val break if (not found): attrs.append([oids.Z3950_ATTRS_GEO, 2, val]) self.fetch_token() if (self.currentToken.find(' ')): # Already quoted term = self.currentToken else: # Accumulate term = [] while (self.currentToken and not self.is_boolean(self.currentToken) and self.currentToken.lower() != 'resultsetid'): term.append(self.currenToken) term = ' '.join(term) self.fetch_token() # Phew. Now build AttributesPlusTerm clause = z3950.AttributesPlusTerm() clause.attributes = [make_attr(*e) for e in attrs] clause.term = ('general', term) return ('op', ('attrTerm', clause))