Documentation
¶
Index ¶
Constants ¶
View Source
const ConnectionTemplate = `` /* 3151-byte string literal not displayed */
ConnectionTemplate is the template for the connection functions. This is included in the init template.
View Source
const ErrorsTemplate = `` /* 460-byte string literal not displayed */
ErrorsTemplate is the template for the errors. This is included in the init template.
View Source
const InitStatementTemplate = `` /* 496-byte string literal not displayed */
InitStatementTemplate is the template for the init functions.
View Source
const OptionsTemplate = `` /* 3417-byte string literal not displayed */
View Source
const SingleRepeatedTypesTemplate = `` /* 1121-byte string literal not displayed */
View Source
const StorageTemplate = `` /* 3358-byte string literal not displayed */
StorageTemplate is the template for the storage functions. This is included in the init template.
View Source
const StructureTemplate = `
// {{ structureName }} is a struct for the "{{ tableName }}" table.
type {{ structureName }} struct {
{{ range $field := fields }}
{{ $field | fieldName }} {{ $field | fieldType }}{{if not ($field | isRelation) }}` + " `db:\"{{ $field | sourceName }}\"`" + `{{end}}{{end}}
}
// TableName returns the table name.
func (t *{{ structureName }}) TableName() string {
return "{{ tableName }}"
}
// ScanRow scans a row into a {{ structureName }}.
func (t *{{ structureName }}) ScanRow(r *sql.Row) error {
return r.Scan({{ range $field := fields }} {{if not ($field | isRelation) }} &t.{{ $field | fieldName }}, {{ end }}{{ end }})
}
// ScanRows scans a single row into the {{ structureName }}.
func (t *{{ structureName }}) ScanRows(r *sql.Rows) error {
return r.Scan(
{{- range $index, $field := fields }}
{{- if not ($field | isRelation) }}
&t.{{ $field | fieldName }},
{{- end}}
{{- end }}
)
}
`
View Source
const TableConditionFilters = `` /* 7979-byte string literal not displayed */
View Source
const TableConditionsTemplate = `` /* 12349-byte string literal not displayed */
View Source
const TableCountMethodTemplate = `` /* 832-byte string literal not displayed */
View Source
const TableCreateMethodTemplate = `` /* 4112-byte string literal not displayed */
View Source
const TableDeleteMethodTemplate = `` /* 1622-byte string literal not displayed */
View Source
const TableFindManyMethodTemplate = `` /* 1585-byte string literal not displayed */
View Source
const TableFindOneMethodTemplate = `` /* 467-byte string literal not displayed */
View Source
const TableFindWithPaginationMethodTemplate = `` /* 1024-byte string literal not displayed */
View Source
const TableGetByIDMethodTemplate = `` /* 632-byte string literal not displayed */
View Source
const TableLockMethodTemplate = `` /* 992-byte string literal not displayed */
View Source
const TableRawQueryMethodTemplate = `` /* 718-byte string literal not displayed */
View Source
const TableStorageTemplate = `
// {{ storageName | lowerCamelCase }} is a struct for the "{{ tableName }}" table.
type {{ storageName | lowerCamelCase }} struct {
db *sql.DB // The database connection.
queryBuilder sq.StatementBuilderType // queryBuilder is used to build queries.
}
// {{structureName}}TableManager is an interface for managing the {{ tableName }} table.
type {{structureName}}TableManager interface {
CreateTable(ctx context.Context) error
DropTable(ctx context.Context) error
TruncateTable(ctx context.Context) error
UpgradeTable(ctx context.Context) error
}
// {{structureName}}CRUDOperations is an interface for managing the {{ tableName }} table.
type {{structureName}}CRUDOperations interface {
{{- if (hasID) }}
Create(ctx context.Context, model *{{structureName}}, opts ...Option) (*{{IDType}}, error)
{{- else }}
Create(ctx context.Context, model *{{structureName}}, opts ...Option) error
{{- end }}
Update(ctx context.Context, id {{IDType}}, updateData *{{structureName}}Update) error
{{- if (hasPrimaryKey) }}
DeleteBy{{ getPrimaryKey.GetName | camelCase }}(ctx context.Context, {{getPrimaryKey.GetName}} {{IDType}}, opts ...Option) error
{{- end }}
{{- if (hasPrimaryKey) }}
FindBy{{ getPrimaryKey.GetName | camelCase }}(ctx context.Context, id {{IDType}}, opts ...Option) (*{{ structureName }}, error)
{{- end }}
}
// {{structureName}}SearchOperations is an interface for searching the {{ tableName }} table.
type {{structureName}}SearchOperations interface {
FindMany(ctx context.Context, builder ...*QueryBuilder) ([]*{{structureName}}, error)
FindOne(ctx context.Context, builders ...*QueryBuilder) (*{{structureName}}, error)
Count(ctx context.Context, builders ...*QueryBuilder) (int64, error)
SelectForUpdate(ctx context.Context, builders ...*QueryBuilder) (*{{structureName}}, error)
}
// {{structureName}}PaginationOperations is an interface for pagination operations.
type {{structureName}}PaginationOperations interface {
FindManyWithPagination(ctx context.Context, limit int, page int, builders ...*QueryBuilder) ([]*{{structureName}}, *Paginator, error)
}
// {{structureName}}RelationLoading is an interface for loading relations.
type {{structureName}}RelationLoading interface {
{{- range $index, $field := fields }}
{{- if and ($field | isRelation) }}
Load{{ $field | pluralFieldName }} (ctx context.Context, model *{{structureName}}, builders ...*QueryBuilder) error
{{- end }}
{{- end }}
{{- range $index, $field := fields }}
{{- if and ($field | isRelation) }}
LoadBatch{{ $field | pluralFieldName }} (ctx context.Context, items []*{{structureName}}, builders ...*QueryBuilder) error
{{- end }}
{{- end }}
}
// {{structureName}}AdvancedDeletion is an interface for advanced deletion operations.
type {{structureName}}AdvancedDeletion interface {
DeleteMany(ctx context.Context, builders ...*QueryBuilder) error
}
// {{structureName}}RawQueryOperations is an interface for executing raw queries.
type {{structureName}}RawQueryOperations interface {
Query(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
QueryRow(ctx context.Context, query string, args ...interface{}) *sql.Row
QueryRows(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
}
// {{ storageName }} is a struct for the "{{ tableName }}" table.
type {{ storageName }} interface {
{{structureName}}TableManager
{{structureName}}CRUDOperations
{{structureName}}SearchOperations
{{structureName}}PaginationOperations
{{structureName}}RelationLoading
{{structureName}}AdvancedDeletion
{{structureName}}RawQueryOperations
}
// New{{ storageName }} returns a new {{ storageName | lowerCamelCase }}.
func New{{ storageName }}(db *sql.DB) {{ storageName }} {
return &{{ storageName | lowerCamelCase }}{
db: db,
queryBuilder: sq.StatementBuilder.PlaceholderFormat(sq.Dollar),
}
}
// TableName returns the table name.
func (t *{{ storageName | lowerCamelCase }}) TableName() string {
return "{{ tableName }}"
}
// Columns returns the columns for the table.
func (t *{{ storageName | lowerCamelCase }}) Columns() []string {
return []string{
{{ range $field := fields }}{{if not ($field | isRelation) }}"{{ $field | sourceName }}",{{ end }}{{ end }}
}
}
// DB returns the underlying sql.DB. This is useful for doing transactions.
func (t *{{ storageName | lowerCamelCase }}) DB(ctx context.Context) QueryExecer {
var db QueryExecer = t.db
if tx, ok := TxFromContext(ctx); ok {
db = tx
}
return db
}
// createTable creates the table in SQLite.
func (t *{{ storageName | lowerCamelCase }}) CreateTable(ctx context.Context) error {
sqlQuery := ` + "`" + `
-- Table: {{ tableName }}
CREATE TABLE IF NOT EXISTS {{ tableName }} (
{{- range $index, $field := fields }}
{{- if not ($field | isRelation) }}
{{ $field | sourceName }} {{if ($field | isAutoIncrement) }} INTEGER PRIMARY KEY AUTOINCREMENT{{else}}{{ $field | sqliteType }}{{end}}{{if and (isNotNull $field) (not (isAutoIncrement $field)) }} NOT NULL{{ end }}{{if ($field | getDefaultValue) }} DEFAULT {{$field | getDefaultValue}}{{end}}{{if not ( $field | isLastField )}},{{end}}
{{- end}}
{{- end}});
-- Indexes and Unique constraints
{{- range $index, $field := fields }}
{{- if ($field | hasUnique) }}
CREATE UNIQUE INDEX IF NOT EXISTS {{ tableName }}_{{ $field | sourceName }}_unique_idx ON {{ tableName }} ({{ $field | sourceName }});
{{- end}}
{{- end}}
{{- range $index, $fields := getStructureUniqueIndexes }}
CREATE UNIQUE INDEX IF NOT EXISTS {{ tableName }}_unique_idx_{{ $fields | sliceToString }} ON {{ tableName }} (
{{- $length := sub (len $fields) 1 }}
{{- range $i, $field := $fields }}
{{ $field | sourceName }}{{ if lt $i $length }}, {{ end }}
{{- end }}
);
{{- end}}
{{- range $index, $field := fields }}
{{- if ($field | hasIndex) }}
CREATE INDEX IF NOT EXISTS {{ tableName }}_{{ $field | sourceName }}_idx ON {{ tableName }} ({{ $field | sourceName }});
{{- end}}
{{- end}}
-- SQLite handles foreign key constraints differently and should be part of table creation
` + "`" + `
_, err := t.db.ExecContext(ctx, sqlQuery)
return err
}
// DropTable drops the table.
func (t *{{ storageName | lowerCamelCase }}) DropTable(ctx context.Context) error {
sqlQuery := ` + "`" + `
DROP TABLE IF EXISTS {{ tableName }};
` + "`" + `
_, err := t.db.ExecContext(ctx,sqlQuery)
return err
}
// TruncateTable truncates the table.
func (t *{{ storageName | lowerCamelCase }}) TruncateTable(ctx context.Context) error {
sqlQuery := ` + "`" + `
TRUNCATE TABLE {{ tableName }};
` + "`" + `
_, err := t.db.ExecContext(ctx,sqlQuery)
return err
}
// UpgradeTable upgrades the table.
// todo: delete this method
func (t *{{ storageName | lowerCamelCase }}) UpgradeTable(ctx context.Context) error {
return nil
}
{{- range $index, $field := fields }}
{{- if and ($field | isRelation) }}
// Load{{ $field | pluralFieldName }} loads the {{ $field | pluralFieldName }} relation.
func (t *{{ storageName | lowerCamelCase }}) Load{{ $field | pluralFieldName }}(ctx context.Context, model *{{structureName}}, builders ...*QueryBuilder) error {
if model == nil {
return errors.Wrap(ErrModelIsNil, "{{structureName}} is nil")
}
// New{{ $field | relationStorageName }} creates a new {{ $field | relationStorageName }}.
s := New{{ $field | relationStorageName }}(t.db)
{{- if ($field | isOptional) }}
// Check if the optional field is nil
if model.{{ $field | getFieldID }} == nil {
// If nil, do not attempt to load the relation
return nil
}
// Add the filter for the relation with dereferenced value
builders = append(builders, FilterBuilder({{ $field | relationStructureName }}{{ $field | getRefID }}Eq(*model.{{ $field | getFieldID }})))
{{- else }}
// Add the filter for the relation without dereferencing
builders = append(builders, FilterBuilder({{ $field | relationStructureName }}{{ $field | getRefID }}Eq(model.{{ $field | getFieldID }})))
{{- end }}
{{- if ($field | isRepeated) }}
relationModels, err := s.FindMany(ctx, builders...)
if err != nil {
return fmt.Errorf("failed to find many {{ $field | relationStorageName }}: %w", err)
}
model.{{ $field | fieldName }} = relationModels
{{- else }}
relationModel, err := s.FindOne(ctx, builders...)
if err != nil {
return fmt.Errorf("failed to find {{ $field | relationStorageName }}: %w", err)
}
model.{{ $field | fieldName }} = relationModel
{{- end }}
return nil
}
{{- end }}
{{- end }}
{{- range $index, $field := fields }}
{{- if and ($field | isRelation) }}
// LoadBatch{{ $field | pluralFieldName }} loads the {{ $field | pluralFieldName }} relation.
func (t *{{ storageName | lowerCamelCase }}) LoadBatch{{ $field | pluralFieldName }}(ctx context.Context, items []*{{structureName}}, builders ...*QueryBuilder) error {
requestItems := make([]interface{}, 0, len(items))
for _, item := range items {
{{- if ($field | isOptional) }}
// Check if the field is nil for optional fields
if item.{{ $field | getFieldID }} == nil {
// Skip nil values for optional fields
continue
}
// Append dereferenced value for optional fields
requestItems = append(requestItems, *item.{{ $field | getFieldID }})
{{- else }}
// Append the value directly for non-optional fields
requestItems = append(requestItems, item.{{ $field | getFieldID }})
{{- end }}
}
// New{{ $field | relationStorageName }} creates a new {{ $field | relationStorageName }}.
s := New{{ $field | relationStorageName }}(t.db)
// Add the filter for the relation
{{- if ($field | isOptional) }}
// Ensure that requestItems are not empty before adding the builder
if len(requestItems) > 0 {
builders = append(builders, FilterBuilder({{ $field | relationStructureName }}{{ $field | getRefID }}In(requestItems...)))
}
{{- else }}
builders = append(builders, FilterBuilder({{ $field | relationStructureName }}{{ $field | getRefID }}In(requestItems...)))
{{- end }}
results, err := s.FindMany(ctx, builders...)
if err != nil {
return fmt.Errorf("failed to find many {{ $field | relationStorageName }}: %w", err)
}
{{- if ($field | isRepeated) }}
resultMap := make(map[interface{}][]*{{ $field | relationStructureName }})
{{- else }}
resultMap := make(map[interface{}]*{{ $field | relationStructureName }})
{{- end }}
for _, result := range results {
{{- if ($field | isRepeated) }}
resultMap[result.{{ $field | getRefID }}] = append(resultMap[result.{{ $field | getRefID }}], result)
{{- else }}
resultMap[result.{{ $field | getRefID }}] = result
{{- end }}
}
// Assign {{ $field | relationStructureName }} to items
for _, item := range items {
{{- if ($field | isOptional) }}
// Skip assignment if the field is nil
if item.{{ $field | getFieldID }} == nil {
continue
}
// Assign the relation if it exists in the resultMap
if v, ok := resultMap[*item.{{ $field | getFieldID }}]; ok {
item.{{ $field | fieldName }} = v
}
{{- else }}
// Assign the relation directly for non-optional fields
if v, ok := resultMap[item.{{ $field | getFieldID }}]; ok {
item.{{ $field | fieldName }} = v
}
{{- end }}
}
return nil
}
{{- end }}
{{- end }}
`
View Source
const TableTemplate = `` /* 469-byte string literal not displayed */
View Source
const TableUpdateMethodTemplate = `` /* 1688-byte string literal not displayed */
View Source
const TransactionManagerTemplate = `` /* 2464-byte string literal not displayed */
View Source
const TypesTemplate = `
{{ range $key, $field := nestedMessages }}
// {{ $key }} is a JSON type nested in another message.
type {{ $field.StructureName }} struct {
{{- range $nestedField := $field.Descriptor.GetField }}
{{ $nestedField | fieldName }} {{ $nestedField | fieldType }}` + " `json:\"{{ $nestedField | sourceName }}\"`" + `
{{- end }}
}
// Scan implements the sql.Scanner interface for JSON.
func (m *{{ $field.StructureName }}) Scan(src interface{}) error {
if bytes, ok := src.([]byte); ok {
return json.Unmarshal(bytes, m)
}
return fmt.Errorf("can't convert %T", src)
}
// Value implements the driver.Valuer interface for JSON.
func (m *{{ $field.StructureName }}) Value() (driver.Value, error) {
if m == nil {
m = &{{ $field.StructureName }}{}
}
return json.Marshal(m)
}
{{ end }}
`
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.