/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2020, 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()
{
  shared_ptr<Profile> profile = 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 = 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 = 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 = 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 = 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 = make_shared<Data>();
    data->wireDecode(sqlite3_column_block(stmt, 0));
  }
  sqlite3_finalize(stmt);

  return data;
}

} // namespace chronochat
