Documentation
¶
Overview ¶
Package db works with the rest of the orm to interface between a database and the ORM abstraction of reading and querying a database. It is architected so that both SQL and NoSQL databases can be used with the abstraction. This allows you to potentially write code that is completely agnostic to what kind of database you are using. Even if 100% portability is not achievable in your use case, the ORM and database abstraction layers should be able to handle most of your needs, such that if you ever did have to port to a different database, it would minimize the amount of custom code you would need to write.
Generally, SQL and NoSQL databases work very differently. However, many SQL databases have recently added NoSQL capabilities, like storing and searching JSON text. Similarly, NoSQL databases have added features to enable searching a database through relationships, similar to SQL capabilities. In addition, NoSQL design advice is often to flatten the database structure as much as possible, so that it looks a whole lot like a SQL database.
The general approach Goradd takes is to generally describe data with key/value pairs. This fits in well with SQL, as key/value pairs are just table-column/field pairs. NoSQL generally works with key-value pairs anyways.
Relationships between structures are described as relationships, either one-to-many, or many-to-many. By keeping the description at a higher level, we allow databases to implement those relationships in the way that works best.
SQL implements one-to-many relationships using foreign keys. In the data description, you will see a Reference type of relationship, which points from the many to the one, and a ReverseRelationship, which is a kind of virtual representation of pointing from the one side to the many. ReverseRelationship lists are populated at the time of a query. In SQL, Many-to-many relationships use an intermediate table, called an Association Table, that has foreign keys pointing in both directions.
NoSQL implements one-to-many relationships using foreign-keys as well, but both sides of the relationship store the foreign key, or keys, that point to the other side. This means that a ReverseRelationship will represent an actual field in the database structure that contains a list of all of the items pointing back at itself. This also means that when these relationships are created or destroyed, both sides of the relationship need to be updated. Similarly, NoSQL many-to-many relationships have lists of foreign keys stored on both sides of the relationship.
The other major difference between SQL and NoSQL databases is the built-in capabilities to do aggregate calculations. In SQL, you generally can create a filtered list of records and ask SQL to sum all the values from a particular field. Some NoSQL databases can do this, and some cannot. The ones that cannot expect the programmer to do their own filtering and summing. GoRADD handles this difference by allowing individual GORADD database drivers to be written that add some aggregate capabilities to a database, and also providing ways for individual developers to simply create their own custom queries that will be non-portable between databases. In any case, there is always a way to do what you want to do, just some databases are easier to work with. It depends what you want to do.
Index ¶
- func AddDatabase(d DatabaseI, key string)
- func ExecuteTransaction(ctx context.Context, d DatabaseI, f func())
- func LowerCaseIdentifier(s string) (i string)
- func Nodes(b QueryBuilder) []NodeI
- func UpperCaseIdentifier(s string) (i string)
- type AliasNodesType
- type Column
- func (cd *Column) ConvertFromString(varName string) string
- func (cd *Column) DefaultConstantName(tableName string) string
- func (cd *Column) DefaultValueAsConstant() string
- func (cd *Column) DefaultValueAsValue() string
- func (cd *Column) GoType() string
- func (cd *Column) IsReference() bool
- func (cd *Column) IsType() bool
- func (cd *Column) JsonKey() string
- func (cd *Column) ModelName() string
- func (cd *Column) ReferenceFunction() string
- func (cd *Column) ReferenceJsonKey(dd *Database) string
- func (cd *Column) ReferenceName() string
- type ColumnDescription
- type Copier
- type Database
- type DatabaseDescription
- type DatabaseI
- type DatabaseIGetter
- type DatabaseILoader
- type DatabaseIMapI
- type DatabaseISetter
- type DatabaseISliceMap
- func (o *DatabaseISliceMap) Clear()
- func (o *DatabaseISliceMap) Copy() *DatabaseISliceMap
- func (o *DatabaseISliceMap) Delete(key string)
- func (o *DatabaseISliceMap) Equals(i DatabaseIMapI) bool
- func (o *DatabaseISliceMap) Get(key string) (val DatabaseI)
- func (o *DatabaseISliceMap) GetAt(position int) (val DatabaseI)
- func (o *DatabaseISliceMap) GetKeyAt(position int) (key string)
- func (o *DatabaseISliceMap) Has(key string) (ok bool)
- func (o *DatabaseISliceMap) IsNil() bool
- func (o *DatabaseISliceMap) Keys() (keys []string)
- func (o *DatabaseISliceMap) Len() int
- func (o *DatabaseISliceMap) Load(key string) (val DatabaseI, ok bool)
- func (o *DatabaseISliceMap) MarshalBinary() (data []byte, err error)
- func (o *DatabaseISliceMap) MarshalJSON() (data []byte, err error)
- func (o *DatabaseISliceMap) Merge(i DatabaseIMapI)
- func (o *DatabaseISliceMap) MergeMap(m map[string]DatabaseI)
- func (o *DatabaseISliceMap) Range(f func(key string, value DatabaseI) bool)
- func (o *DatabaseISliceMap) Set(key string, val DatabaseI)
- func (o *DatabaseISliceMap) SetAt(index int, key string, val DatabaseI)
- func (o *DatabaseISliceMap) SetSortFunc(f func(key1, key2 string, val1, val2 DatabaseI) bool) *DatabaseISliceMap
- func (o *DatabaseISliceMap) SortByKeys() *DatabaseISliceMap
- func (o *DatabaseISliceMap) String() string
- func (o *DatabaseISliceMap) UnmarshalBinary(data []byte) (err error)
- func (o *DatabaseISliceMap) UnmarshalJSON(data []byte) (err error)
- func (o *DatabaseISliceMap) Values() (vals []DatabaseI)
- type FKAction
- type ForeignKeyDescription
- type ForeignKeyInfo
- type Index
- type IndexDescription
- type LimitInfo
- type ManyManyDescription
- type ManyManyReference
- type QueryBuilder
- func (b *QueryBuilder) Alias(name string, n NodeI)
- func (b *QueryBuilder) Condition(c NodeI)
- func (b *QueryBuilder) Context() context.Context
- func (b *QueryBuilder) Count(_ bool, _ ...NodeI) uint
- func (b *QueryBuilder) Delete()
- func (b *QueryBuilder) Distinct()
- func (b *QueryBuilder) Expand(n NodeI)
- func (b *QueryBuilder) GroupBy(nodes ...NodeI)
- func (b *QueryBuilder) Having(node NodeI)
- func (b *QueryBuilder) Init(ctx context.Context)
- func (b *QueryBuilder) Join(n NodeI, condition NodeI)
- func (b *QueryBuilder) Limit(maxRowCount int, offset int)
- func (b *QueryBuilder) Load() []map[string]interface{}
- func (b *QueryBuilder) LoadCursor() CursorI
- func (b *QueryBuilder) OrderBy(nodes ...NodeI)
- func (b *QueryBuilder) Select(nodes ...NodeI)
- func (b *QueryBuilder) Subquery() *SubqueryNode
- type QueryExport
- type ReverseReference
- func (r *ReverseReference) AssociatedGoName() string
- func (r *ReverseReference) AssociatedPkType() string
- func (r *ReverseReference) AssociatedTableName() string
- func (r *ReverseReference) IsNullable() bool
- func (r *ReverseReference) IsUnique() bool
- func (r *ReverseReference) JsonKey(dd *Database) string
- type Table
- type TableDescription
- type TransactionID
- type TypeTable
- type ValueMap
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AddDatabase ¶
AddDatabase adds a database to the global database store. Only call this during app startup.
func ExecuteTransaction ¶ added in v0.9.0
ExecuteTransaction wraps the function in a database transaction
func LowerCaseIdentifier ¶ added in v0.1.1
func Nodes ¶ added in v0.19.0
func Nodes(b QueryBuilder) []NodeI
Nodes is used by the build process to return the nodes referred to in the query. Some nodes will be container nodes, and so will have nodes inside them, but every node is either referred to, or contained in the returned nodes. Only query builders normally need to call this.
func UpperCaseIdentifier ¶ added in v0.1.1
Types ¶
type AliasNodesType ¶ added in v0.19.1
type Column ¶ added in v0.6.0
type Column struct {
// DbName is the name of the column in the database. This is blank if this is a "virtual" table for sql tables like an association or virtual attribute query.
DbName string
// GoName is the name of the column in go code
GoName string
// NativeType is the type of the column as described by the database itself.
NativeType string
// ColumnType is the goradd defined column type
ColumnType GoColumnType
// MaxCharLength is the maximum length of characters to allow in the column if a string type column.
// If the database has the ability to specify this, this will correspond to what is specified.
// In any case, we will generate code to prevent fields from getting bigger than this.
MaxCharLength uint64
// DefaultValue is the default value as specified by the database. We will initialize new ORM objects
// with this value. Call DefaultValueAsValue
DefaultValue interface{}
// MaxValue is the maximum value allowed for numeric values. This can be used by UI objects to tell the user what the limits are.
MaxValue interface{}
// MinValue is the minimum value allowed for numeric values. This can be used by UI objects to tell the user what the limits are.
MinValue interface{}
// IsId is true if this column represents a unique identifier generated by the database
IsId bool
// IsPk is true if this is the primary key column. PK's do not necessarily need to be ID columns, and if not, we will need to do our own work to generate unique PKs.
IsPk bool
// IsNullable is true if the column can be given a NULL value
IsNullable bool
// IsUnique is true if the column's table has a single unique index on the column.
IsUnique bool
// IsTimestamp is true if the field is a timestamp. Timestamps represent a specific point in world time.
IsTimestamp bool
// IsAutoUpdateTimestamp is true if the database is updating the timestamp. Otherwise we will do it manually.
IsAutoUpdateTimestamp bool
// IsDateOnly indicates that we have a datetime type of column that should only be concerned about the date
IsDateOnly bool
// IsTimeOnly indicates that we have a datetime type of column that should only be concerned about the time
IsTimeOnly bool
// Comment is the contents of the comment associated with this field
Comment string
// Filled in by analyzer
// Options are the options extracted from the comments string
Options map[string]interface{}
// ForeignKey is additional information describing a foreign key relationship
ForeignKey *ForeignKeyInfo
// contains filtered or unexported fields
}
Column describes a database column. Most of the information is either gleaned from the structure of the database, or is taken from a file that describes the relationships between different record types. Some of the information is filled in after analysis. Some of the information can be provided through information embedded in database comments.
func (*Column) ConvertFromString ¶ added in v0.7.0
ConvertFromString will return code that will convert the given varName, which should be a string type, to the type of this column.
This is incomplete, and can be built out more if needed
func (*Column) DefaultConstantName ¶ added in v0.6.0
DefaultConstantName returns the name of the default value constant that will be used to refer to the default value
func (*Column) DefaultValueAsConstant ¶ added in v0.6.0
DefaultValueAsConstant returns the default value of the column as a Go constant
func (*Column) DefaultValueAsValue ¶ added in v0.6.0
DefaultValueAsValue returns the default value of the column as a GO value
func (*Column) GoType ¶ added in v0.11.2
GoType returns the Go variable type corresponding to the column.
func (*Column) IsReference ¶ added in v0.6.0
IsReference returns true if the column is a reference to an object in another table.
func (*Column) IsType ¶ added in v0.9.0
IsType returns true if the column contains a type defined by a type table.
func (*Column) JsonKey ¶ added in v0.6.0
JsonKey returns the key used for the column when outputting JSON.
func (*Column) ReferenceFunction ¶ added in v0.6.0
ReferenceFunction returns the function name that should be used to refer to the object that is referred to by a forward reference. It is extracted from the name of foreign key.
func (*Column) ReferenceJsonKey ¶ added in v0.6.0
ReferenceJsonKey returns the key that will be used for the referenced object in JSON.
func (*Column) ReferenceName ¶ added in v0.9.0
ReferenceName returns the name of the referenced object if this is a forward reference.
type ColumnDescription ¶
type ColumnDescription struct {
// Name is the name of the column in the database. This is blank if this is a "virtual" table for sql tables like an association or virtual attribute query.
Name string
// GoName is the name of the column in go code
GoName string
// NativeType is the type of the column as described by the database itself.
NativeType string
// GoType is the goradd defined column type
GoType string
// SubType has additional information to the type of column that can help control code generation
// When column type is "time.Time", the column will default to both a date and time format. You can also make it:
// date (which means date only)
// time (time only)
// timestamp (we will track the modification time of the table here)
// auto timestamp (the database is automatically updating this timestamp for us)
SubType string
// MaxCharLength is the maximum length of characters to allow in the column if a string type column.
// If the database has the ability to specify this, this will correspond to what is specified.
// In any case, we will generate code to prevent fields from getting bigger than this. Zero indicates there is
// no length checking or limiting.
MaxCharLength uint64
// DefaultValue is the default value as specified by the database. We will initialize new ORM objects
// with this value. It will be cast to the corresponding GO type.
DefaultValue interface{}
// MaxValue is the maximum value allowed for numeric values. This can be used by UI objects to tell the user what the limits are.
MaxValue interface{}
// MinValue is the minimum value allowed for numeric values. This can be used by UI objects to tell the user what the limits are.
MinValue interface{}
// IsId is true if this column represents a unique identifier generated by the database
IsId bool
// IsPk is true if this is the primary key column. PK's do not necessarily need to be ID columns, and if not, we will need to do our own work to generate unique PKs.
IsPk bool
// IsNullable is true if the column can be given a NULL value
IsNullable bool
// IsUnique indicates that the field holds unique values
IsUnique bool
// ForeignKey is additional information describing a foreign key relationship
ForeignKey *ForeignKeyDescription
// Comment is the contents of the comment associated with this column
Comment string
// Options are key-value settings that can be used to further describe code generation
Options map[string]interface{}
}
type Copier ¶
type Copier interface {
Copy() interface{}
}
Copier implements the copy interface, that returns a deep copy of an object.
type Database ¶ added in v0.6.0
type Database struct {
// The database key corresponding to its key in the global database cluster
DbKey string
// Tables are the tables in the database
Tables []*Table
// TypeTables contains a description of the enumerated types from the type tables in the database
TypeTables []*TypeTable
// AssociatedObjectPrefix is a prefix placed in front of generated object names. Defaults to "o".
AssociatedObjectPrefix string
// Text to strip off the end of foreign key references when converting to names. Defaults to "_id"
ForeignKeySuffix string
// contains filtered or unexported fields
}
The Database is the top level struct that contains a complete description of a database for purposes of creating queries and doing code generation
func NewDatabase ¶ added in v0.6.0
func NewDatabase(dbKey string, foreignKeySuffix string, desc DatabaseDescription) *Database
NewDatabase creates a new Database object from the given DatabaseDescription object.
func (*Database) IsTypeTable ¶ added in v0.6.0
IsTypeTable returns true if the given name is the name of a type table in the database
type DatabaseDescription ¶
type DatabaseDescription struct {
// The database key corresponding to its key in the global database cluster
Key string
// Tables are the tables in the database
Tables []TableDescription
// MM are the many-to-many links between tables. In SQL databases, these are actual tables,
// but in NoSQL, they become array fields on either side of the relationship.
MM []ManyManyDescription
// The prefix for related objects.
AssociatedObjectPrefix string
}
type DatabaseI ¶
type DatabaseI interface {
// Describe returns a Database object, which is a description of the tables and fields in
// a database and their relationships. SQL databases can, for the most part, generate this description
// based on their structure. NoSQL databases would need to get this description some other way, like through
// a json file.
Describe() *Database
// AssociatedObjectPrefix is a prefix we add to all variables that point to ORM objects. By default this is an "o".
AssociatedObjectPrefix() string
// NewBuilder returns a newly created query builder
NewBuilder(ctx context.Context) QueryBuilderI
// Update will put the given values into a record that already exists in the database. The "fields" value
// should include only fields that have changed.
Update(ctx context.Context, table string, fields map[string]interface{}, pkName string, pkValue interface{})
// Insert will insert a new record into the database with the given values, and return the new record's primary key value.
// The fields value should include all the required values in the database.
Insert(ctx context.Context, table string, fields map[string]interface{}) string
// Delete will delete the given record from the database
Delete(ctx context.Context, table string, pkName string, pkValue interface{})
// Associate sets a many-many relationship to the given values.
// The values are taken from the ORM, and are treated differently depending on whether this is a SQL or NoSQL database.
Associate(ctx context.Context,
table string,
column string,
pk interface{},
relatedTable string,
relatedColumn string,
relatedPks interface{})
// Begin will begin a transaction in the database and return the transaction id
Begin(ctx context.Context) TransactionID
// Commit will commit the given transaction
Commit(ctx context.Context, txid TransactionID)
// Rollback will roll back the given transaction PROVIDED it has not been committed. If it has been
// committed, it will do nothing. Rollback can therefore be used in a defer statement as a safeguard in case
// a transaction fails.
Rollback(ctx context.Context, txid TransactionID)
// PutContext is called early in the processing of a response to insert an empty context that the database can use if needed.
PutBlankContext(ctx context.Context) context.Context
}
DatabaseI is the interface that describes the behaviors required for a database implementation.
func GetDatabase ¶
GetDatabase returns the database given the database's key.
func GetDatabases ¶
func GetDatabases() []DatabaseI
GetDatabases returns all databases in the datastore
type DatabaseIGetter ¶ added in v0.0.9
type DatabaseILoader ¶ added in v0.0.9
type DatabaseIMapI ¶ added in v0.0.9
type DatabaseIMapI interface {
Get(key string) (val DatabaseI)
Has(key string) (exists bool)
Values() []DatabaseI
Keys() []string
Len() int
// Range will iterate over the keys and values in the map. Pattern is taken from sync.Map
Range(f func(key string, value DatabaseI) bool)
Merge(i DatabaseIMapI)
String() string
}
The DatabaseIMapI interface provides a common interface to the many kinds of similar map objects.
Most functions that change the map are omitted so that you can wrap the map in additional functionality that might use Set or SetChanged. If you want to use them in an interface setting, you can create your own interface that includes them.
type DatabaseISetter ¶ added in v0.0.9
type DatabaseISliceMap ¶ added in v0.0.9
type DatabaseISliceMap struct {
// contains filtered or unexported fields
}
A DatabaseISliceMap combines a map with a slice so that you can range over a map in a predictable order. By default, the order will be the same order that items were inserted, i.e. a FIFO list. This is similar to how PHP arrays work. DatabaseISliceMap implements the sort interface so you can change the order before ranging over the values if desired. It is NOT safe for concurrent use. The zero of this is usable immediately. The DatabaseISliceMap satisfies the DatabaseIMapI interface.
func NewDatabaseISliceMap ¶ added in v0.0.9
func NewDatabaseISliceMap() *DatabaseISliceMap
NewDatabaseISliceMap creates a new map that maps string's to DatabaseI's.
func NewDatabaseISliceMapFrom ¶ added in v0.0.9
func NewDatabaseISliceMapFrom(i DatabaseIMapI) *DatabaseISliceMap
NewDatabaseISliceMapFrom creates a new DatabaseIMap from a DatabaseIMapI interface object
func NewDatabaseISliceMapFromMap ¶ added in v0.0.9
func NewDatabaseISliceMapFromMap(i map[string]DatabaseI) *DatabaseISliceMap
NewDatabaseISliceMapFromMap creates a new DatabaseISliceMap from a GO map[string]DatabaseI object. Note that this will pass control of the given map to the new object. After you do this, DO NOT change the original map.
func (*DatabaseISliceMap) Clear ¶ added in v0.0.9
func (o *DatabaseISliceMap) Clear()
func (*DatabaseISliceMap) Copy ¶ added in v0.0.9
func (o *DatabaseISliceMap) Copy() *DatabaseISliceMap
Copy will make a copy of the map and a copy of the underlying data.
func (*DatabaseISliceMap) Delete ¶ added in v0.0.9
func (o *DatabaseISliceMap) Delete(key string)
Delete removes the item with the given key.
func (*DatabaseISliceMap) Equals ¶ added in v0.0.9
func (o *DatabaseISliceMap) Equals(i DatabaseIMapI) bool
Equals returns true if the map equals the given map, paying attention only to the content of the map and not the order.
func (*DatabaseISliceMap) Get ¶ added in v0.0.9
func (o *DatabaseISliceMap) Get(key string) (val DatabaseI)
Get returns the value based on its key. If the key does not exist, an empty value is returned.
func (*DatabaseISliceMap) GetAt ¶ added in v0.0.9
func (o *DatabaseISliceMap) GetAt(position int) (val DatabaseI)
GetAt returns the value based on its position. If the position is out of bounds, an empty value is returned.
func (*DatabaseISliceMap) GetKeyAt ¶ added in v0.0.9
func (o *DatabaseISliceMap) GetKeyAt(position int) (key string)
GetKeyAt returns the key based on its position. If the position is out of bounds, an empty value is returned.
func (*DatabaseISliceMap) Has ¶ added in v0.0.9
func (o *DatabaseISliceMap) Has(key string) (ok bool)
Has returns true if the given key exists in the map.
func (*DatabaseISliceMap) IsNil ¶ added in v0.0.9
func (o *DatabaseISliceMap) IsNil() bool
func (*DatabaseISliceMap) Keys ¶ added in v0.0.9
func (o *DatabaseISliceMap) Keys() (keys []string)
Keys returns the keys of the map, in the order they were added or sorted
func (*DatabaseISliceMap) Len ¶ added in v0.0.9
func (o *DatabaseISliceMap) Len() int
Len returns the number of items in the map
func (*DatabaseISliceMap) Load ¶ added in v0.0.9
func (o *DatabaseISliceMap) Load(key string) (val DatabaseI, ok bool)
Load returns the value based on its key, and a boolean indicating whether it exists in the map. This is the same interface as sync.StdMap.Load()
func (*DatabaseISliceMap) MarshalBinary ¶ added in v0.0.9
func (o *DatabaseISliceMap) MarshalBinary() (data []byte, err error)
MarshalBinary implements the BinaryMarshaler interface to convert the map to a byte stream. If you are using a sort function, you must save and restore the sort function in a separate operation since functions are not serializable.
func (*DatabaseISliceMap) MarshalJSON ¶ added in v0.0.9
func (o *DatabaseISliceMap) MarshalJSON() (data []byte, err error)
MarshalJSON implements the json.Marshaler interface to convert the map into a JSON object.
func (*DatabaseISliceMap) Merge ¶ added in v0.0.9
func (o *DatabaseISliceMap) Merge(i DatabaseIMapI)
Merge the given map into the current one
func (*DatabaseISliceMap) MergeMap ¶ added in v0.19.0
func (o *DatabaseISliceMap) MergeMap(m map[string]DatabaseI)
MergeMap merges the given standard map with the current one. The given one takes precedent on collisions.
func (*DatabaseISliceMap) Range ¶ added in v0.0.9
func (o *DatabaseISliceMap) Range(f func(key string, value DatabaseI) bool)
Range will call the given function with every key and value in the order they were placed in the map, or in if you sorted the map, in your custom order. If f returns false, it stops the iteration. This pattern is taken from sync.Map.
func (*DatabaseISliceMap) Set ¶ added in v0.0.9
func (o *DatabaseISliceMap) Set(key string, val DatabaseI)
Set sets the given key to the given value. If the key already exists, the range order will not change.
func (*DatabaseISliceMap) SetAt ¶ added in v0.0.9
func (o *DatabaseISliceMap) SetAt(index int, key string, val DatabaseI)
SetAt sets the given key to the given value, but also inserts it at the index specified. If the index is bigger than the length, it puts it at the end. Negative indexes are backwards from the end.
func (*DatabaseISliceMap) SetSortFunc ¶ added in v0.19.0
func (o *DatabaseISliceMap) SetSortFunc(f func(key1, key2 string, val1, val2 DatabaseI) bool) *DatabaseISliceMap
SetSortFunc sets the sort function which will determine the order of the items in the map on an ongoing basis. Normally, items will iterate in the order they were added. The sort function is a Less function, that returns true when item 1 is "less" than item 2. The sort function receives both the keys and values, so it can use either to decide how to sort.
func (*DatabaseISliceMap) SortByKeys ¶ added in v0.19.0
func (o *DatabaseISliceMap) SortByKeys() *DatabaseISliceMap
SortByKeys sets up the map to have its sort order sort by keys, lowest to highest
func (*DatabaseISliceMap) String ¶ added in v0.0.9
func (o *DatabaseISliceMap) String() string
func (*DatabaseISliceMap) UnmarshalBinary ¶ added in v0.0.9
func (o *DatabaseISliceMap) UnmarshalBinary(data []byte) (err error)
UnmarshalBinary implements the BinaryUnmarshaler interface to convert a byte stream to a DatabaseISliceMap
func (*DatabaseISliceMap) UnmarshalJSON ¶ added in v0.0.9
func (o *DatabaseISliceMap) UnmarshalJSON(data []byte) (err error)
UnmarshalJSON implements the json.Unmarshaler interface to convert a json object to a DatabaseIMap. The JSON must start with an object.
func (*DatabaseISliceMap) Values ¶ added in v0.0.9
func (o *DatabaseISliceMap) Values() (vals []DatabaseI)
Values returns a slice of the values in the order they were added or sorted.
type FKAction ¶
type FKAction int
FKAction indicates how the database handles situations when one side of a relationship is deleted or the key is changed. These generally correspond to the options available in MySQL InnoDB databases.
const ( FKActionNone FKAction = iota // In a typical database, this is the same as Restrict. For OUR purposes, it means we should deal with it ourselves. // This would be the situation when we are emulating foreign key constraints for databases that don't support them. FKActionSetNull FKActionSetDefault // Not supported in MySQL! FKActionCascade // FKActionRestrict // The database is going to choke on this. We will try to error before something like this happens. )
The foreign key actions tell us what the database will do automatically if a foreign key object is changed. This allows us to do the appropriate thing when we detect in the ORM that a linked object is changing.
func FKActionFromString ¶ added in v0.6.0
type ForeignKeyDescription ¶
type ForeignKeyDescription struct {
//DbKey string // We don't support cross database foreign keys yet. Someday maybe.
// ReferencedTable is the name of the table on the other end of the foreign key
ReferencedTable string
// ReferencedColumn is the database column name in the linked table that matches this column. Often that is the primary key of the other table.
ReferencedColumn string
// UpdateAction indicates how the database will react when the referenced item's id changes.
UpdateAction string
// DeleteAction indicates how the database will react when the referenced item is deleted.
DeleteAction string
// IsUnique is true if the reference is one-to-one
IsUnique bool
// GoName is the name we should use to refer to the related object. Leave blank to get a computed value.
GoName string
// ReverseName is the name that the reverse reference should use to refer to the collection of objects pointing to it.
// Leave blank to get a "ThisAsThat" type default name. The lower-case version of this name will be used as a column name
// to store the values if using a NoSQL database.
ReverseName string
}
type ForeignKeyInfo ¶ added in v0.6.0
type ForeignKeyInfo struct {
//DbKey string // We don't support cross database foreign keys yet. Someday maybe.
// ReferencedTable is the name of the table on the other end of the foreign key
ReferencedTable string
// ReferencedColumn is the database column name in the linked table that matches this column name. Often that is the primary key of the other table.
ReferencedColumn string
// UpdateAction indicates how the database will react when the other end of the relationship's value changes.
UpdateAction FKAction
// DeleteAction indicates how the database will react when the other end of the relationship's record is deleted.
DeleteAction FKAction
// GoName is the name we should use to refer to the related object
GoName string
// GoType is the type of the related object
GoType string
// GoTypePlural is the plural version of the type when referring to groups of related objects
GoTypePlural string
// IsType is true if this is a related type
IsType bool
// RR is filled in by the analyzer and represent a reverse reference relationship
RR *ReverseReference
}
ForeignKeyInfo is additional information to describe what a foreign key points to
func (*ForeignKeyInfo) GoVarName ¶ added in v0.6.0
func (fk *ForeignKeyInfo) GoVarName() string
GoVarName returns the name of the go object used to refer to the kind of object the foreign key points to.
type Index ¶ added in v0.6.0
type Index struct {
// IsUnique indicates whether the index is for a unique index
IsUnique bool
// Columns are the columns that are part of the index
Columns []*Column
}
Index is used by SQL analysis to extract details about an Index in the database. We can use indexes to know how to get to sorted data easily.
type IndexDescription ¶
type IndexDescription struct {
// IsUnique indicates whether the index is unique
IsUnique bool
// ColumnNames are the columns that are part of the index
ColumnNames []string
}
IndexDescription gives us information about how columns are indexed. If a column has a unique index, it will get a corresponding "LoadBy" function in its table's model. Otherwise, it will get a corresponding "LoadSliceBy" function.
type LimitInfo ¶ added in v0.0.7
LimitInfo is the information needed to limit the rows being requested.
type ManyManyDescription ¶ added in v0.6.0
type ManyManyDescription struct {
// Table1 is the name of the first table that is part of the relationship. The private key of that table will be referred to.
Table1 string
// Column1 is the database column name. For SQL databases, this is the name of the column in the assn table. For
// NoSQL, this is the name of the column that will be used to store the ids of the other side. This is optional for
// NoSQL, as one will be created based on the table names if left blank.
Column1 string
// GoName1 is the singular name of the object that Table2 will use to refer to Table1 objects.
GoName1 string
// GoPlural1 is the plural name of the object that Table2 will use to refer to Table1 objects.
GoPlural1 string
// Table2 is the name of the second table that is part of the relationship. The private key of that table will be referred to.
Table2 string
// Column2 is the database column name. For SQL databases, this is the name of the column in the assn table. For
// NoSQL, this is the name of the column that will be used to store the ids of the other side. This is optional for
// NoSQL, as one will be created based on the table names if left blank.
Column2 string
// GoName2 is the singular name of the object that Table1 will use to refer to Table2 objects.
GoName2 string
// GoPlural2 is the plural name of the object that Table1 will use to refer to Table2 objects.
GoPlural2 string
// AssnTableName is the name of the intermediate association table that will be used to create the relationship. This is
// needed for SQL databases, but not for NoSQL, as NoSQL will create additional array columns on each side of the relationship.
AssnTableName string
}
type ManyManyReference ¶
type ManyManyReference struct {
// AssnTableName is the database table creating the association. NoSQL: The originating table. SQL: The association table
AssnTableName string
// AssnColumnName is the column creating the association. NoSQL: The table storing the array of ids on the other end. SQL: the column in the association table pointing towards us.
AssnColumnName string
// AssociatedTableName is the database table being linked. NoSQL & SQL: The table we are joining to
AssociatedTableName string
// AssociatedColumnName is the database column being linked. NoSQL: table point backwards to us. SQL: Column in association table pointing forwards to refTable
AssociatedColumnName string
// AssociatedObjectName is the go name of the object created by this reference
AssociatedObjectName string
// GoName is the name used to refer to an object on the other end of the reference.
GoName string
// GoPlural is the name used to refer to the group of objects on the other end of the reference.
GoPlural string
// IsTypeAssociation is true if this is a many-many relationship with a type table
IsTypeAssociation bool
// MM is the many-many reference on the other end of the relationship that points back to this one.
MM *ManyManyReference
}
The ManyManyReference structure is used by the templates during the codegen process to describe a many-to-many relationship.
func (*ManyManyReference) JsonKey ¶ added in v0.1.1
func (m *ManyManyReference) JsonKey(dd *Database) string
func (*ManyManyReference) ObjName ¶ added in v0.1.1
func (m *ManyManyReference) ObjName(dd *Database) string
type QueryBuilder ¶ added in v0.0.7
type QueryBuilder struct {
Ctx context.Context // The context that will be used in all the queries
Joins []NodeI
OrderBys []NodeI
ConditionNode NodeI
IsDistinct bool
AliasNodes *AliasNodesType
// Adds a COUNT(*) to the select list
GroupBys []NodeI
Selects []NodeI
LimitInfo *LimitInfo
HavingNode NodeI
IsSubquery bool
}
QueryBuilder is a helper to implement the QueryBuilderI interface in various builder classes. It is designed to be embedded in a database specific implementation. It gathers the builder instructions as the query is built. It leaves the implementation of the functions that actually query a database -- Load, Delete, Count -- to the containing structure.
func (*QueryBuilder) Alias ¶ added in v0.0.7
func (b *QueryBuilder) Alias(name string, n NodeI)
Alias adds a node that is given a manual alias name. This is usually some kind of operation, but it can be any query.Aliaser kind of node.
func (*QueryBuilder) Condition ¶ added in v0.0.7
func (b *QueryBuilder) Condition(c NodeI)
Condition adds the condition of the Where clause. If a condition already exists, it will be anded to the previous condition.
func (*QueryBuilder) Context ¶ added in v0.10.0
func (b *QueryBuilder) Context() context.Context
Context returns the context.
func (*QueryBuilder) Count ¶ added in v0.0.7
func (b *QueryBuilder) Count(_ bool, _ ...NodeI) uint
Count is a stub that helps the QueryBuilder implement the query.QueryBuilderI interface so it can be included in sub-queries.
func (*QueryBuilder) Delete ¶ added in v0.0.7
func (b *QueryBuilder) Delete()
Delete is a stub that helps the QueryBuilder implement the query.QueryBuilderI interface so it can be included in sub-queries.
func (*QueryBuilder) Distinct ¶ added in v0.0.7
func (b *QueryBuilder) Distinct()
Distinct sets the distinct bit, causing the query to not return duplicates.
func (*QueryBuilder) Expand ¶ added in v0.0.7
func (b *QueryBuilder) Expand(n NodeI)
Expand expands an array type node so that it will produce individual rows instead of an array of items
func (*QueryBuilder) GroupBy ¶ added in v0.0.7
func (b *QueryBuilder) GroupBy(nodes ...NodeI)
GroupBy sets the nodes that are grouped. According to SQL rules, these then are the only nodes that can be selected, and they MUST be selected.
func (*QueryBuilder) Having ¶ added in v0.0.7
func (b *QueryBuilder) Having(node NodeI)
Having adds a HAVING condition, which is a filter that acts on the results of a query. In particular its useful for filtering after aggregate functions have done their work.
func (*QueryBuilder) Init ¶ added in v0.0.7
func (b *QueryBuilder) Init(ctx context.Context)
Init initializes the QueryBuilder.
func (*QueryBuilder) Join ¶ added in v0.0.7
func (b *QueryBuilder) Join(n NodeI, condition NodeI)
Join will attach the given reference node to the builder.
func (*QueryBuilder) Limit ¶ added in v0.0.7
func (b *QueryBuilder) Limit(maxRowCount int, offset int)
Limit sets the limit parameters of what is returned.
func (*QueryBuilder) Load ¶ added in v0.0.7
func (b *QueryBuilder) Load() []map[string]interface{}
Load is a stub that helps the QueryBuilder implement the query.QueryBuilderI interface so it can be included in sub-queries.
func (*QueryBuilder) LoadCursor ¶ added in v0.19.0
func (b *QueryBuilder) LoadCursor() CursorI
LoadCursor is a stub that helps the QueryBuilder implement the query.QueryBuilderI interface so it can be included in sub-queries.
func (*QueryBuilder) OrderBy ¶ added in v0.0.7
func (b *QueryBuilder) OrderBy(nodes ...NodeI)
OrderBy adds the order by nodes. If these are table type nodes, the primary key of the table will be used. These nodes can be modified using Ascending and Descending calls.
func (*QueryBuilder) Select ¶ added in v0.0.7
func (b *QueryBuilder) Select(nodes ...NodeI)
Select specifies what specific nodes are selected. This is an optimization in order to limit the amount of data returned by the query. Without this, the query will expand all the join items to return every column of each table joined.
func (*QueryBuilder) Subquery ¶ added in v0.0.7
func (b *QueryBuilder) Subquery() *SubqueryNode
Subquery adds a subquery node, which is like a mini query builder that should result in a single value.
type QueryExport ¶ added in v0.0.7
type QueryExport struct {
Joins []NodeI
OrderBys []NodeI
Condition NodeI
Distinct bool
AliasNodes *AliasNodesType
// Adds a COUNT(*) to the select list
GroupBys []NodeI
Selects []NodeI
LimitInfo *LimitInfo
Having NodeI
IsSubquery bool
}
func ExportQuery ¶ added in v0.0.7
func ExportQuery(b *QueryBuilder) *QueryExport
type ReverseReference ¶
type ReverseReference struct {
// DbColumn is only used in NoSQL databases, and is the name of a column that will hold the pk(s) of the referring column(s)
DbColumn string
// AssociatedTableName is the table on the "many" end that is pointing to the table containing the ReverseReference.
AssociatedTable *Table
// AssociatedColumn is the column on the "many" end that is pointing to the table containing the ReverseReference. It is a foreign-key.
AssociatedColumn *Column
// GoName is the name used to represent an object in the reverse relationship
GoName string
// GoPlural is the name used to represent the group of objects in the reverse relationship
GoPlural string
// GoType is the type of object in the collection of "many" objects, which corresponds to the name of the struct corresponding to the table
GoType string
// GoTypePlural is the plural of the type of object in the collection of "many" objects
GoTypePlural string
// Values are freeform values available to the code generation process
Values map[string]string
}
ReverseReference represents a kind of virtual column that is a result of a foreign-key pointing back to this column. This is the "one" side of a one-to-many relationship. Or, if the relationship is unique, this creates a one-to-one relationship. In SQL, since there is only a one-way foreign key, the side being pointed at does not have any direct data in a table indicating the relationship. We create a ReverseReference during data analysis and include it with the table description so that the table can know about the relationship and use it when doing queries.
func (*ReverseReference) AssociatedGoName ¶ added in v0.1.1
func (r *ReverseReference) AssociatedGoName() string
AssociatedGoName returns the name of the column that is pointing back to us. The name returned is the Go name that we could use to name the referenced object.
func (*ReverseReference) AssociatedPkType ¶ added in v0.6.1
func (r *ReverseReference) AssociatedPkType() string
func (*ReverseReference) AssociatedTableName ¶
func (r *ReverseReference) AssociatedTableName() string
func (*ReverseReference) IsNullable ¶ added in v0.7.0
func (r *ReverseReference) IsNullable() bool
func (*ReverseReference) IsUnique ¶
func (r *ReverseReference) IsUnique() bool
func (*ReverseReference) JsonKey ¶ added in v0.1.1
func (r *ReverseReference) JsonKey(dd *Database) string
type Table ¶ added in v0.6.0
type Table struct {
// DbKey is the key used to find the database in the global database cluster
DbKey string
// DbName is the name of the database table or object in the database.
DbName string
// LiteralName is the name of the object when describing it to the world. Use the "literalName" option in the comment to override the default. Should be lower case.
LiteralName string
// LiteralPlural is the plural name of the object. Use the "literalPlural" option in the comment to override the default. Should be lower case.
LiteralPlural string
// GoName is name of the struct when referring to it in go code. Use the "goName" option in the comment to override the default.
GoName string
// GoPlural is the name of a collection of these objects when referring to them in go code. Use the "goPlural" option in the comment to override the default.
GoPlural string
// LcGoName is the same as GoName, but with first letter lower case.
LcGoName string
// Columns is a list of ColumnDescriptions, one for each column in the table.
Columns []*Column
// Indexes are the indexes defined in the database. Unique indexes will result in LoadBy* functions.
Indexes []Index
// Options are key-value pairs of values that can be used to customize how code generation is performed
Options map[string]interface{}
// IsType is true if this is a type table
IsType bool
// Comment is the general comment included in the database
Comment string
// ManyManyReferences describe the many-to-many references pointing to this table
ManyManyReferences []*ManyManyReference
// ReverseReferences describes the many-to-one references pointing to this table
ReverseReferences []*ReverseReference
// contains filtered or unexported fields
}
func GetTableDescription ¶
GetTableDescription returns a table description given a database key and the struct name corresponding to the table. You must call AnalyzeDatabases first to use this.
func (*Table) DefaultHtmlID ¶ added in v0.9.3
func (*Table) PrimaryKeyColumn ¶ added in v0.6.0
func (*Table) PrimaryKeyGoType ¶ added in v0.7.0
type TableDescription ¶
type TableDescription struct {
// Name is the name of the database table or collection.
Name string
// Columns is a list of ColumnDescriptions, one for each column in the table.
// The first column(s) is the primary key
Columns []ColumnDescription
// Indexes are the indexes defined in the database. Unique indexes will result in LoadBy* functions.
Indexes []IndexDescription
// TypeData is the data of the type table if this is a type table. The data structure must match that of the columns.
TypeData []map[string]interface{}
// LiteralName is the name of the object when used in a context that can be presented to the user
LiteralName string
// LiteralPlural is the plural form of the object when used in a context that can be presented to the user
LiteralPlural string
// GoName is the name of the created ORM object that reflects what is in the database
GoName string
// GoPlural is the name that will be used to represent a collection of ORM objects
GoPlural string
// Comment is a comment about the table
Comment string
// Options are key-value settings that can be used to further describe code generation
Options map[string]interface{}
}
type TransactionID ¶
type TransactionID int
type TypeTable ¶ added in v0.6.0
type TypeTable struct {
// DbKey is the key used to find the database in the global database cluster
DbKey string
// DbName is the name of the table in the database
DbName string
// LiteralName is the english name of the object when describing it to the world. Use the "literalName" option in the comment to override the default.
LiteralName string
// LiteralPlural is the plural english name of the object. Use the "literalPlural" option in the comment to override the default.
LiteralPlural string
// GoName is the name of the item as a go type name.
GoName string
// GoPlural is the plural of the go type
GoPlural string
// LcGoName is the lower case version of the go name
LcGoName string
// FieldNames are the names of the fields defined in the table. The first field name MUST be the name of the id field, and 2nd MUST be the name of the name field, the others are optional extra fields.
FieldNames []string
// FieldTypes are the go column types of the fields, indexed by field name
FieldTypes map[string]GoColumnType
// Values are the constant values themselves as defined in the table, mapped to field names in each row.
Values []map[string]interface{}
// PkField is the name of the private key field
PkField string
// Filled in by analyzer
Constants map[int]string
}
TypeTable describes a type table, which essentially defines an enumerated type. In the SQL world, they are a table with an integer key (starting index 1) and a "name" value, though they can have other values associated with them too. Goradd will maintain the relationships in SQL, but in a No-SQL situation, it will embed all the ids and values.
func GetTypeTableDescription ¶
GetTypeTableDescription returns a type table description given a database key and the struct name corresponding to the table. You must call AnalyzeDatabases first to use this.
func (*TypeTable) FieldGoColumnType ¶ added in v0.6.0
FieldGoColumnType returns the GoColumnType corresponding to the given field offset
func (*TypeTable) FieldGoName ¶ added in v0.6.0
FieldGoName returns the go name corresponding to the given field offset