commit 8ecca3824bf524bfd838119f6bf710906dd9b288 Author: JDierkse Date: Wed Feb 12 19:57:50 2020 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a201fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.o.* +*.d.* +*.a.* +.*.swp +.AppleDouble +lib +Libraries diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..876e403 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Makefiles"] + path = Makefiles + url = https://gogs.dierkse.nl/JDierkse/Makefiles diff --git a/Makefile b/Makefile new file mode 120000 index 0000000..6aa5187 --- /dev/null +++ b/Makefile @@ -0,0 +1 @@ +Makefiles/Makefile \ No newline at end of file diff --git a/Makefile.conf b/Makefile.conf new file mode 100644 index 0000000..db925bb --- /dev/null +++ b/Makefile.conf @@ -0,0 +1,6 @@ +# +# Makefile.conf +# + +CFLAGS += -I$(ROOTPATH) -I$(ROOTPATH)/include +DEBUGDIR := .debug diff --git a/Makefile.target b/Makefile.target new file mode 100644 index 0000000..aec7404 --- /dev/null +++ b/Makefile.target @@ -0,0 +1,13 @@ +# +# Makefile.target +# + +SQLite.a.$(ARCH) : $(OBJECTS) + $(call build_target_library_arch,$@,$^) + +SQLite.a: + $(call build_target,$@) + +.DEFAULT_GOAL := SQLite.a + +TARGETS += SQLite.a diff --git a/Makefiles b/Makefiles new file mode 160000 index 0000000..61894c4 --- /dev/null +++ b/Makefiles @@ -0,0 +1 @@ +Subproject commit 61894c4588eb2b85e342a6f923eeb7ac97c3fe64 diff --git a/SQLite/Makefile b/SQLite/Makefile new file mode 120000 index 0000000..d0b0e8e --- /dev/null +++ b/SQLite/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/SQLite/SQLiteClient.cpp b/SQLite/SQLiteClient.cpp new file mode 100644 index 0000000..aaa5849 --- /dev/null +++ b/SQLite/SQLiteClient.cpp @@ -0,0 +1,56 @@ +#include "SQLiteClient.h" +#include +#include +#include + + +namespace SQLite { + +SQLiteClient::SQLiteClient(const std::string& filename) +{ + sqlite3_open(filename.c_str(), &m_pSQLite3); +} + +SQLiteClient::~SQLiteClient() +{ + sqlite3_close(m_pSQLite3); +} + +SQLiteClient::operator sqlite3*() +{ + return m_pSQLite3; +} + +SQLiteResultSet SQLiteClient::ExecuteQuery(const std::string& query) +{ + SQLiteStatement statement(*this, query); + return RetrieveResultSet(statement); +} + +void SQLiteClient::BeginTransaction() +{ + ExecuteQuery("BEGIN TRANSACTION;"); +} + +void SQLiteClient::EndTransaction() +{ + ExecuteQuery("END TRANSACTION;"); +} + + +SQLiteResultSet SQLiteClient::RetrieveResultSet(SQLiteStatement& statement) +{ + try + { + SQLiteResultSet resultSet(statement); + return resultSet; + } + catch (const std::exception& e) + { + std::stringstream err; + err << "SQL error: " << sqlite3_errmsg(*this); + throw std::runtime_error(err.str()); + } +} + +} // namespace SQLite diff --git a/SQLite/SQLiteResultSet.cpp b/SQLite/SQLiteResultSet.cpp new file mode 100644 index 0000000..325d758 --- /dev/null +++ b/SQLite/SQLiteResultSet.cpp @@ -0,0 +1,202 @@ +#include "SQLiteResultSet.h" +#include +#include +#include +#include + + +namespace SQLite { + +SQLiteResultSet::SQLiteResultSet(SQLiteStatement& statement) : + m_currentRow(-1) +{ + int columnCount = sqlite3_column_count(statement); + for (int i = 0; i < columnCount; ++i) + m_columns.push_back(std::string(reinterpret_cast(sqlite3_column_name(statement, i)))); + + int returnCode = 0; + while ((returnCode = sqlite3_step(statement)) == SQLITE_ROW) + { + std::vector row; + for (int i = 0; i < columnCount; ++i) + row.push_back(std::string(reinterpret_cast(sqlite3_column_text(statement, i)))); + + m_values.push_back(row); + } + + if(returnCode != SQLITE_DONE) + { + throw std::runtime_error("Error Creating SQLiteResultSet."); + } +} + +void SQLiteResultSet::AfterLast() +{ + m_currentRow >= Size(); +} + +void SQLiteResultSet::BeforeFirst() +{ + m_currentRow = -1; +} + +bool SQLiteResultSet::First() +{ + if (m_values.empty()) + return false; + + m_currentRow = 0; + return true; +} + +bool SQLiteResultSet::IsAfterLast() const +{ + return m_currentRow >= Size(); +} + +bool SQLiteResultSet::IsBeforeFirst() const +{ + return m_currentRow < 0; +} + +bool SQLiteResultSet::IsFirst() const +{ + return m_currentRow == 0; +} + +bool SQLiteResultSet::IsLast() const +{ + return m_currentRow == LastIndex(); +} + +bool SQLiteResultSet::Last() +{ + if (m_values.empty()) + return false; + + m_currentRow = LastIndex(); + return true; +} + +bool SQLiteResultSet::Next() +{ + if (m_values.empty()) + return false; + + if (m_currentRow >= LastIndex()) + return false; + + ++m_currentRow; + return true; +} + +bool SQLiteResultSet::Previous() +{ + if (m_values.empty()) + return false; + + if (m_currentRow <= 0) + return false; + + --m_currentRow; + return true; +} + +size_t SQLiteResultSet::Row() const +{ + return m_currentRow; +} + +size_t SQLiteResultSet::RowsCount() const +{ + return m_values.size(); +} + +bool SQLiteResultSet::Empty() const +{ + return m_values.size() == 0; +} + +uint32_t SQLiteResultSet::FindColumn(const std::string& columnName) const +{ + if (std::find(m_columns.begin(), m_columns.end(), columnName) != m_columns.end()) + return std::find(m_columns.begin(), m_columns.end(), columnName) - m_columns.begin(); + return -1; +} + +long double SQLiteResultSet::Double(uint32_t columnIndex) const +{ + if (m_currentRow < 0 || m_currentRow > LastIndex()) + throw std::runtime_error("Invalid Row Selected."); + + return std::stod(m_values[m_currentRow][columnIndex]); +} + +long double SQLiteResultSet::Double(const std::string& columnName) const +{ + int index = FindColumn(columnName); + + if (index < 0) + throw std::runtime_error("Invalid Column Name."); + + return Double(index); +} + +int32_t SQLiteResultSet::Int(uint32_t columnIndex) const +{ + if (m_currentRow < 0 || m_currentRow > LastIndex()) + throw std::runtime_error("Invalid Row Selected."); + + return std::stoi(m_values[m_currentRow][columnIndex]); +} + +int32_t SQLiteResultSet::Int(const std::string& columnName) const +{ + int index = FindColumn(columnName); + + if (index < 0) + throw std::runtime_error("Invalid Column Name."); + + return Int(index); +} + +std::string SQLiteResultSet::String(uint32_t columnIndex) const +{ + if (m_currentRow < 0 || m_currentRow > LastIndex()) + throw std::runtime_error("Invalid Row Selected."); + + return m_values[m_currentRow][columnIndex]; +} + +std::string SQLiteResultSet::String(const std::string& columnName) const +{ + int index = FindColumn(columnName); + + if (index < 0) + throw std::runtime_error("Invalid Column Name."); + + return String(index); +} + +void SQLiteResultSet::Print() const +{ + for (auto rowIterator = m_values.begin(); rowIterator != m_values.end(); ++rowIterator) + { + auto columnNameIterator = m_columns.begin(); + for (auto columnIterator = rowIterator->begin(); columnIterator != rowIterator->end(); ++columnIterator, ++columnNameIterator) + std::cout << *columnNameIterator << " = " << *columnIterator << std::endl; + std::cout << std::endl; + } +} + +int SQLiteResultSet::Size() const +{ + return m_values.size(); +} + +int SQLiteResultSet::LastIndex() const +{ + return m_values.size() - 1; +} + +} // namespace SQLite diff --git a/SQLite/SQLiteStatement.cpp b/SQLite/SQLiteStatement.cpp new file mode 100644 index 0000000..02494eb --- /dev/null +++ b/SQLite/SQLiteStatement.cpp @@ -0,0 +1,32 @@ +#include "SQLiteClient.h" +#include "SQLiteStatement.h" +#include +#include +#include + + +namespace SQLite { + +SQLiteStatement::SQLiteStatement(SQLiteClient& client, const std::string& query) +{ + int returnCode = sqlite3_prepare_v2(client, query.c_str(), -1, &m_pStatement, nullptr); + + if (returnCode != SQLITE_OK) + { + std::stringstream err; + err << "SQL error: " << sqlite3_errmsg(client); + throw std::runtime_error(err.str()); + } +} + +SQLiteStatement::~SQLiteStatement() +{ + sqlite3_finalize(m_pStatement); +} + +SQLiteStatement::operator sqlite3_stmt*() +{ + return m_pStatement; +} + +} // namespace SQLite diff --git a/include/SQLiteClient.h b/include/SQLiteClient.h new file mode 100644 index 0000000..28faf82 --- /dev/null +++ b/include/SQLiteClient.h @@ -0,0 +1,35 @@ +#ifndef SQLITECLIENT_H +#define SQLITECLIENT_H + +#include "SQLiteResultSet.h" +#include "SQLiteStatement.h" +#include + + +class sqlite3; + +namespace SQLite { + +class SQLiteClient +{ +public: + SQLiteClient(const std::string& filename); + ~SQLiteClient(); + + operator sqlite3*(); + +public: + SQLiteResultSet ExecuteQuery(const std::string& query); + void BeginTransaction(); + void EndTransaction(); + +private: + SQLiteResultSet RetrieveResultSet(SQLiteStatement& statement); + +private: + sqlite3* m_pSQLite3; +}; + +} // namespace SQLite + +#endif // SQLITECLIENT_H diff --git a/include/SQLiteResultSet.h b/include/SQLiteResultSet.h new file mode 100644 index 0000000..ebe8c6d --- /dev/null +++ b/include/SQLiteResultSet.h @@ -0,0 +1,56 @@ +#ifndef SQLITERESULTSET_H +#define SQLITERESULTSET_H + +#include "SQLiteStatement.h" +#include +#include +#include + + +namespace SQLite { + +class SQLiteResultSet +{ +public: + SQLiteResultSet(SQLiteStatement& statement); + +public: + void AfterLast(); + void BeforeFirst(); + bool First(); + bool IsAfterLast() const; + bool IsBeforeFirst() const; + bool IsFirst() const; + bool IsLast() const; + bool Last(); + bool Next(); + bool Previous(); + + size_t Row() const; + size_t RowsCount() const; + bool Empty() const; + + uint32_t FindColumn(const std::string& columnName) const; + + long double Double(uint32_t columnIndex) const; + long double Double(const std::string& columnLabel) const; + int32_t Int(uint32_t columnIndex) const; + int32_t Int(const std::string& columnLabel) const; + std::string String(uint32_t columnIndex) const; + std::string String(const std::string& columnName) const; + + void Print() const; + +private: + int Size() const; + int LastIndex() const; + +private: + std::vector m_columns; + std::vector> m_values; + int m_currentRow; +}; + +} // namespace SQLite + +#endif // SQLITERESULTSET_H diff --git a/include/SQLiteStatement.h b/include/SQLiteStatement.h new file mode 100644 index 0000000..0fb44f6 --- /dev/null +++ b/include/SQLiteStatement.h @@ -0,0 +1,27 @@ +#ifndef SQLITESTATEMENT_H +#define SQLITESTATEMENT_H + +#include + + +class sqlite3_stmt; + +namespace SQLite { + +class SQLiteClient; + +class SQLiteStatement +{ +public: + SQLiteStatement(SQLiteClient& client, const std::string& query); + ~SQLiteStatement(); + + operator sqlite3_stmt*(); + +private: + sqlite3_stmt* m_pStatement; +}; + +} // namespace SQLite + +#endif // SQLITESTATEMENT_H