1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
#include <cerrno>
#include <cstring>
#include <iostream>
#include <sstream>
#include "test_helpers.hxx"
using namespace PGSTD;
using namespace pqxx;
// Simple test program for libpqxx's Large Objects interface.
namespace
{
const string Contents = "Large object test contents";
class CreateLargeObject : public transactor<>
{
public:
explicit CreateLargeObject(largeobject &O) :
transactor<>("CreateLargeObject"),
m_Object(),
m_ObjectOutput(O)
{
}
void operator()(argument_type &T)
{
m_Object = largeobject(T);
cout << "Created large object #" << m_Object.id() << endl;
}
void on_commit()
{
m_ObjectOutput = m_Object;
}
private:
largeobject m_Object;
largeobject &m_ObjectOutput;
};
class WriteLargeObject : public transactor<>
{
public:
explicit WriteLargeObject(largeobject &O) :
transactor<>("WriteLargeObject"),
m_Object(O)
{
}
void operator()(argument_type &T)
{
largeobjectaccess A(T, m_Object);
const largeobjectaccess::pos_type
orgpos = A.ctell(),
copyorgpos = A.ctell();
PQXX_CHECK_EQUAL(orgpos, 0, "Bad initial position in large object.");
PQXX_CHECK_EQUAL(copyorgpos, orgpos, "ctell() affected positioning.");
const largeobjectaccess::pos_type cxxorgpos = A.tell();
PQXX_CHECK_EQUAL(cxxorgpos, orgpos, "tell() reports bad position.");
A.process_notice("Writing to large object #" +
to_string(largeobject(A).id()) + "\n");
long Bytes = A.cwrite(
Contents.c_str(),
largeobject::size_type(Contents.size()));
PQXX_CHECK_EQUAL(
Bytes,
long(Contents.size()),
"Wrote wrong number of bytes.");
PQXX_CHECK_EQUAL(
A.tell(),
A.ctell(),
"tell() is inconsistent with ctell().");
PQXX_CHECK_EQUAL(A.tell(), Bytes, "Bad large-object position.");
char Buf[200];
const size_t Size = sizeof(Buf) - 1;
PQXX_CHECK_EQUAL(
A.cread(Buf, Size),
0,
"Bad return value from cread() after writing.");
PQXX_CHECK_EQUAL(
size_t(A.cseek(0, ios::cur)),
Contents.size(),
"Unexpected position after cseek(0, cur).");
PQXX_CHECK_EQUAL(
A.cseek(1, ios::beg),
1,
"Unexpected cseek() result after seeking to position 1.");
PQXX_CHECK_EQUAL(
A.cseek(-1, ios::cur),
0,
"Unexpected cseek() result after seeking -1 from position 1.");
PQXX_CHECK(size_t(A.read(Buf, Size)) <= Size, "Got too many bytes.");
PQXX_CHECK_EQUAL(
string(Buf, string::size_type(Bytes)),
Contents,
"Large-object contents were mutilated.");
}
private:
largeobject m_Object;
};
class DeleteLargeObject : public transactor<>
{
public:
explicit DeleteLargeObject(largeobject O) : m_Object(O) {}
void operator()(argument_type &T)
{
m_Object.remove(T);
}
private:
largeobject m_Object;
};
void test_050(transaction_base &orgT)
{
connection_base &C(orgT.conn());
orgT.abort();
largeobject Obj;
C.perform(CreateLargeObject(Obj));
C.perform(WriteLargeObject(Obj));
C.perform(DeleteLargeObject(Obj));
}
} // namespace
PQXX_REGISTER_TEST_T(test_050, nontransaction)
|