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  }