Esempio n. 1
0
void
ActionLog::LookupRecentFileActions(const function<void(const std::string&, int, int)>& visitor,
                                   int limit)
{
  sqlite3_stmt* stmt;

  sqlite3_prepare_v2(m_db,
                     "SELECT AL.filename, AL.action"
                     "   FROM ActionLog AL"
                     "   JOIN "
                     "   (SELECT filename, MAX(action_timestamp) AS action_timestamp "
                     "       FROM ActionLog "
                     "       GROUP BY filename ) AS GAL"
                     "   ON AL.filename = GAL.filename AND AL.action_timestamp = GAL.action_timestamp "
                     "   ORDER BY AL.action_timestamp DESC "
                     "   LIMIT ?;",
                     -1, &stmt, 0);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
  sqlite3_bind_int(stmt, 1, limit);
  int index = 0;
  while (sqlite3_step(stmt) == SQLITE_ROW) {
    std::string filename(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
                         sqlite3_column_bytes(stmt, 0));
    int action = sqlite3_column_int(stmt, 1);
    visitor(filename, action, index);
    index++;
  }

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

  sqlite3_finalize(stmt);
}
Esempio n. 2
0
FileItemsPtr
FileState::LookupFilesForHash(const Buffer& hash)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db,
                     "SELECT filename,version,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,is_complete "
                     "   FROM FileState "
                     "   WHERE type = 0 AND file_hash = ?",
                     -1, &stmt, 0);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
  sqlite3_bind_blob(stmt, 1, hash.buf(), hash.size(), SQLITE_STATIC);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));

  FileItemsPtr retval = make_shared<FileItems>();
  while (sqlite3_step(stmt) == SQLITE_ROW) {
    FileItem file;
    file.set_filename(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
                      sqlite3_column_bytes(stmt, 0));
    file.set_version(sqlite3_column_int64(stmt, 1));
    file.set_device_name(sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
    file.set_seq_no(sqlite3_column_int64(stmt, 3));
    file.set_file_hash(sqlite3_column_blob(stmt, 4), sqlite3_column_bytes(stmt, 4));
    file.set_mtime(sqlite3_column_int(stmt, 5));
    file.set_mode(sqlite3_column_int(stmt, 6));
    file.set_seg_num(sqlite3_column_int64(stmt, 7));
    file.set_is_complete(sqlite3_column_int(stmt, 8));

    retval->push_back(file);
  }
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));

  sqlite3_finalize(stmt);

  return retval;
}
Esempio n. 3
0
/**
 * @todo Implement checking modification time and permissions
 */
FileItemPtr
FileState::LookupFile(const std::string& filename)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db,
                     "SELECT filename,version,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,is_complete "
                     "       FROM FileState "
                     "       WHERE type = 0 AND filename = ?",
                     -1, &stmt, 0);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
  sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);

  FileItemPtr retval;
  if (sqlite3_step(stmt) == SQLITE_ROW) {
    retval = make_shared<FileItem>();
    retval->set_filename(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
                         sqlite3_column_bytes(stmt, 0));
    retval->set_version(sqlite3_column_int64(stmt, 1));
    retval->set_device_name(sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
    retval->set_seq_no(sqlite3_column_int64(stmt, 3));
    retval->set_file_hash(sqlite3_column_blob(stmt, 4), sqlite3_column_bytes(stmt, 4));
    retval->set_mtime(sqlite3_column_int(stmt, 5));
    retval->set_mode(sqlite3_column_int(stmt, 6));
    retval->set_seg_num(sqlite3_column_int64(stmt, 7));
    retval->set_is_complete(sqlite3_column_int(stmt, 8));
  }
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
  sqlite3_finalize(stmt);

  return retval;
}
Esempio n. 4
0
void
FileState::SetFileComplete(const std::string& filename)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db, "UPDATE FileState SET is_complete=1 WHERE type = 0 AND filename = ?", -1,
                     &stmt, 0);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
  sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);

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

  sqlite3_finalize(stmt);
}
Esempio n. 5
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;
}
Esempio n. 6
0
void
FileState::DeleteFile(const std::string& filename)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db, "DELETE FROM FileState WHERE type=0 AND filename=?", -1, &stmt, 0);
  sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);

  _LOG_DEBUG("Delete " << filename);

  sqlite3_step(stmt);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
  sqlite3_finalize(stmt);
}
Esempio n. 7
0
FileItemPtr
ActionLog::LookupAction(const std::string& filename, sqlite3_int64 version, const Buffer& filehash)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db,
                     "SELECT device_name, seq_no, strftime('%s', file_mtime), file_chmod, file_seg_num, file_hash "
                     " FROM ActionLog "
                     " WHERE action = 0 AND "
                     "       filename=? AND "
                     "       version=? AND "
                     "       is_prefix(?, file_hash)=1",
                     -1, &stmt, 0);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));

  sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC);
  sqlite3_bind_int64(stmt, 2, version);
  sqlite3_bind_blob(stmt, 3, filehash.buf(), filehash.size(), SQLITE_STATIC);

  FileItemPtr fileItem;

  if (sqlite3_step(stmt) == SQLITE_ROW) {
    fileItem = make_shared<FileItem>();
    fileItem->set_filename(filename);
    fileItem->set_device_name(sqlite3_column_blob(stmt, 0), sqlite3_column_bytes(stmt, 0));
    fileItem->set_seq_no(sqlite3_column_int64(stmt, 1));
    fileItem->set_mtime(sqlite3_column_int64(stmt, 2));
    fileItem->set_mode(sqlite3_column_int64(stmt, 3));
    fileItem->set_seg_num(sqlite3_column_int64(stmt, 4));

    fileItem->set_file_hash(sqlite3_column_blob(stmt, 5), sqlite3_column_bytes(stmt, 5));
  }

  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE || sqlite3_errcode(m_db) != SQLITE_ROW ||
                    sqlite3_errcode(m_db) != SQLITE_OK,
                  sqlite3_errmsg(m_db));

  return fileItem;
}
Esempio n. 8
0
void
FileState::LookupFilesInFolder(const function<void(const FileItem&)>& visitor,
                               const std::string& folder, int offset /*=0*/, int limit /*=-1*/)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db,
                     "SELECT filename,version,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,is_complete "
                     "   FROM FileState "
                     "   WHERE type = 0 AND directory = ?"
                     "   LIMIT ? OFFSET ?",
                     -1, &stmt, 0);
  if (folder.size() == 0)
    sqlite3_bind_null(stmt, 1);
  else
    sqlite3_bind_text(stmt, 1, folder.c_str(), folder.size(), SQLITE_STATIC);

  sqlite3_bind_int(stmt, 2, limit);
  sqlite3_bind_int(stmt, 3, offset);

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    FileItem file;
    file.set_filename(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
                      sqlite3_column_bytes(stmt, 0));
    file.set_version(sqlite3_column_int64(stmt, 1));
    file.set_device_name(sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
    file.set_seq_no(sqlite3_column_int64(stmt, 3));
    file.set_file_hash(sqlite3_column_blob(stmt, 4), sqlite3_column_bytes(stmt, 4));
    file.set_mtime(sqlite3_column_int(stmt, 5));
    file.set_mode(sqlite3_column_int(stmt, 6));
    file.set_seg_num(sqlite3_column_int64(stmt, 7));
    file.set_is_complete(sqlite3_column_int(stmt, 8));

    visitor(file);
  }

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

  sqlite3_finalize(stmt);
}
Esempio n. 9
0
/**
 * @todo Figure out the way to minimize code duplication
 */
bool
ActionLog::LookupActionsForFile(
  const function<void(const Name& name, sqlite3_int64 seq_no, const ActionItem&)>& visitor,
  const std::string& file, int offset /*=0*/, int limit /*=-1*/)
{
  _LOG_DEBUG("LookupActionsInFolderRecursively: [" << file << "]");
  if (file.empty())
    return false;

  if (limit >= 0)
    limit += 1; // to check if there is more data

  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db,
                     "SELECT device_name,seq_no,action,filename,directory,version,strftime('%s', action_timestamp), "
                     "       file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num, "
                     "       parent_device_name,parent_seq_no "
                     "   FROM ActionLog "
                     "   WHERE filename=? "
                     "   ORDER BY action_timestamp DESC "
                     "   LIMIT ? OFFSET ?",
                     -1, &stmt,
                     0); // there is a small ambiguity with is_prefix matching, but should be ok for now
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));

  sqlite3_bind_text(stmt, 1, file.c_str(), file.size(), SQLITE_STATIC);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));

  sqlite3_bind_int(stmt, 2, limit);
  sqlite3_bind_int(stmt, 3, offset);

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

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    if (limit == 1)
      break;

    ActionItem action;

    Name device_name(Block(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(stmt, 0)),
                           sqlite3_column_bytes(stmt, 0)));

    sqlite3_int64 seq_no = sqlite3_column_int64(stmt, 1);
    action.set_action(static_cast<ActionItem_ActionType>(sqlite3_column_int(stmt, 2)));
    action.set_filename(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3)),
                        sqlite3_column_bytes(stmt, 3));
    std::string directory(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 4)),
                          sqlite3_column_bytes(stmt, 4));
    action.set_version(sqlite3_column_int64(stmt, 5));
    action.set_timestamp(sqlite3_column_int64(stmt, 6));

    if (action.action() == 0) {
      action.set_file_hash(sqlite3_column_blob(stmt, 7), sqlite3_column_bytes(stmt, 7));
      action.set_mtime(sqlite3_column_int(stmt, 8));
      action.set_mode(sqlite3_column_int(stmt, 9));
      action.set_seg_num(sqlite3_column_int64(stmt, 10));
    }
    if (sqlite3_column_bytes(stmt, 11) > 0) {
      action.set_parent_device_name(sqlite3_column_blob(stmt, 11), sqlite3_column_bytes(stmt, 11));
      action.set_parent_seq_no(sqlite3_column_int64(stmt, 12));
    }

    visitor(device_name, seq_no, action);
    limit--;
  }

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

  sqlite3_finalize(stmt);

  return (limit == 1); // more data is available
}
Esempio n. 10
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;
}
Esempio n. 11
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;
}
Esempio n. 12
0
void
FileState::UpdateFile(const std::string& filename, sqlite3_int64 version, const Buffer& hash,
                      const Buffer& device_name, sqlite3_int64 seq_no, time_t atime, time_t mtime,
                      time_t ctime, int mode, int seg_num)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db, "UPDATE FileState "
                           "SET "
                           "device_name=?, seq_no=?, "
                           "version=?,"
                           "file_hash=?,"
                           "file_atime=datetime(?, 'unixepoch'),"
                           "file_mtime=datetime(?, 'unixepoch'),"
                           "file_ctime=datetime(?, 'unixepoch'),"
                           "file_chmod=?, "
                           "file_seg_num=? "
                           "WHERE type=0 AND filename=?",
                     -1, &stmt, 0);

  sqlite3_bind_blob(stmt, 1, device_name.buf(), device_name.size(), SQLITE_STATIC);
  sqlite3_bind_int64(stmt, 2, seq_no);
  sqlite3_bind_int64(stmt, 3, version);
  sqlite3_bind_blob(stmt, 4, hash.buf(), hash.size(), SQLITE_STATIC);
  sqlite3_bind_int64(stmt, 5, atime);
  sqlite3_bind_int64(stmt, 6, mtime);
  sqlite3_bind_int64(stmt, 7, ctime);
  sqlite3_bind_int(stmt, 8, mode);
  sqlite3_bind_int(stmt, 9, seg_num);
  sqlite3_bind_text(stmt, 10, filename.c_str(), -1, SQLITE_STATIC);

  sqlite3_step(stmt);

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

  sqlite3_finalize(stmt);

  int affected_rows = sqlite3_changes(m_db);
  if (affected_rows == 0) // file didn't exist
  {
    sqlite3_stmt* stmt;
    sqlite3_prepare_v2(m_db,
                       "INSERT INTO FileState "
                       "(type,filename,version,device_name,seq_no,file_hash,"
                       "file_atime,file_mtime,file_ctime,file_chmod,file_seg_num) "
                       "VALUES (0, ?, ?, ?, ?, ?, "
                       "datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?, ?)",
                       -1, &stmt, 0);

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

    sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);
    sqlite3_bind_int64(stmt, 2, version);
    sqlite3_bind_blob(stmt, 3, device_name.buf(), device_name.size(), SQLITE_STATIC);
    sqlite3_bind_int64(stmt, 4, seq_no);
    sqlite3_bind_blob(stmt, 5, hash.buf(), hash.size(), SQLITE_STATIC);
    sqlite3_bind_int64(stmt, 6, atime);
    sqlite3_bind_int64(stmt, 7, mtime);
    sqlite3_bind_int64(stmt, 8, ctime);
    sqlite3_bind_int(stmt, 9, mode);
    sqlite3_bind_int(stmt, 10, seg_num);

    sqlite3_step(stmt);
    _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
    sqlite3_finalize(stmt);

    sqlite3_prepare_v2(m_db,
                       "UPDATE FileState SET directory=directory_name(filename) WHERE filename=?",
                       -1, &stmt, 0);
    _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));

    sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);
    sqlite3_step(stmt);
    _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
    sqlite3_finalize(stmt);
  }
}
Esempio n. 13
0
FileState::FileState(const boost::filesystem::path& path)
  : DbHelper(path / ".chronoshare", "file-state.db")
{
  sqlite3_exec(m_db, INIT_DATABASE.c_str(), NULL, NULL, NULL);
  _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
}
Esempio n. 14
0
bool
FileState::LookupFilesInFolderRecursively(const function<void(const FileItem&)>& visitor,
                                          const std::string& folder, int offset /*=0*/,
                                          int limit /*=-1*/)
{
  _LOG_DEBUG("LookupFilesInFolderRecursively: [" << folder << "]");

  if (limit >= 0)
    limit++;

  sqlite3_stmt* stmt;
  if (folder != "") {
    /// @todo Do something to improve efficiency of this query. Right now it is basically scanning the whole database

    sqlite3_prepare_v2(m_db,
                       "SELECT filename,version,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,is_complete "
                       "   FROM FileState "
                       "   WHERE type = 0 AND is_dir_prefix(?, directory)=1 "
                       "   ORDER BY filename "
                       "   LIMIT ? OFFSET ?",
                       -1, &stmt,
                       0); // there is a small ambiguity with is_prefix matching, but should be ok for now
    _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));

    sqlite3_bind_text(stmt, 1, folder.c_str(), folder.size(), SQLITE_STATIC);
    _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));

    sqlite3_bind_int(stmt, 2, limit);
    sqlite3_bind_int(stmt, 3, offset);
  }
  else {
    sqlite3_prepare_v2(m_db,
                       "SELECT filename,version,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,is_complete "
                       "   FROM FileState "
                       "   WHERE type = 0"
                       "   ORDER BY filename "
                       "   LIMIT ? OFFSET ?",
                       -1, &stmt, 0);
    sqlite3_bind_int(stmt, 1, limit);
    sqlite3_bind_int(stmt, 2, offset);
  }

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

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    if (limit == 1)
      break;

    FileItem file;
    file.set_filename(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
                      sqlite3_column_bytes(stmt, 0));
    file.set_version(sqlite3_column_int64(stmt, 1));
    file.set_device_name(sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
    file.set_seq_no(sqlite3_column_int64(stmt, 3));
    file.set_file_hash(sqlite3_column_blob(stmt, 4), sqlite3_column_bytes(stmt, 4));
    file.set_mtime(sqlite3_column_int(stmt, 5));
    file.set_mode(sqlite3_column_int(stmt, 6));
    file.set_seg_num(sqlite3_column_int64(stmt, 7));
    file.set_is_complete(sqlite3_column_int(stmt, 8));

    visitor(file);
    limit--;
  }

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

  sqlite3_finalize(stmt);

  return (limit == 1);
}