open-nomad/vendor/github.com/hashicorp/go-memdb/schema.go

115 lines
2.8 KiB
Go
Raw Normal View History

2016-02-12 18:02:16 +00:00
package memdb
import "fmt"
// DBSchema is the schema to use for the full database with a MemDB instance.
//
// MemDB will require a valid schema. Schema validation can be tested using
// the Validate function. Calling this function is recommended in unit tests.
2016-02-12 18:02:16 +00:00
type DBSchema struct {
// Tables is the set of tables within this database. The key is the
// table name and must match the Name in TableSchema.
2016-02-12 18:02:16 +00:00
Tables map[string]*TableSchema
}
// Validate validates the schema.
2016-02-12 18:02:16 +00:00
func (s *DBSchema) Validate() error {
if s == nil {
return fmt.Errorf("schema is nil")
2016-02-12 18:02:16 +00:00
}
2016-02-12 18:02:16 +00:00
if len(s.Tables) == 0 {
return fmt.Errorf("schema has no tables defined")
2016-02-12 18:02:16 +00:00
}
2016-02-12 18:02:16 +00:00
for name, table := range s.Tables {
if name != table.Name {
return fmt.Errorf("table name mis-match for '%s'", name)
}
2016-02-12 18:02:16 +00:00
if err := table.Validate(); err != nil {
return fmt.Errorf("table %q: %s", name, err)
2016-02-12 18:02:16 +00:00
}
}
2016-02-12 18:02:16 +00:00
return nil
}
// TableSchema is the schema for a single table.
2016-02-12 18:02:16 +00:00
type TableSchema struct {
// Name of the table. This must match the key in the Tables map in DBSchema.
Name string
// Indexes is the set of indexes for querying this table. The key
// is a unique name for the index and must match the Name in the
// IndexSchema.
2016-02-12 18:02:16 +00:00
Indexes map[string]*IndexSchema
}
// Validate is used to validate the table schema
func (s *TableSchema) Validate() error {
if s.Name == "" {
return fmt.Errorf("missing table name")
}
2016-02-12 18:02:16 +00:00
if len(s.Indexes) == 0 {
2017-02-04 00:28:27 +00:00
return fmt.Errorf("missing table indexes for '%s'", s.Name)
2016-02-12 18:02:16 +00:00
}
2016-02-12 18:02:16 +00:00
if _, ok := s.Indexes["id"]; !ok {
return fmt.Errorf("must have id index")
}
2016-02-12 18:02:16 +00:00
if !s.Indexes["id"].Unique {
return fmt.Errorf("id index must be unique")
}
2017-02-04 00:28:27 +00:00
if _, ok := s.Indexes["id"].Indexer.(SingleIndexer); !ok {
return fmt.Errorf("id index must be a SingleIndexer")
}
2016-02-12 18:02:16 +00:00
for name, index := range s.Indexes {
if name != index.Name {
return fmt.Errorf("index name mis-match for '%s'", name)
}
2016-02-12 18:02:16 +00:00
if err := index.Validate(); err != nil {
return fmt.Errorf("index %q: %s", name, err)
2016-02-12 18:02:16 +00:00
}
}
2016-02-12 18:02:16 +00:00
return nil
}
// IndexSchema is the schema for an index. An index defines how a table is
// queried.
2016-02-12 18:02:16 +00:00
type IndexSchema struct {
// Name of the index. This must be unique among a tables set of indexes.
// This must match the key in the map of Indexes for a TableSchema.
Name string
// AllowMissing if true ignores this index if it doesn't produce a
// value. For example, an index that extracts a field that doesn't
// exist from a structure.
2016-02-12 18:02:16 +00:00
AllowMissing bool
Unique bool
Indexer Indexer
2016-02-12 18:02:16 +00:00
}
func (s *IndexSchema) Validate() error {
if s.Name == "" {
return fmt.Errorf("missing index name")
}
if s.Indexer == nil {
return fmt.Errorf("missing index function for '%s'", s.Name)
}
2017-02-04 00:28:27 +00:00
switch s.Indexer.(type) {
case SingleIndexer:
case MultiIndexer:
default:
return fmt.Errorf("indexer for '%s' must be a SingleIndexer or MultiIndexer", s.Name)
}
2016-02-12 18:02:16 +00:00
return nil
}