Skip to content

Commit

Permalink
Address review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Krzmbrzl committed Jan 16, 2024
1 parent 77ed7fb commit be46771
Show file tree
Hide file tree
Showing 24 changed files with 59 additions and 91 deletions.
7 changes: 6 additions & 1 deletion include/soci/blob.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ class SOCI_DECL blob
[[deprecated("Use read_from_start instead")]]
std::size_t read(std::size_t offset, char * buf, std::size_t toRead);

// offset starts from 0
// Extracts data from this blob into the given buffer.
// At most toRead bytes are extracted (and copied into buf).
// The amount of actually read bytes is returned.
//
// Note: Using an offset > 0 on a blob whose size is less than
// or equal to offset, will throw an exception.
std::size_t read_from_start(char * buf, std::size_t toRead,
std::size_t offset = 0);

Expand Down
12 changes: 6 additions & 6 deletions include/soci/firebird/soci-firebird.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,11 @@ struct firebird_blob_backend : details::blob_backend
std::size_t append(char const *buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;

/// Writes the current data into the database by allocating a new BLOB
/// object for it.
///
/// @returns The ID of the newly created BLOB object
ISC_QUAD write_to_db();
// Writes the current data into the database by allocating a new BLOB
// object for it.
//
// Returns The ID of the newly created BLOB object
ISC_QUAD save_to_db();
void assign(ISC_QUAD const & bid);

private:
Expand All @@ -278,7 +278,7 @@ struct firebird_blob_backend : details::blob_backend
void load();
void writeBuffer(std::size_t offset, char const * buf,
std::size_t toWrite);
void closeBlob(bool keepData);
void closeBlob();

firebird_session_backend &session_;
ISC_QUAD blob_id_;
Expand Down
2 changes: 2 additions & 0 deletions include/soci/oracle/soci-oracle.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ struct oracle_blob_backend : details::blob_backend

locator_t lobp_;

// If this is true, then the locator lobp_ points to something useful
// (instead of being the equivalent to a pointer with random value)
bool initialized_;
};

Expand Down
4 changes: 2 additions & 2 deletions include/soci/soci-backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,10 +341,10 @@ class trivial_blob_backend : public blob_backend
throw soci_error("Can't read past-the-end of BLOB data.");
}

toRead = (std::min)(toRead, buffer_.size() - offset);

// make sure that we don't try to read
// past the end of the data
toRead = (std::min)(toRead, buffer_.size() - offset);

memcpy(buf, buffer_.data() + offset, toRead);

return toRead;
Expand Down
9 changes: 6 additions & 3 deletions include/soci/type-traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef SOCI_PRIVATE_SOCI_TYPE_TRAITS_H_INCLUDED
#define SOCI_PRIVATE_SOCI_TYPE_TRAITS_H_INCLUDED
#ifndef SOCI_SOCI_TYPE_TRAITS_H_INCLUDED
#define SOCI_SOCI_TYPE_TRAITS_H_INCLUDED

#include <type_traits>

Expand All @@ -23,6 +23,9 @@ using false_type = std::integral_constant<bool, false>;
using true_type = std::integral_constant<bool, true>;

// Implementation from https://blog.tartanllama.xyz/detection-idiom/
// Note, this is a stub that we require until standard C++ gets support
// for the detection idiom that is not experimental (and thus can be
// assumed to be present).

namespace detector_detail
{
Expand All @@ -43,4 +46,4 @@ using is_detected = typename detector_detail::is_detected<Trait, void, Args...>:

}

#endif // SOCI_PRIVATE_SOCI_TYPE_TRAITS_H_INCLUDED
#endif // SOCI_SOCI_TYPE_TRAITS_H_INCLUDED
16 changes: 6 additions & 10 deletions src/backends/firebird/blob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ firebird_blob_backend::firebird_blob_backend(firebird_session_backend &session)

firebird_blob_backend::~firebird_blob_backend()
{
closeBlob(false);
closeBlob();
}

std::size_t firebird_blob_backend::get_len()
Expand Down Expand Up @@ -152,17 +152,12 @@ void firebird_blob_backend::open()
data_.resize(blob_size);
}

void firebird_blob_backend::closeBlob(bool keepData)
void firebird_blob_backend::closeBlob()
{
from_db_ = false;
loaded_ = false;
max_seg_size_ = 0;

if (!keepData)
{
data_.resize(0);
}

if (blob_handle_ != 0)
{
// close blob
Expand Down Expand Up @@ -231,7 +226,7 @@ void firebird_blob_backend::load()
loaded_ = true;
}

ISC_QUAD firebird_blob_backend::write_to_db()
ISC_QUAD firebird_blob_backend::save_to_db()
{
// close old blob if necessary
ISC_STATUS stat[20];
Expand Down Expand Up @@ -280,14 +275,15 @@ ISC_QUAD firebird_blob_backend::write_to_db()
// In any case, BLOBs in Firebird can't be updated anyway - one always has to create a new BLOB object
// (with a new ID) and then use that to modify the existing one (replace the ID in the corresponding table).
// Therefore, keeping the Blob open for subsequent modification is not needed.
closeBlob(true);
closeBlob();

return blob_id_;
}

void firebird_blob_backend::assign(const ISC_QUAD &id)
{
closeBlob(false);
closeBlob();
data_.clear();

blob_id_ = id;
from_db_ = true;
Expand Down
4 changes: 2 additions & 2 deletions src/backends/firebird/standard-use-type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void firebird_standard_use_type_backend::exchangeData()
throw soci_error("Can't get Firebid BLOB BackEnd");
}

ISC_QUAD blob_id = blob->write_to_db();
ISC_QUAD blob_id = blob->save_to_db();
memcpy(buf_, &blob_id, sizeof(blob_id));
}
break;
Expand All @@ -185,7 +185,7 @@ void firebird_standard_use_type_backend::copy_to_blob(const std::string& in)

blob_->append(in.c_str(), in.length());

ISC_QUAD blob_id = blob_->write_to_db();
ISC_QUAD blob_id = blob_->save_to_db();
memcpy(buf_, &blob_id, sizeof(blob_id));
}

Expand Down
2 changes: 1 addition & 1 deletion src/backends/firebird/vector-use-type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ void firebird_vector_use_type_backend::copy_to_blob(const std::string &in)

blob_ = new firebird_blob_backend(statement_.session_);
blob_->append(in.c_str(), in.length());
ISC_QUAD blob_id = blob_->write_to_db();
ISC_QUAD blob_id = blob_->save_to_db();
memcpy(buf_, &blob_id, sizeof(blob_id));
}

Expand Down
3 changes: 3 additions & 0 deletions src/backends/mysql/standard-use-type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ void mysql_standard_use_type_backend::pre_use(indicator const *ind)
}
else
{
// Note: since the entire MySQL works by assembling the query in text form,
// we can't make use of proper blob objects (that'd require a more sophisticated
// way of using the MySQL API).
buf_ = new char[hex_size + 1];
bbe->write_hex_str(buf_, hex_size);
// Add NULL terminator
Expand Down
8 changes: 3 additions & 5 deletions src/backends/oracle/blob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
#include <ctime>
#include <cctype>

#include <iostream>

#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
Expand Down Expand Up @@ -97,11 +95,11 @@ std::size_t oracle_blob_backend::read_from_start(char *buf, std::size_t toRead,

std::size_t oracle_blob_backend::write_from_start(char const *buf, std::size_t toWrite, std::size_t offset)
{
if (offset > get_len())
{
if (offset > get_len())
{
// If offset == length, the operation is to be understood as appending (and is therefore allowed)
throw soci_error("Can't start writing far past-the-end of BLOB data.");
}
}

ensure_initialized();

Expand Down
18 changes: 9 additions & 9 deletions src/backends/postgresql/blob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ void postgresql_blob_backend::clone()
}

blob_details old_details = details_;
details_ = {};
details_ = {};
reset();
init();

Expand Down Expand Up @@ -282,15 +282,15 @@ void postgresql_blob_backend::clone()
offset += sizeof(buf);
} while (read_bytes == sizeof(buf));

// Dispose old BLOB object
if (destroy_on_close_)
// Dispose old BLOB object
if (destroy_on_close_)
{
// Remove the large object from the DB completely
lo_unlink(session_.conn_, old_details.fd);
}
// Remove the large object from the DB completely
lo_unlink(session_.conn_, old_details.fd);
}
else
{
// Merely close our handle to the large object
lo_close(session_.conn_, old_details.fd);
}
// Merely close our handle to the large object
lo_close(session_.conn_, old_details.fd);
}
}
9 changes: 5 additions & 4 deletions src/backends/sqlite3/statement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,11 @@ sqlite3_statement_backend::bind_and_execute(int number)
break;

case db_blob:
// Since we don't own the buffer_ pointer we are passing here, we can't make any lifetime guarantees other than
// it is currently valid. Thus, we ask SQLite to make a copy of the underlying buffer to ensure
// the database can always access a valid buffer.
bindRes = sqlite3_bind_blob(stmt_, pos, col.buffer_.constData_, static_cast<int>(col.buffer_.size_), SQLITE_TRANSIENT);
// Since we don't own the buffer_ pointer we are passing here, we can't make any lifetime
// guarantees other than it is currently valid. Thus, we ask SQLite to make a copy of the
// underlying buffer to ensure the database can always access a valid buffer.
bindRes = sqlite3_bind_blob(stmt_, pos, col.buffer_.constData_,
static_cast<int>(col.buffer_.size_), SQLITE_TRANSIENT);
break;

case db_xml:
Expand Down
21 changes: 1 addition & 20 deletions tests/common-tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,18 +363,6 @@ class function_creator_base
SOCI_NOT_COPYABLE(function_creator_base)
};

enum class Backend
{
Empty,
SQLite,
MySQL,
PostgreSQL,
ODBC,
Oracle,
Firebird,
DB2,
};

// This is a singleton class, at any given time there is at most one test
// context alive and common_tests fixture class uses it.
class test_context_base
Expand Down Expand Up @@ -416,8 +404,6 @@ class test_context_base
return connectString_;
}

virtual Backend get_backend() const = 0;

virtual std::string to_date_time(std::string const &dateTime) const = 0;

virtual table_creator_base* table_creator_1(session&) const = 0;
Expand Down Expand Up @@ -6404,7 +6390,7 @@ TEST_CASE_METHOD(common_tests, "BLOB", "[core][blob]")
return;
}

const char dummy_data[] = "abcdefghijklmnopüqrstuvwxyz";
const char dummy_data[] = "abcdefghijklmnopqrstuvwxyz";

// Cross-DB usage of BLOBs is only possible if the entire lifetime of the blob object
// is covered in an active transaction.
Expand Down Expand Up @@ -6636,10 +6622,6 @@ TEST_CASE_METHOD(common_tests, "BLOB", "[core][blob]")
containedData = true;
const soci::row &currentRow = *it;

soci::data_type type = currentRow.get_properties(0).get_data_type();
soci::data_type expectedType = tc_.get_backend() != Backend::Oracle ? soci::dt_integer : soci::dt_long_long;
CHECK(type == expectedType);

CHECK(currentRow.get_properties(1).get_data_type() == soci::dt_blob);
}
CHECK(containedData);
Expand Down Expand Up @@ -6750,7 +6732,6 @@ TEST_CASE_METHOD(common_tests, "BLOB", "[core][blob]")
CHECK(!select_stmt.fetch());
}
}
transaction.rollback();
}

TEST_CASE_METHOD(common_tests, "Logger", "[core][log]")
Expand Down
2 changes: 0 additions & 2 deletions tests/db2/test-db2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ class test_context :public test_context_base
test_context(backend_factory const & pi_back_end, std::string const & pi_connect_string)
: test_context_base(pi_back_end, pi_connect_string) {}

Backend get_backend() const override { return Backend::DB2; }

table_creator_base* table_creator_1(soci::session & pr_s) const override
{
pr_s << "SET CURRENT SCHEMA = 'DB2INST1'";
Expand Down
2 changes: 0 additions & 2 deletions tests/firebird/test-firebird.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1191,8 +1191,6 @@ class test_context : public tests::test_context_base
: test_context_base(backEnd, connectString)
{}

tests::Backend get_backend() const override { return tests::Backend::Firebird; }

tests::table_creator_base* table_creator_1(soci::session& s) const override
{
return new TableCreator1(s);
Expand Down
9 changes: 2 additions & 7 deletions tests/mysql/test-mysql.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ class test_context : public test_context_base
std::string const &connectString)
: test_context_base(backEnd, connectString) {}

Backend get_backend() const override { return Backend::MySQL; }

table_creator_base* table_creator_1(soci::session& s) const override
{
return new table_creator_one(s);
Expand All @@ -97,13 +95,10 @@ class test_context : public test_context_base
return "\'" + datdt_string + "\'";
}

#ifndef SOCI_INCLUDED_FROM_ODBC_TEST
// ODBC backend doesn't support BLOBs yet
table_creator_base* table_creator_blob(soci::session& s) const override
table_creator_base * table_creator_blob(soci::session &s) const override
{
return new table_creator_for_blob(s);
return new table_creator_for_blob(s);
}
#endif

bool has_fp_bug() const override
{
Expand Down
2 changes: 0 additions & 2 deletions tests/odbc/test-odbc-access.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ class test_context : public test_context_base
test_context(backend_factory const &backend, std::string const &connstr)
: test_context_base(backend, connstr) {}

Backend get_backend() const override { return Backend::ODBC; }

table_creator_base * table_creator_1(soci::session& s) const
{
return new table_creator_one(s);
Expand Down
2 changes: 0 additions & 2 deletions tests/odbc/test-odbc-db2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ class test_context : public test_context_base
std::string const &connectString)
: test_context_base(backEnd, connectString) {}

Backend get_backend() const override { return Backend::ODBC; }

table_creator_base * table_creator_1(soci::session& s) const
{
return new table_creator_one(s);
Expand Down
2 changes: 0 additions & 2 deletions tests/odbc/test-odbc-mssql.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,6 @@ class test_context : public test_context_base
std::string const &connstr)
: test_context_base(backend, connstr) {}

Backend get_backend() const override { return Backend::ODBC; }

table_creator_base* table_creator_1(soci::session& s) const override
{
return new table_creator_one(s);
Expand Down
Loading

0 comments on commit be46771

Please sign in to comment.