00001 #include <iostream>
00002
00003 #include "Learn/WiimoteGR/Database.h"
00004 #include "Learn/WiimoteGR/TimeSlot.h"
00005 #include "Learn/WiimoteGR/Quantizer.h"
00006 #include "Learn/WiimoteGR/HMMLib.h"
00007
00008 namespace WiimoteGR{
00009
00010
00011 class DBCloser{
00012 public:
00013 ~DBCloser(){
00014 Database::Close();
00015 }
00016 } DBCloserInstance;
00017
00018 Database* Database::dbInstance = 0;
00019
00020 Database& Database::Open()
00021 {
00022 if(dbInstance == 0){
00023 dbInstance = new Database;
00024 }
00025 return *dbInstance;
00026 }
00027
00028 void Database::Close()
00029 {
00030 if(dbInstance!=0){
00031 sqlite3_close(dbInstance->db);
00032 delete dbInstance;
00033 dbInstance = 0;
00034 }
00035 }
00036
00037
00038
00039
00040 void Database::SaveGesture(const Gesture& gesture)
00041 {
00042
00043 rc = sqlite3_bind_text(saveGestureStmt,1, gesture.gestureName.c_str(), gesture.gestureName.size(), SQLITE_TRANSIENT);
00044 if(rc!=SQLITE_OK) std::cout << "Error when binding gestureName in SaveGesture()" << std::endl << sqlite3_errmsg(db) << std::endl;
00045 rc = sqlite3_bind_int(saveGestureStmt,2, gesture.data.size());
00046 if(rc!=SQLITE_OK) std::cout << "Error when binding data in SaveGesture()" << std::endl << sqlite3_errmsg(db) << std::endl;
00047 rc = sqlite3_bind_blob(saveGestureStmt,3, &(gesture.data[0]), sizeof(Acceleration)*gesture.data.size(), SQLITE_TRANSIENT);
00048 if(rc!=SQLITE_OK) std::cout << "Error when binding data in SaveGesture()" << std::endl << sqlite3_errmsg(db) << std::endl;
00049
00050
00051 rc = sqlite3_step(saveGestureStmt);
00052 if(rc!=SQLITE_DONE) std::cout << "Error when evaluating in SaveGesture()" << std::endl << sqlite3_errmsg(db) << std::endl;
00053
00054
00055 sqlite3_reset(saveGestureStmt);
00056 sqlite3_clear_bindings(saveGestureStmt);
00057 }
00058
00059 void Database::SaveObservationSequence(const TimeSlot& seq)
00060 {
00061
00062 rc = sqlite3_bind_text(saveObservationSequenceStmt, 1, seq.gestureName.c_str(), seq.gestureName.size(), SQLITE_TRANSIENT);
00063 if(rc!=SQLITE_OK) std::cout << "Error when binding gestureName in SaveObservationSequence()" << std::endl;
00064 rc = sqlite3_bind_text(saveObservationSequenceStmt, 2, seq.quantizerName.c_str(), seq.quantizerName.size(), SQLITE_TRANSIENT);
00065 if(rc!=SQLITE_OK) std::cout << "Error when binding quantizerName in SaveObservationSequence()" << std::endl;
00066 rc = sqlite3_bind_int(saveObservationSequenceStmt, 3, seq.o.size());
00067 if(rc!=SQLITE_OK) std::cout << "Error when binding o in SaveObservationSequence()" << std::endl;
00068 rc = sqlite3_bind_blob(saveObservationSequenceStmt, 4, &(seq.o[0]), sizeof(size_t)*seq.o.size(), SQLITE_TRANSIENT);
00069 if(rc!=SQLITE_OK) std::cout << "Error when binding o in SaveObservationSequence()" << std::endl;
00070
00071
00072 rc = sqlite3_step(saveObservationSequenceStmt);
00073 if(rc!=SQLITE_DONE) std::cout << "Error when evaluating in SaveObservationSequence()" << std::endl;
00074
00075
00076 sqlite3_reset(saveObservationSequenceStmt);
00077 sqlite3_clear_bindings(saveObservationSequenceStmt);
00078 }
00079
00080 void Database::SaveHMM(const HMM& hmm)
00081 {
00082
00083
00084 rc = sqlite3_bind_text(isExistHMMStmt, 1, hmm.gestureName.c_str(), hmm.gestureName.size(), SQLITE_TRANSIENT);
00085 if(rc!=SQLITE_OK) std::cout << "Error when binding gestureName in SaveHMM() for test existence" << std::endl;
00086 rc = sqlite3_bind_text(isExistHMMStmt, 2, hmm.quantizerName.c_str(), hmm.quantizerName.size(), SQLITE_TRANSIENT);
00087 if(rc!=SQLITE_OK) std::cout << "Error when binding quantizerName in SaveHMM() for test existence" << std::endl;
00088 rc = sqlite3_bind_text(isExistHMMStmt, 3, hmm.modelStyle.c_str(), hmm.modelStyle.size(), SQLITE_TRANSIENT);
00089 if(rc!=SQLITE_OK) std::cout << "Error when binding modelStyle in SaveHMM() for test existence" << std::endl;
00090 rc = sqlite3_bind_int(isExistHMMStmt, 4, hmm.trained);
00091 if(rc!=SQLITE_OK) std::cout << "Error when binding trained in SaveHMM() for test existence" << std::endl;
00092
00093 sqlite3_stmt* chosenStmt = 0;
00094
00095
00096 rc = sqlite3_step(isExistHMMStmt);
00097 if(rc==SQLITE_DONE){
00098
00099 chosenStmt = insertHMMStmt;
00100 }else if(rc==SQLITE_ROW){
00101
00102 chosenStmt = updateHMMStmt;
00103 }else{
00104 std::cout << "Error when evaluating in SaveHMM() for test existence" << std::endl;
00105 }
00106
00107 sqlite3_reset(isExistHMMStmt);
00108 sqlite3_clear_bindings(isExistHMMStmt);
00109
00110
00111
00112 if(chosenStmt != 0){
00113
00114 rc = sqlite3_bind_text(chosenStmt, 1, hmm.gestureName.c_str(), hmm.gestureName.size(), SQLITE_TRANSIENT);
00115 if(rc!=SQLITE_OK) std::cout << "Error when binding gestureName in SaveHMM()" << std::endl;
00116 rc = sqlite3_bind_text(chosenStmt, 2, hmm.quantizerName.c_str(), hmm.quantizerName.size(), SQLITE_TRANSIENT);
00117 if(rc!=SQLITE_OK) std::cout << "Error when binding quantizerName in SaveHMM()" << std::endl;
00118 rc = sqlite3_bind_text(chosenStmt, 3, hmm.modelStyle.c_str(), hmm.modelStyle.size(), SQLITE_TRANSIENT);
00119 if(rc!=SQLITE_OK) std::cout << "Error when binding modelStyle in SaveHMM()" << std::endl;
00120 rc = sqlite3_bind_int(chosenStmt, 4, hmm.trained);
00121 if(rc!=SQLITE_OK) std::cout << "Error when binding trained in SaveHMM()" << std::endl;
00122 rc = sqlite3_bind_int(chosenStmt, 5, hmm.N);
00123 if(rc!=SQLITE_OK) std::cout << "Error when binding N in SaveHMM()" << std::endl;
00124 rc = sqlite3_bind_int(chosenStmt, 6, hmm.M);
00125 if(rc!=SQLITE_OK) std::cout << "Error when binding M in SaveHMM()" << std::endl;
00126 rc = sqlite3_bind_blob(chosenStmt, 7, &(hmm.pi[0]), sizeof(double)*hmm.pi.size(), SQLITE_TRANSIENT);
00127 if(rc!=SQLITE_OK) std::cout << "Error when binding pi in SaveHMM()" << std::endl;
00128 rc = sqlite3_bind_blob(chosenStmt, 8, &(hmm.A[0]), sizeof(double)*hmm.A.size(), SQLITE_TRANSIENT);
00129 if(rc!=SQLITE_OK) std::cout << "Error when binding A in SaveHMM()" << std::endl;
00130 rc = sqlite3_bind_blob(chosenStmt, 9, &(hmm.B[0]), sizeof(double)*hmm.B.size(), SQLITE_TRANSIENT);
00131 if(rc!=SQLITE_OK) std::cout << "Error when binding B in SaveHMM()" << std::endl;
00132
00133
00134 rc = sqlite3_step(chosenStmt);
00135 if(rc!=SQLITE_DONE) std::cout << "Error when evaluating in SaveHMM()" << std::endl;
00136
00137
00138 sqlite3_reset(chosenStmt);
00139 sqlite3_clear_bindings(chosenStmt);
00140 }
00141 }
00142
00143 void Database::LoadGestures(const char* gestureName, vector<Gesture>& gestureVec)
00144 {
00145 gestureVec.reserve(gestureVecSpace);
00146
00147 rc = sqlite3_bind_text(loadGesturesStmt, 1, gestureName, -1, SQLITE_TRANSIENT);
00148 if(rc!=SQLITE_OK) std::cout << "Error when binding gestureName in LoadGestures()" << std::endl;
00149
00150 Gesture tempGesture(gestureName);
00151 size_t dataLength;
00152 const Acceleration* dataPtr = 0;
00153
00154
00155 rc = sqlite3_step(loadGesturesStmt);
00156 while(rc==SQLITE_ROW){
00157 gestureVec.push_back(tempGesture);
00158 dataLength = sqlite3_column_int(loadGesturesStmt, 0);
00159 dataPtr = (const Acceleration*)sqlite3_column_blob(loadGesturesStmt, 1);
00160 gestureVec.back().data.assign(dataPtr,dataPtr+dataLength);
00161 rc = sqlite3_step(loadGesturesStmt);
00162 }
00163 if(rc!=SQLITE_DONE) std::cout << "Error when evaluation in LoadGestures()" << std::endl;
00164
00165 sqlite3_reset(loadGesturesStmt);
00166 sqlite3_clear_bindings(loadGesturesStmt);
00167 }
00168
00169 void Database::LoadObservationSequences(const char* gestureName, const Quantizer& quantizer, vector<TimeSlot>& seqVec)
00170 {
00171 seqVec.reserve(seqVecSpace);
00172
00173 rc = sqlite3_bind_text(loadObservationSequencesStmt, 1, gestureName, -1, SQLITE_TRANSIENT);
00174 if(rc!=SQLITE_OK) std::cout << "Error when binding gestureName in LoadObservationSequences()" << std::endl;
00175 rc = sqlite3_bind_text(loadObservationSequencesStmt, 2, quantizer.name.c_str(), quantizer.name.size(), SQLITE_TRANSIENT);
00176 if(rc!=SQLITE_OK) std::cout << "Error when binding quantizerName in LoadObservationSequences()" << std::endl;
00177
00178 TimeSlot tempSeq(gestureName,quantizer);
00179 size_t oLength;
00180 const size_t* oPtr = 0;
00181
00182
00183 rc = sqlite3_step(loadObservationSequencesStmt);
00184 while(rc==SQLITE_ROW){
00185 oLength= sqlite3_column_int(loadObservationSequencesStmt, 0);
00186 oPtr = (const size_t*)sqlite3_column_blob(loadObservationSequencesStmt, 1);
00187 seqVec.push_back(tempSeq);
00188 seqVec.back().o.assign(oPtr,oPtr+oLength);
00189 rc = sqlite3_step(loadObservationSequencesStmt);
00190 }
00191 if(rc!=SQLITE_DONE) std::cout << "Error when evaluation in LoadObservationSequences()" << std::endl;
00192
00193
00194 sqlite3_reset(loadObservationSequencesStmt);
00195 sqlite3_clear_bindings(loadObservationSequencesStmt);
00196 }
00197
00198 void Database::LoadHMM(HMM& hmm)
00199 {
00200
00201 rc = sqlite3_bind_text(loadHMMStmt, 1, hmm.gestureName.c_str(), hmm.gestureName.size(), SQLITE_TRANSIENT);
00202 if(rc!=SQLITE_OK) std::cout << "Error when binding gestureName in LoadHMM()" << std::endl;
00203 rc = sqlite3_bind_text(loadHMMStmt, 2, hmm.quantizerName.c_str(), hmm.quantizerName.size(), SQLITE_TRANSIENT);
00204 if(rc!=SQLITE_OK) std::cout << "Error when binding quantizerName in LoadHMM()" << std::endl;
00205 rc = sqlite3_bind_text(loadHMMStmt, 3, hmm.modelStyle.c_str(), hmm.modelStyle.size(), SQLITE_TRANSIENT);
00206 if(rc!=SQLITE_OK) std::cout << "Error when binding modelStyle in LoadHMM()" << std::endl;
00207 rc = sqlite3_bind_int(loadHMMStmt, 4, hmm.trained);
00208 if(rc!=SQLITE_OK) std::cout << "Error when binding trained in LoadHMM()" << std::endl;
00209
00210
00211 rc = sqlite3_step(loadHMMStmt);
00212 if(rc==SQLITE_ROW){
00213 hmm.N = sqlite3_column_int(loadHMMStmt, 0);
00214 hmm.M = sqlite3_column_int(loadHMMStmt, 1);
00215 const double* piPtr = (const double*)sqlite3_column_blob(loadHMMStmt, 2);
00216 hmm.pi.assign(piPtr,piPtr+hmm.N);
00217 const double* APtr = (const double*)sqlite3_column_blob(loadHMMStmt, 3);
00218 hmm.A.assign(APtr,APtr+hmm.N*hmm.N);
00219 const double* BPtr = (const double*)sqlite3_column_blob(loadHMMStmt, 4);
00220 hmm.B.assign(BPtr,BPtr+hmm.N*hmm.M);
00221 }
00222 rc = sqlite3_step(loadHMMStmt);
00223 if(rc!=SQLITE_DONE) std::cout << "Error when evaluation in LoadHMM()" << std::endl;
00224
00225
00226 sqlite3_reset(loadHMMStmt);
00227 sqlite3_clear_bindings(loadHMMStmt);
00228 }
00229
00230 void Database::LoadHMMs(const Quantizer& quantizer, const char* modelStyle, bool trained, vector<HMM>& hmmVec)
00231 {
00232 hmmVec.reserve(hmmVecSpace+hmmVec.size());
00233
00234 rc = sqlite3_bind_text(loadHMMsStmt, 1, quantizer.name.c_str(), quantizer.name.size(), SQLITE_TRANSIENT);
00235 if(rc!=SQLITE_OK) std::cout << "Error when binding quantizerName in LoadHMMs()" << std::endl;
00236 rc = sqlite3_bind_text(loadHMMsStmt, 2, modelStyle, -1, SQLITE_TRANSIENT);
00237 if(rc!=SQLITE_OK) std::cout << "Error when binding modelStyle in LoadHMMs()" << std::endl;
00238 rc = sqlite3_bind_int(loadHMMsStmt, 3, trained);
00239 if(rc!=SQLITE_OK) std::cout << "Error when binding trained in LoadHMMs()" << std::endl;
00240
00241 HMM tempHMM(quantizer, modelStyle, trained);
00242
00243
00244 rc = sqlite3_step(loadHMMsStmt);
00245 while(rc==SQLITE_ROW){
00246 hmmVec.push_back(tempHMM);
00247 HMM& curHMM = hmmVec.back();
00248 curHMM.gestureName = (const char*)sqlite3_column_text(loadHMMsStmt, 0);
00249 curHMM.N = sqlite3_column_int(loadHMMsStmt, 1);
00250 curHMM.M = sqlite3_column_int(loadHMMsStmt, 2);
00251 const double* piPtr = (const double*)sqlite3_column_blob(loadHMMsStmt, 3);
00252 curHMM.pi.assign(piPtr,piPtr+curHMM.N);
00253 const double* APtr = (const double*)sqlite3_column_blob(loadHMMsStmt, 4);
00254 curHMM.A.assign(APtr,APtr+curHMM.N*curHMM.N);
00255 const double* BPtr = (const double*)sqlite3_column_blob(loadHMMsStmt, 5);
00256 curHMM.B.assign(BPtr,BPtr+curHMM.N*curHMM.M);
00257 rc = sqlite3_step(loadHMMsStmt);
00258 }
00259 if(rc!=SQLITE_DONE) std::cout << "Error when evaluation in LoadHMMs()" << std::endl;
00260
00261 sqlite3_reset(loadHMMsStmt);
00262 sqlite3_clear_bindings(loadHMMsStmt);
00263 }
00264
00265 void Database::DeleteGestures(const char* gestureName){
00266 string sql = "DELETE FROM GestureTable WHERE gestureName=='" + string(gestureName) + "';";
00267 char* errMsg = 0;
00268 rc = sqlite3_exec(db,sql.c_str(),0,0,&errMsg);
00269 if(rc!=SQLITE_OK) std::cout << errMsg << endl;
00270 }
00271 void Database::DeleteObservationSequences(const char* gestureName, const Quantizer& quantizer){
00272 string sql = "DELETE FROM ObservationSequenceTable WHERE gestureName=='" + string(gestureName)
00273 + "' AND quantizerName=='" + quantizer.name + "';";
00274 char* errMsg = 0;
00275 rc = sqlite3_exec(db,sql.c_str(),0,0,&errMsg);
00276 if(rc!=SQLITE_OK) std::cout << errMsg << endl;
00277 }
00278
00279 Database::Database()
00280 :dbOpened(false),saveGestureStmt(0),saveObservationSequenceStmt(0),
00281 isExistHMMStmt(0),updateHMMStmt(0),insertHMMStmt(0),
00282 loadGesturesStmt(0),loadObservationSequencesStmt(0),loadHMMStmt(0),loadHMMsStmt(0)
00283 {
00284 rc = sqlite3_open("WiimoteGR.db", &db);
00285 if(rc){
00286 std::cout << "Can't open database: " << sqlite3_errmsg(db) << std::endl;
00287 sqlite3_close(db);
00288 }else{
00289 dbOpened=true;
00290 rc = sqlite3_exec(db,
00291 "CREATE TABLE IF NOT EXISTS GestureTable( "
00292 " gestureName TEXT NOT NULL, "
00293 " dataLength INTEGER NOT NULL, "
00294 " data BLOB NOT NULL "
00295 "); "
00296
00297 "CREATE TABLE IF NOT EXISTS ObservationSequenceTable( "
00298 " gestureName TEXT NOT NULL, "
00299 " quantizerName TEXT NOT NULL, "
00300 " oLength INTEGER NOT NULL, "
00301 " o BLOB NOT NULL "
00302 "); "
00303
00304 "CREATE TABLE IF NOT EXISTS HMMTable( "
00305 " gestureName TEXT NOT NULL, "
00306 " quantizerName TEXT NOT NULL, "
00307 " modelStyle TEXT NOT NULL, "
00308 " trained INTEGER NOT NULL, "
00309 " N INTEGER NOT NULL, "
00310 " M INTEGER NOT NULL, "
00311 " pi BLOB NOT NULL, "
00312 " A BLOB NOT NULL, "
00313 " B BLOB NOT NULL "
00314 "); ",
00315 0, 0, &zErrMsg);
00316 if(rc!=SQLITE_OK) std::cout << "Error when CREATE TABLEs" << std::endl;
00317
00318 string saveGestureSQL = "INSERT INTO GestureTable VALUES( :gestureName, :dataLength, :data );";
00319 rc = sqlite3_prepare_v2(db,saveGestureSQL.c_str(),saveGestureSQL.size()+1, &saveGestureStmt, 0);
00320 if(rc!=SQLITE_OK || saveGestureStmt==0) std::cout << "Error when prepare INSERT INTO GestureTable" << std::endl;
00321
00322 string saveObservationSequenceSQL = "INSERT INTO ObservationSequenceTable VALUES( :gestureName, :quantizerName, :oLength, :o );";
00323 rc = sqlite3_prepare_v2(db,saveObservationSequenceSQL.c_str(),saveObservationSequenceSQL.size()+1, &saveObservationSequenceStmt, 0);
00324 if(rc!=SQLITE_OK || saveObservationSequenceStmt==0) std::cout << "Error when prepare INSERT INTO ObservationSequenceTable" << std::endl;
00325
00326 string isExistHMMSQL = "SELECT ROWID FROM HMMTable WHERE gestureName==?1 AND quantizerName==?2 AND modelStyle==?3 AND trained==?4 LIMIT 1;";
00327 rc = sqlite3_prepare_v2(db,isExistHMMSQL.c_str(),isExistHMMSQL.size()+1, &isExistHMMStmt, 0);
00328 if(rc!=SQLITE_OK || isExistHMMStmt==0) std::cout << "Error when prepare SELECT * FROM HMMTable for test existence" << std::endl;
00329
00330 string insertHMMSQL = "INSERT INTO HMMTable VALUES( :gestureName, :quantizerName, :modelStyle, :trained, :N, :M, :pi, :A, :B );";
00331 rc = sqlite3_prepare_v2(db,insertHMMSQL.c_str(),insertHMMSQL.size()+1, &insertHMMStmt, 0);
00332 if(rc!=SQLITE_OK || insertHMMStmt==0) std::cout << "Error when prepare INSERT INTO HMMTable" << std::endl;
00333
00334 string updateHMMSQL = "UPDATE HMMTable SET N=?5, M=?6, pi=?7, A=?8, B=?9 "
00335 "WHERE gestureName==?1 AND quantizerName==?2 AND modelStyle==?3 AND trained==?4;";
00336 rc = sqlite3_prepare_v2(db,updateHMMSQL.c_str(),updateHMMSQL.size()+1, &updateHMMStmt, 0);
00337 if(rc!=SQLITE_OK || updateHMMStmt==0) std::cout << "Error when prepare UPDATE HMMTable" << std::endl;
00338
00339 string loadGesturesSQL = "SELECT dataLength, data FROM GestureTable WHERE gestureName==?1;";
00340 rc = sqlite3_prepare_v2(db,loadGesturesSQL.c_str(),loadGesturesSQL.size()+1, &loadGesturesStmt, 0);
00341 if(rc!=SQLITE_OK || loadGesturesStmt==0) std::cout << "Error when prepare loadGesture statement" << std::endl;
00342
00343 string loadObservationSequencesSQL = "SELECT oLength, o FROM ObservationSequenceTable WHERE gestureName==?1 AND quantizerName==?2;";
00344 rc = sqlite3_prepare_v2(db,loadObservationSequencesSQL.c_str(),loadObservationSequencesSQL.size()+1, &loadObservationSequencesStmt, 0);
00345 if(rc!=SQLITE_OK || loadObservationSequencesStmt==0) std::cout << "Error when prepare loadObservationSequences statement" << std::endl;
00346
00347 string loadHMMSQL = "SELECT N, M, pi, A, B FROM HMMTable WHERE gestureName==?1 AND quantizerName==?2 AND modelStyle==?3 AND trained==?4;";
00348 rc = sqlite3_prepare_v2(db,loadHMMSQL.c_str(),loadHMMSQL.size()+1, &loadHMMStmt, 0);
00349 if(rc!=SQLITE_OK || loadHMMStmt==0) std::cout << "Error when prepare loadHMM statement" << std::endl;
00350
00351 string loadHMMsSQL = "SELECT gestureName, N, M, pi, A, B FROM HMMTable WHERE quantizerName==?1 AND modelStyle==?2 AND trained==?3;";
00352 rc = sqlite3_prepare_v2(db,loadHMMsSQL.c_str(),loadHMMsSQL.size()+1, &loadHMMsStmt, 0);
00353 if(rc!=SQLITE_OK || loadHMMsStmt==0) std::cout << "Error when prepare loadHMMs statement" << std::endl;
00354 }
00355 }
00356
00357 Database::~Database()
00358 {
00359 sqlite3_close(db);
00360 }
00361 }