Пример #1
0
def datetime(e):
    if not isinstance(e, Literal):
        raise SPARQLError("Non-literal passed as datetime: %r" % e)
    if not e.datatype == XSD.dateTime:
        raise SPARQLError(
            "Literal with wrong datatype passed as datetime: %r" % e)
    return e.toPython()
Пример #2
0
def date(e) -> py_datetime.date:
    if not isinstance(e, Literal):
        raise SPARQLError("Non-literal passed as date: %r" % e)
    if e.datatype not in (XSD.date, XSD.dateTime):
        raise SPARQLError("Literal with wrong datatype passed as date: %r" % e)
    result = e.toPython()
    if isinstance(result, py_datetime.datetime):
        return result.date()
    return result
Пример #3
0
def string(s):
    """
    Make sure the passed thing is a string literal
    i.e. plain literal, xsd:string literal or lang-tagged literal
    """
    if not isinstance(s, Literal):
        raise SPARQLError("Non-literal passes as string: %r" % s)
    if s.datatype and s.datatype != XSD.string:
        raise SPARQLError("Non-string datatype-literal passes as string: %r" % s)
    return s
Пример #4
0
def Builtin_TIMEZONE(e, ctx):
    """
    http://www.w3.org/TR/sparql11-query/#func-timezone

    :returns: the timezone part of arg as an xsd:dayTimeDuration.
    :raises: an error if there is no timezone.
    """
    dt = datetime(e.arg)
    if not dt.tzinfo:
        raise SPARQLError("datatime has no timezone: %r" % dt)

    delta = dt.tzinfo.utcoffset(ctx.now)

    d = delta.days
    s = delta.seconds
    neg = ""

    if d < 0:
        s = -24 * 60 * 60 * d - s
        d = 0
        neg = "-"

    h = s / (60 * 60)
    m = (s - h * 60 * 60) / 60
    s = s - h * 60 * 60 - m * 60

    tzdelta = "%sP%sT%s%s%s" % (
        neg,
        "%dD" % d if d else "",
        "%dH" % h if h else "",
        "%dM" % m if m else "",
        "%dS" % s if not d and not h and not m else "",
    )

    return Literal(tzdelta, datatype=XSD.dayTimeDuration)
Пример #5
0
def MultiplicativeExpression(e, ctx):

    expr = e.expr
    other = e.other

    # because of the way the mul-expr production handled operator precedence
    # we sometimes have nothing to do
    if other is None:
        return expr
    try:
        res = Decimal(numeric(expr))
        for op, f in zip(e.op, other):
            f = numeric(f)

            if type(f) == float:
                res = float(res)

            if op == "*":
                res *= f
            else:
                res /= f
    except (InvalidOperation, ZeroDivisionError):
        raise SPARQLError("divide by 0")

    return Literal(res)
Пример #6
0
def Builtin_COALESCE(expr, ctx):
    """
    http://www.w3.org/TR/sparql11-query/#func-coalesce
    """
    for x in expr.get("arg", variables=True):
        if x is not None and not isinstance(x, (SPARQLError, Variable)):
            return x
    raise SPARQLError("COALESCE got no arguments that did not evaluate to an error")
Пример #7
0
def Builtin_DATATYPE(e, ctx):
    l = e.arg
    if not isinstance(l, Literal):
        raise SPARQLError('Can only get datatype of literal: %s' % l)
    if l.language:
        return RDF_langString
    if not l.datatype and not l.language:
        return XSD.string
    return l.datatype
Пример #8
0
def Builtin_DATATYPE(e, ctx):
    l_ = e.arg
    if not isinstance(l_, Literal):
        raise SPARQLError("Can only get datatype of literal: %r" % l_)
    if l_.language:
        return RDF_langString
    if not l_.datatype and not l_.language:
        return XSD.string
    return l_.datatype
Пример #9
0
def Function(e, ctx):
    """
    Custom functions and casts
    """
    pair = _CUSTOM_FUNCTIONS.get(e.iri)
    if pair is None:
        # no such function is registered
        raise SPARQLError("Unknown function %r" % e.iri)
    func, raw = pair
    if raw:
        # function expects expression and context
        return func(e, ctx)
    else:
        # function expects the argument list
        try:
            return func(*e.expr)
        except TypeError as ex:
            # wrong argument number
            raise SPARQLError(*ex.args)
Пример #10
0
 def execute_from_sparql(self, e, ctx):
     if not e.expr:
         raise SPARQLError("Nothing given to SPARQLFunction.")
     params = self.get_params_in_order()
     num_params = len(params)
     if len(e.expr) > num_params:
         raise SPARQLError("Too many parameters passed to SPARQLFunction.")
     elif len(e.expr) < num_params:
         raise SPARQLError("Too few parameters passed to SPARQLFunction.")
     new_binds = ctx.ctx.initBindings.copy()
     new_binds.update(ctx.ctx.bindings)
     g = ctx.ctx.graph
     for i, var in enumerate(e.expr):
         var_val = ctx[var]
         bind_name = params[i].localname
         new_binds[bind_name] = var_val
     if self.ask:
         return self.execute_ask(g, new_binds)
     else:
         return self.execute_select(g, new_binds)
Пример #11
0
def Builtin_STRLANG(expr, ctx):
    """
    http://www.w3.org/TR/sparql11-query/#func-strlang
    """

    s = string(expr.arg1)
    if s.language or s.datatype:
        raise SPARQLError("STRLANG expects a simple literal")

    # TODO: normalisation of lang tag to lower-case
    # should probably happen in literal __init__
    return Literal(str(s), lang=str(expr.arg2).lower())
Пример #12
0
def Builtin_IRI(expr, ctx):
    """
    http://www.w3.org/TR/sparql11-query/#func-iri
    """

    a = expr.arg

    if isinstance(a, URIRef):
        return a
    if isinstance(a, Literal):
        return ctx.prologue.absolutize(URIRef(a))

    raise SPARQLError("IRI function only accepts URIRefs or Literals/Strings!")
Пример #13
0
def Builtin_BNODE(expr, ctx):
    """
    http://www.w3.org/TR/sparql11-query/#func-bnode
    """

    a = expr.arg

    if a is None:
        return BNode()

    if isinstance(a, Literal):
        return ctx.bnodes[a]  # defaultdict does the right thing

    raise SPARQLError("BNode function only accepts no argument or literal/string")
Пример #14
0
 def execute_from_sparql(self, e, ctx):
     if not e.expr:
         raise SPARQLError("Nothing given to SPARQLFunction.")
     params = self.get_params_in_order()
     num_params = len(params)
     if len(e.expr) > num_params:
         raise SPARQLError("Too many parameters passed to SPARQLFunction.")
     elif len(e.expr) < num_params:
         raise SPARQLError("Too few parameters passed to SPARQLFunction.")
     args_map = {str(var): val for var, val in ctx.ctx.initBindings.items()}
     args_map.update(
         {str(var): val
          for var, val in ctx.ctx.bindings.items()})
     g = ctx.ctx.graph
     for i, var in enumerate(e.expr):
         var_val = ctx[var]
         param_name = params[i].localname
         args_map[param_name] = var_val
     results = self.js_exe.execute(g,
                                   args_map,
                                   mode="function",
                                   return_type=self.rtype)
     res = results['_result']
     return res
Пример #15
0
def calculateFinalDateTime(obj1, dt1, obj2, dt2, operation):
    """
        Calculates the final dateTime/date/time resultant after addition/
        subtraction of duration/dayTimeDuration/yearMonthDuration
    """

    # checking compatibility of datatypes (duration types and date/time/dateTime)
    if (isCompatibleDateTimeDatatype(obj1, dt1, obj2, dt2)):
        # proceed
        if (operation == "-"):
            ans = obj1 - obj2
            return Literal(ans, datatype=dt1)
        else:
            ans = obj1 + obj2
            return Literal(ans, datatype=dt1)

    else:
        raise SPARQLError('Incompatible Data types to DateTime Operations')
Пример #16
0
def _compatibleStrings(a, b):
    string(a)
    string(b)

    if b.language and a.language != b.language:
        raise SPARQLError("incompatible arguments to str functions")
Пример #17
0
def literal(s):
    if not isinstance(s, Literal):
        raise SPARQLError("Non-literal passed as string: %r" % s)
    return s
Пример #18
0
def RelationalExpression(e, ctx):

    expr = e.expr
    other = e.other
    op = e.op

    # because of the way the add-expr production handled operator precedence
    # we sometimes have nothing to do
    if other is None:
        return expr

    ops = dict([
        (">", lambda x, y: x.__gt__(y)),
        ("<", lambda x, y: x.__lt__(y)),
        ("=", lambda x, y: x.eq(y)),
        ("!=", lambda x, y: x.neq(y)),
        (">=", lambda x, y: x.__ge__(y)),
        ("<=", lambda x, y: x.__le__(y)),
        ("IN", pyop.contains),
        ("NOT IN", lambda x, y: not pyop.contains(x, y)),
    ])

    if op in ("IN", "NOT IN"):

        res = op == "NOT IN"

        error = False

        if other == RDF.nil:
            other = []

        for x in other:
            try:
                if x == expr:
                    return Literal(True ^ res)
            except SPARQLError as e:
                error = e
        if not error:
            return Literal(False ^ res)
        else:
            raise error

    if op not in ("=", "!=", "IN", "NOT IN"):
        if not isinstance(expr, Literal):
            raise SPARQLError(
                "Compare other than =, != of non-literals is an error: %r" %
                expr)
        if not isinstance(other, Literal):
            raise SPARQLError(
                "Compare other than =, != of non-literals is an error: %r" %
                other)
    else:
        if not isinstance(expr, Node):
            raise SPARQLError("I cannot compare this non-node: %r" % expr)
        if not isinstance(other, Node):
            raise SPARQLError("I cannot compare this non-node: %r" % other)

    if isinstance(expr, Literal) and isinstance(other, Literal):

        if (expr.datatype is not None and expr.datatype not in XSD_DTs
                and other.datatype is not None
                and other.datatype not in XSD_DTs):
            # in SPARQL for non-XSD DT Literals we can only do =,!=
            if op not in ("=", "!="):
                raise SPARQLError(
                    "Can only do =,!= comparisons of non-XSD Literals")

    try:
        r = ops[op](expr, other)
        if r == NotImplemented:
            raise SPARQLError("Error when comparing")
    except TypeError as te:
        raise SPARQLError(*te.args)
    return Literal(r)
Пример #19
0
def AdditiveExpression(e, ctx):

    expr = e.expr
    other = e.other

    # because of the way the add-expr production handled operator precedence
    # we sometimes have nothing to do
    if other is None:
        return expr

    # handling arithmetic(addition/subtraction) of dateTime, date, time
    # and duration datatypes (if any)
    if hasattr(expr, 'datatype') and (expr.datatype in XSD_DateTime_DTs
                                      or expr.datatype in XSD_Duration_DTs):

        res = dateTimeObjects(expr)
        dt = expr.datatype

        for op, term in zip(e.op, other):

            # check if operation is datetime,date,time operation over
            # another datetime,date,time datatype
            if dt in XSD_DateTime_DTs and dt == term.datatype and op == '-':
                # checking if there are more than one datetime operands -
                # in that case it doesn't make sense for example
                # ( dateTime1 - dateTime2 - dateTime3 ) is an invalid operation
                if len(other) > 1:
                    error_message = "Can't evaluate multiple %r arguments"
                    raise SPARQLError(error_message, dt.datatype)
                else:
                    n = dateTimeObjects(term)
                    res = calculateDuration(res, n)
                    return res

            # datetime,date,time +/- duration,dayTimeDuration,yearMonthDuration
            elif (dt in XSD_DateTime_DTs
                  and term.datatype in XSD_Duration_DTs):
                n = dateTimeObjects(term)
                res = calculateFinalDateTime(res, dt, n, term.datatype, op)
                return res

            # duration,dayTimeDuration,yearMonthDuration + datetime,date,time
            elif dt in XSD_Duration_DTs and term.datatype in XSD_DateTime_DTs:
                if op == "+":
                    n = dateTimeObjects(term)
                    res = calculateFinalDateTime(res, dt, n, term.datatype, op)
                    return res

            # rest are invalid types
            else:
                raise SPARQLError('Invalid DateTime Operations')

    # handling arithmetic(addition/subtraction) of numeric datatypes (if any)
    else:
        res = numeric(expr)

        dt = expr.datatype

        for op, term in zip(e.op, other):
            n = numeric(term)
            if isinstance(n, Decimal) and isinstance(res, float):
                n = float(n)
            if isinstance(n, float) and isinstance(res, Decimal):
                res = float(res)

            dt = type_promotion(dt, term.datatype)

            if op == "+":
                res += n
            else:
                res -= n

        return Literal(res, datatype=dt)
Пример #20
0
def default_cast(e, ctx):
    if not e.expr:
        raise SPARQLError("Nothing given to cast.")
    if len(e.expr) > 1:
        raise SPARQLError("Cannot cast more than one thing!")

    x = e.expr[0]

    if e.iri == XSD.string:

        if isinstance(x, (URIRef, Literal)):
            return Literal(x, datatype=XSD.string)
        else:
            raise SPARQLError("Cannot cast term %r of type %r" % (x, type(x)))

    if not isinstance(x, Literal):
        raise SPARQLError("Can only cast Literals to non-string data-types")

    if x.datatype and not x.datatype in XSD_DTs:
        raise SPARQLError("Cannot cast literal with unknown datatype: %r" %
                          x.datatype)

    if e.iri == XSD.dateTime:
        if x.datatype and x.datatype not in (XSD.dateTime, XSD.string):
            raise SPARQLError("Cannot cast %r to XSD:dateTime" % x.datatype)
        try:
            return Literal(isodate.parse_datetime(x), datatype=e.iri)
        except:
            raise SPARQLError("Cannot interpret '%r' as datetime" % x)

    if x.datatype == XSD.dateTime:
        raise SPARQLError("Cannot cast XSD.dateTime to %r" % e.iri)

    if e.iri in (XSD.float, XSD.double):
        try:
            return Literal(float(x), datatype=e.iri)
        except:
            raise SPARQLError("Cannot interpret '%r' as float" % x)

    elif e.iri == XSD.decimal:
        if "e" in x or "E" in x:  # SPARQL/XSD does not allow exponents in decimals
            raise SPARQLError("Cannot interpret '%r' as decimal" % x)
        try:
            return Literal(Decimal(x), datatype=e.iri)
        except:
            raise SPARQLError("Cannot interpret '%r' as decimal" % x)

    elif e.iri == XSD.integer:
        try:
            return Literal(int(x), datatype=XSD.integer)
        except:
            raise SPARQLError("Cannot interpret '%r' as int" % x)

    elif e.iri == XSD.boolean:
        # # I would argue that any number is True...
        # try:
        #     return Literal(bool(int(x)), datatype=XSD.boolean)
        # except:
        if x.lower() in ("1", "true"):
            return Literal(True)
        if x.lower() in ("0", "false"):
            return Literal(False)
        raise SPARQLError("Cannot interpret '%r' as bool" % x)
Пример #21
0
        for x in other:
            try:
                if x == expr:
                    return Literal(True ^ res)
            except SPARQLError, e:
                error = e
        if not error:
            return Literal(False ^ res)
        else:
            raise error

    if not op in ('=', '!=', 'IN', 'NOT IN'):
        if not isinstance(expr, Literal):
            raise SPARQLError(
                "Compare other than =, != of non-literals is an error: %s" %
                expr)
        if not isinstance(other, Literal):
            raise SPARQLError(
                "Compare other than =, != of non-literals is an error: %s" %
                other)
    else:
        if not isinstance(expr, Node):
            raise SPARQLError('I cannot compare this non-node: %s' % expr)
        if not isinstance(other, Node):
            raise SPARQLError('I cannot compare this non-node: %s' % other)

    if isinstance(expr, Literal) and isinstance(other, Literal):

        if expr.datatype != None and expr.datatype not in XSD_DTs and other.datatype != None and other.datatype not in XSD_DTs:
            # in SPARQL for non-XSD DT Literals we can only do =,!=