github.com/cayleygraph/cayley@v0.7.7/examples/hello_schema/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "log" 8 "math/rand" 9 "os" 10 11 "github.com/cayleygraph/cayley" 12 "github.com/cayleygraph/cayley/graph" 13 _ "github.com/cayleygraph/cayley/graph/kv/bolt" 14 "github.com/cayleygraph/cayley/schema" 15 "github.com/cayleygraph/quad" 16 "github.com/cayleygraph/quad/voc" 17 18 // Import RDF vocabulary definitions to be able to expand IRIs like rdf:label. 19 _ "github.com/cayleygraph/quad/voc/core" 20 ) 21 22 type Person struct { 23 // dummy field to enforce all object to have a <id> <rdf:type> <ex:Person> relation 24 // means nothing for Go itself 25 rdfType struct{} `quad:"@type > ex:Person"` 26 ID quad.IRI `json:"@id"` // tag @id is a special one - graph node value will be stored in this field 27 Name string `json:"ex:name"` // field name (predicate) may be written as json field name 28 Age int `quad:"ex:age"` // or in a quad tag 29 } 30 31 type Coords struct { 32 // Object may be without id - it will be generated automatically. 33 // It's also not necessary to have a type definition. 34 Lat float64 `json:"ex:lat"` 35 Lng float64 `json:"ex:lng"` 36 } 37 38 func checkErr(err error) { 39 if err != nil { 40 log.Fatal(err) 41 } 42 } 43 44 func main() { 45 // Define an "ex:" prefix for IRIs that will be expanded to "http://example.org". 46 // "ex:name" will become "http://example.org/name" 47 voc.RegisterPrefix("ex:", "http://example.org/") 48 49 // Associate Go type with an IRI. 50 // All Coords objects will now generate a <id> <rdf:type> <ex:Coords> triple. 51 schema.RegisterType(quad.IRI("ex:Coords"), Coords{}) 52 53 sch := schema.NewConfig() 54 // Override a function to generate IDs. Can be changed to generate UUIDs, for example. 55 sch.GenerateID = func(_ interface{}) quad.Value { 56 return quad.BNode(fmt.Sprintf("node%d", rand.Intn(1000))) 57 } 58 59 // File for your new BoltDB. Use path to regular file and not temporary in the real world 60 tmpdir, err := ioutil.TempDir("", "example") 61 checkErr(err) 62 63 defer os.RemoveAll(tmpdir) // clean up 64 65 // Initialize the database 66 err = graph.InitQuadStore("bolt", tmpdir, nil) 67 checkErr(err) 68 69 // Open and use the database 70 store, err := cayley.NewGraph("bolt", tmpdir, nil) 71 checkErr(err) 72 defer store.Close() 73 qw := graph.NewWriter(store) 74 75 // Save an object 76 bob := Person{ 77 ID: quad.IRI("ex:bob").Full().Short(), 78 Name: "Bob", Age: 32, 79 } 80 fmt.Printf("saving: %+v\n", bob) 81 id, err := sch.WriteAsQuads(qw, bob) 82 checkErr(err) 83 err = qw.Close() 84 checkErr(err) 85 86 fmt.Println("id for object:", id, "=", bob.ID) // should be equal 87 88 // Get object by id 89 var someone Person 90 err = sch.LoadTo(nil, store, &someone, id) 91 checkErr(err) 92 fmt.Printf("loaded: %+v\n", someone) 93 94 // Or get all objects of type Person 95 var people []Person 96 err = sch.LoadTo(nil, store, &people) 97 checkErr(err) 98 fmt.Printf("people: %+v\n", people) 99 100 fmt.Println() 101 102 // Store objects with no ID and type 103 coords := []Coords{ 104 {Lat: 12.3, Lng: 34.5}, 105 {Lat: 39.7, Lng: 8.41}, 106 } 107 qw = graph.NewWriter(store) 108 for _, c := range coords { 109 id, err = sch.WriteAsQuads(qw, c) 110 checkErr(err) 111 fmt.Println("generated id:", id) 112 } 113 err = qw.Close() 114 checkErr(err) 115 116 // Get coords back 117 var newCoords []Coords 118 err = sch.LoadTo(nil, store, &newCoords) 119 checkErr(err) 120 fmt.Printf("coords: %+v\n", newCoords) 121 122 // Print quads 123 fmt.Println("\nquads:") 124 ctx := context.TODO() 125 it := store.QuadsAllIterator() 126 for it.Next(ctx) { 127 fmt.Println(store.Quad(it.Result())) 128 } 129 }