Class: Service::DBService
- Inherits:
-
Service
- Object
- Service
- Service::DBService
- Includes:
- ActiveStorage::DBServiceRails60, ActiveStorage::DBServiceRails61, ActiveStorage::DBServiceRails70
- Defined in:
- lib/active_storage/service/db_service.rb
Overview
Wraps a DB table as an Active Storage service. See ActiveStorage::Service for the generic API documentation that applies to all services.
Constant Summary collapse
- MINIMUM_CHUNK_SIZE =
:nocov:
1
Instance Method Summary collapse
- #delete(key) ⇒ Object
- #delete_prefixed(prefix) ⇒ Object
- #download(key, &block) ⇒ Object
- #download_chunk(key, range) ⇒ Object
- #exist?(key) ⇒ Boolean
- #headers_for_direct_upload(_key, content_type:) ⇒ Object
-
#initialize(public: false) ⇒ DBService
constructor
A new instance of DBService.
- #upload(key, io, checksum: nil) ⇒ Object
- #url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {}) ⇒ Object
Methods included from ActiveStorage::DBServiceRails60
Methods included from ActiveStorage::DBServiceRails70
Constructor Details
#initialize(public: false) ⇒ DBService
Returns a new instance of DBService.
23 24 25 26 27 |
# File 'lib/active_storage/service/db_service.rb', line 23 def initialize(public: false, **) @chunk_size = [ENV.fetch("ASDB_CHUNK_SIZE") { 1.megabytes }.to_i, MINIMUM_CHUNK_SIZE].max @max_size = ENV.fetch("ASDB_MAX_FILE_SIZE", nil)&.to_i @public = public end |
Instance Method Details
#delete(key) ⇒ Object
70 71 72 73 74 75 76 77 78 |
# File 'lib/active_storage/service/db_service.rb', line 70 def delete(key) instrument :delete, key: key do comment = "DBService#delete" record = ::ActiveStorageDB::File.annotate(comment).find_by(ref: key) record&.destroy # NOTE: Ignore files already deleted !record.nil? end end |
#delete_prefixed(prefix) ⇒ Object
80 81 82 83 84 85 86 |
# File 'lib/active_storage/service/db_service.rb', line 80 def delete_prefixed(prefix) instrument :delete_prefixed, prefix: prefix do comment = "DBService#delete_prefixed" sanitized_prefix = "#{ActiveRecord::Base.sanitize_sql_like(prefix)}%" ::ActiveStorageDB::File.annotate(comment).where("ref LIKE ?", sanitized_prefix).destroy_all end end |
#download(key, &block) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/active_storage/service/db_service.rb', line 44 def download(key, &block) if block_given? instrument :streaming_download, key: key do stream(key, &block) end else instrument :download, key: key do retrieve_file(key) end end end |
#download_chunk(key, range) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/active_storage/service/db_service.rb', line 56 def download_chunk(key, range) instrument :download_chunk, key: key, range: range do # NOTE: from/size are derived from Range#begin and Range#size (always integers), # so string interpolation into SQL is safe here. from = range.begin + 1 size = range.size args = adapter_sqlserver? || adapter_sqlite? ? "data, #{from}, #{size}" : "data FROM #{from} FOR #{size}" record = object_for(key, fields: "SUBSTRING(#{args}) AS chunk") raise ActiveStorage::FileNotFoundError unless record record.chunk end end |
#exist?(key) ⇒ Boolean
88 89 90 91 92 93 94 95 |
# File 'lib/active_storage/service/db_service.rb', line 88 def exist?(key) instrument :exist, key: key do |payload| comment = "DBService#exist?" result = ::ActiveStorageDB::File.annotate(comment).exists?(ref: key) payload[:exist] = result result end end |
#headers_for_direct_upload(_key, content_type:) ⇒ Object
117 118 119 |
# File 'lib/active_storage/service/db_service.rb', line 117 def headers_for_direct_upload(_key, content_type:, **) { "Content-Type" => content_type } end |
#upload(key, io, checksum: nil) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/active_storage/service/db_service.rb', line 29 def upload(key, io, checksum: nil, **) instrument :upload, key: key, checksum: checksum do data = io.read if @max_size && data.bytesize > @max_size raise ArgumentError, "File size exceeds the maximum allowed size of #{@max_size} bytes" end if checksum digest = Digest::MD5.base64digest(data) raise ActiveStorage::IntegrityError unless digest == checksum end ::ActiveStorageDB::File.create!(ref: key, data: data) end end |
#url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {}) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/active_storage/service/db_service.rb', line 97 def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {}) instrument :url, key: key do |payload| verified_token_with_expiration = ActiveStorage.verifier.generate( { key: key, content_type: content_type, content_length: content_length, checksum: checksum, service_name: service_name_for_token }, expires_in: expires_in, purpose: :blob_token ) url_helpers.update_service_url(verified_token_with_expiration, ).tap do |generated_url| payload[:url] = generated_url end end end |