blob: 29738bedda2d296626d2672d9ca3a38488479fae [file] [log] [blame]
Shock Jiang3c723182014-09-10 16:41:18 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014, Regents of the University of California.
4 *
5 * This file is part of NDNS (Named Data Networking Domain Name Service).
6 * See AUTHORS.md for complete list of NDNS authors and contributors.
7 *
8 * NDNS is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * NDNS, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
Shock Jiang4e0ab7c2014-09-11 16:23:21 -070020#ifndef NDNS_DB_MGR_HPP
21#define NDNS_DB_MGR_HPP
Shock Jiang3c723182014-09-10 16:41:18 -070022
23#include "config.hpp"
Shock Jiang4e0ab7c2014-09-11 16:23:21 -070024#include "zone.hpp"
Shock Jiangbcdef862014-10-07 14:13:55 -070025#include "rrset.hpp"
Shock Jiang3c723182014-09-10 16:41:18 -070026
27#include <ndn-cxx/common.hpp>
28#include <sqlite3.h>
29
30namespace ndn {
31namespace ndns {
32
Shock Jiang4e0ab7c2014-09-11 16:23:21 -070033#define DEFINE_ERROR(Name, Base) \
34class Name : public Base \
35{ \
36 public: \
37 explicit \
38 Name(const std::string& what) \
39 : Base(what) \
40 { \
41 } \
42};
43
Shock Jiang3c723182014-09-10 16:41:18 -070044/**
45 * @brief Database Manager, which provides some common DB functionalities
Shock Jiangbcdef862014-10-07 14:13:55 -070046 *
47 * @note Function naming here follows MongoDB
Shock Jiang3c723182014-09-10 16:41:18 -070048 */
49class DbMgr : noncopyable
50{
51public:
52 /**
53 * @brief The Database Status
54 */
55 enum DbStatus {
56 DB_CONNECTED,
57 DB_CLOSED,
58 DB_ERROR
59 };
60
Shock Jiang4e0ab7c2014-09-11 16:23:21 -070061 DEFINE_ERROR(Error, std::runtime_error);
62 DEFINE_ERROR(PrepareError, Error);
63 DEFINE_ERROR(ExecuteError, Error);
64
Shock Jiang3c723182014-09-10 16:41:18 -070065public:
66 /**
67 * @brief constructor
68 */
69 explicit
Shock Jiangbcdef862014-10-07 14:13:55 -070070 DbMgr(const std::string& dbFile = DEFAULT_CONFIG_PATH "/" "ndns.db");
Shock Jiang3c723182014-09-10 16:41:18 -070071
72 /**
73 * @brief destructor
74 */
75 ~DbMgr();
76
77 /**
78 * @brief connect to the database
79 */
80 void
81 open();
82
83 /**
84 * @brief close the database connection
85 */
86 void
87 close();
88
89 /**
90 * @brief get error message
91 *
92 * only valid when some db-related error happens,
93 * such as db file does not exist, wrong SQL, etc
94 */
95 const std::string&
96 getErr() const
97 {
98 return m_err;
99 }
100
101 /**
102 * @brief get Database connection status
103 */
104 DbStatus
105 getStatus() const
106 {
107 return m_status;
108 }
109
Shock Jiang4e0ab7c2014-09-11 16:23:21 -0700110public: // Zone manipulation
111 DEFINE_ERROR(ZoneError, Error);
112
113 /**
Shock Jiangbcdef862014-10-07 14:13:55 -0700114 * @brief insert the m_zone to the database, and set the zone's id.
115 * If the zone is already in the db, handle the exception without leaving it to upper level,
116 * meanwhile, set the zone's id too.
117 * @pre m_zone.getId() == 0
118 * @post m_zone.getId() > 0
119 */
120 void
121 insert(Zone& zone);
122
123 /**
Shock Jiang4e0ab7c2014-09-11 16:23:21 -0700124 * @brief lookup the zone by name, fill the m_id and m_ttl
125 * @post whatever the previous id is
126 * @return true if the record exist
127 */
128 bool
Shock Jiangbcdef862014-10-07 14:13:55 -0700129 find(Zone& zone);
Shock Jiang4e0ab7c2014-09-11 16:23:21 -0700130
131 /**
132 * @brief remove the zone
133 * @pre m_zone.getId() > 0
134 * @post m_zone.getId() == 0
135 */
136 void
137 remove(Zone& zone);
138
Shock Jiangbcdef862014-10-07 14:13:55 -0700139public: // Rrset manipulation
140 DEFINE_ERROR(RrsetError, Error);
141
Shock Jiang4e0ab7c2014-09-11 16:23:21 -0700142 /**
Shock Jiangbcdef862014-10-07 14:13:55 -0700143 * @brief add the rrset
144 * @pre m_rrset.getId() == 0
145 * @post m_rrset.getId() > 0
Shock Jiang4e0ab7c2014-09-11 16:23:21 -0700146 */
147 void
Shock Jiangbcdef862014-10-07 14:13:55 -0700148 insert(Rrset& rrset);
149
150 /**
151 * @brief get the data from db according to `m_zone`, `m_label`, `m_type`.
152 *
153 * If record exists, `m_ttl`, `m_version` and `m_data` is set
154 *
155 * @pre m_rrset.getZone().getId() > 0
156 * @post whatever the previous id is,
157 * m_rrset.getId() > 0 if record exists, otherwise m_rrset.getId() == 0
158 * @return true if the record exist
159 */
160 bool
161 find(Rrset& rrset);
162
163 /**
164 * @brief remove the rrset
165 * @pre m_rrset.getId() > 0
166 * @post m_rrset.getId() == 0
167 */
168 void
169 remove(Rrset& rrset);
170
171 /**
172 * @brief replace ttl, version, and Data with new values
173 * @pre m_rrset.getId() > 0
174 */
175 void
176 modify(Rrset& rrset);
Shock Jiang4e0ab7c2014-09-11 16:23:21 -0700177
Shock Jiang3c723182014-09-10 16:41:18 -0700178private:
179 /**
180 * @brief set error message
181 *
182 * only valid when some db-related error happens,
183 * such as db file does not exist, wrong SQL, etc
184 */
185 void
186 setErr(const std::string& err)
187 {
188 this->m_err = err;
189 }
190
191 /**
192 * @brief set Database connection status
193 */
194 void
195 setStatus(DbStatus status)
196 {
197 this->m_status = status;
198 }
199
200private:
201 std::string m_dbFile;
202 sqlite3* m_conn;
203
204 std::string m_err;
205 DbStatus m_status;
206};
207
208} // namespace ndns
209} // namespace ndn
210
Shock Jiang4e0ab7c2014-09-11 16:23:21 -0700211#endif // NDNS_DB_MGR_HPP