blob: 098d3e745c4d31d7b26c7457dfe634036df0a86a [file] [log] [blame]
Alexander Afanasyeveb575e02013-01-26 17:14:51 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
Alexander Afanasyevf4cde4e2016-12-25 13:42:57 -080021#include "dispatcher.hpp"
22#include "fs-watcher.hpp"
23#include "logging.hpp"
24#include "ccnx-wrapper.hpp"
Alexander Afanasyeveb575e02013-01-26 17:14:51 -080025
26#include <boost/make_shared.hpp>
27#include <boost/lexical_cast.hpp>
28
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 Afanasyev24b449f2013-02-06 13:27:59 -080033INIT_LOGGER ("DumpDb");
34
35class StateLogDumper : public DbHelper
36{
37public:
38 StateLogDumper (const filesystem::path &path)
39 : DbHelper (path / ".chronoshare", "sync-log.db")
40 {
41 }
42
43 void
44 DumpState ()
45 {
46 sqlite3_stmt *stmt;
47 sqlite3_prepare_v2 (m_db, "SELECT hash(device_name, seq_no) FROM (SELECT * FROM SyncNodes ORDER BY device_name)", -1, &stmt, 0);
48 sqlite3_step (stmt);
49 Hash hash (sqlite3_column_blob (stmt, 0), sqlite3_column_bytes (stmt, 0));
50 sqlite3_finalize (stmt);
51
52 sqlite3_prepare_v2 (m_db,
53 "SELECT device_name, seq_no, last_known_locator, last_update "
54 " FROM SyncNodes "
55 " ORDER BY device_name", -1, &stmt, 0);
56
57 cout.setf(std::ios::left, std::ios::adjustfield);
58 cout << ">> SYNC NODES (" << hash.shortHash () << ") <<" << endl;
59 cout << "====================================================================================" << endl;
60 cout << setw(30) << "device_name" << " | seq_no | " << setw(20) << "locator" << " | last_update " << endl;
61 cout << "====================================================================================" << endl;
62
63 while (sqlite3_step (stmt) == SQLITE_ROW)
64 {
65 cout << setw (30) << lexical_cast<string> (Name (sqlite3_column_blob (stmt, 0), sqlite3_column_bytes (stmt, 0))) << " | "; // device_name
66 cout << setw (6) << sqlite3_column_int64 (stmt, 1) << " | "; // seq_no
67 cout << setw (20) << lexical_cast<string> (Name (sqlite3_column_blob (stmt, 2), sqlite3_column_bytes (stmt, 2))) << " | "; // locator
68 if (sqlite3_column_bytes (stmt, 3) > 0)
69 {
70 cout << setw (10) << sqlite3_column_text (stmt, 3) << endl;
71 }
72 else
73 {
74 cout << "unknown" << endl;
75 }
76 }
77 sqlite3_finalize (stmt);
78 }
79
80 void
81 DumpLog ()
82 {
83 sqlite3_stmt *stmt;
84 sqlite3_prepare_v2 (m_db,
85 "SELECT state_hash, last_update, state_id "
86 " FROM SyncLog "
87 " ORDER BY last_update", -1, &stmt, 0);
88
89 cout.setf(std::ios::left, std::ios::adjustfield);
90 cout << ">> SYNC LOG <<" << endl;
91 cout << "====================================================================================" << endl;
92 cout << setw(10) << "state_hash" << " | state details " << endl;
93 cout << "====================================================================================" << endl;
94
95 while (sqlite3_step (stmt) == SQLITE_ROW)
96 {
97 cout << setw (10) << Hash (sqlite3_column_blob (stmt, 0), sqlite3_column_bytes (stmt, 0)).shortHash () << " | "; // state hash
98
99 sqlite3_stmt *stmt2;
100 sqlite3_prepare_v2 (m_db,
101 "SELECT device_name, ss.seq_no "
102 " FROM SyncStateNodes ss JOIN SyncNodes sn ON ss.device_id = sn.device_id "
103 " WHERE state_id=? "
104 " ORDER BY device_name", -1, &stmt2, 0);
105 _LOG_DEBUG_COND (sqlite3_errcode (m_db) != SQLITE_OK, sqlite3_errmsg (m_db));
106 sqlite3_bind_int64 (stmt2, 1, sqlite3_column_int64 (stmt, 2));
107
108 while (sqlite3_step (stmt2) == SQLITE_ROW)
109 {
110 cout << lexical_cast<string> (Name (sqlite3_column_blob (stmt2, 0), sqlite3_column_bytes (stmt2, 0)))
111 << "("
112 << sqlite3_column_int64 (stmt2, 1)
113 << "); ";
114 }
115
116 sqlite3_finalize (stmt2);
117
118 cout << endl;
119 }
120 sqlite3_finalize (stmt);
121 }
122};
123
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800124class ActionLogDumper : public DbHelper
125{
126public:
127 ActionLogDumper (const filesystem::path &path)
128 : DbHelper (path / ".chronoshare", "action-log.db")
129 {
130 }
131
132 void
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800133 Dump ()
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800134 {
135 sqlite3_stmt *stmt;
136 sqlite3_prepare_v2 (m_db,
137 "SELECT device_name, seq_no, action, filename, version, file_hash, file_seg_num, parent_device_name, parent_seq_no "
138 " FROM ActionLog "
Alexander Afanasyev0a30a0c2013-01-29 17:25:42 -0800139 " ORDER BY action_timestamp", -1, &stmt, 0);
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800140
141 cout.setf(std::ios::left, std::ios::adjustfield);
142 cout << ">> ACTION LOG <<" << endl;
143 cout << "=============================================================================================================================================================================" << endl;
144 cout << setw(30) << "device_name" << " | seq_no | action |" << setw(40) << " filename " << " | version | file_hash | seg_num | parent_device_name | parent_seq_no" << endl;
145 cout << "=============================================================================================================================================================================" << endl;
146
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800147 while (sqlite3_step (stmt) == SQLITE_ROW)
148 {
149 cout << setw (30) << lexical_cast<string> (Name (sqlite3_column_blob (stmt, 0), sqlite3_column_bytes (stmt, 0))) << " | "; // device_name
150 cout << setw (6) << sqlite3_column_int64 (stmt, 1) << " | "; // seq_no
151 cout << setw (6) << (sqlite3_column_int (stmt, 2)==0?"UPDATE":"DELETE") << " | "; // action
152 cout << setw (40) << sqlite3_column_text (stmt, 3) << " | "; // filename
153 cout << setw (7) << sqlite3_column_int64 (stmt, 4) << " | "; // version
154
155 if (sqlite3_column_int (stmt, 2) == 0)
156 {
157 cout << setw (10) << Hash (sqlite3_column_blob (stmt, 5), sqlite3_column_bytes (stmt, 5)).shortHash () << " | ";
158 cout << setw (7) << sqlite3_column_int64 (stmt, 6) << " | "; // seg_num
159 }
160 else
161 cout << " | | ";
162
163 if (sqlite3_column_bytes (stmt, 7) > 0)
164 {
165 cout << setw (30) << lexical_cast<string> (Name (sqlite3_column_blob (stmt, 7), sqlite3_column_bytes (stmt, 7))) << " | "; // parent_device_name
166 cout << setw (5) << sqlite3_column_int64 (stmt, 8); // seq_no
167 }
168 else
169 cout << setw (30) << " " << " | ";
170 cout << endl;
171 }
172
173 sqlite3_finalize (stmt);
174 }
Zhenkai Zhued457c32013-02-13 15:51:48 -0800175
176 void
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -0700177 DumpActionData(const Ndnx::Name &deviceName, int64_t seqno)
Zhenkai Zhued457c32013-02-13 15:51:48 -0800178 {
179 sqlite3_stmt *stmt;
Zhenkai Zhu555c4f12013-02-13 16:57:36 -0800180 sqlite3_prepare_v2 (m_db, "SELECT action_content_object, action_name FROM ActionLog WHERE device_name = ? and seq_no = ?", -1, &stmt, 0);
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -0700181 Ndnx::NdnxCharbufPtr device_name = deviceName.toNdnxCharbuf();
Zhenkai Zhued457c32013-02-13 15:51:48 -0800182 sqlite3_bind_blob (stmt, 1, device_name->buf(), device_name->length(), SQLITE_STATIC);
183 sqlite3_bind_int64 (stmt, 2, seqno);
184 cout << "Dumping action data for: [" << deviceName << ", " << seqno << "]" <<endl;
185 if (sqlite3_step(stmt) == SQLITE_ROW)
186 {
187 PcoPtr pco = make_shared<ParsedContentObject> (reinterpret_cast<const unsigned char *> (sqlite3_column_blob (stmt, 0)), sqlite3_column_bytes (stmt, 0));
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -0700188 Ndnx::Name actionName = Ndnx::Name(sqlite3_column_blob(stmt, 1), sqlite3_column_bytes(stmt, 0));
Zhenkai Zhued457c32013-02-13 15:51:48 -0800189 if (pco)
190 {
191 ActionItemPtr action = deserializeMsg<ActionItem> (pco->content());
192 if (action)
193 {
Zhenkai Zhu555c4f12013-02-13 16:57:36 -0800194 cout << "Action data size : " << pco->content().size() << endl;
195 cout << "Action data name : " << actionName << endl;
Zhenkai Zhued457c32013-02-13 15:51:48 -0800196 string type = action->action() == ActionItem::UPDATE ? "UPDATE" : "DELETE";
197 cout << "Action Type = " << type << endl;
198 cout << "Timestamp = " << action->timestamp() << endl;
199 string filename = action->filename();
200 cout << "Filename = " << filename << endl;
201 if (action->has_seg_num())
202 {
203 cout << "Segment number = " << action->seg_num() << endl;
204 }
205 if (action->has_file_hash())
206 {
207 cout << "File hash = " << Hash(action->file_hash().c_str(), action->file_hash().size()) << endl;
208 }
209 }
210 else
211 {
212 cerr << "Error! Failed to parse action from pco! " << endl;
213 }
214 }
215 else
216 {
217 cerr << "Error! Invalid pco! " << endl;
218 }
219 }
220 else
221 {
222 cerr << "Error! Can not find the requested action" << endl;
223 }
224 sqlite3_finalize(stmt);
225 }
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800226};
227
228class FileStateDumper : public DbHelper
229{
230public:
231 FileStateDumper (const filesystem::path &path)
232 : DbHelper (path / ".chronoshare", "file-state.db")
233 {
234 }
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800235
236 void
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800237 Dump ()
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800238 {
239 sqlite3_stmt *stmt;
240 sqlite3_prepare_v2 (m_db,
Alexander Afanasyev38826ce2013-01-31 16:31:42 -0800241 "SELECT filename,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,directory,is_complete "
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800242 " FROM FileState "
243 " WHERE type = 0 ORDER BY filename", -1, &stmt, 0);
244
245 cout.setf(std::ios::left, std::ios::adjustfield);
246 cout << ">> FILE STATE <<" << endl;
Alexander Afanasyev38826ce2013-01-31 16:31:42 -0800247 cout << "===================================================================================================================================" << endl;
248 cout << "filename | device_name | seq_no | file_hash | seg_num | directory | is_complete" << endl;
249 cout << "===================================================================================================================================" << endl;
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800250
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800251 while (sqlite3_step (stmt) == SQLITE_ROW)
252 {
253 cout << setw (40) << sqlite3_column_text (stmt, 0) << " | ";
254 cout << setw (30) << lexical_cast<string> (Name (sqlite3_column_blob (stmt, 1), sqlite3_column_bytes (stmt, 1))) << " | ";
255 cout << setw (6) << sqlite3_column_int64 (stmt, 2) << " | ";
256 cout << setw (10) << Hash (sqlite3_column_blob (stmt, 3), sqlite3_column_bytes (stmt, 3)).shortHash () << " | ";
Alexander Afanasyev38826ce2013-01-31 16:31:42 -0800257 cout << setw (6) << sqlite3_column_int64 (stmt, 6) << " | ";
258 if (sqlite3_column_bytes (stmt, 7) == 0)
259 cout << setw (20) << "<NULL>" << " | ";
260 else
261 cout << setw (20) << sqlite3_column_text (stmt, 7) << " | ";
262
263 if (sqlite3_column_int (stmt, 8) == 0)
264 cout << setw (20) << "no" << endl;
265 else
266 cout << setw (20) << "yes" << endl;
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800267 }
268
269 sqlite3_finalize (stmt);
270 }
271};
272
273int main(int argc, char *argv[])
274{
275 INIT_LOGGERS ();
276
Zhenkai Zhued457c32013-02-13 15:51:48 -0800277 if (argc != 3 && !(argc == 5 && string(argv[1]) == "action"))
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800278 {
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800279 cerr << "Usage: ./dump-db state|action|file|all <path-to-shared-folder>" << endl;
Zhenkai Zhued457c32013-02-13 15:51:48 -0800280 cerr << " or: ./dump-db action <path-to-shared-folder> <device-name> <seq-no>" << endl;
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800281 return 1;
282 }
283
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800284 string type = argv[1];
285 if (type == "state")
286 {
287 StateLogDumper dumper (argv[2]);
288 dumper.DumpState ();
289 dumper.DumpLog ();
290 }
291 else if (type == "action")
292 {
293 ActionLogDumper dumper (argv[2]);
Zhenkai Zhued457c32013-02-13 15:51:48 -0800294 if (argc == 5)
295 {
296 dumper.DumpActionData(string(argv[3]), boost::lexical_cast<int64_t>(argv[4]));
297 }
298 else
299 {
300 dumper.Dump ();
301 }
Alexander Afanasyev24b449f2013-02-06 13:27:59 -0800302 }
303 else if (type == "file")
304 {
305 FileStateDumper dumper (argv[2]);
306 dumper.Dump ();
307 }
308 else if (type == "all")
309 {
310 {
311 StateLogDumper dumper (argv[2]);
312 dumper.DumpState ();
313 dumper.DumpLog ();
314 }
315
316 {
317 ActionLogDumper dumper (argv[2]);
318 dumper.Dump ();
319 }
320
321 {
322 FileStateDumper dumper (argv[2]);
323 dumper.Dump ();
324 }
325 }
326 else
327 {
328 cerr << "ERROR: Wrong database type" << endl;
329 cerr << "\nUsage: ./dump-db state|action|file|all <path-to-shared-folder>" << endl;
330 return 1;
331 }
332
Alexander Afanasyeveb575e02013-01-26 17:14:51 -0800333
334 return 0;
335}