active_storage_db 1.1.0 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![gem version](https://badge.fury.io/rb/active_storage_db.svg)](https://badge.fury.io/rb/active_storage_db)
|
4
|
+
[![gem downloads](https://badgen.net/rubygems/dt/active_storage_db)](https://rubygems.org/gems/active_storage_db)
|
5
|
+
[![maintainability](https://api.codeclimate.com/v1/badges/92e1e703c308744a0f66/maintainability)](https://codeclimate.com/github/blocknotes/active_storage_db/maintainability)
|
6
|
+
|
4
7
|
[![linters](https://github.com/blocknotes/active_storage_db/actions/workflows/linters.yml/badge.svg)](https://github.com/blocknotes/active_storage_db/actions/workflows/linters.yml)
|
5
8
|
[![specs Postgres](https://github.com/blocknotes/active_storage_db/actions/workflows/specs_postgres_70.yml/badge.svg)](https://github.com/blocknotes/active_storage_db/actions/workflows/specs_postgres_70.yml)
|
6
9
|
[![Specs MySQL](https://github.com/blocknotes/active_storage_db/actions/workflows/specs_mysql_70.yml/badge.svg)](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
|