diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-06-01 00:17:38 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-06-01 00:17:38 +0100 |
commit | 046cdae1a14a686238ab91b1f883335b2de5a78c (patch) | |
tree | 3fcf031cc9db3d40d65f6ec989b22d97a2dab11e | |
parent | Read test DB connection details from env (diff) | |
download | mygrate-046cdae1a14a686238ab91b1f883335b2de5a78c.tar.bz2 mygrate-046cdae1a14a686238ab91b1f883335b2de5a78c.tar.xz mygrate-046cdae1a14a686238ab91b1f883335b2de5a78c.zip |
Generate DbStmt templates from .sql files
m4 generator and related code. Reshuffles some CTF stuff to avoid
pulling in all of CTF and iostream for its fixed_string. Moves CTF out
of AdHoc namespace.
Add some initial SQL statements.
-rw-r--r-- | Jamroot.jam | 21 | ||||
-rw-r--r-- | lib/Jamfile.jam | 2 | ||||
-rw-r--r-- | lib/compileTimeFormatter.h | 72 | ||||
-rw-r--r-- | lib/dbStmt.h | 4 | ||||
-rw-r--r-- | lib/fixedString.h | 59 | ||||
-rw-r--r-- | lib/genstmt.m4 | 8 | ||||
-rw-r--r-- | lib/input/sql/showMasterStatus.sql | 1 | ||||
-rw-r--r-- | lib/output/dumpToConsole.cpp | 14 | ||||
-rw-r--r-- | lib/output/pq/pqStmt.cpp | 2 | ||||
-rw-r--r-- | lib/output/pq/sql/selectColumns.sql | 6 | ||||
-rw-r--r-- | lib/output/pq/sql/selectSource.sql | 3 | ||||
-rw-r--r-- | lib/output/pq/sql/selectTables.sql | 6 | ||||
-rw-r--r-- | lib/output/pq/sql/updateSourcePosition.sql | 4 | ||||
-rw-r--r-- | lib/streamSupport.cpp | 12 | ||||
-rw-r--r-- | test/test-mysql.cpp | 3 | ||||
-rw-r--r-- | test/test-postgresql.cpp | 2 |
16 files changed, 137 insertions, 82 deletions
diff --git a/Jamroot.jam b/Jamroot.jam index bb22c83..883aaf0 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -4,6 +4,9 @@ using clang : 12 ; using pkg-config ; import pkg-config ; import testing ; +import type : register ; +import generators : register-standard ; +import regex : replace ; pkg-config.import libmariadb ; pkg-config.import libpq ; @@ -37,3 +40,21 @@ project : requirements build-project main ; build-project test ; + +path-constant root : . ; + +type.register SQL : sql ; + +generators.register-standard embed.sql : SQL : CPP H ; + +actions embed.sql +{ + echo "#include \"$(2:B).h\"" > $(1[1]) + m4 -DSOURCE=$(2) -DNS=$(NS) -DNAME=$(2:B) > $(1[2]) lib/genstmt.m4 +} +rule embed.sql ( targets * : sources * : properties * ) +{ + DEPENDS $(targets) : $(root)/lib/genstmt.m4 ; + NS on $(targets) = [ replace $(sources:D) "/" "::" ] ; +} +IMPORT $(__name__) : embed.sql : : embed.sql ; diff --git a/lib/Jamfile.jam b/lib/Jamfile.jam index c54dabc..d805201 100644 --- a/lib/Jamfile.jam +++ b/lib/Jamfile.jam @@ -1,5 +1,5 @@ lib mygrate : - [ glob-tree *.cpp ] + [ glob-tree *.cpp *.sql : bin ] : <link>static <include>. diff --git a/lib/compileTimeFormatter.h b/lib/compileTimeFormatter.h index 17da62e..09aae53 100644 --- a/lib/compileTimeFormatter.h +++ b/lib/compileTimeFormatter.h @@ -1,6 +1,7 @@ -#ifndef ADHOCUTIL_COMPILE_TIME_FORMATTER_H -#define ADHOCUTIL_COMPILE_TIME_FORMATTER_H +#ifndef MYGRATE_COMPILE_TIME_FORMATTER_H +#define MYGRATE_COMPILE_TIME_FORMATTER_H +#include "fixedString.h" #include <array> #include <boost/preprocessor/variadic/size.hpp> #include <cstring> @@ -9,7 +10,7 @@ #include <sstream> // IWYU pragma: export #include <string_view> -namespace AdHoc { +namespace MyGrate { // Template char utils template<typename char_type> constexpr bool @@ -235,82 +236,29 @@ namespace AdHoc { }; }; - // New C++20 implementation - namespace support { - template<typename CharT, std::size_t N> class basic_fixed_string { - public: - // cppcheck-suppress noExplicitConstructor - constexpr basic_fixed_string(const CharT (&str)[N + 1]) - { - for (decltype(N) x = 0; x < N; x++) { - arr.at(x) = str[x]; - } - arr.at(N) = '\0'; - } - constexpr basic_fixed_string(const CharT * str, decltype(N) len) - { - for (decltype(N) x = 0; x < len; x++) { - arr.at(x) = str[x]; - } - arr.at(N) = '\0'; - } - constexpr const char * - s() const - { - return arr.data(); - } - constexpr operator const char *() const - { - return s(); - } - constexpr std::string_view - v() const - { - return {arr.data(), arr.size() - 1}; - } - constexpr auto & - operator[](std::size_t n) const - { - return arr[n]; - } - constexpr auto - size() const - { - return arr.size() - 1; - } - - std::array<CharT, N + 1> arr; - }; - - template<typename CharT, std::size_t N> - basic_fixed_string(const CharT (&str)[N]) -> basic_fixed_string<CharT, N - 1>; - } - - template<const support::basic_fixed_string Str> class LiteralFormatter : public FormatterDetail<Str, Str.size()> { + template<const Support::basic_fixed_string Str> class LiteralFormatter : public FormatterDetail<Str, Str.size()> { }; template<const auto & S, decltype(strlen(S)) L = strlen(S)> class Formatter : - public FormatterDetail<support::basic_fixed_string<typename std::decay<decltype(S[0])>::type, L>(S, L), L> { + public FormatterDetail<Support::basic_fixed_string<typename std::decay<decltype(S[0])>::type, L>(S, L), L> { }; -#define AdHocFormatter(name, str) using name = ::AdHoc::LiteralFormatter<str> - - template<const support::basic_fixed_string Str, typename... Pn> + template<const Support::basic_fixed_string Str, typename... Pn> inline auto scprintf(const Pn &... pn) { return FormatterDetail<Str, Str.size()>::get(pn...); } - template<const support::basic_fixed_string Str, typename stream, typename... Pn> + template<const Support::basic_fixed_string Str, typename stream, typename... Pn> inline auto & scprintf(stream & strm, const Pn &... pn) { return FormatterDetail<Str, Str.size()>::write(strm, pn...); } - template<const support::basic_fixed_string Str, typename... Pn> + template<const Support::basic_fixed_string Str, typename... Pn> inline auto & cprintf(const Pn &... pn) { @@ -327,7 +275,7 @@ namespace AdHoc { #include <iomanip> #include <type_traits> -namespace AdHoc { +namespace MyGrate { #define BASICCONV(PARAMTYPE, OP, ...) \ StreamWriterT(__VA_ARGS__) { \ template<typename... Pn> \ diff --git a/lib/dbStmt.h b/lib/dbStmt.h index 3e98b34..81621de 100644 --- a/lib/dbStmt.h +++ b/lib/dbStmt.h @@ -1,7 +1,7 @@ #ifndef MYGRATE_DBSTMT_H #define MYGRATE_DBSTMT_H -#include <compileTimeFormatter.h> +#include "fixedString.h" #include <dbConn.h> #include <dbRecordSet.h> #include <memory> @@ -12,7 +12,7 @@ namespace MyGrate { class DbConn; enum class ParamMode { None, DollarNum, QMark }; - template<AdHoc::support::basic_fixed_string S, ParamMode pm = ParamMode::None> class DbStmt { + template<Support::basic_fixed_string S, ParamMode pm = ParamMode::None> class DbStmt { public: // This don't account for common table expressions, hopefully won't need those :) static constexpr auto isSelect {S.v().starts_with("SELECT") || S.v().starts_with("SHOW") diff --git a/lib/fixedString.h b/lib/fixedString.h new file mode 100644 index 0000000..df0529a --- /dev/null +++ b/lib/fixedString.h @@ -0,0 +1,59 @@ +#ifndef MYGRATE_SUPPORT_FIXEDSTRING_H +#define MYGRATE_SUPPORT_FIXEDSTRING_H + +#include <array> +#include <cstddef> +#include <string_view> + +namespace MyGrate::Support { + template<typename CharT, std::size_t N> class basic_fixed_string { + public: + // cppcheck-suppress noExplicitConstructor + constexpr basic_fixed_string(const CharT (&str)[N + 1]) + { + for (decltype(N) x = 0; x < N; x++) { + arr.at(x) = str[x]; + } + arr.at(N) = '\0'; + } + constexpr basic_fixed_string(const CharT * str, decltype(N) len) + { + for (decltype(N) x = 0; x < len; x++) { + arr.at(x) = str[x]; + } + arr.at(N) = '\0'; + } + constexpr const char * + s() const + { + return arr.data(); + } + constexpr operator const char *() const + { + return s(); + } + constexpr std::string_view + v() const + { + return {arr.data(), arr.size() - 1}; + } + constexpr auto & + operator[](std::size_t n) const + { + return arr[n]; + } + constexpr auto + size() const + { + return arr.size() - 1; + } + + std::array<CharT, N + 1> arr; + }; + + template<typename CharT, std::size_t N> + basic_fixed_string(const CharT (&str)[N]) -> basic_fixed_string<CharT, N - 1>; + +} + +#endif diff --git a/lib/genstmt.m4 b/lib/genstmt.m4 new file mode 100644 index 0000000..b0f3255 --- /dev/null +++ b/lib/genstmt.m4 @@ -0,0 +1,8 @@ +// NAME +#include <fixedString.h> +#include <dbStmt.h> + +namespace MyGrate::NS { + using NAME = ::MyGrate::DbStmt<R"SQL(dnl +include(SOURCE))SQL">; +} diff --git a/lib/input/sql/showMasterStatus.sql b/lib/input/sql/showMasterStatus.sql new file mode 100644 index 0000000..5746be2 --- /dev/null +++ b/lib/input/sql/showMasterStatus.sql @@ -0,0 +1 @@ +SHOW MASTER STATUS diff --git a/lib/output/dumpToConsole.cpp b/lib/output/dumpToConsole.cpp index 81d9edc..1085bb5 100644 --- a/lib/output/dumpToConsole.cpp +++ b/lib/output/dumpToConsole.cpp @@ -17,7 +17,7 @@ namespace MyGrate::Output { DumpToConsole::tableMap(MyGrate::MariaDB_Event_Ptr event) { const auto & tm = event->event.table_map; - AdHoc::scprintf<"Table map %?.%? -> %?\n">(std::cout, tm.database, tm.table, tm.table_id); + scprintf<"Table map %?.%? -> %?\n">(std::cout, tm.database, tm.table, tm.table_id); EventHandlerBase::tableMap(std::move(event)); } @@ -25,7 +25,7 @@ namespace MyGrate::Output { DumpToConsole::insertRow(MyGrate::MariaDB_Event_Ptr event) { const auto & rs = event->event.rows; - AdHoc::scprintf<"Insert into %?\n">(std::cout, rs.table_id); + scprintf<"Insert into %?\n">(std::cout, rs.table_id); dumpRowData(event->event.rows); } @@ -33,7 +33,7 @@ namespace MyGrate::Output { DumpToConsole::updateRow(MyGrate::MariaDB_Event_Ptr event) { const auto & rs = event->event.rows; - AdHoc::scprintf<"Update %?\n">(std::cout, rs.table_id); + scprintf<"Update %?\n">(std::cout, rs.table_id); dumpRowPairData(event->event.rows); } @@ -41,7 +41,7 @@ namespace MyGrate::Output { DumpToConsole::deleteRow(MyGrate::MariaDB_Event_Ptr event) { const auto & rs = event->event.rows; - AdHoc::scprintf<"Delete from %?\n">(std::cout, rs.table_id); + scprintf<"Delete from %?\n">(std::cout, rs.table_id); dumpRowData(event->event.rows); } @@ -50,19 +50,19 @@ namespace MyGrate::Output { void operator()(const T & v) const { - AdHoc::scprintf<"\t\t%?\n">(std::cout, v); + scprintf<"\t\t%?\n">(std::cout, v); } void operator()(const uint8_t & v) const { - AdHoc::scprintf<"\t\t%d\n">(std::cout, v); + scprintf<"\t\t%d\n">(std::cout, v); } void operator()(const int8_t & v) const { - AdHoc::scprintf<"\t\t%d\n">(std::cout, v); + scprintf<"\t\t%d\n">(std::cout, v); } }; diff --git a/lib/output/pq/pqStmt.cpp b/lib/output/pq/pqStmt.cpp index 04b48c6..078c239 100644 --- a/lib/output/pq/pqStmt.cpp +++ b/lib/output/pq/pqStmt.cpp @@ -46,7 +46,7 @@ namespace MyGrate::Output::Pq { if (const auto i = c->stmts.find(q); i != c->stmts.end()) { return i->second; } - auto nam {AdHoc::scprintf<"pst%0x">(c->stmts.size())}; + auto nam {scprintf<"pst%0x">(c->stmts.size())}; ResPtr res {PQprepare(c->conn.get(), nam.c_str(), q, (int)n, nullptr), PQclear}; verify<std::runtime_error>(PQresultStatus(res.get()) == PGRES_COMMAND_OK, q); return c->stmts.emplace(q, std::move(nam)).first->second; diff --git a/lib/output/pq/sql/selectColumns.sql b/lib/output/pq/sql/selectColumns.sql new file mode 100644 index 0000000..e9cd107 --- /dev/null +++ b/lib/output/pq/sql/selectColumns.sql @@ -0,0 +1,6 @@ +SELECT t.table_name, STRING_AGG(c.column_name, '|' ORDER BY c.ordinal_position) +FROM mygrate.source s + JOIN information_schema.tables t USING(table_schema) + LEFT OUTER JOIN information_schema.columns c USING(table_schema, table_name) +WHERE s.id = $1 +GROUP BY t.table_name diff --git a/lib/output/pq/sql/selectSource.sql b/lib/output/pq/sql/selectSource.sql new file mode 100644 index 0000000..3048410 --- /dev/null +++ b/lib/output/pq/sql/selectSource.sql @@ -0,0 +1,3 @@ +SELECT host, username, password, port, filename, position, serverid, table_schema +FROM mygrate.source s +WHERE s.id = $1 diff --git a/lib/output/pq/sql/selectTables.sql b/lib/output/pq/sql/selectTables.sql new file mode 100644 index 0000000..389dfe2 --- /dev/null +++ b/lib/output/pq/sql/selectTables.sql @@ -0,0 +1,6 @@ +SELECT t.table_name, STRING_AGG(k.column_name, '|' ORDER BY k.ordinal_position) pk_cols +FROM mygrate.source s + JOIN information_schema.tables t USING(table_schema) + LEFT OUTER JOIN information_schema.key_column_usage k USING(table_schema, table_name) +WHERE s.id = $1 +GROUP BY t.table_name diff --git a/lib/output/pq/sql/updateSourcePosition.sql b/lib/output/pq/sql/updateSourcePosition.sql new file mode 100644 index 0000000..3d3d665 --- /dev/null +++ b/lib/output/pq/sql/updateSourcePosition.sql @@ -0,0 +1,4 @@ +UPDATE mygrate.source SET + filename = $1, + position = $2 +WHERE id = $3 diff --git a/lib/streamSupport.cpp b/lib/streamSupport.cpp index 32c1fce..2665b98 100644 --- a/lib/streamSupport.cpp +++ b/lib/streamSupport.cpp @@ -12,7 +12,7 @@ namespace std { std::ostream & operator<<(std::ostream & strm, const std::byte byt) { - return AdHoc::scprintf<"%#02x">(strm, std::to_integer<uint8_t>(byt)); + return MyGrate::scprintf<"%#02x">(strm, std::to_integer<uint8_t>(byt)); } std::ostream & @@ -24,32 +24,32 @@ namespace std { std::ostream & operator<<(std::ostream & s, const tm & tm) { - return AdHoc::scprintf<"%04d-%02d-%02d %02d:%02d:%02d">( + return MyGrate::scprintf<"%04d-%02d-%02d %02d:%02d:%02d">( s, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); } std::ostream & operator<<(std::ostream & s, const timespec & ts) { - return AdHoc::scprintf<"%d.%09d">(s, ts.tv_sec, ts.tv_nsec); + return MyGrate::scprintf<"%d.%09d">(s, ts.tv_sec, ts.tv_nsec); } std::ostream & operator<<(std::ostream & s, const MyGrate::Date & d) { - return AdHoc::scprintf<"%04d-%02d-%02d">(s, d.year, d.month, d.day); + return MyGrate::scprintf<"%04d-%02d-%02d">(s, d.year, d.month, d.day); } std::ostream & operator<<(std::ostream & s, const MyGrate::Time & t) { - return AdHoc::scprintf<"%02d:%02d:%02d">(s, t.hour, t.minute, t.second); + return MyGrate::scprintf<"%02d:%02d:%02d">(s, t.hour, t.minute, t.second); } std::ostream & operator<<(std::ostream & s, const MyGrate::DateTime & dt) { - return AdHoc::scprintf<"%? %?">(s, (const MyGrate::Date)dt, (const MyGrate::Time)dt); + return MyGrate::scprintf<"%? %?">(s, (const MyGrate::Date)dt, (const MyGrate::Time)dt); } std::ostream & diff --git a/test/test-mysql.cpp b/test/test-mysql.cpp index 8710c8b..7c12f9a 100644 --- a/test/test-mysql.cpp +++ b/test/test-mysql.cpp @@ -1,13 +1,12 @@ #define BOOST_TEST_MODULE MySQL #include <boost/test/unit_test.hpp> -#include <compileTimeFormatter.h> -#include <cstddef> #include <cstdint> #include <cstdlib> #include <dbRecordSet.h> #include <dbStmt.h> #include <dbTypes.h> +#include <fixedString.h> #include <helpers.h> #include <input/mysqlConn.h> #include <memory> diff --git a/test/test-postgresql.cpp b/test/test-postgresql.cpp index e89e031..a24acb8 100644 --- a/test/test-postgresql.cpp +++ b/test/test-postgresql.cpp @@ -1,11 +1,11 @@ #define BOOST_TEST_MODULE PostgreSQL #include <boost/test/unit_test.hpp> -#include <compileTimeFormatter.h> #include <cstddef> #include <dbRecordSet.h> #include <dbStmt.h> #include <dbTypes.h> +#include <fixedString.h> #include <helpers.h> #include <memory> #include <output/pq/pqConn.h> |