IBR-DTNSuite 0.6

daemon/src/core/SQLiteBundleStorage.h

Go to the documentation of this file.
00001 /*
00002  * SQLiteBundleStorage.h
00003  *
00004  *  Created on: 09.01.2010
00005  *      Author: Myrtus
00006  */
00007 
00008 
00009 #ifndef SQLITEBUNDLESTORAGE_H_
00010 #define SQLITEBUNDLESTORAGE_H_
00011 
00012 #include "BundleStorage.h"
00013 #include "Component.h"
00014 #include "EventReceiver.h"
00015 #include "core/BundleStorage.h"
00016 #include "core/EventReceiver.h"
00017 #include <ibrdtn/data/MetaBundle.h>
00018 
00019 #include <ibrcommon/thread/Thread.h>
00020 #include <ibrcommon/thread/Conditional.h>
00021 #include <ibrcommon/data/File.h>
00022 #include <ibrcommon/thread/Queue.h>
00023 
00024 #include <sqlite3.h>
00025 #include <string>
00026 #include <list>
00027 #include <set>
00028 
00029 //#define SQLITE_STORAGE_EXTENDED 1
00030 
00031 class SQLiteBundleStorageTest;
00032 
00033 namespace dtn
00034 {
00035         namespace core
00036         {
00037                 class SQLiteBundleStorage: public BundleStorage, public EventReceiver, public dtn::daemon::IndependentComponent, public ibrcommon::MutexInterface
00038                 {
00039                         enum SQL_TABLES
00040                         {
00041                                 SQL_TABLE_BUNDLE = 0,
00042                                 SQL_TABLE_BLOCK = 1,
00043                                 SQL_TABLE_ROUTING = 2,
00044                                 SQL_TABLE_BUNDLE_ROUTING_INFO = 3,
00045                                 SQL_TABLE_NODE_ROUTING_INFO = 4,
00046                                 SQL_TABLE_END = 5
00047                         };
00048 
00049                         // enum of all possible statements
00050                         enum STORAGE_STMT
00051                         {
00052                                 BUNDLE_GET_FILTER,
00053                                 BUNDLE_GET_ID,
00054                                 FRAGMENT_GET_ID,
00055                                 BUNDLE_GET_FRAGMENT,
00056 
00057                                 EXPIRE_BUNDLES,
00058                                 EXPIRE_BUNDLE_FILENAMES,
00059                                 EXPIRE_BUNDLE_DELETE,
00060                                 EXPIRE_NEXT_TIMESTAMP,
00061 
00062                                 EMPTY_CHECK,
00063                                 COUNT_ENTRIES,
00064 
00065                                 BUNDLE_DELETE,
00066                                 FRAGMENT_DELETE,
00067                                 BUNDLE_CLEAR,
00068                                 BUNDLE_STORE,
00069                                 BUNDLE_UPDATE_CUSTODIAN,
00070                                 FRAGMENT_UPDATE_CUSTODIAN,
00071 
00072                                 PROCFLAGS_SET,
00073 
00074                                 BLOCK_GET_ID,
00075                                 BLOCK_GET_ID_FRAGMENT,
00076                                 BLOCK_GET,
00077                                 BLOCK_GET_FRAGMENT,
00078                                 BLOCK_CLEAR,
00079                                 BLOCK_STORE,
00080 
00081 #ifdef SQLITE_STORAGE_EXTENDED
00082                                 ROUTING_GET,
00083                                 ROUTING_REMOVE,
00084                                 ROUTING_CLEAR,
00085                                 ROUTING_STORE,
00086 
00087                                 NODE_GET,
00088                                 NODE_REMOVE,
00089                                 NODE_CLEAR,
00090                                 NODE_STORE,
00091 
00092                                 INFO_GET,
00093                                 INFO_REMOVE,
00094                                 INFO_STORE,
00095 #endif
00096 
00097                                 VACUUM,
00098                                 SQL_QUERIES_END
00099                         };
00100 
00101                         static const std::string _tables[SQL_TABLE_END];
00102 
00103                         // array of sql queries
00104                         static const std::string _sql_queries[SQL_QUERIES_END];
00105 
00106                         // array of the db structure as sql
00107                         static const std::string _db_structure[10];
00108 
00109                 public:
00110                         friend class ::SQLiteBundleStorageTest;
00111 
00112                         class SQLBundleQuery
00113                         {
00114                         public:
00115                                 SQLBundleQuery();
00116                                 virtual ~SQLBundleQuery() = 0;
00117 
00122                                 virtual const std::string getWhere() const = 0;
00123 
00130                                 virtual size_t bind(sqlite3_stmt*, size_t offset) const
00131                                 {
00132                                         return offset;
00133                                 }
00134 
00138                                 sqlite3_stmt *_statement;
00139                         };
00140 
00141                         class SQLiteQueryException : public ibrcommon::Exception
00142                         {
00143                         public:
00144                                 SQLiteQueryException(string what = "Unable to execute Querry.") throw(): Exception(what)
00145                                 {
00146                                 }
00147                         };
00148 
00155                         SQLiteBundleStorage(const ibrcommon::File &path, const size_t &size);
00156 
00160                         virtual ~SQLiteBundleStorage();
00161 
00165                         void openDatabase(const ibrcommon::File &path);
00166 
00171                         void store(const dtn::data::Bundle &bundle);
00172 
00179                         dtn::data::Bundle get(const dtn::data::BundleID &id);
00180 
00184                         const std::list<dtn::data::MetaBundle> get(BundleFilterCallback &cb);
00185 
00186 #ifdef SQLITE_STORAGE_EXTENDED
00187 
00192                         void storeBundleRoutingInfo(const data::BundleID &BundleID, const int &key, const string &routingInfo);
00193 
00199                         void storeNodeRoutingInfo(const data::EID &nodel, const int &key, const std::string &routingInfo);
00200 
00206                         void storeRoutingInfo(const int &key, const std::string &routingInfo);
00207 
00212                         std::string getBundleRoutingInfo(const data::BundleID &bundleID, const int &key);
00213 
00219                         std::string getNodeRoutingInfo(const data::EID &eid, const int &key);
00220 
00226                         std::string getRoutingInfo(const int &key);
00227 
00232                         void removeBundleRoutingInfo(const data::BundleID &bundleID, const int &key);
00233 
00238                         void removeNodeRoutingInfo(const data::EID &eid, const int &key);
00239 
00244                         void removeRoutingInfo(const int &key);
00245 #endif
00246 
00252                         void remove(const dtn::data::BundleID &id);
00253 
00257                         void clear();
00258 
00262                         void clearAll();
00263 
00267                         bool empty();
00268 
00272                         unsigned int count();
00273 
00277                         void releaseCustody(const dtn::data::EID &custodian, const dtn::data::BundleID &id);
00278 
00279 #ifdef SQLITE_STORAGE_EXTENDED
00280 
00285                         void setPriority(const int priority,const dtn::data::BundleID &id);
00286 
00293                         list<data::Block> getBlock(const data::BundleID &bundleID,const char &blocktype);
00294 
00299                         int occupiedSpace();
00300 #endif
00301 
00306                         void raiseEvent(const Event *evt);
00307 
00311                         virtual void trylock() throw (ibrcommon::MutexException);
00312 
00316                         virtual void enter() throw (ibrcommon::MutexException);
00317 
00321                         virtual void leave() throw (ibrcommon::MutexException);
00322 
00323                 protected:
00324                         virtual void componentRun();
00325                         virtual void componentUp();
00326                         virtual void componentDown();
00327                         bool __cancellation();
00328 
00329                 private:
00330                         enum Position
00331                         {
00332                                 FIRST_FRAGMENT  = 0,
00333                                 LAST_FRAGMENT   = 1,
00334                                 BOTH_FRAGMENTS  = 2
00335                         };
00336 
00337                         class AutoResetLock
00338                         {
00339                         public:
00340                                 AutoResetLock(ibrcommon::Mutex &mutex, sqlite3_stmt *st);
00341                                 ~AutoResetLock();
00342 
00343                         private:
00344                                 ibrcommon::MutexLock _lock;
00345                                 sqlite3_stmt *_st;
00346                         };
00347 
00348                         class Task
00349                         {
00350                         public:
00351                                 virtual ~Task() {};
00352                                 virtual void run(SQLiteBundleStorage &storage) = 0;
00353                         };
00354 
00355                         class BlockingTask : public Task
00356                         {
00357                         public:
00358                                 BlockingTask() : _done(false), _abort(false) {};
00359                                 virtual ~BlockingTask() {};
00360                                 virtual void run(SQLiteBundleStorage &storage) = 0;
00361 
00365                                 void wait()
00366                                 {
00367                                         ibrcommon::MutexLock l(_cond);
00368                                         while (!_done && !_abort) _cond.wait();
00369 
00370                                         if (_abort) throw ibrcommon::Exception("Task aborted");
00371                                 }
00372 
00373                                 void abort()
00374                                 {
00375                                         ibrcommon::MutexLock l(_cond);
00376                                         _abort = true;
00377                                         _cond.signal(true);
00378                                 }
00379 
00380                                 void done()
00381                                 {
00382                                         ibrcommon::MutexLock l(_cond);
00383                                         _done = true;
00384                                         _cond.signal(true);
00385                                 }
00386 
00387                         private:
00388                                 ibrcommon::Conditional _cond;
00389                                 bool _done;
00390                                 bool _abort;
00391                         };
00392 
00393                         class TaskRemove : public Task
00394                         {
00395                         public:
00396                                 TaskRemove(const dtn::data::BundleID &id)
00397                                  : _id(id) { };
00398 
00399                                 virtual ~TaskRemove() {};
00400                                 virtual void run(SQLiteBundleStorage &storage);
00401 
00402                         private:
00403                                 const dtn::data::BundleID _id;
00404                         };
00405 
00406                         class TaskIdle : public Task
00407                         {
00408                         public:
00409                                 TaskIdle() { };
00410 
00411                                 virtual ~TaskIdle() {};
00412                                 virtual void run(SQLiteBundleStorage &storage);
00413 
00414                                 static ibrcommon::Mutex _mutex;
00415                                 static bool _idle;
00416                         };
00417 
00418                         class TaskExpire : public Task
00419                         {
00420                         public:
00421                                 TaskExpire(size_t timestamp)
00422                                 : _timestamp(timestamp) { };
00423 
00424                                 virtual ~TaskExpire() {};
00425                                 virtual void run(SQLiteBundleStorage &storage);
00426 
00427                         private:
00428                                 size_t _timestamp;
00429                         };
00430 
00436                         dtn::data::MetaBundle get_meta(const dtn::data::BundleID &id);
00437 
00438                         void get(sqlite3_stmt *st, dtn::data::MetaBundle &bundle, size_t offset = 0);
00439                         void get(sqlite3_stmt *st, dtn::data::Bundle &bundle, size_t offset = 0);
00440 
00441 #ifdef SQLITE_STORAGE_EXTENDED
00442 
00446                         void storeFragment(const dtn::data::Bundle &bundle);
00447 #endif
00448 
00454                         sqlite3_stmt* prepare(const std::string &sqlquery);
00455 
00463                         int prepareBundle(list<std::string> &filenames, dtn::data::Bundle &bundle);
00464 
00470                         int store_blocks(const data::Bundle &Bundle);
00471 
00477                         void get_blocks(dtn::data::Bundle &bundle, const dtn::data::BundleID &id);
00478 
00482                         void check_consistency();
00483 
00484                         void check_fragments(set<string> &payloadFiles);
00485 
00486                         void check_bundles(set<string> &blockFiles);
00487 
00491                         void update_expire_time();
00492 
00496                         void update_custodian(const dtn::data::BundleID &b, const dtn::data::EID &custodian);
00497 
00502                         void new_expire_time(size_t ttl);
00503                         void reset_expire_time();
00504                         size_t get_expire_time();
00505 
00506                         void set_bundleid(sqlite3_stmt *st, const dtn::data::BundleID &id, size_t offset = 0) const;
00507                         void get_bundleid(sqlite3_stmt *st, dtn::data::BundleID &id, size_t offset = 0) const;
00508 
00512                         virtual const std::string getName() const;
00513 
00514                         ibrcommon::File dbPath;
00515                         ibrcommon::File dbFile;
00516                         ibrcommon::File _blockPath;
00517 
00518                         int dbSize;
00519 
00520                         // holds the database handle
00521                         sqlite3 *_database;
00522 
00523                         // contains all jobs to do
00524                         ibrcommon::Queue<Task*> _tasks;
00525 
00526                         ibrcommon::Mutex _next_expiration_lock;
00527                         size_t _next_expiration;
00528 
00529                         // array of statements
00530                         sqlite3_stmt* _statements[SQL_QUERIES_END];
00531 
00532                         // array of locks for each statement
00533                         ibrcommon::Mutex _locks[SQL_QUERIES_END];
00534 
00535                         void add_deletion(const dtn::data::BundleID &id);
00536                         void remove_deletion(const dtn::data::BundleID &id);
00537                         bool contains_deletion(const dtn::data::BundleID &id);
00538 
00539                         // set of bundles to delete
00540                         ibrcommon::Mutex _deletion_mutex;
00541                         std::set<dtn::data::BundleID> _deletion_list;
00542                 };
00543         }
00544 }
00545 
00546 #endif /* SQLITEBUNDLESTORAGE_H_ */