clair/vendor/github.com/google/cayley/quad/quad.go
2015-11-13 14:11:28 -05:00

142 lines
3.6 KiB
Go

// Copyright 2014 The Cayley Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package quad defines quad and triple handling.
package quad
// Defines the struct which makes the QuadStore possible -- the quad.
//
// At its heart, it consists of three fields -- Subject, Predicate, and Object.
// Three IDs that relate to each other. That's all there is to it. The quads
// are the links in the graph, and the existence of node IDs is defined by the
// fact that some quad in the graph mentions them.
//
// This means that a complete representation of the graph is equivalent to a
// list of quads. The rest is just indexing for speed.
//
// Adding fields to the quad is not to be taken lightly. You'll see I mention
// label, but don't as yet use it in any backing store. In general, there
// can be features that can be turned on or off for any store, but I haven't
// decided how to allow/disallow them yet. Another such example would be to add
// a forward and reverse index field -- forward being "order the list of
// objects pointed at by this subject with this predicate" such as first and
// second children, top billing, what have you.
//
// There will never be that much in this file except for the definition, but
// the consequences are not to be taken lightly. But do suggest cool features!
import (
"errors"
"fmt"
)
var (
ErrInvalid = errors.New("invalid N-Quad")
ErrIncomplete = errors.New("incomplete N-Quad")
)
// Our quad struct, used throughout.
type Quad struct {
Subject string `json:"subject"`
Predicate string `json:"predicate"`
Object string `json:"object"`
Label string `json:"label,omitempty"`
}
// Direction specifies an edge's type.
type Direction byte
// List of the valid directions of a quad.
const (
Any Direction = iota
Subject
Predicate
Object
Label
)
var Directions = []Direction{Subject, Predicate, Object, Label}
func (d Direction) Prefix() byte {
switch d {
case Any:
return 'a'
case Subject:
return 's'
case Predicate:
return 'p'
case Label:
return 'c'
case Object:
return 'o'
default:
return '\x00'
}
}
func (d Direction) String() string {
switch d {
case Any:
return "any"
case Subject:
return "subject"
case Predicate:
return "predicate"
case Label:
return "label"
case Object:
return "object"
default:
return fmt.Sprint("illegal direction:", byte(d))
}
}
// Per-field accessor for quads.
func (q Quad) Get(d Direction) string {
switch d {
case Subject:
return q.Subject
case Predicate:
return q.Predicate
case Label:
return q.Label
case Object:
return q.Object
default:
panic(d.String())
}
}
// Pretty-prints a quad.
func (q Quad) String() string {
return fmt.Sprintf("%s -- %s -> %s", q.Subject, q.Predicate, q.Object)
}
func (q Quad) IsValid() bool {
return q.Subject != "" && q.Predicate != "" && q.Object != ""
}
// Prints a quad in N-Quad format.
func (q Quad) NQuad() string {
if q.Label == "" {
//TODO(barakmich): Proper escaping.
return fmt.Sprintf("%s %s %s .", q.Subject, q.Predicate, q.Object)
}
return fmt.Sprintf("%s %s %s %s .", q.Subject, q.Predicate, q.Object, q.Label)
}
type Unmarshaler interface {
Unmarshal() (Quad, error)
}