blob: 1ce0b28380fd3a286daae7a81557de021b17337a [file] [log] [blame]
Weiqi Shi9a223892014-08-24 18:42:58 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevc0e26582017-08-13 21:16:49 -04002/*
Alexander Afanasyev42290b22017-03-09 12:58:29 -08003 * Copyright (c) 2014-2017, Regents of the University of California.
Weiqi Shi9a223892014-08-24 18:42:58 -07004 *
5 * This file is part of NDN repo-ng (Next generation of NDN repository).
6 * See AUTHORS.md for complete list of repo-ng authors and contributors.
7 *
8 * repo-ng is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
Alexander Afanasyev42290b22017-03-09 12:58:29 -080017 * repo-ng, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Weiqi Shi9a223892014-08-24 18:42:58 -070018 */
19
20#include "../src/common.hpp"
21#include "config.hpp"
Alexander Afanasyevc0e26582017-08-13 21:16:49 -040022
23#include <iostream>
Weiqi Shi9a223892014-08-24 18:42:58 -070024#include <string>
Alexander Afanasyevc0e26582017-08-13 21:16:49 -040025
Weiqi Shi9a223892014-08-24 18:42:58 -070026#include <boost/property_tree/info_parser.hpp>
Alexander Afanasyevc0e26582017-08-13 21:16:49 -040027#include <boost/property_tree/ptree.hpp>
28
29#include <sqlite3.h>
Weiqi Shi9a223892014-08-24 18:42:58 -070030
31namespace repo {
32
Wentao Shanga8f3c402014-10-30 14:03:27 -070033using std::string;
Weiqi Shi9a223892014-08-24 18:42:58 -070034
Davide Pesavento5d669612017-09-22 23:49:37 -040035static void
Weiqi Shi9a223892014-08-24 18:42:58 -070036printUsage(const char* programName)
37{
Weiqi Shi9a223892014-08-24 18:42:58 -070038 std::cout
39 << "Usage:\n"
40 << " " << programName << " [-c <path/to/repo-ng.conf>] [-n] [-h]\n"
41 << "\n"
42 << "List names of Data packets in NDN repository. "
43 << "By default, all names will include the implicit digest of Data packets\n"
44 << "\n"
45 << "Options:\n"
46 << " -h: show help message\n"
47 << " -c: set config file path\n"
48 << " -n: do not show implicit digest\n"
49 << std::endl;
Weiqi Shi9a223892014-08-24 18:42:58 -070050}
51
52class RepoEnumerator
53{
54public:
55 class Error : public std::runtime_error
56 {
57 public:
58 explicit
59 Error(const std::string& what)
60 : std::runtime_error(what)
61 {
62 }
63 };
64
65public:
66 RepoEnumerator(const std::string& configFile);
67
68 uint64_t
69 enumerate(bool showImplicitDigest);
70
71private:
72 void
73 readConfig(const std::string& configFile);
74
75private:
76 sqlite3* m_db;
77 std::string m_dbPath;
78};
79
80RepoEnumerator::RepoEnumerator(const std::string& configFile)
81{
82 readConfig(configFile);
83 char* errMsg = 0;
84 int rc = sqlite3_open_v2(m_dbPath.c_str(), &m_db,
85 SQLITE_OPEN_READONLY,
86 #ifdef DISABLE_SQLITE3_FS_LOCKING
87 "unix-dotfile"
88 #else
89 0
90 #endif
91 );
92 if (rc != SQLITE_OK) {
Alexander Afanasyev42290b22017-03-09 12:58:29 -080093 BOOST_THROW_EXCEPTION(Error("Database file open failure"));
Weiqi Shi9a223892014-08-24 18:42:58 -070094 }
95 sqlite3_exec(m_db, "PRAGMA synchronous = OFF", 0, 0, &errMsg);
96 sqlite3_exec(m_db, "PRAGMA journal_mode = WAL", 0, 0, &errMsg);
97}
98
99void
100RepoEnumerator::readConfig(const std::string& configFile)
101{
102 if (configFile.empty()) {
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800103 BOOST_THROW_EXCEPTION(Error("Invalid configuration file name"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700104 }
105
106 std::ifstream fin(configFile.c_str());
107 if (!fin.is_open())
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800108 BOOST_THROW_EXCEPTION(Error("failed to open configuration file '" + configFile + "'"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700109
110 using namespace boost::property_tree;
111 ptree propertyTree;
112 try {
113 read_info(fin, propertyTree);
114 }
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800115 catch (const ptree_error& e) {
116 BOOST_THROW_EXCEPTION(Error("failed to read configuration file '" + configFile + "'"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700117 }
118 ptree repoConf = propertyTree.get_child("repo");
119 m_dbPath = repoConf.get<std::string>("storage.path");
120 m_dbPath += "/ndn_repo.db";
121}
122
123uint64_t
124RepoEnumerator::enumerate(bool showImplicitDigest)
125{
126 sqlite3_stmt* m_stmt = 0;
127 int rc = SQLITE_DONE;
128 string sql = string("SELECT id, name, keylocatorHash FROM NDN_REPO;");
129 rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &m_stmt, 0);
130 if (rc != SQLITE_OK)
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800131 BOOST_THROW_EXCEPTION(Error("Initiation Read Entries from Database Prepare error"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700132 uint64_t entryNumber = 0;
133 while (true) {
134 rc = sqlite3_step(m_stmt);
135 if (rc == SQLITE_ROW) {
136 Name name;
Davide Pesavento5d669612017-09-22 23:49:37 -0400137 name.wireDecode(Block(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(m_stmt, 1)),
Weiqi Shi9a223892014-08-24 18:42:58 -0700138 sqlite3_column_bytes(m_stmt, 1)));
139 try {
140 if (showImplicitDigest) {
141 std::cout << name << std::endl;
142 }
143 else {
144 std::cout << name.getPrefix(-1) << std::endl;
145 }
146 }
147 catch (...){
148 sqlite3_finalize(m_stmt);
149 throw;
150 }
151 entryNumber++;
152 }
153 else if (rc == SQLITE_DONE) {
154 sqlite3_finalize(m_stmt);
155 break;
156 }
157 else {
158 sqlite3_finalize(m_stmt);
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800159 BOOST_THROW_EXCEPTION(Error("Initiation Read Entries error"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700160 }
161 }
162 return entryNumber;
163}
164
165int
166main(int argc, char** argv)
167{
168 string configPath = DEFAULT_CONFIG_FILE;
169 bool showImplicitDigest = true;
170 int opt;
171 while ((opt = getopt(argc, argv, "hc:n")) != -1) {
172 switch (opt) {
173 case 'h':
174 printUsage(argv[0]);
175 return 0;
176 case 'c':
177 configPath = string(optarg);
178 break;
179 case 'n':
180 showImplicitDigest = false;
181 break;
182 default:
183 break;
184 }
185 }
186
187 RepoEnumerator instance(configPath);
188 uint64_t count = instance.enumerate(showImplicitDigest);
189 std::cerr << "Total number of data = " << count << std::endl;
190 return 0;
191}
192
193} // namespace repo
194
195
196int
197main(int argc, char** argv)
198{
199 try {
200 return repo::main(argc, argv);
201 }
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800202 catch (const std::exception& e) {
Weiqi Shi9a223892014-08-24 18:42:58 -0700203 std::cerr << "ERROR: " << e.what() << std::endl;
204 return 2;
205 }
206}