Class: Refile::Postgres::Backend

Inherits:
Object
  • Object
show all
Defined in:
lib/refile/postgres/backend.rb,
lib/refile/postgres/backend/reader.rb

Defined Under Namespace

Classes: Reader

Constant Summary collapse

DEFAULT_REGISTRY_TABLE =
"refile_attachments"
DEFAULT_NAMESPACE =
"default"
PG_LARGE_OBJECT_TABLE =
"pg_largeobject"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, max_size: nil, namespace: DEFAULT_NAMESPACE, registry_table: DEFAULT_REGISTRY_TABLE) ⇒ Backend

Returns a new instance of Backend.



7
8
9
10
11
12
# File 'lib/refile/postgres/backend.rb', line 7

def initialize(connection, max_size: nil, namespace: DEFAULT_NAMESPACE, registry_table: DEFAULT_REGISTRY_TABLE)
  @connection = connection
  @namespace = namespace.to_s
  @registry_table = registry_table
  @max_size = max_size
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



14
15
16
# File 'lib/refile/postgres/backend.rb', line 14

def connection
  @connection
end

#namespaceObject (readonly)

Returns the value of attribute namespace.



14
15
16
# File 'lib/refile/postgres/backend.rb', line 14

def namespace
  @namespace
end

#registry_tableObject (readonly)

Returns the value of attribute registry_table.



14
15
16
# File 'lib/refile/postgres/backend.rb', line 14

def registry_table
  @registry_table
end

Instance Method Details

#clear!(confirm = nil) ⇒ Object

Raises:

  • (ArgumentError)


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/refile/postgres/backend.rb', line 82

def clear!(confirm = nil)
  raise ArgumentError, "are you sure? this will remove all files in the backend, call as `clear!(:confirm)` if you're sure you want to do this" unless confirm == :confirm
  connection.transaction do
    connection.exec_params(%{
      SELECT * FROM #{registry_table}
      INNER JOIN #{PG_LARGE_OBJECT_TABLE} ON #{registry_table}.id = #{PG_LARGE_OBJECT_TABLE}.loid
      WHERE #{registry_table}.namespace = $1::varchar;
    }, [namespace]) do |result|
      result.each_row do |row|
        connection.lo_unlink(row[0].to_s.to_i)
      end
    end
    connection.exec_params("DELETE FROM #{registry_table} WHERE namespace = $1::varchar;", [namespace])
  end
end

#delete(id) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/refile/postgres/backend.rb', line 73

def delete(id)
  if exists?(id)
    connection.transaction do
      connection.lo_unlink(id.to_s.to_i)
      connection.exec_params("DELETE FROM #{registry_table} WHERE id = $1::integer;", [id])
    end
  end
end

#exists?(id) ⇒ Boolean

Returns:

  • (Boolean)


53
54
55
56
57
58
59
60
61
62
63
# File 'lib/refile/postgres/backend.rb', line 53

def exists?(id)
  connection.exec_params(%{
    SELECT count(*) FROM #{registry_table}
    INNER JOIN #{PG_LARGE_OBJECT_TABLE}
    ON #{registry_table}.id = #{PG_LARGE_OBJECT_TABLE}.loid
    WHERE #{registry_table}.namespace = $1::varchar
    AND #{registry_table}.id = $2::integer;
  }, [namespace, id.to_s.to_i]) do |result|
    result[0]["count"].to_i > 0
  end
end

#get(id) ⇒ Object



49
50
51
# File 'lib/refile/postgres/backend.rb', line 49

def get(id)
  Refile::File.new(self, id)
end

#open(id) ⇒ Object



37
38
39
# File 'lib/refile/postgres/backend.rb', line 37

def open(id)
  Reader.new(connection, id)
end

#read(id) ⇒ Object



41
42
43
44
45
46
47
# File 'lib/refile/postgres/backend.rb', line 41

def read(id)
  if exists?(id)
    open(id).read
  else
    nil
  end
end

#size(id) ⇒ Object



65
66
67
68
69
70
71
# File 'lib/refile/postgres/backend.rb', line 65

def size(id)
  if exists?(id)
    open(id).size
  else
    nil
  end
end

#upload(uploadable) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/refile/postgres/backend.rb', line 16

def upload(uploadable)
  Refile.verify_uploadable(uploadable, @max_size)
  oid = connection.lo_creat
  connection.transaction do
    begin
      handle = connection.lo_open(oid, PG::INV_WRITE)
      connection.lo_truncate(handle, 0)
      buffer = "" # reuse the same buffer
      until uploadable.eof?
        uploadable.read(Refile.read_chunk_size, buffer)
        connection.lo_write(handle, buffer)
      end
      uploadable.close
      connection.exec_params("INSERT INTO #{registry_table} VALUES ($1::integer, $2::varchar);", [oid, namespace])
      Refile::File.new(self, oid.to_s)
    ensure
      connection.lo_close(handle)
    end
  end
end