mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-11-13 09:53:53 +00:00
Preload fixes
This commit is contained in:
parent
ce106fa940
commit
c52fcff61d
58
.vscode/tasks.json
vendored
58
.vscode/tasks.json
vendored
@ -24,21 +24,63 @@
|
|||||||
"type": "go",
|
"type": "go",
|
||||||
"label": "go: test workspace",
|
"label": "go: test workspace",
|
||||||
"command": "test",
|
"command": "test",
|
||||||
|
|
||||||
"options": {
|
"options": {
|
||||||
"env": {
|
"cwd": "${workspaceFolder}"
|
||||||
"CGO_ENABLED": "0"
|
|
||||||
},
|
|
||||||
"cwd": "${workspaceFolder}/bin",
|
|
||||||
},
|
},
|
||||||
"args": [
|
"args": [
|
||||||
"../..."
|
"-v",
|
||||||
|
"-race",
|
||||||
|
"-coverprofile=coverage.out",
|
||||||
|
"-covermode=atomic",
|
||||||
|
"./..."
|
||||||
],
|
],
|
||||||
"problemMatcher": [
|
"problemMatcher": [
|
||||||
"$go"
|
"$go"
|
||||||
],
|
],
|
||||||
"group": "build",
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "new"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "go: vet workspace",
|
||||||
|
"command": "go vet ./...",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
],
|
||||||
|
"group": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "go: lint workspace",
|
||||||
|
"command": "golangci-lint run --timeout=5m",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
"problemMatcher": [],
|
||||||
|
"group": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "go: full test suite",
|
||||||
|
"dependsOrder": "sequence",
|
||||||
|
"dependsOn": [
|
||||||
|
"go: vet workspace",
|
||||||
|
"go: test workspace"
|
||||||
|
],
|
||||||
|
"problemMatcher": [],
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": false
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -183,7 +183,8 @@ func (v *ColumnValidator) ValidateRequestOptions(options RequestOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate Preload columns (if specified)
|
// Validate Preload columns (if specified)
|
||||||
for _, preload := range options.Preload {
|
for idx := range options.Preload {
|
||||||
|
preload := options.Preload[idx]
|
||||||
// Note: We don't validate the relation name itself, as it's a relationship
|
// Note: We don't validate the relation name itself, as it's a relationship
|
||||||
// Only validate columns if specified for the preload
|
// Only validate columns if specified for the preload
|
||||||
if err := v.ValidateColumns(preload.Columns); err != nil {
|
if err := v.ValidateColumns(preload.Columns); err != nil {
|
||||||
@ -239,7 +240,8 @@ func (v *ColumnValidator) FilterRequestOptions(options RequestOptions) RequestOp
|
|||||||
|
|
||||||
// Filter Preload columns
|
// Filter Preload columns
|
||||||
validPreloads := make([]PreloadOption, 0, len(options.Preload))
|
validPreloads := make([]PreloadOption, 0, len(options.Preload))
|
||||||
for _, preload := range options.Preload {
|
for idx := range options.Preload {
|
||||||
|
preload := options.Preload[idx]
|
||||||
filteredPreload := preload
|
filteredPreload := preload
|
||||||
filteredPreload.Columns = v.FilterValidColumns(preload.Columns)
|
filteredPreload.Columns = v.FilterValidColumns(preload.Columns)
|
||||||
filteredPreload.OmitColumns = v.FilterValidColumns(preload.OmitColumns)
|
filteredPreload.OmitColumns = v.FilterValidColumns(preload.OmitColumns)
|
||||||
|
|||||||
@ -18,7 +18,7 @@ func GetPrimaryKeyName(model any) string {
|
|||||||
if reflect.TypeOf(model) == nil {
|
if reflect.TypeOf(model) == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
//If we are given a string model name, look up the model
|
// If we are given a string model name, look up the model
|
||||||
if reflect.TypeOf(model).Kind() == reflect.String {
|
if reflect.TypeOf(model).Kind() == reflect.String {
|
||||||
name := model.(string)
|
name := model.(string)
|
||||||
m, err := modelregistry.GetModelByName(name)
|
m, err := modelregistry.GetModelByName(name)
|
||||||
|
|||||||
@ -699,6 +699,7 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
|
|||||||
schema := GetSchema(ctx)
|
schema := GetSchema(ctx)
|
||||||
entity := GetEntity(ctx)
|
entity := GetEntity(ctx)
|
||||||
tableName := GetTableName(ctx)
|
tableName := GetTableName(ctx)
|
||||||
|
model := GetModel(ctx)
|
||||||
|
|
||||||
logger.Info("Deleting records from %s.%s", schema, entity)
|
logger.Info("Deleting records from %s.%s", schema, entity)
|
||||||
|
|
||||||
@ -711,7 +712,7 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
|
|||||||
err := h.db.RunInTransaction(ctx, func(tx common.Database) error {
|
err := h.db.RunInTransaction(ctx, func(tx common.Database) error {
|
||||||
for _, itemID := range v {
|
for _, itemID := range v {
|
||||||
|
|
||||||
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(tableName))), itemID)
|
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(model))), itemID)
|
||||||
if _, err := query.Exec(ctx); err != nil {
|
if _, err := query.Exec(ctx); err != nil {
|
||||||
return fmt.Errorf("failed to delete record %s: %w", itemID, err)
|
return fmt.Errorf("failed to delete record %s: %w", itemID, err)
|
||||||
}
|
}
|
||||||
@ -750,7 +751,7 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
|
|||||||
continue // Skip items without ID
|
continue // Skip items without ID
|
||||||
}
|
}
|
||||||
|
|
||||||
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(tableName))), itemID)
|
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(model))), itemID)
|
||||||
result, err := query.Exec(ctx)
|
result, err := query.Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to delete record %v: %w", itemID, err)
|
return fmt.Errorf("failed to delete record %v: %w", itemID, err)
|
||||||
@ -775,7 +776,7 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
|
|||||||
err := h.db.RunInTransaction(ctx, func(tx common.Database) error {
|
err := h.db.RunInTransaction(ctx, func(tx common.Database) error {
|
||||||
for _, item := range v {
|
for _, item := range v {
|
||||||
if itemID, ok := item["id"]; ok && itemID != nil {
|
if itemID, ok := item["id"]; ok && itemID != nil {
|
||||||
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(tableName))), itemID)
|
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(model))), itemID)
|
||||||
result, err := query.Exec(ctx)
|
result, err := query.Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to delete record %v: %w", itemID, err)
|
return fmt.Errorf("failed to delete record %v: %w", itemID, err)
|
||||||
@ -809,7 +810,7 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
query := h.db.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(tableName))), id)
|
query := h.db.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(model))), id)
|
||||||
|
|
||||||
result, err := query.Exec(ctx)
|
result, err := query.Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1118,7 +1119,8 @@ func (h *Handler) applyPreloads(model interface{}, query common.SelectQuery, pre
|
|||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, preload := range preloads {
|
for idx := range preloads {
|
||||||
|
preload := preloads[idx]
|
||||||
logger.Debug("Processing preload for relation: %s", preload.Relation)
|
logger.Debug("Processing preload for relation: %s", preload.Relation)
|
||||||
relInfo := h.getRelationshipInfo(modelType, preload.Relation)
|
relInfo := h.getRelationshipInfo(modelType, preload.Relation)
|
||||||
if relInfo == nil {
|
if relInfo == nil {
|
||||||
|
|||||||
@ -260,7 +260,7 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
|
|||||||
query = query.ColumnExpr("(?) AS "+colName, colExpr)
|
query = query.ColumnExpr("(?) AS "+colName, colExpr)
|
||||||
for colIndex := range options.Columns {
|
for colIndex := range options.Columns {
|
||||||
if options.Columns[colIndex] == colName {
|
if options.Columns[colIndex] == colName {
|
||||||
//Remove the computed column from the selected columns to avoid duplication
|
// Remove the computed column from the selected columns to avoid duplication
|
||||||
options.Columns = append(options.Columns[:colIndex], options.Columns[colIndex+1:]...)
|
options.Columns = append(options.Columns[:colIndex], options.Columns[colIndex+1:]...)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -274,7 +274,7 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
|
|||||||
query = query.ColumnExpr("(?) AS "+cu.Name, cu.Expression)
|
query = query.ColumnExpr("(?) AS "+cu.Name, cu.Expression)
|
||||||
for colIndex := range options.Columns {
|
for colIndex := range options.Columns {
|
||||||
if options.Columns[colIndex] == cu.Name {
|
if options.Columns[colIndex] == cu.Name {
|
||||||
//Remove the computed column from the selected columns to avoid duplication
|
// Remove the computed column from the selected columns to avoid duplication
|
||||||
options.Columns = append(options.Columns[:colIndex], options.Columns[colIndex+1:]...)
|
options.Columns = append(options.Columns[:colIndex], options.Columns[colIndex+1:]...)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -305,13 +305,13 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
|
|||||||
}
|
}
|
||||||
// Note: Expand would require JOIN implementation
|
// Note: Expand would require JOIN implementation
|
||||||
// For now, we'll use Preload as a fallback
|
// For now, we'll use Preload as a fallback
|
||||||
//query = query.Preload(expand.Relation)
|
// query = query.Preload(expand.Relation)
|
||||||
if options.Preload == nil {
|
if options.Preload == nil {
|
||||||
options.Preload = make([]common.PreloadOption, 0)
|
options.Preload = make([]common.PreloadOption, 0)
|
||||||
}
|
}
|
||||||
skip := false
|
skip := false
|
||||||
for _, existing := range options.Preload {
|
for idx := range options.Preload {
|
||||||
if existing.Relation == expand.Relation {
|
if options.Preload[idx].Relation == expand.Relation {
|
||||||
skip = true
|
skip = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -327,7 +327,8 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply preloading
|
// Apply preloading
|
||||||
for _, preload := range options.Preload {
|
for idx := range options.Preload {
|
||||||
|
preload := options.Preload[idx]
|
||||||
logger.Debug("Applying preload: %s", preload.Relation)
|
logger.Debug("Applying preload: %s", preload.Relation)
|
||||||
query = query.PreloadRelation(preload.Relation, func(sq common.SelectQuery) common.SelectQuery {
|
query = query.PreloadRelation(preload.Relation, func(sq common.SelectQuery) common.SelectQuery {
|
||||||
if len(preload.OmitColumns) > 0 {
|
if len(preload.OmitColumns) > 0 {
|
||||||
@ -972,7 +973,7 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(tableName))), itemID)
|
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(model))), itemID)
|
||||||
|
|
||||||
result, err := query.Exec(ctx)
|
result, err := query.Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1039,7 +1040,7 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(tableName))), itemID)
|
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(model))), itemID)
|
||||||
result, err := query.Exec(ctx)
|
result, err := query.Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to delete record %v: %w", itemID, err)
|
return fmt.Errorf("failed to delete record %v: %w", itemID, err)
|
||||||
@ -1090,7 +1091,7 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(tableName))), itemID)
|
query := tx.NewDelete().Table(tableName).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(model))), itemID)
|
||||||
result, err := query.Exec(ctx)
|
result, err := query.Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to delete record %v: %w", itemID, err)
|
return fmt.Errorf("failed to delete record %v: %w", itemID, err)
|
||||||
@ -1150,7 +1151,7 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
query = query.Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(tableName))), id)
|
query = query.Where(fmt.Sprintf("%s = ?", common.QuoteIdent(reflection.GetPrimaryKeyName(model))), id)
|
||||||
|
|
||||||
// Execute BeforeScan hooks - pass query chain so hooks can modify it
|
// Execute BeforeScan hooks - pass query chain so hooks can modify it
|
||||||
hookCtx.Query = query
|
hookCtx.Query = query
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user