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)
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)
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)
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())
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)
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
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)
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)
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
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))
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))
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
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(_))
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()
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)
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'], }
def test_check(self): XS = get(Namespace, 'xs') self.assertTrue(XS['string'].literal) self.assertTrue(XS['decimal'].literal)
def test_ontology(self): RDFS = get(Namespace, 'rdfs') self.assertEqual(RDFS.code, u'rdfs')
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')
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