blob: 1ce8f2e5905f63881f8e7b48624b8d02910538bc [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/*
Davide Pesavento399f4d92023-09-17 14:03:51 -04003 * Copyright (c) 2014-2023, 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
Davide Pesavento399f4d92023-09-17 14:03:51 -040020#include "common.hpp"
Alexander Afanasyevc0e26582017-08-13 21:16:49 -040021
22#include <iostream>
Weiqi Shi9a223892014-08-24 18:42:58 -070023#include <string>
Davide Pesavento31be3f62019-01-24 23:20:23 -050024#include <unistd.h>
Alexander Afanasyevc0e26582017-08-13 21:16:49 -040025
weijia yuan3aa8d2b2018-03-06 15:35:57 -080026#include <ndn-cxx/util/sqlite3-statement.hpp>
27
Weiqi Shi9a223892014-08-24 18:42:58 -070028#include <boost/property_tree/info_parser.hpp>
Alexander Afanasyevc0e26582017-08-13 21:16:49 -040029#include <boost/property_tree/ptree.hpp>
30
31#include <sqlite3.h>
Weiqi Shi9a223892014-08-24 18:42:58 -070032
33namespace repo {
34
Davide Pesavento5d669612017-09-22 23:49:37 -040035static void
Davide Pesavento31be3f62019-01-24 23:20:23 -050036usage(const char* programName)
Weiqi Shi9a223892014-08-24 18:42:58 -070037{
Davide Pesavento31be3f62019-01-24 23:20:23 -050038 std::cerr << "Usage: "
39 << programName << " [-c <path/to/repo-ng.conf>] [-n] [-h]\n"
40 << "\n"
41 << "List names of Data packets in NDN repository.\n"
42 << "By default, all names will include the implicit digest of Data packets.\n"
43 << "\n"
44 << "Options:\n"
45 << " -h: show help message\n"
46 << " -c: set config file path\n"
47 << " -n: do not show implicit digest\n"
48 << std::endl;
Weiqi Shi9a223892014-08-24 18:42:58 -070049}
50
51class RepoEnumerator
52{
53public:
54 class Error : public std::runtime_error
55 {
56 public:
Davide Pesavento31be3f62019-01-24 23:20:23 -050057 using std::runtime_error::runtime_error;
Weiqi Shi9a223892014-08-24 18:42:58 -070058 };
59
Davide Pesavento31be3f62019-01-24 23:20:23 -050060 explicit
Weiqi Shi9a223892014-08-24 18:42:58 -070061 RepoEnumerator(const std::string& configFile);
62
63 uint64_t
64 enumerate(bool showImplicitDigest);
65
66private:
67 void
68 readConfig(const std::string& configFile);
69
70private:
71 sqlite3* m_db;
72 std::string m_dbPath;
73};
74
75RepoEnumerator::RepoEnumerator(const std::string& configFile)
76{
77 readConfig(configFile);
weijia yuan3aa8d2b2018-03-06 15:35:57 -080078 char* errMsg = nullptr;
79 int rc = sqlite3_open_v2(m_dbPath.c_str(), &m_db, SQLITE_OPEN_READONLY,
Weiqi Shi9a223892014-08-24 18:42:58 -070080 #ifdef DISABLE_SQLITE3_FS_LOCKING
weijia yuan3aa8d2b2018-03-06 15:35:57 -080081 "unix-dotfile"
Weiqi Shi9a223892014-08-24 18:42:58 -070082 #else
weijia yuan3aa8d2b2018-03-06 15:35:57 -080083 nullptr
Weiqi Shi9a223892014-08-24 18:42:58 -070084 #endif
85 );
86 if (rc != SQLITE_OK) {
Alexander Afanasyev42290b22017-03-09 12:58:29 -080087 BOOST_THROW_EXCEPTION(Error("Database file open failure"));
Weiqi Shi9a223892014-08-24 18:42:58 -070088 }
weijia yuan3aa8d2b2018-03-06 15:35:57 -080089 sqlite3_exec(m_db, "PRAGMA synchronous = OFF", nullptr, nullptr, &errMsg);
90 sqlite3_exec(m_db, "PRAGMA journal_mode = WAL", nullptr, nullptr, &errMsg);
Weiqi Shi9a223892014-08-24 18:42:58 -070091}
92
93void
94RepoEnumerator::readConfig(const std::string& configFile)
95{
96 if (configFile.empty()) {
Alexander Afanasyev42290b22017-03-09 12:58:29 -080097 BOOST_THROW_EXCEPTION(Error("Invalid configuration file name"));
Weiqi Shi9a223892014-08-24 18:42:58 -070098 }
99
100 std::ifstream fin(configFile.c_str());
101 if (!fin.is_open())
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800102 BOOST_THROW_EXCEPTION(Error("failed to open configuration file '" + configFile + "'"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700103
104 using namespace boost::property_tree;
105 ptree propertyTree;
106 try {
107 read_info(fin, propertyTree);
108 }
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800109 catch (const ptree_error& e) {
110 BOOST_THROW_EXCEPTION(Error("failed to read configuration file '" + configFile + "'"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700111 }
112 ptree repoConf = propertyTree.get_child("repo");
113 m_dbPath = repoConf.get<std::string>("storage.path");
114 m_dbPath += "/ndn_repo.db";
115}
116
117uint64_t
118RepoEnumerator::enumerate(bool showImplicitDigest)
119{
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800120 ndn::util::Sqlite3Statement stmt(m_db, "SELECT data FROM NDN_REPO_V2;");
121 uint64_t nEntries = 0;
Weiqi Shi9a223892014-08-24 18:42:58 -0700122 while (true) {
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800123 int rc = stmt.step();
Weiqi Shi9a223892014-08-24 18:42:58 -0700124 if (rc == SQLITE_ROW) {
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800125 Data data(stmt.getBlock(0));
126 if (showImplicitDigest) {
127 std::cout << data.getFullName() << std::endl;
Weiqi Shi9a223892014-08-24 18:42:58 -0700128 }
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800129 else {
130 std::cout << data.getName() << std::endl;
Weiqi Shi9a223892014-08-24 18:42:58 -0700131 }
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800132 nEntries++;
Weiqi Shi9a223892014-08-24 18:42:58 -0700133 }
134 else if (rc == SQLITE_DONE) {
Weiqi Shi9a223892014-08-24 18:42:58 -0700135 break;
136 }
137 else {
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800138 BOOST_THROW_EXCEPTION(Error("Initiation Read Entries error"));
Weiqi Shi9a223892014-08-24 18:42:58 -0700139 }
140 }
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800141 return nEntries;
Weiqi Shi9a223892014-08-24 18:42:58 -0700142}
143
Davide Pesavento31be3f62019-01-24 23:20:23 -0500144static int
Weiqi Shi9a223892014-08-24 18:42:58 -0700145main(int argc, char** argv)
146{
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800147 std::string configPath = DEFAULT_CONFIG_FILE;
Weiqi Shi9a223892014-08-24 18:42:58 -0700148 bool showImplicitDigest = true;
Davide Pesavento31be3f62019-01-24 23:20:23 -0500149
Weiqi Shi9a223892014-08-24 18:42:58 -0700150 int opt;
151 while ((opt = getopt(argc, argv, "hc:n")) != -1) {
152 switch (opt) {
153 case 'h':
Davide Pesavento31be3f62019-01-24 23:20:23 -0500154 usage(argv[0]);
Weiqi Shi9a223892014-08-24 18:42:58 -0700155 return 0;
156 case 'c':
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800157 configPath = std::string(optarg);
Weiqi Shi9a223892014-08-24 18:42:58 -0700158 break;
159 case 'n':
160 showImplicitDigest = false;
161 break;
162 default:
Davide Pesavento31be3f62019-01-24 23:20:23 -0500163 usage(argv[0]);
164 return 2;
Weiqi Shi9a223892014-08-24 18:42:58 -0700165 }
166 }
167
168 RepoEnumerator instance(configPath);
169 uint64_t count = instance.enumerate(showImplicitDigest);
170 std::cerr << "Total number of data = " << count << std::endl;
171 return 0;
172}
173
174} // namespace repo
175
Weiqi Shi9a223892014-08-24 18:42:58 -0700176int
177main(int argc, char** argv)
178{
179 try {
180 return repo::main(argc, argv);
181 }
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800182 catch (const std::exception& e) {
Weiqi Shi9a223892014-08-24 18:42:58 -0700183 std::cerr << "ERROR: " << e.what() << std::endl;
Davide Pesavento31be3f62019-01-24 23:20:23 -0500184 return 1;
Weiqi Shi9a223892014-08-24 18:42:58 -0700185 }
186}