sql

package
v0.22.1 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2022 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	SqlTypeUnknown   = "Unknown"
	SqlTypeBlob      = "Blob"
	SqlTypeVarchar   = "VarChar"
	SqlTypeChar      = "Char"
	SqlTypeText      = "Text"
	SqlTypeInteger   = "Int"
	SqlTypeTimestamp = "Timestamp"
	SqlTypeDatetime  = "DateTime"
	SqlTypeDate      = "Date"
	SqlTypeTime      = "Time"
	SqlTypeFloat     = "Float"
	SqlTypeDouble    = "Double"
	SqlTypeBool      = "Bool"
	SqlTypeDecimal   = "Decimal" // a fixed point type
)

Variables

This section is empty.

Functions

func ExtractOptions

func ExtractOptions(comment string) (options map[string]interface{}, remainingComment string, err error)

Find the json encoded list of options in the given string

func FkRuleToAction

func FkRuleToAction(rule sql.NullString) db.FKAction

func GetDataDefLength

func GetDataDefLength(description string) int

GetDataDefLength will extract the length from the definition given a data definition description of the table. If more than one number, returns the first number Example:

bigint(21) -> 21

varchar(50) -> 50 decimal(10,2) -> 10

func GetMinMax

func GetMinMax(o map[string]interface{}, defaultMin float64, defaultMax float64, tableName string, columnName string) (min float64, max float64)

Extracts a minimum and maximum value from the option map, returning defaults if none was found, and making sure the boundaries of anything found are not exceeded

func NewSqlCursor

func NewSqlCursor(rows *sql.Rows,
	columnTypes []query.GoColumnType,
	columnNames []string,
	builder *Builder,
) *sqlCursor

func SqlReceiveRows

func SqlReceiveRows(rows *sql.Rows,
	columnTypes []query.GoColumnType,
	columnNames []string,
	builder *Builder,
) []map[string]interface{}

SqlReceiveRows gets data from a sql result set and returns it as a slice of maps.

Each column is mapped to its column name. If you provide columnNames, those will be used in the map. Otherwise it will get the column names out of the result set provided.

Types

type Builder

type Builder struct {
	db2.QueryBuilder

	IsCount           bool
	IsDelete          bool
	RootDbTable       string                  // The database name for the table that is the root of the query
	RootJoinTreeItem  *JoinTreeItem           // The top of the join tree
	SubPrefix         string                  // The prefix for sub items. If this is a sub query, this gets updated
	SubqueryCounter   int                     // Helper to make unique prefixes for subqueries
	ColumnAliases     *JoinTreeItemSliceMap   // StdMap to go from an alias to a JoinTreeItem for columns, which can also get us to a node
	ColumnAliasNumber int                     // Helper to make unique generated aliases
	TableAliases      *JoinTreeItemSliceMap   // StdMap to go from an alias to a JoinTreeItem for tables
	NodeMap           map[NodeI]*JoinTreeItem // A map that gets us to a JoinTreeItem from a node.
	RowId             int                     // Counter for creating fake ids when doing distinct or orderby selects
	ParentBuilder     *Builder                // The parent builder of a subquery
	// contains filtered or unexported fields
}

A Builder is a helper object to organize a Query object eventually into a SQL string. It builds the join tree and creates the aliases that will eventually be used to generate the sql and then unpack it into fields and objects. It implements the QueryBuilderI interface. It is used both as the overriding controller of a query, and the controller of a subquery, so its recursive. The approach is to gather up the parameters of the query first, build the nodes into a node tree without changing the nodes themselves, build the query, execute the query, and finally return the results.

func NewSqlBuilder

func NewSqlBuilder(ctx context.Context, db DbI) *Builder

NewSqlBuilder creates a new Builder object.

func (*Builder) Count

func (b *Builder) Count(distinct bool, nodes ...NodeI) uint

Count creates a query that selects one thing, a count. If distinct is specified, only distinct items will be selected. If no columns are specified, the count will include NULL items. Otherwise, it will not include NULL results in the count. You cannot include any other select items in a count. If you want to do that, you should do a normal query and add a COUNT operation node.

func (*Builder) Delete

func (b *Builder) Delete()

func (*Builder) GetItemFromNode

func (b *Builder) GetItemFromNode(node NodeI) *JoinTreeItem

func (*Builder) Load

func (b *Builder) Load() (result []map[string]interface{})

Load terminates the builder, queries the database, and returns the results as an array of interfaces similar in structure to a json structure

func (*Builder) LoadCursor

func (b *Builder) LoadCursor() CursorI

LoadCursor terminates the builder, queries the database, and returns a cursor that can be used to step through the results.

LoadCursor is helpful when loading a large set of data that you want to output in chunks. You cannot use this with Joins that create multiple connections to other objects, like reverse FKs or Multi-multi relationships

func (*Builder) Subquery

func (b *Builder) Subquery() *SubqueryNode

Subquery adds a subquery node, which is like a mini query builder that should result in a single value.

type DbHelper

type DbHelper struct {
	// contains filtered or unexported fields
}

DbHelper is a mixin for SQL database drivers. It implements common code needed by all SQL database drivers.

func NewSqlDb

func NewSqlDb(dbKey string, db *sql.DB) DbHelper

NewSqlDb creates a default DbHelper mixin.

func (*DbHelper) AssociatedObjectPrefix

func (s *DbHelper) AssociatedObjectPrefix() string

AssociatedObjectPrefix returns the prefix string used in code generation to indicate a variable is a database object.

func (*DbHelper) AssociationTableSuffix

func (s *DbHelper) AssociationTableSuffix() string

AssociationTableSuffix returns the suffix used to identify association tables.

func (*DbHelper) Begin

func (s *DbHelper) Begin(ctx context.Context) (txid db.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. The Begin-Commit-Rollback pattern is nestable.

func (*DbHelper) Commit

func (s *DbHelper) Commit(ctx context.Context, txid db.TransactionID)

Commit commits the transaction, and if an error occurs, will panic with the error.

func (*DbHelper) DbKey

func (s *DbHelper) DbKey() string

DbKey returns the key of the database in the global database store.

func (*DbHelper) Exec

func (s *DbHelper) Exec(ctx context.Context, sql string, args ...interface{}) (r sql.Result, err error)

Exec executes the given SQL code, without returning any result rows.

func (*DbHelper) GetProfiles

func (s *DbHelper) GetProfiles(ctx context.Context) []ProfileEntry

GetProfiles returns currently collected profile information TODO: Move profiles to a session variable so we can access ajax queries too

func (*DbHelper) IdSuffix

func (s *DbHelper) IdSuffix() string

IdSuffix is the suffix used to indicate that a field is a foreign ky to another table.

func (*DbHelper) PutBlankContext

func (s *DbHelper) PutBlankContext(ctx context.Context) context.Context

PutBlankContext puts a blank context into the context chain to track transactions and other special database situations.

func (*DbHelper) Query

func (s *DbHelper) Query(ctx context.Context, sql string, args ...interface{}) (r *sql.Rows, err error)

Query executes the given sql, and returns a row result set.

func (*DbHelper) Rollback

func (s *DbHelper) Rollback(ctx context.Context, txid db.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. To trigger a Rollback, simply panic.

func (*DbHelper) SetAssociatedObjectPrefix

func (s *DbHelper) SetAssociatedObjectPrefix(prefix string)

SetAssociatedObjectPrefix sets the prefix string used in code generation to indicate a variable is a database object.

func (*DbHelper) SetAssociationTableSuffix

func (s *DbHelper) SetAssociationTableSuffix(suffix string)

SetAssociationTableSuffix sets the suffix used to identify association tables.

func (*DbHelper) SetTypeTableSuffix

func (s *DbHelper) SetTypeTableSuffix(suffix string)

SetTypeTableSuffix sets the suffix used to identify type tables.

func (*DbHelper) SqlDb

func (s *DbHelper) SqlDb() *sql.DB

SqlDb returns the sql database object.

func (*DbHelper) StartProfiling

func (s *DbHelper) StartProfiling()

StartProfiling will start the database profiling process.

func (*DbHelper) TypeTableSuffix

func (s *DbHelper) TypeTableSuffix() string

TypeTableSuffix returns the suffix used to identify type tables.

type DbI

type DbI interface {
	// Exec executes a query that does not expect to return values
	Exec(ctx context.Context, sql string, args ...interface{}) (r sql.Result, err error)
	// Query executes a query that returns values
	Query(ctx context.Context, sql string, args ...interface{}) (r *sql.Rows, err error)
	// TypeTableSuffix returns the suffix used in a table name to indicate that the table is a type table. By default this is "_type".
	TypeTableSuffix() string
	// AssociationTableSuffix returns the suffix used in a table name to indicate that the table is an association table. By default this is "_assn".
	AssociationTableSuffix() string

	// GenerateSelectSql will generate the select sql from the builder. This sql can be specific to the database used.
	GenerateSelectSql(QueryBuilderI) (sql string, args []interface{})
	// GenerateDeleteSql will generate delete sql from the given builder.
	GenerateDeleteSql(QueryBuilderI) (sql string, args []interface{})
}

The DbI interface describes the interface that a sql database needs to implement so that it will work with the Builder object.

type JoinTreeItem

type JoinTreeItem struct {
	Node            query.NodeI
	Parent          *JoinTreeItem
	ChildReferences []*JoinTreeItem // TableNodeI objects
	Leafs           []*JoinTreeItem
	JoinCondition   query.NodeI
	Alias           string
	Expanded        bool
	IsPK            bool
}

JoinTreeItem is used to build the join tree. The join tree creates a hierarchy of joined nodes that let us generate aliases, serialize the query, and afterwards unpack the results.

type JoinTreeItemGetter

type JoinTreeItemGetter interface {
	Get(key string) (val *JoinTreeItem)
}

type JoinTreeItemLoader

type JoinTreeItemLoader interface {
	Load(key string) (val *JoinTreeItem, ok bool)
}

type JoinTreeItemMapI

type JoinTreeItemMapI interface {
	Get(key string) (val *JoinTreeItem)
	Has(key string) (exists bool)
	Values() []*JoinTreeItem
	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 *JoinTreeItem) bool)
	Merge(i JoinTreeItemMapI)
	String() string
}

The JoinTreeItemMapI 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 JoinTreeItemSetter

type JoinTreeItemSetter interface {
	Set(string, *JoinTreeItem)
}

type JoinTreeItemSliceMap

type JoinTreeItemSliceMap struct {
	// contains filtered or unexported fields
}

A JoinTreeItemSliceMap 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. JoinTreeItemSliceMap 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 JoinTreeItemSliceMap satisfies the JoinTreeItemMapI interface.

func NewJoinTreeItemSliceMap

func NewJoinTreeItemSliceMap() *JoinTreeItemSliceMap

NewJoinTreeItemSliceMap creates a new map that maps string's to *JoinTreeItem's.

func NewJoinTreeItemSliceMapFrom

func NewJoinTreeItemSliceMapFrom(i JoinTreeItemMapI) *JoinTreeItemSliceMap

NewJoinTreeItemSliceMapFrom creates a new JoinTreeItemMap from a JoinTreeItemMapI interface object

func NewJoinTreeItemSliceMapFromMap

func NewJoinTreeItemSliceMapFromMap(i map[string]*JoinTreeItem) *JoinTreeItemSliceMap

NewJoinTreeItemSliceMapFromMap creates a new JoinTreeItemSliceMap from a GO map[string]*JoinTreeItem 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 (*JoinTreeItemSliceMap) Clear

func (o *JoinTreeItemSliceMap) Clear()

func (*JoinTreeItemSliceMap) Copy

Copy will make a copy of the map and a copy of the underlying data.

func (*JoinTreeItemSliceMap) Delete

func (o *JoinTreeItemSliceMap) Delete(key string)

Delete removes the item with the given key.

func (*JoinTreeItemSliceMap) Equals

Equals returns true if the map equals the given map, paying attention only to the content of the map and not the order.

func (*JoinTreeItemSliceMap) Get

func (o *JoinTreeItemSliceMap) Get(key string) (val *JoinTreeItem)

Get returns the value based on its key. If the key does not exist, an empty value is returned.

func (*JoinTreeItemSliceMap) GetAt

func (o *JoinTreeItemSliceMap) GetAt(position int) (val *JoinTreeItem)

GetAt returns the value based on its position. If the position is out of bounds, an empty value is returned.

func (*JoinTreeItemSliceMap) GetKeyAt

func (o *JoinTreeItemSliceMap) 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 (*JoinTreeItemSliceMap) Has

func (o *JoinTreeItemSliceMap) Has(key string) (ok bool)

Has returns true if the given key exists in the map.

func (*JoinTreeItemSliceMap) IsNil

func (o *JoinTreeItemSliceMap) IsNil() bool

func (*JoinTreeItemSliceMap) Keys

func (o *JoinTreeItemSliceMap) Keys() (keys []string)

Keys returns the keys of the map, in the order they were added or sorted

func (*JoinTreeItemSliceMap) Len

func (o *JoinTreeItemSliceMap) Len() int

Len returns the number of items in the map

func (*JoinTreeItemSliceMap) Load

func (o *JoinTreeItemSliceMap) Load(key string) (val *JoinTreeItem, 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 (*JoinTreeItemSliceMap) MarshalBinary

func (o *JoinTreeItemSliceMap) 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 (*JoinTreeItemSliceMap) MarshalJSON

func (o *JoinTreeItemSliceMap) MarshalJSON() (data []byte, err error)

MarshalJSON implements the json.Marshaler interface to convert the map into a JSON object.

func (*JoinTreeItemSliceMap) Merge

Merge the given map into the current one

func (*JoinTreeItemSliceMap) MergeMap

func (o *JoinTreeItemSliceMap) MergeMap(m map[string]*JoinTreeItem)

MergeMap merges the given standard map with the current one. The given one takes precedent on collisions.

func (*JoinTreeItemSliceMap) Range

func (o *JoinTreeItemSliceMap) Range(f func(key string, value *JoinTreeItem) 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 (*JoinTreeItemSliceMap) Set

func (o *JoinTreeItemSliceMap) Set(key string, val *JoinTreeItem)

Set sets the given key to the given value. If the key already exists, the range order will not change.

func (*JoinTreeItemSliceMap) SetAt

func (o *JoinTreeItemSliceMap) SetAt(index int, key string, val *JoinTreeItem)

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 (*JoinTreeItemSliceMap) SetSortFunc

func (o *JoinTreeItemSliceMap) SetSortFunc(f func(key1, key2 string, val1, val2 *JoinTreeItem) bool) *JoinTreeItemSliceMap

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 (*JoinTreeItemSliceMap) SortByKeys

func (o *JoinTreeItemSliceMap) SortByKeys() *JoinTreeItemSliceMap

SortByKeys sets up the map to have its sort order sort by keys, lowest to highest

func (*JoinTreeItemSliceMap) String

func (o *JoinTreeItemSliceMap) String() string

func (*JoinTreeItemSliceMap) UnmarshalBinary

func (o *JoinTreeItemSliceMap) UnmarshalBinary(data []byte) (err error)

UnmarshalBinary implements the BinaryUnmarshaler interface to convert a byte stream to a JoinTreeItemSliceMap

func (*JoinTreeItemSliceMap) UnmarshalJSON

func (o *JoinTreeItemSliceMap) UnmarshalJSON(data []byte) (err error)

UnmarshalJSON implements the json.Unmarshaler interface to convert a json object to a JoinTreeItemMap. The JSON must start with an object.

func (*JoinTreeItemSliceMap) Values

func (o *JoinTreeItemSliceMap) Values() (vals []*JoinTreeItem)

Values returns a slice of the values in the order they were added or sorted.

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

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, because there are some idiosyncrasies with how Go treats return values that prevents returning an address of R from a function

func (SqlReceiver) BoolI

func (r SqlReceiver) BoolI() interface{}

BoolI returns the value as an interface to a boolean

func (SqlReceiver) DoubleI

func (r SqlReceiver) DoubleI() interface{}

DoubleI returns the value as a float64 interface

func (SqlReceiver) FloatI

func (r SqlReceiver) FloatI() interface{}

FloatI returns the value as an interface to a float32 value.

func (SqlReceiver) Int64I

func (r SqlReceiver) Int64I() interface{}

Int64I returns the given value as an interface to an Int64

func (SqlReceiver) IntI

func (r SqlReceiver) IntI() interface{}

IntI returns the receiver as an interface to an int.

func (SqlReceiver) StringI

func (r SqlReceiver) StringI() interface{}

StringI returns the value as an interface to a string

func (SqlReceiver) TimeI

func (r SqlReceiver) TimeI() interface{}

TimeI returns the value as a time.Time value in UTC, or in the case of CURRENT_TIME, a string "now".

func (SqlReceiver) Uint64I

func (r SqlReceiver) Uint64I() interface{}

Uint64I returns a value as an interface to a UInt64.

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{}

UintI converts the value to an interface to a GO uint.

Some drivers (like MySQL) return all integers as Int64. 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{}

Unpack converts a SqlReceiver to a type corresponding to the given GoColumnType

func (SqlReceiver) UnpackDefaultValue added in v0.20.0

func (r SqlReceiver) UnpackDefaultValue(typ GoColumnType) interface{}

UnpackDefaultValue converts a SqlReceiver used to get the default value to a type corresponding to the given GoColumnType.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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