class CarrierWave::Storage::PostgresqlTable::File

Constants

READ_CHUNK_SIZE
STREAM_CHUNK_SIZE

Attributes

path[R]

Public Class Methods

new(path) click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 58
def initialize(path)
  @path = path
  @record = CarrierWaveFile.find_or_initialize_by(:path => path)
  @read_pos = 0
end

Public Instance Methods

content_type() click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 119
def content_type
  @record.content_type
end
content_type=(new_content_type) click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 123
def content_type=(new_content_type)
  @record.update_attribute(:content_type, new_content_type)
end
delete() click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 192
def delete
  CarrierWaveFile.delete_all_files("id = #{CarrierWaveFile.connection.quote(@record.id)}")
end
eof?() click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 111
def eof?
  @read_pos == self.size
end
exists?() click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 178
def exists?
  @record && @record.persisted?
end
filename() click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 99
def filename
  ::File.basename(@path)
end
last_modified() click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 103
def last_modified
  @record.updated_at
end
move_to(new_path) click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 182
def move_to(new_path)
  CarrierWaveFile.transaction do
    # Remove any existing files at the current path.
    CarrierWaveFile.delete_all_files("path = #{CarrierWaveFile.connection.quote(new_path)} AND id != #{CarrierWaveFile.connection.quote(@record.id)}")

    # Change the current record's path to the new path.
    @record.update_attribute(:path, new_path)
  end
end
read(length = nil, buffer = nil) click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 64
def read(length = nil, buffer = nil)
  data = nil
  CarrierWaveFile.transaction do
    raw_connection = CarrierWaveFile.connection.raw_connection

    begin
      lo = raw_connection.lo_open(@record.pg_largeobject_oid)
      if length
        raw_connection.lo_lseek(lo, @read_pos, PG::SEEK_SET)
        data = raw_connection.lo_read(lo, length)
        @read_pos = raw_connection.lo_tell(lo)
      else
        data = raw_connection.lo_read(lo, self.size)
      end
    ensure
      raw_connection.lo_close(lo) if lo
    end
  end

  if (buffer && data)
    buffer.replace(data)
  end

  data
end
rewind() click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 115
def rewind
  @read_pos = 0
end
size() click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 107
def size
  @size = @record.size || fetch_size
end
store(new_file) click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 131
def store(new_file)
  CarrierWaveFile.transaction do
    connection = CarrierWaveFile.connection
    raw_connection = connection.raw_connection
    oid = nil
    if new_file.kind_of?(CarrierWave::Storage::PostgresqlTable::File)
      file = new_file
    else
      file = new_file.to_file
    end

    begin
      oid = @record.pg_largeobject_oid || raw_connection.lo_creat
      handle = raw_connection.lo_open(oid, PG::INV_WRITE)
      raw_connection.lo_truncate(handle, 0)
      buffer = String.new # rubocop:disable Style/EmptyLiteral
      until file.eof?
        file.read(READ_CHUNK_SIZE, buffer)
        raw_connection.lo_write(handle, buffer)
      end
      file.rewind
    ensure
      raw_connection.lo_close(handle)
    end

    begin
      old_oid = @record.pg_largeobject_oid
      @record.pg_largeobject_oid = oid
      @record.size = new_file.size
      @record.content_type = new_file.content_type
      @record.save

      # Cleanup old, unused largeobject OIDs if we're updating the
      # record with a new OID reference.
      if (old_oid && old_oid != oid)
        old_references = connection.select_value("SELECT COUNT(*) FROM #{CarrierWaveFile.table_name} WHERE pg_largeobject_oid = #{CarrierWaveFile.connection.quote(old_oid)}").to_i
        if (old_references == 0)
          raw_connection.lo_unlink(old_oid)
        end
      end
    rescue ::ActiveRecord::RecordNotUnique
      @record = CarrierWaveFile.find_or_initialize_by(:path => @path)
      retry
    end
  end
end
to_tempfile() click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 90
def to_tempfile
  Tempfile.new(:binmode => true).tap do |tempfile|
    IO.copy_stream(self, tempfile)
    self.rewind
    tempfile.rewind
    tempfile.fsync
  end
end
url(_options = {}) click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 127
def url(_options = {})
  ::File.join("/", @path)
end

Private Instance Methods

fetch_size() click to toggle source
# File lib/carrierwave/storage/postgresql_table.rb, line 198
def fetch_size
  size = nil
  CarrierWaveFile.transaction do
    raw_connection = CarrierWaveFile.connection.raw_connection
    lo = raw_connection.lo_open(@record.pg_largeobject_oid)
    size = raw_connection.lo_lseek(lo, 0, PG::SEEK_END)
  end

  size
end