active_storage_db 1.1.0 → 1.1.2
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 +4 -4
- data/README.md +3 -0
- data/app/controllers/active_storage_db/files_controller.rb +22 -16
- data/app/models/active_storage_db/application_record.rb +7 -0
- data/app/models/active_storage_db/file.rb +1 -1
- data/db/migrate/20200702202022_create_active_storage_db_files.rb +15 -2
- data/lib/active_storage/service/db_service.rb +17 -12
- data/lib/active_storage_db/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33872893aefc8f1086a8c422819990e10d1d46d2b97bd87d67662fd153536243
|
4
|
+
data.tar.gz: 0e662cd62a06ec353c9e02706c1c553500edafa146e4149d21fa57626d129d5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a418655f7275cc54264b25733712cbe813eeede79eb7d08833c2e333427d7a9c1cb44f1c46b3a338cf20407abf0d7d9b59e2dfcdec0f1467b77f47ca85b7357e
|
7
|
+
data.tar.gz: ac8d6c3c8fc9c44177d474c709f67ff5a46a8c1835c15e9f753773ac846851e23bd13ef2e8e0c3fd13185ea0d8f528f31aac8ae48275a46288bde22a6ad04dee
|
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# Active Storage DB
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/active_storage_db)
|
4
|
+
[](https://rubygems.org/gems/active_storage_db)
|
5
|
+
[](https://codeclimate.com/github/blocknotes/active_storage_db/maintainability)
|
6
|
+
|
4
7
|
[](https://github.com/blocknotes/active_storage_db/actions/workflows/linters.yml)
|
5
8
|
[](https://github.com/blocknotes/active_storage_db/actions/workflows/specs_postgres_70.yml)
|
6
9
|
[](https://github.com/blocknotes/active_storage_db/actions/workflows/specs_mysql_70.yml)
|
@@ -8,34 +8,41 @@ module ActiveStorageDB
|
|
8
8
|
if (key = decode_verified_key)
|
9
9
|
serve_file(key[:key], content_type: key[:content_type], disposition: key[:disposition])
|
10
10
|
else
|
11
|
-
head
|
11
|
+
head(:not_found)
|
12
12
|
end
|
13
13
|
rescue ActiveStorage::FileNotFoundError
|
14
|
-
head
|
14
|
+
head(:not_found)
|
15
15
|
end
|
16
16
|
|
17
17
|
def update
|
18
18
|
if (token = decode_verified_token)
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
head :unprocessable_entity
|
23
|
-
end
|
19
|
+
file_uploaded = upload_file(token, body: request.body)
|
20
|
+
head(file_uploaded ? :no_content : :unprocessable_entity)
|
24
21
|
else
|
25
|
-
head
|
22
|
+
head(:not_found)
|
26
23
|
end
|
27
24
|
rescue ActiveStorage::IntegrityError
|
28
|
-
head
|
25
|
+
head(:unprocessable_entity)
|
29
26
|
end
|
30
27
|
|
31
28
|
private
|
32
29
|
|
30
|
+
def acceptable_content?(token)
|
31
|
+
token[:content_type] == request.content_mime_type && token[:content_length] == request.content_length
|
32
|
+
end
|
33
|
+
|
33
34
|
def db_service
|
34
35
|
ActiveStorage::Blob.service
|
35
36
|
end
|
36
37
|
|
37
38
|
def decode_verified_key
|
38
|
-
ActiveStorage.verifier.verified(params[:encoded_key], purpose: :blob_key)
|
39
|
+
key = ActiveStorage.verifier.verified(params[:encoded_key], purpose: :blob_key)
|
40
|
+
key&.deep_symbolize_keys
|
41
|
+
end
|
42
|
+
|
43
|
+
def decode_verified_token
|
44
|
+
token = ActiveStorage.verifier.verified(params[:encoded_token], purpose: :blob_token)
|
45
|
+
token&.deep_symbolize_keys
|
39
46
|
end
|
40
47
|
|
41
48
|
def serve_file(key, content_type:, disposition:)
|
@@ -43,15 +50,14 @@ module ActiveStorageDB
|
|
43
50
|
type: content_type || DEFAULT_SEND_FILE_TYPE,
|
44
51
|
disposition: disposition || DEFAULT_SEND_FILE_DISPOSITION
|
45
52
|
}
|
46
|
-
send_data
|
53
|
+
send_data(db_service.download(key), options)
|
47
54
|
end
|
48
55
|
|
49
|
-
def
|
50
|
-
|
51
|
-
end
|
56
|
+
def upload_file(token, body:)
|
57
|
+
return false unless acceptable_content?(token)
|
52
58
|
|
53
|
-
|
54
|
-
|
59
|
+
db_service.upload(token[:key], request.body, checksum: token[:checksum])
|
60
|
+
true
|
55
61
|
end
|
56
62
|
end
|
57
63
|
end
|
@@ -2,12 +2,25 @@
|
|
2
2
|
|
3
3
|
class CreateActiveStorageDBFiles < ActiveRecord::Migration[6.0]
|
4
4
|
def change
|
5
|
-
create_table :active_storage_db_files do |t|
|
5
|
+
create_table :active_storage_db_files, id: primary_key_type do |t|
|
6
6
|
t.string :ref, null: false
|
7
7
|
t.binary :data, null: false
|
8
|
-
|
8
|
+
|
9
|
+
if connection.supports_datetime_with_precision?
|
10
|
+
t.datetime :created_at, precision: 6, null: false
|
11
|
+
else
|
12
|
+
t.datetime :created_at, null: false
|
13
|
+
end
|
9
14
|
|
10
15
|
t.index [:ref], unique: true
|
11
16
|
end
|
12
17
|
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def primary_key_type
|
22
|
+
config = Rails.configuration.generators
|
23
|
+
primary_key_type = config.options[config.orm][:primary_key_type]
|
24
|
+
primary_key_type || :primary_key
|
25
|
+
end
|
13
26
|
end
|
@@ -36,18 +36,14 @@ module ActiveStorage
|
|
36
36
|
end
|
37
37
|
else
|
38
38
|
instrument :download, key: key do
|
39
|
-
|
40
|
-
raise(ActiveStorage::FileNotFoundError) unless record
|
41
|
-
|
42
|
-
record.data
|
39
|
+
retrieve_file(key)
|
43
40
|
end
|
44
41
|
end
|
45
42
|
end
|
46
43
|
|
47
44
|
def download_chunk(key, range)
|
48
45
|
instrument :download_chunk, key: key, range: range do
|
49
|
-
|
50
|
-
record = ::ActiveStorageDB::File.select(chunk_select).find_by(ref: key)
|
46
|
+
record = object_for(key, fields: "SUBSTRING(data FROM #{range.begin + 1} FOR #{range.size}) AS chunk")
|
51
47
|
raise(ActiveStorage::FileNotFoundError) unless record
|
52
48
|
|
53
49
|
record.chunk
|
@@ -63,7 +59,7 @@ module ActiveStorage
|
|
63
59
|
|
64
60
|
def delete_prefixed(prefix)
|
65
61
|
instrument :delete_prefixed, prefix: prefix do
|
66
|
-
::ActiveStorageDB::File.where('ref LIKE ?', "#{prefix}%").destroy_all
|
62
|
+
::ActiveStorageDB::File.where('ref LIKE ?', "#{ApplicationRecord.sanitize_sql_like(prefix)}%").destroy_all
|
67
63
|
end
|
68
64
|
end
|
69
65
|
|
@@ -127,17 +123,26 @@ module ActiveStorage
|
|
127
123
|
end
|
128
124
|
|
129
125
|
def ensure_integrity_of(key, checksum)
|
130
|
-
|
131
|
-
return if Digest::MD5.base64digest(file.data) == checksum
|
126
|
+
return if Digest::MD5.base64digest(object_for(key).data) == checksum
|
132
127
|
|
133
128
|
delete(key)
|
134
129
|
raise ActiveStorage::IntegrityError
|
135
130
|
end
|
136
131
|
|
132
|
+
def retrieve_file(key)
|
133
|
+
file = object_for(key)
|
134
|
+
raise(ActiveStorage::FileNotFoundError) unless file
|
135
|
+
|
136
|
+
file.data
|
137
|
+
end
|
138
|
+
|
139
|
+
def object_for(key, fields: nil)
|
140
|
+
as_file = fields ? ::ActiveStorageDB::File.select(*fields) : ::ActiveStorageDB::File
|
141
|
+
as_file.find_by(ref: key)
|
142
|
+
end
|
143
|
+
|
137
144
|
def stream(key)
|
138
|
-
size =
|
139
|
-
::ActiveStorageDB::File.select('OCTET_LENGTH(data) AS size').find_by(ref: key)&.size ||
|
140
|
-
raise(ActiveStorage::FileNotFoundError)
|
145
|
+
size = object_for(key, fields: 'OCTET_LENGTH(data) AS size')&.size || raise(ActiveStorage::FileNotFoundError)
|
141
146
|
(size / @chunk_size.to_f).ceil.times.each do |i|
|
142
147
|
range = (i * @chunk_size..((i + 1) * @chunk_size) - 1)
|
143
148
|
yield download_chunk(key, range)
|
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.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mattia Roccoberton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activestorage
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- README.md
|
78
78
|
- Rakefile
|
79
79
|
- app/controllers/active_storage_db/files_controller.rb
|
80
|
+
- app/models/active_storage_db/application_record.rb
|
80
81
|
- app/models/active_storage_db/file.rb
|
81
82
|
- config/initializers/inflections.rb
|
82
83
|
- config/routes.rb
|