blob: 1dc4410d77be270b597ff2a8e424863607560f6c [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
35void
36printUsage(const char* programName)
37{
38
39 std::cout
40 << "Usage:\n"
41 << " " << programName << " [-c <path/to/repo-ng.conf>] [-n] [-h]\n"
42 << "\n"
43 << "List names of Data packets in NDN repository. "
44 << "By default, all names will include the implicit digest of Data packets\n"
45 << "\n"
46 << "Options:\n"
47 << " -h: show help message\n"
48 << " -c: set config file path\n"
49 << " -n: do not show implicit digest\n"
50 << std::endl;
51 ;
52}
53
54class RepoEnumerator
55{
56public:
57 class Error : public std::runtime_error
58 {
59 public:
60 explicit
61 Error(const std::string& what)
62 : std::runtime_error(what)
63 {
64 }
65 };
66
67public:
68 RepoEnumerator(const std::string& configFile);
69
70 uint64_t
71 enumerate(bool showImplicitDigest);
72
73private:
74 void
75 readConfig(const std::string& configFile);
76
77private:
78 sqlite3* m_db;
79 std::string m_dbPath;
80};
81
82RepoEnumerator::RepoEnumerator(const std::string& configFile)
83{
84 readConfig(configFile);
85 char* errMsg = 0;
86 int rc = sqlite3_open_v2(m_dbPath.c_str(), &m_db,
87 SQLITE_OPEN_READONLY,
88 #ifdef DISABLE_SQLITE3_FS_LOCKING
89 "unix-dotfile"
90 #else
91 0
92 #endif
93 );
94 if (rc != SQLITE_OK) {
Alexander Afanasyev42290b22017-03-09 12:58:29 -080095 BOOST_THROW_EXCEPTION(Error("Database file open failure"));
Weiqi Shi9a223892014-08-24 18:42:58 -070096 }
97 sqlite3_exec(m_db, "PRAGMA synchronous = OFF", 0, 0, &errMsg);
98 sqlite3_exec(m_db, "PRAGMA journal_mode = WAL", 0, 0, &errMsg);
99}
100
101void
102RepoEnumerator::readConfig(const std::string& configFile)
103{
104 if (configFile.empty()) {
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800105 BOOST_THROW_EXCEPTION(Error("Invalid configuration file name"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700106 }
107
108 std::ifstream fin(configFile.c_str());
109 if (!fin.is_open())
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800110 BOOST_THROW_EXCEPTION(Error("failed to open configuration file '" + configFile + "'"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700111
112 using namespace boost::property_tree;
113 ptree propertyTree;
114 try {
115 read_info(fin, propertyTree);
116 }
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800117 catch (const ptree_error& e) {
118 BOOST_THROW_EXCEPTION(Error("failed to read configuration file '" + configFile + "'"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700119 }
120 ptree repoConf = propertyTree.get_child("repo");
121 m_dbPath = repoConf.get<std::string>("storage.path");
122 m_dbPath += "/ndn_repo.db";
123}
124
125uint64_t
126RepoEnumerator::enumerate(bool showImplicitDigest)
127{
128 sqlite3_stmt* m_stmt = 0;
129 int rc = SQLITE_DONE;
130 string sql = string("SELECT id, name, keylocatorHash FROM NDN_REPO;");
131 rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &m_stmt, 0);
132 if (rc != SQLITE_OK)
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800133 BOOST_THROW_EXCEPTION(Error("Initiation Read Entries from Database Prepare error"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700134 uint64_t entryNumber = 0;
135 while (true) {
136 rc = sqlite3_step(m_stmt);
137 if (rc == SQLITE_ROW) {
138 Name name;
139 name.wireDecode(Block(sqlite3_column_blob(m_stmt, 1),
140 sqlite3_column_bytes(m_stmt, 1)));
141 try {
142 if (showImplicitDigest) {
143 std::cout << name << std::endl;
144 }
145 else {
146 std::cout << name.getPrefix(-1) << std::endl;
147 }
148 }
149 catch (...){
150 sqlite3_finalize(m_stmt);
151 throw;
152 }
153 entryNumber++;
154 }
155 else if (rc == SQLITE_DONE) {
156 sqlite3_finalize(m_stmt);
157 break;
158 }
159 else {
160 sqlite3_finalize(m_stmt);
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800161 BOOST_THROW_EXCEPTION(Error("Initiation Read Entries error"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700162 }
163 }
164 return entryNumber;
165}
166
167int
168main(int argc, char** argv)
169{
170 string configPath = DEFAULT_CONFIG_FILE;
171 bool showImplicitDigest = true;
172 int opt;
173 while ((opt = getopt(argc, argv, "hc:n")) != -1) {
174 switch (opt) {
175 case 'h':
176 printUsage(argv[0]);
177 return 0;
178 case 'c':
179 configPath = string(optarg);
180 break;
181 case 'n':
182 showImplicitDigest = false;
183 break;
184 default:
185 break;
186 }
187 }
188
189 RepoEnumerator instance(configPath);
190 uint64_t count = instance.enumerate(showImplicitDigest);
191 std::cerr << "Total number of data = " << count << std::endl;
192 return 0;
193}
194
195} // namespace repo
196
197
198int
199main(int argc, char** argv)
200{
201 try {
202 return repo::main(argc, argv);
203 }
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800204 catch (const std::exception& e) {
Weiqi Shi9a223892014-08-24 18:42:58 -0700205 std::cerr << "ERROR: " << e.what() << std::endl;
206 return 2;
207 }
208}