@@ -212,11 +212,14 @@ func (db *relationalDb) Reset() {
212212 db .gormDBMap = make (map [dbrole.DbRole ]* gorm.DB )
213213}
214214
215- // Find Finds a single record that has the same values as non-zero fields in the record.
216- // record argument must be a pointer to a struct and will be modified in-place.
217- // Returns ErrRecordNotFound if a record could not be found.
218- func (db * relationalDb ) Find (ctx context.Context , record Record ) error {
219- return db .FindInTable (ctx , GetTableName (record ), record )
215+ func (db * relationalDb ) commitWhenTxNotInsideCtx (ctx context.Context , tx * gorm.DB ) error {
216+ if ! db .txFetcher .IsTransactionCtx (ctx ) {
217+ if err := tx .Commit ().Error ; err != nil {
218+ db .logger .Debug (err )
219+ return ErrExecutingSqlStmt .Wrap (err )
220+ }
221+ }
222+ return nil
220223}
221224
222225func rollbackTx (tx * gorm.DB , db * relationalDb ) {
@@ -225,10 +228,21 @@ func rollbackTx(tx *gorm.DB, db *relationalDb) {
225228 }
226229}
227230
231+ // Find Finds a single record that has the same values as non-zero fields in the record.
232+ // record argument must be a pointer to a struct and will be modified in-place.
233+ // Returns ErrRecordNotFound if a record could not be found.
234+ func (db * relationalDb ) Find (ctx context.Context , record Record ) error {
235+ return db .FindInTable (ctx , GetTableName (record ), record , false )
236+ }
237+
238+ func (db * relationalDb ) FindSoftDeleted (ctx context.Context , record Record ) error {
239+ return db .FindInTable (ctx , GetTableName (record ), record , true )
240+ }
241+
228242// Finds a single record that has the same values as non-zero fields in the record.
229243// record argument must be a pointer to a struct and will be modified in-place.
230244// Returns ErrRecordNotFound if a record could not be found.
231- func (db * relationalDb ) FindInTable (ctx context.Context , tableName string , record Record ) (err error ) {
245+ func (db * relationalDb ) FindInTable (ctx context.Context , tableName string , record Record , softDelete bool ) (err error ) {
232246 var tx * gorm.DB
233247 if tx , err = db .GetDBTransaction (ctx , tableName , record ); err != nil {
234248 return err
@@ -240,54 +254,62 @@ func (db *relationalDb) FindInTable(ctx context.Context, tableName string, recor
240254 }
241255 }()
242256
243- if err = tx .Table (tableName ).Where (record ).First (record ).Error ; err != nil {
244- if errors .Is (err , gorm .ErrRecordNotFound ) {
245- return ErrRecordNotFound .Wrap (err ).WithValue ("record" , fmt .Sprintf ("%+v" , record )).WithValue (DB_NAME , db .dbName )
257+ if softDelete {
258+ if err = tx .Unscoped ().Table (tableName ).Where (record ).First (record ).Error ; err != nil {
259+ if errors .Is (err , gorm .ErrRecordNotFound ) {
260+ return ErrRecordNotFound .Wrap (err ).WithValue ("record" , fmt .Sprintf ("%+v" , record )).WithValue (DB_NAME , db .dbName )
261+ }
262+ db .logger .Debug (err )
263+ return ErrExecutingSqlStmt .Wrap (err ).WithValue (DB_NAME , db .dbName )
246264 }
247- db . logger . Debug ( err )
248- return ErrExecutingSqlStmt . Wrap ( err ). WithValue ( DB_NAME , db . dbName )
249- }
250- if ! db . txFetcher . IsTransactionCtx ( ctx ) {
251- if err = tx . Commit (). Error ; err != nil {
265+ } else {
266+ if err = tx . Table ( tableName ). Where ( record ). First ( record ). Error ; err != nil {
267+ if errors . Is ( err , gorm . ErrRecordNotFound ) {
268+ return ErrRecordNotFound . Wrap ( err ). WithValue ( "record" , fmt . Sprintf ( "%+v" , record )). WithValue ( DB_NAME , db . dbName )
269+ }
252270 db .logger .Debug (err )
253- return ErrExecutingSqlStmt .Wrap (err )
271+ return ErrExecutingSqlStmt .Wrap (err ). WithValue ( DB_NAME , db . dbName )
254272 }
255273 }
256- return nil
274+ return db . commitWhenTxNotInsideCtx ( ctx , tx )
257275}
258276
259277// Finds all records in a DB table.
260278// records must be a pointer to a slice of structs and will be modified in-place.
261279func (db * relationalDb ) FindAll (ctx context.Context , records interface {}, pagination * Pagination ) error {
280+ return db .FindAllInTable (ctx , GetTableName (records ), records , pagination , false )
281+ }
282+
283+ func (db * relationalDb ) FindAllIncludingSoftDeleted (ctx context.Context , records interface {}, pagination * Pagination ) error {
284+ return db .FindAllInTable (ctx , GetTableName (records ), records , pagination , true )
285+ }
286+
287+ func (db * relationalDb ) FindAllInTable (ctx context.Context , tableName string , records interface {}, pagination * Pagination , softDelete bool ) error {
262288 if reflect .TypeOf (records ).Kind () != reflect .Ptr || reflect .TypeOf (records ).Elem ().Kind () != reflect .Slice {
263289 errMsg := "\" records\" argument has to be a pointer to a slice of structs implementing \" Record\" interface"
264290 err := ErrNotPtrToStructSlice .Wrap (fmt .Errorf (errMsg ))
265291 db .logger .Debug (err )
266292 return err
267293 }
268-
269- tableName := GetTableName (records )
270- return db .FindAllInTable (ctx , tableName , records , pagination )
271- }
272-
273- // FindAllInTable Finds all records in DB table tableName.
274- // records must be a pointer to a slice of structs and will be modified in-place.
275- func (db * relationalDb ) FindAllInTable (ctx context.Context , tableName string , records interface {}, pagination * Pagination ) error {
276294 record := GetRecordInstanceFromSlice (records )
277- return db .FindWithFilterInTable (ctx , tableName , record , records , pagination )
295+ return db .FindWithFilterInTable (ctx , tableName , record , records , pagination , softDelete )
278296}
279297
280298// FindWithFilter Finds multiple records in a DB table.
281299// If record argument is non-empty, uses the non-empty fields as criteria in a query.
282300// records must be a pointer to a slice of structs and will be modified in-place.
283301func (db * relationalDb ) FindWithFilter (ctx context.Context , record Record , records interface {}, pagination * Pagination ) error {
284- return db .FindWithFilterInTable (ctx , GetTableName (record ), record , records , pagination )
302+ return db .FindWithFilterInTable (ctx , GetTableName (record ), record , records , pagination , false )
303+ }
304+
305+ func (db * relationalDb ) FindWithFilterIncludingSoftDeleted (ctx context.Context , record Record , records interface {}, pagination * Pagination ) error {
306+ return db .FindWithFilterInTable (ctx , GetTableName (record ), record , records , pagination , true )
285307}
286308
287309// Finds multiple records in DB table tableName.
288310// If record argument is non-empty, uses the non-empty fields as criteria in a query.
289311// records must be a pointer to a slice of structs and will be modified in-place.
290- func (db * relationalDb ) FindWithFilterInTable (ctx context.Context , tableName string , record Record , records interface {}, pagination * Pagination ) (err error ) {
312+ func (db * relationalDb ) FindWithFilterInTable (ctx context.Context , tableName string , record Record , records interface {}, pagination * Pagination , softDelete bool ) (err error ) {
291313 if reflect .TypeOf (records ).Kind () != reflect .Ptr || reflect .TypeOf (records ).Elem ().Kind () != reflect .Slice {
292314 return ErrNotPtrToStruct .WithValue (TYPE , TypeName (records ))
293315 }
@@ -297,28 +319,38 @@ func (db *relationalDb) FindWithFilterInTable(ctx context.Context, tableName str
297319 return err
298320 }
299321
300- if err = tx .Table (tableName ).Where (record ).Error ; err != nil {
301- db .logger .Debug (err )
302- return ErrExecutingSqlStmt .Wrap (err ).WithValue (DB_NAME , db .dbName )
322+ if softDelete {
323+ if err = tx .Unscoped ().Table (tableName ).Where (record ).Error ; err != nil {
324+ db .logger .Debug (err )
325+ return ErrExecutingSqlStmt .Wrap (err ).WithValue (DB_NAME , db .dbName )
326+ }
327+ } else {
328+ if err = tx .Table (tableName ).Where (record ).Error ; err != nil {
329+ db .logger .Debug (err )
330+ return ErrExecutingSqlStmt .Wrap (err ).WithValue (DB_NAME , db .dbName )
331+ }
303332 }
333+
304334 if pagination != nil {
305335 tx .Offset (pagination .Offset ).Limit (pagination .Limit )
306336 if pagination .SortBy != "" {
307337 tx .Order (pagination .SortBy )
308338 }
309339 }
310- if err = tx .Find (records ).Error ; err != nil {
311- db .logger .Debug (err )
312- return ErrExecutingSqlStmt .Wrap (err ).WithValue (DB_NAME , db .dbName )
313- }
314340
315- if ! db . txFetcher . IsTransactionCtx ( ctx ) {
316- if err = tx .Commit ( ).Error ; err != nil {
341+ if softDelete {
342+ if err = tx .Unscoped (). Find ( records ).Error ; err != nil {
317343 db .logger .Debug (err )
318- return ErrExecutingSqlStmt .Wrap (err )
344+ return ErrExecutingSqlStmt .Wrap (err ).WithValue (DB_NAME , db .dbName )
345+ }
346+ } else {
347+ if err = tx .Find (records ).Error ; err != nil {
348+ db .logger .Debug (err )
349+ return ErrExecutingSqlStmt .Wrap (err ).WithValue (DB_NAME , db .dbName )
319350 }
320351 }
321- return nil
352+
353+ return db .commitWhenTxNotInsideCtx (ctx , tx )
322354}
323355
324356/*
@@ -347,11 +379,9 @@ func (db *relationalDb) InsertInTable(ctx context.Context, tableName string, rec
347379 db .logger .Debug (err )
348380 return 0 , ErrExecutingSqlStmt .Wrap (err ).WithValue (DB_NAME , db .dbName )
349381 }
350- if ! db .txFetcher .IsTransactionCtx (ctx ) {
351- if err = tx .Commit ().Error ; err != nil {
352- db .logger .Debug (err )
353- return 0 , ErrExecutingSqlStmt .Wrap (err )
354- }
382+ err = db .commitWhenTxNotInsideCtx (ctx , tx )
383+ if err != nil {
384+ return 0 , err
355385 }
356386 return tx .RowsAffected , nil
357387}
@@ -407,11 +437,9 @@ func (db *relationalDb) delete(ctx context.Context, tableName string, record Rec
407437 return 0 , ErrExecutingSqlStmt .Wrap (err ).WithValue (DB_NAME , db .dbName )
408438 }
409439 }
410- if ! db .txFetcher .IsTransactionCtx (ctx ) {
411- if err = tx .Commit ().Error ; err != nil {
412- db .logger .Debug (err )
413- return 0 , ErrExecutingSqlStmt .Wrap (err )
414- }
440+ err = db .commitWhenTxNotInsideCtx (ctx , tx )
441+ if err != nil {
442+ return 0 , err
415443 }
416444 return tx .RowsAffected , nil
417445}
@@ -506,11 +534,9 @@ func (db *relationalDb) UpsertInTable(ctx context.Context, tableName string, rec
506534 return 0 , ErrExecutingSqlStmt .Wrap (err ).WithValue (DB_NAME , db .dbName )
507535 }
508536 }
509- if ! db .txFetcher .IsTransactionCtx (ctx ) {
510- if err = tx .Commit ().Error ; err != nil {
511- db .logger .Debug (err )
512- return 0 , ErrExecutingSqlStmt .Wrap (err )
513- }
537+ err = db .commitWhenTxNotInsideCtx (ctx , tx )
538+ if err != nil {
539+ return 0 , err
514540 }
515541 return tx .RowsAffected , nil
516542}
@@ -540,11 +566,9 @@ func (db *relationalDb) UpdateInTable(ctx context.Context, tableName string, rec
540566 return 0 , err
541567 }
542568 }
543- if ! db .txFetcher .IsTransactionCtx (ctx ) {
544- if err = tx .Commit ().Error ; err != nil {
545- db .logger .Debug (err )
546- return 0 , ErrExecutingSqlStmt .Wrap (err )
547- }
569+ err = db .commitWhenTxNotInsideCtx (ctx , tx )
570+ if err != nil {
571+ return 0 , err
548572 }
549573 return tx .RowsAffected , nil
550574}
0 commit comments