예제 #1
0
shared_ptr<Data>
ActionLog::LookupActionData(const Name& deviceName, sqlite3_int64 seqno)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db,
                     "SELECT action_content_object FROM ActionLog WHERE device_name=? AND seq_no=?",
                     -1, &stmt, 0);

  sqlite3_bind_blob(stmt, 1, deviceName.wireEncode().wire(), deviceName.wireEncode().size(),
                    SQLITE_STATIC); // ndn version
  sqlite3_bind_int64(stmt, 2, seqno);

  shared_ptr<Data> retval;

  if (sqlite3_step(stmt) == SQLITE_ROW) {
    // _LOG_DEBUG(sqlite3_column_blob(stmt, 0) << ", " << sqlite3_column_bytes(stmt, 0));
    retval = make_shared<Data>();
    retval->wireDecode(Block(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(stmt, 0)),
                             sqlite3_column_bytes(stmt, 0)));
  }
  else {
    _LOG_TRACE("No action found for deviceName [" << deviceName << "] and seqno:" << seqno);
  }
  // _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK && sqlite3_errcode(m_db) != SQLITE_ROW,
  // sqlite3_errmsg(m_db));
  sqlite3_finalize(stmt);

  return retval;
}
예제 #2
0
shared_ptr<Data>
ActionLog::LookupActionData(const Name& actionName)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db, "SELECT action_content_object FROM ActionLog WHERE action_name=?", -1,
                     &stmt, 0);

  _LOG_DEBUG(actionName);

  _LOG_DEBUG(" LookActionData <<<<<<< " << actionName << " " << actionName.wireEncode().size());

  sqlite3_bind_blob(stmt, 1, actionName.wireEncode().wire(), actionName.wireEncode().size(),
                    SQLITE_STATIC);

  shared_ptr<Data> retval; // = make_shared<Data>();
  if (sqlite3_step(stmt) == SQLITE_ROW) {
    // _LOG_DEBUG(sqlite3_column_blob(stmt, 0) << ", " << sqlite3_column_bytes(stmt, 0));
    retval = make_shared<Data>();
    retval->wireDecode(Block(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(stmt, 0)),
                             sqlite3_column_bytes(stmt, 0)));
  }
  else {
    _LOG_TRACE("No action found for name: " << actionName);
  }
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_ROW, sqlite3_errmsg(m_db));
  sqlite3_finalize(stmt);

  return retval;
}
예제 #3
0
void
Sqlite3ConsumerDb::deleteKey(const Name& keyName)
{
  sqlite3_stmt *statement;
  sqlite3_prepare_v2
    (database_, "DELETE FROM decryptionkeys WHERE key_name=?", -1, &statement, 0);
  sqlite3_bind_blob(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_step(statement);
  sqlite3_finalize(statement);
}
예제 #4
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
void
PibDb::setDefaultCertNameOfKey(const Name& certificateName)
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "UPDATE certificates SET is_default=1 WHERE certificate_name=?",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_step(statement);
  sqlite3_finalize(statement);
}
예제 #5
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
void
PibDb::setDefaultKeyNameOfIdentity(const Name& keyName)
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "UPDATE keys SET is_default=1 WHERE key_name=?",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_step(statement);
  sqlite3_finalize(statement);
}
예제 #6
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
void
PibDb::deleteKey(const Name& keyName)
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "DELETE FROM keys WHERE key_name=?",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_step(statement);
  sqlite3_finalize(statement);
}
예제 #7
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
void
PibDb::setDefaultIdentity(const Name& identity)
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "UPDATE identities SET is_default=1 WHERE identity=?",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_step(statement);
  sqlite3_finalize(statement);
}
예제 #8
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
void
PibDb::deleteIdentity(const Name& identity)
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "DELETE FROM identities WHERE identity=?",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_step(statement);
  sqlite3_finalize(statement);
}
예제 #9
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
void
PibDb::deleteCertificate(const Name& certificateName)
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "DELETE FROM certificates WHERE certificate_name=?",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_step(statement);
  sqlite3_finalize(statement);
}
예제 #10
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
int64_t
PibDb::addIdentity(const Name& identity)
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "INSERT INTO identities (identity) values (?)",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_step(statement);
  sqlite3_finalize(statement);

  return sqlite3_last_insert_rowid(m_database);
}
예제 #11
0
void
ValidatorInvitation::checkPolicy (const Interest& interest,
                                  int stepCount,
                                  const OnInterestValidated& onValidated,
                                  const OnInterestValidationFailed& onValidationFailed,
                                  vector<shared_ptr<ValidationRequest> >& nextSteps)
{
  const Name& interestName  = interest.getName();

  if (!m_invitationInterestRule.match(interestName))
    return onValidationFailed(interest.shared_from_this(),
                              "Invalid interest name: " +  interest.getName().toUri());

  Name signedName = interestName.getPrefix(-1);
  ndn::Buffer signedBlob = ndn::Buffer(signedName.wireEncode().value(),
                                       signedName.wireEncode().value_size());

  Block signatureBlock = interestName.get(Invitation::SIGNATURE).blockFromValue();
  Block signatureInfo = interestName.get(Invitation::KEY_LOCATOR).blockFromValue();
  Signature signature(signatureInfo, signatureBlock);

  if (signature.getKeyLocator().getType() != KeyLocator::KeyLocator_Name)
    return onValidationFailed(interest.shared_from_this(),
                              "KeyLocator is not a name: " + interest.getName().toUri());

  const Name & keyLocatorName = signature.getKeyLocator().getName();

  Data innerData;
  innerData.wireDecode(interestName.get(Invitation::INVITER_CERT).blockFromValue());

  return internalCheck(signedBlob.buf(), signedBlob.size(),
                       signature,
                       keyLocatorName,
                       innerData,
                       bind(onValidated, interest.shared_from_this()),
                       bind(onValidationFailed, interest.shared_from_this(), _1));
}
예제 #12
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
bool
PibDb::hasIdentity(const Name& identity) const
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "SELECT id FROM identities WHERE identity=?",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
  int result = sqlite3_step(statement);
  sqlite3_finalize(statement);

  if (result == SQLITE_ROW)
    return true;
  else
    return false;
}
예제 #13
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
bool
PibDb::hasCertificate(const Name& certificateName) const
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "SELECT id FROM certificates WHERE certificate_name=?",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
  int result = sqlite3_step(statement);
  sqlite3_finalize(statement);

  if (result == SQLITE_ROW)
    return true;
  else
    return false;
}
예제 #14
0
void
Sqlite3ConsumerDb::addKey(const Name& keyName, const Blob& keyBlob)
{
  sqlite3_stmt *statement;
  sqlite3_prepare_v2
    (database_, "INSERT INTO decryptionkeys(key_name, key_buf) values (?, ?)",
     -1, &statement, 0);
  sqlite3_bind_blob(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_bind_blob(statement, 2, keyBlob, SQLITE_TRANSIENT);

  int status = sqlite3_step(statement);
  sqlite3_finalize(statement);
  if (status != SQLITE_DONE)
    throw ConsumerDb::Error
      ("Sqlite3ConsumerDb::addKey: Cannot add the key to the database");
}
예제 #15
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
shared_ptr<PublicKey>
PibDb::getKey(const Name& keyName) const
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "SELECT key_bits FROM keys WHERE key_name=?"
                     , -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);

  shared_ptr<PublicKey> key;
  if (sqlite3_step(statement) == SQLITE_ROW) {
      key = make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
                                   sqlite3_column_bytes(statement, 0));
  }
  sqlite3_finalize(statement);
  return key;
}
예제 #16
0
파일: name-tree.cpp 프로젝트: danposch/NFD
// Interface of different hash functions
size_t
computeHash(const Name& prefix)
{
  prefix.wireEncode();  // guarantees prefix's wire buffer is not empty

  size_t hashValue = 0;
  size_t hashUpdate = 0;

  for (Name::const_iterator it = prefix.begin(); it != prefix.end(); it++)
    {
      const char* wireFormat = reinterpret_cast<const char*>( it->wire() );
      hashUpdate = CityHash::compute(wireFormat, it->size());
      hashValue ^= hashUpdate;
    }

  return hashValue;
}
예제 #17
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
Name
PibDb::getDefaultKeyNameOfIdentity(const Name& identity) const
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "SELECT key_name FROM keys JOIN identities ON keys.identity_id=identities.id\
                      WHERE identities.identity=? AND keys.is_default=1",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);

  Name keyName = NON_EXISTING_KEY;
  if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
    keyName = Name(sqlite3_column_block(statement, 0));
  }

  sqlite3_finalize(statement);
  return keyName;
}
예제 #18
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
Name
PibDb::getDefaultCertNameOfKey(const Name& keyName) const
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "SELECT certificate_name\
                      FROM certificates JOIN keys ON certificates.key_id=keys.id\
                      WHERE keys.key_name=? AND certificates.is_default=1",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);

  Name certName = NON_EXISTING_CERTIFICATE;
  if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
    certName = Name(sqlite3_column_block(statement, 0));
  }
  sqlite3_finalize(statement);
  return certName;
}
예제 #19
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
shared_ptr<IdentityCertificate>
PibDb::getCertificate(const Name& certificateName) const
{
  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "SELECT certificate_data FROM certificates WHERE certificate_name=?",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);

  shared_ptr<IdentityCertificate> certificate;
  if (sqlite3_step(statement) == SQLITE_ROW) {
    certificate = make_shared<IdentityCertificate>();
    certificate->wireDecode(sqlite3_column_block(statement, 0));
  }

  sqlite3_finalize(statement);
  return certificate;
}
예제 #20
0
Blob
Sqlite3ConsumerDb::getKey(const Name& keyName)
{
  sqlite3_stmt *statement;
  sqlite3_prepare_v2
    (database_, "SELECT key_buf FROM decryptionkeys WHERE key_name=?",
     -1, &statement, 0);
  sqlite3_bind_blob(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);

  int res = sqlite3_step(statement);

  Blob key;
  if (res == SQLITE_ROW)
    key = Blob
      (static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
       sqlite3_column_bytes(statement, 0));

  sqlite3_finalize(statement);
  return key;
}
예제 #21
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
vector<Name>
PibDb::listKeyNamesOfIdentity(const Name& identity) const
{
  vector<Name> keyNames;

  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "SELECT key_name FROM keys JOIN identities ON keys.identity_id=identities.id\
                      WHERE identities.identity=?",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);

  keyNames.clear();
  while (sqlite3_step(statement) == SQLITE_ROW) {
    Name keyName(sqlite3_column_block(statement, 0));
    keyNames.push_back(keyName);
  }

  sqlite3_finalize(statement);
  return keyNames;
}
예제 #22
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
vector<Name>
PibDb::listCertNamesOfKey(const Name& keyName) const
{
  vector<Name> certNames;

  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "SELECT certificate_name\
                      FROM certificates JOIN keys ON certificates.key_id=keys.id\
                      WHERE keys.key_name=?",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);

  certNames.clear();
  while (sqlite3_step(statement) == SQLITE_ROW) {
    Name name(sqlite3_column_block(statement, 0));
    certNames.push_back(name);
  }
  sqlite3_finalize(statement);

  return certNames;
}
예제 #23
0
파일: pib-db.cpp 프로젝트: CSUL/ndn-tools
int64_t
PibDb::addKey(const Name& keyName, const PublicKey& key)
{
  if (keyName.empty())
    return 0;

  Name&& identity = keyName.getPrefix(-1);
  if (!hasIdentity(identity))
    addIdentity(identity);

  sqlite3_stmt* statement;
  sqlite3_prepare_v2(m_database,
                     "INSERT INTO keys (identity_id, key_name, key_type, key_bits) \
                      values ((SELECT id FROM identities WHERE identity=?), ?, ?, ?)",
                     -1, &statement, nullptr);
  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_bind_block(statement, 2, keyName.wireEncode(), SQLITE_TRANSIENT);
  sqlite3_bind_int(statement, 3, key.getKeyType());
  sqlite3_bind_blob(statement, 4, key.get().buf(), key.get().size(), SQLITE_STATIC);
  sqlite3_step(statement);
  sqlite3_finalize(statement);

  return sqlite3_last_insert_rowid(m_database);
}
예제 #24
0
ActionItemPtr
ActionLog::AddRemoteAction(const Name& deviceName, sqlite3_int64 seqno, shared_ptr<Data> actionData)
{
  if (!actionData) {
    _LOG_ERROR("actionData is not valid");
    return ActionItemPtr();
  }
  ActionItemPtr action = deserializeMsg<ActionItem>(
    Buffer(actionData->getContent().value(), actionData->getContent().value_size()));

  if (!action) {
    _LOG_ERROR("action cannot be decoded");
    return ActionItemPtr();
  }

  _LOG_DEBUG("AddRemoteAction: [" << deviceName.toUri() << "] seqno: " << seqno);

  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db,
                     "INSERT INTO ActionLog "
                     "(device_name, seq_no, action, filename, version, action_timestamp, "
                     "file_hash, file_atime, file_mtime, file_ctime, file_chmod, file_seg_num, "
                     "parent_device_name, parent_seq_no, "
                     "action_name, action_content_object) "
                     "VALUES (?, ?, ?, ?, ?, datetime(?, 'unixepoch'),"
                     "        ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?,?, "
                     "        ?, ?, "
                     "        ?, ?);",
                     -1, &stmt, 0);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));

  sqlite3_bind_blob(stmt, 1, deviceName.wireEncode().wire(), deviceName.wireEncode().size(),
                    SQLITE_STATIC);
  sqlite3_bind_int64(stmt, 2, seqno);

  sqlite3_bind_int(stmt, 3, action->action());
  sqlite3_bind_text(stmt, 4, action->filename().c_str(), action->filename().size(), SQLITE_STATIC);
  sqlite3_bind_int64(stmt, 5, action->version());
  sqlite3_bind_int64(stmt, 6, action->timestamp());

  if (action->action() == ActionItem::UPDATE) {
    sqlite3_bind_blob(stmt, 7, action->file_hash().c_str(), action->file_hash().size(),
                      SQLITE_STATIC);

    // sqlite3_bind_int64(stmt, 8, atime); // NULL
    sqlite3_bind_int64(stmt, 9, action->mtime());
    // sqlite3_bind_int64(stmt, 10, ctime); // NULL

    sqlite3_bind_int(stmt, 11, action->mode());
    sqlite3_bind_int(stmt, 12, action->seg_num());
  }

  if (action->has_parent_device_name()) {
    sqlite3_bind_blob(stmt, 13, action->parent_device_name().c_str(),
                      action->parent_device_name().size(), SQLITE_STATIC);
    sqlite3_bind_int64(stmt, 14, action->parent_seq_no());
  }

  Name actionName = Name(deviceName);
  actionName.append("action").append(m_sharedFolderName).appendNumber(seqno);

  sqlite3_bind_blob(stmt, 15, actionName.wireEncode().wire(), actionName.wireEncode().size(),
                    SQLITE_STATIC);
  sqlite3_bind_blob(stmt, 16, actionData->wireEncode().wire(), actionData->wireEncode().size(),
                    SQLITE_STATIC);
  sqlite3_step(stmt);

  // if action needs to be applied to file state, the trigger will take care of it

  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));

  sqlite3_finalize(stmt);

  // I had a problem including directory_name assignment as part of the initial insert.
  sqlite3_prepare_v2(m_db,
                     "UPDATE ActionLog SET directory=directory_name(filename) WHERE device_name=? AND seq_no=?",
                     -1, &stmt, 0);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));

  sqlite3_bind_blob(stmt, 1, deviceName.wireEncode().wire(), deviceName.wireEncode().size(),
                    SQLITE_STATIC);
  sqlite3_bind_int64(stmt, 2, seqno);
  sqlite3_step(stmt);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));

  sqlite3_finalize(stmt);

  return action;
}
예제 #25
0
ActionItemPtr
ActionLog::AddLocalActionDelete(const std::string& filename)
{
  _LOG_DEBUG("Adding local action DELETE");

  sqlite3_exec(m_db, "BEGIN TRANSACTION;", 0, 0, 0);

  const Block device_name = m_syncLog->GetLocalName().wireEncode();
  sqlite3_int64 version;
  BufferPtr parent_device_name;
  sqlite3_int64 parent_seq_no = -1;

  sqlite3_int64 action_time = std::time(0);

  tie(version, parent_device_name, parent_seq_no) = GetLatestActionForFile(filename);
  if (!parent_device_name) // no records exist or file was already deleted
  {
    _LOG_DEBUG("Nothing to delete... [" << filename << "]");

    // just in case, remove data from FileState
    sqlite3_stmt* stmt;
    sqlite3_prepare_v2(m_db, "DELETE FROM FileState WHERE filename = ? ", -1, &stmt, 0);
    sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC); // file

    sqlite3_step(stmt);

    _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));

    sqlite3_finalize(stmt);

    sqlite3_exec(m_db, "END TRANSACTION;", 0, 0, 0);
    return ActionItemPtr();
  }
  version++;

  sqlite3_int64 seq_no = m_syncLog->GetNextLocalSeqNo();

  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db, "INSERT INTO ActionLog "
                           "(device_name, seq_no, action, filename, version, action_timestamp, "
                           "parent_device_name, parent_seq_no, "
                           "action_name, action_content_object) "
                           "VALUES(?, ?, ?, ?, ?, datetime(?, 'unixepoch'),"
                           "        ?, ?,"
                           "        ?, ?)",
                     -1, &stmt, 0);

  sqlite3_bind_blob(stmt, 1, device_name.wire(), device_name.size(), SQLITE_STATIC);
  sqlite3_bind_int64(stmt, 2, seq_no);
  sqlite3_bind_int(stmt, 3, 1);
  sqlite3_bind_text(stmt, 4, filename.c_str(), filename.size(), SQLITE_STATIC); // file

  sqlite3_bind_int64(stmt, 5, version);
  sqlite3_bind_int64(stmt, 6, action_time);

  sqlite3_bind_blob(stmt, 7, parent_device_name->buf(), parent_device_name->size(), SQLITE_STATIC);
  sqlite3_bind_int64(stmt, 8, parent_seq_no);

  ActionItemPtr item = make_shared<ActionItem>();
  item->set_action(ActionItem::DELETE);
  item->set_filename(filename);
  item->set_version(version);
  item->set_timestamp(action_time);
  item->set_parent_device_name(parent_device_name->buf(), parent_device_name->size());
  item->set_parent_seq_no(parent_seq_no);

  std::string item_msg;
  item->SerializeToString(&item_msg);

  // action name: /<device_name>/<appname>/action/<shared-folder>/<action-seq>
  Name actionName = Name("/");
  actionName.append(m_syncLog->GetLocalName()).append(m_appName).append("action");
  actionName.append(m_sharedFolderName).appendNumber(seq_no);
  _LOG_DEBUG("ActionName: " << actionName);

  shared_ptr<Data> actionData = make_shared<Data>();
  actionData->setName(actionName);
  actionData->setFreshnessPeriod(time::seconds(60));
  actionData->setContent(reinterpret_cast<const uint8_t*>(item_msg.c_str()), item_msg.size());
  m_keyChain.sign(*actionData);

  sqlite3_bind_blob(stmt, 9, actionName.wireEncode().wire(), actionName.wireEncode().size(),
                    SQLITE_STATIC);
  sqlite3_bind_blob(stmt, 10, actionData->wireEncode().wire(), actionData->wireEncode().size(),
                    SQLITE_STATIC);

  sqlite3_step(stmt);

  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));

  // cout << Name(parent_device_name) << endl;

  // assign name to the action, serialize action, and create content object

  sqlite3_finalize(stmt);

  // I had a problem including directory_name assignment as part of the initial insert.
  sqlite3_prepare_v2(m_db,
                     "UPDATE ActionLog SET directory=directory_name(filename) WHERE device_name=? AND seq_no=?",
                     -1, &stmt, 0);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));

  sqlite3_bind_blob(stmt, 1, device_name.wire(), device_name.size(), SQLITE_STATIC);
  sqlite3_bind_int64(stmt, 2, seq_no);
  sqlite3_step(stmt);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));

  sqlite3_finalize(stmt);

  sqlite3_exec(m_db, "END TRANSACTION;", 0, 0, 0);

  return item;
}