blob: e6245ea023505b8586b9005c53c7caee1a25ddca [file] [log] [blame]
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2016, Regents of the University of California.
Alexander Afanasyeveb575e02013-01-26 17:14:51 -08004 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08005 * This file is part of ChronoShare, a decentralized file sharing application over NDN.
Alexander Afanasyeveb575e02013-01-26 17:14:51 -08006 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08007 * ChronoShare is free software: you can redistribute it and/or modify it under the terms
8 * of the GNU General Public License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
Alexander Afanasyeveb575e02013-01-26 17:14:51 -080010 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -080011 * ChronoShare is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyeveb575e02013-01-26 17:14:51 -080014 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -080015 * You should have received copies of the GNU General Public License along with
16 * ChronoShare, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * See AUTHORS.md for complete list of ChronoShare authors and contributors.
Alexander Afanasyeveb575e02013-01-26 17:14:51 -080019 */
20
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080021#include "ccnx-wrapper.hpp"
Alexander Afanasyevf4cde4e2016-12-25 13:42:57 -080022#include "dispatcher.hpp"
23#include "fs-watcher.hpp"
24#include "logging.hpp"
Alexander Afanasyeveb575e02013-01-26 17:14:51 -080025
Alexander Afanasyeveb575e02013-01-26 17:14:51 -080026#include <boost/lexical_cast.hpp>
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080027#include <boost/make_shared.hpp>
Alexander Afanasyeveb575e02013-01-26 17:14:51 -080028
29using namespace boost;
30using namespace std;
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070031using namespace Ndnx;
Alexander Afanasyeveb575e02013-01-26 17:14:51 -080032
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080033INIT_LOGGER("DumpDb");
Alexander Afanasyev24b449f2013-02-06 13:27:59 -080034
35class StateLogDumper : public DbHelper
36{
37public:
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080038 StateLogDumper(const filesystem::path& path)
39 : DbHelper(path / ".chronoshare", "sync-log.db")
Alexander Afanasyev24b449f2013-02-06 13:27:59 -080040 {
41 }
42
43 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080044 DumpState()
Alexander Afanasyev24b449f2013-02-06 13:27:59 -080045 {
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080046 sqlite3_stmt* stmt;
47 sqlite3_prepare_v2(m_db,
48 "SELECT hash(device_name, seq_no) FROM (SELECT * FROM SyncNodes ORDER BY device_name)",
49 -1, &stmt, 0);
50 sqlite3_step(stmt);
51 Hash hash(sqlite3_column_blob(stmt, 0), sqlite3_column_bytes(stmt, 0));
52 sqlite3_finalize(stmt);
Alexander Afanasyev24b449f2013-02-06 13:27:59 -080053
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080054 sqlite3_prepare_v2(m_db, "SELECT device_name, seq_no, last_known_locator, last_update "
55 " FROM SyncNodes "
56 " ORDER BY device_name",
57 -1, &stmt, 0);
Alexander Afanasyev24b449f2013-02-06 13:27:59 -080058
59 cout.setf(std::ios::left, std::ios::adjustfield);
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080060 cout << ">> SYNC NODES (" << hash.shortHash() << ") <<" << endl;
61 cout << "===================================================================================="
62 << endl;
63 cout << setw(30) << "device_name"
64 << " | seq_no | " << setw(20) << "locator"
65 << " | last_update " << endl;
66 cout << "===================================================================================="
67 << endl;
Alexander Afanasyev24b449f2013-02-06 13:27:59 -080068
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080069 while (sqlite3_step(stmt) == SQLITE_ROW) {
70 cout << setw(30)
71 << lexical_cast<string>(Name(sqlite3_column_blob(stmt, 0), sqlite3_column_bytes(stmt, 0)))
72 << " | "; // device_name
73 cout << setw(6) << sqlite3_column_int64(stmt, 1) << " | "; // seq_no
74 cout << setw(20)
75 << lexical_cast<string>(Name(sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2)))
76 << " | "; // locator
77 if (sqlite3_column_bytes(stmt, 3) > 0) {
78 cout << setw(10) << sqlite3_column_text(stmt, 3) << endl;
Alexander Afanasyev24b449f2013-02-06 13:27:59 -080079 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080080 else {
81 cout << "unknown" << endl;
82 }
83 }
84 sqlite3_finalize(stmt);
Alexander Afanasyev24b449f2013-02-06 13:27:59 -080085 }
86
87 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080088 DumpLog()
Alexander Afanasyev24b449f2013-02-06 13:27:59 -080089 {
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080090 sqlite3_stmt* stmt;
91 sqlite3_prepare_v2(m_db, "SELECT state_hash, last_update, state_id "
92 " FROM SyncLog "
93 " ORDER BY last_update",
94 -1, &stmt, 0);
Alexander Afanasyev24b449f2013-02-06 13:27:59 -080095
96 cout.setf(std::ios::left, std::ios::adjustfield);
97 cout << ">> SYNC LOG <<" << endl;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080098 cout << "===================================================================================="
99 << endl;
100 cout << setw(10) << "state_hash"
101 << " | state details " << endl;
102 cout << "===================================================================================="
103 << endl;
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800104
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800105 while (sqlite3_step(stmt) == SQLITE_ROW) {
106 cout << setw(10)
107 << Hash(sqlite3_column_blob(stmt, 0), sqlite3_column_bytes(stmt, 0)).shortHash()
108 << " | "; // state hash
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800109
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800110 sqlite3_stmt* stmt2;
111 sqlite3_prepare_v2(m_db,
112 "SELECT device_name, ss.seq_no "
113 " FROM SyncStateNodes ss JOIN SyncNodes sn ON ss.device_id = sn.device_id "
114 " WHERE state_id=? "
115 " ORDER BY device_name",
116 -1, &stmt2, 0);
117 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
118 sqlite3_bind_int64(stmt2, 1, sqlite3_column_int64(stmt, 2));
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800119
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800120 while (sqlite3_step(stmt2) == SQLITE_ROW) {
121 cout << lexical_cast<string>(
122 Name(sqlite3_column_blob(stmt2, 0), sqlite3_column_bytes(stmt2, 0)))
123 << "(" << sqlite3_column_int64(stmt2, 1) << "); ";
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800124 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800125
126 sqlite3_finalize(stmt2);
127
128 cout << endl;
129 }
130 sqlite3_finalize(stmt);
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800131 }
132};
133
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800134class ActionLogDumper : public DbHelper
135{
136public:
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800137 ActionLogDumper(const filesystem::path& path)
138 : DbHelper(path / ".chronoshare", "action-log.db")
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800139 {
140 }
141
142 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800143 Dump()
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800144 {
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800145 sqlite3_stmt* stmt;
146 sqlite3_prepare_v2(m_db,
147 "SELECT device_name, seq_no, action, filename, version, file_hash, file_seg_num, parent_device_name, parent_seq_no "
148 " FROM ActionLog "
149 " ORDER BY action_timestamp",
150 -1, &stmt, 0);
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800151
152 cout.setf(std::ios::left, std::ios::adjustfield);
153 cout << ">> ACTION LOG <<" << endl;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800154 cout << "============================================================================================================================================================================="
155 << endl;
156 cout << setw(30) << "device_name"
157 << " | seq_no | action |" << setw(40) << " filename "
158 << " | version | file_hash | seg_num | parent_device_name | parent_seq_no"
159 << endl;
160 cout << "============================================================================================================================================================================="
161 << endl;
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800162
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800163 while (sqlite3_step(stmt) == SQLITE_ROW) {
164 cout << setw(30)
165 << lexical_cast<string>(Name(sqlite3_column_blob(stmt, 0), sqlite3_column_bytes(stmt, 0)))
166 << " | "; // device_name
167 cout << setw(6) << sqlite3_column_int64(stmt, 1) << " | "; // seq_no
168 cout << setw(6) << (sqlite3_column_int(stmt, 2) == 0 ? "UPDATE" : "DELETE") << " | "; // action
169 cout << setw(40) << sqlite3_column_text(stmt, 3) << " | "; // filename
170 cout << setw(7) << sqlite3_column_int64(stmt, 4) << " | "; // version
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800171
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800172 if (sqlite3_column_int(stmt, 2) == 0) {
173 cout << setw(10)
174 << Hash(sqlite3_column_blob(stmt, 5), sqlite3_column_bytes(stmt, 5)).shortHash()
175 << " | ";
176 cout << setw(7) << sqlite3_column_int64(stmt, 6) << " | "; // seg_num
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800177 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800178 else
179 cout << " | | ";
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800180
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800181 if (sqlite3_column_bytes(stmt, 7) > 0) {
182 cout << setw(30) << lexical_cast<string>(
183 Name(sqlite3_column_blob(stmt, 7), sqlite3_column_bytes(stmt, 7)))
184 << " | "; // parent_device_name
185 cout << setw(5) << sqlite3_column_int64(stmt, 8); // seq_no
186 }
187 else
188 cout << setw(30) << " "
189 << " | ";
190 cout << endl;
191 }
192
193 sqlite3_finalize(stmt);
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800194 }
Zhenkai Zhued457c32013-02-13 15:51:48 -0800195
196 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800197 DumpActionData(const Ccnx::Name& deviceName, int64_t seqno)
Zhenkai Zhued457c32013-02-13 15:51:48 -0800198 {
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800199 sqlite3_stmt* stmt;
200 sqlite3_prepare_v2(m_db,
201 "SELECT action_content_object, action_name FROM ActionLog WHERE device_name = ? and seq_no = ?",
202 -1, &stmt, 0);
203 Ccnx::CcnxCharbufPtr device_name = deviceName.toCcnxCharbuf();
204 sqlite3_bind_blob(stmt, 1, device_name->buf(), device_name->length(), SQLITE_STATIC);
205 sqlite3_bind_int64(stmt, 2, seqno);
206 cout << "Dumping action data for: [" << deviceName << ", " << seqno << "]" << endl;
207 if (sqlite3_step(stmt) == SQLITE_ROW) {
208 PcoPtr pco = make_shared<ParsedContentObject>(reinterpret_cast<const unsigned char*>(
209 sqlite3_column_blob(stmt, 0)),
210 sqlite3_column_bytes(stmt, 0));
211 Ccnx::Name actionName = Ccnx::Name(sqlite3_column_blob(stmt, 1), sqlite3_column_bytes(stmt, 0));
212 if (pco) {
213 ActionItemPtr action = deserializeMsg<ActionItem>(pco->content());
214 if (action) {
Zhenkai Zhu555c4f12013-02-13 16:57:36 -0800215 cout << "Action data size : " << pco->content().size() << endl;
216 cout << "Action data name : " << actionName << endl;
Zhenkai Zhued457c32013-02-13 15:51:48 -0800217 string type = action->action() == ActionItem::UPDATE ? "UPDATE" : "DELETE";
218 cout << "Action Type = " << type << endl;
219 cout << "Timestamp = " << action->timestamp() << endl;
220 string filename = action->filename();
221 cout << "Filename = " << filename << endl;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800222 if (action->has_seg_num()) {
Zhenkai Zhued457c32013-02-13 15:51:48 -0800223 cout << "Segment number = " << action->seg_num() << endl;
224 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800225 if (action->has_file_hash()) {
226 cout << "File hash = " << Hash(action->file_hash().c_str(), action->file_hash().size())
227 << endl;
Zhenkai Zhued457c32013-02-13 15:51:48 -0800228 }
229 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800230 else {
Zhenkai Zhued457c32013-02-13 15:51:48 -0800231 cerr << "Error! Failed to parse action from pco! " << endl;
232 }
233 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800234 else {
Zhenkai Zhued457c32013-02-13 15:51:48 -0800235 cerr << "Error! Invalid pco! " << endl;
236 }
237 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800238 else {
Zhenkai Zhued457c32013-02-13 15:51:48 -0800239 cerr << "Error! Can not find the requested action" << endl;
240 }
241 sqlite3_finalize(stmt);
242 }
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800243};
244
245class FileStateDumper : public DbHelper
246{
247public:
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800248 FileStateDumper(const filesystem::path& path)
249 : DbHelper(path / ".chronoshare", "file-state.db")
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800250 {
251 }
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800252
253 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800254 Dump()
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800255 {
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800256 sqlite3_stmt* stmt;
257 sqlite3_prepare_v2(m_db,
258 "SELECT filename,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,directory,is_complete "
259 " FROM FileState "
260 " WHERE type = 0 ORDER BY filename",
261 -1, &stmt, 0);
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800262
263 cout.setf(std::ios::left, std::ios::adjustfield);
264 cout << ">> FILE STATE <<" << endl;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800265 cout << "==================================================================================================================================="
266 << endl;
267 cout << "filename | device_name | seq_no | file_hash | seg_num | directory | is_complete"
268 << endl;
269 cout << "==================================================================================================================================="
270 << endl;
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800271
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800272 while (sqlite3_step(stmt) == SQLITE_ROW) {
273 cout << setw(40) << sqlite3_column_text(stmt, 0) << " | ";
274 cout << setw(30)
275 << lexical_cast<string>(Name(sqlite3_column_blob(stmt, 1), sqlite3_column_bytes(stmt, 1)))
276 << " | ";
277 cout << setw(6) << sqlite3_column_int64(stmt, 2) << " | ";
278 cout << setw(10)
279 << Hash(sqlite3_column_blob(stmt, 3), sqlite3_column_bytes(stmt, 3)).shortHash() << " | ";
280 cout << setw(6) << sqlite3_column_int64(stmt, 6) << " | ";
281 if (sqlite3_column_bytes(stmt, 7) == 0)
282 cout << setw(20) << "<NULL>"
283 << " | ";
284 else
285 cout << setw(20) << sqlite3_column_text(stmt, 7) << " | ";
Alexander Afanasyev38826ce2013-01-31 16:31:42 -0800286
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800287 if (sqlite3_column_int(stmt, 8) == 0)
288 cout << setw(20) << "no" << endl;
289 else
290 cout << setw(20) << "yes" << endl;
291 }
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800292
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800293 sqlite3_finalize(stmt);
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800294 }
295};
296
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800297int
298main(int argc, char* argv[])
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800299{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800300 INIT_LOGGERS();
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800301
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800302 if (argc != 3 && !(argc == 5 && string(argv[1]) == "action")) {
303 cerr << "Usage: ./dump-db state|action|file|all <path-to-shared-folder>" << endl;
304 cerr << " or: ./dump-db action <path-to-shared-folder> <device-name> <seq-no>" << endl;
305 return 1;
306 }
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800307
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800308 string type = argv[1];
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800309 if (type == "state") {
310 StateLogDumper dumper(argv[2]);
311 dumper.DumpState();
312 dumper.DumpLog();
313 }
314 else if (type == "action") {
315 ActionLogDumper dumper(argv[2]);
316 if (argc == 5) {
317 dumper.DumpActionData(string(argv[3]), boost::lexical_cast<int64_t>(argv[4]));
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800318 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800319 else {
320 dumper.Dump();
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800321 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800322 }
323 else if (type == "file") {
324 FileStateDumper dumper(argv[2]);
325 dumper.Dump();
326 }
327 else if (type == "all") {
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800328 {
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800329 StateLogDumper dumper(argv[2]);
330 dumper.DumpState();
331 dumper.DumpLog();
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800332 }
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800333
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800334 {
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800335 ActionLogDumper dumper(argv[2]);
336 dumper.Dump();
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800337 }
338
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800339 {
340 FileStateDumper dumper(argv[2]);
341 dumper.Dump();
342 }
343 }
344 else {
345 cerr << "ERROR: Wrong database type" << endl;
346 cerr << "\nUsage: ./dump-db state|action|file|all <path-to-shared-folder>" << endl;
347 return 1;
348 }
349
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800350
351 return 0;
352}