diff --git a/db/db.h b/db/db.h index 4196cde..40b4fb0 100644 --- a/db/db.h +++ b/db/db.h @@ -11,5 +11,8 @@ namespace sql = SQLite; #include #include #include +#include +#include namespace db_builder = db::migrations::builder; +namespace stmt = db::statements::builder; diff --git a/db/statements/builder/Statement.cpp b/db/statements/builder/Statement.cpp new file mode 100644 index 0000000..cf21df4 --- /dev/null +++ b/db/statements/builder/Statement.cpp @@ -0,0 +1,22 @@ +#include "Statement.h" +#include "StatementBuilder.h" + +namespace db { + namespace statements { + namespace builder { + class InsertStatementBuilder; + + InsertStatementBuilder Statement::insert() { + return InsertStatementBuilder{}; + } + + std::string Statement::str() const { + return body + "\n"; + } + + std::ostream &operator<<(std::ostream &os, const Statement &s) { + return os << s.body << std::endl; + } + } + } +} diff --git a/db/statements/builder/Statement.h b/db/statements/builder/Statement.h new file mode 100644 index 0000000..5fc0ccb --- /dev/null +++ b/db/statements/builder/Statement.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include + +namespace db { + namespace statements { + namespace builder { + class StatementBuilder; + class InsertStatementBuilder; + + class Statement { + public: + Statement() = default; + + friend class InsertStatementBuilder; + friend std::ostream &operator<<(std::ostream &os, const Statement &s); + + static InsertStatementBuilder insert(); + + std::string str() const; + private: + std::string body; + }; + } + } +} diff --git a/db/statements/builder/StatementBuilder.h b/db/statements/builder/StatementBuilder.h new file mode 100644 index 0000000..b8c78fd --- /dev/null +++ b/db/statements/builder/StatementBuilder.h @@ -0,0 +1,74 @@ +#pragma once + +#include "Statement.h" +#include +#include + +namespace db { + namespace statements { + namespace builder { + class InsertStatementBuilder; + + class AbstractStatementBuilder { + protected: + Statement &m_statement; + explicit AbstractStatementBuilder(Statement &statement) : m_statement(statement) {} + public: + operator Statement() const { + return std::move(m_statement); + } + }; + + class StatementBuilder : public AbstractStatementBuilder { + public: + Statement m_statement; + StatementBuilder() : AbstractStatementBuilder{m_statement} { + } + }; + + class InsertStatementBuilder : public StatementBuilder { + public: + explicit InsertStatementBuilder() : StatementBuilder() { + } + + InsertStatementBuilder &table(const std::string &table) { + m_statement.body += "INSERT INTO " + table + " "; + return *this; + } + + InsertStatementBuilder &columns(const std::string &cols) { + m_statement.body += "(" + cols + ")\n"; + return *this; + } + + InsertStatementBuilder &values() { + m_statement.body += " VALUES "; + return *this; + } + + InsertStatementBuilder &row(const std::string &values) { + m_statement.body += " (" + values + "),\n"; + return *this; + } + + InsertStatementBuilder &row(const std::vector &values) { + m_statement.body += " ("; + bool first = true; + for(auto const& v : values) { + if(first) { first = false; } else { m_statement.body += ","; } + m_statement.body += v; + } + m_statement.body += "),\n"; + return *this; + } + + InsertStatementBuilder &close() { + m_statement.body.pop_back(); + m_statement.body.pop_back(); + m_statement.body += ";\n"; + return *this; + } + }; + } + } +}