Class: Gemvault::Vault

Inherits:
Object
  • Object
show all
Extended by:
Forwardable, VaultSession
Defined in:
lib/gemvault/vault.rb

Overview

The public vault interface. Delegates storage to a backend chosen by file format: a Dbvault (SQLite) for existing SQLite files, a Tarvault (tarball) otherwise. New vaults are Tarvaults. Only the selected backend is loaded, so the tar path never requires sqlite3.

Defined Under Namespace

Classes: DuplicateGemError, Error, InvalidGemError, NotFoundError, ReadOnlyError, UnsupportedVersionError

Constant Summary collapse

SQLITE_MAGIC =
"SQLite format 3#{0.chr}".freeze
TAR_MAGIC =
"ustar".freeze
TAR_MAGIC_OFFSET =
257
CURRENT_FORMAT =
2
MIN_READABLE_FORMAT =
1

Class Method Summary collapse

Instance Method Summary collapse

Methods included from VaultSession

open

Constructor Details

#initialize(path, create: false) ⇒ Vault

Returns a new instance of Vault.



83
84
85
# File 'lib/gemvault/vault.rb', line 83

def initialize(path, create: false)
  @backend = self.class.backend_for(File.expand_path(path), create: create)
end

Class Method Details

.assert_readable!(version, path) ⇒ Object



32
33
34
35
36
37
# File 'lib/gemvault/vault.rb', line 32

def self.assert_readable!(version, path)
  return if version.between?(MIN_READABLE_FORMAT, CURRENT_FORMAT)

  raise UnsupportedVersionError,
        "Vault #{path} is format #{version}; this gemvault reads up to #{CURRENT_FORMAT}. Upgrade gemvault."
end

.backend_for(path, create:) ⇒ Object

Raises:



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/gemvault/vault.rb', line 39

def self.backend_for(path, create:)
  return build_tarvault(path, create: true) if create
  raise NotFoundError, "Vault not found: #{path}" unless File.exist?(path)

  case container_kind(path)
  when :sqlite then build_dbvault(path)
  when :tar then build_tarvault(path, create: false)
  else
    raise Error, "Unrecognized vault format: #{path} (not a Dbvault or Tarvault; it may require a newer gemvault)"
  end
end

.build_dbvault(path) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/gemvault/vault.rb', line 69

def self.build_dbvault(path)
  require_relative "dbvault"
  Dbvault.new(path)
rescue LoadError => e
  raise Error,
        "#{path} is a legacy SQLite vault; it needs the sqlite3 gem (#{e.message}). " \
        "Install sqlite3, or upgrade the vault with a gemvault that includes it."
end

.build_tarvault(path, create:) ⇒ Object



78
79
80
81
# File 'lib/gemvault/vault.rb', line 78

def self.build_tarvault(path, create:)
  require_relative "tarvault"
  Tarvault.new(path, create: create)
end

.container_kind(path) ⇒ Object



51
52
53
54
55
56
# File 'lib/gemvault/vault.rb', line 51

def self.container_kind(path)
  return :sqlite if sqlite?(path)
  return :tar if tar?(path)

  :unknown
end

.sqlite?(path) ⇒ Boolean

Returns:

  • (Boolean)


58
59
60
# File 'lib/gemvault/vault.rb', line 58

def self.sqlite?(path)
  File.exist?(path) && File.binread(path, SQLITE_MAGIC.bytesize) == SQLITE_MAGIC
end

.tar?(path) ⇒ Boolean

Returns:

  • (Boolean)


62
63
64
65
66
67
# File 'lib/gemvault/vault.rb', line 62

def self.tar?(path)
  return false unless File.exist?(path)

  header = File.binread(path, TAR_MAGIC_OFFSET + TAR_MAGIC.bytesize)
  header.to_s[TAR_MAGIC_OFFSET, TAR_MAGIC.bytesize] == TAR_MAGIC
end