blob: be51b34d71e48d56da9abf5e07727dd6a573ac3c [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California.
*
* This file is part of NDN repo-ng (Next generation of NDN repository).
* See AUTHORS.md for complete list of repo-ng authors and contributors.
*
* repo-ng is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* repo-ng, e.g., in COPYING.md file. if (not, see <http://www.gnu.org/licenses/>.
*/
#include "../src/common.hpp"
#include "config.hpp"
#include <string>
#include <sqlite3.h>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/info_parser.hpp>
namespace repo {
using namespace ndn::time;
void
printUsage(const char* programName)
{
std::cout
<< "Usage:\n"
<< " " << programName << " [-c <path/to/repo-ng.conf>] [-n] [-h]\n"
<< "\n"
<< "List names of Data packets in NDN repository. "
<< "By default, all names will include the implicit digest of Data packets\n"
<< "\n"
<< "Options:\n"
<< " -h: show help message\n"
<< " -c: set config file path\n"
<< " -n: do not show implicit digest\n"
<< std::endl;
;
}
class RepoEnumerator
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
public:
RepoEnumerator(const std::string& configFile);
uint64_t
enumerate(bool showImplicitDigest);
private:
void
readConfig(const std::string& configFile);
private:
sqlite3* m_db;
std::string m_dbPath;
};
RepoEnumerator::RepoEnumerator(const std::string& configFile)
{
readConfig(configFile);
char* errMsg = 0;
int rc = sqlite3_open_v2(m_dbPath.c_str(), &m_db,
SQLITE_OPEN_READONLY,
#ifdef DISABLE_SQLITE3_FS_LOCKING
"unix-dotfile"
#else
0
#endif
);
if (rc != SQLITE_OK) {
throw Error("Database file open failure");
}
sqlite3_exec(m_db, "PRAGMA synchronous = OFF", 0, 0, &errMsg);
sqlite3_exec(m_db, "PRAGMA journal_mode = WAL", 0, 0, &errMsg);
}
void
RepoEnumerator::readConfig(const std::string& configFile)
{
if (configFile.empty()) {
throw Error("Invalid configuration file name");
}
std::ifstream fin(configFile.c_str());
if (!fin.is_open())
throw Error("failed to open configuration file '" + configFile + "'");
using namespace boost::property_tree;
ptree propertyTree;
try {
read_info(fin, propertyTree);
}
catch (ptree_error& e) {
throw Error("failed to read configuration file '" + configFile + "'");
}
ptree repoConf = propertyTree.get_child("repo");
m_dbPath = repoConf.get<std::string>("storage.path");
m_dbPath += "/ndn_repo.db";
}
uint64_t
RepoEnumerator::enumerate(bool showImplicitDigest)
{
sqlite3_stmt* m_stmt = 0;
int rc = SQLITE_DONE;
string sql = string("SELECT id, name, keylocatorHash FROM NDN_REPO;");
rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &m_stmt, 0);
if (rc != SQLITE_OK)
throw Error("Initiation Read Entries from Database Prepare error");
uint64_t entryNumber = 0;
while (true) {
rc = sqlite3_step(m_stmt);
if (rc == SQLITE_ROW) {
Name name;
name.wireDecode(Block(sqlite3_column_blob(m_stmt, 1),
sqlite3_column_bytes(m_stmt, 1)));
try {
if (showImplicitDigest) {
std::cout << name << std::endl;
}
else {
std::cout << name.getPrefix(-1) << std::endl;
}
}
catch (...){
sqlite3_finalize(m_stmt);
throw;
}
entryNumber++;
}
else if (rc == SQLITE_DONE) {
sqlite3_finalize(m_stmt);
break;
}
else {
sqlite3_finalize(m_stmt);
throw Error("Initiation Read Entries error");
}
}
return entryNumber;
}
int
main(int argc, char** argv)
{
string configPath = DEFAULT_CONFIG_FILE;
bool showImplicitDigest = true;
int opt;
while ((opt = getopt(argc, argv, "hc:n")) != -1) {
switch (opt) {
case 'h':
printUsage(argv[0]);
return 0;
case 'c':
configPath = string(optarg);
break;
case 'n':
showImplicitDigest = false;
break;
default:
break;
}
}
RepoEnumerator instance(configPath);
uint64_t count = instance.enumerate(showImplicitDigest);
std::cerr << "Total number of data = " << count << std::endl;
return 0;
}
} // namespace repo
int
main(int argc, char** argv)
{
try {
return repo::main(argc, argv);
}
catch (std::exception& e) {
std::cerr << "ERROR: " << e.what() << std::endl;
return 2;
}
}