MCPcopy Create free account
hub / github.com/cloudbase/garm / CreateFileObject

Method CreateFileObject

database/sql/file_store.go:24–152  ·  view source on GitHub ↗

func (s *sqlDatabase) CreateFileObject(ctx context.Context, name string, size int64, tags []string, reader io.Reader) (fileObjParam params.FileObject, err error) {

(ctx context.Context, param params.CreateFileObjectParams, reader io.Reader)

Source from the content-addressed store, hash-verified

22
23// func (s *sqlDatabase) CreateFileObject(ctx context.Context, name string, size int64, tags []string, reader io.Reader) (fileObjParam params.FileObject, err error) {
24func (s *sqlDatabase) CreateFileObject(ctx context.Context, param params.CreateFileObjectParams, reader io.Reader) (fileObjParam params.FileObject, err error) {
25 // Save the file to temporary storage first. This allows us to accept the entire file, even over
26 // a slow connection, without locking the database as we stream the file to the DB.
27 // SQLite will lock the entire database (including for readers) when the data is being committed.
28 tmpFile, err := util.GetTmpFileHandle("")
29 if err != nil {
30 return params.FileObject{}, fmt.Errorf("failed to create tmp file: %w", err)
31 }
32 defer func() {
33 tmpFile.Close()
34 os.Remove(tmpFile.Name()) //nolint:gosec // G703 - path from os.CreateTemp, not user input
35 }()
36 if _, err := io.Copy(tmpFile, reader); err != nil {
37 return params.FileObject{}, fmt.Errorf("failed to copy data: %w", err)
38 }
39 if err := tmpFile.Sync(); err != nil {
40 return params.FileObject{}, fmt.Errorf("failed to flush data to disk: %w", err)
41 }
42 // File has been transferred. We need to seek to the beginning of the file. This same handler will be used
43 // to streab the data to the database.
44 if _, err := tmpFile.Seek(0, 0); err != nil {
45 return params.FileObject{}, fmt.Errorf("failed to seek to beginning: %w", err)
46 }
47 // Read first 8KB for type detection
48 buffer := make([]byte, 8192)
49 n, _ := io.ReadFull(tmpFile, buffer)
50 fileType := util.DetectFileType(buffer[:n])
51
52 fileObj := FileObject{
53 Name: param.Name,
54 Description: param.Description,
55 FileType: fileType,
56 Size: param.Size,
57 }
58
59 defer func() {
60 if err == nil {
61 s.sendNotify(common.FileObjectEntityType, common.CreateOperation, fileObjParam)
62 }
63 }()
64
65 var fileBlob FileBlob
66 err = s.objectsConn.Transaction(func(tx *gorm.DB) error {
67 // Create the file first
68 if err := tx.Create(&fileObj).Error; err != nil {
69 return fmt.Errorf("failed to create file object: %w", err)
70 }
71
72 // create the file blob, without any space allocated for the blob.
73 fileBlob = FileBlob{
74 FileObjectID: fileObj.ID,
75 }
76 if err := tx.Create(&fileBlob).Error; err != nil {
77 return fmt.Errorf("failed to create file blob object: %w", err)
78 }
79
80 // allocate space for the blob using the zeroblob() function. This will allow us to avoid
81 // having to allocate potentially huge byte arrays in memory and writing that huge blob to

Callers

nothing calls this directly

Calls 7

sendNotifyMethod · 0.95
GetTmpFileHandleFunction · 0.92
DetectFileTypeFunction · 0.92
UpdateMethod · 0.80
CloseMethod · 0.65
WriteMethod · 0.45

Tested by

no test coverage detected