Ejemplo n.º 1
0
 def test_get_namespace(self):
     RDFS, DCTERMS = get(Namespace, 'rdfs'), get(Namespace, 'dcterms')
     self.assertEqual(u'rdfs', RDFS.code)
     # self.assertEqual(get(URI, RDFS_URI_STR), rdfs.resource)
     # self.assertEqual(get(URI, DCTERMS_URI_STR), dcterms.resource)
     self.assertEqual('rdfs', RDFS.code)
     self.assertEqual('dcterms', DCTERMS.code)
Ejemplo n.º 2
0
 def test_statement(self):
     DESCRIPTION = u'''Description may include but is not limited to: an abstract,
     a table of contents, a graphical representation, or a free-text account of the resource.
     '''
     p = get(Namespace, 'dc')['description']
     s = create(Statement, p.resource, p, object={'value': DESCRIPTION, 'language': 'en-US'})
     t = get(Statement, p, p)
     self.assertEqual(p.name, 'description')
     self.assertEqual(s, t)
     self.assertEqual(s.subject, p.resource)
     self.assertEqual(s.object, DESCRIPTION)
Ejemplo n.º 3
0
 def test_predicate(self):
     p = get(Namespace, 'dc')['description']
     self.assertEqual(u'description', p.resource.name)
     self.assertEqual(u'description', p.name)
     self.assertEqual(p.domain, get(Namespace, 'rdfs')['Resource'])
     self.assertEqual(Resource, p.Domain)
     XS = get(Namespace, 'xs')
     STRING = XS['string']
     self.assertEqual(STRING, p.range)
     self.assertEqual(STRING.Model, String)
     self.assertEqual(String, p.Range)
Ejemplo n.º 4
0
 def test_concept(self):
     XS = get(Namespace, 'xs')
     TEXT = XS['string']
     TMP = create(Namespace, 'tmp', 'http://tmp.tmp.tmp/tmp/tmp/')
     T = create(Concept, TMP, 'T')
     one_one = Cardinality.objects.get(domain='1', range='1') # IGNORE:E1101
     P = create(Predicate, TMP, 'P', domain=T, range=TEXT, cardinality=one_one)
     r = create(Resource, TMP, 'r', T)
     create(Statement, r, P, 'something clever')
     s = get(Statement, r, P)
     self.assertEqual(s.object, u'something clever')
     result = Concept.objects.values_for_concept(concept=T)
     self.assertEqual(1, result.count())
Ejemplo n.º 5
0
 def test_one_predicate_with_TEXT_range(self):
     XS = get(Namespace, 'xs')
     TEXT = XS['string']
     TMP = create(Namespace, 'tmp', 'http://tmp.tmp.tmp/tmp/tmp/')
     T = create(Concept, TMP, 'T', 'rdf.models.Resource')
     one_one = Cardinality.objects.get(domain='1', range='1') # IGNORE:E1101
     P = create(Predicate, TMP, 'P', domain=T, range=TEXT, cardinality=one_one)
     r = create(Resource, TMP, 'r', T)
     create(Statement, r, P, 'something clever')
     s = get(Statement, r, P)
     self.assertEqual(s.object, u'something clever')
     values = Concept.objects.values_for_predicates(P, domain=T)
     self.assertEqual(1, values.count())
     r_ = values[0]
     self.assertEqual(r_[P], s.object)
Ejemplo n.º 6
0
    def parameterize(self, *args, **kwargs): # IGNORE:R0201
        """
        A filter for constructing keyword arguments for passing to the model constructor
        or the create or get_or_create methods of this manager.

        The arguments are processed and new keyword arguments added to the keyword
        arguments received. The resulting keyword arguments dictionary is returned.

        The keyword arguments received must not conflict with the new keyword
        arguments formed.

        The argument list should be formed as follows:

            0 or 1 arguments: Exception raised, subject and predicate are required.

            2 arguments:
                Argument 0: Added as the 'subject' element.
                Argument 1: Added as the 'predicate' element.

            3 arguments:
                Arguments 0, 1 - as for 2 arguments.
                Argument 3: Added as the 'object' element.

        If more than 3 arguments are passed an exception is raised.
        """
        from rdf.models import Predicate, Resource
        from rdf.shortcuts import get
        l = len(args)
        if 0 == l:
            pass # Using keyword arguments
        elif 1 == l:
            raise Exception('expect subject and predicate, and optionally object')
        elif 2 == l:
            p = args[1]
            p = get(Predicate, resource=p) if isinstance(p, Resource) else p
            kwargs['predicate'] = p
            kwargs['subject'] = args[0]
        elif 3 == l:
            p = args[1]
            p = get(Predicate, resource=p) if isinstance(p, Resource) else p
            kwargs['predicate'] = p
            kwargs['subject'] = args[0]
            kwargs['object'] = args[2]
        else:
            raise Exception(
                '''expected subject and predicate, and optionally object; got '%s' '''\
                % unicode(args))
        return kwargs
Ejemplo n.º 7
0
def _compiler_support(literal):
    """
    Creates an implicit literal and predicate pair imitating the ontology elements 
    that would appear in an ontology fragment constructed by mirroring the database 
    table underlying the parameter literal.  
    
    The query compiler uses the literal and predicate during the processing of 
    clauses that contain predicates using the parameter literal as the range. 
    """
    RDF, RDFS, DRDFS = \
        get((Namespace, 'rdf'), (Namespace, 'rdfs'), (Namespace, 'drdfs'))
    one_to_one = Cardinality.objects.get(domain='1', range='1')
    title = literal.title + ' (*)'
    description = 'Compiler support for %ss' % literal.title
    unique = (literal.namespace.code, literal.name)
    tr, _ = Resource.objects.get_or_create(
        namespace=DRDFS, name='_%s%s' % unique, type=RDFS['Literal'])
    t, _ = Concept.objects.get_or_create(
        resource=tr, 
        title=title,
        description=description,
        model_name=literal.model_name, 
        literal=True)
    pr, _ = Resource.objects.get_or_create(
        namespace=DRDFS, name='_%s%svalue' % unique, type=RDF['Property'])
    Predicate.objects.get_or_create(
        resource=pr, 
        domain=literal, 
        range=t,
        field_name='%s.value' % literal.model_name,
        cardinality=one_to_one, 
        title=title,
        description=description)
Ejemplo n.º 8
0
 def test_predicates(self):
     XS = get(Namespace, 'xs')
     TEXT = XS['string']
     mm = Cardinality.objects.get(domain='1', range='1')
     mo = Cardinality.objects.get(domain='1', range='?')
     oo = Cardinality.objects.get(domain='?', range='?')
     TMP = create(Namespace, 'tmp', 'http://tmp/tmp#')
     T = create(Concept, TMP, 'T')
     M0 = create(Predicate, TMP, 'M0', domain=T, range=TEXT, cardinality=mm) 
     M1 = create(Predicate, TMP, 'M1', domain=T, range=TEXT, cardinality=mm) 
     M2 = create(Predicate, TMP, 'M2', domain=T, range=TEXT, cardinality=mm)
     O0 = create(Predicate, TMP, 'O0', domain=T, range=TEXT, cardinality=mo) 
     O1 = create(Predicate, TMP, 'O1', domain=T, range=TEXT, cardinality=oo) 
     mandatory = T.mandatory_predicates 
     optional = T.optional_predicates
     all = T.predicates
     self.assertEqual(3, len(mandatory))
     self.assertEqual(2, len(optional))
     self.assertEqual(5, len(all))
     for M in (M0, M1, M2):
         self.assertTrue(M in mandatory)
         self.assertFalse(M in optional)
         self.assertTrue(M in all)
     for O in (O0, O1):
         self.assertFalse(O in mandatory)
         self.assertTrue(O in optional)
         self.assertTrue(O in all)
     for P in (M0, M1, M2, O0, O1):
         self.assertTrue(P in all)
Ejemplo n.º 9
0
 def test_empty_chain_length_5(self):
     DC = get(Namespace, 'dc')
     TMP = create(Namespace, 'tmp', 'http://tmp/tmp#')
     TMQ = create(Namespace, 'tmq', 'http://tmq/tmq#')
     C, D, E, F, G = create(
         (Concept, TMP, 'C'), (Concept, TMP, 'D'), (Concept, TMP, 'E'), 
         (Concept, TMQ, 'F'), (Concept, TMQ, 'G'))
     one_one = Cardinality.objects.get(domain='1', range='1') # IGNORE:E1101
     P = create(Predicate, TMP, 'P', domain=C, range=D, cardinality=one_one)
     Q = create(Predicate, TMP, 'Q', domain=D, range=E, cardinality=one_one)
     R = create(Predicate, TMQ, 'R', domain=E, range=F, cardinality=one_one)
     S = create(Predicate, TMQ, 'S', domain=F, range=G, cardinality=one_one)
     rqs = SPARQLQuerySet().rdql(u'''
         select c.rdf:about, e.dc:title, g.dc:description 
         from tmp:C c, tmp:D d, tmp:E e, tmq:F f, tmq:G g
         where c tmp:P d
           and d tmp:Q e 
           and e tmq:R f
           and f tmq:S g
         using tmp for "http://tmp/tmp#",
               tmq for "http://tmq/tmq#",
               dc for "http://purl.org/dc/elements/1.1/",
               rdf for "http://www.w3.org/1999/02/22-rdf-syntax-ns#"''')
     select = u'select c.name, e__dc__title__o.value, g__dc__description__o.value from rdf_statement e__dc__title__s, rdf_statement e__tmq__R__s, rdf_resource e, rdf_resource d, rdf_resource g, rdf_resource f, rdf_statement c__tmp__P__s, rdf_statement f__tmq__S__s, rdf_resource c, rdf_statement g__dc__description__s, rdf_string g__dc__description__o, rdf_statement d__tmp__Q__s, rdf_string e__dc__title__o where c__tmp__P__s.subject_id = c.id and c__tmp__P__s.predicate_id = %s and c__tmp__P__s.object_resource_id = d.id and d__tmp__Q__s.subject_id = d.id and d__tmp__Q__s.predicate_id = %s and d__tmp__Q__s.object_resource_id = e.id and e__tmq__R__s.subject_id = e.id and e__tmq__R__s.predicate_id = %s and e__tmq__R__s.object_resource_id = f.id and f__tmq__S__s.subject_id = f.id and f__tmq__S__s.predicate_id = %s and f__tmq__S__s.object_resource_id = g.id and c.type_id = %s and e.type_id = %s and d.type_id = %s and g.type_id = %s and f.type_id = %s and e__dc__title__s.subject_id = e.id and e__dc__title__s.predicate_id = %s and e__dc__title__s.id = e__dc__title__o.statement_id and g__dc__description__s.subject_id = g.id and g__dc__description__s.predicate_id = %s and g__dc__description__s.id = g__dc__description__o.statement_id' % (P.id, Q.id, R.id, S.id, C.id, E.id, D.id, G.id, F.id, DC['title'].id, DC['description'].id)
     count = u'select count(*) from rdf_statement e__dc__title__s, rdf_statement e__tmq__R__s, rdf_resource e, rdf_resource d, rdf_resource g, rdf_resource f, rdf_statement c__tmp__P__s, rdf_statement f__tmq__S__s, rdf_resource c, rdf_statement g__dc__description__s, rdf_string g__dc__description__o, rdf_statement d__tmp__Q__s, rdf_string e__dc__title__o where c__tmp__P__s.subject_id = c.id and c__tmp__P__s.predicate_id = %s and c__tmp__P__s.object_resource_id = d.id and d__tmp__Q__s.subject_id = d.id and d__tmp__Q__s.predicate_id = %s and d__tmp__Q__s.object_resource_id = e.id and e__tmq__R__s.subject_id = e.id and e__tmq__R__s.predicate_id = %s and e__tmq__R__s.object_resource_id = f.id and f__tmq__S__s.subject_id = f.id and f__tmq__S__s.predicate_id = %s and f__tmq__S__s.object_resource_id = g.id and c.type_id = %s and e.type_id = %s and d.type_id = %s and g.type_id = %s and f.type_id = %s and e__dc__title__s.subject_id = e.id and e__dc__title__s.predicate_id = %s and e__dc__title__s.id = e__dc__title__o.statement_id and g__dc__description__s.subject_id = g.id and g__dc__description__s.predicate_id = %s and g__dc__description__s.id = g__dc__description__o.statement_id' % (P.id, Q.id, R.id, S.id, C.id, E.id, D.id, G.id, F.id, DC['title'].id, DC['description'].id)
     self.assertEqual(0, rqs.count())
     self.assertEqual(getattr(rqs, '_cached_query').select, select)
     self.assertEqual(getattr(rqs, '_cached_query').count, count)
     self.assertEqual(0, len(rqs.filter())) # IGNORE:E1101
Ejemplo n.º 10
0
 def test_get_from_values(self):
     N = create(Namespace, 'n', 'http://example.com/namespace/')
     T = create(Concept, N, 't')
     r = create(Resource, N, 'r', T)
     V = get(Namespace, code='xs')['string']
     one_none = Cardinality.objects.get(domain='1', range='?') # IGNORE:E1101
     p = create(Predicate, N, 'p', domain=r.type, range=V, cardinality=one_none)
     v = {'value': u'something clever'}
     s, _ = get_or_create(Statement, r, p, v)
     self.assertEqual(r, s.subject)
     self.assertEqual(p, s.predicate)
     self.assertEqual(v['value'], s.object)
     self.assertEqual(String, type(s.object))
     self.assertEqual(None, s.reified)
     t = get(Statement, r, p)
     self.assertEqual(r, t.subject)
     self.assertEqual(p, t.predicate)
     self.assertEqual(v['value'], t.object)
     self.assertEqual(String, type(t.object))
Ejemplo n.º 11
0
 def test_resource_types(self):
     _, RDFS, OWL = get((Namespace, 'rdf'), (Namespace, 'rdfs'), (Namespace, 'owl'))
     CLASS, LITERAL, OWL_CLASS = RDFS['Class'], RDFS['Literal'], OWL['Class']
     types = Concept.objects.all()
     for t in types:
         if t.literal:
             # Nasty... special-casing the base literal type: 
             rtype = LITERAL
             if t is LITERAL:
                 rtype = CLASS
             self.assertEqual(rtype, t.resource.type)
         else:
             if not t.resource.type in (CLASS, OWL_CLASS):
                 print t.resource.type, t, t.resource
             self.assertTrue(t.resource.type in (CLASS, OWL_CLASS))
Ejemplo n.º 12
0
 def test_simple_empty_with_literal_object(self):
     XS = get(Namespace, 'xs')
     TMP = create(Namespace, 'tmp', 'http://tmp/tmp#')
     TEXT = XS['string']
     self.assertTrue(TEXT.literal)
     C = create(Concept, TMP, 'C') # Defaults to 'rdf.models.Resource'
     one_one = Cardinality.objects.get(domain='1', range='1') # IGNORE:E1101
     P = create(Predicate, TMP, 'P', domain=C, range=TEXT, cardinality=one_one)
     self.assertTrue(P.literal)
     rqs = SPARQLQuerySet().rdql(\
         u'select c.tmp:P from tmp:C c using tmp for "http://tmp/tmp#"')
     select = u'''select c__tmp__P__o.value from rdf_resource c, rdf_statement c__tmp__P__s, rdf_string c__tmp__P__o where c.type_id = %s and c__tmp__P__s.subject_id = c.id and c__tmp__P__s.predicate_id = %s and c__tmp__P__s.id = c__tmp__P__o.statement_id''' % (C.id, P.id)
     count = u'''select count(*) from rdf_resource c, rdf_statement c__tmp__P__s, rdf_string c__tmp__P__o where c.type_id = %s and c__tmp__P__s.subject_id = c.id and c__tmp__P__s.predicate_id = %s and c__tmp__P__s.id = c__tmp__P__o.statement_id''' % (C.id, P.id)
     self.assertEqual(0, rqs.count())
     self.assertEqual(getattr(rqs, '_cached_query').select, select)
     self.assertEqual(getattr(rqs, '_cached_query').count, count)
     self.assertEqual(0, len(rqs.filter())) # IGNORE:E1101
Ejemplo n.º 13
0
 def test_offsets_and_limits(self):
     XS = get(Namespace, 'xs')
     TMP = create(Namespace, 'tmp', 'http://tmp/tmp#')
     TEXT = XS['string']
     C = create(Concept, TMP, 'C') 
     one_one = Cardinality.objects.get(domain='1', range='1') # IGNORE:E1101
     P = create(Predicate, TMP, 'P', domain=C, range=TEXT, cardinality=one_one)
     for i in range(0, 20):
         r = create(Resource, TMP, 'r%s' % i, type=C)
         create(Statement, r, P, 'r%s' % i)
     _ = Concept.objects.values_for_concept(concept=C)
     self.assertEqual(20, len(_))
     self.assertEqual(20, _.count())
     _ = Concept.objects.values_for_concept(concept=C)[:10]
     self.assertEqual(10, _.count())
     self.assertEqual(10, len(_))
     _ = Concept.objects.values_for_concept(concept=C)[7:10]
     self.assertEqual(3, _.count())
     self.assertEqual(3, len(_))
Ejemplo n.º 14
0
def post():
    '''
    Invoked during the ontology load process, after all core ontology definitions 
    have been parsed but before any additional fragments are loaded. 
    
    Carries out any necessary post-processing for the coreontology elements, 
    including but not limited to: 
    
        * Specifying predicate cardinalities
        * Establishing model mappings for concepts and literals
        * Synthesizing value predicates for literals
        
    '''
    RDF, RDFS, OWL, XS, DC, DRDFS = get(
        (Namespace, 'rdf'), (Namespace, 'rdfs'), (Namespace, 'owl'),
        (Namespace, 'xs'), (Namespace, 'dc'), (Namespace, 'drdfs'))
    
    one_to_one = Cardinality.objects.get(domain='1', range='1')
    any_to_one = Cardinality.objects.get(domain='*', range='1')

    # Ontologies...
    
    ONTOLOGY = OWL['Ontology']
    ONTOLOGY.model_name = 'rdf.models.Ontology'
    ONTOLOGY.save()
    
    _mark_internal_ontologies()
    
    # First arrange support for accessing resource identifier strings, e.g. rdf:about:
    
    URI, _ = get_or_create(
        # URI literal stored in the resources table, in the name field. 
        # This unfortunately leaves off the namespace prefix but will do for now.
        Concept, DRDFS, 'uri', 
        defaults=dict(
            literal=True, 
            model_name='rdf.models.Resource', 
            title='Uniform Resource Identifier', 
            description='A string that uniquely identifies the associated resource.'))
    URI.resource.type = RDFS['Literal']
    URI.resource.save()
        
    get_or_create(
        # Predicate for accessing the URI for a resource.
        Predicate, RDF, 'about', 
        defaults=dict(
            domain=RDFS['Resource'],
            range=URI, 
            cardinality=one_to_one, 
            field_name='rdf.models.Resource.name', # Not quite right... missing prefix
            title='RDF About',
            description='Associates a resource with its URI'))
    
    # Now map some built-in predicates to the right database columns, assign 
    # cardinalities, etc.:

    TYPE = RDF['type']
    TYPE.field_name = 'rdf.models.Resource.type'
    TYPE.cardinality = one_to_one
    TYPE.save()
    
    SUBJECT = RDF['subject']
    SUBJECT.field_name = 'rdf.models.Statement.subject'
    SUBJECT.cardinality = any_to_one
    SUBJECT.save()
    
    PREDICATE = RDF['predicate']
    PREDICATE.field_name = 'rdf.models.Statement.predicate'
    PREDICATE.cardinality = any_to_one
    PREDICATE.save()

    OBJECT = RDF['predicate']
    OBJECT.cardinality = any_to_one
    OBJECT.save()
    
    # RDF['object'] field is more complicated... it is special-cased in the compiler.
    
    b = Concept.objects.get(resource__namespace=XS, resource__name='boolean')
    b.title='Boolean Literal'
    b.description='The literal type used to store Boolean truth values.'
    b.save()
    _recursive_map_model(b, 'rdf.models.Boolean')

    d = Concept.objects.get(resource__namespace=XS, resource__name='date')
    d.title = 'Date Literal'
    d.description = 'The literal type used to store date values.'
    d.save()
    _recursive_map_model(d, 'rdf.models.Date')

    t = Concept.objects.get(resource__namespace=XS, resource__name='time')
    t.title = 'Time literal'
    t.description = 'The literal type used to store timestamps.'
    t.save()
    _recursive_map_model(t, 'rdf.models.Time')

    t = Concept.objects.get(resource__namespace=XS, resource__name='dateTime')
    t.title = 'Date-Time literal'
    t.description = 'Another literal type used to store timestamps.'
    t.save()
    _recursive_map_model(t, 'rdf.models.Time')

    d = Concept.objects.get(resource__namespace=XS, resource__name='duration')
    d.title='Duration Literal'
    d.description='The literal type used to store durations.'
    d.save()
    _recursive_map_model(d, 'rdf.models.Duration')

    d = Concept.objects.get(resource__namespace=XS, resource__name='decimal')
    d.title='Decimal Literal'
    d.description='The literal type used to store decimal numbers.'
    d.save()
    _recursive_map_model(d, 'rdf.models.Decimal')

    d = Concept.objects.get(resource__namespace=XS, resource__name='double')
    d.title='Double Literal'
    d.description='The literal type used to store double size floating point numbers.'
    d.save()
    _recursive_map_model(d, 'rdf.models.Float')

    d = Concept.objects.get(resource__namespace=XS, resource__name='float')
    d.title='Float Literal'
    d.description='The literal type used to store floating point numbers.'
    d.save()
    _recursive_map_model(d, 'rdf.models.Float')

    s = Concept.objects.get(resource__namespace=XS, resource__name='string')
    s.title = 'String Literal'
    s.description='The literal type used to store text values.'
    s.save()
    _recursive_map_model(s, 'rdf.models.String')

    p = Predicate.objects.get(resource__namespace=DC, resource__name='title')
    p.range = XS['string']
    p.save()

    p = Predicate.objects.get(resource__namespace=DC, resource__name='description')
    p.range = XS['string']
    p.save()
Ejemplo n.º 15
0
 def test_mandatory(self):
     RDF, RDFS = get((Namespace, 'rdf'), (Namespace, 'rdfs'))
     pp = RDFS['Class'].mandatory_predicates
     self.assertTrue(RDF['type'] in pp)
     self.assertTrue(RDF['about'] in pp)
Ejemplo n.º 16
0
                if not os.path.exists(dirname):
                    os.mkdir(dirname)
                basename = f.app_path.replace('.', '-') + '.rdf'
                of = codecs.open(os.path.join(dirname, basename), 'w', encoding='utf-8')
                of.write(generate_RDF(f))
                of.close()
        except Exception, x: # IGNORE:W0703 Catching everything
            if 0 < self.verbosity:
                print '''RDF generation failed failed with an exception.'''
            if self.show_traceback:
                exc = sys.exc_info()
                print x, type(x)
                traceback.print_tb(exc[2])
            
            
XS, DRDFS = get((Namespace, 'xs'), (Namespace, 'drdfs')) 
    
_LITERAL_TYPE_MAP = {
    AutoField: XS['decimal'],
    BooleanField: XS['boolean'],
    CharField: XS['string'],
    DateField: XS['date'], 
    DateTimeField: XS['time'],
    DecimalField: XS['decimal'], 
    FloatField: XS['float'],  
    IntegerField: XS['decimal'], 
    TextField: XS['string'], 
    TimeField: XS['time'],
}

Ejemplo n.º 17
0
 def test_check(self):
     XS = get(Namespace, 'xs')
     self.assertTrue(XS['string'].literal)
     self.assertTrue(XS['decimal'].literal)
Ejemplo n.º 18
0
 def test_ontology(self):
     RDFS = get(Namespace, 'rdfs')
     self.assertEqual(RDFS.code, u'rdfs')
Ejemplo n.º 19
0
from django.core.exceptions import ObjectDoesNotExist

from rdf.models import Cardinality, Namespace, Ontology, Predicate, Resource, \
    Statement, Concept
from rdf.shortcuts import get

from rdf.serializers import _JC, _split_URI, _DXML 


RDF = get(Namespace, 'rdf')
RDFS = get(Namespace, 'rdfs')
OWL = get(Namespace, 'owl')
DC = get(Namespace, 'dc')
DRDFS = get(Namespace, 'drdfs')

RESOURCE, CONCEPT, LITERAL, PREDICATE = get(
    (Concept, RDFS, 'Resource'), 
    (Concept, RDFS, 'Class'), 
    (Concept, RDFS, 'Literal'), 
    (Concept, RDF, 'Property'))

RDF_RDF = _JC(RDF.uri, 'RDF')
RDF_DESCRIPTION = _JC(RDF.uri, 'Description')
RDF_RESOURCE = _JC(RDF.uri, 'resource')
RDF_ID = _JC(RDF.uri, 'ID')
RDF_ABOUT = _JC(RDF.uri, 'about')
RDF_PROPERTY = _JC(RDF.uri, 'Property')

RDFS_CLASS = _JC(RDFS.uri, 'Class')
RDFS_LITERAL = _JC(RDFS.uri, 'Literal')
RDFS_DATATYPE = _JC(RDFS.uri, 'Datatype')
Ejemplo n.º 20
0
def _generalize(ast):
    """
    Generic resources are stored as instances of the RDF Resource model, and 
    statements using generic predicates are stored as instances of the RDF 
    Statement model. In both cases query compilation is complicated by the need to 
    insert additional variables, predicates and constraints to ensure that the 
    generated SQL uses the internal RDF tables where necessary.
    
    The generated RDQL clauses are full of names with excessive uses of `__`, 
    which is necessary to avoid name collisions - but also precludes the use of 
    the `__` substring in regular names (or else the possibility of name collisions
    arises again...).

    The generalizer is required not to modify the AST except by adding new elements. 
    In some cases predicates and constraints need to be replaced or expanded, which 
    is achieved by hanging new `_generalized` attributes on the existing objects.
    """ 
    
    from rdf.models import Namespace, Predicate, Concept

    RDF, RDFS, DRDFS = get((Namespace, 'rdf'), (Namespace, 'rdfs'), (Namespace, 'drdfs'))
    TYPE, SUBJECT, PREDICATE, OBJECT, ABOUT, STATEMENT, RESOURCE, _ = get(
        # This doesn't work here:
        #     RDF['type', 'subject', 'predicate', 'object', 'about']
        # ... because the Namespace [] operator is disabled during template execution... 
        (Predicate, RDF, 'type'), 
        (Predicate, RDF, 'subject'),
        (Predicate, RDF, 'predicate'),
        (Predicate, RDF, 'object'),
        (Predicate, RDF, 'about'),
        (Concept, RDF, 'Statement'),
        (Concept, RDFS, 'Resource'),
        (Concept, RDFS, 'Class')) 
    
    def _variable(reference):
        """
        Code generation for a generic concept needs to use the RDF model tables.
        This method ensures that the resources are constrained to the appropriate 
        concept, by synthesizing a new constraint of the form
        
            x rdf:type 10
 
        where 10 is the type_id column value for the resources x.
 
        It also points the code generator at the general resources table by 
        rebinding the input variable to the top-level resource concept. 
        """ 
        reference.concept.binding._generalized = RESOURCE
        pref = PredicateRef(variable=reference, binding=TYPE)
        ccon = Constraint(
            subject=reference, predicate=pref, object=reference.concept.binding.id)
        return (ccon,)
    
    def _predicate(reference):
        """
        Code generation for a generic predicate needs to use the RDF model tables. 
        This method takes a predicate reference from RDQL clauses of the kind 
            
            select x.y:z from y:X x using ...
            
        and creates new variables corresponding to implicit clauses of the kind
        
            rdf:Statement x__y__z__s
            <range of y:z> x__y__z__o
        
        Then three constraints are also added:
        
            x__y__z__s rdf:subject x
            x__y__z__s rdf:predicate y:z
            x__y__z__s rdf:object x__y__z__o

        """    
        assert not hasattr(reference, '_spanned')
        variables, constraints = [], []
        prefix = [
            reference.variable.name,            # x
            reference.binding.namespace.code,   # y
            reference.binding.name,             # z
        ]
        svar = Variable(
            name=u'__'.join(prefix + ['s']).replace('-', '_'), concept=STATEMENT)
        scon = Constraint(subject=svar, predicate=SUBJECT, object=reference.variable)
        pcon = Constraint(
            subject=svar, predicate=PREDICATE, object=reference.binding.id)
        ovar = Variable(
            name=u'__'.join(prefix + ['o']).replace('-', '_'), 
            concept=reference.binding.range)
        ocon = Constraint(subject=svar, predicate=OBJECT, object=ovar)
        if reference.binding.literal:
            if not reference.binding == ABOUT:
                # Must match identical construction in magic._compiler_support:
                opname = '_%s%svalue' \
                    % (reference.binding.range.namespace.code, 
                       reference.binding.range.name)
                opname.replace('-', '_')
                opred = Predicate.objects.get(
                    resource__name=opname, resource__namespace=DRDFS)
                opref = PredicateRef(binding=opred, variable=ovar)
            else:
                opref = reference # rdf:about is a special case...
        else:
            # Using rdf:about to indicate the URI of the resource. 
            # This is kind of broken in that the query will actually return the local 
            # name of the resource instead of the URI.
            opref = PredicateRef(binding=ABOUT, variable=ovar)
        assert not opref is None
        reference._generalized = opref
        variables.extend((svar, ovar))
        constraints.extend((scon, pcon, ocon))
        return variables, constraints

    def _constraint(reference):
        assert not hasattr(reference, '_spanned')
        variables = []
        prefix = [
            reference.predicate.variable.name,            # x
            reference.predicate.binding.namespace.code,   # y
            reference.predicate.binding.name,             # z
        ]
        svar = Variable(
            name=u'__'.join(prefix + ['s']).replace('-', '_'), concept=STATEMENT)
        scon = Constraint(
            subject=svar, predicate=SUBJECT, object=reference.predicate.variable)
        pcon = Constraint(
            subject=svar, predicate=PREDICATE, object=reference.predicate.binding.id)
        ocon = Constraint(subject=svar, predicate=OBJECT, object=reference.object)
        variables.append(svar)
        reference._generalized = (scon, pcon, ocon)
        return variables

    variables, constraints = [], []
    for v in ast.variables:
        if v.concept.binding.generic:
            constraints.extend(_variable(v))
    for p in ast.predicates:
        if hasattr(p, '_spanned'):
            p = p._spanned
        if p.binding.generic:
            vv, cc = _predicate(p)
            variables.extend(vv)
            constraints.extend(cc)
    for c in ast.constraints:
        if c.predicate.binding.generic:
            variables.extend(_constraint(c))
    ast.variables.add(*variables) # IGNORE:W0142
    ast.constraints.extend(constraints)
    return ast