blob: 83d2acc8c8ff4b35f84fac087c67f51c3313d11f [file] [log] [blame]
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyeva9369b42017-01-11 11:58:00 -08003 * Copyright (c) 2013-2017, Regents of the University of California.
Alexander Afanasyev0a30a0c2013-01-29 17:25:42 -08004 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08005 * This file is part of ChronoShare, a decentralized file sharing application over NDN.
Alexander Afanasyev0a30a0c2013-01-29 17:25:42 -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 Afanasyev0a30a0c2013-01-29 17:25:42 -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 Afanasyev0a30a0c2013-01-29 17:25:42 -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 Afanasyev0a30a0c2013-01-29 17:25:42 -080019 */
20
Lijing Wang51837ad2016-12-25 14:43:53 -080021#include "file-state.hpp"
22#include "core/logging.hpp"
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080023
Alexander Afanasyev1cf5c432017-01-13 23:22:15 -080024_LOG_INIT(FileState);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080025
Lijing Wang51837ad2016-12-25 14:43:53 -080026namespace ndn {
27namespace chronoshare {
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080028
29const std::string INIT_DATABASE = "\
30 \n\
31CREATE TABLE FileState ( \n\
32 type INTEGER NOT NULL, /* 0 - newest, 1 - oldest */ \n\
33 filename TEXT NOT NULL, \n\
Alexander Afanasyev6fb5dc62013-02-27 11:34:52 -080034 version INTEGER, \n\
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080035 directory TEXT, \n\
36 device_name BLOB NOT NULL, \n\
37 seq_no INTEGER NOT NULL, \n\
38 file_hash BLOB NOT NULL, \n\
39 file_atime TIMESTAMP, \n\
40 file_mtime TIMESTAMP, \n\
41 file_ctime TIMESTAMP, \n\
42 file_chmod INTEGER, \n\
43 file_seg_num INTEGER, \n\
44 is_complete INTEGER, \n\
45 \n\
46 PRIMARY KEY (type, filename) \n\
47); \n\
48 \n\
49CREATE INDEX FileState_device_name_seq_no ON FileState (device_name, seq_no); \n\
50CREATE INDEX FileState_type_file_hash ON FileState (type, file_hash); \n\
51";
52
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080053FileState::FileState(const boost::filesystem::path& path)
54 : DbHelper(path / ".chronoshare", "file-state.db")
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080055{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080056 sqlite3_exec(m_db, INIT_DATABASE.c_str(), NULL, NULL, NULL);
57 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080058}
59
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080060FileState::~FileState()
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080061{
62}
63
64void
Lijing Wang51837ad2016-12-25 14:43:53 -080065FileState::UpdateFile(const std::string& filename, sqlite3_int64 version, const Buffer& hash,
66 const Buffer& device_name, sqlite3_int64 seq_no, time_t atime, time_t mtime,
67 time_t ctime, int mode, int seg_num)
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080068{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080069 sqlite3_stmt* stmt;
70 sqlite3_prepare_v2(m_db, "UPDATE FileState "
71 "SET "
72 "device_name=?, seq_no=?, "
73 "version=?,"
74 "file_hash=?,"
75 "file_atime=datetime(?, 'unixepoch'),"
76 "file_mtime=datetime(?, 'unixepoch'),"
77 "file_ctime=datetime(?, 'unixepoch'),"
78 "file_chmod=?, "
79 "file_seg_num=? "
80 "WHERE type=0 AND filename=?",
81 -1, &stmt, 0);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080082
Lijing Wang51837ad2016-12-25 14:43:53 -080083 sqlite3_bind_blob(stmt, 1, device_name.buf(), device_name.size(), SQLITE_STATIC);
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080084 sqlite3_bind_int64(stmt, 2, seq_no);
85 sqlite3_bind_int64(stmt, 3, version);
Lijing Wang51837ad2016-12-25 14:43:53 -080086 sqlite3_bind_blob(stmt, 4, hash.buf(), hash.size(), SQLITE_STATIC);
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080087 sqlite3_bind_int64(stmt, 5, atime);
88 sqlite3_bind_int64(stmt, 6, mtime);
89 sqlite3_bind_int64(stmt, 7, ctime);
90 sqlite3_bind_int(stmt, 8, mode);
91 sqlite3_bind_int(stmt, 9, seg_num);
92 sqlite3_bind_text(stmt, 10, filename.c_str(), -1, SQLITE_STATIC);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080093
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080094 sqlite3_step(stmt);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080095
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080096 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_ROW && sqlite3_errcode(m_db) != SQLITE_DONE,
97 sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -080098
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080099 sqlite3_finalize(stmt);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800100
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800101 int affected_rows = sqlite3_changes(m_db);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800102 if (affected_rows == 0) // file didn't exist
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800103 {
104 sqlite3_stmt* stmt;
105 sqlite3_prepare_v2(m_db,
106 "INSERT INTO FileState "
Lijing Wang51837ad2016-12-25 14:43:53 -0800107 "(type,filename,version,device_name,seq_no,file_hash,"
108 "file_atime,file_mtime,file_ctime,file_chmod,file_seg_num) "
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800109 "VALUES (0, ?, ?, ?, ?, ?, "
110 "datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?, ?)",
111 -1, &stmt, 0);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800112
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800113 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800114
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800115 sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);
116 sqlite3_bind_int64(stmt, 2, version);
Lijing Wang51837ad2016-12-25 14:43:53 -0800117 sqlite3_bind_blob(stmt, 3, device_name.buf(), device_name.size(), SQLITE_STATIC);
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800118 sqlite3_bind_int64(stmt, 4, seq_no);
Lijing Wang51837ad2016-12-25 14:43:53 -0800119 sqlite3_bind_blob(stmt, 5, hash.buf(), hash.size(), SQLITE_STATIC);
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800120 sqlite3_bind_int64(stmt, 6, atime);
121 sqlite3_bind_int64(stmt, 7, mtime);
122 sqlite3_bind_int64(stmt, 8, ctime);
123 sqlite3_bind_int(stmt, 9, mode);
124 sqlite3_bind_int(stmt, 10, seg_num);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800125
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800126 sqlite3_step(stmt);
127 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
128 sqlite3_finalize(stmt);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800129
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800130 sqlite3_prepare_v2(m_db,
131 "UPDATE FileState SET directory=directory_name(filename) WHERE filename=?",
132 -1, &stmt, 0);
133 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800134
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800135 sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);
136 sqlite3_step(stmt);
137 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
138 sqlite3_finalize(stmt);
139 }
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800140}
141
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800142void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800143FileState::DeleteFile(const std::string& filename)
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800144{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800145 sqlite3_stmt* stmt;
146 sqlite3_prepare_v2(m_db, "DELETE FROM FileState WHERE type=0 AND filename=?", -1, &stmt, 0);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800147 sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);
148
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800149 _LOG_DEBUG("Delete " << filename);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800150
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800151 sqlite3_step(stmt);
152 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
153 sqlite3_finalize(stmt);
154}
155
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800156void
157FileState::SetFileComplete(const std::string& filename)
158{
159 sqlite3_stmt* stmt;
160 sqlite3_prepare_v2(m_db, "UPDATE FileState SET is_complete=1 WHERE type = 0 AND filename = ?", -1,
161 &stmt, 0);
162 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
163 sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);
164
165 sqlite3_step(stmt);
166 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
167
168 sqlite3_finalize(stmt);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800169}
170
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800171/**
172 * @todo Implement checking modification time and permissions
173 */
174FileItemPtr
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800175FileState::LookupFile(const std::string& filename)
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800176{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800177 sqlite3_stmt* stmt;
178 sqlite3_prepare_v2(m_db,
179 "SELECT filename,version,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,is_complete "
180 " FROM FileState "
181 " WHERE type = 0 AND filename = ?",
182 -1, &stmt, 0);
183 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800184 sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);
185
186 FileItemPtr retval;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800187 if (sqlite3_step(stmt) == SQLITE_ROW) {
188 retval = make_shared<FileItem>();
189 retval->set_filename(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
190 sqlite3_column_bytes(stmt, 0));
191 retval->set_version(sqlite3_column_int64(stmt, 1));
192 retval->set_device_name(sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
193 retval->set_seq_no(sqlite3_column_int64(stmt, 3));
194 retval->set_file_hash(sqlite3_column_blob(stmt, 4), sqlite3_column_bytes(stmt, 4));
195 retval->set_mtime(sqlite3_column_int(stmt, 5));
196 retval->set_mode(sqlite3_column_int(stmt, 6));
197 retval->set_seg_num(sqlite3_column_int64(stmt, 7));
198 retval->set_is_complete(sqlite3_column_int(stmt, 8));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800199 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800200 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
201 sqlite3_finalize(stmt);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800202
203 return retval;
204}
205
206FileItemsPtr
Lijing Wang51837ad2016-12-25 14:43:53 -0800207FileState::LookupFilesForHash(const Buffer& hash)
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800208{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800209 sqlite3_stmt* stmt;
210 sqlite3_prepare_v2(m_db,
211 "SELECT filename,version,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,is_complete "
212 " FROM FileState "
213 " WHERE type = 0 AND file_hash = ?",
214 -1, &stmt, 0);
215 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
Lijing Wang51837ad2016-12-25 14:43:53 -0800216 sqlite3_bind_blob(stmt, 1, hash.buf(), hash.size(), SQLITE_STATIC);
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800217 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800218
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800219 FileItemsPtr retval = make_shared<FileItems>();
220 while (sqlite3_step(stmt) == SQLITE_ROW) {
221 FileItem file;
222 file.set_filename(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
223 sqlite3_column_bytes(stmt, 0));
224 file.set_version(sqlite3_column_int64(stmt, 1));
225 file.set_device_name(sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
226 file.set_seq_no(sqlite3_column_int64(stmt, 3));
227 file.set_file_hash(sqlite3_column_blob(stmt, 4), sqlite3_column_bytes(stmt, 4));
228 file.set_mtime(sqlite3_column_int(stmt, 5));
229 file.set_mode(sqlite3_column_int(stmt, 6));
230 file.set_seg_num(sqlite3_column_int64(stmt, 7));
231 file.set_is_complete(sqlite3_column_int(stmt, 8));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800232
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800233 retval->push_back(file);
234 }
235 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800236
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800237 sqlite3_finalize(stmt);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800238
239 return retval;
240}
241
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800242void
Lijing Wang51837ad2016-12-25 14:43:53 -0800243FileState::LookupFilesInFolder(const function<void(const FileItem&)>& visitor,
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800244 const std::string& folder, int offset /*=0*/, int limit /*=-1*/)
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800245{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800246 sqlite3_stmt* stmt;
247 sqlite3_prepare_v2(m_db,
248 "SELECT filename,version,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,is_complete "
249 " FROM FileState "
250 " WHERE type = 0 AND directory = ?"
251 " LIMIT ? OFFSET ?",
252 -1, &stmt, 0);
253 if (folder.size() == 0)
254 sqlite3_bind_null(stmt, 1);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800255 else
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800256 sqlite3_bind_text(stmt, 1, folder.c_str(), folder.size(), SQLITE_STATIC);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800257
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800258 sqlite3_bind_int(stmt, 2, limit);
259 sqlite3_bind_int(stmt, 3, offset);
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800260
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800261 while (sqlite3_step(stmt) == SQLITE_ROW) {
262 FileItem file;
263 file.set_filename(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
264 sqlite3_column_bytes(stmt, 0));
265 file.set_version(sqlite3_column_int64(stmt, 1));
266 file.set_device_name(sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
267 file.set_seq_no(sqlite3_column_int64(stmt, 3));
268 file.set_file_hash(sqlite3_column_blob(stmt, 4), sqlite3_column_bytes(stmt, 4));
269 file.set_mtime(sqlite3_column_int(stmt, 5));
270 file.set_mode(sqlite3_column_int(stmt, 6));
271 file.set_seg_num(sqlite3_column_int64(stmt, 7));
272 file.set_is_complete(sqlite3_column_int(stmt, 8));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800273
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800274 visitor(file);
275 }
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800276
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800277 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800278
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800279 sqlite3_finalize(stmt);
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800280}
281
282FileItemsPtr
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800283FileState::LookupFilesInFolder(const std::string& folder, int offset /*=0*/, int limit /*=-1*/)
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800284{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800285 FileItemsPtr retval = make_shared<FileItems>();
Lijing Wang51837ad2016-12-25 14:43:53 -0800286 LookupFilesInFolder(bind(static_cast<void (FileItems::*)(const FileItem&)>(&FileItems::push_back),
287 retval.get(), _1),
288 folder, offset, limit);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800289
290 return retval;
291}
292
Alexander Afanasyev6fb5dc62013-02-27 11:34:52 -0800293bool
Lijing Wang51837ad2016-12-25 14:43:53 -0800294FileState::LookupFilesInFolderRecursively(const function<void(const FileItem&)>& visitor,
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800295 const std::string& folder, int offset /*=0*/,
296 int limit /*=-1*/)
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800297{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800298 _LOG_DEBUG("LookupFilesInFolderRecursively: [" << folder << "]");
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800299
Alexander Afanasyev6fb5dc62013-02-27 11:34:52 -0800300 if (limit >= 0)
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800301 limit++;
Alexander Afanasyev6fb5dc62013-02-27 11:34:52 -0800302
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800303 sqlite3_stmt* stmt;
304 if (folder != "") {
305 /// @todo Do something to improve efficiency of this query. Right now it is basically scanning the whole database
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800306
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800307 sqlite3_prepare_v2(m_db,
308 "SELECT filename,version,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,is_complete "
309 " FROM FileState "
Lijing Wang51837ad2016-12-25 14:43:53 -0800310 " WHERE type = 0 AND is_dir_prefix(?, directory)=1 "
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800311 " ORDER BY filename "
312 " LIMIT ? OFFSET ?",
313 -1, &stmt,
314 0); // there is a small ambiguity with is_prefix matching, but should be ok for now
315 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800316
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800317 sqlite3_bind_text(stmt, 1, folder.c_str(), folder.size(), SQLITE_STATIC);
318 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800319
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800320 sqlite3_bind_int(stmt, 2, limit);
321 sqlite3_bind_int(stmt, 3, offset);
322 }
323 else {
324 sqlite3_prepare_v2(m_db,
325 "SELECT filename,version,device_name,seq_no,file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num,is_complete "
326 " FROM FileState "
327 " WHERE type = 0"
328 " ORDER BY filename "
329 " LIMIT ? OFFSET ?",
330 -1, &stmt, 0);
331 sqlite3_bind_int(stmt, 1, limit);
332 sqlite3_bind_int(stmt, 2, offset);
333 }
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800334
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800335 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_OK, sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800336
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800337 while (sqlite3_step(stmt) == SQLITE_ROW) {
338 if (limit == 1)
339 break;
Alexander Afanasyev6fb5dc62013-02-27 11:34:52 -0800340
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800341 FileItem file;
342 file.set_filename(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
343 sqlite3_column_bytes(stmt, 0));
344 file.set_version(sqlite3_column_int64(stmt, 1));
345 file.set_device_name(sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
346 file.set_seq_no(sqlite3_column_int64(stmt, 3));
347 file.set_file_hash(sqlite3_column_blob(stmt, 4), sqlite3_column_bytes(stmt, 4));
348 file.set_mtime(sqlite3_column_int(stmt, 5));
349 file.set_mode(sqlite3_column_int(stmt, 6));
350 file.set_seg_num(sqlite3_column_int64(stmt, 7));
351 file.set_is_complete(sqlite3_column_int(stmt, 8));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800352
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800353 visitor(file);
354 limit--;
355 }
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800356
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800357 _LOG_DEBUG_COND(sqlite3_errcode(m_db) != SQLITE_DONE, sqlite3_errmsg(m_db));
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800358
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800359 sqlite3_finalize(stmt);
Alexander Afanasyev6fb5dc62013-02-27 11:34:52 -0800360
361 return (limit == 1);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800362}
363
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800364FileItemsPtr
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800365FileState::LookupFilesInFolderRecursively(const std::string& folder, int offset /*=0*/,
366 int limit /*=-1*/)
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800367{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800368 FileItemsPtr retval = make_shared<FileItems>();
Lijing Wang51837ad2016-12-25 14:43:53 -0800369 LookupFilesInFolder(bind(static_cast<void (FileItems::*)(const FileItem&)>(&FileItems::push_back),
370 retval.get(), _1),
371 folder, offset, limit);
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800372
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800373 return retval;
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800374}
Lijing Wang51837ad2016-12-25 14:43:53 -0800375
376} // namespace chronoshare
377} // namespace ndn