From a2b2faa6019572388248617d0ac740bde95feb74 Mon Sep 17 00:00:00 2001
From: znone <glyc@sina.com.cn>
Date: Fri, 26 Feb 2021 13:44:08 +0000
Subject: [PATCH] PostgreSQL: support binary data PostgreSQl: add database pool
---
test/TestPostgres.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 105 insertions(+), 7 deletions(-)
diff --git a/test/TestPostgres.cpp b/test/TestPostgres.cpp
index 983b084..eeab3f2 100644
--- a/test/TestPostgres.cpp
+++ b/test/TestPostgres.cpp
@@ -40,13 +40,15 @@
{
this->id = 0;
TEST_ADD(TestPostgres::test_dual)
- TEST_ADD(TestPostgres::test_clear)
- TEST_ADD(TestPostgres::test_insert)
- TEST_ADD(TestPostgres::test_select)
- TEST_ADD(TestPostgres::test_update)
- TEST_ADD(TestPostgres::test_insert2)
- TEST_ADD(TestPostgres::test_iterator)
- TEST_ADD(TestPostgres::test_any)
+ TEST_ADD(TestPostgres::test_clear)
+ TEST_ADD(TestPostgres::test_insert)
+ TEST_ADD(TestPostgres::test_select)
+ TEST_ADD(TestPostgres::test_update)
+ TEST_ADD(TestPostgres::test_insert2)
+ TEST_ADD(TestPostgres::test_iterator)
+ TEST_ADD(TestPostgres::test_insert_blob)
+ TEST_ADD(TestPostgres::test_select_blob)
+ TEST_ADD(TestPostgres::test_any)
}
inline void TestPostgres::connect(qtl::postgres::database& db)
@@ -188,6 +190,89 @@
}
}
+void hex_string(char* dest, const unsigned char* bytes, size_t count)
+{
+ for (size_t i = 0; i != count; i++)
+ {
+ sprintf(&dest[i * 2], "%02X", bytes[i] & 0xFF);
+ }
+}
+
+void TestPostgres::test_insert_blob()
+{
+ qtl::postgres::database db;
+ connect(db);
+
+ try
+ {
+#ifdef _WIN32
+ const char filename[] = "C:\\windows\\explorer.exe";
+#else
+ const char filename[] = "/bin/sh";
+#endif //_WIN32
+ qtl::postgres::transaction trans(db);
+ qtl::postgres::large_object content = qtl::postgres::large_object::load(db.handle(), filename);
+ TEST_ASSERT_MSG(content.oid()>0, "Cannot open test file.");
+ fstream fs(filename, ios::binary | ios::in);
+ unsigned char md5[16] = { 0 };
+ char md5_hex[33] = { 0 };
+ get_md5(fs, md5);
+ hex_string(md5_hex, md5, sizeof(md5));
+ printf("MD5 of file %s: %s.\n", filename, md5_hex);
+
+ db.simple_execute("DELETE FROM test_blob");
+
+ fs.clear();
+ fs.seekg(0, ios::beg);
+ db.query_first("INSERT INTO test_blob (filename, content, md5) values($1, $2, $3) returning id",
+ forward_as_tuple(filename, content, qtl::const_blob_data(md5, sizeof(md5))), id);
+ content.close();
+ trans.commit();
+ }
+ catch (qtl::postgres::error& e)
+ {
+ ASSERT_EXCEPTION(e);
+ }
+}
+
+void TestPostgres::test_select_blob()
+{
+ qtl::postgres::database db;
+ connect(db);
+
+ try
+ {
+ const char dest_file[] = "explorer.exe";
+
+ unsigned char md5[16] = { 0 };
+ std::string source_file;
+ qtl::postgres::transaction trans(db);
+ qtl::postgres::large_object content;
+ qtl::const_blob_data md5_value;
+ db.query_first("SELECT filename, content, md5 FROM test_blob WHERE id=$1", make_tuple(id),
+ forward_as_tuple(source_file, content, qtl::blob_data(md5, sizeof(md5))));
+ if (content.is_open())
+ {
+ content.save(dest_file);
+ ifstream fs(dest_file, ios::binary | ios::in);
+ TEST_ASSERT_MSG(fs, "Cannot open test file.");
+ char md5_hex[33] = { 0 };
+ hex_string(md5_hex, md5, sizeof(md5));
+ printf("MD5 of file %s stored in database: %s.\n", source_file.data(), md5_hex);
+ fs.clear();
+ fs.seekg(0, ios::beg);
+ get_md5(fs, md5);
+ hex_string(md5_hex, md5, sizeof(md5));
+ printf("MD5 of file %s: %s.\n", dest_file, md5_hex);
+ content.close();
+ }
+ }
+ catch (qtl::postgres::error& e)
+ {
+ ASSERT_EXCEPTION(e);
+ }
+}
+
void TestPostgres::test_any()
{
#ifdef _QTL_ENABLE_CPP17
@@ -218,6 +303,19 @@
#endif
}
+void TestPostgres::get_md5(std::istream& is, unsigned char* result)
+{
+ std::array<char, 64 * 1024> buffer;
+ MD5_CTX context;
+ MD5Init(&context);
+ while (!is.eof())
+ {
+ is.read(&buffer.front(), buffer.size());
+ MD5Update(&context, (unsigned char*)buffer.data(), (unsigned int)is.gcount());
+ }
+ MD5Final(result, &context);
+}
+
int main(int argc, char* argv[])
{
Test::TextOutput output(Test::TextOutput::Verbose);
--
Gitblit v1.9.3