Example #1
0
File: pqf.py Project: gr/PyZ3950
    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)
Example #2
0
    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)
Example #3
0
 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))
Example #4
0
    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))
Example #6
0
    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))
Example #7
0
    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))