Documentation
¶
Index ¶
- Constants
- func AddDatabase(d DatabaseI, key string)
- func AnalyzeDatabases()
- func GetDatabases() map[string]DatabaseI
- func IsProfiling(ctx context.Context) bool
- func NewSqlBuilder(db SqlDbI) *sqlBuilder
- func ReceiveRows(rows *sql.Rows, columnTypes []GoColumnType, columnNames []string) (values []map[string]interface{})
- type ColumnDescription
- type Copier
- type DatabaseDescription
- type DatabaseI
- type Describer
- type FKAction
- type ForeignKeyDescription
- type ForeignKeyType
- type IndexDescription
- type LoaderFunc
- type ManyManyReference
- type Mysql5
- func (m *Mysql5) Delete(ctx context.Context, table string, pkName string, pkValue interface{})
- func (m *Mysql5) Describe() *DatabaseDescription
- func (m *Mysql5) Insert(ctx context.Context, table string, fields map[string]interface{}) string
- func (m *Mysql5) NewBuilder() QueryBuilderI
- func (m *Mysql5) Update(ctx context.Context, table string, fields map[string]interface{}, ...)
- type Option
- type ProfileEntry
- type ReverseReference
- type SqlContext
- type SqlDb
- func (s *SqlDb) AssociatedObjectPrefix() string
- func (s *SqlDb) AssociationTableSuffix() string
- func (s *SqlDb) Begin(ctx context.Context) (txid TransactionID)
- func (s *SqlDb) Commit(ctx context.Context, txid TransactionID)
- func (s *SqlDb) DbKey() string
- func (s *SqlDb) Exec(ctx context.Context, sql string, args ...interface{}) (r sql.Result, err error)
- func (s *SqlDb) GoStructPrefix() string
- func (s *SqlDb) IdSuffix() string
- func (s *SqlDb) Prepare(ctx context.Context, sql string) (r *sql.Stmt, err error)
- func (s *SqlDb) Query(ctx context.Context, sql string, args ...interface{}) (r *sql.Rows, err error)
- func (s *SqlDb) Rollback(ctx context.Context, txid TransactionID)
- func (s *SqlDb) SetAssociatedObjectPrefix(prefix string)
- func (s *SqlDb) SetAssociationTableSuffix(suffix string)
- func (s *SqlDb) SetGoStructPrefix(prefix string)
- func (s *SqlDb) SetTypeTableSuffix(suffix string)
- func (s *SqlDb) StartProfiling()
- func (s *SqlDb) TypeTableSuffix() string
- type SqlDbI
- type SqlReceiver
- func (r SqlReceiver) BoolI() interface{}
- func (r SqlReceiver) DoubleI() interface{}
- func (r SqlReceiver) FloatI() interface{}
- func (r SqlReceiver) Int64I() interface{}
- func (r SqlReceiver) IntI() interface{}
- func (r SqlReceiver) StringI() interface{}
- func (r SqlReceiver) TimeI() interface{}
- func (r SqlReceiver) Uint64I() interface{}
- func (r SqlReceiver) UintI() interface{}
- func (r SqlReceiver) Unpack(typ GoColumnType) interface{}
- type TableDescription
- type TransactionID
- type TypeTableDescription
- type ValueMap
Constants ¶
const ( MYSQL_TYPE_SET = "Set" MYSQL_TYPE_ENUM = "Enum" )
const ( SELECT = "SELECT" INSERT = "INSERT" UPDATE = "UPDATE" DELETE = "DELETE" )
const ( SQL_TYPE_UNKNOWN = "Unknown" SQL_TYPE_BLOB = "Blob" SQL_TYPE_VARCHAR = "VarChar" SQL_TYPE_CHAR = "Char" SQL_TYPE_TEXT = "Text" SQL_TYPE_INTEGER = "Int" SQL_TYPE_DATETIME = "DateTime" SQL_TYPE_DATE = "Date" SQL_TYPE_TIME = "Time" SQL_TYPE_FLOAT = "Float" SQL_TYPE_DOUBLE = "Double" SQL_TYPE_BOOL = "Bool" SQL_TYPE_DECIMAL = "Decimal" // a fixed point type )
Variables ¶
This section is empty.
Functions ¶
func AddDatabase ¶
func AnalyzeDatabases ¶
func AnalyzeDatabases()
func GetDatabases ¶
func IsProfiling ¶
func NewSqlBuilder ¶
func NewSqlBuilder(db SqlDbI) *sqlBuilder
* NewsqlBuilder creates a new sqlBuilder object.
func ReceiveRows ¶
func ReceiveRows(rows *sql.Rows, columnTypes []GoColumnType, columnNames []string) (values []map[string]interface{})
ReceiveRows gets data from a sql result set and returns it as a slice of maps. Each row is mapped to its table name. If you provide table names, those will be used in the map. Otherwise it will get the table names out of the result set provided
Types ¶
type ColumnDescription ¶
type ColumnDescription struct {
DbName string // name in database. Blank if this is a "virtual" table for sql tables. i.e. an association or virtual attribute query
GoName string
NativeType string // type of table based on native description of table
GoType GoColumnType // represents a basic go type
MaxCharLength uint64 // To help fields limit the number of characters or bytes they will accept, when its known
DefaultValue interface{} // gets cast to the goType
MaxValue interface{}
MinValue interface{}
IsId bool // Is this a unique identifier that is generated by the database system?
IsPk bool // A primary key. Could be generated by us.
IsNullable bool
IsIndexed bool // Does it have a single index on itself. Will generate a LoadBy function
IsUnique bool
IsAutoUpdateTimestamp bool // Database is auto updating this timestamp, or
ShouldUpdateTimestamp bool // We should generate code to auto update this timestamp.
Comment string
// Filled in by analyzer
Options *maps.SliceMap
ForeignKey *ForeignKeyType
ModelName string // code generating convenience. The internal name in the model corresponding to this column.
}
ColumnDescription describes a database column for the purpose of code generation. 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 (*ColumnDescription) DefaultConstantName ¶
func (cd *ColumnDescription) DefaultConstantName(tableName string) string
func (*ColumnDescription) DefaultValueAsConstant ¶
func (cd *ColumnDescription) DefaultValueAsConstant() string
Returns the default
func (*ColumnDescription) DefaultValueAsValue ¶
func (cd *ColumnDescription) DefaultValueAsValue() string
func (*ColumnDescription) IsReference ¶
func (cd *ColumnDescription) IsReference() bool
type Copier ¶
type Copier interface {
Copy() interface{}
}
Copier implements the copy interface, that returns a deep copy of an object.
type DatabaseDescription ¶
type DatabaseDescription struct {
// The database key corresponding to its key in the global database cluster
DbKey string
Tables []*TableDescription
// Type tables contain a description of an enumerated type
TypeTables []*TypeTableDescription
// The prefix for related objects.
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 DatabaseDescription is the top level struct that contains a complete description of a database for purposes of generating and creating queries
func NewDatabaseDescription ¶
func NewDatabaseDescription(dbKey string, objectPrefix string, fkSuffix string) *DatabaseDescription
func (*DatabaseDescription) IsTypeTable ¶
func (dd *DatabaseDescription) IsTypeTable(name string) bool
func (*DatabaseDescription) TableDescription ¶
func (dd *DatabaseDescription) TableDescription(name string) *TableDescription
func (*DatabaseDescription) TypeTableDescription ¶
func (dd *DatabaseDescription) TypeTableDescription(name string) *TypeTableDescription
type DatabaseI ¶
type DatabaseI interface {
Describe() *DatabaseDescription
// For codegen
GoStructPrefix() string
AssociatedObjectPrefix() string
// Aid to build queries and deletes
NewBuilder() QueryBuilderI
Update(ctx context.Context, table string, fields map[string]interface{}, pkName string, pkValue string)
Insert(ctx context.Context, table string, fields map[string]interface{}) string
Delete(ctx context.Context, table string, pkName string, pkValue interface{})
Begin(ctx context.Context) TransactionID
Commit(ctx context.Context, txid TransactionID)
Rollback(ctx context.Context, txid TransactionID)
}
The dataStore is the central database collection used in codegeneration and the orm.
func GetDatabase ¶
type Describer ¶
type Describer interface {
Describe() *DatabaseDescription
}
type FKAction ¶
type FKAction int
const ( FK_ACTION_NONE 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. FK_ACTION_SET_NULL FK_ACTION_SET_DEFAULT // Not supported in MySQL! FK_ACTION_CASCADE // FK_ACTION_RESTRICT // 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.
type ForeignKeyDescription ¶
type ForeignKeyDescription struct {
KeyName string
Columns []string
RelationSchema string
RelationTable string
// contains filtered or unexported fields
}
Describes a foreign key relationship between columns in one table and columns in a different table We currently allow the collection of multi-table and cross-database fk data, but we don't currently support them in codegen.
type ForeignKeyType ¶
type ForeignKeyType struct {
//DbKey string // We don't support cross database foreign keys yet. Someday maybe.
TableName string
ColumnName string
UpdateAction FKAction
DeleteAction FKAction
GoName string // The name we should use to refer to the related object
GoType string // The type of the related object
IsType bool
RR *ReverseReference // Filled in by analyzer, the corresponding
}
func (*ForeignKeyType) GoVarName ¶
func (fk *ForeignKeyType) GoVarName() string
type IndexDescription ¶
type LoaderFunc ¶
type LoaderFunc func(QueryBuilderI, map[string]interface{})
type ManyManyReference ¶
type ManyManyReference struct {
// NoSQL: The originating table. SQL: The association table
AssnTableName string
// NoSQL: The table storing the array of ids on the other end. SQL: the table in the association table pointing towards us.
AssnColumnName string
// NoSQL & SQL: The table we are joining to
AssociatedTableName string
// NoSQL: table point backwards to us. SQL: Column in association table pointing forwards to refTable
AssociatedColumnName string
AssociatedObjectName string
// The virtual table names used to describe the objects on the other end of the association
GoName string
GoPlural string
IsTypeAssociation bool
Options maps.SliceMap
MM *ManyManyReference // ManyManyReference pointing back towards this one
}
The ManyManyReference structure is used by the templates during the codegen process to describe a many-to-any relationship.
type Mysql5 ¶
type Mysql5 struct {
SqlDb
// contains filtered or unexported fields
}
Mysql5 is the goradd driver for mysql databases. It works through the excellent go-sql-driver driver, to supply functionality above go's built in driver. To use it, call NewMysql5, but afterwards, work through the DB parent interface so that the underlying database can be swapped out later if needed.
Timezones Timezones are always tricky. Mysql has some interesting quirks:
- Datetime types are internally stored in the timezone of the server, and then returned based on the
timezone of the client.
- Timestamp types are internally stored in UTC and returned in the timezone of the client.
The benefit of this is that you can move your database to a server in another timezone, and the times will automatically change to the correct timezone.
- The mysql-go-driver has the ability to set a default timezone in the Loc configuration parameter
It appears to convert all times to this timezone before sending them to the database, and then when receiving times, it will set this as the timezone of the date.
These issues are further compounded by the fact that MYSQL can initialize date and time values to what it believes is the current date and time in its server's timezone, but will not save the timezone itself.
So, as a general rule, use Datetime types to represent a date combined with a time, like an appointment in a calendar or a recurring event that happens in whatever the current timezone is. Use Timestamp types to store data that records when an event happened.
Also, set the Loc configuration parameter to be the same as the server's timezone. By default its UTC. That will make it so all dates and times are in the same timezone as those automatically generated by MYSQL. It is best to set this and your database to UTC, as this will make your database portable to other timezones.
Set the ParseTime configuration paramater to TRUE so that the driver will parse the times into the correct timezone, navigating the GO server and database server timezones. Otherwise, we can only assume that the database is in UTC time, since we will not get any timezone info from the server.
Since the driver will return times in the timezone of the mysql server, our own sql driver will convert these to local time. This will mean that you can save data in local time, and you will receive data in local time in your app, but you need to be aware that when you view the data in the SQL, it will appear in whatever timezone the MYSQL server is set to.
func (*Mysql5) Describe ¶
func (m *Mysql5) Describe() *DatabaseDescription
func (*Mysql5) NewBuilder ¶
func (m *Mysql5) NewBuilder() QueryBuilderI
type ProfileEntry ¶
type ProfileEntry struct {
DbKey string
BeginTime time.Time
EndTime time.Time
Typ string
Sql string
}
ProfileEntry contains the data collected during sql profiling
func GetProfiles ¶
func GetProfiles(ctx context.Context) []ProfileEntry
TODO: Move profiles to a session variable so we can access ajax queries too
type ReverseReference ¶
type SqlContext ¶
type SqlContext struct {
// contains filtered or unexported fields
}
SqlContext is what is stored in the current context to keep track of queries. You must save a copy of this in the current context with the SqlContext key before calling database functions in order to use transactions or database profiling, or anything else the context is required for. The framework does this for you, but you will need to do this yourself if using the orm without the framework.
type SqlDb ¶
type SqlDb struct {
// contains filtered or unexported fields
}
func (*SqlDb) AssociatedObjectPrefix ¶
func (*SqlDb) AssociationTableSuffix ¶
func (*SqlDb) Begin ¶
func (s *SqlDb) Begin(ctx context.Context) (txid TransactionID)
Begin starts a transaction. You should immediately defer a Rollback using the returned transaction id. If you Commit before the Rollback happens, no Rollback will occur.
func (*SqlDb) Commit ¶
func (s *SqlDb) Commit(ctx context.Context, txid TransactionID)
Commit commits the transaction, and if an error occurs, will panic with the error.
func (*SqlDb) GoStructPrefix ¶
func (*SqlDb) Rollback ¶
func (s *SqlDb) Rollback(ctx context.Context, txid TransactionID)
Rollback will rollback the transaction if the transaction is still pointing to the given txid. This gives the effect that if you call Rollback on a transaction that has already been committed, no Rollback will happen. This makes it easier to implement a transaction management scheme, because you simply always defer a Rollback after a Begin. Pass the txid that you got from the Begin to the Rollback
func (*SqlDb) SetAssociatedObjectPrefix ¶
func (*SqlDb) SetAssociationTableSuffix ¶
func (*SqlDb) SetGoStructPrefix ¶
func (*SqlDb) SetTypeTableSuffix ¶
func (*SqlDb) StartProfiling ¶
func (s *SqlDb) StartProfiling()
func (*SqlDb) TypeTableSuffix ¶
type SqlReceiver ¶
type SqlReceiver struct {
R interface{}
}
SqlReceiver is an encapsulation of a way of receiving data from sql queries as interface{} pointers. This allows you to get data without knowing the type of data you are asking for ahead of time, and is easier for dealing with NULL fields. Some database drivers (MySql for one), return different results in fields depending on how you call the query (using a prepared statement can return different results than without one), or if the data does not quite fit (UInt64 in particular will return a string if the returned value is bigger than MaxInt64, but smaller than MaxUint64.)
Pass the address of the R member to the sql.Scan method when using an object of this type. IsRequired because there are some idiosyncracies with how Go treats return values that would prevent returning an address of R from a function
func (SqlReceiver) BoolI ¶
func (r SqlReceiver) BoolI() interface{}
func (SqlReceiver) DoubleI ¶
func (r SqlReceiver) DoubleI() interface{}
func (SqlReceiver) FloatI ¶
func (r SqlReceiver) FloatI() interface{}
func (SqlReceiver) Int64I ¶
func (r SqlReceiver) Int64I() interface{}
func (SqlReceiver) IntI ¶
func (r SqlReceiver) IntI() interface{}
func (SqlReceiver) StringI ¶
func (r SqlReceiver) StringI() interface{}
func (SqlReceiver) TimeI ¶
func (r SqlReceiver) TimeI() interface{}
func (SqlReceiver) Uint64I ¶
func (r SqlReceiver) Uint64I() interface{}
Some drivers (like MySQL) return all integers as Int64. This converts to uint64. Its up to you to make sure you only use this on 64-bit uints or smaller.
func (SqlReceiver) UintI ¶
func (r SqlReceiver) UintI() interface{}
Some drivers (like MySQL) return all integers as Int64. This converts to basic golang uint. Its up to you to make sure you only use this on 32-bit uints or smaller
func (SqlReceiver) Unpack ¶
func (r SqlReceiver) Unpack(typ GoColumnType) interface{}
Convert an SqlReceiver to a type corresponding to the given GoColumnType
type TableDescription ¶
type TableDescription struct {
// Key used to find database in the global database cluster
DbKey string
// The name of the database table or object
DbName string
// The literal 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
// The plural name of the object. Use the "literalPlural" option in the comment to override the default. Should be lower case.
LiteralPlural string
// The name of the struct when referring to it in go code. Use the "goName" option in the comment to override the default.
GoName string
// 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
// same as GoName, but with first letter lower case
LcGoName string
Columns []*ColumnDescription
Indexes []IndexDescription // Creates LoadBy functions. Mapped by index name.
Options maps.SliceMap
IsType bool
IsAssociation bool
Comment string
// The following items are filled in by the analyze process
ManyManyReferences []*ManyManyReference
ReverseReferences []*ReverseReference
HasDateTime bool
PrimaryKeyColumn *ColumnDescription
// Do not process this table
Skip bool
// contains filtered or unexported fields
}
func GetTableDescription ¶
func GetTableDescription(key string, goTypeName string) *TableDescription
func NewTableDescription ¶
func NewTableDescription(tableName string) *TableDescription
func (*TableDescription) GetColumn ¶
func (td *TableDescription) GetColumn(name string) *ColumnDescription
type TransactionID ¶
type TransactionID int
type TypeTableDescription ¶
type TypeTableDescription struct {
// Key used to find database in the global database cluster
DbKey string
// Name in the database
DbName string
// The english name of the object when describing it to the world. Use the "literalName" option in the comment to override the default.
EnglishName string
// The plural english name of the object. Use the "literalPlural" option in the comment to override the default.
EnglishPlural string
// The name of the item as a go type name.
GoName string
GoPlural string
LcGoName string
FieldNames []string // 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
FieldTypes map[string]GoColumnType
Values []map[string]interface{}
PkField string
// Filled in by analyzer
Constants map[uint]string
}
Type tables essentially define enumerated types. 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 ¶
func GetTypeTableDescription(key string, goTypeName string) *TypeTableDescription
func (*TypeTableDescription) FieldGoName ¶
func (tt *TypeTableDescription) FieldGoName(i int) string
Return the go name corresponding to the given field offset
func (*TypeTableDescription) FieldGoType ¶
func (tt *TypeTableDescription) FieldGoType(i int) string
Return the go type corresponding to the given field offset