You've already forked pocketbase
							
							
				mirror of
				https://github.com/pocketbase/pocketbase.git
				synced 2025-10-31 08:37:38 +02:00 
			
		
		
		
	[#151] remove files on cascade deletion
This commit is contained in:
		| @@ -1,8 +1,6 @@ | ||||
| package apis | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"github.com/labstack/echo/v5" | ||||
| @@ -160,13 +158,6 @@ func (api *collectionApi) delete(c echo.Context) error { | ||||
| 			return rest.NewBadRequestError("Failed to delete collection. Make sure that the collection is not referenced by other collections.", err) | ||||
| 		} | ||||
|  | ||||
| 		// try to delete the collection files | ||||
| 		if err := api.deleteCollectionFiles(e.Collection); err != nil && api.app.IsDebug() { | ||||
| 			// non critical error - only log for debug | ||||
| 			// (usually could happen because of S3 api limits) | ||||
| 			log.Println(err) | ||||
| 		} | ||||
|  | ||||
| 		return e.HttpContext.NoContent(http.StatusNoContent) | ||||
| 	}) | ||||
|  | ||||
| @@ -176,18 +167,3 @@ func (api *collectionApi) delete(c echo.Context) error { | ||||
|  | ||||
| 	return handlerErr | ||||
| } | ||||
|  | ||||
| func (api *collectionApi) deleteCollectionFiles(collection *models.Collection) error { | ||||
| 	fs, err := api.app.NewFilesystem() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer fs.Close() | ||||
|  | ||||
| 	failed := fs.DeletePrefix(collection.BaseFilesPath()) | ||||
| 	if len(failed) > 0 { | ||||
| 		return errors.New("Failed to delete all record files.") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -356,13 +356,6 @@ func (api *recordApi) delete(c echo.Context) error { | ||||
| 			return rest.NewBadRequestError("Failed to delete record. Make sure that the record is not part of a required relation reference.", err) | ||||
| 		} | ||||
|  | ||||
| 		// try to delete the record files | ||||
| 		if err := api.deleteRecordFiles(e.Record); err != nil && api.app.IsDebug() { | ||||
| 			// non critical error - only log for debug | ||||
| 			// (usually could happen due to S3 api limits) | ||||
| 			log.Println(err) | ||||
| 		} | ||||
|  | ||||
| 		return e.HttpContext.NoContent(http.StatusNoContent) | ||||
| 	}) | ||||
|  | ||||
| @@ -373,21 +366,6 @@ func (api *recordApi) delete(c echo.Context) error { | ||||
| 	return handlerErr | ||||
| } | ||||
|  | ||||
| func (api *recordApi) deleteRecordFiles(record *models.Record) error { | ||||
| 	fs, err := api.app.NewFilesystem() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer fs.Close() | ||||
|  | ||||
| 	failed := fs.DeletePrefix(record.BaseFilesPath()) | ||||
| 	if len(failed) > 0 { | ||||
| 		return fmt.Errorf("Failed to delete %d record files.", len(failed)) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (api *recordApi) exportRequestData(c echo.Context) map[string]any { | ||||
| 	result := map[string]any{} | ||||
| 	queryParams := map[string]any{} | ||||
|   | ||||
							
								
								
									
										37
									
								
								core/base.go
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								core/base.go
									
									
									
									
									
								
							| @@ -5,6 +5,7 @@ import ( | ||||
| 	"database/sql" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"time" | ||||
| @@ -123,7 +124,7 @@ type BaseApp struct { | ||||
| // | ||||
| // To initialize the app, you need to call `app.Bootsrap()`. | ||||
| func NewBaseApp(dataDir string, encryptionEnv string, isDebug bool) *BaseApp { | ||||
| 	return &BaseApp{ | ||||
| 	app := &BaseApp{ | ||||
| 		dataDir:             dataDir, | ||||
| 		isDebug:             isDebug, | ||||
| 		encryptionEnv:       encryptionEnv, | ||||
| @@ -209,6 +210,10 @@ func NewBaseApp(dataDir string, encryptionEnv string, isDebug bool) *BaseApp { | ||||
| 		onCollectionBeforeDeleteRequest: &hook.Hook[*CollectionDeleteEvent]{}, | ||||
| 		onCollectionAfterDeleteRequest:  &hook.Hook[*CollectionDeleteEvent]{}, | ||||
| 	} | ||||
|  | ||||
| 	app.registerDefaultHooks() | ||||
|  | ||||
| 	return app | ||||
| } | ||||
|  | ||||
| // Bootstrap initializes the application | ||||
| @@ -750,3 +755,33 @@ func (app *BaseApp) createDao(db dbx.Builder) *daos.Dao { | ||||
|  | ||||
| 	return dao | ||||
| } | ||||
|  | ||||
| func (app *BaseApp) registerDefaultHooks() { | ||||
| 	deletePrefix := func(prefix string) error { | ||||
| 		fs, err := app.NewFilesystem() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		defer fs.Close() | ||||
|  | ||||
| 		failed := fs.DeletePrefix(prefix) | ||||
| 		if len(failed) > 0 { | ||||
| 			return errors.New("Failed to delete the files at " + prefix) | ||||
| 		} | ||||
|  | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// delete storage files from deleted Collection, Records, etc. | ||||
| 	app.OnModelAfterDelete().Add(func(e *ModelEvent) error { | ||||
| 		if m, ok := e.Model.(models.FilesManager); ok && m.BaseFilesPath() != "" { | ||||
| 			if err := deletePrefix(m.BaseFilesPath()); err != nil && app.IsDebug() { | ||||
| 				// non critical error - only log for debug | ||||
| 				// (usually could happen because of S3 api limits) | ||||
| 				log.Println(err) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return nil | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -15,6 +15,12 @@ type ColumnValueMapper interface { | ||||
| 	ColumnValueMap() map[string]any | ||||
| } | ||||
|  | ||||
| // FilesManager defines an interface with common methods that files manager models should implement. | ||||
| type FilesManager interface { | ||||
| 	// BaseFilesPath returns the storage dir path used by the interface instance. | ||||
| 	BaseFilesPath() string | ||||
| } | ||||
|  | ||||
| // Model defines an interface with common methods that all db models should have. | ||||
| type Model interface { | ||||
| 	TableName() string | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package models | ||||
| import "github.com/pocketbase/pocketbase/models/schema" | ||||
|  | ||||
| var _ Model = (*Collection)(nil) | ||||
| var _ FilesManager = (*Collection)(nil) | ||||
|  | ||||
| type Collection struct { | ||||
| 	BaseModel | ||||
|   | ||||
| @@ -16,6 +16,7 @@ import ( | ||||
|  | ||||
| var _ Model = (*Record)(nil) | ||||
| var _ ColumnValueMapper = (*Record)(nil) | ||||
| var _ FilesManager = (*Record)(nil) | ||||
|  | ||||
| type Record struct { | ||||
| 	BaseModel | ||||
|   | ||||
		Reference in New Issue
	
	Block a user