00001 #ifndef VideoExcel_TableDataSourceSqliteDb_h
00002 #define VideoExcel_TableDataSourceSqliteDb_h
00003
00004 #include "TableDataSource.h"
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "CppSQLite3.h"
00019
00020
00021
00022
00023 namespace Impala {
00024 namespace Application {
00025 namespace VideoExcel {
00026
00027
00028
00029 class TableDataSourceSqliteDb : public TableDataSource
00030 {
00031 public:
00032
00033 TableDataSourceSqliteDb(std::string database, bool readonly=true):
00034 TableDataSource()
00035 {
00036 Init(database, readonly);
00037 }
00038
00039 ~TableDataSourceSqliteDb()
00040 {
00041 ILOG_DEBUG("destructing DB");
00042 if (mSqlDb) {
00043 sqlite3_enable_shared_cache(false);
00044 delete mSqlDb;
00045 }
00046 if (mQueryBuffer)
00047 delete mQueryBuffer;
00048 if (mBuffer)
00049 delete mBuffer;
00050 }
00051
00052
00053
00054 virtual std::string
00055 GetTextDataByID(std::string column, int row)
00056 {
00057 if (OutOfBounds(row))
00058 return "";
00059
00060 if (column == "filename")
00061 return RetrieveTextFromDb("origfilename", row);
00062
00063 if (column == "timestamp" || column == "width" || column == "height")
00064 return RetrieveTextFromDb(column, row);
00065
00066 return "N/A";
00067 }
00068
00069 virtual double
00070 GetNormalizedDataByID(std::string column, int row)
00071 {
00072 return 0;
00073 }
00074
00075 virtual Array2dVec3UInt8*
00076 GetImageDataByID(std::string column, int row)
00077 {
00078 if (OutOfBounds(row))
00079 return 0;
00080 Array2dVec3UInt8* ar = 0;
00081 ar = RetrieveImageFromDb(row);
00082 return ar;
00083 }
00084
00085
00086
00087 std::string
00088 RetrieveTextFromDb(std::string field, int index)
00089 {
00090
00091 std::ostringstream os;
00092 os << "select " << field << " from cache where idx=(" << index << ");";
00093 try
00094 {
00095 CppSQLite3Query q = mSqlDb->execQuery(os.str().c_str());
00096 std::string val = q.getStringField(field.c_str());
00097 return val;
00098 } catch (CppSQLite3Exception &e)
00099 {
00100 return "";
00101 }
00102 }
00103
00104 Array2dVec3UInt8*
00105 RetrieveImageFromDb(int index)
00106 {
00107 CppSQLite3Buffer b;
00108 b.format("select data from cache where idx = '%d';", index);
00109 CppSQLite3Query q = mSqlDb->execQuery(b);
00110
00111
00112 if (q.fieldIsNull("data"))
00113 {
00114 ILOG_WARN("no thumbnail found for " << index);
00115 return 0;
00116 }
00117
00118 int length;
00119 const unsigned char* image= q.getBlobField("data", length);
00120
00121 Core::Array::Array2dVec3UInt8* datastream = 0;
00122 ReadJpgFromMemory(datastream, (char*)image, length);
00123 return datastream;
00124 }
00125
00126
00127 int
00128 GetNrOfImages()
00129 {
00130 return mSqlDb->execScalar("select count(*) from cache;");
00131 }
00132
00133
00134 bool
00135 DbReady()
00136 {
00137 return mDbOpened;
00138 }
00139
00140 std::string
00141 DbGetStringProperty(std::string key)
00142 {
00143 mQueryBuffer->format("select value from properties where key=(%Q);", key.c_str());
00144 try
00145 {
00146 CppSQLite3Query q = mSqlDb->execQuery(mQueryBuffer->buffer());
00147 std::string val = q.getStringField("value");
00148 return val;
00149 } catch (CppSQLite3Exception &e)
00150 {
00151 return "";
00152 }
00153 }
00154
00155 int
00156 DbGetIntProperty(std::string key)
00157 {
00158 mQueryBuffer->format("select value from properties where key=(%Q);", key.c_str());
00159
00160
00161 CppSQLite3Query q = mSqlDb->execQuery(mQueryBuffer->buffer());
00162 int val = q.getIntField("value");
00163 return val;
00164
00165
00166
00167
00168 }
00169
00170
00171 CppSQLite3DB*
00172 GetDBHandle()
00173 {
00174 return mSqlDb;
00175 }
00176
00177 int
00178 GetThumbWidth()
00179 {
00180 return mTWidth;
00181 }
00182
00183 int
00184 GetThumbHeight()
00185 {
00186 return mTHeight;
00187 }
00188
00189 private:
00190
00191 bool
00192 OpenDb(std::string database, bool readonly=true)
00193 {
00194 mSqlDb->open(database.c_str());
00195 mReadonly = readonly;
00196 ILOG_INFO("Opening database " << database << "...");
00197 int version = DbGetIntProperty("dbversion");
00198 ILOG_DEBUG("Database version: " << version);
00199 if (version == -1)
00200 {
00201 ILOG_ERROR("Cannot open non-existing database.");
00202 return false;
00203 }
00204
00205 sqlite3_enable_shared_cache(true);
00206
00207 if (version != 5)
00208 {
00209 ILOG_WARN("trying to open an incompatible database version.");
00210 return false;
00211 }
00212
00213 try
00214 {
00215 int rows = mSqlDb->execScalar("select count(*) from cache;");
00216 ILOG_INFO("Database opened, " << rows << " images found.");
00217 }
00218 catch (CppSQLite3Exception& e)
00219 {
00220 ILOG_ERROR("Could not read from cache table.");
00221 return false;
00222 }
00223 return true;
00224 }
00225
00226
00227 bool
00228 DbHasFile(std::string file)
00229 {
00230 mQueryBuffer->format("select count(*) from cache where origfilename=%Q;", file.c_str());
00231 int rows = mSqlDb->execScalar(mQueryBuffer->buffer());
00232 if (rows == 1)
00233 return true;
00234 return false;
00235 }
00236
00237 void
00238 Init(std::string database, bool readonly)
00239 {
00240 ILOG_DEBUG("initializing TableDataSourceSqliteDb...");
00241
00242 mSqlDb = new CppSQLite3DB();
00243 mMaxBufferSize = 256000;
00244 mBuffer = new char[mMaxBufferSize];
00245 mQueryBuffer = new CppSQLite3Buffer();
00246 mDatabaseFile = database;
00247 mDbOpened = OpenDb(database, readonly);
00248
00249 if (!mDbOpened)
00250 {
00251 return;
00252 }
00253
00254 mTotalRows = GetNrOfImages();
00255 mFilteredRows = mTotalRows;
00256
00257 mTWidth = 512;
00258 mTHeight = 512;
00259
00260 AddColumn("id", TYPE_TEXT, 50);
00261 AddColumn("image", TYPE_IMAGE, 120);
00262 AddColumn("filename", TYPE_TEXT, 300);
00263 AddColumn("timestamp", TYPE_TEXT, 120);
00264 AddColumn("width", TYPE_TEXT, 120);
00265 AddColumn("height", TYPE_TEXT, 120);
00266
00267 }
00268
00269 std::string mDatabaseFile;
00270
00271 CppSQLite3DB *mSqlDb;
00272 CppSQLite3Buffer *mQueryBuffer;
00273
00274 int mTWidth, mTHeight;
00275
00276 int mMaxBufferSize;
00277 char *mBuffer;
00278 bool mUseFileTimes;
00279 bool mDbOpened;
00280 bool mReadonly;
00281
00282
00283 ILOG_VAR_DEC;
00284
00285 };
00286
00287 ILOG_VAR_INIT(TableDataSourceSqliteDb, Application.VideoExcel);
00288
00289
00290 }
00291 }
00292 }
00293
00294
00295 #endif // TableDataSourceSqliteDb_h