feature/fact_knowledge_base #7
@ -1,13 +1,16 @@
|
|||||||
#include "knowledge_base.h"
|
#include "knowledge_base.h"
|
||||||
#include "models/action.h"
|
#include "models/action.h"
|
||||||
#include "models/entity.h"
|
#include "models/entity.h"
|
||||||
|
#include "models/error.h"
|
||||||
#include "models/fact.h"
|
#include "models/fact.h"
|
||||||
#include "models/rule.h"
|
#include "models/rule.h"
|
||||||
#include "models/suggest_action.h"
|
#include "models/suggest_action.h"
|
||||||
#include "models/verb.h"
|
#include "models/verb.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
obelisk::KnowledgeBase::KnowledgeBase(const char* filename, int flags)
|
obelisk::KnowledgeBase::KnowledgeBase(const char* filename, int flags)
|
||||||
{
|
{
|
||||||
@ -23,6 +26,8 @@ obelisk::KnowledgeBase::KnowledgeBase(const char* filename, int flags)
|
|||||||
logSqliteError(result);
|
logSqliteError(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableForeignKeys();
|
||||||
|
|
||||||
if (!dbExists)
|
if (!dbExists)
|
||||||
{
|
{
|
||||||
createTable(obelisk::Action::createTable);
|
createTable(obelisk::Action::createTable);
|
||||||
@ -42,16 +47,25 @@ obelisk::KnowledgeBase::~KnowledgeBase()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void obelisk::KnowledgeBase::createTable(std::function<const char*()> function)
|
/**
|
||||||
|
* @brief Enable foreign key functionality in the open database.
|
||||||
|
*
|
||||||
|
* This must always be done when the connection is opened or it will not
|
||||||
|
* enforce the foreign key constraints.
|
||||||
|
*/
|
||||||
|
void obelisk::KnowledgeBase::enableForeignKeys()
|
||||||
{
|
{
|
||||||
char* tmp;
|
char* errmsg;
|
||||||
auto result = sqlite3_exec(dbConnection_, function(), NULL, NULL, &tmp);
|
int result = sqlite3_exec(dbConnection_,
|
||||||
|
"PRAGMA foreign_keys = ON;",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&errmsg);
|
||||||
if (result != SQLITE_OK)
|
if (result != SQLITE_OK)
|
||||||
{
|
{
|
||||||
logSqliteError(result);
|
logSqliteError(result);
|
||||||
if (tmp)
|
if (errmsg)
|
||||||
{
|
{
|
||||||
std::string errmsg(tmp);
|
|
||||||
throw obelisk::KnowledgeBaseException(errmsg);
|
throw obelisk::KnowledgeBaseException(errmsg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -61,53 +75,103 @@ void obelisk::KnowledgeBase::createTable(std::function<const char*()> function)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: change these to throw errors instead of return int
|
void obelisk::KnowledgeBase::createTable(std::function<const char*()> function)
|
||||||
int obelisk::KnowledgeBase::addEntities(std::vector<obelisk::Entity>& entities)
|
{
|
||||||
|
char* errmsg;
|
||||||
|
int result = sqlite3_exec(dbConnection_, function(), NULL, NULL, &errmsg);
|
||||||
|
if (result != SQLITE_OK)
|
||||||
|
{
|
||||||
|
logSqliteError(result);
|
||||||
|
if (errmsg)
|
||||||
|
{
|
||||||
|
throw obelisk::KnowledgeBaseException(errmsg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw obelisk::KnowledgeBaseException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void obelisk::KnowledgeBase::addEntities(std::vector<obelisk::Entity>& entities)
|
||||||
{
|
{
|
||||||
for (auto& entity : entities)
|
for (auto& entity : entities)
|
||||||
{
|
{
|
||||||
entity.insertEntity(dbConnection_);
|
try
|
||||||
|
{
|
||||||
|
entity.insertEntity(dbConnection_);
|
||||||
|
}
|
||||||
|
catch (obelisk::DatabaseException::ConstraintException& exception)
|
||||||
|
{
|
||||||
|
// ignore unique constraint error
|
||||||
|
if (std::strcmp(exception.what(),
|
||||||
|
"UNIQUE constraint failed: entity.name")
|
||||||
|
!= 0)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int obelisk::KnowledgeBase::addVerbs(std::vector<obelisk::Verb>& verbs)
|
void obelisk::KnowledgeBase::addVerbs(std::vector<obelisk::Verb>& verbs)
|
||||||
{
|
{
|
||||||
for (auto& verb : verbs)
|
for (auto& verb : verbs)
|
||||||
{
|
{
|
||||||
verb.insertVerb(dbConnection_);
|
try
|
||||||
|
{
|
||||||
|
verb.insertVerb(dbConnection_);
|
||||||
|
}
|
||||||
|
catch (obelisk::DatabaseException::ConstraintException& exception)
|
||||||
|
{
|
||||||
|
// ignore unique constraint error
|
||||||
|
if (std::strcmp(exception.what(),
|
||||||
|
"UNIQUE constraint failed: verb.name")
|
||||||
|
!= 0)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int obelisk::KnowledgeBase::addFacts(std::vector<obelisk::Fact>& facts)
|
void obelisk::KnowledgeBase::addFacts(std::vector<obelisk::Fact>& facts)
|
||||||
{
|
{
|
||||||
for (auto& fact : facts)
|
for (auto& fact : facts)
|
||||||
{
|
{
|
||||||
fact.insertFact(dbConnection_);
|
try
|
||||||
|
{
|
||||||
|
fact.insertFact(dbConnection_);
|
||||||
|
}
|
||||||
|
catch (obelisk::DatabaseException::ConstraintException& exception)
|
||||||
|
{
|
||||||
|
// ignore unique constraint error
|
||||||
|
if (std::strcmp(exception.what(),
|
||||||
|
"UNIQUE constraint failed: fact.left_entity, fact.right_entity, fact.verb")
|
||||||
|
!= 0)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int obelisk::KnowledgeBase::getEntity(obelisk::Entity& entity)
|
void obelisk::KnowledgeBase::getEntity(obelisk::Entity& entity)
|
||||||
{
|
{
|
||||||
entity.selectEntity(dbConnection_);
|
entity.selectEntity(dbConnection_);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int obelisk::KnowledgeBase::getVerb(obelisk::Verb& verb)
|
void obelisk::KnowledgeBase::getVerb(obelisk::Verb& verb)
|
||||||
{
|
{
|
||||||
verb.selectVerb(dbConnection_);
|
verb.selectVerb(dbConnection_);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int obelisk::KnowledgeBase::getFact(obelisk::Fact& fact)
|
void obelisk::KnowledgeBase::getFact(obelisk::Fact& fact)
|
||||||
{
|
{
|
||||||
fact.selectFact(dbConnection_);
|
fact.selectFact(dbConnection_);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: log files?
|
// TODO: log files? or just throw an error?
|
||||||
void obelisk::KnowledgeBase::logSqliteError(int result)
|
void obelisk::KnowledgeBase::logSqliteError(int result)
|
||||||
{
|
{
|
||||||
std::cout << sqlite3_errstr(result) << std::endl;
|
std::cout << sqlite3_errstr(result) << std::endl;
|
||||||
|
@ -24,6 +24,7 @@ namespace obelisk
|
|||||||
int flags_;
|
int flags_;
|
||||||
void logSqliteError(int result);
|
void logSqliteError(int result);
|
||||||
|
|
||||||
|
void enableForeignKeys();
|
||||||
void createTable(std::function<const char*()> function);
|
void createTable(std::function<const char*()> function);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -37,13 +38,13 @@ namespace obelisk
|
|||||||
|
|
||||||
~KnowledgeBase();
|
~KnowledgeBase();
|
||||||
|
|
||||||
int addEntities(std::vector<obelisk::Entity>& entities);
|
void addEntities(std::vector<obelisk::Entity>& entities);
|
||||||
int addVerbs(std::vector<obelisk::Verb>& verbs);
|
void addVerbs(std::vector<obelisk::Verb>& verbs);
|
||||||
int addFacts(std::vector<obelisk::Fact>& facts);
|
void addFacts(std::vector<obelisk::Fact>& facts);
|
||||||
|
|
||||||
int getEntity(obelisk::Entity& entity);
|
void getEntity(obelisk::Entity& entity);
|
||||||
int getVerb(obelisk::Verb& verb);
|
void getVerb(obelisk::Verb& verb);
|
||||||
int getFact(obelisk::Fact& fact);
|
void getFact(obelisk::Fact& fact);
|
||||||
|
|
||||||
void getDouble(double& result, float var1, float var2);
|
void getDouble(double& result, float var1, float var2);
|
||||||
void getFloat(float& result1, float& result2, double var);
|
void getFloat(float& result1, float& result2, double var);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "models/entity.h"
|
#include "models/entity.h"
|
||||||
|
#include "models/error.h"
|
||||||
|
|
||||||
const char* obelisk::Entity::createTable()
|
const char* obelisk::Entity::createTable()
|
||||||
{
|
{
|
||||||
@ -11,118 +12,139 @@ const char* obelisk::Entity::createTable()
|
|||||||
)";
|
)";
|
||||||
}
|
}
|
||||||
|
|
||||||
int obelisk::Entity::selectEntity(sqlite3* dbConnection)
|
void obelisk::Entity::selectEntity(sqlite3* dbConnection)
|
||||||
{
|
{
|
||||||
// TODO: check if database is open
|
if (dbConnection == nullptr)
|
||||||
|
{
|
||||||
|
throw obelisk::DatabaseException("database isn't open");
|
||||||
|
}
|
||||||
|
|
||||||
sqlite3_stmt* ppStmt = nullptr;
|
sqlite3_stmt* ppStmt = nullptr;
|
||||||
const char* pzTail = nullptr;
|
|
||||||
|
|
||||||
auto result = sqlite3_prepare_v2(dbConnection,
|
auto result = sqlite3_prepare_v2(dbConnection,
|
||||||
"SELECT id, name FROM entity WHERE name=?;",
|
"SELECT id, name FROM entity WHERE name=?",
|
||||||
-1,
|
-1,
|
||||||
&ppStmt,
|
&ppStmt,
|
||||||
&pzTail);
|
nullptr);
|
||||||
|
|
||||||
if (result != SQLITE_OK)
|
if (result != SQLITE_OK)
|
||||||
{
|
{
|
||||||
// TODO: something went wrong throw an error
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pzTail != nullptr)
|
result = sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_STATIC);
|
||||||
|
switch (result)
|
||||||
{
|
{
|
||||||
// TODO: Something was not used... throw an error
|
case SQLITE_OK :
|
||||||
}
|
break;
|
||||||
|
case SQLITE_TOOBIG :
|
||||||
result
|
throw obelisk::DatabaseException::SizeException();
|
||||||
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
|
break;
|
||||||
if (result != SQLITE_OK)
|
case SQLITE_RANGE :
|
||||||
{
|
throw obelisk::DatabaseException::RangeException();
|
||||||
// TODO: Something is wrong... throw an error
|
break;
|
||||||
|
case SQLITE_NOMEM :
|
||||||
|
throw obelisk::DatabaseException::MemoryException();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = sqlite3_step(ppStmt);
|
result = sqlite3_step(ppStmt);
|
||||||
if (result != SQLITE_DONE)
|
switch (result)
|
||||||
{
|
{
|
||||||
// TODO: Something is wrong... throw an error
|
case SQLITE_DONE :
|
||||||
|
// no rows in the database
|
||||||
|
break;
|
||||||
|
case SQLITE_ROW :
|
||||||
|
setId(sqlite3_column_int(ppStmt, 0));
|
||||||
|
setName((char*) sqlite3_column_text(ppStmt, 1));
|
||||||
|
break;
|
||||||
|
case SQLITE_BUSY :
|
||||||
|
throw obelisk::DatabaseException::BusyException();
|
||||||
|
break;
|
||||||
|
case SQLITE_MISUSE :
|
||||||
|
throw obelisk::DatabaseException::MisuseException();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == SQLITE_ROW)
|
result = sqlite3_finalize(ppStmt);
|
||||||
{
|
|
||||||
setId(sqlite3_column_int(ppStmt, 0));
|
|
||||||
setName((char*) sqlite3_column_text(ppStmt, 1));
|
|
||||||
|
|
||||||
result = sqlite3_finalize(ppStmt);
|
if (result != SQLITE_OK)
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
result = sqlite3_finalize(ppStmt);
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int obelisk::Entity::insertEntity(sqlite3* dbConnection)
|
void obelisk::Entity::insertEntity(sqlite3* dbConnection)
|
||||||
{
|
{
|
||||||
// TODO: check if database is open
|
if (dbConnection == nullptr)
|
||||||
|
|
||||||
/*selectEntity(dbConnection);
|
|
||||||
if (getId() != 0)
|
|
||||||
{
|
{
|
||||||
// TODO: already exists in database, throw an error? Or skip past it?
|
throw obelisk::DatabaseException("database isn't open");
|
||||||
return -1;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
sqlite3_stmt* ppStmt = nullptr;
|
|
||||||
const char* pzTail = nullptr;
|
|
||||||
|
|
||||||
auto result = sqlite3_prepare_v2(dbConnection,
|
|
||||||
"INSERT INTO entity (name) VALUES (?);",
|
|
||||||
-1,
|
|
||||||
&ppStmt,
|
|
||||||
&pzTail);
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: something went wrong throw an error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pzTail != nullptr)
|
sqlite3_stmt* ppStmt = nullptr;
|
||||||
|
|
||||||
|
auto result = sqlite3_prepare_v2(dbConnection,
|
||||||
|
"INSERT INTO entity (name) VALUES (?)",
|
||||||
|
-1,
|
||||||
|
&ppStmt,
|
||||||
|
nullptr);
|
||||||
|
if (result != SQLITE_OK)
|
||||||
{
|
{
|
||||||
// TODO: Something was not used... throw an error
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
|
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
|
||||||
if (result != SQLITE_OK)
|
switch (result)
|
||||||
{
|
{
|
||||||
// TODO: Something is wrong... throw an error
|
case SQLITE_OK :
|
||||||
|
break;
|
||||||
|
case SQLITE_TOOBIG :
|
||||||
|
throw obelisk::DatabaseException::SizeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_RANGE :
|
||||||
|
throw obelisk::DatabaseException::RangeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_NOMEM :
|
||||||
|
throw obelisk::DatabaseException::MemoryException();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = sqlite3_step(ppStmt);
|
result = sqlite3_step(ppStmt);
|
||||||
if (result != SQLITE_DONE)
|
switch (result)
|
||||||
{
|
{
|
||||||
// TODO: Something is wrong... throw an error
|
case SQLITE_DONE :
|
||||||
|
setId((int) sqlite3_last_insert_rowid(dbConnection));
|
||||||
|
sqlite3_set_last_insert_rowid(dbConnection, 0);
|
||||||
|
break;
|
||||||
|
case SQLITE_CONSTRAINT :
|
||||||
|
throw obelisk::DatabaseException::ConstraintException(
|
||||||
|
sqlite3_errmsg(dbConnection));
|
||||||
|
case SQLITE_BUSY :
|
||||||
|
throw obelisk::DatabaseException::BusyException();
|
||||||
|
break;
|
||||||
|
case SQLITE_MISUSE :
|
||||||
|
throw obelisk::DatabaseException::MisuseException();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
setId((int) sqlite3_last_insert_rowid(dbConnection));
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_set_last_insert_rowid(dbConnection, 0);
|
|
||||||
|
|
||||||
result = sqlite3_finalize(ppStmt);
|
result = sqlite3_finalize(ppStmt);
|
||||||
if (result != SQLITE_OK)
|
if (result != SQLITE_OK)
|
||||||
{
|
{
|
||||||
// TODO: Something is wrong... throw an error
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int& obelisk::Entity::getId()
|
int& obelisk::Entity::getId()
|
||||||
|
@ -46,8 +46,8 @@ namespace obelisk
|
|||||||
std::string& getName();
|
std::string& getName();
|
||||||
void setName(std::string name);
|
void setName(std::string name);
|
||||||
|
|
||||||
int selectEntity(sqlite3* dbConnection);
|
void selectEntity(sqlite3* dbConnection);
|
||||||
int insertEntity(sqlite3* dbConnection);
|
void insertEntity(sqlite3* dbConnection);
|
||||||
};
|
};
|
||||||
} // namespace obelisk
|
} // namespace obelisk
|
||||||
|
|
||||||
|
146
src/models/error.h
Normal file
146
src/models/error.h
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#ifndef OBELISK_MODELS_ERROR_H
|
||||||
|
#define OBELISK_MODELS_ERROR_H
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace obelisk
|
||||||
|
{
|
||||||
|
class DatabaseException : public std::exception
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const std::string errorMessage_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DatabaseException() :
|
||||||
|
errorMessage_("an unknown error ocurred")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseException(const int errorCode) :
|
||||||
|
errorMessage_(
|
||||||
|
"database error " + std::to_string(errorCode) + " ocurred")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseException(const std::string& errorMessage) :
|
||||||
|
errorMessage_(errorMessage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* what() const noexcept
|
||||||
|
{
|
||||||
|
return errorMessage_.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
class SizeException : public std::exception
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const std::string errorMessage_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SizeException() :
|
||||||
|
errorMessage_("size of string or blob exceeds limits")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* what() const noexcept
|
||||||
|
{
|
||||||
|
return errorMessage_.c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class RangeException : public std::exception
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const std::string errorMessage_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RangeException() :
|
||||||
|
errorMessage_("parameter index is out of range")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* what() const noexcept
|
||||||
|
{
|
||||||
|
return errorMessage_.c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MemoryException : public std::exception
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const std::string errorMessage_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MemoryException() :
|
||||||
|
errorMessage_("not enough memory for operation")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* what() const noexcept
|
||||||
|
{
|
||||||
|
return errorMessage_.c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BusyException : public std::exception
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const std::string errorMessage_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BusyException() :
|
||||||
|
errorMessage_(
|
||||||
|
"database was busy and operation not performed")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* what() const noexcept
|
||||||
|
{
|
||||||
|
return errorMessage_.c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MisuseException : public std::exception
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const std::string errorMessage_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MisuseException() :
|
||||||
|
errorMessage_("misuse of the database routine")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* what() const noexcept
|
||||||
|
{
|
||||||
|
return errorMessage_.c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConstraintException : public std::exception
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const std::string errorMessage_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ConstraintException() :
|
||||||
|
errorMessage_("a constraint exception occurred")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintException(const std::string& errorMessage) :
|
||||||
|
errorMessage_(errorMessage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* what() const noexcept
|
||||||
|
{
|
||||||
|
return errorMessage_.c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // namespace obelisk
|
||||||
|
|
||||||
|
#endif
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "models/error.h"
|
||||||
#include "models/fact.h"
|
#include "models/fact.h"
|
||||||
|
|
||||||
const char* obelisk::Fact::createTable()
|
const char* obelisk::Fact::createTable()
|
||||||
@ -9,6 +10,7 @@ const char* obelisk::Fact::createTable()
|
|||||||
"right_entity" INTEGER NOT NULL,
|
"right_entity" INTEGER NOT NULL,
|
||||||
"verb" INTEGER NOT NULL,
|
"verb" INTEGER NOT NULL,
|
||||||
PRIMARY KEY("id" AUTOINCREMENT),
|
PRIMARY KEY("id" AUTOINCREMENT),
|
||||||
|
UNIQUE("left_entity", "right_entity", "verb")
|
||||||
FOREIGN KEY("verb") REFERENCES "verb"("id") ON DELETE RESTRICT,
|
FOREIGN KEY("verb") REFERENCES "verb"("id") ON DELETE RESTRICT,
|
||||||
FOREIGN KEY("right_entity") REFERENCES "entity"("id") ON DELETE RESTRICT,
|
FOREIGN KEY("right_entity") REFERENCES "entity"("id") ON DELETE RESTRICT,
|
||||||
FOREIGN KEY("left_entity") REFERENCES "entity"("id") ON DELETE RESTRICT
|
FOREIGN KEY("left_entity") REFERENCES "entity"("id") ON DELETE RESTRICT
|
||||||
@ -16,146 +18,214 @@ const char* obelisk::Fact::createTable()
|
|||||||
)";
|
)";
|
||||||
}
|
}
|
||||||
|
|
||||||
int obelisk::Fact::selectFact(sqlite3* dbConnection)
|
void obelisk::Fact::selectFact(sqlite3* dbConnection)
|
||||||
{
|
{
|
||||||
// TODO: check if database is open
|
if (dbConnection == nullptr)
|
||||||
|
|
||||||
sqlite3_stmt* ppStmt = nullptr;
|
|
||||||
const char* pzTail = nullptr;
|
|
||||||
|
|
||||||
auto result = sqlite3_prepare_v2(dbConnection,
|
|
||||||
"SELECT id, left_entity, right_entity, verb FROM fact WHERE (left_entity=? AND right_entity=? AND verb=?);",
|
|
||||||
-1,
|
|
||||||
&ppStmt,
|
|
||||||
&pzTail);
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
{
|
||||||
// TODO: something went wrong throw an error
|
throw obelisk::DatabaseException("database isn't open");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pzTail != nullptr)
|
sqlite3_stmt* ppStmt = nullptr;
|
||||||
|
|
||||||
|
auto result = sqlite3_prepare_v2(dbConnection,
|
||||||
|
"SELECT id, left_entity, right_entity, verb FROM fact WHERE (left_entity=? AND right_entity=? AND verb=?)",
|
||||||
|
-1,
|
||||||
|
&ppStmt,
|
||||||
|
nullptr);
|
||||||
|
if (result != SQLITE_OK)
|
||||||
{
|
{
|
||||||
// TODO: Something was not used... throw an error
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
}
|
}
|
||||||
|
|
||||||
result = sqlite3_bind_int(ppStmt, 1, getLeftEntity().getId());
|
result = sqlite3_bind_int(ppStmt, 1, getLeftEntity().getId());
|
||||||
if (result != SQLITE_OK)
|
switch (result)
|
||||||
{
|
{
|
||||||
// TODO: Something is wrong... throw an error
|
case SQLITE_OK :
|
||||||
|
break;
|
||||||
|
case SQLITE_TOOBIG :
|
||||||
|
throw obelisk::DatabaseException::SizeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_RANGE :
|
||||||
|
throw obelisk::DatabaseException::RangeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_NOMEM :
|
||||||
|
throw obelisk::DatabaseException::MemoryException();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = sqlite3_bind_int(ppStmt, 2, getRightEntity().getId());
|
result = sqlite3_bind_int(ppStmt, 2, getRightEntity().getId());
|
||||||
if (result != SQLITE_OK)
|
switch (result)
|
||||||
{
|
{
|
||||||
// TODO: Something is wrong... throw an error
|
case SQLITE_OK :
|
||||||
|
break;
|
||||||
|
case SQLITE_TOOBIG :
|
||||||
|
throw obelisk::DatabaseException::SizeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_RANGE :
|
||||||
|
throw obelisk::DatabaseException::RangeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_NOMEM :
|
||||||
|
throw obelisk::DatabaseException::MemoryException();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = sqlite3_bind_int(ppStmt, 3, getVerb().getId());
|
result = sqlite3_bind_int(ppStmt, 3, getVerb().getId());
|
||||||
if (result != SQLITE_OK)
|
switch (result)
|
||||||
{
|
{
|
||||||
// TODO: Something is wrong... throw an error
|
case SQLITE_OK :
|
||||||
|
break;
|
||||||
|
case SQLITE_TOOBIG :
|
||||||
|
throw obelisk::DatabaseException::SizeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_RANGE :
|
||||||
|
throw obelisk::DatabaseException::RangeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_NOMEM :
|
||||||
|
throw obelisk::DatabaseException::MemoryException();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = sqlite3_step(ppStmt);
|
result = sqlite3_step(ppStmt);
|
||||||
if (result != SQLITE_DONE)
|
switch (result)
|
||||||
{
|
{
|
||||||
// TODO: Something is wrong... throw an error
|
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));
|
||||||
|
break;
|
||||||
|
case SQLITE_BUSY :
|
||||||
|
throw obelisk::DatabaseException::BusyException();
|
||||||
|
break;
|
||||||
|
case SQLITE_MISUSE :
|
||||||
|
throw obelisk::DatabaseException::MisuseException();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == 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));
|
|
||||||
|
|
||||||
result = sqlite3_finalize(ppStmt);
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = sqlite3_finalize(ppStmt);
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int obelisk::Fact::insertFact(sqlite3* dbConnection)
|
|
||||||
{
|
|
||||||
// TODO: make sure database is open
|
|
||||||
|
|
||||||
// check if the fact id exists, based on the ids of the entities and verb
|
|
||||||
/*selectFact(dbConnection);
|
|
||||||
if (getId() != 0)
|
|
||||||
{
|
|
||||||
// TODO: Verb is already in database, throw an error? Or just skip it?
|
|
||||||
return -1;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// TODO: verify that verbId, leftEntityId, and rightEntityId are not 0
|
|
||||||
|
|
||||||
sqlite3_stmt* ppStmt = nullptr;
|
|
||||||
const char* pzTail = nullptr;
|
|
||||||
|
|
||||||
auto result = sqlite3_prepare_v2(dbConnection,
|
|
||||||
"INSERT INTO fact (left_entity, right_entity, verb) VALUES (?, ?, ?);",
|
|
||||||
-1,
|
|
||||||
&ppStmt,
|
|
||||||
&pzTail);
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: something went wrong throw an error
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pzTail != nullptr)
|
|
||||||
{
|
|
||||||
// TODO: Something was not used... throw an error
|
|
||||||
}
|
|
||||||
|
|
||||||
result = sqlite3_bind_int(ppStmt, 1, getLeftEntity().getId());
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
|
|
||||||
result = sqlite3_bind_int(ppStmt, 2, getRightEntity().getId());
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
|
|
||||||
result = sqlite3_bind_int(ppStmt, 3, getVerb().getId());
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
|
|
||||||
result = sqlite3_step(ppStmt);
|
|
||||||
if (result != SQLITE_DONE)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setId((int) sqlite3_last_insert_rowid(dbConnection));
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_set_last_insert_rowid(dbConnection, 0);
|
|
||||||
|
|
||||||
result = sqlite3_finalize(ppStmt);
|
result = sqlite3_finalize(ppStmt);
|
||||||
if (result != SQLITE_OK)
|
if (result != SQLITE_OK)
|
||||||
{
|
{
|
||||||
// TODO: Something is wrong... throw an error
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void obelisk::Fact::insertFact(sqlite3* dbConnection)
|
||||||
|
{
|
||||||
|
if (dbConnection == nullptr)
|
||||||
|
{
|
||||||
|
throw obelisk::DatabaseException("database isn't open");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
sqlite3_stmt* ppStmt = nullptr;
|
||||||
|
|
||||||
|
auto result = sqlite3_prepare_v2(dbConnection,
|
||||||
|
"INSERT INTO fact (left_entity, right_entity, verb) 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::DatabaseException::SizeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_RANGE :
|
||||||
|
throw obelisk::DatabaseException::RangeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_NOMEM :
|
||||||
|
throw obelisk::DatabaseException::MemoryException();
|
||||||
|
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::DatabaseException::SizeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_RANGE :
|
||||||
|
throw obelisk::DatabaseException::RangeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_NOMEM :
|
||||||
|
throw obelisk::DatabaseException::MemoryException();
|
||||||
|
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::DatabaseException::SizeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_RANGE :
|
||||||
|
throw obelisk::DatabaseException::RangeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_NOMEM :
|
||||||
|
throw obelisk::DatabaseException::MemoryException();
|
||||||
|
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::DatabaseException::ConstraintException(
|
||||||
|
sqlite3_errmsg(dbConnection));
|
||||||
|
case SQLITE_BUSY :
|
||||||
|
throw obelisk::DatabaseException::BusyException();
|
||||||
|
break;
|
||||||
|
case SQLITE_MISUSE :
|
||||||
|
throw obelisk::DatabaseException::MisuseException();
|
||||||
|
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()
|
int& obelisk::Fact::getId()
|
||||||
|
@ -69,8 +69,8 @@ namespace obelisk
|
|||||||
Verb& getVerb();
|
Verb& getVerb();
|
||||||
void setVerb(obelisk::Verb verb);
|
void setVerb(obelisk::Verb verb);
|
||||||
|
|
||||||
int selectFact(sqlite3* dbConnection);
|
void selectFact(sqlite3* dbConnection);
|
||||||
int insertFact(sqlite3* dbConnection);
|
void insertFact(sqlite3* dbConnection);
|
||||||
};
|
};
|
||||||
} // namespace obelisk
|
} // namespace obelisk
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ const char* obelisk::Rule::createTable()
|
|||||||
"fact" INTEGER NOT NULL,
|
"fact" INTEGER NOT NULL,
|
||||||
"reason" INTEGER NOT NULL CHECK("reason" != "fact"),
|
"reason" INTEGER NOT NULL CHECK("reason" != "fact"),
|
||||||
PRIMARY KEY("id" AUTOINCREMENT),
|
PRIMARY KEY("id" AUTOINCREMENT),
|
||||||
|
UNIQUE("fact", "reason"),
|
||||||
FOREIGN KEY("fact") REFERENCES "fact"("id") ON DELETE RESTRICT,
|
FOREIGN KEY("fact") REFERENCES "fact"("id") ON DELETE RESTRICT,
|
||||||
FOREIGN KEY("reason") REFERENCES "fact"("id") ON DELETE RESTRICT
|
FOREIGN KEY("reason") REFERENCES "fact"("id") ON DELETE RESTRICT
|
||||||
);
|
);
|
||||||
|
@ -9,6 +9,7 @@ const char* obelisk::SuggestAction::createTable()
|
|||||||
"true_action" INTEGER NOT NULL,
|
"true_action" INTEGER NOT NULL,
|
||||||
"false_action" INTEGER NOT NULL,
|
"false_action" INTEGER NOT NULL,
|
||||||
PRIMARY KEY("id" AUTOINCREMENT),
|
PRIMARY KEY("id" AUTOINCREMENT),
|
||||||
|
UNIQUE("fact", "true_action", "false_action"),
|
||||||
FOREIGN KEY("fact") REFERENCES "fact"("id") ON DELETE RESTRICT,
|
FOREIGN KEY("fact") REFERENCES "fact"("id") ON DELETE RESTRICT,
|
||||||
FOREIGN KEY("true_action") REFERENCES "action"("id") ON DELETE RESTRICT,
|
FOREIGN KEY("true_action") REFERENCES "action"("id") ON DELETE RESTRICT,
|
||||||
FOREIGN KEY("false_action") REFERENCES "action"("id") ON DELETE RESTRICT
|
FOREIGN KEY("false_action") REFERENCES "action"("id") ON DELETE RESTRICT
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "models/error.h"
|
||||||
#include "models/verb.h"
|
#include "models/verb.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -13,119 +14,137 @@ const char* obelisk::Verb::createTable()
|
|||||||
)";
|
)";
|
||||||
}
|
}
|
||||||
|
|
||||||
int obelisk::Verb::selectVerb(sqlite3* dbConnection)
|
void obelisk::Verb::selectVerb(sqlite3* dbConnection)
|
||||||
{
|
{
|
||||||
// TODO: check if database is open
|
if (dbConnection == nullptr)
|
||||||
|
{
|
||||||
|
throw obelisk::DatabaseException("database isn't open");
|
||||||
|
}
|
||||||
|
|
||||||
sqlite3_stmt* ppStmt = nullptr;
|
sqlite3_stmt* ppStmt = nullptr;
|
||||||
const char* pzTail = nullptr;
|
|
||||||
|
|
||||||
auto result = sqlite3_prepare_v2(dbConnection,
|
auto result = sqlite3_prepare_v2(dbConnection,
|
||||||
"SELECT id, name FROM verb WHERE name=?;",
|
"SELECT id, name FROM verb WHERE name=?",
|
||||||
-1,
|
-1,
|
||||||
&ppStmt,
|
&ppStmt,
|
||||||
&pzTail);
|
nullptr);
|
||||||
if (result != SQLITE_OK)
|
if (result != SQLITE_OK)
|
||||||
{
|
{
|
||||||
// TODO: something went wrong throw an error
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pzTail != nullptr)
|
result = sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_STATIC);
|
||||||
|
switch (result)
|
||||||
{
|
{
|
||||||
// TODO: Something was not used... throw an error
|
case SQLITE_OK :
|
||||||
}
|
break;
|
||||||
|
case SQLITE_TOOBIG :
|
||||||
result
|
throw obelisk::DatabaseException::SizeException();
|
||||||
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
|
break;
|
||||||
if (result != SQLITE_OK)
|
case SQLITE_RANGE :
|
||||||
{
|
throw obelisk::DatabaseException::RangeException();
|
||||||
// TODO: Something is wrong... throw an error
|
break;
|
||||||
|
case SQLITE_NOMEM :
|
||||||
|
throw obelisk::DatabaseException::MemoryException();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = sqlite3_step(ppStmt);
|
result = sqlite3_step(ppStmt);
|
||||||
if (result != SQLITE_DONE)
|
switch (result)
|
||||||
{
|
{
|
||||||
// TODO: Something is wrong... throw an error
|
case SQLITE_DONE :
|
||||||
|
// no rows in the database
|
||||||
|
break;
|
||||||
|
case SQLITE_ROW :
|
||||||
|
setId(sqlite3_column_int(ppStmt, 0));
|
||||||
|
setName((char*) sqlite3_column_text(ppStmt, 1));
|
||||||
|
break;
|
||||||
|
case SQLITE_BUSY :
|
||||||
|
throw obelisk::DatabaseException::BusyException();
|
||||||
|
break;
|
||||||
|
case SQLITE_MISUSE :
|
||||||
|
throw obelisk::DatabaseException::MisuseException();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == SQLITE_ROW)
|
|
||||||
{
|
|
||||||
setId(sqlite3_column_int(ppStmt, 0));
|
|
||||||
setName((char*) sqlite3_column_text(ppStmt, 1));
|
|
||||||
|
|
||||||
result = sqlite3_finalize(ppStmt);
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = sqlite3_finalize(ppStmt);
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int obelisk::Verb::insertVerb(sqlite3* dbConnection)
|
|
||||||
{
|
|
||||||
// TODO: make sure database is open
|
|
||||||
|
|
||||||
/*selectVerb(dbConnection);
|
|
||||||
if (getId() != 0)
|
|
||||||
{
|
|
||||||
// TODO: Verb is already in database, throw an error? Or just skip it?
|
|
||||||
return -1;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
sqlite3_stmt* ppStmt = nullptr;
|
|
||||||
const char* pzTail = nullptr;
|
|
||||||
|
|
||||||
auto result = sqlite3_prepare_v2(dbConnection,
|
|
||||||
"INSERT INTO verb (name) VALUES (?);",
|
|
||||||
-1,
|
|
||||||
&ppStmt,
|
|
||||||
&pzTail);
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: something went wrong throw an error
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pzTail != nullptr)
|
|
||||||
{
|
|
||||||
// TODO: Something was not used... throw an error
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
|
|
||||||
if (result != SQLITE_OK)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
|
|
||||||
result = sqlite3_step(ppStmt);
|
|
||||||
if (result != SQLITE_DONE)
|
|
||||||
{
|
|
||||||
// TODO: Something is wrong... throw an error
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setId((int) sqlite3_last_insert_rowid(dbConnection));
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_set_last_insert_rowid(dbConnection, 0);
|
|
||||||
|
|
||||||
result = sqlite3_finalize(ppStmt);
|
result = sqlite3_finalize(ppStmt);
|
||||||
if (result != SQLITE_OK)
|
if (result != SQLITE_OK)
|
||||||
{
|
{
|
||||||
// TODO: Something is wrong... throw an error
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void obelisk::Verb::insertVerb(sqlite3* dbConnection)
|
||||||
|
{
|
||||||
|
if (dbConnection == nullptr)
|
||||||
|
{
|
||||||
|
throw obelisk::DatabaseException("database isn't open");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
sqlite3_stmt* ppStmt = nullptr;
|
||||||
|
|
||||||
|
auto result = sqlite3_prepare_v2(dbConnection,
|
||||||
|
"INSERT INTO verb (name) VALUES (?)",
|
||||||
|
-1,
|
||||||
|
&ppStmt,
|
||||||
|
nullptr);
|
||||||
|
if (result != SQLITE_OK)
|
||||||
|
{
|
||||||
|
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case SQLITE_OK :
|
||||||
|
break;
|
||||||
|
case SQLITE_TOOBIG :
|
||||||
|
throw obelisk::DatabaseException::SizeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_RANGE :
|
||||||
|
throw obelisk::DatabaseException::RangeException();
|
||||||
|
break;
|
||||||
|
case SQLITE_NOMEM :
|
||||||
|
throw obelisk::DatabaseException::MemoryException();
|
||||||
|
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::DatabaseException::ConstraintException(
|
||||||
|
sqlite3_errmsg(dbConnection));
|
||||||
|
case SQLITE_BUSY :
|
||||||
|
throw obelisk::DatabaseException::BusyException();
|
||||||
|
break;
|
||||||
|
case SQLITE_MISUSE :
|
||||||
|
throw obelisk::DatabaseException::MisuseException();
|
||||||
|
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::Verb::getId()
|
int& obelisk::Verb::getId()
|
||||||
|
@ -46,8 +46,8 @@ namespace obelisk
|
|||||||
std::string& getName();
|
std::string& getName();
|
||||||
void setName(std::string name);
|
void setName(std::string name);
|
||||||
|
|
||||||
int selectVerb(sqlite3* dbConnection);
|
void selectVerb(sqlite3* dbConnection);
|
||||||
int insertVerb(sqlite3* dbConnection);
|
void insertVerb(sqlite3* dbConnection);
|
||||||
};
|
};
|
||||||
} // namespace obelisk
|
} // namespace obelisk
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user