Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/controllers/active_storage_db/files_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def show

def update
if (token = decode_verified_token)
file_uploaded = upload_file(token, body: request.body)
file_uploaded = upload_file(token)
head(file_uploaded ? :no_content : unprocessable)
else
head(:not_found)
Expand Down Expand Up @@ -54,7 +54,7 @@ def serve_file(key, content_type:, disposition:)
send_data(db_service.download(key), options)
end

def upload_file(token, body:) # rubocop:disable Naming/PredicateMethod
def upload_file(token) # rubocop:disable Naming/PredicateMethod
return false unless acceptable_content?(token)

db_service.upload(token[:key], request.body, checksum: token[:checksum])
Expand Down
16 changes: 12 additions & 4 deletions lib/active_storage/service/db_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def url_for_direct_upload(key, expires_in:, content_type:, content_length:, chec
content_type: content_type,
content_length: content_length,
checksum: checksum,
service_name: respond_to?(:name) ? name : "db"
service_name: service_name_for_token
},
expires_in: expires_in,
purpose: :blob_token
Expand All @@ -108,12 +108,20 @@ def headers_for_direct_upload(_key, content_type:, **)

private

def service_name_for_token
respond_to?(:name) ? name : "db"
end

def adapter_sqlite?
@adapter_sqlite ||= active_storage_db_adapter_name == "SQLite"
return @adapter_sqlite if defined?(@adapter_sqlite)

@adapter_sqlite = active_storage_db_adapter_name == "SQLite"
end

def adapter_sqlserver?
@adapter_sqlserver ||= active_storage_db_adapter_name == "SQLServer"
return @adapter_sqlserver if defined?(@adapter_sqlserver)

@adapter_sqlserver = active_storage_db_adapter_name == "SQLServer"
end

def active_storage_db_adapter_name
Expand All @@ -131,7 +139,7 @@ def generate_url(key, expires_in:, filename:, content_type:, disposition:)
key: key,
disposition: content_disposition,
content_type: content_type,
service_name: respond_to?(:name) ? name : "db"
service_name: service_name_for_token
},
expires_in: expires_in,
purpose: :blob_key
Expand Down
8 changes: 5 additions & 3 deletions lib/active_storage/service/db_service_rails70.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ def compose(source_keys, destination_key, **)
buffer = nil
comment = "DBService#compose"
source_keys.each do |source_key|
data = ::ActiveStorageDB::File.annotate(comment).find_by!(ref: source_key).data
record = ::ActiveStorageDB::File.annotate(comment).find_by(ref: source_key)
raise ActiveStorage::FileNotFoundError unless record

if buffer
buffer << data
buffer << record.data
else
buffer = +data
buffer = +record.data
end
end
::ActiveStorageDB::File.create!(ref: destination_key, data: buffer) if buffer
Expand Down
30 changes: 18 additions & 12 deletions lib/tasks/active_storage_db_tasks.rake
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,40 @@ module ActiveStorage
module_function

def print_blob_header(digits: 0)
puts ['Size'.rjust(8), 'Date'.rjust(18), 'Id'.rjust(digits + 2), ' Filename'].join
puts ["Size".rjust(8), "Date".rjust(18), "Id".rjust(digits + 2), " Filename"].join
end

def print_blob(blob, digits: 0)
size = (blob.byte_size / 1024).to_s.rjust(7)
date = blob.created_at.strftime('%Y-%m-%d %H:%M')
date = blob.created_at.strftime("%Y-%m-%d %H:%M")
puts "#{size}K #{date} #{blob.id.to_s.rjust(digits)} #{blob.filename}"
end
end
end

namespace :asdb do
desc 'ActiveStorageDB: list attachments ordered by blob id desc'
desc "ActiveStorageDB: list attachments ordered by blob id desc"
task list: [:environment] do |_t, _args|
query = ActiveStorage::Blob.order(id: :desc).limit(100)
digits = query.ids.inject(0) { |ret, id| size = id.to_s.size; [size, ret].max }
digits = query.ids.inject(0) { |ret, id|
size = id.to_s.size
[size, ret].max
}

ActiveStorage::Tasks.print_blob_header(digits: digits)
query.each do |blob|
ActiveStorage::Tasks.print_blob(blob, digits: digits)
end
end

desc 'ActiveStorageDB: download attachment by blob id'
desc "ActiveStorageDB: download attachment by blob id"
task :download, [:blob_id, :destination] => [:environment] do |_t, args|
blob_id = args[:blob_id]&.strip
destination = args[:destination]&.strip || Dir.pwd
abort('Required arguments: source blob id, destination path') if blob_id.blank? || destination.blank?
abort("Required arguments: source blob id, destination path") if blob_id.blank? || destination.blank?

blob = ActiveStorage::Blob.find_by(id: blob_id)
abort('Source file not found') unless blob
abort("Source file not found") unless blob

destination = "#{destination}/#{blob.filename}" if Dir.exist?(destination)
dir = File.dirname(destination)
Expand All @@ -45,20 +48,23 @@ namespace :asdb do
puts "#{ret} bytes written - #{destination}"
end

desc 'ActiveStorageDB: search attachment by filename (or part of it)'
desc "ActiveStorageDB: search attachment by filename (or part of it)"
task :search, [:filename] => [:environment] do |_t, args|
filename = args[:filename]&.strip
abort('Required arguments: filename') if filename.blank?
abort("Required arguments: filename") if filename.blank?

blobs = ActiveStorage::Blob.where('filename LIKE ?', "%#{filename}%").order(id: :desc)
blobs = ActiveStorage::Blob.where("filename LIKE ?", "%#{ActiveRecord::Base.sanitize_sql_like(filename)}%").order(id: :desc)
if blobs.any?
digits = blobs.ids.inject(0) { |ret, id| size = id.to_s.size; [size, ret].max }
digits = blobs.ids.inject(0) { |ret, id|
size = id.to_s.size
[size, ret].max
}
ActiveStorage::Tasks.print_blob_header(digits: digits)
blobs.each do |blob|
ActiveStorage::Tasks.print_blob(blob, digits: digits)
end
else
puts 'No results'
puts "No results"
end
end
end
2 changes: 2 additions & 0 deletions spec/integration/attachments_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
ActiveStorage.touch_attachment_records = false
example.run
ActiveStorage.touch_attachment_records = touch_option
else
example.run
end
end

Expand Down
Loading