lib/bundler_api/gem_info.rb
require 'bundler_api'
require 'compact_index'
# Return data about all the gems: all gem names, all versions of all gems, all dependencies for all versions of a gem
class BundlerApi::GemInfo
VERSIONS_FILE_PATH = "./versions.list"
DepKey = Struct.new(:name, :number, :platform, :required_ruby_version, :rubygems_version, :checksum, :created_at)
def initialize(connection)
@conn = connection
end
# @param [String] the gem name
def deps_for(gem_name)
dataset = @conn[<<-SQL, gem_name]
SELECT rv.name, rv.number, rv.platform, rv.required_ruby_version, rv.checksum,
rv.rubygems_version, d.requirements, rv.created_at, for_dep_name.name dep_name
FROM
(SELECT r.name, v.number, v.platform,v.rubygems_version, v.checksum,
v.required_ruby_version, v.created_at, v.id AS version_id
FROM rubygems AS r, versions AS v
WHERE v.rubygem_id = r.id
AND v.indexed is true
AND r.name = ?
ORDER BY v.created_at, v.number, v.platform) AS rv
LEFT JOIN dependencies AS d ON
d.version_id = rv.version_id
LEFT JOIN rubygems AS for_dep_name ON
d.rubygem_id = for_dep_name.id
AND d.scope = 'runtime'
ORDER BY rv.created_at, rv.number, rv.platform, for_dep_name.name;
SQL
deps = {}
dataset.each do |row|
key = DepKey.new(
row[:name],
row[:number],
row[:platform],
row[:required_ruby_version],
row[:rubygems_version],
row[:checksum],
row[:created_at]
)
deps[key] = [] unless deps[key]
deps[key] << [row[:dep_name], row[:requirements]] if row[:dep_name]
end
deps.map do |dep_key, gem_deps|
{
name: dep_key.name,
number: dep_key.number,
platform: dep_key.platform,
rubygems_version: dep_key.rubygems_version,
ruby_version: dep_key.required_ruby_version,
checksum: dep_key.checksum,
created_at: dep_key.created_at,
dependencies: gem_deps
}
end
end
# return list of gem names
def names
@conn[:rubygems].select(:name).order(:name).all.map {|r| r[:name] }
end
def versions(date,include_yanks = false)
dataset = if include_yanks
@conn[<<-SQL, date,date]
(SELECT r.name, v.created_at as date, v.info_checksum, v.number, v.platform
FROM rubygems AS r, versions AS v
WHERE v.rubygem_id = r.id AND
v.created_at > ?)
UNION
(SELECT r.name, v.yanked_at as date, v.yanked_info_checksum as info_checksum, '-'||v.number, v.platform
FROM rubygems AS r, versions AS v
WHERE v.rubygem_id = r.id AND
v.indexed is false AND
v.yanked_at > ?)
ORDER BY date, number, platform, name
SQL
else
@conn[<<-SQL, date]
SELECT r.name, v.created_at, v.checksum, v.info_checksum, v.number, v.platform
FROM rubygems AS r, versions AS v
WHERE v.rubygem_id = r.id AND
v.indexed is true AND
v.created_at > ?
ORDER BY v.created_at, v.number, v.platform, r.name
SQL
end
dataset.map do |entry|
CompactIndex::Gem.new(entry[:name], [
CompactIndex::GemVersion.new(
entry[:number],
entry[:platform],
entry[:checksum],
entry[:info_checksum]
)
])
end
end
def info(name)
deps = deps_for(name)
deps.map! do |dep|
dependencies = dep[:dependencies].map do |d|
CompactIndex::Dependency.new(d[0], d[1])
end
CompactIndex::GemVersion.new(
dep[:number],
dep[:platform],
dep[:checksum],
dep[:info_checksum],
dependencies,
dep[:ruby_version],
dep[:rubygems_version]
)
end
CompactIndex.info(deps)
end
end