11# frozen_string_literal: true
22
3+ require 'active_storage/service/db_service_rails60'
4+ require 'active_storage/service/db_service_rails61'
5+ require 'active_storage/service/db_service_rails70'
6+
37module ActiveStorage
8+ # Wraps a DB table as an Active Storage service. See ActiveStorage::Service
9+ # for the generic API documentation that applies to all services.
410 class Service ::DBService < Service
5- def initialize ( **)
11+ if Rails ::VERSION ::MAJOR >= 7
12+ include ActiveStorage ::DBServiceRails70
13+ elsif Rails ::VERSION ::MAJOR == 6 && Rails ::VERSION ::MINOR == 1
14+ include ActiveStorage ::DBServiceRails61
15+ else
16+ include ActiveStorage ::DBServiceRails60
17+ end
18+
19+ def initialize ( public : false , **)
620 @chunk_size = ENV . fetch ( 'ASDB_CHUNK_SIZE' ) { 1 . megabytes }
21+ @public = public
722 end
823
924 def upload ( key , io , checksum : nil , **)
@@ -22,22 +37,27 @@ def download(key, &block)
2237 else
2338 instrument :download , key : key do
2439 record = ::ActiveStorageDB ::File . find_by ( ref : key )
25- record &.data || raise ( ActiveStorage ::FileNotFoundError )
40+ raise ( ActiveStorage ::FileNotFoundError ) unless record
41+
42+ record . data
2643 end
2744 end
2845 end
2946
3047 def download_chunk ( key , range )
3148 instrument :download_chunk , key : key , range : range do
3249 chunk_select = "SUBSTRING(data FROM #{ range . begin + 1 } FOR #{ range . size } ) AS chunk"
33- ::ActiveStorageDB ::File . select ( chunk_select ) . find_by ( ref : key ) &.chunk ||
34- raise ( ActiveStorage ::FileNotFoundError )
50+ record = ::ActiveStorageDB ::File . select ( chunk_select ) . find_by ( ref : key )
51+ raise ( ActiveStorage ::FileNotFoundError ) unless record
52+
53+ record . chunk
3554 end
3655 end
3756
3857 def delete ( key )
3958 instrument :delete , key : key do
4059 ::ActiveStorageDB ::File . find_by ( ref : key ) &.destroy
60+ # Ignore files already deleted
4161 end
4262 end
4363
@@ -55,50 +75,23 @@ def exist?(key)
5575 end
5676 end
5777
58- def url ( key , expires_in :, filename :, disposition :, content_type :)
59- instrument :url , key : key do |payload |
60- content_disposition = content_disposition_with ( type : disposition , filename : filename )
61- verified_key_with_expiration = ActiveStorage . verifier . generate (
62- {
63- key : key ,
64- disposition : content_disposition ,
65- content_type : content_type
66- } ,
67- expires_in : expires_in ,
68- purpose : :blob_key
69- )
70- current_uri = URI . parse ( current_host )
71- generated_url = url_helpers . service_url (
72- verified_key_with_expiration ,
73- protocol : current_uri . scheme ,
74- host : current_uri . host ,
75- port : current_uri . port ,
76- disposition : content_disposition ,
77- content_type : content_type ,
78- filename : filename
79- )
80- payload [ :url ] = generated_url
81-
82- generated_url
83- end
84- end
85-
8678 def url_for_direct_upload ( key , expires_in :, content_type :, content_length :, checksum :, custom_metadata : { } )
8779 instrument :url , key : key do |payload |
8880 verified_token_with_expiration = ActiveStorage . verifier . generate (
8981 {
9082 key : key ,
9183 content_type : content_type ,
9284 content_length : content_length ,
93- checksum : checksum
85+ checksum : checksum ,
86+ service_name : respond_to? ( :name ) ? name : 'db'
9487 } ,
9588 expires_in : expires_in ,
9689 purpose : :blob_token
9790 )
98- generated_url = url_helpers . update_service_url ( verified_token_with_expiration , host : current_host )
99- payload [ :url ] = generated_url
10091
101- generated_url
92+ url_helpers . update_service_url ( verified_token_with_expiration , url_options ) . tap do |generated_url |
93+ payload [ :url ] = generated_url
94+ end
10295 end
10396 end
10497
@@ -108,15 +101,29 @@ def headers_for_direct_upload(_key, content_type:, **)
108101
109102 private
110103
111- def current_host
112- if ActiveStorage ::Current . respond_to? :url_options
113- opts = ActiveStorage ::Current . url_options || { }
114- url = "#{ opts [ :protocol ] } #{ opts [ :host ] } "
115- url += ":#{ opts [ :port ] } " if opts [ :port ]
116- url || ''
117- else
118- ActiveStorage ::Current . host
119- end
104+ def generate_url ( key , expires_in :, filename :, content_type :, disposition :)
105+ content_disposition = content_disposition_with ( type : disposition , filename : filename )
106+ verified_key_with_expiration = ActiveStorage . verifier . generate (
107+ {
108+ key : key ,
109+ disposition : content_disposition ,
110+ content_type : content_type ,
111+ service_name : respond_to? ( :name ) ? name : 'db'
112+ } ,
113+ expires_in : expires_in ,
114+ purpose : :blob_key
115+ )
116+
117+ current_uri = URI . parse ( current_host )
118+ url_helpers . service_url (
119+ verified_key_with_expiration ,
120+ protocol : current_uri . scheme ,
121+ host : current_uri . host ,
122+ port : current_uri . port ,
123+ disposition : content_disposition ,
124+ content_type : content_type ,
125+ filename : filename
126+ )
120127 end
121128
122129 def ensure_integrity_of ( key , checksum )
0 commit comments