blob: c71789fa9bade2803b0dcedb7aaa056e75802f9c [file] [log] [blame]
Yingdi Yu783ce4b2013-10-18 17:04:19 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Yingdi Yu
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
9 */
10
11#include "dns-storage.h"
12#include "exception.h"
13
14#include <boost/filesystem.hpp>
15
16
17using namespace std;
18using namespace ndn;
19namespace fs = boost::filesystem;
20
21const string INIT_DD_TABLE = "\
22CREATE TABLE IF NOT EXISTS \n \
23 DnsData( \n \
24 dns_identity BLOB NOT NULL, \n \
25 dns_name BLOB NOT NULL, \n \
26 dns_type BLOB NOT NULL, \n \
27 data_name BLOB NOT NULL, \n \
28 dns_value BLOB NOT NULL, \n \
29 \
30 PRIMARY KEY (dns_identity, dns_name, dns_type) \n \
31 ); \
32CREATE INDEX dd_index ON DnsData(dns_identity, dns_name, dns_type); \n \
33CREATE INDEX dd_index2 ON DnsData(data_name); \n \
34";
35
36DnsStorage::DnsStorage()
37{
38 fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
39 fs::create_directories (chronosDir);
40
41 int res = sqlite3_open((chronosDir / "dns.db").c_str (), &m_db);
42 if (res != SQLITE_OK)
43 throw LnException("Chronos DNS DB cannot be open/created");
44
45 // Check if SelfProfile table exists
46 sqlite3_stmt *stmt;
47 sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='DnsData'", -1, &stmt, 0);
48 res = sqlite3_step (stmt);
49
50 bool ddTableExist = false;
51 if (res == SQLITE_ROW)
52 ddTableExist = true;
53 sqlite3_finalize (stmt);
54
55 if(!ddTableExist)
56 {
57 char *errmsg = 0;
58 res = sqlite3_exec (m_db, INIT_DD_TABLE.c_str (), NULL, NULL, &errmsg);
59 if (res != SQLITE_OK && errmsg != 0)
60 throw LnException("Init \"error\" in DnsData");
61 }
62}
63
64DnsStorage::~DnsStorage()
65{
66 sqlite3_close(m_db);
67}
68
69void
70DnsStorage::updateDnsData(const ndn::Blob& data, const std::string& identity, const std::string& name, const std::string& type, const string& dataName)
71{
72 sqlite3_stmt *stmt;
73 sqlite3_prepare_v2 (m_db, "SELECT data_name FROM DnsData where dns_identity=? and dns_name=? and dns_type=?", -1, &stmt, 0);
74 sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size(), SQLITE_TRANSIENT);
75 sqlite3_bind_text(stmt, 2, name.c_str(), name.size(), SQLITE_TRANSIENT);
76 sqlite3_bind_text(stmt, 3, type.c_str(), type.size(), SQLITE_TRANSIENT);
77
78 if(sqlite3_step (stmt) != SQLITE_ROW)
79 {
80 sqlite3_finalize(stmt);
81 sqlite3_prepare_v2 (m_db, "INSERT INTO DnsData (dns_identity, dns_name, dns_type, dns_value, data_name) VALUES (?, ?, ?, ?, ?)", -1, &stmt, 0);
82 sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size(), SQLITE_TRANSIENT);
83 sqlite3_bind_text(stmt, 2, name.c_str(), name.size(), SQLITE_TRANSIENT);
84 sqlite3_bind_text(stmt, 3, type.c_str(), type.size(), SQLITE_TRANSIENT);
85 sqlite3_bind_text(stmt, 4, data.buf(), data.size(), SQLITE_TRANSIENT);
86 sqlite3_bind_text(stmt, 5, dataName.c_str(), dataName.size(), SQLITE_TRANSIENT);
87 sqlite3_step(stmt);
88 sqlite3_finalize(stmt);
89 }
90 else
91 {
92 sqlite3_finalize(stmt);
93 sqlite3_prepare_v2 (m_db, "UPDATE DnsData SET dns_value=?, data_name=? WHERE dns_identity=? and dns_name=?, dns_type=?", -1, &stmt, 0);
94 sqlite3_bind_text(stmt, 1, data.buf(), data.size(), SQLITE_TRANSIENT);
95 sqlite3_bind_text(stmt, 2, dataName.c_str(), dataName.size(), SQLITE_TRANSIENT);
96 sqlite3_bind_text(stmt, 3, identity.c_str(), identity.size(), SQLITE_TRANSIENT);
97 sqlite3_bind_text(stmt, 4, name.c_str(), name.size(), SQLITE_TRANSIENT);
98 sqlite3_bind_text(stmt, 5, type.c_str(), type.size(), SQLITE_TRANSIENT);
99 sqlite3_step(stmt);
100 sqlite3_finalize(stmt);
101 }
102}
103
104void
105DnsStorage::updateDnsSelfProfileData(const Data& data, const Name& identity)
106{
107 string dnsIdentity = identity.toUri();
108 string dnsName("N/A");
109 string dnsType("PROFILE");
110 Ptr<Blob> dnsValue = data.encodeToWire();
111
112 updateDnsData(*dnsValue, dnsIdentity, dnsName, dnsType, data.getName().toUri());
113}
114
115void
116DnsStorage::updateDnsEndorseOthers(const Data& data, const Name& identity, const Name& endorsee)
117{
118 string dnsIdentity = identity.toUri();
119 string dnsName = endorsee.toUri();
120 string dnsType("ENORSEE");
121 Ptr<Blob> dnsValue = data.encodeToWire();
122
123 updateDnsData(*dnsValue, dnsIdentity, dnsName, dnsType, data.getName().toUri());
124}
125
126void
127DnsStorage::updateDnsOthersEndorse(const Data& data, const Name& identity, const Name& endorser)
128{
129 string dnsIdentity = identity.toUri();
130 string dnsName = endorser.toUri();
131 string dnsType("ENORSER");
132 Ptr<Blob> dnsValue = data.encodeToWire();
133
134 updateDnsData(*dnsValue, dnsIdentity, dnsName, dnsType, data.getName().toUri());
135}
136
137Ptr<Data>
138DnsStorage::getData(const Name& dataName)
139{
140 sqlite3_stmt *stmt;
141 sqlite3_prepare_v2 (m_db, "SELECT dns_value FROM DnsData where data_name=?", -1, &stmt, 0);
142 sqlite3_bind_text(stmt, 1, dataName.toUri().c_str(), dataName.toUri().size(), SQLITE_TRANSIENT);
143
144 if(sqlite3_step (stmt) == SQLITE_ROW)
145 {
146 Blob dnsDataBlob(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
147 boost::iostreams::stream
148 <boost::iostreams::array_source> is (dnsDataBlob.buf(), dnsDataBlob.size());
149 return Data::decodeFromWire(is);
150 }
151 return NULL;
152}