Difficulty using the `schema` package

schema

#1

I have a source which looks like:

<dialect-source-file.raml#> <http://raml.org/vocabularies/meta#vocabularies> <dialect-source-file.raml#vocabularies/validation> .
<dialect-source-file.raml#vocabularies/validation> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://raml.org/vocabularies/meta#External> .
<dialect-source-file.raml#vocabularies/validation> <http://raml.org/vocabularies/meta#name> "validation" .
<dialect-source-file.raml#vocabularies/validation> <http://raml.org/vocabularies/meta#uri> "../vocabulary/validation.raml" .
<dialect-source-file.raml#> <http://raml.org/vocabularies/meta#external> <dialect-source-file.raml#external/schema-org> .
<dialect-source-file.raml#external/schema-org> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://raml.org/vocabularies/meta#External> .
<dialect-source-file.raml#external/schema-org> <http://raml.org/vocabularies/meta#name> "schema-org" .
<dialect-source-file.raml#external/schema-org> <http://raml.org/vocabularies/meta#uri> "http://schema.org/" .

I’m trying to use the schema package to load this struct from it:

type DialectExternal struct {
	Name    string   `quad:"http://raml.org/vocabularies/meta#name,optional"`
	URI     string   `quad:"http://raml.org/vocabularies/meta#uri,optional"`
}

I also tried with meta:name,optional in the tag and meta:uri,optional.

I always get an error saying:

required field is missing

That’s when calling:

	var dst DialectExternal
	schema.LoadTo(nil, store.store(), &dst)
	fmt.Println("DST", dst)
	// Same with:
	schema.LoadTo(nil, store.store(), &dst, quad.IRI("dialect-source-file.raml#vocabularies/validation"))
	fmt.Println("DST", dst)	

I’m quite puzzled… it seems to be a very simple case. Anything I’m missing ?

One thing I don’t understand is when/by which piece of code is the FullIRI or ShortIRI called to do the prefix resolution, and what is actually compared in the DB. The fact that WriteToQuads outputs quad.IRI("rdf:type") tipped me on that… not sure if I should use the long or short form…

thanks for any insight!


#2

I forgot to say I also have this:

func init() {
	schema.RegisterType(quad.IRI("http://raml.org/vocabularies/meta#External"), DialectExternal{})
}

#4

wait! :slight_smile: didn’t it work ?


#5

I’m looking at https://github.com/cayleygraph/cayley/blob/master/schema/schema_test.go#L541-L549 and there’s no other fields… that’s why I thought it was sufficient.


#6

I forgot to use schema.LoadTo() … doh!

I’m rewriting it now :wink:


#7

See: https://github.com/cayleygraph/cayley/issues/694

It seems schema implicitly requires the rdf:type predicate to be that IRI, and not the long-form, in the Store.


#8

I don’t understand how the “resolution” of prefixed predicates gets done… I can’t find any code doing that in the whole codebase…


#9

Yes, you are right.
I have it working now - so will post shortly.


#10

I have it working by changing:

	store.AddQuad(quad.Quad{
		quad.IRI("dialect-source-file.raml#vocabularies/validation"),
		quad.IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"),
		quad.IRI("http://raml.org/vocabularies/meta#External"),
		nil})

to

	store.AddQuad(quad.Quad{
		quad.IRI("dialect-source-file.raml#vocabularies/validation"),
		quad.IRI("rdf:type"),
		quad.IRI("http://raml.org/vocabularies/meta#External"),
		nil})

but that means my dataset is unusable (!!)


#11

You’ve found the answer yourself, but here’s my code anyway:

package main

import (
	"context"
	"fmt"
	"strings"

	"github.com/cayleygraph/cayley"
	"github.com/cayleygraph/cayley/quad"
	"github.com/cayleygraph/cayley/quad/nquads"
	"github.com/cayleygraph/cayley/schema"
)

const quads = `
<dialect-source-file.raml#> <http://raml.org/vocabularies/meta#vocabularies> <dialect-source-file.raml#vocabularies/validation> .
<dialect-source-file.raml#vocabularies/validation> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://raml.org/vocabularies/meta#External> .
<dialect-source-file.raml#vocabularies/validation> <http://raml.org/vocabularies/meta#name> "validation" .
<dialect-source-file.raml#vocabularies/validation> <http://raml.org/vocabularies/meta#uri> "../vocabulary/validation.raml" .
<dialect-source-file.raml#> <http://raml.org/vocabularies/meta#external> <dialect-source-file.raml#external/schema-org> .
<dialect-source-file.raml#external/schema-org> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://raml.org/vocabularies/meta#External> .
<dialect-source-file.raml#external/schema-org> <http://raml.org/vocabularies/meta#name> "schema-org" .
<dialect-source-file.raml#external/schema-org> <http://raml.org/vocabularies/meta#uri> "http://schema.org/" .

<dialect-source-file.raml#vocabularies/validation> <rdf:type> <http://raml.org/vocabularies/meta#External> .
`

func init() {
	schema.RegisterType(quad.IRI("http://raml.org/vocabularies/meta#External"), DialectExternal{})
}

type DialectExternal struct {
	ID   quad.IRI `json:"@id"`
	Name string   `quad:"http://raml.org/vocabularies/meta#name,optional"`
	URI  string   `quad:"http://raml.org/vocabularies/meta#uri,optional"`
}

func main() {

	store, err := cayley.NewMemoryGraph()
	if err != nil {
		panic(err)
	}
	defer store.Close()

	fmt.Println("Inserting quads...\n")
	for _, v := range strings.Split(quads, "\n") {
		if len(v) > 0 {
			qd, err := nquads.Parse(v)
			if err != nil {
				panic(err)
			}
			store.QuadWriter.AddQuad(qd)
		}
	}
	fmt.Println("...result:")

	var dst DialectExternal
	err = schema.LoadTo(context.TODO(), store, &dst,
		quad.IRI("dialect-source-file.raml#vocabularies/validation"))
	if err != nil {
		panic(err)
	}
	fmt.Println("DST", dst)
}


#12

The docs talk about rdfType, but no piece of code ever tries to read that…


#13

It just means you need to add an <rdf:type> quad for every ID which can be modelled by that go type.


#14

So there, where does the resolution of those short-form to long-form IRIs happen ? Does it even try ? Should we always store the short-form in the Store ?


#15

Remember that any value in Cayley is only stored in the database once, so long/short-form does not make too much difference in storage terms. All the quads are just 4 UIDs one UID per unique value.

To answer your question directly, I think long-short translation is done in cayley/voc.


#16

yeah… I see there is ShortIRI and FullIRI… but nothing uses that it seems… it needs to be manually done I guess


#17

ok, but thanks for the tips and time investigating that with me… I really appreciate :slight_smile: