github.com/goadesign/gorma/dsl
dsl
import "github.com/goadesign/gorma/dsl"
Overview
Package dsl uses the Goa DSL engine to generate a data storage layer for your Goa API.
Using a few DSL definitions you can extend the Goa API to include database persistence.
An example:
var sg = StorageGroup("MyStorageGroup", func() {
Description("This is the global storage group")
Store("mysql", gorma.MySQL, func() {
Description("This is the mysql relational store")
Model("Bottle", func() {
BuildsFrom(func() {
Payload("myresource","actionname") // e.g. "bottle", "create" resource definition
})
RendersTo(Bottle) // a Media Type definition
Description("This is the bottle model")
Field("ID", gorma.Integer, func() { // redundant
PrimaryKey()
Description("This is the ID PK field")
})
Field("Vintage", gorma.Integer, func() {
SQLTag("index") // Add an index
})
Field("CreatedAt", gorma.Timestamp)
Field("UpdatedAt", gorma.Timestamp) // Shown for demonstration
Field("DeletedAt", gorma.NullableTimestamp) // These are added by default
})
})
})
Gorma uses Gorm (https://github.com/jinzhu/gorm) for database access. Gorm was chosen as the best of the ‘light-ORM’ libraries available for Go. It does the mundane work and allows you to do anything manually if you choose.
The base Gorma definition is a StorageGroup
which represents all the storage needs for an
application. A StorageGroup will contain one or more Store
, which represends a database or
other persistence mechanism. Gorma supports all the databases that Gorm supports, and
it is possible in the future to support others – like Key/Value stores.
Every Store
will have one or more Model
s which maps a Go structure to a table in the database.
Use the BuildsFrom
and RendersTo
DSL to build generated functions to convert the model to Media
Type definitions and from User Type definitions.
A Model
will contain one or more fields. Gorma will use the BuildsFrom
definition to populate
a base set of fields. Custom DSL is provided to add additional fields:
Each table will likely want a primary key. Gorma automatically adds one to your table called “ID” if there isn’t one already. Gorma supports Integer primary keys currently, but support for UUID and string primary keys is in the plan for the future. [github](https://github.com/goadesign/gorma/issues/57)
In the event that the BuildsFrom
types don’t contain all the fields that you want to include in your
model, you can add extra fields using the Field
DSL:
Field("foo", gorma.String, func() {
Description("This is the foo field")
})
You can also specify modifications to fields that you know will be inherited from the BuildsFrom
DSL. For
example if the type specified in BuildsFrom
contains a field called Author
and you want to ensure that
it gets indexed, you can specify the field explicitly and add a SQLTag
declaration:
Field("author", gorma.String, func() {
SQLTag("index")
})
In general the only time you need to declare fields explicitly is if you want to modify the type or attributes
of the fields that are inherited from the BuildsFrom
type, or if you want to add extra fields not included
in the BuildsFrom
types.
You may specify more than one BuildsFrom
type.
You can control naming between the BuildsFrom
and RendersTo
models by using the MapsTo
and MapsFrom
DSL:
Field("Title", func(){
MapsFrom(UserPayload, "position")
})
This creates a field in the Gorma model called “Title”, which is populated from the “position” field in the UserPayload.
The MapsTo
DSL can be used similarly to change output field mapping to Media Types.
Gorma generates all the helpers you need to translate to and from the Goa types (media types and payloads). This makes wiring up your Goa controllers almost too easy to be considered programming.
Index
- func Alias(d string)
- func BelongsTo(parent string)
- func BuildsFrom(dsl func())
- func Cached(d string)
- func DatabaseFieldName(name string)
- func Description(d string)
- func DynamicTableName()
- func Field(name string, args …interface{})
- func HasMany(name, child string)
- func HasOne(child string)
- func ManyToMany(other, tablename string)
- func MapsFrom(utd *design.UserTypeDefinition, field string)
- func MapsTo(mtd *design.MediaTypeDefinition, field string)
- func Model(name string, dsl func())
- func NoAutomaticIDFields()
- func NoAutomaticSoftDelete()
- func NoAutomaticTimestamps()
- func Nullable()
- func Payload(r interface{}, act string)
- func PrimaryKey()
- func RendersTo(rt interface{})
- func Roler()
- func SQLTag(d string)
- func SanitizeDBFieldName(name string) string
- func SanitizeFieldName(name string) string
- func StorageGroup(name string, dsli func()) *gorma.StorageGroupDefinition
- func Store(name string, storeType gorma.RelationalStorageType, dsl func())
Package files
doc.go relationalfield.go relationalmodel.go relationalstore.go runner.go storagegroup.go
func Alias
func Alias(d string)
Alias overrides the name of the SQL store’s table or field.
func BelongsTo
func BelongsTo(parent string)
BelongsTo signifies a relationship between this model and a Parent. The Parent has the child, and the Child belongs to the Parent.
Usage: BelongsTo(“User”)
func BuildsFrom
func BuildsFrom(dsl func())
BuildsFrom informs Gorma that this model will be populated from a Goa UserType. Conversion functions will be generated to convert from the payload to the model.
Usage: BuildsFrom(YourType)
Fields not in YourType
that you want in your model must be
added explicitly with the Field
DSL.
func Cached
func Cached(d string)
Cached caches the models for duration
seconds.
Not fully implemented yet, and not guaranteed to stay
in Gorma long-term because of the complex rendering
that happens in the conversion functions.
func DatabaseFieldName
func DatabaseFieldName(name string)
DatabaseFieldName allows for customization of the column name by seting the struct tags. This is necessary to create correlate non standard column naming conventions in gorm.
func Description
func Description(d string)
Description sets the definition description. Description can be called inside StorageGroup, RelationalStore, RelationalModel, RelationalField
func DynamicTableName
func DynamicTableName()
DynamicTableName sets a boolean flag that causes the generator to generate function definitions in the database models that specify the name of the database table. Useful when using multiple tables with different names but same schema e.g. Users, AdminUsers.
func Field
func Field(name string, args ...interface{})
Field is a DSL definition for a field in a Relational Model. Parameter Options:
// A field called "Title" with default type `String`.
Field("Title")
// Explicitly specify the type.
Field("Title", gorma.String)
// "Title" field, as `String` with other DSL included.
Field("Title", func(){... other field level dsl ...})
// All options specified: name, type and dsl.
Field("Title", gorma.String, func(){... other field level dsl ...})
func HasMany
func HasMany(name, child string)
HasMany signifies a relationship between this model and a set of Children. The Parent has the children, and the Children belong to the Parent. The first parameter becomes the name of the field in the model struct, the second parameter is the name of the child model. The Child model will have a ParentID field appended to the field list. The Parent model definition will use the first parameter as the field name in the struct definition.
Usage: HasMany(“Orders”, “Order”)
Generated struct field definition: Children []Child
func HasOne
func HasOne(child string)
HasOne signifies a relationship between this model and another model. If this model HasOne(OtherModel), then OtherModel is expected to have a ThisModelID field as a Foreign Key to this model’s Primary Key. ThisModel will have a field named OtherModel of type OtherModel.
Usage: HasOne(“Proposal”)
func ManyToMany
func ManyToMany(other, tablename string)
ManyToMany creates a join table to store the intersection relationship between this model and another model. For example, in retail an Order can contain many products, and a product can belong to many orders. To express this relationship use the following syntax:
Model("Order", func(){
ManyToMany("Product", "order_lines")
})
This specifies that the Order and Product tables have a “junction” table
called order_lines
that contains the order and product information.
The generated model will have a field called Products
that will
be an array of type Product
.
func MapsFrom
func MapsFrom(utd *design.UserTypeDefinition, field string)
MapsFrom establishes a mapping relationship between a source Type field and this model. The source type must be a UserTypeDefinition “Type” in goa. These are typically Payloads.
func MapsTo
func MapsTo(mtd *design.MediaTypeDefinition, field string)
MapsTo establishes a mapping relationship between a field in model and a MediaType in goa.
func Model
func Model(name string, dsl func())
Model is the DSL that represents a Relational Model.
Model name should be Title cased. Use BuildsFrom() and RendersTo() DSL
to define the mapping between a Model and a Goa Type.
Models may contain multiple instances of the Field
DSL to
add fields to the model.
To control whether the ID field is auto-generated, use NoAutomaticIDFields()
Similarly, use NoAutomaticTimestamps() and NoAutomaticSoftDelete() to
prevent CreatedAt, UpdatedAt and DeletedAt fields from being created.
func NoAutomaticIDFields
func NoAutomaticIDFields()
NoAutomaticIDFields applies to a Store
or Model
type. It allows you
to turn off the default behavior that will automatically create
an ID/int Primary Key for each model.
func NoAutomaticSoftDelete
func NoAutomaticSoftDelete()
NoAutomaticSoftDelete applies to a Store
or Model
type. It allows
you to turn off the default behavior that will automatically
create a DeletedAt
field (*time.Time) that acts as a
soft-delete filter for your models.
func NoAutomaticTimestamps
func NoAutomaticTimestamps()
NoAutomaticTimestamps applies to a Store
or Model
type. It allows you
to turn off the default behavior that will automatically create
an CreatedAt
and UpdatedAt
fields for each model.
func Nullable
func Nullable()
Nullable sets the fields nullability A Nullable field will be stored as a pointer. A field that is not Nullable won’t be stored as a pointer.
func Payload
func Payload(r interface{}, act string)
Payload specifies the Resource and Action containing a User Type (Payload). Gorma will generate a conversion function for the Payload to the Model.
func PrimaryKey
func PrimaryKey()
PrimaryKey establishes a field as a Primary Key by
seting the struct tags necessary to create the PK in gorm.
Valid only for Integer
datatypes currently
func RendersTo
func RendersTo(rt interface{})
RendersTo informs Gorma that this model will need to be rendered to a Goa type. Conversion functions will be generated to convert to/from the model.
Usage: RendersTo(MediaType)
func Roler
func Roler()
Roler sets a boolean flag that cause the generation of a Role() function that returns the model’s Role value Creates a “Role” field in the table if it doesn’t already exist as a string type
func SQLTag
func SQLTag(d string)
SQLTag sets the model’s struct tag sql
value
for indexing and other purposes.
func SanitizeDBFieldName
func SanitizeDBFieldName(name string) string
SanitizeDBFieldName is exported for testing purposes
func SanitizeFieldName
func SanitizeFieldName(name string) string
SanitizeFieldName is exported for testing purposes
func StorageGroup
func StorageGroup(name string, dsli func()) *gorma.StorageGroupDefinition
StorageGroup implements the top level Gorma DSL There should be one StorageGroup per Goa application.
func Store
func Store(name string, storeType gorma.RelationalStorageType, dsl func())
Store represents a database. Gorma lets you specify a database type, but it’s currently not used for any generation logic.
Generated by godoc2md