Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SSMCore / src / QueryProcessor / EvaluationEngine.cpp
1 /******************************************************************
2 *
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
4 *
5 *
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ******************************************************************/
20 #include "EvaluationEngine.h"
21
22 #define CHK_SQLITE(val, cond) {SSM_CLEANUP_COND_ASSERT(val, cond, sqlite3_errmsg(m_pSQLite3));}
23
24 SSMRESULT CEvaluationEngine::finalConstruct()
25 {
26     SSMRESULT res = SSM_E_FAIL;
27
28     m_pSQLite3 = NULL;
29
30     m_mtxTriggerId.lock();
31     m_iTriggerId = 0;
32     m_mtxTriggerId.unlock();
33
34     SSM_CLEANUP_ASSERT(CreateInstance(OID_ITasker, (IBase **)&m_pTasker));
35     SSM_CLEANUP_ASSERT(initializeEngine());
36
37 CLEANUP:
38     return res;
39 }
40
41 void CEvaluationEngine::finalRelease()
42 {
43     terminateEngine();
44 }
45
46 SSMRESULT CEvaluationEngine::executeSQL_NoReturn(std::string strSQL)
47 {
48     SSMRESULT       res = SSM_E_FAIL;
49     sqlite3_stmt    *stmt = NULL;
50
51     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
52     CHK_SQLITE(sqlite3_step(stmt), SQLITE_DONE);
53     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
54
55     res = SSM_S_OK;
56 CLEANUP:
57     return res;
58 }
59
60 SSMRESULT CEvaluationEngine::executeSQL_IntReturn(std::string strSQL, int *pResult)
61 {
62     SSMRESULT       res = SSM_E_FAIL;
63     sqlite3_stmt    *stmt = NULL;
64
65     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
66     CHK_SQLITE(sqlite3_step(stmt), SQLITE_ROW);
67     *pResult = sqlite3_column_int(stmt, 0);
68     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
69
70     res = SSM_S_OK;
71 CLEANUP:
72     return res;
73 }
74
75 void CEvaluationEngine::onSQLTrigger(sqlite3_context *context, int argc,
76                                      sqlite3_value **argv)
77 {
78     CEvaluationEngine *pEvaluationEngine = (CEvaluationEngine *)sqlite3_value_int64(argv[0]);
79
80     pEvaluationEngine->onWatcherTriggered(sqlite3_value_int(argv[1]), sqlite3_value_int(argv[2]));
81 }
82
83 void CEvaluationEngine::onExecute(void *pArg)
84 {
85     std::map<int, IEvaluationEngineEvent *>::iterator itor;
86     intptr_t *pData = (intptr_t *)pArg;
87
88     m_mtxTriggerId.lock();
89     itor = m_mapTriggers.find(pData[0]);
90     if (itor != m_mapTriggers.end())
91     {
92         IEvaluationEngineEvent      *pEvent = itor->second;
93         pEvent->onWatchModelData(pData[0], pData[1]);
94     }
95     m_mtxTriggerId.unlock();
96 }
97
98 void CEvaluationEngine::onTerminate(void *pArg)
99 {
100     intptr_t *pData = (intptr_t *)pArg;
101     SAFE_ARRAY_DELETE(pData);
102 }
103
104 SSMRESULT CEvaluationEngine::onWatcherTriggered(int triggerId, int dataId)
105 {
106     intptr_t     *pData = new intptr_t[2];
107     pData[0] = triggerId;
108     pData[1] = dataId;
109     m_pTasker->addTask(this, (void *)pData);
110     return SSM_S_OK;
111 }
112
113 SSMRESULT CEvaluationEngine::initializeEngine()
114 {
115     SSMRESULT           res = SSM_E_FAIL;
116     sqlite3             *pBackupFile = NULL;
117     sqlite3_backup      *pBackup = NULL;
118
119     const char *strCreate_ModelRelationTable =
120         "create table [ModelRelation]\
121                 (\
122                 modelId integer primary key autoincrement,\
123                 modelName text NOT NULL,\
124                 lPos int NOT NULL,\
125                 rPos int NOT NULL\
126                 );";
127
128     const char *strCreate_DataRelationTable =
129         "create table [DataRelation]\
130                 (\
131                 id integer primary key autoincrement,\
132                 modelId int NOT NULL,\
133                 lPos int NOT NULL,\
134                 rPos int NOT NULL,\
135                 dataId int NOT NULL\
136                 );";
137
138     //Create rootModel
139     const char *strRootModel = "insert into [ModelRelation] values (null, 'root', 1, 2);";
140
141     const char *tblRoot =
142         "create table [ModelData1](dataId integer primary key autoincrement, name text);";
143
144     const char *rootData = "insert into [ModelData1] values (null, 'root');";
145
146     const char *rootRelation = "insert into [DataRelation] values (null, 1, 1, 2, 1);";
147
148     CHK_SQLITE(sqlite3_open_v2(LOCATION_SSM_DB, &m_pSQLite3,
149                                SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL), SQLITE_OK);
150
151     CHK_SQLITE(sqlite3_create_function_v2(m_pSQLite3, "OnSQLTrigger", 3, SQLITE_UTF8, NULL,
152                                           onSQLTrigger, NULL, NULL, NULL),
153                SQLITE_OK);
154
155     if (strlen(LOCATION_SSM_DB_DUMP) > 0 &&
156         sqlite3_open_v2(LOCATION_SSM_DB_DUMP, &pBackupFile, SQLITE_OPEN_READWRITE, NULL) == SQLITE_OK)
157     {
158         pBackup = sqlite3_backup_init(m_pSQLite3, "main", pBackupFile, "main");
159         CHK_SQLITE(sqlite3_errcode(pBackupFile), SQLITE_OK);
160         SSM_CLEANUP_NULL_ASSERT(pBackup);
161         CHK_SQLITE(sqlite3_backup_step(pBackup, -1), SQLITE_DONE);
162         CHK_SQLITE(sqlite3_backup_finish(pBackup), SQLITE_OK);
163         CHK_SQLITE(sqlite3_close(pBackupFile), SQLITE_OK);
164         res = SSM_S_OK;
165     }
166     else
167     {
168         SSM_CLEANUP_ASSERT(executeSQL_NoReturn(strCreate_ModelRelationTable));
169         SSM_CLEANUP_ASSERT(executeSQL_NoReturn(strCreate_DataRelationTable));
170
171         SSM_CLEANUP_ASSERT(executeSQL_NoReturn(strRootModel));
172         SSM_CLEANUP_ASSERT(executeSQL_NoReturn(tblRoot));
173         SSM_CLEANUP_ASSERT(executeSQL_NoReturn(rootData));
174         SSM_CLEANUP_ASSERT(executeSQL_NoReturn(rootRelation));
175     }
176
177 CLEANUP:
178     return res;
179 }
180
181 void CEvaluationEngine::terminateEngine()
182 {
183     SSMRESULT           res = SSM_E_FAIL;
184     sqlite3             *pBackupFile = NULL;
185     sqlite3_backup      *pBackup = NULL;
186     std::stringstream   sstream;
187
188     //Remove all triggers on db side
189     m_mtxTriggerId.lock();
190     for (std::map<int, IEvaluationEngineEvent *>::iterator itor = m_mapTriggers.begin();
191          itor != m_mapTriggers.end(); ++itor)
192     {
193         sstream << "drop trigger WatchInsertModel" << itor->first << ";" << std::ends;
194         SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
195         sstream.str("");
196
197         sstream << "drop trigger WatchUpdateModel" << itor->first << ";" << std::ends;
198         SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
199         sstream.str("");
200     }
201
202     if (strlen(LOCATION_SSM_DB_DUMP) > 0)
203     {
204         CHK_SQLITE(sqlite3_open(LOCATION_SSM_DB_DUMP, &pBackupFile), SQLITE_OK);
205         pBackup = sqlite3_backup_init(pBackupFile, "main", m_pSQLite3, "main");
206         CHK_SQLITE(sqlite3_errcode(pBackupFile), SQLITE_OK);
207         SSM_CLEANUP_NULL_ASSERT(pBackup);
208         CHK_SQLITE(sqlite3_backup_step(pBackup, -1), SQLITE_DONE);
209         CHK_SQLITE(sqlite3_backup_finish(pBackup), SQLITE_OK);
210         CHK_SQLITE(sqlite3_close(pBackupFile), SQLITE_OK);
211     }
212
213     CHK_SQLITE(sqlite3_close(m_pSQLite3), SQLITE_OK);
214
215     m_pSQLite3 = NULL;
216
217     res = SSM_S_OK;
218
219 CLEANUP:
220     m_mtxTriggerId.unlock();
221     return;
222 }
223
224 SSMRESULT CEvaluationEngine::createModel(int parentModelId, const char *newModelName,
225         ModelPropertyVec *pModelDescs, int *pModelId)
226 {
227     SSMRESULT res = SSM_E_FAIL;
228     std::stringstream sstream;
229     std::string         strSQL;
230     sqlite3_stmt        *stmt = NULL;
231     int         lPos = 0;
232
233     //Check if same name exists
234     sstream << "select modelId from [ModelRelation] where modelName='" << newModelName << "';" <<
235             std::ends;
236     strSQL = sstream.str();
237     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
238     if (sqlite3_step(stmt) == SQLITE_ROW)
239     {
240         *pModelId = sqlite3_column_int(stmt, 0);
241         CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
242         res = SSM_S_OK;
243         goto CLEANUP;
244     }
245     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
246     sstream.str("");
247
248     sstream << "select lPos from [ModelRelation] where modelId = '" << parentModelId << "';" <<
249             std::ends;
250     SSM_CLEANUP_ASSERT(executeSQL_IntReturn(sstream.str(), &lPos));
251     sstream.str("");
252
253     sstream << "update [ModelRelation] set rPos = rPos + 2 where rPos > " << lPos << ";" << std::ends;
254     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
255     sstream.str("");
256
257     sstream << "update [ModelRelation] set lPos = lPos + 2 where lPos > " << lPos << ";" << std::ends;
258     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
259     sstream.str("");
260
261     sstream << "insert into [ModelRelation] values (null, '" << newModelName << "', " << lPos + 1 <<
262             ", " << lPos + 2 <<
263             ");" << std::ends;
264     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
265     sstream.str("");
266
267     SSM_CLEANUP_ASSERT(executeSQL_IntReturn("select last_insert_rowid();", pModelId));
268
269     sstream << "create table [ModelData" << *pModelId <<
270             "](dataId integer primary key autoincrement, lastTime NOT NULL DEFAULT CURRENT_TIMESTAMP, lifetime integer NOT NULL DEFAULT 2147483647, available text DEFAULT 'true'";
271
272     for (ModelPropertyVec::iterator itor =
273              pModelDescs->begin(); itor != pModelDescs->end(); ++itor)
274     {
275         sstream << "," << itor->propertyName;
276         switch (itor->propertyType)
277         {
278             case ModelProperty::TYPE_NUMERIC:
279                 sstream << " numeric";
280                 break;
281
282             case ModelProperty::TYPE_INTEGER:
283                 sstream << " integer";
284                 break;
285
286             case ModelProperty::TYPE_REAL:
287                 sstream << " real";
288                 break;
289
290             case ModelProperty::TYPE_TEXT:
291                 sstream << " text";
292                 break;
293
294             default:
295                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
296         }
297     }
298
299     sstream << ");" << std::ends;
300
301     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
302
303 CLEANUP:
304     return res;
305 }
306
307 SSMRESULT CEvaluationEngine::addModelData(int modelId, int parentModelId, int parentDataId,
308         ModelPropertyVec *pModelValues, int *pDataId)
309 {
310     SSMRESULT           res = SSM_E_FAIL;
311     std::stringstream   sstream;
312     std::string         strSQL;
313     sqlite3_stmt        *stmt = NULL;
314     int                 lPos = 0;
315     unsigned int        i;
316
317     sstream << "insert into [ModelData" << modelId << "] (";
318
319     for (ModelPropertyVec::iterator itor = pModelValues->begin();
320          itor != pModelValues->end(); ++itor)
321     {
322         sstream << itor->propertyName;
323
324         if (itor < pModelValues->end() - 1)
325         {
326             sstream << ",";
327         }
328     }
329
330     sstream << ") values (";
331
332     for (i = 0; i < pModelValues->size(); i++)
333     {
334         sstream << "?";
335
336         if (i < pModelValues->size() - 1)
337         {
338             sstream << ",";
339         }
340     }
341
342     sstream << ");" << std::ends;
343
344     strSQL = sstream.str();
345     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
346     sstream.str("");
347
348     i = 1;
349     for (ModelPropertyVec::iterator itor = pModelValues->begin();
350          itor != pModelValues->end(); ++itor)
351     {
352         switch (itor->propertyType)
353         {
354             case ModelProperty::TYPE_NUMERIC:
355             case ModelProperty::TYPE_INTEGER:
356                 CHK_SQLITE(sqlite3_bind_int(stmt, i, atoi(itor->propertyValue.c_str())), SQLITE_OK);
357                 break;
358
359             case ModelProperty::TYPE_REAL:
360                 CHK_SQLITE(sqlite3_bind_double(stmt, i, atof(itor->propertyValue.c_str())), SQLITE_OK);
361                 break;
362
363             case ModelProperty::TYPE_TEXT:
364                 CHK_SQLITE(sqlite3_bind_text(stmt, i, itor->propertyValue.c_str(), itor->propertyValue.size(),
365                                              SQLITE_STATIC), SQLITE_OK);
366                 break;
367
368             default:
369                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
370         }
371
372         i++;
373     }
374
375     m_mtxDataRelation.lock();
376
377     CHK_SQLITE(sqlite3_step(stmt), SQLITE_DONE);
378
379     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
380
381     SSM_CLEANUP_ASSERT(executeSQL_IntReturn("select last_insert_rowid();", pDataId));
382
383     sstream << "select lPos from [DataRelation] where modelId = " << parentModelId << " and dataId = "
384             << parentDataId << ";" << std::ends;
385     SSM_CLEANUP_ASSERT(executeSQL_IntReturn(sstream.str(), &lPos));
386     sstream.str("");
387
388     sstream << "update [DataRelation] set rPos = rPos + 2 where rPos > " << lPos << ";" << std::ends;
389     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
390     sstream.str("");
391
392     sstream << "update [DataRelation] set lPos = lPos + 2 where lPos > " << lPos << ";" << std::ends;
393     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
394     sstream.str("");
395
396     sstream << "insert into [DataRelation] values (null, " << modelId << ", " << lPos + 1 << ", " <<
397             lPos + 2 <<
398             ", " << *pDataId << ");" << std::ends;
399     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
400
401 CLEANUP:
402     m_mtxDataRelation.unlock();
403     return res;
404 }
405
406 SSMRESULT CEvaluationEngine::updateModelData(int modelId, int dataId,
407         ModelPropertyVec *pModelValues)
408 {
409     SSMRESULT res = SSM_E_FAIL;
410     std::stringstream sstream;
411     std::string         strSQL;
412     sqlite3_stmt        *stmt = NULL;
413     unsigned int        i = 1;
414
415     sstream << "update [ModelData" << modelId << "] set lastTime=CURRENT_TIMESTAMP, ";
416
417     for (ModelPropertyVec::iterator itor = pModelValues->begin();
418          itor != pModelValues->end(); ++itor)
419     {
420         sstream << itor->propertyName << "=?";
421
422         if (itor < pModelValues->end() - 1)
423         {
424             sstream << ",";
425         }
426     }
427
428     sstream << " where dataId = " << dataId << ";" << std::ends;
429
430     strSQL = sstream.str();
431     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
432
433     for (ModelPropertyVec::iterator itor = pModelValues->begin();
434          itor != pModelValues->end(); ++itor)
435     {
436         switch (itor->propertyType)
437         {
438             case ModelProperty::TYPE_NUMERIC:
439             case ModelProperty::TYPE_INTEGER:
440                 CHK_SQLITE(sqlite3_bind_int(stmt, i, atoi(itor->propertyValue.c_str())), SQLITE_OK);
441                 break;
442
443             case ModelProperty::TYPE_REAL:
444                 CHK_SQLITE(sqlite3_bind_double(stmt, i, atof(itor->propertyValue.c_str())), SQLITE_OK);
445                 break;
446
447             case ModelProperty::TYPE_TEXT:
448                 CHK_SQLITE(sqlite3_bind_text(stmt, i, itor->propertyValue.c_str(), itor->propertyValue.size(),
449                                              SQLITE_STATIC), SQLITE_OK);
450                 break;
451
452             default:
453                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
454         }
455
456         i++;
457     }
458
459     CHK_SQLITE(sqlite3_step(stmt), SQLITE_DONE);
460
461     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
462
463     res = SSM_S_OK;
464
465 CLEANUP:
466     return res;
467 }
468 /*
469 SSMRESULT CEvaluationEngine::DeleteModel(int modelId)
470 {
471     SSMRESULT       res = SSM_E_FAIL;
472     std::stringstream sstream;
473     std::string     strSQL;
474     sqlite3_stmt    *stmt = NULL;
475     int             lPos = 0;
476     int             rPos = 0;
477     int             width = 0;
478     IntVec          dataIds;
479
480     sstream << "select lPos, rPos from [ModelRelation] where modelId = " << modelId << ";" << std::ends;
481
482     strSQL = sstream.str();
483     sstream.str("");
484     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
485     CHK_SQLITE(sqlite3_step(stmt), SQLITE_ROW);
486     lPos = sqlite3_column_int(stmt, 0);
487     rPos = sqlite3_column_int(stmt, 1);
488     width = rPos - lPos + 1;
489     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
490
491     sstream << "delete from [ModelRelation] where lPos between " << lPos << " and " << rPos <<
492         ";update [ModelRelation] set rPos = rPos - " << width << " where rPos > " << rPos <<
493         ";update [ModelRelation] set lPos = lPos - " << width << " where lPos > " << lPos << std::ends;
494     CHK_SSMRESULT(ExecuteSQL_NoReturn(sstream.str()));
495     sstream.str("");
496
497     sstream << "select dataId from [DataRelation] where modelId = " << modelId << ";" << std::ends;
498     strSQL = sstream.str();
499     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
500     while(sqlite3_step(stmt) == SQLITE_ROW)
501     {
502         dataIds.push_back(sqlite3_column_int(stmt, 0));
503     }
504     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
505
506     for(std::vector<int>::iterator itor = dataIds.begin();
507         itor != dataIds.end(); ++itor)
508     {
509         CHK_SSMRESULT(DeleteModelData(modelId, *itor));
510     }
511
512 CLEANUP:
513     return res;
514 }
515 */
516 SSMRESULT CEvaluationEngine::deleteModelData(int modelId, int dataId)
517 {
518     SSMRESULT res = SSM_E_FAIL;
519     std::stringstream sstream;
520     std::string strSQL;
521     sqlite3_stmt *stmt = NULL;
522     int             lPos = 0;
523     int             rPos = 0;
524     int             width = 0;
525
526     m_mtxDataRelation.lock();
527
528     sstream << "select lPos, rPos from [DataRelation] where modelId = " << modelId << " and dataId = "
529             << dataId << ";" << std::ends;
530
531     strSQL = sstream.str();
532     sstream.str("");
533     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
534     CHK_SQLITE(sqlite3_step(stmt), SQLITE_ROW);
535     lPos = sqlite3_column_int(stmt, 0);
536     rPos = sqlite3_column_int(stmt, 1);
537     width = rPos - lPos + 1;
538     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
539
540     sstream << "delete from [DataRelation] where lPos between " << lPos << " and " << rPos << ";" <<
541             std::ends;
542     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
543     sstream.str("");
544
545     sstream << "update [DataRelation] set rPos = rPos - " << width << " where rPos > " << rPos << ";" <<
546             std::ends;
547     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
548     sstream.str("");
549
550     sstream << "update [DataRelation] set lPos = lPos - " << width << " where lPos > " << lPos << ";" <<
551             std::ends;
552     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
553     sstream.str("");
554
555     sstream << "delete from [ModelData" << modelId << "] where dataId = " << dataId << ";" << std::ends;
556     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
557
558 CLEANUP:
559     m_mtxDataRelation.unlock();
560     return res;
561 }
562
563 SSMRESULT CEvaluationEngine::getModelDataSet(int modelId, int startIndex, int count,
564         std::vector<ModelPropertyVec> *pDataSet, int *pLastIndex)
565 {
566     SSMRESULT res = SSM_E_FAIL;
567     std::stringstream sstream;
568     std::string     strSQL;
569     int             columnCount = 0;
570     sqlite3_stmt    *stmt = NULL;
571     const char      *textData = NULL;
572
573     sstream << "select * from [ModelData" << modelId << "] where dataId > " << startIndex << " limit "
574             << count << ";" << std::ends;
575
576     strSQL = sstream.str();
577     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
578
579     *pLastIndex = 0;
580     while (sqlite3_step(stmt) == SQLITE_ROW)
581     {
582         ModelPropertyVec modelProperties;
583
584         columnCount = sqlite3_column_count(stmt);
585         for (int i = 0; i < columnCount; i++)
586         {
587             ModelProperty modelData;
588             switch (sqlite3_column_type(stmt, i))
589             {
590                 case SQLITE_INTEGER:
591                     modelData.propertyType = ModelProperty::TYPE_INTEGER;
592                     sstream.str("");
593                     sstream << sqlite3_column_int(stmt, i) << std::ends;
594                     modelData.propertyValue = sstream.str();
595                     break;
596
597                 case SQLITE_FLOAT:
598                     modelData.propertyType = ModelProperty::TYPE_REAL;
599                     sstream.str("");
600                     sstream << sqlite3_column_double(stmt, i) << std::ends;
601                     modelData.propertyValue = sstream.str();
602                     break;
603
604                 case SQLITE_BLOB:
605                 case SQLITE_TEXT:
606                     modelData.propertyType = ModelProperty::TYPE_TEXT;
607                     textData = (const char *)sqlite3_column_text(stmt, i);
608                     if (textData != NULL)
609                     {
610                         modelData.propertyValue = textData;
611                     }
612                     break;
613
614                 default:
615                     modelData.propertyType = ModelProperty::TYPE_TEXT;
616                     textData = (const char *)sqlite3_column_text(stmt, i);
617                     if (textData != NULL)
618                     {
619                         modelData.propertyValue = textData;
620                     }
621                     break;
622             };
623             modelProperties.push_back(modelData);
624         }
625
626         pDataSet->push_back(modelProperties);
627         *pLastIndex = sqlite3_column_int(stmt, 0);
628     }
629
630     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
631
632     res = SSM_S_OK;
633
634 CLEANUP:
635     return res;
636 }
637
638 SSMRESULT CEvaluationEngine::getModelData(int modelId, int dataId,
639         ModelPropertyVec *pModelProperties)
640 {
641     SSMRESULT       res = SSM_E_FAIL;
642     std::stringstream sstream;
643     std::string     strSQL;
644     int             columnCount = 0;
645     sqlite3_stmt    *stmt = NULL;
646     const char      *textData = NULL;
647
648     sstream << "select * from [ModelData" << modelId << "] where dataId=" << dataId << ";" << std::ends;
649
650     strSQL = sstream.str();
651     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
652
653     while (sqlite3_step(stmt) == SQLITE_ROW)
654     {
655         columnCount = sqlite3_column_count(stmt);
656         for (int i = 0; i < columnCount; i++)
657         {
658             ModelProperty modelData;
659             switch (sqlite3_column_type(stmt, i))
660             {
661                 case SQLITE_INTEGER:
662                     modelData.propertyType = ModelProperty::TYPE_INTEGER;
663                     sstream.str("");
664                     sstream << sqlite3_column_int(stmt, i) << std::ends;
665                     modelData.propertyValue = sstream.str();
666                     break;
667
668                 case SQLITE_FLOAT:
669                     modelData.propertyType = ModelProperty::TYPE_REAL;
670                     sstream.str("");
671                     sstream << sqlite3_column_double(stmt, i) << std::ends;
672                     modelData.propertyValue = sstream.str();
673                     break;
674
675                 case SQLITE_BLOB:
676                 case SQLITE_TEXT:
677                     modelData.propertyType = ModelProperty::TYPE_TEXT;
678                     textData = (const char *)sqlite3_column_text(stmt, i);
679                     if (textData != NULL)
680                     {
681                         modelData.propertyValue = textData;
682                     }
683                     break;
684
685                 default:
686                     modelData.propertyType = ModelProperty::TYPE_TEXT;
687                     textData = (const char *)sqlite3_column_text(stmt, i);
688                     if (textData != NULL)
689                     {
690                         modelData.propertyValue = textData;
691                     }
692                     break;
693             };
694             pModelProperties->push_back(modelData);
695         }
696     }
697
698     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
699
700     res = SSM_S_OK;
701 CLEANUP:
702     return res;
703 }
704 /*
705 SSMRESULT CEvaluationEngine::GetModelSchema(int modelId, ModelPropertyVec *pModelProperties)
706 {
707     SSMRESULT       res = SSM_E_FAIL;
708     std::stringstream sstream;
709     std::string     strSQL;
710     sqlite3_stmt    *stmt = NULL;
711     std::string     propertyType;
712
713     sstream << "pragma table_info('ModelData" << modelId << "');" << std::ends;
714
715     strSQL = sstream.str();
716     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
717
718     while(sqlite3_step(stmt) == SQLITE_ROW)
719     {
720         ModelProperty modelData;
721         modelData.propertyName = (const char*)sqlite3_column_text(stmt, 1);
722         propertyType = (const char*)sqlite3_column_text(stmt, 2);
723
724         if(propertyType == "integer")
725         {
726             modelData.propertyType = ModelProperty::Type_INTEGER;
727         }
728         else if(propertyType == "int")
729         {
730             modelData.propertyType = ModelProperty::Type_INTEGER;
731         }
732         else if(propertyType == "real")
733         {
734             modelData.propertyType = ModelProperty::Type_REAL;
735         }
736         else if(propertyType == "text")
737         {
738             modelData.propertyType = ModelProperty::Type_TEXT;
739         }
740         else
741         {
742             modelData.propertyType = ModelProperty::Type_TEXT;
743         }
744         pModelProperties->push_back(modelData);
745     }
746
747     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
748
749     res = SSM_S_OK;
750 CLEANUP:
751     return res;
752 }
753 */
754 SSMRESULT CEvaluationEngine::getConditionedModelData(int modelId,
755         ModelConditionVec *pModelConditions, IntVec *pDataIds)
756 {
757     SSMRESULT res = SSM_E_FAIL;
758     std::stringstream sstream;
759     std::string strSQL;
760     sqlite3_stmt *stmt = NULL;
761
762     sstream << "select dataId from [ModelData" << modelId <<
763             "] where CURRENT_TIMESTAMP < datetime( strftime('%s', lastTime) + lifetime, 'unixepoch') and ";
764
765     for (ModelConditionVec::iterator itor = pModelConditions->begin();
766          itor != pModelConditions->end(); ++itor)
767     {
768         sstream << itor->modelProperty.propertyName;
769         switch (itor->predicate)
770         {
771             case ModelCondition::PREDICATE_EQ:
772                 sstream << "=";
773                 break;
774
775             case ModelCondition::PREDICATE_NEQ:
776                 sstream << "!=";
777                 break;
778
779             case ModelCondition::PREDICATE_GT:
780                 sstream << ">";
781                 break;
782
783             case ModelCondition::PREDICATE_LT:
784                 sstream << "<";
785                 break;
786
787             case ModelCondition::PREDICATE_GTE:
788                 sstream << ">=";
789                 break;
790
791             case ModelCondition::PREDICATE_LTE:
792                 sstream << "<=";
793                 break;
794
795             default:
796                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
797         }
798
799         switch (itor->modelProperty.propertyType)
800         {
801             case ModelProperty::TYPE_NUMERIC:
802             case ModelProperty::TYPE_INTEGER:
803             case ModelProperty::TYPE_REAL:
804                 sstream << itor->modelProperty.propertyValue;
805                 break;
806
807             case ModelProperty::TYPE_TEXT:
808                 sstream << "'" << itor->modelProperty.propertyValue << "'";
809                 break;
810
811             default:
812                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
813         }
814
815         if (itor < pModelConditions->end() - 1)
816         {
817             sstream << " and ";
818         }
819     }
820
821     sstream << ";" << std::ends;
822
823     strSQL = sstream.str();
824     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
825
826     while (sqlite3_step(stmt) == SQLITE_ROW)
827     {
828         pDataIds->push_back(sqlite3_column_int(stmt, 0));
829     }
830
831     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
832
833     res = SSM_S_OK;
834
835 CLEANUP:
836     return res;
837 }
838
839 SSMRESULT CEvaluationEngine::watchModelData(int modelId, ModelConditionVec *pModelConditions,
840         IEvaluationEngineEvent *pEvaluationEngineEvent, int *pTriggerId)
841 {
842     SSMRESULT res = SSM_E_FAIL;
843     std::stringstream sstream;
844     std::stringstream sstreamCondition;
845
846     for (ModelConditionVec::iterator itor = pModelConditions->begin();
847          itor != pModelConditions->end(); ++itor)
848     {
849         sstreamCondition << "NEW." << itor->modelProperty.propertyName;
850         switch (itor->predicate)
851         {
852             case ModelCondition::PREDICATE_EQ:
853                 sstreamCondition << "=";
854                 break;
855
856             case ModelCondition::PREDICATE_NEQ:
857                 sstreamCondition << "!=";
858                 break;
859
860             case ModelCondition::PREDICATE_GT:
861                 sstreamCondition << ">";
862                 break;
863
864             case ModelCondition::PREDICATE_LT:
865                 sstreamCondition << "<";
866                 break;
867
868             case ModelCondition::PREDICATE_GTE:
869                 sstreamCondition << ">=";
870                 break;
871
872             case ModelCondition::PREDICATE_LTE:
873                 sstreamCondition << "<=";
874                 break;
875
876             default:
877                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
878         }
879
880         switch (itor->modelProperty.propertyType)
881         {
882             case ModelProperty::TYPE_NUMERIC:
883             case ModelProperty::TYPE_INTEGER:
884             case ModelProperty::TYPE_REAL:
885                 sstreamCondition << itor->modelProperty.propertyValue;
886                 break;
887
888             case ModelProperty::TYPE_TEXT:
889                 sstreamCondition << "'" << itor->modelProperty.propertyValue << "'";
890                 break;
891
892             default:
893                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
894         }
895
896         if (itor < pModelConditions->end() - 1)
897         {
898             sstreamCondition << " and ";
899         }
900     }
901
902     sstreamCondition << std::ends;
903
904     m_mtxDataRelation.lock();
905
906     sstream << "CREATE TRIGGER WatchInsertModel" << m_iTriggerId << " AFTER INSERT ON [ModelData" <<
907             modelId << "] WHEN ";
908     sstream << sstreamCondition.str().c_str() << " BEGIN SELECT OnSQLTrigger(" <<
909             reinterpret_cast<intptr_t>(this) << ", " << m_iTriggerId << ", NEW.dataId); END;" << std::ends;
910     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
911     sstream.str("");
912
913     sstream << "CREATE TRIGGER WatchUpdateModel" << m_iTriggerId << " AFTER UPDATE ON [ModelData" <<
914             modelId << "] WHEN ";
915     sstream << sstreamCondition.str().c_str() << " BEGIN SELECT OnSQLTrigger(" <<
916             reinterpret_cast<intptr_t>(this) << ", " << m_iTriggerId << ", NEW.dataId); END;" << std::ends;
917     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
918
919     m_mtxTriggerId.lock();
920     pEvaluationEngineEvent->addRef();
921     m_mapTriggers[m_iTriggerId] = pEvaluationEngineEvent;
922     *pTriggerId = m_iTriggerId++;
923
924 CLEANUP:
925     m_mtxTriggerId.unlock();
926     m_mtxDataRelation.unlock();
927     return res;
928 }
929
930 SSMRESULT CEvaluationEngine::dropWatchModelData(int triggerId)
931 {
932     SSMRESULT res = SSM_E_FAIL;
933     std::stringstream sstream;
934
935     m_mtxDataRelation.lock();
936
937     sstream << "drop trigger WatchInsertModel" << triggerId << ";" << std::ends;
938     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
939     sstream.str("");
940
941     sstream << "drop trigger WatchUpdateModel" << triggerId << ";" << std::ends;
942     SSM_CLEANUP_ASSERT(executeSQL_NoReturn(sstream.str()));
943
944     m_mtxTriggerId.lock();
945     m_mapTriggers[triggerId]->release();
946     m_mapTriggers.erase(triggerId);
947
948 CLEANUP:
949     m_mtxTriggerId.unlock();
950     m_mtxDataRelation.unlock();
951     return res;
952 }
953
954 SSMRESULT CEvaluationEngine::getParentDataId(int modelId, int dataId, int parentModelId,
955         int *pParentDataId)
956 {
957     SSMRESULT res = SSM_E_FAIL;
958     std::stringstream sstream;
959
960     sstream <<
961             "select parent.dataId from [DataRelation] as node, [DataRelation] as parent where parent.modelId="
962             <<
963             parentModelId << " and node.modelId=" << modelId << " and node.dataId=" <<
964             dataId << " and node.lPos between parent.lPos and parent.rPos;" << std::ends;
965
966     m_mtxDataRelation.lock();
967     SSM_CLEANUP_ASSERT(executeSQL_IntReturn(sstream.str(), pParentDataId));
968
969 CLEANUP:
970     m_mtxDataRelation.unlock();
971     return res;
972 }
973
974 SSMRESULT CEvaluationEngine::getChildDataId(int modelId, int dataId, int ChildModelId,
975         IntVec *pChildDataIds)
976 {
977     SSMRESULT res = SSM_E_FAIL;
978     std::stringstream sstream;
979     std::string strSQL;
980     sqlite3_stmt *stmt = NULL;
981
982     sstream <<
983             "select child.dataId from [DataRelation] as node, [DataRelation] as child where child.modelId=" <<
984             ChildModelId << " and node.modelId=" << modelId << " and node.dataId=" <<
985             dataId << " and child.lPos between node.lPos and node.rPos order by child.dataId;" << std::ends;
986
987     strSQL = sstream.str();
988     sstream.str("");
989
990     m_mtxDataRelation.lock();
991     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
992
993     while (sqlite3_step(stmt) == SQLITE_ROW)
994     {
995         pChildDataIds->push_back(sqlite3_column_int(stmt, 0));
996     }
997
998     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
999     res = SSM_S_OK;
1000
1001 CLEANUP:
1002     m_mtxDataRelation.unlock();
1003     return res;
1004 }
1005 /*
1006 SSMRESULT CEvaluationEngine::GetPathToRoot(int currentModelId, IntVec *pPath)
1007 {
1008     SSMRESULT res = SSM_E_FAIL;
1009     std::stringstream sstream;
1010     std::string strSQL;
1011     sqlite3_stmt *stmt = NULL;
1012
1013     sstream << "select parent.modelId from [ModelRelation] as node, [ModelRelation] as parent where " <<
1014         "node.lPos between parent.lPos and parent.rPos and node.modelId = " << currentModelId << " order by node.lPos;" << std::ends;
1015
1016     strSQL = sstream.str();
1017     sstream.str("");
1018     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
1019
1020     while(sqlite3_step(stmt) == SQLITE_ROW)
1021     {
1022         pPath->push_back(sqlite3_column_int(stmt, 0));
1023     }
1024
1025     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
1026
1027     res = SSM_S_OK;
1028 CLEANUP:
1029     return res;
1030 }
1031
1032 SSMRESULT CEvaluationEngine::GetModelId(const char *modelName, int *pModelId)
1033 {
1034     SSMRESULT res = SSM_E_FAIL;
1035     std::stringstream sstream;
1036
1037     sstream << "select modelId from [ModelRelation] where modelName = '" << modelName << "';" << std::ends;
1038
1039     CHK_SSMRESULT(ExecuteSQL_IntReturn(sstream.str(), pModelId));
1040
1041 CLEANUP:
1042     return res;
1043 }
1044
1045 SSMRESULT CEvaluationEngine::GetModelHierarchy(int rootModelId, StringVec *pPath)
1046 {
1047     SSMRESULT res = SSM_E_FAIL;
1048     std::stringstream sstream;
1049     std::string strSQL;
1050     sqlite3_stmt *stmt = NULL;
1051     StringVec   lastModels;
1052     int         currIndex = 0;
1053     int         lastIndex = 0;
1054
1055     sstream << "select node.modelName, (COUNT(parent.modelName) - (sub_tree.depth + 1)) as depth from [ModelRelation] as node, "\
1056         "[ModelRelation] as parent, [ModelRelation] as sub_parent, (select node.modelName, (count(parent.modelName) - 1) as depth from "\
1057         "[ModelRelation] as node, [ModelRelation] as parent where node.lPos between parent.lPos and parent.rPos and node.modelId = " << rootModelId <<
1058         " group by node.lPos, node.modelName) as sub_tree where node.lPos between parent.lPos and parent.rPos and node.lPos between "<<
1059         "sub_parent.lPos and sub_parent.rPos and sub_parent.modelName = sub_tree.modelName group by node.lPos, node.modelName, sub_tree.depth " <<
1060         "order by node.lPos;" << std::ends;
1061
1062     strSQL = sstream.str();
1063     sstream.str("");
1064     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
1065
1066     while(sqlite3_step(stmt) == SQLITE_ROW)
1067     {
1068         currIndex = sqlite3_column_int(stmt, 1);
1069
1070         if(currIndex < lastIndex)
1071
1072         {
1073             for(int i=0; i < lastIndex - currIndex + 1; i++)
1074             {
1075                 lastModels.pop_back();
1076             }
1077         }
1078
1079         lastModels.push_back((const char*)sqlite3_column_text(stmt, 0));
1080
1081         for(StringVec::iterator itor = lastModels.begin();
1082             itor != lastModels.end(); ++itor)
1083         {
1084             sstream << *itor;
1085
1086             if(itor < lastModels.end() - 1)
1087             {
1088                 sstream << ".";
1089             }
1090         }
1091
1092         sstream << std::ends;
1093
1094         pPath->push_back(sstream.str());
1095
1096         sstream.str("");
1097
1098         lastIndex = currIndex;
1099     }
1100
1101     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
1102
1103     res = SSM_S_OK;
1104 CLEANUP:
1105     return res;
1106 }
1107
1108 SSMRESULT CEvaluationEngine::GetDataHierarchy(int rootModelId, int dataId, StringVec *pPath)
1109 {
1110     SSMRESULT res = SSM_E_FAIL;
1111     std::stringstream sstream;
1112     std::string strSQL;
1113     sqlite3_stmt *stmt = NULL;
1114
1115     sstream << "select [ModelRelation].modelName, node.dataId, (COUNT(parent.modelId) - (sub_tree.depth + 1)) as depth "\
1116         "from [ModelRelation], [DataRelation] as node, [DataRelation] as parent, [DataRelation] as sub_parent, "\
1117         "(select node.modelId, (count(parent.modelId) - 1) as depth from [DataRelation] as node, [DataRelation] as parent "\
1118         "where node.lPos between parent.lPos and parent.rPos and node.modelId = " << rootModelId <<
1119         " and node.dataId = " << dataId << " group by node.lPos, node.modelId) as sub_tree "\
1120         "where node.lPos between parent.lPos and parent.rPos and node.lPos between sub_parent.lPos and sub_parent.rPos and "\
1121         "sub_parent.modelId = sub_tree.modelId and [ModelRelation].modelId = node.modelId "\
1122         "group by node.lPos, [ModelRelation].modelName, node.dataId, sub_tree.depth order by node.lPos;" << std::ends;
1123
1124     strSQL = sstream.str();
1125     sstream.str("");
1126     CHK_SQLITE(sqlite3_prepare_v2(m_pSQLite3, strSQL.c_str(), strSQL.length(), &stmt, NULL), SQLITE_OK);
1127
1128     while(sqlite3_step(stmt) == SQLITE_ROW)
1129     {
1130         sstream << sqlite3_column_text(stmt, 0) << " " << sqlite3_column_int(stmt, 1) << " " << sqlite3_column_int(stmt, 2) << std::ends;
1131         pPath->push_back(sstream.str());
1132         sstream.str("");
1133     }
1134
1135     CHK_SQLITE(sqlite3_finalize(stmt), SQLITE_OK);
1136
1137     res = SSM_S_OK;
1138 CLEANUP:
1139     return res;
1140 }
1141 */