implement rules

This commit is contained in:
2023-02-19 01:03:35 -03:00
parent 2f54f13b54
commit ba8788af56
7 changed files with 517 additions and 27 deletions

View File

@@ -174,6 +174,25 @@ void obelisk::KnowledgeBase::addSuggestActions(std::vector<obelisk::SuggestActio
}
}
void obelisk::KnowledgeBase::addRules(std::vector<obelisk::Rule>& rules)
{
for (auto& rule : rules)
{
try
{
rule.insert(dbConnection_);
}
catch (obelisk::DatabaseConstraintException& exception)
{
// ignore unique constraint error
if (std::strcmp(exception.what(), "UNIQUE constraint failed: rule.fact, rule.reason") != 0)
{
throw;
}
}
}
}
void obelisk::KnowledgeBase::getEntity(obelisk::Entity& entity)
{
entity.selectByName(dbConnection_);
@@ -199,6 +218,11 @@ void obelisk::KnowledgeBase::getSuggestAction(obelisk::SuggestAction& suggestAct
suggestAction.selectById(dbConnection_);
}
void obelisk::KnowledgeBase::getRule(obelisk::Rule& rule)
{
rule.selectById(dbConnection_);
}
void obelisk::KnowledgeBase::getFloat(float& result1, float& result2, double var)
{
result1 = (float) var;

View File

@@ -127,6 +127,14 @@ namespace obelisk
*/
void addSuggestActions(std::vector<obelisk::SuggestAction>& suggestActions);
/**
* @brief Add rules to the KnowledgeBase.
*
* @param[in,out] rules The rules to add. If the insert is successful it
* will have a row ID, if not the ID will be 0.
*/
void addRules(std::vector<obelisk::Rule>& rules);
/**
* @brief Get an Entity object based on the ID it contains.
*
@@ -167,6 +175,14 @@ namespace obelisk
*/
void getSuggestAction(obelisk::SuggestAction& suggestAction);
/**
* @brief Get a Rule based on the ID it contains.
*
* @param[in,out] rule The Rule object should contain just the ID
* and the rest will be filled in.
*/
void getRule(obelisk::Rule& rule);
/**
* @brief Take a float and divide it into 2 floats.
*

View File

@@ -1,3 +1,4 @@
#include "models/error.h"
#include "models/rule.h"
const char* obelisk::Rule::createTable()
@@ -15,6 +16,173 @@ const char* obelisk::Rule::createTable()
)";
}
void obelisk::Rule::selectById(sqlite3* dbConnection)
{
if (dbConnection == nullptr)
{
throw obelisk::DatabaseException("database isn't open");
}
sqlite3_stmt* ppStmt = nullptr;
auto result = sqlite3_prepare_v2(dbConnection,
"SELECT id, fact, reason FROM rule WHERE (fact=? AND reason=?)",
-1,
&ppStmt,
nullptr);
if (result != SQLITE_OK)
{
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
}
result = sqlite3_bind_int(ppStmt, 1, getFact().getId());
switch (result)
{
case SQLITE_OK :
break;
case SQLITE_TOOBIG :
throw obelisk::DatabaseSizeException();
break;
case SQLITE_RANGE :
throw obelisk::DatabaseRangeException();
break;
case SQLITE_NOMEM :
throw obelisk::DatabaseMemoryException();
break;
default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
break;
}
result = sqlite3_bind_int(ppStmt, 2, getReason().getId());
switch (result)
{
case SQLITE_OK :
break;
case SQLITE_TOOBIG :
throw obelisk::DatabaseSizeException();
break;
case SQLITE_RANGE :
throw obelisk::DatabaseRangeException();
break;
case SQLITE_NOMEM :
throw obelisk::DatabaseMemoryException();
break;
default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
break;
}
result = sqlite3_step(ppStmt);
switch (result)
{
case SQLITE_DONE :
// no rows in the database
break;
case SQLITE_ROW :
setId(sqlite3_column_int(ppStmt, 0));
getFact().setId(sqlite3_column_int(ppStmt, 1));
getReason().setId(sqlite3_column_int(ppStmt, 2));
break;
case SQLITE_BUSY :
throw obelisk::DatabaseBusyException();
break;
case SQLITE_MISUSE :
throw obelisk::DatabaseMisuseException();
break;
default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
break;
}
result = sqlite3_finalize(ppStmt);
if (result != SQLITE_OK)
{
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
}
}
void obelisk::Rule::insert(sqlite3* dbConnection)
{
if (dbConnection == nullptr)
{
throw obelisk::DatabaseException("database isn't open");
}
sqlite3_stmt* ppStmt = nullptr;
auto result
= sqlite3_prepare_v2(dbConnection, "INSERT INTO rule (fact, reason) VALUES (?, ?)", -1, &ppStmt, nullptr);
if (result != SQLITE_OK)
{
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
}
result = sqlite3_bind_int(ppStmt, 1, getFact().getId());
switch (result)
{
case SQLITE_OK :
break;
case SQLITE_TOOBIG :
throw obelisk::DatabaseSizeException();
break;
case SQLITE_RANGE :
throw obelisk::DatabaseRangeException();
break;
case SQLITE_NOMEM :
throw obelisk::DatabaseMemoryException();
break;
default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
break;
}
result = sqlite3_bind_int(ppStmt, 2, getReason().getId());
switch (result)
{
case SQLITE_OK :
break;
case SQLITE_TOOBIG :
throw obelisk::DatabaseSizeException();
break;
case SQLITE_RANGE :
throw obelisk::DatabaseRangeException();
break;
case SQLITE_NOMEM :
throw obelisk::DatabaseMemoryException();
break;
default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
break;
}
result = sqlite3_step(ppStmt);
switch (result)
{
case SQLITE_DONE :
setId((int) sqlite3_last_insert_rowid(dbConnection));
sqlite3_set_last_insert_rowid(dbConnection, 0);
break;
case SQLITE_CONSTRAINT :
throw obelisk::DatabaseConstraintException(sqlite3_errmsg(dbConnection));
case SQLITE_BUSY :
throw obelisk::DatabaseBusyException();
break;
case SQLITE_MISUSE :
throw obelisk::DatabaseMisuseException();
break;
default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
break;
}
result = sqlite3_finalize(ppStmt);
if (result != SQLITE_OK)
{
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
}
}
int& obelisk::Rule::getId()
{
return id_;

View File

@@ -131,6 +131,21 @@ namespace obelisk
* @param[in] reason The reason Fact.
*/
void setReason(obelisk::Fact reason);
/**
* @brief Select the Rule from the KnowledgeBase by IDs of the
* sub-objects.
*
* @param[in] dbConnection The database connection to use.
*/
void selectById(sqlite3* dbConnection);
/**
* @brief Insert the Rule into the KnowledgeBase.
*
* @param[in] dbConnection The database connection to use.
*/
void insert(sqlite3* dbConnection);
};
} // namespace obelisk