IBR-DTNSuite  0.12
SQLiteDatabase.h
Go to the documentation of this file.
1 /*
2  * SQLiteDatabase.h
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #ifndef SQLITEDATABASE_H_
23 #define SQLITEDATABASE_H_
24 
26 #include "storage/BundleSeeker.h"
27 #include "storage/BundleSelector.h"
28 #include <ibrdtn/data/EID.h>
29 #include <ibrdtn/data/MetaBundle.h>
30 #include <ibrcommon/data/File.h>
31 #include <map>
32 #include <set>
33 #include <list>
34 #include <sqlite3.h>
35 
36 namespace dtn
37 {
38  namespace storage
39  {
41  {
42  friend class SQLiteBundleSet;
43 
44  enum SQL_TABLES
45  {
46  SQL_TABLE_BUNDLE = 0,
47  SQL_TABLE_BLOCK = 1,
48  SQL_TABLE_ROUTING = 2,
49  SQL_TABLE_BUNDLE_ROUTING_INFO = 3,
50  SQL_TABLE_NODE_ROUTING_INFO = 4,
51  SQL_TABLE_PROPERTIES = 5,
52  SQL_TABLE_BUNDLE_SET = 6,
53  SQL_TABLE_BUNDLE_SET_NAME = 7,
54  SQL_TABLE_END = 8
55  };
56 
57  // enum of all possible statements
58  enum STORAGE_STMT
59  {
60  BUNDLE_GET_ITERATOR,
61  BUNDLE_GET_FILTER,
62  BUNDLE_GET_ID,
63  BUNDLE_GET_LENGTH_ID,
64  GET_DISTINCT_DESTINATIONS,
65 
66  EXPIRE_BUNDLES,
67  EXPIRE_BUNDLE_FILENAMES,
68  EXPIRE_BUNDLE_DELETE,
69  EXPIRE_NEXT_TIMESTAMP,
70 
71  EMPTY_CHECK,
72  COUNT_ENTRIES,
73 
74  BUNDLE_DELETE,
75  BUNDLE_CLEAR,
76  BUNDLE_STORE,
77  BUNDLE_UPDATE_CUSTODIAN,
78 
79  PROCFLAGS_SET,
80 
81  BLOCK_GET_ID,
82  BLOCK_GET,
83  BLOCK_CLEAR,
84  BLOCK_STORE,
85 
86  BUNDLE_SET_ADD,
87  BUNDLE_SET_CLEAR,
88  BUNDLE_SET_GET,
89  BUNDLE_SET_GET_EXPIRED,
90  BUNDLE_SET_EXPIRE,
91  BUNDLE_SET_GET_ALL,
92  BUNDLE_SET_COUNT,
93  BUNDLE_SET_EXPIRE_NEXT_TIMESTAMP,
94  BUNDLE_SET_COPY,
95 
96  BUNDLE_SET_NAME_ADD,
97  BUNDLE_SET_NAME_GET_ID,
98  BUNDLE_SET_NAME_REMOVE,
99 
100  VACUUM,
101  SQL_QUERIES_END
102  };
103 
104  static const int DBSCHEMA_FRESH_VERSION;
105  static const int DBSCHEMA_VERSION;
106  static const std::string QUERY_SCHEMAVERSION;
107  static const std::string SET_SCHEMAVERSION;
108 
109  static const std::string _select_names[3];
110 
111  static const std::string _where_filter[2];
112 
113  static const std::string _tables[SQL_TABLE_END];
114 
115  // array of sql queries
116  static const std::string _sql_queries[SQL_QUERIES_END];
117 
118  // array of the db structure as sql
119  static const int DB_STRUCTURE_END = 15;
120  static const std::string _db_structure[DB_STRUCTURE_END];
121 
122  static const std::string TAG;
123 
124  public:
126  {
128  };
129 
131  {
132  public:
133  virtual ~DatabaseListener() = 0;
134  virtual void eventBundleExpired(const dtn::data::BundleID&, const dtn::data::Length) throw () = 0;
135  virtual void iterateDatabase(const dtn::data::MetaBundle&, const dtn::data::Length) = 0;
136  };
137 
139  {
140  public:
141  SQLBundleQuery();
142  virtual ~SQLBundleQuery() = 0;
143 
148  virtual const std::string getWhere() const throw () = 0;
149 
156  virtual int bind(sqlite3_stmt*, int offset) const throw ()
157  {
158  return offset;
159  }
160  };
161 
163  {
164  public:
165  SQLiteQueryException(string what = "Unable to execute Querry.") throw() : Exception(what)
166  {
167  }
168  };
169 
170  class Statement
171  {
172  public:
173  Statement(sqlite3 *database, const std::string&);
174  ~Statement();
175 
176  sqlite3_stmt* operator*();
177  void prepare() throw (SQLiteQueryException);
178  void reset() throw ();
179  int step() throw (SQLiteQueryException);
180 
181  private:
182  sqlite3 *_database;
183  sqlite3_stmt *_st;
184  const std::string _query;
185  };
186 
187  typedef std::list<std::pair<int, const ibrcommon::File> > blocklist;
188  typedef std::pair<int, const ibrcommon::File> blocklist_entry;
189 
190  SQLiteDatabase(const ibrcommon::File &file, DatabaseListener &listener);
191  virtual ~SQLiteDatabase();
192 
196  void open() throw (SQLiteQueryException);
197 
202  void close();
203 
208  void expire(const dtn::data::Timestamp &timestamp) throw ();
209 
213  void vacuum() throw (SQLiteQueryException);
214 
220  void update(UPDATE_VALUES, const dtn::data::BundleID &id, const dtn::data::EID&) throw (SQLiteQueryException);
221 
227  dtn::data::Length remove(const dtn::data::BundleID &id) throw (SQLiteQueryException);
228 
232  virtual void get(const BundleSelector &cb, BundleResult &result) throw (NoBundleFoundException, BundleSelectorException);
233 
239  void get(const dtn::data::BundleID &id, dtn::data::MetaBundle &meta) const throw (SQLiteQueryException, NoBundleFoundException);
240 
246  void get(const dtn::data::BundleID &id, dtn::data::Bundle &bundle, blocklist &blocks) const throw (SQLiteQueryException, NoBundleFoundException);
247 
252  void store(const dtn::data::Bundle &bundle, const dtn::data::Length &size) throw (SQLiteQueryException);
253  void store(const dtn::data::BundleID &id, int index, const dtn::data::Block &block, const ibrcommon::File &file) throw (SQLiteQueryException);
254  void transaction() throw (SQLiteQueryException);
255  void rollback() throw (SQLiteQueryException);
256  void commit() throw (SQLiteQueryException);
257 
258  bool empty() const throw (SQLiteQueryException);
259 
260  dtn::data::Size count() const throw (SQLiteQueryException);
261 
262  void clear() throw (SQLiteQueryException);
263 
267  bool contains(const dtn::data::BundleID &id) throw (SQLiteDatabase::SQLiteQueryException);
268 
272  virtual const eid_set getDistinctDestinations() throw (SQLiteQueryException);
273 
277  void iterateAll() throw (SQLiteQueryException);
278 
279  /*** BEGIN: methods for unit-testing ***/
280 
285  void setFaulty(bool mode);
286 
287  /*** END: methods for unit-testing ***/
288 
289  private:
296  void get(Statement &st, dtn::data::MetaBundle &bundle, int offset = 0) const throw (SQLiteQueryException);
297 
304  void get(Statement &st, dtn::data::Bundle &bundle, const int offset = 0) const throw (SQLiteQueryException);
305 
313  void __get(const BundleSelector &cb, Statement &st, BundleResult &ret, size_t &items_added, const int bind_offset, const size_t offset, const size_t query_limit) const throw (SQLiteQueryException, NoBundleFoundException, BundleSelectorException);
314 
318  void update_expire_time() throw (SQLiteQueryException);
319 
324  void new_expire_time(const dtn::data::Timestamp &ttl) throw ();
325  void reset_expire_time() throw ();
326  const dtn::data::Timestamp& get_expire_time() const throw ();
327 
328  void set_bundleid(Statement &st, const dtn::data::BundleID &id, int offset = 0) const throw (SQLiteQueryException);
329 
333  int getVersion() throw (SQLiteQueryException);
334 
339  void setVersion(int version) throw (SQLiteQueryException);
340 
346  void doUpgrade(int oldVersion, int newVersion) throw (ibrcommon::Exception);
347 
348  ibrcommon::File _file;
349 
350  // holds the database handle
351  sqlite3 *_database;
352 
353  // next expiration
354  dtn::data::Timestamp _next_expiration;
355 
356  // listener for events on the database
357  DatabaseListener &_listener;
358 
359  bool _faulty;
360  };
361  } /* namespace storage */
362 } /* namespace dtn */
363 #endif /* SQLITEDATABASE_H_ */