/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2013-2021, Regents of the University of California
 *                          Yingdi Yu
 *
 * BSD license, See the LICENSE file for more information
 *
 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
 * Author: Qiuhan Ding <qiuhanding@cs.ucla.edu>
 */

#include "contact-storage.hpp"

#include <ndn-cxx/security/transform/buffer-source.hpp>
#include <ndn-cxx/security/transform/digest-filter.hpp>
#include <ndn-cxx/security/transform/hex-encode.hpp>
#include <ndn-cxx/security/transform/stream-sink.hpp>

#include <boost/filesystem.hpp>

namespace chronochat {

namespace fs = boost::filesystem;

using std::string;
using std::vector;

// user's own profile;
const string INIT_SP_TABLE =
  "CREATE TABLE IF NOT EXISTS                          "
  "  SelfProfile(                                      "
  "      profile_type      BLOB NOT NULL,              "
  "      profile_value     BLOB NOT NULL,              "
  "      PRIMARY KEY (profile_type)                    "
  "  );                                                "
  "CREATE INDEX sp_index ON SelfProfile(profile_type); ";

// user's self endorse cert;
const string INIT_SE_TABLE =
  "CREATE TABLE IF NOT EXISTS                      "
  "  SelfEndorse(                                  "
  "      identity          BLOB NOT NULL UNIQUE,   "
  "      endorse_data      BLOB NOT NULL,          "
  "      PRIMARY KEY (identity)                    "
  "  );                                            "
  "CREATE INDEX se_index ON SelfEndorse(identity); ";

// contact's basic info
const string INIT_CONTACT_TABLE =
  "CREATE TABLE IF NOT EXISTS                                "
  "  Contact(                                                "
  "      contact_namespace BLOB NOT NULL,                    "
  "      contact_alias     BLOB NOT NULL,                    "
  "      contact_keyName   BLOB NOT NULL,                    "
  "      contact_key       BLOB NOT NULL,                    "
  "      notBefore         INTEGER DEFAULT 0,                "
  "      notAfter          INTEGER DEFAULT 0,                "
  "      is_introducer     INTEGER DEFAULT 0,                "
  "      PRIMARY KEY (contact_namespace)                     "
  "  );                                                      "
  "CREATE INDEX contact_index ON Contact(contact_namespace); ";

// contact's trust scope;
const string INIT_TS_TABLE =
  "CREATE TABLE IF NOT EXISTS                                 "
  "  TrustScope(                                              "
  "      id                INTEGER PRIMARY KEY AUTOINCREMENT, "
  "      contact_namespace BLOB NOT NULL,                     "
  "      trust_scope       BLOB NOT NULL                      "
  "  );                                                       "
  "CREATE INDEX ts_index ON TrustScope(contact_namespace);    ";

// contact's profile
const string INIT_CP_TABLE =
  "CREATE TABLE IF NOT EXISTS                                 "
  "  ContactProfile(                                          "
  "      profile_identity  BLOB NOT NULL,                     "
  "      profile_type      BLOB NOT NULL,                     "
  "      profile_value     BLOB NOT NULL,                     "
  "      endorse           INTEGER NOT NULL,                  "
  "      PRIMARY KEY (profile_identity, profile_type)         "
  "  );                                                       "
  "CREATE INDEX cp_index ON ContactProfile(profile_identity); ";

// user's endorsement on contacts
const string INIT_PE_TABLE =
  "CREATE TABLE IF NOT EXISTS                         "
  "  ProfileEndorse(                                  "
  "      identity          BLOB NOT NULL UNIQUE,      "
  "      endorse_data      BLOB NOT NULL,             "
  "      PRIMARY KEY (identity)                       "
  "  );                                               "
  "CREATE INDEX pe_index ON ProfileEndorse(identity); ";

// contact's endorsements on the user
const string INIT_CE_TABLE =
  "CREATE TABLE IF NOT EXISTS               "
  "  CollectEndorse(                        "
  "      endorser          BLOB NOT NULL,   "
  "      endorse_name      BLOB NOT NULL,   "
  "      endorse_data      BLOB NOT NULL,   "
  "      PRIMARY KEY (endorser)             "
  "  );                                     ";

// dns data;
const string INIT_DD_TABLE =
  "CREATE TABLE IF NOT EXISTS                             "
  "  DnsData(                                             "
  "      dns_name      BLOB NOT NULL,                     "
  "      dns_type      BLOB NOT NULL,                     "
  "      data_name     BLOB NOT NULL,                     "
  "      dns_value     BLOB NOT NULL,                     "
  "      PRIMARY KEY (dns_name, dns_type)                 "
  "  );                                                   "
  "CREATE INDEX dd_index ON DnsData(dns_name, dns_type);  "
  "CREATE INDEX dd_index2 ON DnsData(data_name);          ";

/**
 * A utility function to call the normal sqlite3_bind_text where the value and length are
 * value.c_str() and value.size().
 */
static int
sqlite3_bind_string(sqlite3_stmt* statement,
                    int index,
                    const string& value,
                    void(*destructor)(void*))
{
  return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
}

/**
 * A utility function to call the normal sqlite3_bind_blob where the value and length are
 * block.wire() and block.size().
 */
static int
sqlite3_bind_block(sqlite3_stmt* statement,
                   int index,
                   const Block& block,
                   void(*destructor)(void*))
{
  return sqlite3_bind_blob(statement, index, block.wire(), block.size(), destructor);
}

/**
 * A utility function to generate string by calling the normal sqlite3_column_text.
 */
static string
sqlite3_column_string(sqlite3_stmt* statement, int column)
{
  return string(reinterpret_cast<const char*>(sqlite3_column_text(statement, column)),
                sqlite3_column_bytes(statement, column));
}

/**
 * A utility function to generate block by calling the normal sqlite3_column_text.
 */
static Block
sqlite3_column_block(sqlite3_stmt* statement, int column)
{
  return Block(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(statement, column)),
               sqlite3_column_bytes(statement, column));
}


ContactStorage::ContactStorage(const Name& identity)
  : m_identity(identity)
{
  fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
  fs::create_directories(chronosDir);

  int res = sqlite3_open((chronosDir / getDBName()).c_str(), &m_db);
  if (res != SQLITE_OK)
    NDN_THROW(Error("chronochat DB cannot be open/created"));

  initializeTable("SelfProfile", INIT_SP_TABLE);
  initializeTable("SelfEndorse", INIT_SE_TABLE);
  initializeTable("Contact", INIT_CONTACT_TABLE);
  initializeTable("TrustScope", INIT_TS_TABLE);
  initializeTable("ContactProfile", INIT_CP_TABLE);
  initializeTable("ProfileEndorse", INIT_PE_TABLE);
  initializeTable("CollectEndorse", INIT_CE_TABLE);
  initializeTable("DnsData", INIT_DD_TABLE);

}

string
ContactStorage::getDBName()
{
  string dbName("chronos-");

  std::ostringstream ss;
  {
    using namespace ndn::security::transform;
    bufferSource(m_identity.wireEncode().wire(), m_identity.wireEncode().size())
        >> digestFilter(ndn::DigestAlgorithm::SHA256)
        >> hexEncode(false)
        >> streamSink(ss);
  }
  dbName.append(ss.str()).append(".db");

  return dbName;
}

void
ContactStorage::initializeTable(const string& tableName, const string& sqlCreateStmt)
{
  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db,
                     "SELECT name FROM sqlite_master WHERE type='table' And name=?",
                     -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, tableName, SQLITE_TRANSIENT);
  int res = sqlite3_step(stmt);

  bool tableExist = false;
  if (res == SQLITE_ROW)
    tableExist = true;
  sqlite3_finalize(stmt);

  if (!tableExist) {
    char *errmsg = nullptr;
    res = sqlite3_exec(m_db, sqlCreateStmt.c_str (), nullptr, nullptr, &errmsg);
    if (res != SQLITE_OK && errmsg != nullptr)
      NDN_THROW(Error("Init \"error\" in " + tableName));
  }
}

shared_ptr<Profile>
ContactStorage::getSelfProfile()
{
  auto profile = std::make_shared<Profile>(m_identity);
  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db, "SELECT profile_type, profile_value FROM SelfProfile",
                     -1, &stmt, nullptr);

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    string profileType = sqlite3_column_string(stmt, 0);
    string profileValue = sqlite3_column_string (stmt, 1);
    (*profile)[profileType] = profileValue;
  }
  sqlite3_finalize(stmt);

  return profile;
}

void
ContactStorage::addSelfEndorseCertificate(const EndorseCertificate& newEndorseCertificate)
{
  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db,
                     "INSERT OR REPLACE INTO SelfEndorse (identity, endorse_data) values (?, ?)",
                     -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, m_identity.toUri(), SQLITE_TRANSIENT);
  sqlite3_bind_block(stmt, 2, newEndorseCertificate.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_step(stmt);

  sqlite3_finalize(stmt);
}

shared_ptr<EndorseCertificate>
ContactStorage::getSelfEndorseCertificate()
{
  shared_ptr<EndorseCertificate> cert;

  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db,
                     "SELECT endorse_data FROM SelfEndorse where identity=?",
                      -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, m_identity.toUri(), SQLITE_TRANSIENT);

  if (sqlite3_step(stmt) == SQLITE_ROW) {
    cert = std::make_shared<EndorseCertificate>();
    cert->wireDecode(sqlite3_column_block(stmt, 0));
  }

  sqlite3_finalize(stmt);

  return cert;
}

void
ContactStorage::addEndorseCertificate(const EndorseCertificate& endorseCertificate,
                                      const Name& identity)
{
  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db,
                     "INSERT OR REPLACE INTO ProfileEndorse \
                      (identity, endorse_data) values (?, ?)",
                     -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
  sqlite3_bind_block(stmt, 2, endorseCertificate.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_step(stmt);

  sqlite3_finalize(stmt);
}

void
ContactStorage::updateCollectEndorse(const EndorseCertificate& endorseCertificate)
{
  Name endorserName = endorseCertificate.getSigner();
  Name certName = endorseCertificate.getName();

  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db,
                     "INSERT OR REPLACE INTO CollectEndorse \
                      (endorser, endorse_name, endorse_data) \
                      VALUES (?, ?, ?)",
                     -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, endorserName.toUri(), SQLITE_TRANSIENT);
  sqlite3_bind_string(stmt, 2, certName.toUri(), SQLITE_TRANSIENT);
  sqlite3_bind_block(stmt, 3, endorseCertificate.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_step(stmt);
  sqlite3_finalize(stmt);
  return;
}

void
ContactStorage::getCollectEndorse(EndorseCollection& endorseCollection)
{
  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db, "SELECT endorse_name, endorse_data FROM CollectEndorse",
                     -1, &stmt, nullptr);

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    string certName = sqlite3_column_string(stmt, 0);
    std::ostringstream ss;
    {
      using namespace ndn::security::transform;
      bufferSource(sqlite3_column_text(stmt, 1), sqlite3_column_bytes(stmt, 1))
          >> digestFilter(ndn::DigestAlgorithm::SHA256)
          >> streamSink(ss);
    }
    endorseCollection.addCollectionEntry(Name(certName), ss.str());
  }

  sqlite3_finalize(stmt);
}

shared_ptr<EndorseCertificate>
ContactStorage::getCollectEndorseByName(const Name& name)
{
  shared_ptr<EndorseCertificate> cert;

  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db,
                     "SELECT endorse_name, endorse_data FROM CollectEndorse where endorse_name=?",
                      -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, name.toUri(), SQLITE_TRANSIENT);

  if (sqlite3_step(stmt) == SQLITE_ROW) {
    cert = std::make_shared<EndorseCertificate>();
    cert->wireDecode(sqlite3_column_block(stmt, 1));
  }

  sqlite3_finalize(stmt);

  return cert;
}

void
ContactStorage::getEndorseList(const Name& identity, vector<string>& endorseList)
{
  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db,
                     "SELECT profile_type FROM ContactProfile \
                      WHERE profile_identity=? AND endorse=1 ORDER BY profile_type",
                     -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    string profileType = sqlite3_column_string(stmt, 0);
    endorseList.push_back(profileType);
  }
  sqlite3_finalize(stmt);
}


void
ContactStorage::removeContact(const Name& identityName)
{
  string identity = identityName.toUri();

  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db, "DELETE FROM Contact WHERE contact_namespace=?", -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
  sqlite3_step(stmt);
  sqlite3_finalize(stmt);

  sqlite3_prepare_v2(m_db, "DELETE FROM ContactProfile WHERE profile_identity=?", -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
  sqlite3_step(stmt);
  sqlite3_finalize(stmt);

  sqlite3_prepare_v2(m_db, "DELETE FROM TrustScope WHERE contact_namespace=?", -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
  sqlite3_step(stmt);
  sqlite3_finalize(stmt);
}

void
ContactStorage::addContact(const Contact& contact)
{
  if (doesContactExist(contact.getNameSpace()))
    NDN_THROW(Error("Normal Contact has already existed"));

  string identity = contact.getNameSpace().toUri();
  bool isIntroducer = contact.isIntroducer();

  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db,
                     "INSERT INTO Contact (contact_namespace, contact_alias, contact_keyName, \
                      contact_key, notBefore, notAfter, is_introducer) \
                      values (?, ?, ?, ?, ?, ?, ?)",
                     -1, &stmt, nullptr);

  sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
  sqlite3_bind_string(stmt, 2, contact.getAlias(), SQLITE_TRANSIENT);
  sqlite3_bind_string(stmt, 3, contact.getPublicKeyName().toUri(), SQLITE_TRANSIENT);
  sqlite3_bind_text(stmt, 4,
                    reinterpret_cast<const char*>(contact.getPublicKey().data()),
                    contact.getPublicKey().size(), SQLITE_TRANSIENT);
  sqlite3_bind_int64(stmt, 5, time::toUnixTimestamp(contact.getNotBefore()).count());
  sqlite3_bind_int64(stmt, 6, time::toUnixTimestamp(contact.getNotAfter()).count());
  sqlite3_bind_int(stmt, 7, (isIntroducer ? 1 : 0));

  sqlite3_step(stmt);

  sqlite3_finalize(stmt);

  const Profile& profile = contact.getProfile();
  for (auto it = profile.begin(); it != profile.end(); it++) {
    sqlite3_prepare_v2(m_db,
                       "INSERT INTO ContactProfile \
                        (profile_identity, profile_type, profile_value, endorse) \
                        values (?, ?, ?, 0)",
                       -1, &stmt, nullptr);
    sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
    sqlite3_bind_string(stmt, 2, it->first, SQLITE_TRANSIENT);
    sqlite3_bind_string(stmt, 3, it->second, SQLITE_TRANSIENT);
    sqlite3_step(stmt);
    sqlite3_finalize(stmt);
  }

  if (isIntroducer) {
    auto it  = contact.trustScopeBegin();
    auto end = contact.trustScopeEnd();

    while (it != end) {
      sqlite3_prepare_v2(m_db,
                         "INSERT INTO TrustScope (contact_namespace, trust_scope) values (?, ?)",
                         -1, &stmt, nullptr);
      sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
      sqlite3_bind_string(stmt, 2, it->first.toUri(), SQLITE_TRANSIENT);
      sqlite3_step(stmt);
      sqlite3_finalize(stmt);
      it++;
    }
  }
}


shared_ptr<Contact>
ContactStorage::getContact(const Name& identity) const
{
  shared_ptr<Contact> contact;
  Profile profile;

  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db,
                     "SELECT contact_alias, contact_keyName, contact_key, notBefore, notAfter, \
                      is_introducer FROM Contact where contact_namespace=?",
                      -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);

  if (sqlite3_step(stmt) == SQLITE_ROW) {
    string alias = sqlite3_column_string(stmt, 0);
    string keyName = sqlite3_column_string(stmt, 1);
    ndn::Buffer key(sqlite3_column_text(stmt, 2), sqlite3_column_bytes (stmt, 2));
    time::system_clock::TimePoint notBefore =
      time::fromUnixTimestamp(time::milliseconds(sqlite3_column_int64 (stmt, 3)));
    time::system_clock::TimePoint notAfter =
      time::fromUnixTimestamp(time::milliseconds(sqlite3_column_int64 (stmt, 4)));
    int isIntroducer = sqlite3_column_int (stmt, 5);

    contact = std::make_shared<Contact>(identity, alias, Name(keyName),
                                        notBefore, notAfter, key, isIntroducer);
  }
  sqlite3_finalize(stmt);

  if (!static_cast<bool>(contact))
    return contact;

  sqlite3_prepare_v2(m_db,
                     "SELECT profile_type, profile_value FROM ContactProfile \
                      where profile_identity=?",
                     -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    string type = sqlite3_column_string(stmt, 0);
    string value = sqlite3_column_string(stmt, 1);
    profile[type] = value;
  }
  sqlite3_finalize(stmt);
  contact->setProfile(profile);

  if (contact->isIntroducer()) {
    sqlite3_prepare_v2(m_db,
                       "SELECT trust_scope FROM TrustScope WHERE contact_namespace=?",
                       -1, &stmt, nullptr);
    sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);

    while (sqlite3_step(stmt) == SQLITE_ROW) {
      Name scope(sqlite3_column_string(stmt, 0));
      contact->addTrustScope(scope);
    }
    sqlite3_finalize(stmt);
  }

  return contact;
}


void
ContactStorage::updateIsIntroducer(const Name& identity, bool isIntroducer)
{
  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db, "UPDATE Contact SET is_introducer=? WHERE contact_namespace=?",
                     -1, &stmt, nullptr);
  sqlite3_bind_int(stmt, 1, (isIntroducer ? 1 : 0));
  sqlite3_bind_string(stmt, 2, identity.toUri(), SQLITE_TRANSIENT);
  sqlite3_step(stmt);
  sqlite3_finalize(stmt);
  return;
}

void
ContactStorage::updateAlias(const Name& identity, const string& alias)
{
  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db, "UPDATE Contact SET contact_alias=? WHERE contact_namespace=?",
                     -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, alias, SQLITE_TRANSIENT);
  sqlite3_bind_string(stmt, 2, identity.toUri(), SQLITE_TRANSIENT);
  sqlite3_step(stmt);
  sqlite3_finalize(stmt);
  return;
}

bool
ContactStorage::doesContactExist(const Name& name)
{
  bool result = false;

  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db, "SELECT count(*) FROM Contact WHERE contact_namespace=?",
                     -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, name.toUri(), SQLITE_TRANSIENT);

  int res = sqlite3_step(stmt);

  if (res == SQLITE_ROW) {
    int countAll = sqlite3_column_int(stmt, 0);
    if (countAll > 0)
      result = true;
  }

  sqlite3_finalize(stmt);
  return result;
}

void
ContactStorage::getAllContacts(vector<shared_ptr<Contact> >& contacts) const
{
  vector<Name> contactNames;

  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db, "SELECT contact_namespace FROM Contact", -1, &stmt, nullptr);

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    string identity = sqlite3_column_string(stmt, 0);
    contactNames.push_back(Name(identity));
  }
  sqlite3_finalize(stmt);

  for (auto it = contactNames.begin(); it != contactNames.end(); it++) {
    shared_ptr<Contact> contact = getContact(*it);
    if (static_cast<bool>(contact))
      contacts.push_back(contact);
  }
}

void
ContactStorage::updateDnsData(const Block& data, const string& name,
                              const string& type, const string& dataName)
{
  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db,
                     "INSERT OR REPLACE INTO DnsData (dns_name, dns_type, dns_value, data_name) \
                      VALUES (?, ?, ?, ?)",
                     -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, name, SQLITE_TRANSIENT);
  sqlite3_bind_string(stmt, 2, type, SQLITE_TRANSIENT);
  sqlite3_bind_block(stmt, 3, data, SQLITE_TRANSIENT);
  sqlite3_bind_string(stmt, 4, dataName, SQLITE_TRANSIENT);
  sqlite3_step(stmt);

  sqlite3_finalize(stmt);
}

shared_ptr<Data>
ContactStorage::getDnsData(const Name& dataName)
{
  shared_ptr<Data> data;

  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db, "SELECT dns_value FROM DnsData where data_name=?", -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, dataName.toUri(), SQLITE_TRANSIENT);

  if (sqlite3_step(stmt) == SQLITE_ROW) {
    data = std::make_shared<Data>();
    data->wireDecode(sqlite3_column_block(stmt, 0));
  }
  sqlite3_finalize(stmt);

  return data;
}

shared_ptr<Data>
ContactStorage::getDnsData(const string& name, const string& type)
{
  shared_ptr<Data> data;

  sqlite3_stmt *stmt;
  sqlite3_prepare_v2(m_db, "SELECT dns_value FROM DnsData where dns_name=? and dns_type=?",
                     -1, &stmt, nullptr);
  sqlite3_bind_string(stmt, 1, name, SQLITE_TRANSIENT);
  sqlite3_bind_string(stmt, 2, type, SQLITE_TRANSIENT);

  if (sqlite3_step(stmt) == SQLITE_ROW) {
    data = std::make_shared<Data>();
    data->wireDecode(sqlite3_column_block(stmt, 0));
  }
  sqlite3_finalize(stmt);

  return data;
}

} // namespace chronochat
