Class: Upload
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Upload
- Includes:
- Checksummable, EachBatch, ObjectStorable
- Defined in:
- app/models/upload.rb
Constant Summary collapse
- STORE_COLUMN =
:store- CHECKSUM_THRESHOLD =
Upper limit for foreground checksum processing
100.megabytes
Constants inherited from ApplicationRecord
Constants included from HasCheckConstraints
HasCheckConstraints::NOT_NULL_CHECK_PATTERN
Constants included from ResetOnColumnErrors
ResetOnColumnErrors::MAX_RESET_PERIOD
Class Method Summary collapse
-
.begin_fast_destroy ⇒ Object
FastDestroyAll concerns.
- .destroy_for_associations!(records, uploader = AttachmentUploader) ⇒ Object
-
.finalize_fast_destroy(items_to_remove) ⇒ Object
FastDestroyAll concerns.
Instance Method Summary collapse
- #absolute_path ⇒ Object
-
#build_uploader(mounted_as = nil) ⇒ GitlabUploader
Initialize the associated Uploader class with current model.
- #calculate_checksum! ⇒ Object
-
#exist? ⇒ Boolean
This checks for existence of the upload on storage.
- #filename ⇒ Object
- #local? ⇒ Boolean
-
#needs_checksum? ⇒ Boolean
Returns whether generating checksum is needed.
- #relative_path ⇒ Object
-
#retrieve_uploader(mounted_as = nil) ⇒ GitlabUploader
Initialize the associated Uploader class with current model and retrieve existing file from the store to a local cache.
- #uploader_context ⇒ Object
Methods inherited from ApplicationRecord
===, cached_column_list, #create_or_load_association, current_transaction, declarative_enum, default_select_columns, delete_all_returning, #deleted_from_database?, id_in, id_not_in, iid_in, nullable_column?, primary_key_in, #readable_by?, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, #to_ability_name, underscore, where_exists, where_not_exists, with_fast_read_statement_timeout, without_order
Methods included from Organizations::Sharding
Methods included from ResetOnColumnErrors
#reset_on_union_error, #reset_on_unknown_attribute_error
Methods included from Gitlab::SensitiveSerializableHash
Class Method Details
.begin_fast_destroy ⇒ Object
FastDestroyAll concerns
39 40 41 42 43 44 |
# File 'app/models/upload.rb', line 39 def begin_fast_destroy { Uploads::Local => Uploads::Local.new.keys(with_files_stored_locally), Uploads::Fog => Uploads::Fog.new.keys(with_files_stored_remotely) } end |
.destroy_for_associations!(records, uploader = AttachmentUploader) ⇒ Object
54 55 56 57 58 59 60 61 62 |
# File 'app/models/upload.rb', line 54 def destroy_for_associations!(records, uploader = AttachmentUploader) return if records.blank? for_model_type_and_id(records.klass, records.pluck_primary_key) .for_uploader(uploader) .then { |uploads| [uploads, uploads.begin_fast_destroy] } .tap { |uploads, _| uploads.delete_all } .tap { |_, files| finalize_fast_destroy(files) } end |
.finalize_fast_destroy(items_to_remove) ⇒ Object
FastDestroyAll concerns
48 49 50 51 52 |
# File 'app/models/upload.rb', line 48 def finalize_fast_destroy(items_to_remove) items_to_remove.each do |store_class, keys| store_class.new.delete_keys_async(keys) end end |
Instance Method Details
#absolute_path ⇒ Object
65 66 67 68 69 70 |
# File 'app/models/upload.rb', line 65 def absolute_path raise ObjectStorage::RemoteStoreError, _("Remote object has no absolute path.") unless local? return path unless relative_path? uploader_class.absolute_path(self) end |
#build_uploader(mounted_as = nil) ⇒ GitlabUploader
Initialize the associated Uploader class with current model
87 88 89 90 91 |
# File 'app/models/upload.rb', line 87 def build_uploader(mounted_as = nil) uploader_class.new(model, mounted_as || mount_point).tap do |uploader| uploader.upload = self end end |
#calculate_checksum! ⇒ Object
76 77 78 79 80 81 |
# File 'app/models/upload.rb', line 76 def calculate_checksum! self.checksum = nil return unless needs_checksum? self.checksum = self.class.sha256_hexdigest(absolute_path) end |
#exist? ⇒ Boolean
This checks for existence of the upload on storage
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'app/models/upload.rb', line 107 def exist? exist = if local? File.exist?(absolute_path) else retrieve_uploader.exists? end # Help sysadmins find missing upload files if persisted? && !exist exception = RuntimeError.new("Uploaded file does not exist") Gitlab::ErrorTracking.track_exception(exception, self.attributes) Gitlab::Metrics.counter(:upload_file_does_not_exist_total, _('The number of times an upload record could not find its file')).increment end exist end |
#filename ⇒ Object
146 147 148 |
# File 'app/models/upload.rb', line 146 def filename File.basename(path) end |
#local? ⇒ Boolean
132 133 134 |
# File 'app/models/upload.rb', line 132 def local? store == ObjectStorage::Store::LOCAL end |
#needs_checksum? ⇒ Boolean
Returns whether generating checksum is needed
This takes into account whether file exists, if any checksum exists or if the storage has checksum generation code implemented
142 143 144 |
# File 'app/models/upload.rb', line 142 def needs_checksum? checksum.nil? && local? && exist? end |
#relative_path ⇒ Object
72 73 74 |
# File 'app/models/upload.rb', line 72 def relative_path uploader_class.relative_path(self) end |
#retrieve_uploader(mounted_as = nil) ⇒ GitlabUploader
Initialize the associated Uploader class with current model and retrieve existing file from the store to a local cache
98 99 100 101 102 |
# File 'app/models/upload.rb', line 98 def retrieve_uploader(mounted_as = nil) build_uploader(mounted_as).tap do |uploader| uploader.retrieve_from_store!(filename) end end |
#uploader_context ⇒ Object
124 125 126 127 128 129 130 |
# File 'app/models/upload.rb', line 124 def uploader_context { identifier: filename, secret: secret, uploaded_by_user_id: uploaded_by_user_id }.compact end |