#include "models/error.h" #include "models/fact.h" const char* obelisk::Fact::createTable() { return R"( CREATE TABLE "fact" ( "id" INTEGER NOT NULL UNIQUE, "left_entity" INTEGER NOT NULL, "verb" INTEGER NOT NULL, "right_entity" INTEGER NOT NULL, "is_true" INTEGER NOT NULL DEFAULT 0, PRIMARY KEY("id" AUTOINCREMENT), UNIQUE("left_entity", "right_entity", "verb") FOREIGN KEY("verb") REFERENCES "verb"("id") ON DELETE RESTRICT, FOREIGN KEY("right_entity") REFERENCES "entity"("id") ON DELETE RESTRICT, FOREIGN KEY("left_entity") REFERENCES "entity"("id") ON DELETE RESTRICT ); )"; } void obelisk::Fact::selectById(sqlite3* dbConnection) { if (dbConnection == nullptr) { throw obelisk::DatabaseException("database isn't open"); } sqlite3_stmt* ppStmt = nullptr; const char* query; if (getId() == 0) { query = "SELECT id, left_entity, right_entity, verb, is_true FROM fact WHERE (left_entity=? AND right_entity=? AND verb=?)"; } else { query = "SELECT id, left_entity, right_entity, verb, is_true FROM fact WHERE (id=?)"; } auto result = sqlite3_prepare_v2(dbConnection, query, -1, &ppStmt, nullptr); if (result != SQLITE_OK) { throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); } if (getId() == 0) { result = sqlite3_bind_int(ppStmt, 1, getLeftEntity().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, getRightEntity().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, 3, getVerb().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; } } else { result = sqlite3_bind_int(ppStmt, 1, 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)); getLeftEntity().setId(sqlite3_column_int(ppStmt, 1)); getRightEntity().setId(sqlite3_column_int(ppStmt, 2)); getVerb().setId(sqlite3_column_int(ppStmt, 3)); setIsTrue(sqlite3_column_int(ppStmt, 4)); 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::Fact::selectByName(sqlite3* dbConnection) { if (dbConnection == nullptr) { throw obelisk::DatabaseException("database isn't open"); } sqlite3_stmt* ppStmt = nullptr; auto result = sqlite3_prepare_v2(dbConnection, "SELECT fact.id, fact.left_entity, fact.right_entity, fact.verb, fact.is_true FROM fact LEFT JOIN entity le ON le.id = fact.left_entity LEFT JOIN entity re ON re.id = fact.right_entity LEFT JOIN verb v ON fact.verb = v.id WHERE (le.name=? AND v.name=? AND re.name=?)", -1, &ppStmt, nullptr); if (result != SQLITE_OK) { throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); } result = sqlite3_bind_text(ppStmt, 1, getLeftEntity().getName().c_str(), -1, SQLITE_STATIC); 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_text(ppStmt, 2, getVerb().getName().c_str(), -1, SQLITE_STATIC); 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_text(ppStmt, 3, getRightEntity().getName().c_str(), -1, SQLITE_STATIC); 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)); getLeftEntity().setId(sqlite3_column_int(ppStmt, 1)); getRightEntity().setId(sqlite3_column_int(ppStmt, 2)); getVerb().setId(sqlite3_column_int(ppStmt, 3)); setIsTrue(sqlite3_column_int(ppStmt, 4)); 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::Fact::selectActionByFact(sqlite3* dbConnection, obelisk::Action& action) { if (dbConnection == nullptr) { throw obelisk::DatabaseException("database isn't open"); } sqlite3_stmt* ppStmt = nullptr; auto result = sqlite3_prepare_v2(dbConnection, "SELECT CASE f.is_true WHEN 0 THEN (SELECT name FROM action WHERE id = fa.id) WHEN 1 THEN (SELECT name from action WHERE id = ta.id) END action FROM suggest_action LEFT JOIN action ta ON ta.id = suggest_action.true_action LEFT JOIN action fa ON fa.id = suggest_action.false_action LEFT JOIN fact f ON f.id = suggest_action.fact WHERE (f.id = ?)", -1, &ppStmt, nullptr); if (result != SQLITE_OK) { throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); } result = sqlite3_bind_int(ppStmt, 1, 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 : action.setName((char*) sqlite3_column_text(ppStmt, 0)); 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::Fact::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 fact (left_entity, right_entity, verb, is_true) VALUES (?, ?, ?, ?)", -1, &ppStmt, nullptr); if (result != SQLITE_OK) { throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); } result = sqlite3_bind_int(ppStmt, 1, getLeftEntity().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, getRightEntity().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, 3, getVerb().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, 4, getIsTrue()); 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)); } } void obelisk::Fact::updateIsTrue(sqlite3* dbConnection) { if (dbConnection == nullptr) { throw obelisk::DatabaseException("database isn't open"); } sqlite3_stmt* ppStmt = nullptr; auto result = sqlite3_prepare_v2(dbConnection, "UPDATE fact SET is_true=? WHERE id=?", -1, &ppStmt, nullptr); if (result != SQLITE_OK) { throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); } result = sqlite3_bind_int(ppStmt, 1, getIsTrue()); 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, 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 : // Row updated 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::Fact::getId() { return id_; } void obelisk::Fact::setId(int id) { id_ = id; } obelisk::Entity& obelisk::Fact::getLeftEntity() { return leftEntity_; } void obelisk::Fact::setLeftEntity(obelisk::Entity leftEntity) { leftEntity_ = leftEntity; } obelisk::Entity& obelisk::Fact::getRightEntity() { return rightEntity_; } void obelisk::Fact::setRightEntity(obelisk::Entity rightEntity) { rightEntity_ = rightEntity; } obelisk::Verb& obelisk::Fact::getVerb() { return verb_; } void obelisk::Fact::setVerb(obelisk::Verb verb) { verb_ = verb; } double& obelisk::Fact::getIsTrue() { return isTrue_; } void obelisk::Fact::setIsTrue(double isTrue) { isTrue_ = isTrue; }