summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jamroot.jam21
-rw-r--r--lib/Jamfile.jam2
-rw-r--r--lib/compileTimeFormatter.h72
-rw-r--r--lib/dbStmt.h4
-rw-r--r--lib/fixedString.h59
-rw-r--r--lib/genstmt.m48
-rw-r--r--lib/input/sql/showMasterStatus.sql1
-rw-r--r--lib/output/dumpToConsole.cpp14
-rw-r--r--lib/output/pq/pqStmt.cpp2
-rw-r--r--lib/output/pq/sql/selectColumns.sql6
-rw-r--r--lib/output/pq/sql/selectSource.sql3
-rw-r--r--lib/output/pq/sql/selectTables.sql6
-rw-r--r--lib/output/pq/sql/updateSourcePosition.sql4
-rw-r--r--lib/streamSupport.cpp12
-rw-r--r--test/test-mysql.cpp3
-rw-r--r--test/test-postgresql.cpp2
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>