active_storage_db 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a465e1b93b8ab6436f800b2a0ff6e38f049fae621587924d9b2299f3fa06946
4
- data.tar.gz: 78583f7c6aa00b0a8c7ab1d98f05d4d34e8ff8a1846f0ed70a0c3e16e97275c7
3
+ metadata.gz: 5455342b089699d34e3f5e4386465431a93258ab9fa6610c8ba91b7c2c2f53f4
4
+ data.tar.gz: 86790589793eb8d0f6f5f4e781a3f5a161282d6a4f9409936a0ce0b5378ff243
5
5
  SHA512:
6
- metadata.gz: 76ef220615b3e3704a99803a8bbe3af211855278d3532a97bbc9f325a5455ff393dde657180368d10bdecce8592afe99a41be7f6fe28e325d3671fa3b414087a
7
- data.tar.gz: c555f306068194447e708c743abdc829f8043728585da32bbf504d689571d38a72725dbe97382665bd20fdaa95848b48ee018d45ab5d22692c1736ad9bcc59cb
6
+ metadata.gz: 2cc59ba9f5dd3510810412b6173b56b6e40f1a43570d1976a07c769c01a5f015d23c779f6ecde67e1d7e8471c4fa39a8dbc848c6ee943a24fc4f88c91d7017c3
7
+ data.tar.gz: 792e00cf27b413d645475dd500425b7e77b8ce96e82e32e4b5c474c025916dcc5b5593edf2fe13e1db8656ab429b9a60ed8ce6a1e78608af4392ee232a2423b0
data/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  [![specs Postgres](https://github.com/blocknotes/active_storage_db/actions/workflows/specs_postgres_71.yml/badge.svg)](https://github.com/blocknotes/active_storage_db/actions/workflows/specs_postgres_71.yml)
9
9
  [![specs MySQL](https://github.com/blocknotes/active_storage_db/actions/workflows/specs_mysql_71.yml/badge.svg)](https://github.com/blocknotes/active_storage_db/actions/workflows/specs_mysql_71.yml)
10
10
 
11
- An Active Storage service upload/download plugin that stores files in a PostgreSQL or MySQL database.
11
+ An Active Storage service upload/download plugin that stores files in a PostgreSQL or MySQL database. Experimental support also for MSSQL.
12
12
 
13
13
  Main features:
14
14
  - attachment data stored in a binary field (or blob);
@@ -8,6 +8,7 @@ module ActiveStorage
8
8
  # Wraps a DB table as an Active Storage service. See ActiveStorage::Service
9
9
  # for the generic API documentation that applies to all services.
10
10
  class Service::DBService < Service
11
+ # :nocov:
11
12
  if Rails::VERSION::MAJOR >= 7
12
13
  include ActiveStorage::DBServiceRails70
13
14
  elsif Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR == 1
@@ -15,6 +16,7 @@ module ActiveStorage
15
16
  else
16
17
  include ActiveStorage::DBServiceRails60
17
18
  end
19
+ # :nocov:
18
20
 
19
21
  def initialize(public: false, **)
20
22
  @chunk_size = ENV.fetch('ASDB_CHUNK_SIZE') { 1.megabytes }
@@ -43,7 +45,10 @@ module ActiveStorage
43
45
 
44
46
  def download_chunk(key, range)
45
47
  instrument :download_chunk, key: key, range: range do
46
- record = object_for(key, fields: "SUBSTRING(data FROM #{range.begin + 1} FOR #{range.size}) AS chunk")
48
+ from = range.begin + 1
49
+ size = range.size
50
+ args = adapter_sqlserver? ? "data, #{from}, #{size}" : "data FROM #{from} FOR #{size}"
51
+ record = object_for(key, fields: "SUBSTRING(#{args}) AS chunk")
47
52
  raise(ActiveStorage::FileNotFoundError) unless record
48
53
 
49
54
  record.chunk
@@ -97,6 +102,10 @@ module ActiveStorage
97
102
 
98
103
  private
99
104
 
105
+ def adapter_sqlserver?
106
+ @adapter_sqlserver ||= ActiveStorageDB::File.connection.adapter_name == 'SQLServer'
107
+ end
108
+
100
109
  def generate_url(key, expires_in:, filename:, content_type:, disposition:)
101
110
  content_disposition = content_disposition_with(type: disposition, filename: filename)
102
111
  verified_key_with_expiration = ActiveStorage.verifier.generate(
@@ -142,7 +151,8 @@ module ActiveStorage
142
151
  end
143
152
 
144
153
  def stream(key)
145
- size = object_for(key, fields: 'OCTET_LENGTH(data) AS size')&.size || raise(ActiveStorage::FileNotFoundError)
154
+ data_size = adapter_sqlserver? ? 'DATALENGTH(data)' : 'OCTET_LENGTH(data)'
155
+ size = object_for(key, fields: "#{data_size} AS size")&.size || raise(ActiveStorage::FileNotFoundError)
146
156
  (size / @chunk_size.to_f).ceil.times.each do |i|
147
157
  range = (i * @chunk_size..((i + 1) * @chunk_size) - 1)
148
158
  yield download_chunk(key, range)
@@ -19,8 +19,7 @@ module ActiveStorage
19
19
 
20
20
  def current_host
21
21
  opts = url_options || {}
22
- url = "#{opts[:protocol]}#{opts[:host]}"
23
- url + ":#{opts[:port]}" if opts[:port]
22
+ opts[:port] ? "#{opts[:protocol]}#{opts[:host]}:#{opts[:port]}" : "#{opts[:protocol]}#{opts[:host]}"
24
23
  end
25
24
 
26
25
  def private_url(key, expires_in:, filename:, content_type:, disposition:, **)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveStorageDB
4
- VERSION = '1.2.0'
4
+ VERSION = '1.3.1'
5
5
  end
@@ -19,12 +19,12 @@ end
19
19
  namespace :asdb do
20
20
  desc 'ActiveStorageDB: list attachments ordered by blob id desc'
21
21
  task list: [:environment] do |_t, _args|
22
- query = ::ActiveStorage::Blob.order(id: :desc).limit(100)
22
+ query = ActiveStorage::Blob.order(id: :desc).limit(100)
23
23
  digits = query.ids.inject(0) { |ret, id| size = id.to_s.size; [size, ret].max }
24
24
 
25
- ::ActiveStorage::Tasks.print_blob_header(digits: digits)
25
+ ActiveStorage::Tasks.print_blob_header(digits: digits)
26
26
  query.each do |blob|
27
- ::ActiveStorage::Tasks.print_blob(blob, digits: digits)
27
+ ActiveStorage::Tasks.print_blob(blob, digits: digits)
28
28
  end
29
29
  end
30
30
 
@@ -34,7 +34,7 @@ namespace :asdb do
34
34
  destination = args[:destination]&.strip || Dir.pwd
35
35
  abort('Required arguments: source blob id, destination path') if blob_id.blank? || destination.blank?
36
36
 
37
- blob = ::ActiveStorage::Blob.find_by(id: blob_id)
37
+ blob = ActiveStorage::Blob.find_by(id: blob_id)
38
38
  abort('Source file not found') unless blob
39
39
 
40
40
  destination = "#{destination}/#{blob.filename}" if Dir.exist?(destination)
@@ -50,12 +50,12 @@ namespace :asdb do
50
50
  filename = args[:filename]&.strip
51
51
  abort('Required arguments: filename') if filename.blank?
52
52
 
53
- blobs = ::ActiveStorage::Blob.where('filename LIKE ?', "%#{filename}%").order(id: :desc)
53
+ blobs = ActiveStorage::Blob.where('filename LIKE ?', "%#{filename}%").order(id: :desc)
54
54
  if blobs.any?
55
55
  digits = blobs.ids.inject(0) { |ret, id| size = id.to_s.size; [size, ret].max }
56
- ::ActiveStorage::Tasks.print_blob_header(digits: digits)
56
+ ActiveStorage::Tasks.print_blob_header(digits: digits)
57
57
  blobs.each do |blob|
58
- ::ActiveStorage::Tasks.print_blob(blob, digits: digits)
58
+ ActiveStorage::Tasks.print_blob(blob, digits: digits)
59
59
  end
60
60
  else
61
61
  puts 'No results'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_storage_db
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mattia Roccoberton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-22 00:00:00.000000000 Z
11
+ date: 2024-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activestorage