def getDatafileFormat(client, case):
    l = case['dfformat'].split(':')
    query = Query(client, "DatafileFormat", conditions={
        "name": "= '%s'" % l[0],
    })
    if len(l) > 1:
        query.addConditions({"version": "= '%s'" % l[1]})
    return (client.assertedSearch(query)[0])
def test_query_limit(client):
    """Add a LIMIT clause to the last example.
    """
    query = Query(client, "Rule", order=['grouping', 'what', 'id'], 
                  conditions={"grouping":"IS NOT NULL"})
    query.setLimit( (0,10) )
    print(str(query))
    res = client.search(query)
    assert len(res) == 10
Exemple #3
0
    def searchUniqueKey(self, key, objindex=None):
        """Search the object that belongs to a unique key.

        This is in a sense the inverse method to
        :meth:`icat.entity.Entity.getUniqueKey`, the key must
        previously have been generated by it.  This method searches
        the Entity object that the key has been generated for from the
        server.

        if objindex is not :const:`None`, it is used as a cache of
        previously retrieved objects.  It must be a dict that maps
        keys to Entity objects.  The object retrieved by this method
        call will be added to this index.

        This method uses the JPQL inspired query syntax introduced
        with ICAT 4.3.0.  It won't work with older ICAT servers.

        :param key: the unique key of the object to search for.
        :type key: :class:`str`
        :param objindex: cache of Entity objects.
        :type objindex: :class:`dict`
        :return: the object corresponding to the key.
        :rtype: :class:`icat.entity.Entity`
        :raise SearchResultError: if the object has not been found.
        :raise ValueError: if the key is not well formed.
        :raise VersionMethodError: if connected to an ICAT server
            older then 4.3.0.
        """

        if self.apiversion < '4.3':
            raise VersionMethodError("searchUniqueKey", self.apiversion)
        if objindex is not None and key in objindex:
            return objindex[key]
        us = key.index('_')
        beanname = key[:us]
        av = parse_attr_val(key[us+1:])
        info = self.getEntityInfo(beanname)
        query = Query(self, beanname)
        for f in info.fields:
            if f.name in av.keys():
                attr = f.name
                if f.relType == "ATTRIBUTE":
                    cond = "= '%s'" % simpleqp_unquote(av[attr])
                    query.addConditions({attr:cond})
                elif f.relType == "ONE":
                    rk = str("%s_%s" % (f.type, av[attr]))
                    ro = self.searchUniqueKey(rk, objindex)
                    query.addConditions({"%s.id" % attr:"= %d" % ro.id})
                else:
                    raise ValueError("malformed '%s': invalid attribute '%s'" 
                                     % (key, attr))
        obj = self.assertedSearch(query)[0]
        if objindex is not None:
            objindex[key] = obj
        return obj
def test_query_limit_placeholder(client):
    """LIMIT clauses are particular useful with placeholders.
    """
    query = Query(client, "Rule", order=['grouping', 'what', 'id'], 
                  conditions={"grouping":"IS NOT NULL"})
    query.setLimit( ("%d","%d") )
    print(str(query))
    print(str(query) % (0,30))
    res = client.search(str(query) % (0,30))
    assert len(res) == 30
    print(str(query) % (30,30))
    res = client.search(str(query) % (30,30))
    assert len(res) == 14
def test_query_aggregate_distinct_attribute(client):
    """Test DISTINCT on an attribute in the search result.

    Support for adding aggregate functions has been added in
    Issue #32.
    """
    require_icat_version("4.7.0", "SELECT DISTINCT in queries")
    query = Query(client, "Datafile", 
                  attribute="datafileFormat.name", 
                  conditions={ "dataset.investigation.id":
                               "= %d" % investigation.id })
    print(str(query))
    res = client.search(query)
    assert sorted(res) == ["NeXus", "NeXus", "other", "other"]
    query.setAggregate("DISTINCT")
    print(str(query))
    res = client.search(query)
    assert sorted(res) == ["NeXus", "other"]
Exemple #6
0
    def searchMatching(self, obj, includes=None):
        """Search the matching object.

        Search the object from the ICAT server that matches the given
        object in the uniqueness constraint.

        >>> dataset = client.new("dataset", investigation=inv, name=dsname)
        >>> dataset = client.searchMatching(dataset)
        >>> dataset.id
        172383L

        :param obj: an entity object having the attrinutes for the
            uniqueness constraint set accordingly.
        :type obj: :class:`icat.entity.Entity`
        :param includes: list of related objects to add to the INCLUDE
            clause of the search query.
            See :meth:`icat.query.Query.addIncludes` for details.
        :type includes: iterable of :class:`str`
        :return: the corresponding object.
        :rtype: :class:`icat.entity.Entity`
        :raise SearchResultError: if the object has not been found.
        :raise ValueError: if the object's class does not have a
            uniqueness constraint or if any attribute needed for the
            constraint is not set.
        """
        if 'id' in obj.Constraint:
            raise ValueError("%s does not have a uniqueness constraint.")
        query = Query(self, obj.BeanName, includes=includes)
        for a in obj.Constraint:
            v = getattr(obj, a)
            if v is None:
                raise ValueError("%s is not set" % a)
            if a in obj.InstAttr:
                query.addConditions({a: "= '%s'" % v})
            elif a in obj.InstRel:
                query.addConditions({"%s.id" % a: "= %d" % v.id})
            else:
                raise InternalError("Invalid constraint '%s' in %s."
                                    % (a, obj.BeanName))
        return self.assertedSearch(query)[0]
def test_query_aggregate_distinct_related_obj(client):
    """Test DISTINCT on a related object in the search result.

    Support for adding aggregate functions has been added in
    Issue #32.
    """
    require_icat_version("4.7.0", "SELECT DISTINCT in queries")
    query = Query(client, "Datafile", 
                  attribute="datafileFormat", 
                  conditions={ "dataset.investigation.id":
                               "= %d" % investigation.id })
    print(str(query))
    res = client.search(query)
    assert len(res) == 4
    for n in res:
        assert isinstance(n, icat.entity.Entity)
    query.setAggregate("DISTINCT")
    print(str(query))
    res = client.search(query)
    assert len(res) == 2
    for n in res:
        assert isinstance(n, icat.entity.Entity)
def test_query_condition_list(client):
    """We may also add a list of conditions on a single attribute.
    """
    condition = {"datafileCreateTime": [">= '2012-01-01'", "< '2013-01-01'"]}
    query = Query(client, "Datafile", conditions=condition)
    print(str(query))
    qstr = str(query)
    res = client.search(query)
    assert len(res) == 3

    # The last example also works by adding the conditions separately.
    query = Query(client, "Datafile")
    query.addConditions({"datafileCreateTime": ">= '2012-01-01'"})
    query.addConditions({"datafileCreateTime": "< '2013-01-01'"})
    print(str(query))
    assert str(query) == qstr
    res = client.search(query)
    assert len(res) == 3
Exemple #9
0
else:
    f = open(conf.datafile, 'r')
data = yaml.load(f)
f.close()


# ------------------------------------------------------------
# Query examples
# ------------------------------------------------------------

# To simplify things, we take search values from the example data job.
inp = data['jobs']['job1']['input']

print("\nA simple query for an investigation by name.")
name = inp['datasets'][0]['investigation']
q = Query(client, "Investigation", conditions={"name":"= '%s'" % name})
print(str(q))
res = client.search(q)
print("%d result(s)" % len(res))
# keep the investigation id for a later example
if len(res) > 0:
    invid = res[0].id
else:
    # No result, use a bogus id instead
    invid = 4711

print("\nUse investigation id: %d" % invid)

print("\nQuery a datafile by its name, dataset name, and investigation name:")
df = inp['datafiles'][0]
conditions = {