Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support of bulk operations for ORM in ORACLE and SQLite backends #1053

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 30 additions & 11 deletions include/soci/row.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@

namespace soci
{
struct CaseInsensitiveComparator {
bool operator()(const std::string& a, const std::string& b) const noexcept
{
return ::strcasecmp(a.c_str(), b.c_str()) < 0;
}
};

class SOCI_DECL column_properties
{
Expand All @@ -40,7 +46,7 @@ class SOCI_DECL column_properties
class SOCI_DECL row
{
public:
row();
row(std::size_t bulk_size = 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
row(std::size_t bulk_size = 1);
explicit row(std::size_t bulk_size = 1);

~row();

row(row &&other) = default;
Expand All @@ -51,13 +57,17 @@ class SOCI_DECL row
std::size_t size() const;
void clean_up();

//bulk buffer size
std::size_t bulk_size() const { return bulk_size_; }
void bulk_size(const std::size_t sz) { bulk_size_ = sz; }

indicator get_indicator(std::size_t pos) const;
indicator get_indicator(std::string const& name) const;

template <typename T>
inline void add_holder(T* t, indicator* ind)
inline void add_holder(std::vector<T>* t, std::vector<indicator>* ind)
{
holders_.push_back(new details::type_holder<T>(t));
holders_.push_back(new details::vector_type_holder<T>(t));
indicators_.push_back(ind);
}

Expand All @@ -68,17 +78,17 @@ class SOCI_DECL row
T get(std::size_t pos) const
{
typedef typename type_conversion<T>::base_type base_type;
base_type const& baseVal = holders_.at(pos)->get<base_type>();
base_type const& baseVal = holders_.at(pos)->get<base_type>(bulk_pos_);

T ret;
type_conversion<T>::from_base(baseVal, *indicators_.at(pos), ret);
type_conversion<T>::from_base(baseVal, (*indicators_.at(pos))[bulk_pos_], ret);
return ret;
}

template <typename T>
T get(std::size_t pos, T const &nullValue) const
{
if (i_null == *indicators_.at(pos))
if (i_null == (*indicators_.at(pos))[bulk_pos_])
{
return nullValue;
}
Expand All @@ -98,7 +108,7 @@ class SOCI_DECL row
{
std::size_t const pos = find_column(name);

if (i_null == *indicators_[pos])
if (i_null == (*indicators_[pos])[bulk_pos_])
{
return nullValue;
}
Expand All @@ -122,6 +132,13 @@ class SOCI_DECL row
void reset_get_counter() const
{
currentPos_ = 0;
bulk_pos_ = 0;
}

void next(std::size_t num = 1) const
{
currentPos_ = 0;
bulk_pos_ += num;
}

private:
Expand All @@ -130,12 +147,14 @@ class SOCI_DECL row
std::size_t find_column(std::string const& name) const;

std::vector<column_properties> columns_;
std::vector<details::holder*> holders_;
std::vector<indicator*> indicators_;
std::map<std::string, std::size_t> index_;
std::vector<details::vector_holder*> holders_;
std::vector<std::vector<indicator>*> indicators_;
std::map<std::string, std::size_t, CaseInsensitiveComparator> index_;

bool uppercaseColumnNames_;
mutable std::size_t currentPos_;
mutable std::size_t currentPos_; //column
mutable std::size_t bulk_pos_; //row
mutable std::size_t bulk_size_;
};

} // namespace soci
Expand Down
2 changes: 2 additions & 0 deletions include/soci/soci-platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ namespace std {
}
}
#endif // _MSC_VER < 1800
#define strncasecmp _strnicmp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be unused?

#define strcasecmp _stricmp
#endif // _MSC_VER

#if defined(__CYGWIN__) || defined(__MINGW32__)
Expand Down
9 changes: 9 additions & 0 deletions include/soci/sqlite3/soci-sqlite3.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ class SOCI_SQLITE3_DECL sqlite3_soci_error : public soci_error
int result_;
};


typedef std::map<std::string, data_type> sqlite3_data_type_map;
sqlite3_data_type_map get_data_type_map();

Comment on lines +63 to +66
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There doesn't seem to be any reason to extract this here, is there?

struct sqlite3_statement_backend;
struct sqlite3_standard_into_type_backend : details::standard_into_type_backend
{
Expand All @@ -84,6 +88,7 @@ struct sqlite3_standard_into_type_backend : details::standard_into_type_backend
int position_;
};

struct sqlite3_column;
struct sqlite3_vector_into_type_backend : details::vector_into_type_backend
{
sqlite3_vector_into_type_backend(sqlite3_statement_backend &st)
Expand All @@ -106,6 +111,10 @@ struct sqlite3_vector_into_type_backend : details::vector_into_type_backend
void *data_;
details::exchange_type type_;
int position_;

private:
data_type get_column_type(int colNum);
sqlite3_column get_column(int colNum);
};

struct sqlite3_standard_use_type_backend : details::standard_use_type_backend
Expand Down
5 changes: 3 additions & 2 deletions include/soci/statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,9 @@ class SOCI_DECL statement_impl
template<typename T>
void into_row()
{
T * t = new T();
indicator * ind = new indicator(i_ok);
std::size_t bulk_size = row_->bulk_size();
std::vector<T>* t = new std::vector<T>(bulk_size);
std::vector<indicator>* ind = new std::vector<indicator>(bulk_size);
row_->add_holder(t, ind);
exchange_for_row(into(*t, *ind));
}
Expand Down
44 changes: 25 additions & 19 deletions include/soci/type-conversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ struct base_value_holder

// Automatically create into_type from a type_conversion

template <typename T>
template <typename T, typename X>
class conversion_into_type
: private base_value_holder<T>,
public into_type<typename type_conversion<T>::base_type>
Expand Down Expand Up @@ -80,7 +80,7 @@ class conversion_into_type

// Automatically create use_type from a type_conversion

template <typename T>
template <typename T, typename X>
class conversion_use_type
: private base_value_holder<T>,
public use_type<typename type_conversion<T>::base_type>
Expand Down Expand Up @@ -195,8 +195,8 @@ struct base_vector_holder

// Automatically create a std::vector based into_type from a type_conversion

template <typename T>
class conversion_into_type<std::vector<T> >
template <typename T, typename X>
class conversion_into_type<std::vector<T> , X>
: private base_vector_holder<T>,
public into_type<std::vector<typename type_conversion<T>::base_type> >
{
Expand Down Expand Up @@ -295,8 +295,8 @@ class conversion_into_type<std::vector<T> >

// Automatically create a std::vector based use_type from a type_conversion

template <typename T>
class conversion_use_type<std::vector<T> >
template <typename T, typename X>
class conversion_use_type<std::vector<T>, X >
: private base_vector_holder<T>,
public use_type<std::vector<typename type_conversion<T>::base_type> >
{
Expand Down Expand Up @@ -408,62 +408,68 @@ class conversion_use_type<std::vector<T> >
template <typename T>
into_type_ptr do_into(T & t, user_type_tag)
{
return into_type_ptr(new conversion_into_type<T>(t));
return into_type_ptr(new conversion_into_type<T, typename type_conversion<T>::base_type>(t));
}

template <typename T>
into_type_ptr do_into(std::vector<T>& t, user_type_tag)
{
return into_type_ptr(new conversion_into_type<std::vector<T>, typename type_conversion<T>::base_type>(t));
}

template <typename T>
into_type_ptr do_into(T & t, indicator & ind, user_type_tag)
{
return into_type_ptr(new conversion_into_type<T>(t, ind));
return into_type_ptr(new conversion_into_type<T, typename type_conversion<T>::base_type>(t, ind));
}

template <typename T>
into_type_ptr do_into(std::vector<T> & t,
std::size_t begin, size_t * end, user_type_tag)
{
return into_type_ptr(
new conversion_into_type<std::vector<T> >(t, begin, end));
new conversion_into_type<std::vector<T> , typename type_conversion<T>::base_type>(t, begin, end));
}

template <typename T>
into_type_ptr do_into(std::vector<T> & t, std::vector<indicator> & ind,
user_type_tag)
{
return into_type_ptr(new conversion_into_type<std::vector<T> >(t, ind));
return into_type_ptr(new conversion_into_type<std::vector<T> , typename type_conversion<T>::base_type>(t, ind));
}

template <typename T>
into_type_ptr do_into(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, size_t * end, user_type_tag)
{
return into_type_ptr(
new conversion_into_type<std::vector<T> >(t, ind, begin, end));
new conversion_into_type<std::vector<T> , typename type_conversion<T>::base_type>(t, ind, begin, end));
}

template <typename T>
use_type_ptr do_use(T & t, std::string const & name, user_type_tag)
{
return use_type_ptr(new conversion_use_type<T>(t, name));
return use_type_ptr(new conversion_use_type<T, typename type_conversion<T>::base_type>(t, name));
}

template <typename T>
use_type_ptr do_use(T const & t, std::string const & name, user_type_tag)
{
return use_type_ptr(new conversion_use_type<T>(t, name));
return use_type_ptr(new conversion_use_type<T, typename type_conversion<T>::base_type>(t, name));
}

template <typename T>
use_type_ptr do_use(T & t, indicator & ind,
std::string const & name, user_type_tag)
{
return use_type_ptr(new conversion_use_type<T>(t, ind, name));
return use_type_ptr(new conversion_use_type<T, typename type_conversion<T>::base_type>(t, ind, name));
}

template <typename T>
use_type_ptr do_use(T const & t, indicator & ind,
std::string const & name, user_type_tag)
{
return use_type_ptr(new conversion_use_type<T>(t, ind, name));
return use_type_ptr(new conversion_use_type<T, typename type_conversion<T>::base_type>(t, ind, name));
}

template <typename T>
Expand All @@ -472,7 +478,7 @@ use_type_ptr do_use(std::vector<T> & t,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, begin, end, name));
new conversion_use_type<std::vector<T> , typename type_conversion<T>::base_type>(t, begin, end, name));
}

template <typename T>
Expand All @@ -481,7 +487,7 @@ use_type_ptr do_use(const std::vector<T> & t,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, begin, end, name));
new conversion_use_type<std::vector<T> , typename type_conversion<T>::base_type>(t, begin, end, name));
}

template <typename T>
Expand All @@ -490,7 +496,7 @@ use_type_ptr do_use(std::vector<T> & t, std::vector<indicator> & ind,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, ind, begin, end, name));
new conversion_use_type<std::vector<T> , typename type_conversion<T>::base_type>(t, ind, begin, end, name));
}

template <typename T>
Expand All @@ -499,7 +505,7 @@ use_type_ptr do_use(const std::vector<T> & t, std::vector<indicator> & ind,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, ind, begin, end, name));
new conversion_use_type<std::vector<T> , typename type_conversion<T>::base_type>(t, ind, begin, end, name));
}

} // namespace details
Expand Down
Loading
Loading