Compare commits

...

1 Commits

Author SHA1 Message Date
Hein
62a8e56f1b feat(reflection): add GetPointerElement function for type handling
Some checks failed
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in -27m40s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in -27m8s
Build , Vet Test, and Lint / Lint Code (push) Successful in -27m5s
Build , Vet Test, and Lint / Build (push) Successful in -27m21s
Tests / Unit Tests (push) Successful in -27m42s
Tests / Integration Tests (push) Failing after -27m55s
* Introduced GetPointerElement to simplify pointer type extraction.
* Updated handleUpdate methods to utilize GetPointerElement for better clarity and maintainability.
2026-01-06 10:45:23 +02:00
3 changed files with 23 additions and 10 deletions

View File

@@ -47,3 +47,20 @@ func ExtractTableNameOnly(fullName string) string {
return fullName[startIndex:]
}
// GetPointerElement returns the element type if the provided reflect.Type is a pointer.
// If the type is a slice of pointers, it returns the element type of the pointer within the slice.
// If neither condition is met, it returns the original type.
func GetPointerElement(v reflect.Type) reflect.Type {
if v.Kind() == reflect.Ptr {
return v.Elem()
}
if v.Kind() == reflect.Slice && v.Elem().Kind() == reflect.Ptr {
subElem := v.Elem()
if subElem.Elem().Kind() == reflect.Ptr {
return subElem.Elem().Elem()
}
return v.Elem()
}
return v
}

View File

@@ -702,7 +702,7 @@ func (h *Handler) handleUpdate(ctx context.Context, w common.ResponseWriter, url
pkName := reflection.GetPrimaryKeyName(model)
// First, read the existing record from the database
existingRecord := reflect.New(reflect.TypeOf(model).Elem()).Interface()
existingRecord := reflect.New(reflection.GetPointerElement(reflect.TypeOf(model))).Interface()
selectQuery := h.db.NewSelect().Model(existingRecord)
// Apply conditions to select
@@ -850,7 +850,7 @@ func (h *Handler) handleUpdate(ctx context.Context, w common.ResponseWriter, url
for _, item := range updates {
if itemID, ok := item["id"]; ok {
// First, read the existing record
existingRecord := reflect.New(reflect.TypeOf(model).Elem()).Interface()
existingRecord := reflect.New(reflection.GetPointerElement(reflect.TypeOf(model))).Interface()
selectQuery := tx.NewSelect().Model(existingRecord).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(pkName)), itemID)
if err := selectQuery.ScanModel(ctx); err != nil {
if err == sql.ErrNoRows {
@@ -958,7 +958,7 @@ func (h *Handler) handleUpdate(ctx context.Context, w common.ResponseWriter, url
if itemMap, ok := item.(map[string]interface{}); ok {
if itemID, ok := itemMap["id"]; ok {
// First, read the existing record
existingRecord := reflect.New(reflect.TypeOf(model).Elem()).Interface()
existingRecord := reflect.New(reflection.GetPointerElement(reflect.TypeOf(model))).Interface()
selectQuery := tx.NewSelect().Model(existingRecord).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(pkName)), itemID)
if err := selectQuery.ScanModel(ctx); err != nil {
if err == sql.ErrNoRows {

View File

@@ -1240,7 +1240,7 @@ func (h *Handler) handleUpdate(ctx context.Context, w common.ResponseWriter, id
txNestedProcessor := common.NewNestedCUDProcessor(tx, h.registry, h)
// First, read the existing record from the database
existingRecord := reflect.New(reflect.TypeOf(model).Elem()).Interface()
existingRecord := reflect.New(reflection.GetPointerElement(reflect.TypeOf(model))).Interface()
selectQuery := tx.NewSelect().Model(existingRecord).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(pkName)), targetID)
if err := selectQuery.ScanModel(ctx); err != nil {
if err == sql.ErrNoRows {
@@ -1294,9 +1294,7 @@ func (h *Handler) handleUpdate(ctx context.Context, w common.ResponseWriter, id
// Populate model instance from dataMap to preserve custom types (like SqlJSONB)
// Get the type of the model, handling both pointer and non-pointer types
modelType := reflect.TypeOf(model)
if modelType.Kind() == reflect.Ptr {
modelType = modelType.Elem()
}
modelType = reflection.GetPointerElement(modelType)
modelInstance := reflect.New(modelType).Interface()
if err := reflection.MapToStruct(dataMap, modelInstance); err != nil {
return fmt.Errorf("failed to populate model from data: %w", err)
@@ -1600,9 +1598,7 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
// First, fetch the record that will be deleted
modelType := reflect.TypeOf(model)
if modelType.Kind() == reflect.Ptr {
modelType = modelType.Elem()
}
modelType = reflection.GetPointerElement(modelType)
recordToDelete := reflect.New(modelType).Interface()
selectQuery := h.db.NewSelect().Model(recordToDelete).Where(fmt.Sprintf("%s = ?", common.QuoteIdent(pkName)), id)