blob: 76ae31d7d658600f69d11e904c48672f2c87eddb [file] [log] [blame]
Yingdi Yud04ed1a2013-10-14 14:07:03 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
Varun Patila24bd3e2020-11-24 10:08:33 +05303 * Copyright (c) 2020, Regents of the University of California
Yingdi Yud04ed1a2013-10-14 14:07:03 -07004 * Yingdi Yu
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
Qiuhan Ding0cfc1512015-02-17 17:44:11 -08009 * Author: Qiuhan Ding <qiuhanding@cs.ucla.edu>
Yingdi Yud04ed1a2013-10-14 14:07:03 -070010 */
11
Yingdi Yu0b0a7362014-08-05 16:31:30 -070012#include "contact-storage.hpp"
Yingdi Yu0b0a7362014-08-05 16:31:30 -070013#include "cryptopp.hpp"
Yingdi Yud04ed1a2013-10-14 14:07:03 -070014
Varun Patila24bd3e2020-11-24 10:08:33 +053015#include <boost/filesystem.hpp>
Yingdi Yu0b0a7362014-08-05 16:31:30 -070016
Yingdi Yueb692ac2015-02-10 18:46:18 -080017namespace chronochat {
Yingdi Yu0b0a7362014-08-05 16:31:30 -070018
Yingdi Yud04ed1a2013-10-14 14:07:03 -070019namespace fs = boost::filesystem;
20
Yingdi Yu0b0a7362014-08-05 16:31:30 -070021using std::string;
22using std::vector;
Yingdi Yu3b318c12013-10-15 17:54:00 -070023
Yingdi Yu0b0a7362014-08-05 16:31:30 -070024// user's own profile;
25const string INIT_SP_TABLE =
26 "CREATE TABLE IF NOT EXISTS "
27 " SelfProfile( "
28 " profile_type BLOB NOT NULL, "
29 " profile_value BLOB NOT NULL, "
30 " PRIMARY KEY (profile_type) "
31 " ); "
32 "CREATE INDEX sp_index ON SelfProfile(profile_type); ";
Yingdi Yu17032f82014-03-25 15:48:23 -070033
Yingdi Yu0b0a7362014-08-05 16:31:30 -070034// user's self endorse cert;
35const string INIT_SE_TABLE =
36 "CREATE TABLE IF NOT EXISTS "
37 " SelfEndorse( "
38 " identity BLOB NOT NULL UNIQUE, "
39 " endorse_data BLOB NOT NULL, "
40 " PRIMARY KEY (identity) "
41 " ); "
42 "CREATE INDEX se_index ON SelfEndorse(identity); ";
Yingdi Yu3b318c12013-10-15 17:54:00 -070043
Yingdi Yu0b0a7362014-08-05 16:31:30 -070044// contact's basic info
45const string INIT_CONTACT_TABLE =
46 "CREATE TABLE IF NOT EXISTS "
47 " Contact( "
48 " contact_namespace BLOB NOT NULL, "
49 " contact_alias BLOB NOT NULL, "
50 " contact_keyName BLOB NOT NULL, "
51 " contact_key BLOB NOT NULL, "
52 " notBefore INTEGER DEFAULT 0, "
53 " notAfter INTEGER DEFAULT 0, "
54 " is_introducer INTEGER DEFAULT 0, "
55 " PRIMARY KEY (contact_namespace) "
56 " ); "
57 "CREATE INDEX contact_index ON Contact(contact_namespace); ";
Yingdi Yud04ed1a2013-10-14 14:07:03 -070058
Yingdi Yu0b0a7362014-08-05 16:31:30 -070059// contact's trust scope;
60const string INIT_TS_TABLE =
61 "CREATE TABLE IF NOT EXISTS "
62 " TrustScope( "
63 " id INTEGER PRIMARY KEY AUTOINCREMENT, "
64 " contact_namespace BLOB NOT NULL, "
65 " trust_scope BLOB NOT NULL "
66 " ); "
67 "CREATE INDEX ts_index ON TrustScope(contact_namespace); ";
Yingdi Yud04ed1a2013-10-14 14:07:03 -070068
Yingdi Yu0b0a7362014-08-05 16:31:30 -070069// contact's profile
70const string INIT_CP_TABLE =
71 "CREATE TABLE IF NOT EXISTS "
72 " ContactProfile( "
73 " profile_identity BLOB NOT NULL, "
74 " profile_type BLOB NOT NULL, "
75 " profile_value BLOB NOT NULL, "
76 " endorse INTEGER NOT NULL, "
77 " PRIMARY KEY (profile_identity, profile_type) "
78 " ); "
79 "CREATE INDEX cp_index ON ContactProfile(profile_identity); ";
Yingdi Yub2e747d2013-11-05 23:06:43 -080080
Yingdi Yu0b0a7362014-08-05 16:31:30 -070081// user's endorsement on contacts
82const string INIT_PE_TABLE =
83 "CREATE TABLE IF NOT EXISTS "
84 " ProfileEndorse( "
85 " identity BLOB NOT NULL UNIQUE, "
86 " endorse_data BLOB NOT NULL, "
87 " PRIMARY KEY (identity) "
88 " ); "
89 "CREATE INDEX pe_index ON ProfileEndorse(identity); ";
Yingdi Yub2e747d2013-11-05 23:06:43 -080090
Yingdi Yu0b0a7362014-08-05 16:31:30 -070091// contact's endorsements on the user
92const string INIT_CE_TABLE =
93 "CREATE TABLE IF NOT EXISTS "
94 " CollectEndorse( "
95 " endorser BLOB NOT NULL, "
96 " endorse_name BLOB NOT NULL, "
97 " endorse_data BLOB NOT NULL, "
98 " PRIMARY KEY (endorser) "
99 " ); ";
Yingdi Yub2e747d2013-11-05 23:06:43 -0800100
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700101// dns data;
102const string INIT_DD_TABLE =
103 "CREATE TABLE IF NOT EXISTS "
104 " DnsData( "
105 " dns_name BLOB NOT NULL, "
106 " dns_type BLOB NOT NULL, "
107 " data_name BLOB NOT NULL, "
108 " dns_value BLOB NOT NULL, "
109 " PRIMARY KEY (dns_name, dns_type) "
110 " ); "
111 "CREATE INDEX dd_index ON DnsData(dns_name, dns_type); "
112 "CREATE INDEX dd_index2 ON DnsData(data_name); ";
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700113
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700114/**
115 * A utility function to call the normal sqlite3_bind_text where the value and length are
116 * value.c_str() and value.size().
117 */
118static int
119sqlite3_bind_string(sqlite3_stmt* statement,
120 int index,
121 const string& value,
122 void(*destructor)(void*))
123{
124 return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
125}
126
127/**
128 * A utility function to call the normal sqlite3_bind_blob where the value and length are
129 * block.wire() and block.size().
130 */
131static int
132sqlite3_bind_block(sqlite3_stmt* statement,
133 int index,
134 const Block& block,
135 void(*destructor)(void*))
136{
137 return sqlite3_bind_blob(statement, index, block.wire(), block.size(), destructor);
138}
139
140/**
141 * A utility function to generate string by calling the normal sqlite3_column_text.
142 */
143static string
144sqlite3_column_string(sqlite3_stmt* statement, int column)
145{
146 return string(reinterpret_cast<const char*>(sqlite3_column_text(statement, column)),
147 sqlite3_column_bytes(statement, column));
148}
149
150/**
151 * A utility function to generate block by calling the normal sqlite3_column_text.
152 */
153static Block
154sqlite3_column_block(sqlite3_stmt* statement, int column)
155{
Varun Patil3d850902020-11-23 12:19:14 +0530156 return Block(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(statement, column)),
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700157 sqlite3_column_bytes(statement, column));
158}
159
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800160
161ContactStorage::ContactStorage(const Name& identity)
162 : m_identity(identity)
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700163{
164 fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700165 fs::create_directories(chronosDir);
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700166
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700167 int res = sqlite3_open((chronosDir / getDBName()).c_str(), &m_db);
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700168 if (res != SQLITE_OK)
Varun Patila24bd3e2020-11-24 10:08:33 +0530169 NDN_THROW(Error("chronochat DB cannot be open/created"));
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700170
Yingdi Yufa4ce792014-02-06 18:09:22 -0800171 initializeTable("SelfProfile", INIT_SP_TABLE);
172 initializeTable("SelfEndorse", INIT_SE_TABLE);
173 initializeTable("Contact", INIT_CONTACT_TABLE);
174 initializeTable("TrustScope", INIT_TS_TABLE);
175 initializeTable("ContactProfile", INIT_CP_TABLE);
176 initializeTable("ProfileEndorse", INIT_PE_TABLE);
177 initializeTable("CollectEndorse", INIT_CE_TABLE);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800178 initializeTable("DnsData", INIT_DD_TABLE);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700179
Yingdi Yu3b318c12013-10-15 17:54:00 -0700180}
181
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700182string
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800183ContactStorage::getDBName()
184{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700185 string dbName("chronos-");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800186
Yingdi Yu17032f82014-03-25 15:48:23 -0700187 std::stringstream ss;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800188 {
189 using namespace CryptoPP;
190
191 SHA256 hash;
192 StringSource(m_identity.wireEncode().wire(), m_identity.wireEncode().size(), true,
193 new HashFilter(hash, new HexEncoder(new FileSink(ss), false)));
194 }
195 dbName.append(ss.str()).append(".db");
196
197 return dbName;
198}
199
Yingdi Yu3b318c12013-10-15 17:54:00 -0700200void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700201ContactStorage::initializeTable(const string& tableName, const string& sqlCreateStmt)
Yingdi Yu3b318c12013-10-15 17:54:00 -0700202{
Yingdi Yufa4ce792014-02-06 18:09:22 -0800203 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700204 sqlite3_prepare_v2(m_db,
205 "SELECT name FROM sqlite_master WHERE type='table' And name=?",
206 -1, &stmt, 0);
207 sqlite3_bind_string(stmt, 1, tableName, SQLITE_TRANSIENT);
208 int res = sqlite3_step(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800209
210 bool tableExist = false;
211 if (res == SQLITE_ROW)
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700212 tableExist = true;
213 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800214
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700215 if (!tableExist) {
216 char *errmsg = 0;
Varun Patila24bd3e2020-11-24 10:08:33 +0530217 res = sqlite3_exec(m_db, sqlCreateStmt.c_str (), nullptr, nullptr, &errmsg);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700218 if (res != SQLITE_OK && errmsg != 0)
Varun Patila24bd3e2020-11-24 10:08:33 +0530219 NDN_THROW(Error("Init \"error\" in " + tableName));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700220 }
Yingdi Yu3b318c12013-10-15 17:54:00 -0700221}
222
Yingdi Yu76dd8002013-12-24 11:16:32 +0800223shared_ptr<Profile>
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800224ContactStorage::getSelfProfile()
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700225{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800226 shared_ptr<Profile> profile = make_shared<Profile>(m_identity);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700227 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700228 sqlite3_prepare_v2(m_db, "SELECT profile_type, profile_value FROM SelfProfile", -1, &stmt, 0);
Yingdi Yu2ac40fb2013-10-21 13:38:38 -0700229
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700230 while (sqlite3_step(stmt) == SQLITE_ROW) {
231 string profileType = sqlite3_column_string(stmt, 0);
232 string profileValue = sqlite3_column_string (stmt, 1);
233 (*profile)[profileType] = profileValue;
234 }
Yingdi Yu72781e52013-11-06 23:00:21 -0800235 sqlite3_finalize(stmt);
236
Yingdi Yu3b318c12013-10-15 17:54:00 -0700237 return profile;
238}
Yingdi Yuae8217c2013-11-09 00:03:26 -0800239
Yingdi Yufa4ce792014-02-06 18:09:22 -0800240void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800241ContactStorage::addSelfEndorseCertificate(const EndorseCertificate& newEndorseCertificate)
Yingdi Yufa4ce792014-02-06 18:09:22 -0800242{
Yingdi Yufa4ce792014-02-06 18:09:22 -0800243 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700244 sqlite3_prepare_v2(m_db,
245 "INSERT OR REPLACE INTO SelfEndorse (identity, endorse_data) values (?, ?)",
246 -1, &stmt, 0);
247 sqlite3_bind_string(stmt, 1, m_identity.toUri(), SQLITE_TRANSIENT);
248 sqlite3_bind_block(stmt, 2, newEndorseCertificate.wireEncode(), SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700249 sqlite3_step(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800250
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700251 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800252}
253
Varun Patil3d850902020-11-23 12:19:14 +0530254shared_ptr<EndorseCertificate>
255ContactStorage::getSelfEndorseCertificate()
256{
257 shared_ptr<EndorseCertificate> cert;
258
259 sqlite3_stmt *stmt;
260 sqlite3_prepare_v2(m_db,
261 "SELECT endorse_data FROM SelfEndorse where identity=?",
262 -1, &stmt, 0);
263 sqlite3_bind_string(stmt, 1, m_identity.toUri(), SQLITE_TRANSIENT);
264
265 if (sqlite3_step(stmt) == SQLITE_ROW) {
266 cert = make_shared<EndorseCertificate>();
267 cert->wireDecode(sqlite3_column_block(stmt, 0));
268 }
269
270 sqlite3_finalize(stmt);
271
272 return cert;
273}
274
Yingdi Yufa4ce792014-02-06 18:09:22 -0800275void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700276ContactStorage::addEndorseCertificate(const EndorseCertificate& endorseCertificate,
277 const Name& identity)
Yingdi Yufa4ce792014-02-06 18:09:22 -0800278{
Yingdi Yufa4ce792014-02-06 18:09:22 -0800279 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700280 sqlite3_prepare_v2(m_db,
281 "INSERT OR REPLACE INTO ProfileEndorse \
282 (identity, endorse_data) values (?, ?)",
283 -1, &stmt, 0);
284 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
285 sqlite3_bind_block(stmt, 2, endorseCertificate.wireEncode(), SQLITE_TRANSIENT);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800286 sqlite3_step(stmt);
287
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700288 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800289}
290
291void
292ContactStorage::updateCollectEndorse(const EndorseCertificate& endorseCertificate)
293{
294 Name endorserName = endorseCertificate.getSigner();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800295 Name certName = endorseCertificate.getName();
Yingdi Yufa4ce792014-02-06 18:09:22 -0800296
297 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700298 sqlite3_prepare_v2(m_db,
299 "INSERT OR REPLACE INTO CollectEndorse \
300 (endorser, endorse_name, endorse_data) \
Varun Patil3d850902020-11-23 12:19:14 +0530301 VALUES (?, ?, ?)",
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700302 -1, &stmt, 0);
303 sqlite3_bind_string(stmt, 1, endorserName.toUri(), SQLITE_TRANSIENT);
304 sqlite3_bind_string(stmt, 2, certName.toUri(), SQLITE_TRANSIENT);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700305 sqlite3_bind_block(stmt, 3, endorseCertificate.wireEncode(), SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700306 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700307 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800308 return;
309}
310
311void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800312ContactStorage::getCollectEndorse(EndorseCollection& endorseCollection)
Yingdi Yufa4ce792014-02-06 18:09:22 -0800313{
314 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700315 sqlite3_prepare_v2(m_db, "SELECT endorse_name, endorse_data FROM CollectEndorse", -1, &stmt, 0);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800316
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700317 while (sqlite3_step(stmt) == SQLITE_ROW) {
318 string certName = sqlite3_column_string(stmt, 0);
319 std::stringstream ss;
Yingdi Yufa4ce792014-02-06 18:09:22 -0800320 {
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700321 using namespace CryptoPP;
322 SHA256 hash;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800323
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700324 StringSource(sqlite3_column_text(stmt, 1), sqlite3_column_bytes (stmt, 1), true,
325 new HashFilter(hash, new FileSink(ss)));
Yingdi Yufa4ce792014-02-06 18:09:22 -0800326 }
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800327 endorseCollection.addCollectionEntry(Name(certName), ss.str());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700328 }
Yingdi Yufa4ce792014-02-06 18:09:22 -0800329
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700330 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800331}
332
Varun Patil3d850902020-11-23 12:19:14 +0530333shared_ptr<EndorseCertificate>
334ContactStorage::getCollectEndorseByName(const Name& name)
335{
336 shared_ptr<EndorseCertificate> cert;
337
338 sqlite3_stmt *stmt;
339 sqlite3_prepare_v2(m_db,
340 "SELECT endorse_name, endorse_data FROM CollectEndorse where endorse_name=?",
341 -1, &stmt, 0);
342 sqlite3_bind_string(stmt, 1, name.toUri(), SQLITE_TRANSIENT);
343
344 if (sqlite3_step(stmt) == SQLITE_ROW) {
345 cert = make_shared<EndorseCertificate>();
346 cert->wireDecode(sqlite3_column_block(stmt, 1));
347 }
348
349 sqlite3_finalize(stmt);
350
351 return cert;
352}
353
Yingdi Yufa4ce792014-02-06 18:09:22 -0800354void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700355ContactStorage::getEndorseList(const Name& identity, vector<string>& endorseList)
Yingdi Yufa4ce792014-02-06 18:09:22 -0800356{
357 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700358 sqlite3_prepare_v2(m_db,
359 "SELECT profile_type FROM ContactProfile \
360 WHERE profile_identity=? AND endorse=1 ORDER BY profile_type",
361 -1, &stmt, 0);
362 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800363
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700364 while (sqlite3_step(stmt) == SQLITE_ROW) {
365 string profileType = sqlite3_column_string(stmt, 0);
366 endorseList.push_back(profileType);
367 }
368 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800369}
370
371
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700372void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800373ContactStorage::removeContact(const Name& identityName)
Yingdi Yuae8217c2013-11-09 00:03:26 -0800374{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700375 string identity = identityName.toUri();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700376
377 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700378 sqlite3_prepare_v2(m_db, "DELETE FROM Contact WHERE contact_namespace=?", -1, &stmt, 0);
379 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700380 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700381 sqlite3_finalize(stmt);
Yingdi Yuae8217c2013-11-09 00:03:26 -0800382
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700383 sqlite3_prepare_v2(m_db, "DELETE FROM ContactProfile WHERE profile_identity=?", -1, &stmt, 0);
384 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700385 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700386 sqlite3_finalize(stmt);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700387
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700388 sqlite3_prepare_v2(m_db, "DELETE FROM TrustScope WHERE contact_namespace=?", -1, &stmt, 0);
389 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700390 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700391 sqlite3_finalize(stmt);
Yingdi Yuae8217c2013-11-09 00:03:26 -0800392}
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700393
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700394void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800395ContactStorage::addContact(const Contact& contact)
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700396{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700397 if (doesContactExist(contact.getNameSpace()))
Varun Patila24bd3e2020-11-24 10:08:33 +0530398 NDN_THROW(Error("Normal Contact has already existed"));
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700399
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700400 string identity = contact.getNameSpace().toUri();
Yingdi Yu71c01872013-11-03 16:22:05 -0800401 bool isIntroducer = contact.isIntroducer();
402
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700403 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700404 sqlite3_prepare_v2(m_db,
405 "INSERT INTO Contact (contact_namespace, contact_alias, contact_keyName, \
406 contact_key, notBefore, notAfter, is_introducer) \
407 values (?, ?, ?, ?, ?, ?, ?)",
408 -1, &stmt, 0);
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700409
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700410 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
411 sqlite3_bind_string(stmt, 2, contact.getAlias(), SQLITE_TRANSIENT);
412 sqlite3_bind_string(stmt, 3, contact.getPublicKeyName().toUri(), SQLITE_TRANSIENT);
413 sqlite3_bind_text(stmt, 4,
Varun Patil3d850902020-11-23 12:19:14 +0530414 reinterpret_cast<const char*>(contact.getPublicKey().data()),
415 contact.getPublicKey().size(), SQLITE_TRANSIENT);
Yingdi Yua7876722014-03-25 14:46:55 -0700416 sqlite3_bind_int64(stmt, 5, time::toUnixTimestamp(contact.getNotBefore()).count());
417 sqlite3_bind_int64(stmt, 6, time::toUnixTimestamp(contact.getNotAfter()).count());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800418 sqlite3_bind_int(stmt, 7, (isIntroducer ? 1 : 0));
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700419
Yingdi Yu1cc45d92015-02-09 14:19:54 -0800420 sqlite3_step(stmt);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800421
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700422 sqlite3_finalize(stmt);
Yingdi Yu71c01872013-11-03 16:22:05 -0800423
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800424 const Profile& profile = contact.getProfile();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700425 for (Profile::const_iterator it = profile.begin(); it != profile.end(); it++) {
426 sqlite3_prepare_v2(m_db,
427 "INSERT INTO ContactProfile \
428 (profile_identity, profile_type, profile_value, endorse) \
429 values (?, ?, ?, 0)",
430 -1, &stmt, 0);
431 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
432 sqlite3_bind_string(stmt, 2, it->first, SQLITE_TRANSIENT);
433 sqlite3_bind_string(stmt, 3, it->second, SQLITE_TRANSIENT);
Yingdi Yu1cc45d92015-02-09 14:19:54 -0800434 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700435 sqlite3_finalize(stmt);
436 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800437
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700438 if (isIntroducer) {
439 Contact::const_iterator it = contact.trustScopeBegin();
440 Contact::const_iterator end = contact.trustScopeEnd();
441
442 while (it != end) {
443 sqlite3_prepare_v2(m_db,
444 "INSERT INTO TrustScope (contact_namespace, trust_scope) values (?, ?)",
445 -1, &stmt, 0);
446 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
447 sqlite3_bind_string(stmt, 2, it->first.toUri(), SQLITE_TRANSIENT);
Yingdi Yu1cc45d92015-02-09 14:19:54 -0800448 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700449 sqlite3_finalize(stmt);
450 it++;
Yingdi Yub2e747d2013-11-05 23:06:43 -0800451 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700452 }
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700453}
454
Yingdi Yufa4ce792014-02-06 18:09:22 -0800455
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800456shared_ptr<Contact>
457ContactStorage::getContact(const Name& identity) const
Yingdi Yufa4ce792014-02-06 18:09:22 -0800458{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800459 shared_ptr<Contact> contact;
460 Profile profile;
461
Yingdi Yufa4ce792014-02-06 18:09:22 -0800462 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700463 sqlite3_prepare_v2(m_db,
464 "SELECT contact_alias, contact_keyName, contact_key, notBefore, notAfter, \
465 is_introducer FROM Contact where contact_namespace=?",
466 -1, &stmt, 0);
467 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800468
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700469 if (sqlite3_step(stmt) == SQLITE_ROW) {
470 string alias = sqlite3_column_string(stmt, 0);
471 string keyName = sqlite3_column_string(stmt, 1);
Varun Patil3d850902020-11-23 12:19:14 +0530472 ndn::Buffer key(sqlite3_column_text(stmt, 2), sqlite3_column_bytes (stmt, 2));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700473 time::system_clock::TimePoint notBefore =
474 time::fromUnixTimestamp(time::milliseconds(sqlite3_column_int64 (stmt, 3)));
475 time::system_clock::TimePoint notAfter =
476 time::fromUnixTimestamp(time::milliseconds(sqlite3_column_int64 (stmt, 4)));
477 int isIntroducer = sqlite3_column_int (stmt, 5);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800478
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700479 contact = make_shared<Contact>(identity, alias, Name(keyName),
480 notBefore, notAfter, key, isIntroducer);
481 }
482 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800483
Varun Patil3d850902020-11-23 12:19:14 +0530484 if (!static_cast<bool>(contact))
485 return contact;
486
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700487 sqlite3_prepare_v2(m_db,
488 "SELECT profile_type, profile_value FROM ContactProfile \
489 where profile_identity=?",
490 -1, &stmt, 0);
491 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700492
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700493 while (sqlite3_step(stmt) == SQLITE_ROW) {
494 string type = sqlite3_column_string(stmt, 0);
495 string value = sqlite3_column_string(stmt, 1);
496 profile[type] = value;
497 }
498 sqlite3_finalize(stmt);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800499 contact->setProfile(profile);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800500
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700501 if (contact->isIntroducer()) {
502 sqlite3_prepare_v2(m_db,
503 "SELECT trust_scope FROM TrustScope WHERE contact_namespace=?",
504 -1, &stmt, 0);
505 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800506
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700507 while (sqlite3_step(stmt) == SQLITE_ROW) {
508 Name scope(sqlite3_column_string(stmt, 0));
509 contact->addTrustScope(scope);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800510 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700511 sqlite3_finalize(stmt);
512 }
Yingdi Yufa4ce792014-02-06 18:09:22 -0800513
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800514 return contact;
Yingdi Yufa4ce792014-02-06 18:09:22 -0800515}
516
517
Yingdi Yub2e747d2013-11-05 23:06:43 -0800518void
Yingdi Yufa4ce792014-02-06 18:09:22 -0800519ContactStorage::updateIsIntroducer(const Name& identity, bool isIntroducer)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800520{
521 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700522 sqlite3_prepare_v2(m_db, "UPDATE Contact SET is_introducer=? WHERE contact_namespace=?",
523 -1, &stmt, 0);
Yingdi Yub2e747d2013-11-05 23:06:43 -0800524 sqlite3_bind_int(stmt, 1, (isIntroducer ? 1 : 0));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700525 sqlite3_bind_string(stmt, 2, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700526 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700527 sqlite3_finalize(stmt);
Yingdi Yub2e747d2013-11-05 23:06:43 -0800528 return;
529}
530
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700531void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700532ContactStorage::updateAlias(const Name& identity, const string& alias)
Yingdi Yu2ac40fb2013-10-21 13:38:38 -0700533{
Yingdi Yu71c01872013-11-03 16:22:05 -0800534 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700535 sqlite3_prepare_v2(m_db, "UPDATE Contact SET contact_alias=? WHERE contact_namespace=?",
536 -1, &stmt, 0);
537 sqlite3_bind_string(stmt, 1, alias, SQLITE_TRANSIENT);
538 sqlite3_bind_string(stmt, 2, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700539 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700540 sqlite3_finalize(stmt);
Yingdi Yu71c01872013-11-03 16:22:05 -0800541 return;
Yingdi Yu2ac40fb2013-10-21 13:38:38 -0700542}
543
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700544bool
Yingdi Yu71c01872013-11-03 16:22:05 -0800545ContactStorage::doesContactExist(const Name& name)
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700546{
547 bool result = false;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700548
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700549 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700550 sqlite3_prepare_v2(m_db, "SELECT count(*) FROM Contact WHERE contact_namespace=?", -1, &stmt, 0);
551 sqlite3_bind_string(stmt, 1, name.toUri(), SQLITE_TRANSIENT);
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700552
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700553 int res = sqlite3_step(stmt);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700554
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700555 if (res == SQLITE_ROW) {
556 int countAll = sqlite3_column_int (stmt, 0);
557 if (countAll > 0)
558 result = true;
559 }
560
561 sqlite3_finalize(stmt);
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700562 return result;
563}
564
Yingdi Yu76dd8002013-12-24 11:16:32 +0800565void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700566ContactStorage::getAllContacts(vector<shared_ptr<Contact> >& contacts) const
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700567{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700568 vector<Name> contactNames;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800569
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700570 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700571 sqlite3_prepare_v2(m_db, "SELECT contact_namespace FROM Contact", -1, &stmt, 0);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700572
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700573 while (sqlite3_step(stmt) == SQLITE_ROW) {
574 string identity = sqlite3_column_string(stmt, 0);
575 contactNames.push_back(Name(identity));
576 }
577 sqlite3_finalize(stmt);
Yingdi Yu71c01872013-11-03 16:22:05 -0800578
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700579 for (vector<Name>::iterator it = contactNames.begin(); it != contactNames.end(); it++) {
580 shared_ptr<Contact> contact = getContact(*it);
581 if (static_cast<bool>(contact))
582 contacts.push_back(contact);
583 }
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700584}
Yingdi Yu3b318c12013-10-15 17:54:00 -0700585
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800586void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700587ContactStorage::updateDnsData(const Block& data, const string& name,
588 const string& type, const string& dataName)
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700589{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800590 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700591 sqlite3_prepare_v2(m_db,
592 "INSERT OR REPLACE INTO DnsData (dns_name, dns_type, dns_value, data_name) \
593 VALUES (?, ?, ?, ?)",
594 -1, &stmt, 0);
595 sqlite3_bind_string(stmt, 1, name, SQLITE_TRANSIENT);
596 sqlite3_bind_string(stmt, 2, type, SQLITE_TRANSIENT);
597 sqlite3_bind_block(stmt, 3, data, SQLITE_TRANSIENT);
598 sqlite3_bind_string(stmt, 4, dataName, SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700599 sqlite3_step(stmt);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800600
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800601 sqlite3_finalize(stmt);
602}
603
604shared_ptr<Data>
605ContactStorage::getDnsData(const Name& dataName)
606{
607 shared_ptr<Data> data;
608
609 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700610 sqlite3_prepare_v2(m_db, "SELECT dns_value FROM DnsData where data_name=?", -1, &stmt, 0);
611 sqlite3_bind_string(stmt, 1, dataName.toUri(), SQLITE_TRANSIENT);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700612
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700613 if (sqlite3_step(stmt) == SQLITE_ROW) {
614 data = make_shared<Data>();
615 data->wireDecode(sqlite3_column_block(stmt, 0));
616 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800617 sqlite3_finalize(stmt);
618
619 return data;
620}
621
622shared_ptr<Data>
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700623ContactStorage::getDnsData(const string& name, const string& type)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800624{
625 shared_ptr<Data> data;
626
627 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700628 sqlite3_prepare_v2(m_db, "SELECT dns_value FROM DnsData where dns_name=? and dns_type=?",
629 -1, &stmt, 0);
630 sqlite3_bind_string(stmt, 1, name, SQLITE_TRANSIENT);
631 sqlite3_bind_string(stmt, 2, type, SQLITE_TRANSIENT);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700632
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700633 if (sqlite3_step(stmt) == SQLITE_ROW) {
634 data = make_shared<Data>();
635 data->wireDecode(sqlite3_column_block(stmt, 0));
636 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800637 sqlite3_finalize(stmt);
638
639 return data;
640}
641
Yingdi Yueb692ac2015-02-10 18:46:18 -0800642} // namespace chronochat