Skip to content

Commit

Permalink
Support user readable table names.
Browse files Browse the repository at this point in the history
  • Loading branch information
chinmaygarde authored and dnfield committed Apr 27, 2022
1 parent 7b3ab41 commit 188890c
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 175 deletions.
8 changes: 3 additions & 5 deletions impeller/archivist/archivable.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,9 @@
namespace impeller {

struct ArchiveDef {
using Member = uint64_t;
using Members = std::vector<Member>;

const ArchiveDef* isa = nullptr;
const std::string table_name;
const bool auto_key = true;
const Members members;
const std::vector<std::string> members;
};

class ArchiveLocation;
Expand All @@ -31,6 +27,8 @@ using PrimaryKey = std::optional<int64_t>;
///
class Archivable {
public:
virtual ~Archivable() = default;

virtual PrimaryKey GetPrimaryKey() const = 0;

virtual bool Write(ArchiveLocation& item) const = 0;
Expand Down
18 changes: 9 additions & 9 deletions impeller/archivist/archive.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,25 @@ class Archive {
bool IsValid() const;

template <class T,
class = std::enable_if<std::is_base_of<Archivable, T>::value>>
bool Write(const T& archivable) {
const ArchiveDef& def = T::ArchiveDefinition;
class = std::enable_if_t<std::is_base_of<Archivable, T>::value>>
[[nodiscard]] bool Write(const T& archivable) {
const ArchiveDef& def = T::kArchiveDefinition;
return ArchiveInstance(def, archivable).has_value();
}

template <class T,
class = std::enable_if<std::is_base_of<Archivable, T>::value>>
bool Read(PrimaryKey name, T& archivable) {
const ArchiveDef& def = T::ArchiveDefinition;
class = std::enable_if_t<std::is_base_of<Archivable, T>::value>>
[[nodiscard]] bool Read(PrimaryKey name, T& archivable) {
const ArchiveDef& def = T::kArchiveDefinition;
return UnarchiveInstance(def, name, archivable);
}

using UnarchiveStep = std::function<bool(ArchiveLocation&)>;

template <class T,
class = std::enable_if<std::is_base_of<Archivable, T>::value>>
size_t Read(UnarchiveStep stepper) {
const ArchiveDef& def = T::ArchiveDefinition;
class = std::enable_if_t<std::is_base_of<Archivable, T>::value>>
[[nodiscard]] size_t Read(UnarchiveStep stepper) {
const ArchiveDef& def = T::kArchiveDefinition;
return UnarchiveInstances(def, stepper);
}

Expand Down
87 changes: 32 additions & 55 deletions impeller/archivist/archive_class_registration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,66 +11,41 @@

namespace impeller {

static const char* const ArchiveColumnPrefix = "col_";
static const char* const ArchivePrimaryKeyColumnName = "primary_key";
static constexpr const char* kArchivePrimaryKeyColumnName = "primary_key";

ArchiveClassRegistration::ArchiveClassRegistration(ArchiveDatabase& database,
ArchiveDef definition)
: database_(database), class_name_(definition.table_name) {
/*
* Each class in the archive class hierarchy is assigned an entry in the
* class map.
*/
const ArchiveDef* current = &definition;
size_t currentMember = 1;
while (current != nullptr) {
auto membersInCurrent = current->members.size();
member_count_ += membersInCurrent;
MemberColumnMap map;
for (const auto& member : current->members) {
map[member] = currentMember++;
}
class_map_[current->table_name] = map;
current = current->isa;
: database_(database), definition_(std::move(definition)) {
for (size_t i = 0; i < definition.members.size(); i++) {
// The first index entry is the primary key. So add one to the index.
column_map_[definition.members[i]] = i + 1;
}

is_ready_ = CreateTable(definition.auto_key);
is_valid_ = CreateTable();
}

const std::string& ArchiveClassRegistration::GetClassName() const {
return class_name_;
return definition_.table_name;
}

size_t ArchiveClassRegistration::GetMemberCount() const {
return member_count_;
return column_map_.size();
}

bool ArchiveClassRegistration::IsValid() const {
return is_ready_;
return is_valid_;
}

std::optional<size_t> ArchiveClassRegistration::FindColumnIndex(
const std::string& className,
ArchiveDef::Member member) const {
auto found = class_map_.find(className);

if (found == class_map_.end()) {
return std::nullopt;
}

const auto& memberToColumns = found->second;

auto foundColumn = memberToColumns.find(member);

if (foundColumn == memberToColumns.end()) {
const std::string& member) const {
auto found = column_map_.find(member);
if (found == column_map_.end()) {
return std::nullopt;
}

return foundColumn->second;
return found->second;
}

bool ArchiveClassRegistration::CreateTable(bool autoIncrement) {
if (class_name_.size() == 0 || member_count_ == 0) {
bool ArchiveClassRegistration::CreateTable() {
if (definition_.table_name.empty() || definition_.members.empty()) {
return false;
}

Expand All @@ -80,16 +55,17 @@ bool ArchiveClassRegistration::CreateTable(bool autoIncrement) {
* Table names cannot participate in parameter substitution, so we prepare
* a statement and check its validity before running.
*/
stream << "CREATE TABLE IF NOT EXISTS " << class_name_.c_str() << " ("
<< ArchivePrimaryKeyColumnName;
stream << "CREATE TABLE IF NOT EXISTS " << definition_.table_name << " ("
<< kArchivePrimaryKeyColumnName;

if (autoIncrement) {
if (definition_.auto_key) {
stream << " INTEGER PRIMARY KEY AUTOINCREMENT, ";
} else {
stream << " INTEGER PRIMARY KEY, ";
}
for (size_t i = 0, columns = member_count_; i < columns; i++) {
stream << ArchiveColumnPrefix << std::to_string(i + 1);

for (size_t i = 0, columns = definition_.members.size(); i < columns; i++) {
stream << definition_.members[i];
if (i != columns - 1) {
stream << ", ";
}
Expand All @@ -112,19 +88,19 @@ bool ArchiveClassRegistration::CreateTable(bool autoIncrement) {
ArchiveStatement ArchiveClassRegistration::CreateQueryStatement(
bool single) const {
std::stringstream stream;
stream << "SELECT " << ArchivePrimaryKeyColumnName << ", ";
for (size_t i = 0, members = member_count_; i < members; i++) {
stream << ArchiveColumnPrefix << std::to_string(i + 1);
if (i != members - 1) {
stream << "SELECT " << kArchivePrimaryKeyColumnName << ", ";
for (size_t i = 0, columns = definition_.members.size(); i < columns; i++) {
stream << definition_.members[i];
if (i != columns - 1) {
stream << ",";
}
}
stream << " FROM " << class_name_;
stream << " FROM " << definition_.table_name;

if (single) {
stream << " WHERE " << ArchivePrimaryKeyColumnName << " = ?";
stream << " WHERE " << kArchivePrimaryKeyColumnName << " = ?";
} else {
stream << " ORDER BY " << ArchivePrimaryKeyColumnName << " ASC";
stream << " ORDER BY " << kArchivePrimaryKeyColumnName << " ASC";
}

stream << ";";
Expand All @@ -134,10 +110,11 @@ ArchiveStatement ArchiveClassRegistration::CreateQueryStatement(

ArchiveStatement ArchiveClassRegistration::CreateInsertStatement() const {
std::stringstream stream;
stream << "INSERT OR REPLACE INTO " << class_name_ << " VALUES ( ?, ";
for (size_t i = 0; i < member_count_; i++) {
stream << "INSERT OR REPLACE INTO " << definition_.table_name
<< " VALUES ( ?, ";
for (size_t i = 0, columns = definition_.members.size(); i < columns; i++) {
stream << "?";
if (i != member_count_ - 1) {
if (i != columns - 1) {
stream << ", ";
}
}
Expand Down
15 changes: 6 additions & 9 deletions impeller/archivist/archive_class_registration.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ class ArchiveClassRegistration {

bool IsValid() const;

std::optional<size_t> FindColumnIndex(const std::string& className,
ArchiveDef::Member member) const;
std::optional<size_t> FindColumnIndex(const std::string& member) const;

const std::string& GetClassName() const;

Expand All @@ -29,20 +28,18 @@ class ArchiveClassRegistration {
ArchiveStatement CreateQueryStatement(bool single) const;

private:
using MemberColumnMap = std::map<ArchiveDef::Member, size_t>;
using ClassMap = std::map<std::string, MemberColumnMap>;
using MemberColumnMap = std::map<std::string, size_t>;

friend class ArchiveDatabase;

ArchiveClassRegistration(ArchiveDatabase& database, ArchiveDef definition);

bool CreateTable(bool autoIncrement);
bool CreateTable();

ArchiveDatabase& database_;
ClassMap class_map_;
std::string class_name_;
size_t member_count_ = 0;
bool is_ready_ = false;
const ArchiveDef definition_;
MemberColumnMap column_map_;
bool is_valid_ = false;

FML_DISALLOW_COPY_AND_ASSIGN(ArchiveClassRegistration);
};
Expand Down
47 changes: 23 additions & 24 deletions impeller/archivist/archive_location.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,37 @@ ArchiveLocation::ArchiveLocation(Archive& context,
: context_(context),
statement_(statement),
registration_(registration),
primary_key_(name),
current_class_(registration.GetClassName()) {}
primary_key_(name) {}

PrimaryKey ArchiveLocation::GetPrimaryKey() const {
return primary_key_;
}

bool ArchiveLocation::Write(ArchiveDef::Member member,
bool ArchiveLocation::Write(const std::string& member,
const std::string& item) {
auto index = registration_.FindColumnIndex(current_class_, member);
auto index = registration_.FindColumnIndex(member);
return index.has_value() ? statement_.WriteValue(index.value(), item) : false;
}

bool ArchiveLocation::WriteIntegral(ArchiveDef::Member member, int64_t item) {
auto index = registration_.FindColumnIndex(current_class_, member);
bool ArchiveLocation::WriteIntegral(const std::string& member, int64_t item) {
auto index = registration_.FindColumnIndex(member);
return index.has_value() ? statement_.WriteValue(index.value(), item) : false;
}

bool ArchiveLocation::Write(ArchiveDef::Member member, double item) {
auto index = registration_.FindColumnIndex(current_class_, member);
bool ArchiveLocation::Write(const std::string& member, double item) {
auto index = registration_.FindColumnIndex(member);
return index.has_value() ? statement_.WriteValue(index.value(), item) : false;
}

bool ArchiveLocation::Write(ArchiveDef::Member member, const Allocation& item) {
auto index = registration_.FindColumnIndex(current_class_, member);
bool ArchiveLocation::Write(const std::string& member, const Allocation& item) {
auto index = registration_.FindColumnIndex(member);
return index.has_value() ? statement_.WriteValue(index.value(), item) : false;
}

bool ArchiveLocation::Write(ArchiveDef::Member member,
bool ArchiveLocation::Write(const std::string& member,
const ArchiveDef& otherDef,
const Archivable& other) {
auto index = registration_.FindColumnIndex(current_class_, member);
auto index = registration_.FindColumnIndex(member);

if (!index.has_value()) {
return false;
Expand Down Expand Up @@ -76,13 +75,13 @@ bool ArchiveLocation::Write(ArchiveDef::Member member,
std::optional<int64_t> ArchiveLocation::WriteVectorKeys(
std::vector<int64_t>&& members) {
ArchiveVector vector(std::move(members));
return context_.ArchiveInstance(ArchiveVector::ArchiveDefinition, vector);
return context_.ArchiveInstance(ArchiveVector::kArchiveDefinition, vector);
}

bool ArchiveLocation::ReadVectorKeys(PrimaryKey name,
std::vector<int64_t>& members) {
ArchiveVector vector;
if (!context_.UnarchiveInstance(ArchiveVector::ArchiveDefinition, name,
if (!context_.UnarchiveInstance(ArchiveVector::kArchiveDefinition, name,
vector)) {
return false;
}
Expand All @@ -91,30 +90,30 @@ bool ArchiveLocation::ReadVectorKeys(PrimaryKey name,
return true;
}

bool ArchiveLocation::Read(ArchiveDef::Member member, std::string& item) {
auto index = registration_.FindColumnIndex(current_class_, member);
bool ArchiveLocation::Read(const std::string& member, std::string& item) {
auto index = registration_.FindColumnIndex(member);
return index.has_value() ? statement_.ReadValue(index.value(), item) : false;
}

bool ArchiveLocation::ReadIntegral(ArchiveDef::Member member, int64_t& item) {
auto index = registration_.FindColumnIndex(current_class_, member);
bool ArchiveLocation::ReadIntegral(const std::string& member, int64_t& item) {
auto index = registration_.FindColumnIndex(member);
return index.has_value() ? statement_.ReadValue(index.value(), item) : false;
}

bool ArchiveLocation::Read(ArchiveDef::Member member, double& item) {
auto index = registration_.FindColumnIndex(current_class_, member);
bool ArchiveLocation::Read(const std::string& member, double& item) {
auto index = registration_.FindColumnIndex(member);
return index.has_value() ? statement_.ReadValue(index.value(), item) : false;
}

bool ArchiveLocation::Read(ArchiveDef::Member member, Allocation& item) {
auto index = registration_.FindColumnIndex(current_class_, member);
bool ArchiveLocation::Read(const std::string& member, Allocation& item) {
auto index = registration_.FindColumnIndex(member);
return index.has_value() ? statement_.ReadValue(index.value(), item) : false;
}

bool ArchiveLocation::Read(ArchiveDef::Member member,
bool ArchiveLocation::Read(const std::string& member,
const ArchiveDef& otherDef,
Archivable& other) {
auto index = registration_.FindColumnIndex(current_class_, member);
auto index = registration_.FindColumnIndex(member);

/*
* Make sure a member is present at that column
Expand Down
Loading

0 comments on commit 188890c

Please sign in to comment.