Documentation
¶
Overview ¶
Package mmb – the [qb]MDD Model Builder – provides a wrapper around mdd to create models with a convenient syntax. Yes this encourages “model as code”! This fits well, because code is also a model. I.e. you will end up doing model as code as model as code as model… – you get the idea?
Seriously now: Using a Go library for modeling brings a lot of tool support without much development effort. This library is intentionally not written as a fluent API. For me the hierarchical indentation of the source code according to the model structure had high priority and this cannot be achieved with a fluent API. It is recommended to read the examples to get into it.
Example ¶
var (
types CommonTypes
school, instructor, student ClassRef
)
mdl, err := Model("[qb]MMB Example",
Package("common", &types),
Package("education",
Class("School", Entity,
Attribute("name", &types.Text),
).As(&school),
Class("University", Extends{&school}),
Class("Instructor", Entity,
Attribute("name", &types.Text),
).As(&instructor),
Class("Student", Entity,
Attribute("name", &types.Text),
).As(&student),
Association(
Between(&school).And(Many(1), &instructor, Role("faculty")),
Name("teaches at"),
),
Association(
Between(&school).And(Many(1), &student),
Name("enrolled at"),
),
Association(
Between(Many(1), &instructor, Role("teacher")).And(Many(1), &student),
Name("teaches"),
),
),
)
if err != nil {
fmt.Println(err)
return
}
c := mdl.PackageString("<education>").TypeString("<Student>").(*mdd.Class)
for _, a := range c.AllAttributes() {
fmt.Println(a, a.Derived())
}
for _, a := range c.Associated() {
fmt.Println(a, a.Derived())
}
Output: <name>:<:common::Text:>[1] false <School>:<:education::School:>[1] false <teacher>:<:education::Instructor:>[1..*] false
Index ¶
- Constants
- func Association(a *assocDefn, defn ...assocCmd) *assocDefn
- func Attribute(name string, defn ...AttributeCmd) attrib
- func Between(defn ...aendCmd) between
- func Build(m *mdd.Model, defn ...ModelCmd) error
- func BuildAtom(a *mdd.Atom, defn ...AtomCmd) error
- func BuildClass(c *mdd.Class, defn ...ClassCmd) error
- func BuildEnum(e *mdd.Enum, defn ...EnumCmd) error
- func BuildPackage(pkg *mdd.Package, defn ...PackageCmd) error
- func From(defn ...aendCmd) from
- func IsKey(defn ...keyCmd) skeyDefn
- func Key(defn ...keyCmd) keyDefn
- func Many(n uint, defn ...collCmd) many
- func MixIn(mode mdd.MixMode, classes ...*ClassRef) mix
- func Model(name string, defn ...ModelCmd) (*mdd.Model, error)
- func Mult(min, max uint, defn ...collCmd) mult
- func Num(n uint, defn ...collCmd) num
- func Restict(atoms ...*AtomRef) restrict
- func Tag(key, value any) tag
- type AssocEndRef
- type AtomCmd
- type AtomDefn
- type AtomRef
- type AttributeCmd
- type AttributeRef
- type ClassCmd
- type ClassDefn
- type ClassRef
- type Collection
- type CommonTypes
- type Comparability
- type EnumCmd
- type EnumDefn
- type EnumRef
- type Extends
- type KeyRef
- type Literals
- type ModelCmd
- type Name
- type PackageCmd
- type PackageDefn
- type Role
Examples ¶
Constants ¶
const ( Entity classFlag = iota Abstract )
const ( Equal = Comparability(mdd.Equal) Less = Comparability(mdd.Less) Orders = Comparability(mdd.Orders) )
const ( One multFlag = iota Opt )
const Derived attributeFlag = 0
const Extensible boolExt = true
const Global keyFlag = 1
Variables ¶
This section is empty.
Functions ¶
func Association ¶
func Association(a *assocDefn, defn ...assocCmd) *assocDefn
func Attribute ¶ added in v0.7.0
func Attribute(name string, defn ...AttributeCmd) attrib
func BuildPackage ¶ added in v0.10.0
func BuildPackage(pkg *mdd.Package, defn ...PackageCmd) error
Types ¶
type AssocEndRef ¶ added in v0.12.0
type AtomDefn ¶ added in v0.10.0
type AtomDefn struct {
// contains filtered or unexported fields
}
func Atom ¶ added in v0.8.0
TODO Comparability -> atomDefn
Example ¶
type tagType struct{}
var real AtomRef
mdl, _ := Model("Atom Example",
Package("pkg",
Atom("Bool", Equal, Tag(tagType{}, 4711)),
Atom("Real", Orders).As(&real),
Atom("Integer", Orders, Restict(&real)),
),
)
for _, t := range mdl.PackageString("<pkg>").Atoms() {
fmt.Println(t)
}
Output: A<:pkg::Bool:> A<:pkg::Real:> A<:pkg::Integer:>
type AttributeCmd ¶ added in v0.10.0
type AttributeRef ¶ added in v0.12.0
type ClassDefn ¶ added in v0.10.0
type ClassDefn struct {
// contains filtered or unexported fields
}
func Class ¶
Example ¶
var typ CommonTypes
var part ClassRef // use this to refer to class "Part"
mdl, _ := Model("Class Example",
Package("pkg",
&typ, // we need some basic types
Class("Part",
Attribute("this", &typ.Bool),
Attribute("and", &typ.Date, Opt),
Attribute("that", &typ.Text, Many(1)),
).As(&part),
Class("Composite",
Attribute("id", &typ.NonNegInt),
Attribute("parts", &part, Mult(2, 200)),
),
),
)
for _, c := range mdl.PackageString("<pkg>").Classes() {
fmt.Printf("%s used by %s\n", c, c.Use())
}
Output: C<:pkg::Part:> used by [<parts>:<:pkg::Part:>[2..200]] C<:pkg::Composite:> used by []
type Collection ¶ added in v0.10.0
type Collection int
const ( Unique Collection = (1 + iota) Ordered )
func (Collection) String ¶ added in v0.10.0
func (i Collection) String() string
type CommonTypes ¶ added in v0.10.0
type CommonTypes struct {
// Use this to represent Boolean values
Bool AtomRef
// The integer numbers ℤ
Integer AtomRef
// Natural numbers including zero ℕ∪{0}
NonNegInt AtomRef
// Natural numbers ℕ (according to Peano's original formulation i.e. 0∉ℕ)
PositiveInt AtomRef
// Real numbers ℝ (somewhat hard to completely map to implementations)
Real AtomRef
// The subset of ℝ that can be exactly represented as a decimal numeral
Decimal AtomRef
// Sequence of symbols (most often implemented by a notion of computer
// string)
Text AtomRef
// Denotes a specific day on earth. Its up to you if you consider it to be
// with or without time-zone.
Date AtomRef
// Wall-clock time, independent of any date. Its up to you if you consider
// it to be with or without time-zone.
Time AtomRef
// A precise instant in time. Its up to you if you consider it to be with
// or without time-zone.
Timestamp AtomRef
}
CommonTypes provides references to a set of useful types that can be used in many models. Before using an of the field types it has to be initialized in a package.
Example ¶
var types CommonTypes
Model("Common Types Example", Package("pkg", &types))
fmt.Println(types.Bool.Type())
fmt.Println(types.Text.Type())
fmt.Println(types.Timestamp.Type())
Output: A<:pkg::Boolean:> A<:pkg::Text:> A<:pkg::Timestamp:>
type Comparability ¶ added in v0.10.0
type Comparability mdd.Comparability
func (Comparability) String ¶ added in v0.10.0
func (c Comparability) String() string
type EnumDefn ¶ added in v0.10.0
type EnumDefn struct {
// contains filtered or unexported fields
}
func Enum ¶
Example ¶
mdl, _ := Model("Enum Example",
Package("pkg",
Enum("Colors", Literals{"RED", "GREEN", "BLUE"}),
Enum("Metasyntactical Variables", Literals{"foo", "bar", "baz"}, Orders, Extensible),
),
)
for _, t := range mdl.PackageString("<pkg>").Enums() {
fmt.Println(t)
}
Output: E<:pkg::Colors:> E<:pkg::Metasyntactical Variables:>
type Extends ¶ added in v0.10.0
type Extends []*ClassRef
Example ¶
var typ CommonTypes
var base, derived ClassRef
Model("Extends Example",
Package("pkg",
&typ,
Class("Base", Attribute("a", &typ.Integer)).As(&base),
Class("Derived", Extends{&base},
Attribute("b", &typ.Text),
).As(&derived),
),
)
fmt.Print(base.Type(), ":")
for _, a := range base.Type().AllAttributes() {
fmt.Printf(" %s", a)
}
fmt.Print("\n", derived.Type(), ":")
for _, a := range derived.Type().Attributes() {
fmt.Printf(" %s", a)
}
fmt.Print("\n", derived.Type(), ":")
for _, a := range derived.Type().AllAttributes() {
fmt.Printf(" %s", a)
}
Output: C<:pkg::Base:>: <a>:<:pkg::Integer:>[1] C<:pkg::Derived:>: <b>:<:pkg::Text:>[1] C<:pkg::Derived:>: <a>:<:pkg::Integer:>[1] <b>:<:pkg::Text:>[1]
Example (MultipleInheritance) ¶
var typ CommonTypes
var base1, base2, derived ClassRef
_, err := Model("Extends Example",
Package("pkg",
&typ,
Class("Base 1", Attribute("b", &typ.Integer, Many(0))).As(&base1),
Class("Base 2", Attribute("b", &typ.Real, Opt)).As(&base2),
Class("Derived", Extends{&base1, &base2},
Attribute("d", &typ.Text),
).As(&derived),
),
)
if err != nil {
fmt.Println(err)
return
}
for _, a := range derived.Type().AllAttributes() {
fmt.Println(a)
}
Output: <b>:<:pkg::Integer:>[0..1] <d>:<:pkg::Text:>[1]
type PackageCmd ¶ added in v0.10.0
type PackageDefn ¶ added in v0.10.0
type PackageDefn struct {
// contains filtered or unexported fields
}
func Package ¶
func Package(name string, defn ...PackageCmd) PackageDefn
func (PackageDefn) As ¶ added in v0.11.0
func (p PackageDefn) As(in **mdd.Package) PackageDefn