class Pione::Package::Database

Package::Database is a repository of package informations and the digest for cache reference. The keys of database are package name, editor, and tag.

Public Class Methods

load(location=Global.package_database_location) click to toggle source

Load package database from the location. The location should be local.

# File lib/pione/package/package-database.rb, line 19
def load(location=Global.package_database_location)
  unless location.local?
    raise DatabaseError.new("package database file should be in local: %s" % location.address)
  end

  if location.exist?
    read location.path.open(File::RDONLY) do |f|
      f.flock(File::LOCK_SH)
      f.read
    end
  else
    db = new
    db.save
    Log::SystemLog.info "PIONE created a new package database at %s" % Global.package_database_location.address
    return db
  end
end
new() click to toggle source
# File lib/pione/package/package-database.rb, line 38
def initialize
  # make a 3d table
  @table = Hash.new {|h1,k1| h1[k1] = Hash.new {|h2,k2| h2[k2] = Hash.new}}
  @digests = []
end
read(str) click to toggle source

Read package database from the string.

# File lib/pione/package/package-database.rb, line 9
def read(str)
  JSON.load(str).each_with_object(new) do |data, db|
    db.add(DatabaseRecord.new(
        name: data["PackageName"], editor: data["Editor"], tag: data["Tag"],
        location: data["Location"], state: data["State"], digest: data["Digest"]
    ))
  end
end

Public Instance Methods

add(record) click to toggle source

Add the record.

# File lib/pione/package/package-database.rb, line 45
def add(record)
  unless record.kind_of?(DatabaseRecord)
    record = DatabaseRecord.new(record)
  end
  @table[record.name][record.editor || "origin"][record.tag] = record
  @digests << record.digest
end
count() click to toggle source

Return record number of the database.

# File lib/pione/package/package-database.rb, line 60
def count
  @table.inject(0) do |i1, (_, t1)|
    t1.inject(i1) do |i2, (_, t2)|
      t2.inject(i2) {|i3, (_, val)| val ? i3 + 1 : i3}
    end
  end
end
delete(name, editor, tag) click to toggle source

Delete a record by the tuple of name, editor, and tag. Editor is “origin” if it is nil.

# File lib/pione/package/package-database.rb, line 55
def delete(name, editor, tag)
  @table[name][editor || "origin"][tag] = nil
end
exist?(name, editor, tag) click to toggle source

Return true if the package exists in database.

@param [String] name

package name

@param [String] editor

editor name

@param [String] tag

tag name

@return [Boolean]

true if the package exists in database
# File lib/pione/package/package-database.rb, line 88
def exist?(name, editor, tag)
  not(find(name, editor, tag).nil?)
end
find(name, editor, tag) click to toggle source

Find a record by the tuple of name, editor, and tag. Editor is “origin” if it is nil.

# File lib/pione/package/package-database.rb, line 74
def find(name, editor, tag)
  @table[name][editor || "origin"][tag]
end
has_digest?(digest) click to toggle source

Return true if the digest is included in package database.

# File lib/pione/package/package-database.rb, line 69
def has_digest?(digest)
  @digests.include?(digest)
end
save(location=Global.package_database_location) click to toggle source

Save the database to the location.

# File lib/pione/package/package-database.rb, line 93
def save(location=Global.package_database_location)
  json = JSON.generate(self)

  # NOTE: File#flock needs read & write mode to avoid truncating without lock
  location.path.open(File::RDWR|File::CREAT) do |f|
    f.flock(File::LOCK_EX)
    f.rewind
    f.write(json)
    f.flush
    f.truncate(f.pos)
  end
end
to_json(*args) click to toggle source

Convert to JSON.

# File lib/pione/package/package-database.rb, line 107
def to_json(*args)
  @table.each_with_object([]) do |(_, t1), list|
    t1.each{|_, t2| t2.each{|_, record| list << record if record}}
  end.to_json(*args)
end