From 7a5c188ec422a121bae4c988c4e29097bad9c888 Mon Sep 17 00:00:00 2001 From: Ayoub Aarrasse Date: Tue, 12 Aug 2025 18:32:03 +0100 Subject: [PATCH] godoc added to callbacks --- oracle/create.go | 16 ++++++++++++++++ oracle/delete.go | 26 +++++++++++++++++++++++++- oracle/update.go | 24 +++++++++++++++++++++++- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/oracle/create.go b/oracle/create.go index b8999c1..4aeddcd 100644 --- a/oracle/create.go +++ b/oracle/create.go @@ -50,6 +50,22 @@ import ( "gorm.io/gorm/schema" ) +// Create overrides GORM's create callback for Oracle. +// +// Behavior: +// - If the schema has fields with default DB values and only one row is +// being inserted, it builds an INSERT ... RETURNING statement. +// - If no RETURNING is needed, it emits a standard INSERT. +// - If multiple rows require RETURNING, it builds a PL/SQL block using +// FORALL and BULK COLLECT; if an ON CONFLICT clause is present and +// resolvable, it emits a MERGE. +// - For that last case, it validates Dest (non-nil, non-empty slice with +// no nil elements), normalizes bind variables for Oracle, and populates +// destinations from OUT parameters. +// +// Register with: +// +// db.Callback().Create().Replace("gorm:create", oracle.Create) func Create(db *gorm.DB) { if db.Error != nil || db.Statement == nil { return diff --git a/oracle/delete.go b/oracle/delete.go index aaa29aa..31f8a2e 100644 --- a/oracle/delete.go +++ b/oracle/delete.go @@ -49,7 +49,31 @@ import ( "gorm.io/gorm/schema" ) -// Delete callback function for Oracle +// Delete overrides GORM's delete callback for Oracle. +// +// Delete builds a safe, Oracle-compatible DELETE that supports soft deletes, +// hard deletes, and optional RETURNING of deleted rows. +// +// Behavior: +// - DELETE safety: checks for missing WHERE conditions and refuses to run +// unless AllowGlobalUpdate is set or the WHERE clause has meaningful +// conditions. +// - Soft delete: if the model has a soft-delete field and Unscoped is false, +// it lets GORM emit the UPDATE that marks rows as deleted. If a RETURNING +// clause is present with soft delete, it executes via QueryContext so the +// returned columns can be scanned. +// - Hard delete + RETURNING: it emits a PL/SQL block that performs DELETE … +// RETURNING BULK COLLECT INTO, wiring per-row sql.Out destinations so the +// deleted rows (or selected columns) can be populated back into the +// destination slice. +// - Hard delete (no RETURNING): it emits a standard DELETE and executes it +// via ExecContext. +// - Expressions: it expands WHERE expressions, including IN with slices, and +// normalizes bind variables for Oracle. +// +// Register with: +// +// db.Callback().Delete().Replace("gorm:delete", oracle.Delete) func Delete(db *gorm.DB) { if db.Error != nil || db.Statement == nil { return diff --git a/oracle/update.go b/oracle/update.go index 5b498b1..be0a2a6 100644 --- a/oracle/update.go +++ b/oracle/update.go @@ -50,7 +50,29 @@ import ( "gorm.io/gorm/schema" ) -// Update callback function for Oracle +// Update overrides GORM's update callback for Oracle. +// +// It builds Oracle-compatible UPDATE statements and supports: +// +// - Standard updates without RETURNING using GORM’s default SQL build, with +// bind variable conversion for Oracle types. +// - Updates with RETURNING, emitting a PL/SQL block that performs +// UPDATE … RETURNING BULK COLLECT INTO for multi-row updates, +// wiring sql.Out binds for each returned column and row. +// - UPDATE safety: checks for missing WHERE conditions and refuses to run +// unless AllowGlobalUpdate is set or the WHERE clause has meaningful +// conditions (beyond soft-delete filters). +// - Primary key WHERE injection when the destination object or slice has +// identifiable PK values, to avoid unintended mass updates. +// - Soft-delete compatibility: conditions on deleted_at are ignored for the +// safety check, but preserved in the WHERE for the actual SQL. +// +// For updates with RETURNING, OUT bind results are mapped back into the +// destination struct or slice using getUpdateReturningValues. +// +// Register with: +// +// db.Callback().Update().Replace("gorm:update", oracle.Update) func Update(db *gorm.DB) { if db.Error != nil || db.Statement == nil { return