ddml

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 27, 2025 License: MIT Imports: 4 Imported by: 2

README

DDML - Document Database Markup Language for Go

CI Status codecov Go Report Card CodeQL Go Reference License Go Version Release

A Go package for building and generating document database schemas programmatically.

Features

  • Complete Schema Support: Schemas, collections, fields, indexes, and enums
  • Nested Documents: Support for embedded objects and arrays
  • Fluent Builder API: Chainable methods for easy schema construction
  • DDML Generation: Convert Go structs to DDML syntax
  • Validation: Comprehensive validation of schema structures
  • Serialization: JSON and YAML serialization support

Installation

go get github.com/zoobzio/ddml

Quick Start

package main

import (
    "fmt"
    "github.com/zoobzio/ddml"
)

func main() {
    // Create a new schema
    schema := ddml.NewSchema("ecommerce").
        WithNote("E-commerce document store")

    // Create an enum
    schema.AddEnum(
        ddml.NewEnum("order_status", "pending", "processing", "shipped", "delivered"),
    )

    // Create a collection
    orders := ddml.NewCollection("orders").
        AddField(ddml.NewField("_id", ddml.TypeObjectID).WithPrimaryKey()).
        AddField(ddml.NewField("customer_id", ddml.TypeString).WithRequired()).
        AddField(ddml.NewField("status", ddml.TypeEnum).WithEnumRef("order_status")).
        AddField(ddml.NewField("total", ddml.TypeFloat).WithRequired()).
        AddIndex(ddml.NewIndex("customer_id").WithName("idx_customer"))

    // Add collection to schema
    schema.AddCollection(orders)

    // Validate
    if err := schema.Validate(); err != nil {
        panic(err)
    }

    // Generate DDML
    fmt.Println(schema.Generate())
}

Examples

Nested Objects
collection := ddml.NewCollection("users").
    AddField(ddml.NewField("_id", ddml.TypeObjectID).WithPrimaryKey()).
    AddField(
        ddml.NewObjectField("address").
            AddField(ddml.NewField("street", ddml.TypeString).WithRequired()).
            AddField(ddml.NewField("city", ddml.TypeString).WithRequired()).
            AddField(ddml.NewField("postal_code", ddml.TypeString)),
    )
Arrays
// Simple string array
collection.AddField(
    ddml.NewArrayField("tags", ddml.NewField("", ddml.TypeString)),
)

// Array of nested objects
collection.AddField(
    ddml.NewArrayField("items",
        ddml.NewObjectField("").
            AddField(ddml.NewField("product_id", ddml.TypeString).WithRequired()).
            AddField(ddml.NewField("quantity", ddml.TypeInt).WithRequired()).
            AddField(ddml.NewField("price", ddml.TypeFloat).WithRequired()),
    ),
)
Enums
schema.AddEnum(
    ddml.NewEnum("order_status", "pending", "processing", "shipped", "delivered").
        WithNote("Order status values"),
)

collection.AddField(
    ddml.NewField("status", ddml.TypeEnum).
        WithEnumRef("order_status").
        WithRequired().
        WithDefault("pending"),
)
Field References
collection.AddField(
    ddml.NewField("customer_id", ddml.TypeString).
        WithRequired().
        WithRef("customers", "_id"),
)
Indexes
// Simple index
collection.AddIndex(ddml.NewIndex("customer_id"))

// Composite index
collection.AddIndex(
    ddml.NewIndex("customer_id", "created_at").
        WithName("idx_customer_created").
        WithUnique(),
)

// Geo index
collection.AddIndex(
    ddml.NewIndex("location").
        WithType(ddml.IndexGeo2DSphere),
)

// TTL index
collection.AddIndex(
    ddml.NewIndex("expires_at").
        WithTTL(3600),
)

API Reference

Core Types
  • Schema: Top-level container for document database schema
  • Collection: Document collection with fields and indexes
  • Field: Document field (supports nesting)
  • Index: Index definition with various types
  • Enum: Enumeration type
Field Types
const (
    TypeString   FieldType = "string"
    TypeInt      FieldType = "int"
    TypeFloat    FieldType = "float"
    TypeBool     FieldType = "bool"
    TypeDate     FieldType = "date"
    TypeObjectID FieldType = "objectid"
    TypeObject   FieldType = "object"
    TypeArray    FieldType = "array"
    TypeEnum     FieldType = "enum"
    TypeBinary   FieldType = "binary"
    TypeGeoPoint FieldType = "geopoint"
)
Index Types
const (
    IndexText        IndexType = "text"
    IndexGeo2D       IndexType = "geo2d"
    IndexGeo2DSphere IndexType = "geo2dsphere"
    IndexHashed      IndexType = "hashed"
)

Methods

Schema Methods
  • NewSchema(name string) *Schema
  • WithNote(note string) *Schema
  • AddCollection(collection *Collection) *Schema
  • AddEnum(enum *Enum) *Schema
  • Validate() error
  • Generate() string
  • ToJSON() ([]byte, error)
  • FromJSON(data []byte) error
  • ToYAML() ([]byte, error)
  • FromYAML(data []byte) error
Collection Methods
  • NewCollection(name string) *Collection
  • WithNote(note string) *Collection
  • WithSetting(key, value string) *Collection
  • AddField(field *Field) *Collection
  • AddIndex(index *Index) *Collection
Field Methods
  • NewField(name string, fieldType FieldType) *Field
  • NewObjectField(name string) *Field
  • NewArrayField(name string, elementType *Field) *Field
  • WithRequired() *Field
  • WithUnique() *Field
  • WithPrimaryKey() *Field
  • WithDefault(value string) *Field
  • WithEnumRef(enumName string) *Field
  • WithRef(collection, field string) *Field
  • AddField(nested *Field) *Field
Index Methods
  • NewIndex(fields ...string) *Index
  • WithName(name string) *Index
  • WithUnique() *Index
  • WithSparse() *Index
  • WithTTL(seconds int) *Index
  • WithType(indexType IndexType) *Index
  • WithOrder(fieldName string, order IndexOrder) *Index
Enum Methods
  • NewEnum(name string, values ...string) *Enum
  • WithNote(note string) *Enum

License

MIT

Documentation

Overview

Package ddml provides types and utilities for defining document database schemas. DDML (Document Database Markup Language) is a schema definition language for document databases, supporting nested structures, arrays, and index configurations.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Collection

type Collection struct {
	Name     string
	Note     *string
	Settings map[string]string
	Fields   []*Field
	Indexes  []*Index
}

Collection represents a document collection.

func NewCollection

func NewCollection(name string) *Collection

NewCollection creates a new document collection.

Example
package main

import (
	"fmt"

	"github.com/zoobzio/ddml"
)

func main() {
	collection := ddml.NewCollection("orders").
		AddField(ddml.NewField("_id", ddml.TypeObjectID).WithPrimaryKey()).
		AddField(ddml.NewField("customer_id", ddml.TypeString).WithRequired())

	fmt.Println(collection.Name)
	fmt.Println(len(collection.Fields))
}
Output:
orders
2

func (*Collection) AddField

func (c *Collection) AddField(field *Field) *Collection

AddField adds a field to the collection.

func (*Collection) AddIndex

func (c *Collection) AddIndex(index *Index) *Collection

AddIndex adds an index to the collection.

func (*Collection) Generate

func (c *Collection) Generate() string

Generate generates the DDML syntax for a Collection.

func (*Collection) Validate

func (c *Collection) Validate() error

Validate validates a Collection.

func (*Collection) WithNote

func (c *Collection) WithNote(note string) *Collection

WithNote adds a note to the collection.

func (*Collection) WithSetting

func (c *Collection) WithSetting(key, value string) *Collection

WithSetting adds a setting to the collection.

type Enum

type Enum struct {
	Values []string
	Name   string
	Note   *string
}

Enum represents an enumeration type.

func NewEnum

func NewEnum(name string, values ...string) *Enum

NewEnum creates a new enum with the given values.

Example
package main

import (
	"fmt"

	"github.com/zoobzio/ddml"
)

func main() {
	enum := ddml.NewEnum("order_status", "pending", "processing", "shipped", "delivered").
		WithNote("Order status values")

	fmt.Println(enum.Name)
	fmt.Println(len(enum.Values))
}
Output:
order_status
4

func (*Enum) Generate

func (e *Enum) Generate() string

Generate generates the DDML syntax for an Enum.

func (*Enum) Validate

func (e *Enum) Validate() error

Validate validates an Enum.

func (*Enum) WithNote

func (e *Enum) WithNote(note string) *Enum

WithNote adds a note to the enum.

type Field

type Field struct {
	// For nested documents (Type == TypeObject)
	Fields []*Field

	// For arrays (Type == TypeArray)
	ArrayOf *Field

	// For references
	Ref *FieldRef

	Note    *string
	Default *string
	EnumRef *string // For enums (Type == TypeEnum)
	Name    string
	Type    FieldType

	Required   bool
	Unique     bool
	PrimaryKey bool
}

Field represents a document field (recursive for nesting).

func NewArrayField

func NewArrayField(name string, elementType *Field) *Field

NewArrayField creates a new array field with element type.

Example
package main

import (
	"fmt"

	"github.com/zoobzio/ddml"
)

func main() {
	// Simple string array
	tags := ddml.NewArrayField("tags", ddml.NewField("", ddml.TypeString))

	fmt.Println(tags.Name)
	fmt.Println(tags.Type)
	fmt.Println(tags.ArrayOf.Type)
}
Output:
tags
array
string
Example (WithObjects)
package main

import (
	"fmt"

	"github.com/zoobzio/ddml"
)

func main() {
	// Array of nested objects
	items := ddml.NewArrayField("items",
		ddml.NewObjectField("").
			AddField(ddml.NewField("product_id", ddml.TypeString).WithRequired()).
			AddField(ddml.NewField("quantity", ddml.TypeInt).WithRequired()),
	)

	fmt.Println(items.Name)
	fmt.Println(items.ArrayOf.Type)
	fmt.Println(len(items.ArrayOf.Fields))
}
Output:
items
object
2

func NewField

func NewField(name string, fieldType FieldType) *Field

NewField creates a new document field.

Example
package main

import (
	"fmt"

	"github.com/zoobzio/ddml"
)

func main() {
	field := ddml.NewField("email", ddml.TypeString).
		WithRequired().
		WithUnique().
		WithNote("User email address")

	fmt.Println(field.Name)
	fmt.Println(field.Type)
	fmt.Println(field.Required)
}
Output:
email
string
true

func NewObjectField

func NewObjectField(name string) *Field

NewObjectField creates a new nested object field.

Example
package main

import (
	"fmt"

	"github.com/zoobzio/ddml"
)

func main() {
	address := ddml.NewObjectField("address").
		AddField(ddml.NewField("street", ddml.TypeString).WithRequired()).
		AddField(ddml.NewField("city", ddml.TypeString).WithRequired()).
		AddField(ddml.NewField("postal_code", ddml.TypeString))

	fmt.Println(address.Name)
	fmt.Println(address.Type)
	fmt.Println(len(address.Fields))
}
Output:
address
object
3

func (*Field) AddField

func (f *Field) AddField(nested *Field) *Field

AddField adds a nested field (for object types).

func (*Field) Generate

func (f *Field) Generate() string

Generate generates the DDML syntax for a Field.

func (*Field) Validate

func (f *Field) Validate() error

Validate validates a Field recursively.

func (*Field) WithDefault

func (f *Field) WithDefault(value string) *Field

WithDefault sets a default value for the field.

func (*Field) WithEnumRef

func (f *Field) WithEnumRef(enumName string) *Field

WithEnumRef sets the enum reference for an enum field.

func (*Field) WithNote

func (f *Field) WithNote(note string) *Field

WithNote adds a note to the field.

func (*Field) WithPrimaryKey

func (f *Field) WithPrimaryKey() *Field

WithPrimaryKey marks the field as a primary key.

func (*Field) WithRef

func (f *Field) WithRef(collection, field string) *Field

WithRef sets a reference to another collection's field.

func (*Field) WithRequired

func (f *Field) WithRequired() *Field

WithRequired marks the field as required.

func (*Field) WithUnique

func (f *Field) WithUnique() *Field

WithUnique marks the field as unique.

type FieldRef

type FieldRef struct {
	Collection string
	Field      string
}

FieldRef represents a reference to another collection's field.

func (*FieldRef) Validate

func (r *FieldRef) Validate() error

Validate validates a FieldRef.

type FieldType

type FieldType string

FieldType represents the data type of a document field.

const (
	TypeString   FieldType = "string"
	TypeInt      FieldType = "int"
	TypeFloat    FieldType = "float"
	TypeBool     FieldType = "bool"
	TypeDate     FieldType = "date"
	TypeObjectID FieldType = "objectid"
	TypeObject   FieldType = "object"
	TypeArray    FieldType = "array"
	TypeEnum     FieldType = "enum"
	TypeBinary   FieldType = "binary"
	TypeGeoPoint FieldType = "geopoint"
)

Document field types.

type Index

type Index struct {
	Fields []IndexField
	Name   *string
	TTL    *int
	Type   *IndexType
	Unique bool
	Sparse bool
}

Index represents an index definition.

func NewIndex

func NewIndex(fields ...string) *Index

NewIndex creates a new index on the specified fields.

Example
package main

import (
	"fmt"

	"github.com/zoobzio/ddml"
)

func main() {
	idx := ddml.NewIndex("customer_id", "created_at").
		WithName("idx_customer_created").
		WithUnique()

	fmt.Println(len(idx.Fields))
	fmt.Println(idx.Unique)
}
Output:
2
true

func (*Index) Generate

func (i *Index) Generate() string

Generate generates the DDML syntax for an Index.

func (*Index) Validate

func (i *Index) Validate() error

Validate validates an Index.

func (*Index) WithName

func (i *Index) WithName(name string) *Index

WithName sets the index name.

func (*Index) WithOrder

func (i *Index) WithOrder(fieldName string, order IndexOrder) *Index

WithOrder sets the order for a specific field in the index.

func (*Index) WithSparse

func (i *Index) WithSparse() *Index

WithSparse marks the index as sparse.

func (*Index) WithTTL

func (i *Index) WithTTL(seconds int) *Index

WithTTL sets the TTL for the index (in seconds).

func (*Index) WithType

func (i *Index) WithType(indexType IndexType) *Index

WithType sets the index type.

func (*Index) WithUnique

func (i *Index) WithUnique() *Index

WithUnique marks the index as unique.

type IndexField

type IndexField struct {
	Order *IndexOrder
	Name  string
}

IndexField represents a field in an index.

type IndexOrder

type IndexOrder string

IndexOrder represents the sort order of an index field.

const (
	Ascending  IndexOrder = "asc"
	Descending IndexOrder = "desc"
)

Index sort orders.

type IndexType

type IndexType string

IndexType represents the type of index.

const (
	IndexText        IndexType = "text"
	IndexGeo2D       IndexType = "geo2d"
	IndexGeo2DSphere IndexType = "geo2dsphere"
	IndexHashed      IndexType = "hashed"
)

Index types.

type Schema

type Schema struct {
	Collections map[string]*Collection
	Enums       map[string]*Enum
	Name        string
	Note        *string
}

Schema represents a document database schema containing collections and enums.

func NewSchema

func NewSchema(name string) *Schema

NewSchema creates a new document database schema.

Example
package main

import (
	"fmt"

	"github.com/zoobzio/ddml"
)

func main() {
	schema := ddml.NewSchema("ecommerce").
		WithNote("E-commerce document store")

	fmt.Println(schema.Name)
}
Output:
ecommerce

func (*Schema) AddCollection

func (s *Schema) AddCollection(collection *Collection) *Schema

AddCollection adds a collection to the schema.

func (*Schema) AddEnum

func (s *Schema) AddEnum(enum *Enum) *Schema

AddEnum adds an enum to the schema.

func (*Schema) FromJSON

func (s *Schema) FromJSON(data []byte) error

FromJSON populates a Schema from JSON bytes.

func (*Schema) FromYAML

func (s *Schema) FromYAML(data []byte) error

FromYAML populates a Schema from YAML bytes.

func (*Schema) Generate

func (s *Schema) Generate() string

Generate generates the DDML syntax from a Schema.

func (*Schema) ToJSON

func (s *Schema) ToJSON() ([]byte, error)

ToJSON converts a Schema to JSON bytes.

Example
package main

import (
	"fmt"

	"github.com/zoobzio/ddml"
)

func main() {
	schema := ddml.NewSchema("test").
		AddCollection(
			ddml.NewCollection("users").
				AddField(ddml.NewField("_id", ddml.TypeObjectID)),
		)

	data, err := schema.ToJSON()
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	fmt.Println(len(data) > 0)
}
Output:
true

func (*Schema) ToYAML

func (s *Schema) ToYAML() ([]byte, error)

ToYAML converts a Schema to YAML bytes.

func (*Schema) Validate

func (s *Schema) Validate() error

Validate validates a Schema.

Example
package main

import (
	"fmt"

	"github.com/zoobzio/ddml"
)

func main() {
	schema := ddml.NewSchema("test").
		AddCollection(
			ddml.NewCollection("users").
				AddField(ddml.NewField("_id", ddml.TypeObjectID)),
		)

	err := schema.Validate()
	fmt.Println(err == nil)
}
Output:
true

func (*Schema) WithNote

func (s *Schema) WithNote(note string) *Schema

WithNote adds a note to the schema.

type ValidationError

type ValidationError struct {
	Field   string
	Message string
}

ValidationError represents a validation error.

func (*ValidationError) Error

func (e *ValidationError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL