active_storage-postgresql 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02204d5bc6e8a8e41d30c3d38ae5308345dce145c9b80f98127dacd8c74ac3ba
4
- data.tar.gz: 2e15d75e150d8d3be1634f21f7c75b6018fa6a4b75f079aa301de2a526ff3f43
3
+ metadata.gz: 8e03540828022cafb6f37bcb926ed367951072e40af4970f51809b796e5fc8d5
4
+ data.tar.gz: 369c7335dfbb46aa1add165303bbb8c505600df7be8dc08663968b35884a08d5
5
5
  SHA512:
6
- metadata.gz: 0f94e2258f91ef67cba241bca7936225f9f11076b307114a81df7b6f9b5d20aa7d126dd136c94d31813e045395635f3ad6de36b5f8eaf638d4b1c91d319db28a
7
- data.tar.gz: c244fed09f914b4ce819577949ae12a33f80c8d4f0cee9987d3efd0952eb8a9048a52ba5aaaec959e1ef1b51d1045585313fb0ca63a1827d6684605a1853b5fe
6
+ metadata.gz: ffc0882ec92da092e0954498f3815367b9d52b6329e4aae764531cb888ffdd22b87ebaffd8189acb3c2750db71af0badf632642c57b3fd5ff30d80dc22100042
7
+ data.tar.gz: 9e4aabe7a6cd2dbf777749078db3e2d382ff385067bdd045883d5a3b56cab9bbc5dbe3926f191451c394677b2d4e76f7e00c315c82772ff8a9a1d86561823bd9
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # ActiveStorage::PostgreSQL
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/active_storage-postgresql.svg)](https://badge.fury.io/rb/active_storage-postgresql)
4
+ [![Build Status](https://travis-ci.com/lsylvester/active_storage-postgresql.svg?branch=master)](https://travis-ci.com/lsylvester/active_storage-postgresql)
5
+
3
6
  ActiveStorage Service to store files PostgeSQL.
4
7
 
5
8
  Files are stored in PostgreSQL as Large Objects, which provide streaming style access.
@@ -7,13 +10,13 @@ More information about Large Objects can be found [here](https://www.postgresql.
7
10
 
8
11
  This allows use of ActiveStorage on hosting platforms with ephemeral file systems such as Heroku without relying on third party storage services.
9
12
 
10
- There are [some limits](https://dba.stackexchange.com/questions/127270/what-are-the-limits-of-postgresqls-large-object-facility) to the storage of Large Objects in PostgerSQL, so this is only recommended for prototyping and very small sites.
13
+ There are [some limits](https://dba.stackexchange.com/questions/127270/what-are-the-limits-of-postgresqls-large-object-facility) to the storage of Large Objects in PostgerSQL, so this is only recommended for prototyping and very small sites.
11
14
 
12
15
  ## Installation
13
16
  Add this line to your application's Gemfile:
14
17
 
15
18
  ```ruby
16
- gem 'active_storage-postgresql', git: "https://github.com/lsylvester/active_storage-postgresql"
19
+ gem 'active_storage-postgresql'
17
20
  ```
18
21
 
19
22
  And then execute:
@@ -1,8 +1,31 @@
1
1
  class ActiveStorage::PostgreSQL::File < ActiveRecord::Base
2
2
  self.table_name = "active_storage_postgresql_files"
3
3
 
4
- before_create do
5
- self.oid ||= lo_creat
4
+ attribute :oid, :integer, default: ->{ connection.raw_connection.lo_creat }
5
+ attr_accessor :checksum, :io
6
+ attr_writer :digest
7
+
8
+ def digest
9
+ @digest ||= Digest::MD5.new
10
+ end
11
+
12
+ before_create :write_or_import, if: :io
13
+ before_create :verify_checksum, if: :checksum
14
+
15
+ def write_or_import
16
+ if io.respond_to?(:to_path)
17
+ import(io.to_path)
18
+ else
19
+ open(::PG::INV_WRITE) do |file|
20
+ while data = io.read(5.megabytes)
21
+ write(data)
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ def verify_checksum
28
+ raise ActiveStorage::IntegrityError unless digest.base64digest == checksum
6
29
  end
7
30
 
8
31
  def self.open(key, &block)
@@ -22,34 +45,40 @@ class ActiveStorage::PostgreSQL::File < ActiveRecord::Base
22
45
 
23
46
  def write(content)
24
47
  lo_write(@lo, content)
48
+ digest.update(content)
25
49
  end
26
50
 
27
51
  def read(bytes=size)
28
52
  lo_read(@lo, bytes)
29
53
  end
30
54
 
31
- def seek(position)
32
- lo_seek(@lo, position, 0)
55
+ def seek(position, whence=PG::SEEK_SET)
56
+ lo_seek(@lo, position, whence)
33
57
  end
34
58
 
35
59
  def import(path)
36
- transaction do
37
- self.oid = lo_import(path)
38
- end
60
+ self.oid = lo_import(path)
61
+ self.digest = Digest::MD5.file(path)
62
+ end
63
+
64
+ def tell
65
+ lo_tell(@lo)
39
66
  end
40
67
 
41
68
  def size
42
- current_position = lo_tell(@lo)
43
- lo_seek(@lo, 0,2)
44
- lo_tell(@lo).tap do
45
- lo_seek(@lo, current_position,0)
69
+ current_position = tell
70
+ seek(0, PG::SEEK_END)
71
+ tell.tap do
72
+ seek(current_position)
46
73
  end
47
74
  end
48
75
 
49
- before_destroy do
50
- self.class.connection.raw_connection.lo_unlink(oid)
76
+ def unlink
77
+ lo_unlink(oid)
51
78
  end
52
79
 
80
+ before_destroy :unlink
81
+
53
82
  delegate :lo_seek, :lo_tell, :lo_import, :lo_read, :lo_write, :lo_open,
54
83
  :lo_unlink, :lo_close, :lo_creat, to: 'self.class.connection.raw_connection'
55
84
 
@@ -1,5 +1,5 @@
1
1
  module ActiveStorage
2
2
  module PostgreSQL
3
- VERSION = '0.1.0'
3
+ VERSION = '0.1.1'
4
4
  end
5
5
  end
@@ -9,33 +9,9 @@ module ActiveStorage
9
9
  def initialize(**options)
10
10
  end
11
11
 
12
- def upload(key, io, checksum: nil)
12
+ def upload(key, io, checksum: nil, **)
13
13
  instrument :upload, key: key, checksum: checksum do
14
- if io.respond_to?(:to_path)
15
- ActiveStorage::PostgreSQL::File.create!(key: key) do |file|
16
- file.import(io.to_path)
17
- end
18
- if checksum
19
- unless Digest::MD5.file(io.to_path).base64digest == checksum
20
- delete key
21
- raise ActiveStorage::IntegrityError
22
- end
23
- end
24
- else
25
- md5 = Digest::MD5.new
26
- ActiveStorage::PostgreSQL::File.create!(key: key).open(::PG::INV_WRITE) do |file|
27
- while data = io.read(5.megabytes)
28
- md5.update(data)
29
- file.write(data)
30
- end
31
- end
32
- if checksum
33
- unless md5.base64digest == checksum
34
- delete key
35
- raise ActiveStorage::IntegrityError
36
- end
37
- end
38
- end
14
+ ActiveStorage::PostgreSQL::File.create!(key: key, io: io, checksum: checksum)
39
15
  end
40
16
  end
41
17
 
@@ -88,17 +64,23 @@ module ActiveStorage
88
64
 
89
65
  def url(key, expires_in:, filename:, disposition:, content_type:)
90
66
  instrument :url, key: key do |payload|
91
- verified_key_with_expiration = ActiveStorage.verifier.generate(key, expires_in: expires_in, purpose: :blob_key)
92
-
93
- generated_url =
94
- url_helpers.rails_disk_service_url(
95
- verified_key_with_expiration,
96
- host: current_host,
97
- filename: filename,
98
- disposition: content_disposition_with(type: disposition, filename: filename),
67
+ content_disposition = content_disposition_with(type: disposition, filename: filename)
68
+ verified_key_with_expiration = ActiveStorage.verifier.generate(
69
+ {
70
+ key: key,
71
+ disposition: content_disposition,
99
72
  content_type: content_type
100
- )
73
+ },
74
+ { expires_in: expires_in,
75
+ purpose: :blob_key }
76
+ )
101
77
 
78
+ generated_url = url_helpers.rails_disk_service_url(verified_key_with_expiration,
79
+ host: current_host,
80
+ disposition: content_disposition,
81
+ content_type: content_type,
82
+ filename: filename
83
+ )
102
84
  payload[:url] = generated_url
103
85
 
104
86
  generated_url
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_storage-postgresql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lachlan Sylvester
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-27 00:00:00.000000000 Z
11
+ date: 2018-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -104,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
104
  version: '0'
105
105
  requirements: []
106
106
  rubyforge_project:
107
- rubygems_version: 2.7.3
107
+ rubygems_version: 2.7.6
108
108
  signing_key:
109
109
  specification_version: 4
110
110
  summary: PostgreSQL Adapter for Active Storage