gen

package
v1.8.97 Latest Latest
Warning

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

Go to latest
Published: Apr 7, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var CacheInterfaceTemplate = template.Must(template.New("template-cache-interface-file").Funcs(template.FuncMap{
	"dataTypeToGoTypeString": schema.DataTypeToGoTypeString,
	"dataTypeToFormatString": schema.DataTypeToFormatString,
	"toArgName":              toArgName,
	"columnsToMethodName":    columnsToMethodName,
	"columnsToMethodArgs":    columnsToMethodArgs,
	"columnsToMethodParams":  columnsToMethodParams,
	"columnsToKey":           columnsToKey,
	"columnValuesToKey":      columnValuesToKey,
	"columnModelValuesToKey": columnModelValuesToKey,
}).Parse(`// Generated Code; DO NOT EDIT.

package caches

import ( 
	"{{ .BasePackage }}/gen/definitions/models" 
)

// I{{.Table.Name}}Cache is an interface for the {{.Table.Name}} cache
type I{{.Table.Name}}Cache interface {
	FromID(id int64) (*models.{{.Table.Name}}, error) 
	Save(model *models.{{.Table.Name}}){{range $index := .CacheConfig.Indices}}{{ if not $index.Index.Unique }}
	AddIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) 
	RemoveIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) {{else}}
	AddUniqueIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) 
	RemoveUniqueIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}){{end}}{{end}}
	Delete(id int64) 
	All(page, limit int64) ([]*models.{{.Table.Name}}, error)
	Count() (int64, error) 
	{{range $index := .CacheConfig.Indices}}{{ if not $index.Index.Unique}}From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}, page, limit int64) ([]*models.{{$.Table.Name}}, error)
	CountFrom{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}) (int64, error)
	{{else}}From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}) (*models.{{$.Table.Name}}, error)
	{{end}}{{end}}
}

`))
View Source
var CacheTemplate = template.Must(template.New("template-cache-file").Funcs(template.FuncMap{
	"dataTypeToGoTypeString": schema.DataTypeToGoTypeString,
	"dataTypeToFormatString": schema.DataTypeToFormatString,
	"toArgName":              toArgName,
	"columnsToMethodName":    columnsToMethodName,
	"columnsToMethodArgs":    columnsToMethodArgs,
	"columnsToMethodParams":  columnsToMethodParams,
	"columnsToKey":           columnsToKey,
	"columnValuesToKey":      columnValuesToKey,
	"columnModelValuesToKey": columnModelValuesToKey,
}).Parse(`// Generated Code; DO NOT EDIT.

package caches

import ( 
	"{{ .BasePackage }}/core/components/redis" 
	"{{ .BasePackage }}/gen/definitions/models" 

	"fmt"
)

const ( 
	// {{.Table.Name}}_Index_ID_Key is the string key for the primary key ({{.PrimaryKey}})
	{{.Table.Name}}_Index_ID_Key = "{{.Table.Name | toArgName}}_idx_id"
{{range $index := .CacheConfig.Indices}}{{if $index.Index.Unique}}
	// {{$.Table.Name}}_Index_{{$index.Columns | columnsToKey}}_Key is the string key of a unique index (hash map) for field {{$index.Index.Field}}
	{{$.Table.Name}}_Index_{{$index.Columns | columnsToKey}}_Key = "{{$.Table.Name | toArgName}}_idx_{{$index.Columns | columnsToKey}}"
{{end}}{{end}})

// {{.Table.Name}}_Key returns the string key for the unique primary key 
func {{.Table.Name}}_Key(id int64) string { 
	return fmt.Sprintf("{{ .Table.Name | toArgName }}_%d", id)
}
{{range $index := .CacheConfig.Indices}}{{if not $index.Index.Unique}}

// {{$.Table.Name}}_Index_{{range $column := $index.Columns}}{{$column.Name}}_{{end}}Key is the string key of a non-unique index for fields {{range $column := $index.Columns}}{{$column.Name}}, {{end}}
func {{$.Table.Name}}_Index_{{range $column := $index.Columns}}{{$column.Name}}_{{end}}Key({{range $column := $index.Columns}}
	{{$column.Name | toArgName}} {{$column | dataTypeToGoTypeString}},{{end}}
) string { 
	return fmt.Sprintf("{{$.Table.Name | toArgName}}_idx{{range $column := $index.Columns}}_{{$column.Name | toArgName}}_{{$column | dataTypeToFormatString}}{{end}}",{{range $column := $index.Columns}}
		{{$column.Name | toArgName}},{{end}}	
	)
}{{end}}{{end}}

// {{.Table.Name}}Cache is a cache for {{.Table.Name}} objects
type {{.Table.Name}}Cache struct {
	cache redis.RedisInterface
}

// New{{.Table.Name}}Cache returns a new instance of {{.Table.Name}}Cache
func New{{.Table.Name}}Cache(
	cache redis.RedisInterface, 
) *{{.Table.Name}}Cache {
	return &{{.Table.Name}}Cache{
		cache,
	}
}

// FromID retrieves a {{.Table.Name}} model by its primary key
func (r *{{.Table.Name}}Cache) FromID(id int64) (*models.{{.Table.Name}}, error) { 
	
	var e error 

	var model = &models.{{.Table.Name}}{} 

	// Get the item by key 
	e = r.cache.Get({{.Table.Name}}_Key(id), model) 

	return model, e 
}

// Save creates or updates an existing {{.Table.Name}} model
func (r *{{.Table.Name}}Cache) Save(model *models.{{.Table.Name}}) { 
	
	r.cache.Set({{.Table.Name}}_Key(model.{{.PrimaryKey}}), model)

	// Primary Key 
	r.cache.ZAdd({{.Table.Name}}_Index_ID_Key, 0, {{.Table.Name}}_Key(model.{{.PrimaryKey}}))
	{{range $index := .CacheConfig.Indices}}{{ if not $index.Index.Unique }}
	// Index: {{$index.Index.Field}}
	r.AddIndex_{{$index.Columns | columnsToMethodName}}(model)
	{{else}}
	// Unique Index: {{$index.Index.Field}}
	r.AddUniqueIndex_{{$index.Columns | columnsToMethodName}}(model)
	{{end}}{{end}}
}

{{range $index := .CacheConfig.Indices}}{{ if not $index.Index.Unique }}
// AddIndex_{{$index.Columns | columnsToMethodName}} adds an index on the {{$index.Index.Field}} field(s)
func (r *{{$.Table.Name}}Cache) AddIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) { 
	r.cache.ZAdd(
		{{$.Table.Name}}_Index_{{range $column := $index.Columns}}{{$column.Name}}_{{end}}Key({{range $column := $index.Columns}}
			model.{{$column.Name}},{{end}}
		), 
		0,
		{{$.Table.Name}}_Key(model.{{$.PrimaryKey}}),
	)
}

// RemoveIndex_{{$index.Columns | columnsToMethodName}} removes an index on the {{$index.Index.Field}} field
func (r *{{$.Table.Name}}Cache) RemoveIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) { 
	r.cache.ZRem(
		{{$.Table.Name}}_Index_{{range $column := $index.Columns}}{{$column.Name}}_{{end}}Key({{range $column := $index.Columns}}
			model.{{$column.Name}},{{end}}
		), 
		{{$.Table.Name}}_Key(model.{{$.PrimaryKey}}),
	)
}
{{else}}
// AddUniqueIndex_{{$index.Columns | columnsToMethodName}} adds an index on the {{$index.Index.Field}} field
func (r *{{$.Table.Name}}Cache) AddUniqueIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) { 
	r.cache.HSet(
		{{$.Table.Name}}_Index_{{$index.Columns | columnsToKey}}_Key,
		{{$index.Columns | columnModelValuesToKey}},
		{{$.Table.Name}}_Key(model.{{$.PrimaryKey}}),
	)
}

// RemoveUniqueIndex_{{$index.Columns | columnsToMethodName}} removes an index on the {{$index.Index.Field}} field
func (r *{{$.Table.Name}}Cache) RemoveUniqueIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) { 
	r.cache.HDel(
		{{$.Table.Name}}_Index_{{$index.Columns | columnsToKey}}_Key, 
		{{$index.Columns | columnModelValuesToKey}}, 
	)
}
{{end}}{{end}}

// Delete removes a {{.Table.Name}} object from the cache
func (r *{{.Table.Name}}Cache) Delete(id int64) { 
	
	var e error 
	var model = &models.{{.Table.Name}}{} 

	if e = r.cache.Get({{.Table.Name}}_Key(id), model); e == nil { 

		// Delete the key 
		r.cache.Del({{.Table.Name}}_Key(id))

		// Primary Key 
		r.cache.ZRem({{.Table.Name}}_Index_ID_Key, {{.Table.Name}}_Key(id))
		{{range $index := .CacheConfig.Indices}}{{ if not $index.Index.Unique}}
		// Index: {{$index.Index.Field}}
		r.RemoveIndex_{{$index.Columns | columnsToMethodName}}(model)
		{{else}}
		// Unique Index: {{$index.Index.Field}}
		r.RemoveUniqueIndex_{{$index.Columns | columnsToMethodName}}(model)
		{{end}}{{end}}
	}
}

// All returns a slice of {{.Table.Name}} objects 
func (r *{{.Table.Name}}Cache) All(page, limit int64) ([]*models.{{.Table.Name}}, error) { 

	var e error 
	var keys []string 
	var collection = []*models.{{.Table.Name}}{} 

	if keys, e = r.cache.ZRangeByScore({{.Table.Name}}_Index_ID_Key, 0, 0, page*limit, limit); e == nil { 
		for k := range keys { 
			var model = &models.{{.Table.Name}}{} 
			if e = r.cache.Get(keys[k], model); e == nil { 
				collection = append(collection, model) 
			}
		}
	}

	return collection, e 
}

// Count returns a count of all {{.Table.Name}} objects 
func (r *{{.Table.Name}}Cache) Count() (int64, error) { 
	return r.cache.ZCard({{.Table.Name}}_Index_ID_Key)
}

{{range $index := .CacheConfig.Indices}}
{{if not $index.Index.Unique}}// From{{$index.Columns | columnsToMethodName}} returns a slice of {{$.Table.Name}} objects by their indexed field '{{$index.Index.Field}}'
func (r *{{$.Table.Name}}Cache) From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}, page, limit int64) ([]*models.{{$.Table.Name}}, error) { 

	var e error 
	var keys []string 
	var collection = []*models.{{$.Table.Name}}{} 

	if keys, e = r.cache.ZRangeByScore({{$.Table.Name}}_Index_{{range $column := $index.Columns}}{{$column.Name}}_{{end}}Key({{range $column := $index.Columns}}{{$column.Name | toArgName}},{{end}}), 0, 0, limit*page, limit); e == nil { 
		for k := range keys { 
			var model = &models.{{$.Table.Name}}{} 
			if e = r.cache.Get(keys[k], model); e == nil { 
				collection = append(collection, model) 
			}
		}
	}

	return collection, e 
} 

// CountFrom{{$index.Columns | columnsToMethodName}} returns a count of items by {{$index.Index.Field}}
func (r *{{$.Table.Name}}Cache) CountFrom{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}) (int64, error) { 
	return r.cache.ZCard({{$.Table.Name}}_Index_{{range $column := $index.Columns}}{{$column.Name}}_{{end}}Key({{$index.Columns | columnsToMethodArgs}}))
}
{{else}}// From{{range $column := $index.Columns}}{{$column.Name}}{{end}} returns a single {{$.Table.Name}} by its unique field(s) '{{$index.Index.Field}}'
func (r *{{$.Table.Name}}Cache) From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}) (*models.{{$.Table.Name}}, error) { 
	var key = r.cache.HGet({{$.Table.Name}}_Index_{{range $column := $index.Columns}}{{$column.Name}}_{{end}}Key, {{$index.Columns | columnValuesToKey}})

	if len(key) > 0 { 
		var model = &models.{{$.Table.Name}}{}
		r.cache.Get(key, model)
		return model, nil 
	}

	return nil, nil 
}
{{end}}
{{end}}
`))
View Source
var DALTemplate = template.Must(template.New("template-dal-file").Funcs(template.FuncMap{
	"dataTypeToGoTypeString": schema.DataTypeToGoTypeString,
	"dataTypeToFormatString": schema.DataTypeToFormatString,
	"toArgName":              toArgName,
}).Parse(`// Generated Code; DO NOT EDIT.

package dal

import ( 
	"{{ .BasePackage }}/gen/definitions/models" 
	"github.com/macinnir/dvc/core/lib/utils/db"
	"github.com/macinnir/dvc/core/lib/utils/log"
	"github.com/macinnir/dvc/core/lib/utils/errors"
	"github.com/macinnir/dvc/core/lib/utils/query"
	"database/sql"
	"context"
	"fmt"{{ if .HasNull }}
	"gopkg.in/guregu/null.v3"{{ end }}{{ if or .IsDateCreated .IsLastUpdated }}
	"time"{{ end }}{{ if .HasSpecialColumns }}
	"strconv"
	"strings"{{ end }}
)

// {{.Table.Name}}DAL is a data repository for {{.Table.Name}} objects
type {{.Table.Name}}DAL struct {
	db  []db.IDB
	log log.ILog
}

// New{{.Table.Name}}DAL returns a new instance of {{.Table.Name}}Repo
func New{{.Table.Name}}DAL(db []db.IDB, log log.ILog) *{{.Table.Name}}DAL {
	return &{{.Table.Name}}DAL{db, log}
}

func (r *{{.Table.Name}}DAL) Raw(shard int64, q string, args ...interface{}) ([]*models.{{.Table.Name}}, error) { 
	return (&models.{{.Table.Name}}{}).Raw(r.db[shard], fmt.Sprintf(q, args...)) 
}

func (r *{{.Table.Name}}DAL) Select(shard int64) *models.{{.Table.Name}}DALSelector { 
	return (&models.{{.Table.Name}}{}).Select(r.db[shard])
}

func (r *{{.Table.Name}}DAL) Count(shard int64) *models.{{.Table.Name}}DALCounter { 
	return (&models.{{.Table.Name}}{}).Count(r.db[shard])
}

func (r *{{.Table.Name}}DAL) Sum(shard int64, col query.Column) *models.{{.Table.Name}}DALSummer { 
	return (&models.{{.Table.Name}}{}).Sum(r.db[shard], col)
}

func (r *{{.Table.Name}}DAL) Min(shard int64, col query.Column) *models.{{.Table.Name}}DALMinner { 
	return (&models.{{.Table.Name}}{}).Min(r.db[shard], col)
}

func (r *{{.Table.Name}}DAL) Max(shard int64, col query.Column) *models.{{.Table.Name}}DALMaxer { 
	return (&models.{{.Table.Name}}{}).Max(r.db[shard], col)
}

func (r *{{.Table.Name}}DAL) Get(shard int64) *models.{{.Table.Name}}DALGetter { 
	return (&models.{{.Table.Name}}{}).Get(r.db[shard])
}

// Create creates a new {{.Table.Name}} entry in the database
func (r *{{.Table.Name}}DAL) Create(shard int64, model *models.{{.Table.Name}}) error { {{if .IsDateCreated}}
	
	model.DateCreated = time.Now().UnixNano() / 1000000{{end}}
	{{if .IsLastUpdated}}
	model.LastUpdated = time.Now().UnixNano() / 1000000
	{{end}}
	e := model.Create(r.db[shard])
	if e != nil {
		r.log.Errorf("{{.Table.Name}}DAL.Insert > %s", e.Error())
		return fmt.Errorf("{{.Table.Name}}DAL.Insert: %w", e)	
	}

	// r.log.Debugf("{{.Table.Name}}DAL.Insert(%d)", model.{{.PrimaryKey}})

	return nil
}

// CreateMany creates {{.Table.Name}} objects in chunks
func (r *{{.Table.Name}}DAL) CreateMany(shard int64, modelSlice []*models.{{.Table.Name}}) error {

	var e error 

	// No records 
	if len(modelSlice) == 0 {
		return nil
	}

	// Don't use a transaction if only a single value
	if len(modelSlice) == 1 {
		e = r.Create(shard, modelSlice[0])
		if e != nil { 
			return fmt.Errorf("{{.Table.Name}}CreateMany([](%d)): %w", len(modelSlice), e)
		}

		return nil 
	}

	chunkSize := 25
	chunks := [][]*models.{{.Table.Name}}{}

	for i := 0; i < len(modelSlice); i += chunkSize {
		end := i + chunkSize
		if end > len(modelSlice) {
			end = len(modelSlice)
		}
		chunks = append(chunks, modelSlice[i:end])
	}

	for chunkID, chunk := range chunks {

		var tx *sql.Tx
		ctx := context.Background()
		tx, e = r.db[shard].BeginTx(ctx, nil)
		if e != nil {
			return fmt.Errorf("{{.Table.Name}}CreateMany([](%d)) (Chunk %d): %w", len(modelSlice), chunkID, e)
		}

		for insertID, model := range chunk {

			{{if .IsDateCreated}}
			model.DateCreated = time.Now().UnixNano() / 1000000{{end}}
			{{if .IsLastUpdated}}
			model.LastUpdated = time.Now().UnixNano() / 1000000{{end}}

			var result sql.Result 
			result, e = tx.ExecContext(ctx, "{{.InsertSQL}}", {{.InsertArgs}})
			if e != nil {
				r.log.Errorf("{{.Table.Name}}.CreateMany([](%d)) (Chunk %d.%d) > %s", len(modelSlice), chunkID, insertID, e.Error())
				break
			} else {
				// r.log.Debugf("{{.Table.Name}}.CreateMany([](%d)) (Chunk %d.%d)", len(modelSlice), chunkID, insertID)
				model.{{.PrimaryKey}}, _ = result.LastInsertId()
			}
		}

		if e != nil {
			return fmt.Errorf("{{.Table.Name}}CreateMany([](%d)) (Chunk %d): %w", len(modelSlice), chunkID, e)
		}

		e = tx.Commit()
		if e != nil {
			return fmt.Errorf("{{.Table.Name}}CreateMany([](%d)) (Chunk %d Commit): %w", len(modelSlice), chunkID, e)
		}
	}

	return nil 

}

// Update updates an existing {{.Table.Name}} entry in the database
func (r *{{.Table.Name}}DAL) Update(shard int64, model *models.{{.Table.Name}}) error {
	var e error
{{if .IsLastUpdated}}
	model.LastUpdated = time.Now().UnixNano() / 1000000{{end}}
	_, e = r.db[shard].Exec("{{.UpdateSQL}}", {{.UpdateArgs}})
	if e != nil {
		r.log.Errorf("{{.Table.Name}}DAL.Update(%d) > %s", model.{{.PrimaryKey}}, e.Error())
		return fmt.Errorf("{{.Table.Name}}DAL.Update(%d): %w", model.{{.PrimaryKey}}, e)
	} else {
		// r.log.Debugf("{{.Table.Name}}DAL.Update(%d)", model.{{.PrimaryKey}})
	}
	return nil
}

// UpdateMany updates a slice of {{.Table.Name}} objects in chunks
func (r {{.Table.Name}}DAL) UpdateMany(shard int64, modelSlice []*models.{{.Table.Name}}) error {
	var e error

	// No records 
	if len(modelSlice) == 0 {
		return nil
	}

	// Don't use a transaction if only a single value
	if len(modelSlice) == 1 {
		e = r.Update(shard, modelSlice[0])
		if e != nil { 
			return fmt.Errorf("{{.Table.Name}}UpdateMany([](%d)): %w", len(modelSlice), e)
		}
		return nil
	}

	chunkSize := 25
	chunks := [][]*models.{{.Table.Name}}{}

	for i := 0; i < len(modelSlice); i += chunkSize {
		end := i + chunkSize
		if end > len(modelSlice) {
			end = len(modelSlice)
		}
		chunks = append(chunks, modelSlice[i:end])
	}

	for chunkID, chunk := range chunks {

		var tx *sql.Tx
		ctx := context.Background()
		tx, e = r.db[shard].BeginTx(ctx, nil)
		if e != nil {
			return fmt.Errorf("{{.Table.Name}}UpdateMany([](%d)) (Chunk %d): %w", len(modelSlice), chunkID, e)
		}

		for updateID, model := range chunk {
{{if .IsLastUpdated}}
			model.LastUpdated = time.Now().UnixNano() / 1000000{{end}}

			_, e = tx.ExecContext(ctx, "{{.UpdateSQL}}", {{.UpdateArgs}})
			if e != nil {
				r.log.Errorf("{{.Table.Name}}.UpdateMany([](%d)) (Chunk %d.%d) > %s", len(modelSlice), chunkID, updateID, e.Error())
				return fmt.Errorf("{{.Table.Name}}UpdateMany([](%d)) (Chunk %d.%d): %w", len(modelSlice), chunkID, updateID, e)
			} else {
				// r.log.Debugf("{{.Table.Name}}.UpdateMany([](%d)) (Chunk %d.%d)", len(modelSlice), chunkID, updateID)
			}
		}

		if e != nil {
			return fmt.Errorf("{{.Table.Name}}UpdateMany([](%d)) (Chunk %d): %w", len(modelSlice), chunkID, e)
		}

		e = tx.Commit()

		if e != nil { 
			return fmt.Errorf("{{.Table.Name}}UpdateMany([](%d)) (Chunk %d Commit): %w", len(modelSlice), chunkID, e)
		}
	}

	return nil

}{{if .IsDeleted}}

// Delete marks an existing {{.Table.Name}} entry in the database as deleted
func (r *{{.Table.Name}}DAL) Delete(shard int64, {{.PrimaryKey | toArgName}} {{.IDType}}) error {
	var e error
	_, e = r.db[shard].Exec("UPDATE ` + "`{{.Table.Name}}` SET `IsDeleted` = 1 WHERE `{{.PrimaryKey}}` = ?" + `", {{.PrimaryKey | toArgName}})
	if e != nil {
		r.log.Errorf("{{.Table.Name}}DAL.Delete(%d) > %s", {{.PrimaryKey | toArgName}}, e.Error())
		return fmt.Errorf("{{.Table.Name}}DAL.Delete(%d): %w", {{.PrimaryKey | toArgName}}, e)
	} else {
		// r.log.Debugf("{{.Table.Name}}DAL.Delete(%d)", {{.PrimaryKey | toArgName}})
	}
	return nil
}

// DeleteMany marks {{.Table.Name}} objects in chunks as deleted
func (r {{.Table.Name}}DAL) DeleteMany(shard int64, modelSlice []*models.{{.Table.Name}}) error {

	var e error 

	// No records 
	if len(modelSlice) == 0 {
		return nil
	}

	// Don't use a transaction if only a single value
	if len(modelSlice) == 1 {
		e = r.Delete(shard, modelSlice[0].{{.PrimaryKey}})

		if e != nil {
			return fmt.Errorf("{{.Table.Name}}DeleteMany([](%d)): %w", len(modelSlice), e)
		}
		return nil
	}

	chunkSize := 25
	chunks := [][]*models.{{.Table.Name}}{}

	for i := 0; i < len(modelSlice); i += chunkSize {
		end := i + chunkSize
		if end > len(modelSlice) {
			end = len(modelSlice)
		}
		chunks = append(chunks, modelSlice[i:end])
	}

	for chunkID, chunk := range chunks {

		var tx *sql.Tx
		ctx := context.Background()
		tx, e = r.db[shard].BeginTx(ctx, nil)
		if e != nil {
			return fmt.Errorf("{{.Table.Name}}DeleteMany([](%d)) (Chunk %d): %w", len(modelSlice), chunkID, e)
		}

		for deleteID, model := range chunk {
{{if .IsLastUpdated}}
			model.LastUpdated = time.Now().UnixNano() / 1000000{{end}}
			_, e = tx.ExecContext(ctx, "UPDATE ` + "`{{.Table.Name}}` SET `IsDeleted`= 1 WHERE `{{.PrimaryKey}}` = ?" + `", model.{{.PrimaryKey}})
			if e != nil {
				r.log.Errorf("{{.Table.Name}}.DeleteMany([](%d)) (Chunk %d.%d) > %s", len(modelSlice), chunkID, deleteID, e.Error())
				return fmt.Errorf("{{.Table.Name}}DeleteMany([](%d)) (Chunk %d.%d): %w", len(modelSlice), chunkID, deleteID, e)
			} else {
				// r.log.Debugf("{{.Table.Name}}.DeleteMany([](%d)) (Chunk %d.%d)", len(modelSlice), chunkID, deleteID)
			}
		}

		if e != nil {
			return fmt.Errorf("{{.Table.Name}}DeleteMany([](%d)) (Chunk %d): %w", len(modelSlice), chunkID, e)
		}

		e = tx.Commit()

		if e != nil { 
			return fmt.Errorf("{{.Table.Name}}DeleteMany([](%d)) (Chunk %d Commit): %w", len(modelSlice), chunkID, e)
		} 
	}

	return nil

}{{end}}

// DeleteHard performs a SQL DELETE operation on a {{.Table.Name}} entry in the database
func (r *{{.Table.Name}}DAL) DeleteHard(shard int64, {{.PrimaryKey | toArgName}} {{.IDType}}) error {
	_, e := r.db[shard].Exec("DELETE FROM ` + "`{{.Table.Name}}`" + ` WHERE {{.PrimaryKey}} = ?", {{.PrimaryKey | toArgName}})
	if e != nil {
		r.log.Errorf("{{.Table.Name}}DAL.HardDelete(%d) > %s", {{.PrimaryKey | toArgName}}, e.Error())
		return fmt.Errorf("{{.Table.Name}}DAL.HardDelete(%d): %w", {{.PrimaryKey | toArgName}}, e)
	} else {
		// r.log.Debugf("{{.Table.Name}}DAL.HardDelete(%d)", {{.PrimaryKey | toArgName}})
	}
	return nil
}

// DeleteManyHard deletes {{.Table.Name}} objects in chunks
func (r {{.Table.Name}}DAL) DeleteManyHard(shard int64, modelSlice []*models.{{.Table.Name}}) error {

	var e error
	// No records 
	if len(modelSlice) == 0 {
		return nil
	}

	// Don't use a transaction if only a single value
	if len(modelSlice) == 1 {
		e = r.DeleteHard(shard, modelSlice[0].{{.PrimaryKey}})
		if e != nil {
			return fmt.Errorf("{{.Table.Name}}DeleteManyHard([](%d)): %w", len(modelSlice), e)
		}	
		return nil
	}

	chunkSize := 25
	chunks := [][]*models.{{.Table.Name}}{}

	for i := 0; i < len(modelSlice); i += chunkSize {
		end := i + chunkSize
		if end > len(modelSlice) {
			end = len(modelSlice)
		}
		chunks = append(chunks, modelSlice[i:end])
	}

	for chunkID, chunk := range chunks {

		var tx *sql.Tx
		ctx := context.Background()
		tx, e = r.db[shard].BeginTx(ctx, nil)
		if e != nil {
			return fmt.Errorf("{{.Table.Name}}DeleteManyHard([](%d)) (Chunk %d): %w", len(modelSlice), chunkID, e)
		}

		for deleteID, model := range chunk {

			_, e = tx.ExecContext(ctx, "DELETE FROM ` + "`{{.Table.Name}}` WHERE `{{.PrimaryKey}}` = ?" + `", model.{{.PrimaryKey}})
			if e != nil {
				r.log.Errorf("{{.Table.Name}}.DeleteManyHard([](%d)) (Chunk %d.%d) > %s", len(modelSlice), chunkID, deleteID, e.Error())
				break
			} else {
				// r.log.Debugf("{{.Table.Name}}.DeleteManyHard([](%d)) (Chunk %d.%d)", len(modelSlice), chunkID, deleteID)
			}
		}

		if e != nil {
			return fmt.Errorf("{{.Table.Name}}DeleteManyHard([](%d)) (Chunk %d): %w", len(modelSlice), chunkID, e)
		}

		e = tx.Commit()

		if e != nil {
			return fmt.Errorf("{{.Table.Name}}DeleteManyHard([](%d)) (Chunk %d Commit): %w", len(modelSlice), chunkID, e)
		}
	}

	return nil
}

// FromID gets a single {{.Table.Name}} object by its Primary Key
func (r *{{.Table.Name}}DAL) FromID(shard int64, {{.PrimaryKey | toArgName}} {{.IDType}}, mustExist bool) (*models.{{.Table.Name}}, error) {

	model, e := (&models.{{.Table.Name}}{}).Get(r.db[shard]).Where(query.EQ(models.{{.Table.Name}}_Column_{{.PrimaryKey}}, {{.PrimaryKey | toArgName}})).Run()

	if model == nil {
		if mustExist { 
			return nil, errors.NewRecordNotFoundError()
		}

		return nil, nil 
	}

	switch e { 
	case sql.ErrNoRows: 
		// r.log.Debugf("{{.Table.Name}}DAL.FromID(%d) > NOT FOUND", {{.PrimaryKey | toArgName}})

		if mustExist {
			e = errors.NewRecordNotFoundError()
			return nil, e 
		}

		return nil, nil
	case nil: 

		{{ if .IsDeleted}}if model.IsDeleted == 1 && mustExist { 
			return nil, errors.NewRecordNotFoundError()
		}{{end}}

		// r.log.Debugf("{{.Table.Name}}DAL.FromID(%d)", model.{{.PrimaryKey}})
		return model, nil 

	default: 
		r.log.Errorf("{{.Table.Name}}DAL.FromID(%d) > %s", {{.PrimaryKey | toArgName}}, e.Error())
		return nil, e 
	}
}

// FromIDs returns a slice of {{.Table.Name}} objects by a set of primary keys
func (r *{{.Table.Name}}DAL) FromIDs(shard int64, {{.PrimaryKey | toArgName}}s []{{.IDType}}) ([]*models.{{.Table.Name}}, error) {

	// No records 
	if len({{.PrimaryKey | toArgName}}s) == 0 {
		return []*models.{{.Table.Name}}{}, nil 
	}

	model, e := (&models.{{.Table.Name}}{}).Select(r.db[shard]).Where(
		query.INInt64(models.{{.Table.Name}}_Column_{{.PrimaryKey}}, {{.PrimaryKey | toArgName}}s),
	).Run()

	if e != nil {
		r.log.Errorf("{{.Table.Name}}DAL.FromIDs(%v) > %s", {{.PrimaryKey | toArgName}}s, e.Error())
		return []*models.{{.Table.Name}}{}, fmt.Errorf("{{.Table.Name}}DAL.FromIDs(%v): %w", {{.PrimaryKey | toArgName}}s, e)
	}
	
	// r.log.Debugf("{{.Table.Name}}DAL.FromIDs(%v)", {{.PrimaryKey | toArgName}}s)

	return model, nil 
}

// FromIDsMap returns a map of {{.Table.Name}} objects from primary keys indexed by a set of primary keys
func (r *{{.Table.Name}}DAL) FromIDsMap(shard int64, {{.PrimaryKey | toArgName}}s []{{.IDType}}) (map[{{.IDType}}]*models.{{.Table.Name}}, error) {


	model, e := r.FromIDs(shard, {{.PrimaryKey | toArgName}}s)
	if e != nil { 
		return map[{{.IDType}}]*models.{{.Table.Name}}{}, fmt.Errorf("{{.Table.Name}}DAL.FromIDsMap(%v): %w", {{.PrimaryKey | toArgName}}s, e)
	}
	
	result := make(map[{{.IDType}}]*models.{{.Table.Name}})
	for k := range model {
		result[model[k].{{.PrimaryKey}}] = model[k]
	}
	
	// r.log.Debugf("{{.Table.Name}}DAL.FromIDsMap(%v)", {{.PrimaryKey | toArgName}}s)

	return result, nil 
}


{{range $col := .SpecialColumns}}
{{if eq $col.DataType "vector"}}

// Get{{$col.Name}} gets the {{$col.Name}} column on a {{$.Table.Name}} object
func (r *{{$.Table.Name}}DAL) Get{{$col.Name}}(shard int64, {{$.PrimaryKey | toArgName}} {{$.IDType}}) ([]float64, error) {
	
	var vectorString null.String
	err := r.db[shard].QueryRow("SELECT VEC_ToText(` + "`{{.Name}}`) AS `{{.Name}}` FROM " + "`{{$.Table.Name}}`" + ` WHERE ` + "`{{$.PrimaryKey}}` = ?" + `", {{$.PrimaryKey | toArgName}}).Scan(&vectorString)
	if err != nil {
		r.log.Errorf("{{$.Table.Name}}DAL.Get{{$col.Name}}(%d) > %s", {{$.PrimaryKey | toArgName}}, err.Error())
		return nil, fmt.Errorf("{{$.Table.Name}}DAL.Get{{$col.Name}}(%d): %w", {{$.PrimaryKey | toArgName}}, err)
	}

	if !vectorString.Valid {
		return nil, nil 
	}

	stringSlice := strings.Split(vectorString.String, ", ")
	
	// 2. Create a slice to store the resulting float64 values
	floatSlice := make([]float64, len(stringSlice))
	
	// 3. Iterate over the string slice and parse each element
	for i, s := range stringSlice {
		// Use ParseFloat with a bitSize of 64 for float64
		f, err := strconv.ParseFloat(s, 64)
		if err != nil {
			// Handle the error (e.g., log it, skip the value, or return)
			fmt.Printf("Error parsing float from string %s: %v\n", s, err)
			continue
		}
		floatSlice[i] = f
	}

	if err != nil {
		r.log.Errorf("{{$.Table.Name}}DAL.Get{{$col.Name}}Vector(%d) > %s", {{$.PrimaryKey | toArgName}}, err.Error())
		return nil, fmt.Errorf("{{$.Table.Name}}DAL.Get{{$col.Name}}(%d): %w", {{$.PrimaryKey | toArgName}}, err)
	}

	return floatSlice, nil 
}

// Set{{$col.Name}} sets the {{$col.Name}} column on a {{$.Table.Name}} object
func (r *{{$.Table.Name}}DAL) Set{{$col.Name}}Vector(shard int64, {{$.PrimaryKey | toArgName}} {{$.IDType}}, {{$col.Name | toArgName}} []float64) error {
	
	stringSlice := make([]string, 0, len({{$col.Name | toArgName}}))

	// 3. Iterate over the float64 slice and convert each element to a string
	for _, f := range {{$col.Name | toArgName}} {
		// 'f' format, -1 precision (smallest number of digits necessary), 64-bit float
		s := strconv.FormatFloat(f, 'f', -1, 64)
		stringSlice = append(stringSlice, s)
	}

	// 4. Join the string slice into a single string with a delimiter (e.g., a comma and space)
	result := "[" + strings.Join(stringSlice, ", ") + "]"

	_, e := r.db[shard].Exec("UPDATE ` + "`{{$.Table.Name}}` SET `{{$col.Name}}` = VEC_FromText(?) WHERE `{{$.PrimaryKey}}` = ?" + `", result, {{$.PrimaryKey | toArgName}})
	if e != nil {
		r.log.Errorf("{{$.Table.Name}}DAL.Set{{$col.Name}}(%d, %v) > %s", {{$.PrimaryKey | toArgName}}, {{$col.Name | toArgName}}, e.Error())
		return fmt.Errorf("{{$.Table.Name}}DAL.Set{{$col.Name}}(%d, %v): %w", {{$.PrimaryKey | toArgName}}, {{$col.Name | toArgName}}, e)
	} else {
		// r.log.Debugf("{{$.Table.Name}}DAL.Set{{$col.Name}}(%d, %v)", {{$.PrimaryKey | toArgName}}, {{$col.Name | toArgName}})
	}
	return nil 
}
{{end}}
{{end}}

{{range $col := .UpdateColumns}}
// Set{{$col.Name}} sets the {{$col.Name}} column on a {{$.Table.Name}} object
func (r *{{$.Table.Name}}DAL) Set{{$col.Name}}(shard int64, {{$.PrimaryKey | toArgName}} {{$.IDType}}, {{$col.Name | toArgName}} {{$col | dataTypeToGoTypeString}}) error {
	_, e := r.db[shard].Exec("UPDATE ` + "`{{$.Table.Name}}` SET `{{$col.Name}}` = ? WHERE `{{$.PrimaryKey}}` = ?" + `", {{$col.Name | toArgName}}, {{$.PrimaryKey | toArgName}})
	if e != nil {
		r.log.Errorf("{{$.Table.Name}}DAL.Set{{$col.Name}}(%d, %v) > %s", {{$.PrimaryKey | toArgName}}, {{$col.Name | toArgName}}, e.Error())
		return fmt.Errorf("{{$.Table.Name}}DAL.Set{{$col.Name}}(%d, %v): %w", {{$.PrimaryKey | toArgName}}, {{$col.Name | toArgName}}, e)
	} else {
		// r.log.Debugf("{{$.Table.Name}}DAL.Set{{$col.Name}}(%d, %v)", {{$.PrimaryKey | toArgName}}, {{$col.Name | toArgName}})
	}
	return nil 
}

// ManyFrom{{$col.Name}} returns a slice of {{$.Table.Name}} models from {{$col.Name}}
func (r *{{$.Table.Name}}DAL) ManyFrom{{$col.Name}}(shard int64, {{$col.Name | toArgName}} {{$col | dataTypeToGoTypeString}}, limit, offset int64, orderBy, orderDir string) ([]*models.{{$.Table.Name}}, error) {
	
	q := (&models.{{$.Table.Name}}{}).Select(r.db[shard]).Where(
		query.EQ(models.{{$.Table.Name}}_Column_{{$col.Name}}, {{$col.Name | toArgName}}), 
	)
	
	{{if $.IsDeleted}}
		q.Where(query.And(), query.EQ(models.{{$.Table.Name}}_Column_IsDeleted, 0)){{end}}

	if len(orderBy) > 0 { 
		q.OrderBy(query.Column(orderBy), query.OrderDirFromString(orderDir))
	}

	if limit > 0 { 
		q.Limit(limit, offset) 
	}

	collection, e := q.Run()

	if e != nil {
		r.log.Errorf("{{$.Table.Name}}DAL.ManyFrom{{$col.Name}}({{if or (eq $col.GoType "int") (eq $col.GoType "int64")}}%d{{else}}%s{{end}}, %d, %d, %s, %s) > %s", {{$col.Name | toArgName}}, limit, offset, orderBy, orderDir, e.Error())
		return nil, e 
	} 
	
	// r.log.Debugf("{{$.Table.Name}}DAL.ManyFrom{{$col.Name}}({{if or (eq $col.GoType "int") (eq $col.GoType "int64")}}%d{{else}}%s{{end}}, %d, %d, %s, %s)", {{$col.Name | toArgName}}, limit, offset, orderBy, orderDir)
	
	return collection, nil 
}

{{if or (eq $col.GoType "int64") (eq $col.GoType "int")}}
// ManyFrom{{$col.Name}}s returns a slice of {{$.Table.Name}} models from {{$col.Name}}s
func (r *{{$.Table.Name}}DAL) ManyFrom{{$col.Name}}s(shard int64, {{$col.Name | toArgName}}s []{{$col | dataTypeToGoTypeString}}, limit, offset int64, orderBy, orderDir string) ([]*models.{{$.Table.Name}}, error) {
		
	// No records 
	if len({{$col.Name | toArgName}}s) == 0 {
		return nil, nil 
	}

	q := (&models.{{$.Table.Name}}{}).Select(r.db[shard]).Where(
		query.INInt{{if eq $col.GoType "int64"}}64{{end}}(models.{{$.Table.Name}}_Column_{{$col.Name}}, {{$col.Name | toArgName}}s), {{if $.IsDeleted}}		
		query.And(), 
		query.EQ(models.{{$.Table.Name}}_Column_IsDeleted, 0),{{end}}
	)

	if len(orderBy) > 0 { 
		q.OrderBy(query.Column(orderBy), query.OrderDirFromString(orderDir))
	}
	
	if limit > 0 { 
		q.Limit(limit, offset) 
	}
	
	collection, e := q.Run()

	if e != nil {
		r.log.Errorf("{{$.Table.Name}}DAL.ManyFrom{{$col.Name}}s(%v, %d, %d, %s, %s) > %s", {{$col.Name | toArgName}}s, limit, offset, orderBy, orderDir, e.Error())
	} else {
		// r.log.Debugf("{{$.Table.Name}}DAL.ManyFrom{{$col.Name}}s(%d, %d, %s, %s)", limit, offset, orderBy, orderDir)
	}
	return collection, e 
}
{{end}}

// CountFrom{{$col.Name}} returns the number of {{$.Table.Name}} records from {{$col.Name}}
func (r *{{$.Table.Name}}DAL) CountFrom{{$col.Name}}(shard int64, {{$col.Name | toArgName}} {{$col | dataTypeToGoTypeString}}) (int64, error) {
	
	count, e := (&models.{{$.Table.Name}}{}).Count(r.db[shard]).Where(
		query.EQ(models.{{$.Table.Name}}_Column_{{$col.Name}}, {{$col.Name | toArgName}}),{{if $.IsDeleted}}		
		query.And(), 
		query.EQ(models.{{$.Table.Name}}_Column_IsDeleted, 0), {{end}}
	).Run()

	if e != nil {
		r.log.Errorf("{{$.Table.Name}}DAL.CountFrom{{$col.Name}}({{$col | dataTypeToFormatString}}) > %s", {{$col.Name | toArgName}}, e.Error())
	} else {
		// r.log.Debugf("{{$.Table.Name}}DAL.CountFrom{{$col.Name}}({{$col | dataTypeToFormatString}})", {{$col.Name | toArgName}})
	}

	return count, e
}

// SingleFrom{{$col.Name}} returns a single {{$.Table.Name}} record by its {{$col.Name}}
func (r *{{$.Table.Name}}DAL) SingleFrom{{$col.Name}}(shard int64, {{$col.Name | toArgName}} {{$col | dataTypeToGoTypeString}}, mustExist bool) (*models.{{$.Table.Name}}, error) {

	model, e := (&models.{{$.Table.Name}}{}).Get(r.db[shard]).Where(
		query.EQ(models.{{$.Table.Name}}_Column_{{$col.Name}}, {{$col.Name | toArgName}}),{{if $.IsDeleted}}
		query.And(), 
		query.EQ(models.{{$.Table.Name}}_Column_IsDeleted, 0), {{end}}
	).Run()

	if model == nil {
		if mustExist { 
			return nil, errors.NewRecordNotFoundError()
		}

		return nil, nil 
	}

	switch e { 
	case sql.ErrNoRows: 
		// r.log.Debugf("{{$.Table.Name}}DAL.SingleFrom{{$col.Name}}(%d) > NOT FOUND", {{$col.Name | toArgName}})

		if mustExist {
			e = errors.NewRecordNotFoundError()
			return nil, e 
		}

		return nil, nil
	case nil: 

		{{if $.IsDeleted}}if model.IsDeleted == 1 && mustExist { 
			return nil, errors.NewRecordNotFoundError()
		}{{end}}

		
		// r.log.Debugf("{{$.Table.Name}}DAL.SingleFrom{{$col.Name}}({{if $col.IsString}}%s{{end}}{{if not $col.IsString}}%d{{end}})", model.{{$col.Name}})
		return model, nil 

	default: 
		r.log.Errorf("{{$.Table.Name}}DAL.SingleFrom{{$col.Name}}({{if $col.IsString}}%s{{end}}{{if not $col.IsString}}%d{{end}}) > %s", {{$col.Name | toArgName}}, e.Error())
		return nil, e 
	}
}{{end}}

// ManyPaged returns a slice of {{.Table.Name}} models
func (r *{{.Table.Name}}DAL) ManyPaged(shard int64, limit, offset int64, orderBy, orderDir string) ([]*models.{{.Table.Name}}, error) {

	q := (&models.{{.Table.Name}}{}).Select(r.db[shard]){{if $.IsDeleted}}		
	q.Where(
		query.EQ(models.{{.Table.Name}}_Column_IsDeleted, 0),
	)
	{{end}}
	if len(orderBy) > 0 { 
		q.OrderBy(query.Column(orderBy), query.OrderDirFromString(orderDir))
	}
	
	if limit > 0 { 
		q.Limit(limit, offset) 
	}
	
	collection, e := q.Run()

	if e != nil {
		r.log.Errorf("{{.Table.Name}}DAL.ManyPaged(%d, %d, %s, %s) > %s", limit, offset, orderBy, orderDir, e.Error())
	} else {
		// r.log.Debugf("{{.Table.Name}}DAL.ManyPaged(%d, %d, %s, %s)", limit, offset, orderBy, orderDir)
	}
	return collection, e 
}
{{ if gt (len .StringColumns) 0 }}{{ range $col := .StringColumns}}
// Search{{$col.Name}} searches the {{$col.Name}} field in the {{$.Table.Name}} table
func (r *{{$.Table.Name}}DAL) Search{{$col.Name}}(shard int64, queryString string, limit, offset int64, leftOrRightOrBoth int) ([]*models.{{$.Table.Name}}, error) { 

	q := (&models.{{$.Table.Name}}{}).Select(r.db[shard]){{if $.IsDeleted}}		
	q.Where(
		query.EQ(models.{{$.Table.Name}}_Column_IsDeleted, 0),
	){{end}}

	// Search left
	switch leftOrRightOrBoth { 
	case 2: 
		// Search both 
		queryString = "%" + queryString + "%"
	case 1: 
		// Search right 
		queryString = "%" + queryString
	default:  
		// Search left (0)
		queryString += "%"
	} 

	q.Where(query.Like(models.{{$.Table.Name}}_Column_{{$col.Name}}, queryString))
	
	if limit > 0 { 
		q.Limit(limit, offset) 
	}
	
	collection, e := q.Run()

	if e != nil {
		r.log.Errorf("{{$.Table.Name}}DAL.Search(%s, %d) > %s", queryString, limit, e.Error())
	} else {
		// r.log.Debugf("{{$.Table.Name}}DAL.Search(%s, %d)", queryString, limit)
	}
	return collection, e 
}
{{ end }}
{{ end }}
`))
View Source
var RepoInterfaceTemplate = template.Must(template.New("template-repo-interface-file").Funcs(template.FuncMap{
	"dataTypeToGoTypeString": schema.DataTypeToGoTypeString,
	"dataTypeToFormatString": schema.DataTypeToFormatString,
	"toArgName":              toArgName,
	"columnsToMethodName":    columnsToMethodName,
	"columnsToMethodArgs":    columnsToMethodArgs,
	"columnsToMethodParams":  columnsToMethodParams,
	"columnsToKey":           columnsToKey,
	"columnValuesToKey":      columnValuesToKey,
	"columnModelValuesToKey": columnModelValuesToKey,
}).Parse(`// Generated Code; DO NOT EDIT.

package repos

import ( 
	"{{ .BasePackage }}/gen/definitions/models" 
	"{{ .BasePackage }}/gen/definitions/collections"{{ if gt (len .CacheConfig.Location) 0}}
	"{{ .BasePackage }}/{{ .CacheConfig.Location }}"{{end}}
)

// I{{.Table.Name}}Repo is an interface for the {{.Table.Name}} repo
type I{{.Table.Name}}Repo interface {
	FromID(id int64, mustExist bool) (*models.{{.Table.Name}}, error){{if .CacheConfig.HasHashID}}
	FromHashID(hashID string, mustExist bool) (*models.{{.Table.Name}}, error){{end}}{{ if gt (len .CacheConfig.Properties) 0 }}
	AggregateFromID(id int64, mustExist bool) (*aggregates.{{.Table.Name}}Aggregate, error){{end}}
	Reset({{.PrimaryKey | toArgName}} int64) error
	Create(model *models.{{.Table.Name}}) error
	CreateMany(modelSlice []*models.{{.Table.Name}}) error
	Update(model *models.{{.Table.Name}}) error
	UpdateMany(modelSlice []*models.{{.Table.Name}}) error
	Delete(id int64) error
	DeleteMany(modelSlice []*models.{{.Table.Name}}) error
	All(page, limit int64) ([]*models.{{.Table.Name}}, error)
	AllAsCollection(page, limit int64) (*collections.{{.Table.Name}}Collection, error)

	{{range $index := .CacheConfig.Indices}}{{ if not $index.Index.Unique}}From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}, page, limit int64) ([]*models.{{$.Table.Name}}, error)
	CollectionFrom{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}, page, limit int64) (*collections.{{$.Table.Name}}Collection, error){{else}}From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}, mustExist bool) (*models.{{$.Table.Name}}, error){{if gt (len $.CacheConfig.Properties) 0}}
	AggregateFrom{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}, mustExist bool) (*aggregates.{{$.Table.Name}}Aggregate, error){{end}}{{end}}
	{{end}}{{range $index := .CacheConfig.Indices}}{{ if not $index.Index.Unique }}
	AddIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) 
	RemoveIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) {{else}}
	AddUniqueIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) 
	RemoveUniqueIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}){{end}}{{end}}
	{{if gt (len .CacheConfig.Search) 0}}{{range $search := .CacheConfig.Search}}
	// Search{{$search.SearchColumns | columnsToMethodName}} searches the {{range $col := $search.SearchColumns}}{{$col.Name}}{{end}} 
	// leftOrRightOrCenter is 2 == Center, 1 == Right, 0 (default) == Left
	Search{{$search.SearchColumns | columnsToMethodName}}({{$search.ConditionColumns | columnsToMethodParams}}{{if gt (len $search.ConditionColumns) 0}},{{end}}{{ $search.SearchColumns | columnsToMethodParams }}, leftOrRightOrCenter, page, limit int64) ([]*models.{{$.Table.Name}}, error){{end}}{{end}} 
}

`))
View Source
var RepoTemplate = template.Must(template.New("template-repo-file").Funcs(template.FuncMap{
	"dataTypeToGoTypeString": schema.DataTypeToGoTypeString,
	"dataTypeToFormatString": schema.DataTypeToFormatString,
	"toArgName":              toArgName,
	"columnsToMethodName":    columnsToMethodName,
	"columnsToMethodArgs":    columnsToMethodArgs,
	"columnsToMethodParams":  columnsToMethodParams,
	"columnsToKey":           columnsToKey,
	"columnValuesToKey":      columnValuesToKey,
	"columnModelValuesToKey": columnModelValuesToKey,
}).Parse(`// Generated Code; DO NOT EDIT.

package repos

import ( 
	"{{ .BasePackage }}/gen/definitions/collections" 
	"{{ .BasePackage }}/gen/definitions/models" 
	"{{ .BasePackage }}/gen/definitions/caches" 
	"{{ .BasePackage }}/gen/definitions/dal" 
	"{{ .BasePackage }}/core/components/config" 
	{{ if .CacheConfig.HasHashID }}"{{ .BasePackage }}/core/utils/hashids"{{end}}{{ if gt (len .CacheConfig.Location) 0}}
	"{{ .BasePackage }}/{{ .CacheConfig.Location }}"{{end}}{{if gt (len .CacheConfig.Search) 0}}
	"github.com/macinnir/dvc/core/lib/utils/query"{{end}}

	"fmt"
)


// {{.Table.Name}}Repo is a repo for {{.Table.Name}} objects
type {{.Table.Name}}Repo struct {
	config *config.Config
	{{.Table.Name | toArgName}}Cache caches.I{{.Table.Name}}Cache
	{{.Table.Name | toArgName}}DAL dal.I{{.Table.Name}}DAL
	{{ if .CacheConfig.HasHashID }}idHasher             *hashids.IDHasher{{end}}{{ if gt (len .CacheConfig.Properties) 0}}{{range $agg := .CacheConfig.Properties}}
	{{$agg.Aggregate.Table | toArgName}}Repo *{{$agg.Aggregate.Table}}Repo{{end}}{{end}}
}

// New{{.Table.Name}}Repo returns a new instance of {{.Table.Name}}Repo
func New{{.Table.Name}}Repo(
	config *config.Config, 
	{{.Table.Name | toArgName}}Cache caches.I{{.Table.Name}}Cache,
	{{.Table.Name | toArgName}}DAL dal.I{{.Table.Name}}DAL, 
	{{ if .CacheConfig.HasHashID }}idHasher             *hashids.IDHasher,{{end}}{{ if gt (len .CacheConfig.Properties) 0}}{{range $agg := .CacheConfig.Properties}}
	{{$agg.Aggregate.Table | toArgName}}Repo *{{$agg.Aggregate.Table}}Repo,{{end}}{{end}}
) *{{.Table.Name}}Repo {
	return &{{.Table.Name}}Repo{
		config, 
		{{.Table.Name | toArgName}}Cache,
		{{.Table.Name | toArgName}}DAL, 
		{{ if .CacheConfig.HasHashID }}idHasher,{{end}}{{ if gt (len .CacheConfig.Properties) 0}}{{range $agg := .CacheConfig.Properties}}
		{{$agg.Aggregate.Table | toArgName}}Repo,{{end}}{{end}}
	}
}

// FromID retrieves a {{.Table.Name}} model by its primary key
func (r *{{.Table.Name}}Repo) FromID(id int64, mustExist bool) (*models.{{.Table.Name}}, error) { 
	
	var model *models.{{.Table.Name}}
	var e error 
	
	if model, e = r.{{.Table.Name | toArgName}}Cache.FromID(id); e != nil { 
		return nil, e 
	}

	if model != nil { 
		return model, nil 
	}


	if model, e = r.{{.Table.Name | toArgName}}DAL.FromID(config.DEFAULT_SHARD, id, mustExist); e != nil { 
		return nil, e 
	}

	if model != nil { 
		r.{{.Table.Name | toArgName}}Cache.Save(model)
	}

	return model, e 
}

// Reset deletes a {{.Table.Name}} object from the cache and resaves it (if it exists).
func (r *{{.Table.Name}}Repo) Reset({{.PrimaryKey | toArgName}} int64) error { 

	var e error 
	var model *models.{{.Table.Name}}

	if model, e = r.{{.Table.Name | toArgName}}DAL.FromID(config.DEFAULT_SHARD, {{.PrimaryKey | toArgName}}, false); e != nil { 
		return e 
	}

	// No model in the database, so delete it from the cache
	if model == nil { 
		r.{{.Table.Name | toArgName}}Cache.Delete({{.PrimaryKey | toArgName}})
		return nil 
	}

	// Reset the cache 
	r.{{.Table.Name | toArgName}}Cache.Save(model) 
	return nil 
}

{{ if .CacheConfig.HasHashID }}// FromHashID returns a {{.Table.Name}} object based on its unique hashID
func (r *{{.Table.Name}}Repo) FromHashID(hashID string, mustExist bool) (*models.{{.Table.Name}}, error) { 

	var id = r.idHasher.FromHashID(hashID)

	return r.FromID(id, mustExist) 
}
{{ end }}{{ if gt (len .CacheConfig.Properties) 0 }}
// AggregateFromID returns a {{.Table.Name}}Aggregate object 
func (r *{{.Table.Name}}Repo) AggregateFromID(id int64, mustExist bool) (*aggregates.{{.Table.Name}}Aggregate, error) { 

	var model *models.{{.Table.Name}}
	var e error 

	if model, e = r.FromID(id, true); e != nil { 
		return nil, e 
	}

	var agg = &aggregates.{{.Table.Name}}Aggregate{ 
		{{.Table.Name}}: model, 
	}
	{{range $agg := .CacheConfig.Properties}}
	if agg.{{$agg.Aggregate.Property}}, e =  r.{{$agg.Aggregate.Table | toArgName}}Repo.From{{ if eq $agg.Aggregate.Type "Many"}}{{$agg.Aggregate.On}}{{ else }}ID{{ end }}(model.{{$agg.Aggregate.On}}, {{ if eq $agg.Aggregate.Type "Many" }}0, 0{{ else }}true{{end}}); e != nil { 
		return nil, e 
	}{{end}}

	return agg, nil
}
{{ end }}
// Create creates or updates an existing {{.Table.Name}} model
func (r *{{.Table.Name}}Repo) Create(model *models.{{.Table.Name}}) error { 
	
	var e error 

	if e = r.{{.Table.Name | toArgName}}DAL.Create(config.DEFAULT_SHARD, model); e != nil { 
		return e 
	}

	r.{{.Table.Name | toArgName}}Cache.Save(model) 
	
	return e 
}

// CreateMany creates a slice of {{.Table.Name}} objects 
func (r *{{.Table.Name}}Repo) CreateMany(modelSlice []*models.{{.Table.Name}}) error { 
	
	var  e error 

	if e = r.{{.Table.Name | toArgName}}DAL.CreateMany(config.DEFAULT_SHARD, modelSlice); e != nil { 
		return e 
	}

	for k := range modelSlice { 
		r.{{.Table.Name | toArgName}}Cache.Save(modelSlice[k]) 
	}

	return nil 
}

// Update updates an existing {{.Table.Name}} model
func (r *{{.Table.Name}}Repo) Update(model *models.{{.Table.Name}}) error { 

	var e = r.{{.Table.Name | toArgName}}DAL.Update(config.DEFAULT_SHARD, model) 
	
	if e == nil { 
		r.{{.Table.Name | toArgName}}Cache.Save(model) 
	}
	
	return e 
}

// UpdateMany updates a slice of {{.Table.Name}} objects 
func (r *{{.Table.Name}}Repo) UpdateMany(modelSlice []*models.{{.Table.Name}}) error { 

	for k := range modelSlice { 
		r.{{.Table.Name | toArgName}}Cache.Save(modelSlice[k]) 
	}

	return r.{{.Table.Name | toArgName}}DAL.UpdateMany(config.DEFAULT_SHARD, modelSlice)
}

// Delete removes a {{.Table.Name}} object from the cache
func (r *{{.Table.Name}}Repo) Delete(id int64) error { 
	r.{{.Table.Name | toArgName}}Cache.Delete(id) 
	return r.{{.Table.Name | toArgName}}DAL.Delete(config.DEFAULT_SHARD, id)
}

// DeleteMany deletes a slice of {{.Table.Name}} objects 
func (r *{{.Table.Name}}Repo) DeleteMany(modelSlice []*models.{{.Table.Name}}) error { 

	for k := range modelSlice { 
		r.{{.Table.Name | toArgName}}Cache.Delete(modelSlice[k].{{.PrimaryKey}}) 
	}

	return r.{{.Table.Name | toArgName}}DAL.DeleteMany(config.DEFAULT_SHARD, modelSlice)
}

// All returns a slice of {{.Table.Name}} objects 
func (r *{{.Table.Name}}Repo) All(page, limit int64) ([]*models.{{.Table.Name}}, error) { 
	
	var e error 
	var items []*models.{{.Table.Name}}

	if items, e = r.{{$.Table.Name | toArgName}}Cache.All(page, limit); e != nil { 
		return nil, e 
	}

	if len(items) == 0 { 
		
		if items, e = r.{{$.Table.Name | toArgName}}DAL.ManyPaged(config.DEFAULT_SHARD, limit, page*limit, "", ""); e != nil {
			return nil, fmt.Errorf("{{$.Table.Name}}Repo::All() -> {{$.Table.Name}}DAL.ManyPaged(): %w", e)
		}

		if len(items) > 0 { 
			for k := range items { 
				r.{{$.Table.Name | toArgName}}Cache.Save(items[k])
			}
		}
	}

	return items, nil 
}

// AllAsCollection returns a collection of {{.Table.Name}} objects 
func (r *{{.Table.Name}}Repo) AllAsCollection(page, limit int64) (*collections.{{.Table.Name}}Collection, error) { 
	
	var e error 
	var collection = &collections.{{.Table.Name}}Collection{}

	if collection.Data, e = r.{{$.Table.Name | toArgName}}Cache.All(page, limit); e != nil { 
		return nil, e 
	}

	if len(collection.Data) == 0 { 
		
		if collection.Data, e = r.{{$.Table.Name | toArgName}}DAL.ManyPaged(config.DEFAULT_SHARD, limit, page*limit, "", ""); e != nil {
			return nil, fmt.Errorf("{{$.Table.Name}}Repo::AllAsCollection() -> {{$.Table.Name}}DAL.ManyPaged(): %w", e)
		}

		if len(collection.Data) > 0 { 
			for k := range collection.Data { 
				r.{{$.Table.Name | toArgName}}Cache.Save(collection.Data[k])
			}
		}

		if collection.Count, e = r.{{$.Table.Name | toArgName}}DAL.Count(config.DEFAULT_SHARD).Run(); e != nil { 
			return nil, fmt.Errorf("{{$.Table.Name}}Repo::AllAsCollection() -> {{$.Table.Name}}DAL.Count(): %w", e)
		}
	}

	if collection.Count, e = r.{{$.Table.Name | toArgName}}Cache.Count(); e != nil { 
		return nil, e 
	}


	return collection, nil 
}
{{range $index := .CacheConfig.Indices}}
{{if not $index.Index.Unique}}// From{{$index.Columns | columnsToMethodName}} returns a collection of {{$.Table.Name}} objects by their indexed field '{{$index.Index.Field}}'
func (r *{{$.Table.Name}}Repo) From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}, page, limit int64) ([]*models.{{$.Table.Name}}, error) { 

	var e error 
	var items = []*models.{{$.Table.Name}}{} 

	if items, e = r.{{$.Table.Name | toArgName}}Cache.From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodArgs}}, page, limit); e != nil { 
		return nil, e 
	}

	if len(items) == 0 { 
		
		if items, e = r.{{$.Table.Name | toArgName}}DAL.ManyFrom{{$index.Columns | columnsToMethodName}}(config.DEFAULT_SHARD, {{$index.Columns | columnsToMethodArgs}}, limit, page*limit, "", ""); e != nil {
			return nil, fmt.Errorf("{{$.Table.Name}}Repo::All() -> {{$.Table.Name}}DAL.ManyPaged(): %w", e)
		}

		if len(items) > 0 { 
			for k := range items { 
				r.{{$.Table.Name | toArgName}}Cache.Save(items[k])
			}
		}
	}

	return items, nil
} 

// CollectionFrom{{$index.Columns | columnsToMethodName}} returns a collection of {{$.Table.Name}} objects by their indexed field '{{$index.Index.Field}}'
func (r *{{$.Table.Name}}Repo) CollectionFrom{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}, page, limit int64) (*collections.{{$.Table.Name}}Collection, error) { 

	var e error 
	var collection = &collections.{{$.Table.Name}}Collection{} 

	if collection.Data, e = r.From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodArgs}}, page, limit); e != nil { 
		return nil, e 
	}

	if collection.Count, e = r.{{$.Table.Name | toArgName}}Cache.CountFrom{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodArgs}}); e != nil { 
		return nil, e 
	}

	return collection, nil
}
{{else}}// From{{$index.Columns | columnsToMethodName}} returns a single {{$.Table.Name}} by its unique field(s) '{{$index.Index.Field}}'
func (r *{{$.Table.Name}}Repo) From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}, mustExist bool) (*models.{{$.Table.Name}}, error) { 
	
	var model, e = r.{{$.Table.Name | toArgName}}Cache.From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodArgs}}) 
	
	if e != nil || model == nil { 
	
		if model, e = r.{{$.Table.Name | toArgName}}DAL.SingleFrom{{$index.Columns | columnsToMethodName}}(config.DEFAULT_SHARD, {{$index.Columns | columnsToMethodArgs}}, mustExist); e != nil {
			return nil, e 
		}

		if model != nil { 
			r.{{$.Table.Name | toArgName}}Cache.Save(model) 
		}
	}

	return model, e
}
{{ if gt (len $.CacheConfig.Properties) 0 }}
// AggregateFrom{{$index.Columns | columnsToMethodName}} returns a {{$.Table.Name}}Aggregate object by its unique field(s) '{{$index.Index.Field}}'
func (r *{{$.Table.Name}}Repo) AggregateFrom{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodParams}}, mustExist bool) (*aggregates.{{$.Table.Name}}Aggregate, error) { 

	var model, e = r.From{{$index.Columns | columnsToMethodName}}({{$index.Columns | columnsToMethodArgs}}, mustExist) 
	if e != nil { 
		return nil, e 
	}
	
	var agg = &aggregates.{{$.Table.Name}}Aggregate{ 
		{{$.Table.Name}}: model, 
	}
	{{range $agg := $.CacheConfig.Properties}}
	if agg.{{$agg.Aggregate.Property}}, e =  r.{{$agg.Aggregate.Table | toArgName}}Repo.From{{ if eq $agg.Aggregate.Type "Many"}}{{$agg.Aggregate.On}}{{ else }}ID{{ end }}(model.{{$agg.Aggregate.On}}, {{ if eq $agg.Aggregate.Type "Many" }}0, 0{{ else }}true{{end}}); e != nil { 
		return nil, e 
	}
	{{end}}
	return agg, nil
}{{end}}{{end}}{{end}}
{{range $index := .CacheConfig.Indices}}{{ if not $index.Index.Unique }}
// AddIndex_{{$index.Columns | columnsToMethodName}} adds an index on the {{$index.Index.Field}} field(s)
func (r *{{$.Table.Name}}Repo) AddIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) { 
	r.{{$.Table.Name | toArgName}}Cache.AddIndex_{{$index.Columns | columnsToMethodName}}(model)
}

// RemoveIndex_{{$index.Columns | columnsToMethodName}} removes an index on the {{$index.Index.Field}} field
func (r *{{$.Table.Name}}Repo) RemoveIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) { 
	r.{{$.Table.Name | toArgName}}Cache.RemoveIndex_{{$index.Columns | columnsToMethodName}}(model)
}{{else}}

// AddUniqueIndex_{{$index.Columns | columnsToMethodName}} adds an index on the {{$index.Index.Field}} field
func (r *{{$.Table.Name}}Repo) AddUniqueIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) { 
	r.{{$.Table.Name | toArgName}}Cache.AddUniqueIndex_{{$index.Columns | columnsToMethodName}}(model)
}

// RemoveUniqueIndex_{{$index.Columns | columnsToMethodName}} removes an index on the {{$index.Index.Field}} field
func (r *{{$.Table.Name}}Repo) RemoveUniqueIndex_{{$index.Columns | columnsToMethodName}}(model *models.{{$.Table.Name}}) { 
	r.{{$.Table.Name | toArgName}}Cache.RemoveUniqueIndex_{{$index.Columns | columnsToMethodName}}(model)
}{{end}}{{end}}
{{if and (.CacheConfig.Search) (gt (len .CacheConfig.Search) 0)}}{{range $search := .CacheConfig.Search}}
// Search{{$search.SearchColumns | columnsToMethodName}} searches the {{range $col := $search.SearchColumns}}{{$col.Name}},{{end}} column(s) 
// leftOrRightOrCenter is 2 == Center, 1 == Right, 0 (default) == Left
func (r *{{$.Table.Name}}Repo)Search{{$search.SearchColumns | columnsToMethodName}}({{$search.ConditionColumns | columnsToMethodParams}}{{if gt (len $search.ConditionColumns) 0}},{{end}}{{ $search.SearchColumns | columnsToMethodParams }}, leftOrRightOrCenter, page, limit int64) ([]*models.{{$.Table.Name}}, error) { 
	
	var e error
	var model []*models.{{$.Table.Name}}

	q := r.{{$.Table.Name | toArgName}}DAL.Select(config.DEFAULT_SHARD).Where(
		query.EQ(models.{{$.Table.Name}}_Column_IsDeleted, 0), 
		query.And(), 
	)

	switch leftOrRightOrCenter { 
		case 2: 
			// Search both 
			{{range $col := $search.SearchColumns}}{{$col.Name | toArgName}} = "%" + {{$col.Name | toArgName}} + "%"
			{{end}}
		case 1: 
			// Search right 
			{{range $col := $search.SearchColumns}}{{$col.Name | toArgName}} = "%" + {{$col.Name | toArgName}}
			{{end}}
		default:  
			// Search left (0)
			{{range $col := $search.SearchColumns}}{{$col.Name | toArgName}} = {{$col.Name | toArgName}} + "%"
			{{end}}
	} 
	{{if gt (len $search.ConditionColumns) 0}}
	// Conditions
	q.Where(
		query.Ands({{range $col := $search.ConditionColumns}}
			query.EQ(models.{{$.Table.Name}}_Column_{{$col.Name}}, {{ $col.Name | toArgName }}),{{end}}
		),
	)
	{{end}}
	// Search Fields
	q.Where(
		query.Ors({{range $col := $search.SearchColumns}}
			query.Like(models.{{$.Table.Name}}_Column_{{$col.Name}}, {{ $col.Name | toArgName }}),{{end}}
		),
	)
	
	if limit > 0 { 
		q.Limit(limit, limit*page)
	}

	if model, e = q.Run(); e != nil { 
		return nil, e 
	}

	return model, nil 
}
{{end}}{{end}}

// TODO Search with conditions (e.g. AccountID, UserID)
// TODO Search OR (e.g. Title OR Description)
// TODO Search left/all/right search
`))

Functions

func BuildPermissionsGoFile added in v1.8.20

func BuildPermissionsGoFile(permissions []PermissionTplType, permissionsFilePath string) error

func BuildTypescriptPermissions added in v1.8.11

func BuildTypescriptPermissions(permissions []PermissionTplType, permissionsFilePath string) error

BuildTypescriptPermissions returns a formatted typescript file of permission constants

func CleanTypescriptDTOs added in v1.8.91

func CleanTypescriptDTOs(config *lib.Config, routes *lib.RoutesJSONContainer) error

func ColumnMapToNames added in v1.8.89

func ColumnMapToNames(columns map[string]string) []string

func FetchAllPermissionsFromControllers added in v1.8.82

func FetchAllPermissionsFromControllers(controllers []*lib.Controller) (map[string]string, error)

func GenAPIData added in v1.8.95

func GenAPIData(config *lib.Config, routes *lib.RoutesJSONContainer) error

func GenAPIDocs added in v1.8.89

func GenAPIDocs(config *lib.Config, routes *lib.RoutesJSONContainer)

func GenAppBootstrapFile added in v1.8.90

func GenAppBootstrapFile(basePackage string) error

GenAppBootstrapFile generates the services bootstrap file

func GenCacheInterfaces added in v1.8.95

func GenCacheInterfaces(basePackage string, tables []*schema.Table, cache map[string]*lib.CacheConfig) error

func GenCaches added in v1.8.95

func GenCaches(tables []*schema.Table, basePackage string, config map[string]*lib.CacheConfig) error

func GenControllerBootstrap added in v1.8.89

func GenControllerBootstrap(basePackageName string, dirs []string) string

GenControllerBootstrap generates the bootstrap file for the applications controllers

func GenDALs

func GenDALs(tables []*schema.Table, config *lib.Config) error

func GenDTOImportStrings added in v1.8.95

func GenDTOImportStrings(columns map[string]string) string

func GenGoPerms added in v1.8.20

func GenGoPerms(config *lib.Config, permissions []PermissionTplType) (e error)

0.018100 0.000900

func GenInterface

func GenInterface(comment, pkgName, ifaceName, ifaceComment string, methods []string, imports []string) ([]byte, error)

GenInterface takes makes the interface into a byte array

func GenInterface2 added in v1.8.91

func GenInterface2(structName, srcFile, packageName, interfaceName, destDir, destFile string) error

func GenInterfaces

func GenInterfaces(srcDir, destDir string) error

func GenRepoBootstrapFile added in v1.8.95

func GenRepoBootstrapFile(basePackage string, cache map[string]*lib.CacheConfig) error

func GenRepoInterfaces added in v1.8.95

func GenRepoInterfaces(basePackage string, tables []*schema.Table, cache map[string]*lib.CacheConfig) error

func GenRepos added in v1.8.95

func GenRepos(basePackage string, tables []*schema.Table, cache map[string]*lib.CacheConfig) error

func GenRoutesAndPermissions added in v1.8.19

func GenRoutesAndPermissions(schemaList *schema.SchemaList, controllers []*lib.Controller, dirs []string, config *lib.Config) (*lib.RoutesJSONContainer, error)

GenRoutesAndPermissions generates a list of routes from a directory of controller files 0.0824 0.008664

func GenTSPerms added in v1.8.20

func GenTSPerms(config *lib.Config, permissions []PermissionTplType) (e error)

0.014938 seconds 0.005944 0.000568

func GenTSRoutes added in v1.8.89

func GenTSRoutes(controllers []*lib.Controller, config *lib.Config) error

func GenerateCacheBootstrapFile added in v1.8.95

func GenerateCacheBootstrapFile(basePackage string, cache map[string]*lib.CacheConfig) error

func GenerateDALsBootstrapFile

func GenerateDALsBootstrapFile(config *lib.Config, schemaList *schema.SchemaList) error

GenerateDALsBootstrapFile generates a dal bootstrap file in golang

func GenerateGoCache added in v1.8.95

func GenerateGoCache(basePackage string, cacheConfig *lib.CacheConfig, table *schema.Table, dir string) (e error)

GenerateGoDAL returns a string for a repo in golang

func GenerateGoCacheInterface added in v1.8.95

func GenerateGoCacheInterface(basePackage string, cacheConfig *lib.CacheConfig, table *schema.Table, dir string) (e error)

GenerateGoDAL returns a string for a repo in golang

func GenerateGoDAL

func GenerateGoDAL(config *lib.Config, table *schema.Table, dir string) (e error)

GenerateGoDAL returns a string for a repo in golang

func GenerateGoRepo added in v1.8.95

func GenerateGoRepo(basePackage string, cacheConfig *lib.CacheConfig, table *schema.Table, dir string) (e error)

GenerateGoDAL returns a string for a repo in golang

func GenerateGoRepoInterface added in v1.8.95

func GenerateGoRepoInterface(basePackage string, cacheConfig *lib.CacheConfig, table *schema.Table, dir string) (e error)

GenerateGoDAL returns a string for a repo in golang

func GenerateRepoCollection added in v1.8.95

func GenerateRepoCollection(basePackage string, tableName string)

func GenerateRepoCollectionItem added in v1.8.95

func GenerateRepoCollectionItem(basePackage string, tableName string)

func GenerateTypescriptDTO added in v1.8.89

func GenerateTypescriptDTO(name string, columns map[string]string) ([]byte, error)

GenerateTypescriptType returns a string for a type in typescript TODO need a map of all types so that import paths can be used for struct and array types TODO test for struct types (apart from array types)

func GenerateTypescriptModel added in v1.8.89

func GenerateTypescriptModel(name string, columns map[string]string) (string, error)

GenerateTypescriptType returns a string for a type in typescript

func GenerateTypescriptModels added in v1.8.89

func GenerateTypescriptModels(config *lib.Config, routes *lib.RoutesJSONContainer) error

GenerateTypescriptModels returns a string for a typscript types file

func GenerateTypesriptDTOs added in v1.8.89

func GenerateTypesriptDTOs(config *lib.Config, routes *lib.RoutesJSONContainer) error

func ImportString added in v1.8.89

func ImportString(sb io.Writer, fullName, objectName, importPath string, doIncludeConstructor bool)

func ImportStrings added in v1.8.89

func ImportStrings(sb io.Writer, columns map[string]string)

func InheritStrings added in v1.8.89

func InheritStrings(sb io.Writer, columns map[string]string) []string

func LoadPermissionsFromJSON added in v1.8.34

func LoadPermissionsFromJSON() map[string]string

LoadPermissionsFromJSON loads a set of permissions from a JSON file

func LoadRoutes added in v1.8.89

func LoadRoutes(config *lib.Config) (*lib.RoutesJSONContainer, error)

func TSFileHeader added in v1.8.89

func TSFileHeader(sb io.Writer, name string)

Types

type AggregateColumn added in v1.8.95

type AggregateColumn struct {
	Column    *schema.Column
	Aggregate *lib.CacheConfigAggregateProperty
}

type CacheData added in v1.8.95

type CacheData struct {
	Indices    []*IndexColumn
	Properties []*AggregateColumn
	HasHashID  bool
	Location   string
	Search     []*SearchColumn
}

func ParseIndices added in v1.8.95

func ParseIndices(cacheConfig *lib.CacheConfig, table *schema.Table) *CacheData

type Gen

type Gen struct {
	Config *lib.Config
}

Gen conntains all of the generator functionality

func (*Gen) GenerateDALSQL

func (g *Gen) GenerateDALSQL(dir string, database *schema.Schema) (e error)

GenerateDALSQL generates a constants file filled with sql statements

func (*Gen) GetOrphanedDals

func (g *Gen) GetOrphanedDals(dir string, database *schema.Schema) []string

GetOrphanedDals gets repo files that aren't in the database.Tables map

type GoControllerBootstrapTemplateValues added in v1.8.91

type GoControllerBootstrapTemplateValues struct {
	Imports     []string
	Controllers []struct {
		Title string
		Name  string
	}
}

type IndexColumn added in v1.8.95

type IndexColumn struct {
	Columns []*schema.Column
	Index   *lib.CacheConfigIndex
}

type PermissionTplType added in v1.8.91

type PermissionTplType struct {
	Title       string
	Description string
	Name        string
}

func BuildTplPermissions added in v1.8.91

func BuildTplPermissions(permissionMap map[string]string) []PermissionTplType

type RepoBootstrapConfig added in v1.8.95

type RepoBootstrapConfig struct {
	Name   string
	Config *lib.CacheConfig
}

type RoutesTplValues added in v1.8.91

type RoutesTplValues struct {
	Imports     []string
	AppDTOsPath string
	Controllers []*lib.Controller
}

type ScoredRepoItem added in v1.8.95

type ScoredRepoItem struct {
	Name  string
	Score int
}

type SearchColumn added in v1.8.95

type SearchColumn struct {
	ConditionColumns []*schema.Column
	SearchColumns    []*schema.Column
	Search           *lib.CacheConfigSearch
}

type TSRouteGenerator added in v1.8.89

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

func NewTSRouteGenerator added in v1.8.89

func NewTSRouteGenerator(c *lib.Controller) *TSRouteGenerator

func (*TSRouteGenerator) AddImport added in v1.8.89

func (t *TSRouteGenerator) AddImport(importType string)

type TypeToImport added in v1.8.95

type TypeToImport struct {
	FullName     string
	BaseTypeName string
	ObjectName   string
	ImportPath   string
	RequiresNew  bool
}

func NewTypeToImport added in v1.8.95

func NewTypeToImport(fullName string, baseType string) TypeToImport

type TypescriptGenerator added in v1.8.89

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

func NewTypescriptGenerator added in v1.8.89

func NewTypescriptGenerator(config *lib.Config, routes *lib.RoutesJSONContainer) *TypescriptGenerator

func (*TypescriptGenerator) CleanTypescriptAggregates added in v1.8.91

func (tg *TypescriptGenerator) CleanTypescriptAggregates() error

func (*TypescriptGenerator) ExtractColumns added in v1.8.89

func (tg *TypescriptGenerator) ExtractColumns(goType string) map[string]string

func (*TypescriptGenerator) GenerateTypescriptAggregate added in v1.8.89

func (tg *TypescriptGenerator) GenerateTypescriptAggregate(name string) ([]byte, error)

GenerateTypescriptAggregate returns a string for a type in typescript

func (*TypescriptGenerator) GenerateTypescriptAggregates added in v1.8.91

func (tg *TypescriptGenerator) GenerateTypescriptAggregates() error

0.008535

func (*TypescriptGenerator) GenerateTypescriptDefaults added in v1.8.89

func (tg *TypescriptGenerator) GenerateTypescriptDefaults(sb io.Writer, objectName string)

func (*TypescriptGenerator) GenerateTypescriptFields added in v1.8.89

func (tg *TypescriptGenerator) GenerateTypescriptFields(sb io.Writer, objectName string)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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