File indexing completed on 2025-02-11 03:07:42
0001 #ifndef CondCore_ConditionDatabase_DbCore_h
0002 #define CondCore_ConditionDatabase_DbCore_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include "CondCore/CondDB/interface/Exception.h"
0017 #include "CondCore/CondDB/interface/Binary.h"
0018 #include "CondCore/CondDB/interface/Time.h"
0019 #include "CondCore/CondDB/interface/Types.h"
0020
0021 #include "CoralBase/AttributeList.h"
0022 #include "CoralBase/Attribute.h"
0023 #include "CoralBase/AttributeSpecification.h"
0024 #include "CoralBase/Blob.h"
0025 #include "CoralBase/TimeStamp.h"
0026 #include "RelationalAccess/ICursor.h"
0027 #include "RelationalAccess/ISchema.h"
0028 #include "RelationalAccess/ISessionProxy.h"
0029 #include "RelationalAccess/IQuery.h"
0030 #include "RelationalAccess/TableDescription.h"
0031 #include "RelationalAccess/ITable.h"
0032 #include "RelationalAccess/IColumn.h"
0033 #include "RelationalAccess/ITableDataEditor.h"
0034 #include "RelationalAccess/IBulkOperation.h"
0035 #include "RelationalAccess/SchemaException.h"
0036
0037 #include <tuple>
0038 #include <cstring>
0039 #include <set>
0040 #include <map>
0041 #include <memory>
0042
0043 #include <boost/date_time/posix_time/posix_time.hpp>
0044
0045
0046
0047
0048 #define conddb_table(NAME) \
0049 namespace NAME { \
0050 static constexpr char const* tname = #NAME; \
0051 } \
0052 namespace NAME
0053
0054
0055
0056
0057 #define FIXSIZE_COLUMN(NAME, TYPE, SIZE) \
0058 struct NAME { \
0059 static constexpr char const* name = #NAME; \
0060 typedef TYPE type; \
0061 static constexpr size_t size = SIZE; \
0062 static std::string tableName() { return std::string(tname); } \
0063 static std::string fullyQualifiedName() { return std::string(tname) + "." + std::string(name); } \
0064 };
0065
0066
0067 #define VARSIZE_COLUMN(NAME, TYPE) FIXSIZE_COLUMN(NAME, TYPE, 0)
0068
0069
0070 #define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
0071 #define WRONG_PAR_NUMBER_ERROR(...) static_assert(false, "\"column\" macro accepts exactly 2 or 3 parameters")
0072 #define SELECT_COLUMN_MACRO(...) GET_4TH_ARG(__VA_ARGS__, FIXSIZE_COLUMN, VARSIZE_COLUMN, WRONG_PAR_NUMBER_ERROR)
0073
0074
0075 #define conddb_column(...) SELECT_COLUMN_MACRO(__VA_ARGS__)(__VA_ARGS__)
0076
0077 namespace cond {
0078
0079 namespace persistency {
0080
0081
0082 template <typename T, typename P>
0083 inline void static_assert_is_same_decayed() {
0084 static_assert(std::is_same<typename std::decay<T>::type, typename std::decay<P>::type>::value,
0085 "Parameter types don't match with the RowBuffer types");
0086 };
0087
0088
0089 template <typename T>
0090 inline void f_add_attribute(coral::AttributeList& data,
0091 const std::string& attributeName,
0092 const T& param,
0093 bool init = true) {
0094 if (init)
0095 data.extend<T>(attributeName);
0096 data[attributeName].data<T>() = param;
0097 }
0098
0099 template <>
0100 inline void f_add_attribute(coral::AttributeList& data,
0101 const std::string& attributeName,
0102 const cond::Binary& param,
0103 bool init) {
0104 if (init)
0105 data.extend<coral::Blob>(attributeName);
0106 data[attributeName].bind(param.get());
0107 }
0108
0109 template <>
0110 inline void f_add_attribute(coral::AttributeList& data,
0111 const std::string& attributeName,
0112 const boost::posix_time::ptime& param,
0113 bool init) {
0114 if (init)
0115 data.extend<coral::TimeStamp>(attributeName);
0116 data[attributeName].data<coral::TimeStamp>() = coral::TimeStamp(param);
0117 }
0118
0119 template <>
0120 inline void f_add_attribute(coral::AttributeList& data,
0121 const std::string& attributeName,
0122 const cond::TimeType& param,
0123 bool init) {
0124 if (init)
0125 data.extend<std::string>(attributeName);
0126 data[attributeName].data<std::string>() = cond::time::timeTypeName(param);
0127 }
0128
0129 template <>
0130 inline void f_add_attribute(coral::AttributeList& data,
0131 const std::string& attributeName,
0132 const cond::SynchronizationType& param,
0133 bool init) {
0134 if (init)
0135 data.extend<std::string>(attributeName);
0136 data[attributeName].data<std::string>() = synchronizationTypeNames(param);
0137 }
0138
0139
0140 template <typename Column, typename P>
0141 inline void f_add_column_data(coral::AttributeList& data, const P& param, bool init = true) {
0142 static_assert_is_same_decayed<typename Column::type, P>();
0143 f_add_attribute(data, Column::name, param, init);
0144 }
0145
0146
0147 template <typename Column, typename P>
0148 inline void f_add_condition_data(coral::AttributeList& data,
0149 std::string& whereClause,
0150 const P& value,
0151 const std::string condition = "=") {
0152 static_assert_is_same_decayed<typename Column::type, P>();
0153 std::stringstream varId;
0154 unsigned int id = data.size();
0155 varId << Column::name << "_" << id;
0156 if (!whereClause.empty())
0157 whereClause += " AND ";
0158 whereClause += Column::fullyQualifiedName() + " " + condition + " :" + varId.str() + " ";
0159
0160 f_add_attribute(data, varId.str(), value);
0161 }
0162
0163
0164 template <typename C1, typename C2>
0165 inline void f_add_condition(std::string& whereClause, const std::string condition = "=") {
0166 if (!whereClause.empty())
0167 whereClause += " AND ";
0168 whereClause += C1::fullyQualifiedName() + " " + condition + " " + C2::fullyQualifiedName() + " ";
0169 }
0170
0171
0172
0173 template <typename... Columns>
0174 class RowBuffer {
0175 private:
0176 template <typename Params, int n, typename T1, typename... Ts>
0177 void _set(const Params& params, bool init = true) {
0178 f_add_column_data<T1>(m_data, std::get<n>(params), init);
0179 _set<Params, n + 1, Ts...>(params, init);
0180 }
0181
0182 template <typename Params, int n>
0183 void _set(const Params&, bool) {}
0184
0185 public:
0186 RowBuffer() : m_data() {}
0187
0188 template <typename P>
0189 explicit RowBuffer(const P& params) : m_data() {
0190 _set<P, 0, Columns...>(params);
0191 }
0192
0193 template <typename P>
0194 void set(const P& params) {
0195 bool init = (m_data.size() == 0);
0196
0197 _set<P, 0, Columns...>(params, init);
0198 }
0199
0200 const coral::AttributeList& get() const { return m_data; }
0201
0202 protected:
0203 coral::AttributeList m_data;
0204 };
0205
0206 template <typename... Columns>
0207 class ConditionBuffer {
0208 private:
0209 template <typename Params, int n, typename T1, typename... Ts>
0210 void _set(const Params& params) {
0211 f_add_condition_data<T1>(m_data, m_clause, std::get<n>(params));
0212 _set<Params, n + 1, Ts...>(params);
0213 }
0214
0215 template <typename Params, int n>
0216 void _set(const Params&) {}
0217
0218 public:
0219 ConditionBuffer() : m_data(), m_clause() {}
0220
0221 template <typename P>
0222 void set(const P& params) {
0223
0224 _set<P, 0, Columns...>(params);
0225 }
0226
0227 void addStaticCondition(const std::string& condition) {
0228 if (!m_clause.empty()) {
0229 m_clause += " AND ";
0230 }
0231 m_clause += condition;
0232 }
0233
0234 const coral::AttributeList& get() const { return m_data; }
0235
0236 const std::string& getClause() const { return m_clause; }
0237
0238 protected:
0239 coral::AttributeList m_data;
0240 std::string m_clause;
0241 };
0242
0243 template <typename T>
0244 struct AttributeTypeName {
0245 std::string operator()() { return coral::AttributeSpecification::typeNameForType<T>(); }
0246 };
0247 template <>
0248 struct AttributeTypeName<cond::Binary> {
0249 std::string operator()() { return coral::AttributeSpecification::typeNameForType<coral::Blob>(); }
0250 };
0251 template <>
0252 struct AttributeTypeName<boost::posix_time::ptime> {
0253 std::string operator()() { return coral::AttributeSpecification::typeNameForType<coral::TimeStamp>(); }
0254 };
0255 template <>
0256 struct AttributeTypeName<cond::TimeType> {
0257 std::string operator()() { return coral::AttributeSpecification::typeNameForType<std::string>(); }
0258 };
0259 template <>
0260 struct AttributeTypeName<cond::SynchronizationType> {
0261 std::string operator()() { return coral::AttributeSpecification::typeNameForType<std::string>(); }
0262 };
0263
0264 template <typename T>
0265 void f_add_column_description(coral::TableDescription& table,
0266 const std::string& columnName,
0267 size_t size = 0,
0268 bool notNull = true) {
0269 table.insertColumn(columnName, AttributeTypeName<T>()(), size);
0270 if (notNull)
0271 table.setNotNullConstraint(columnName);
0272 }
0273
0274 template <typename T, typename Arg1>
0275 constexpr bool is_same_any() {
0276 return std::is_same<T, Arg1>::value;
0277 };
0278
0279 template <typename T, typename Arg1, typename Arg2, typename... Args>
0280 constexpr bool is_same_any() {
0281 return is_same_any<T, Arg1>() || is_same_any<T, Arg2, Args...>();
0282 };
0283
0284 template <typename... Types>
0285 class TableDescription {
0286 private:
0287 template <int n>
0288 void addColumn(coral::TableDescription&) {}
0289
0290 template <int n, typename Arg1, typename... Args>
0291 void addColumn(coral::TableDescription& tableDescription) {
0292 std::string columnName(Arg1::name);
0293 f_add_column_description<typename Arg1::type>(m_description, columnName, Arg1::size);
0294 addColumn<n + 1, Args...>(m_description);
0295 }
0296
0297 template <int, typename Col1, typename... Cols>
0298 void checkColumns() {
0299 static_assert(is_same_any<Col1, Types...>(), "Specified Column has not been found in the table.");
0300 checkColumns<0, Cols...>();
0301 }
0302
0303 template <int>
0304 void checkColumns() {}
0305
0306 public:
0307 explicit TableDescription(const char* name) : m_description("ConditionDatabase") {
0308 m_description.setName(name);
0309 addColumn<0, Types...>(m_description);
0310 }
0311
0312
0313 template <typename... ColumnTypes>
0314 void setPrimaryKey() {
0315 checkColumns<0, ColumnTypes...>();
0316 m_description.setPrimaryKey(makeList<ColumnTypes...>());
0317 }
0318
0319 template <typename... ColumnTypes>
0320 void setUniqueConstraint(const std::string& name) {
0321 checkColumns<0, ColumnTypes...>();
0322 m_description.setUniqueConstraint(makeList<ColumnTypes...>(), name);
0323 }
0324
0325 template <typename... ColumnTypes>
0326 void createIndex(const std::string& name) {
0327 checkColumns<0, ColumnTypes...>();
0328 m_description.createIndex(name, makeList<ColumnTypes...>());
0329 }
0330
0331 template <typename Column, typename ReferencedColumn>
0332 void setForeignKey(const std::string& name) {
0333 checkColumns<0, Column>();
0334 m_description.createForeignKey(name, Column::name, ReferencedColumn::tableName(), ReferencedColumn::name);
0335 }
0336
0337 const coral::TableDescription& get() { return m_description; }
0338
0339 private:
0340 template <int n>
0341 void _makeList(std::vector<std::string>&) {}
0342
0343 template <int n, typename Arg1, typename... Args>
0344 void _makeList(std::vector<std::string>& columnNames) {
0345 columnNames.push_back(Arg1::name);
0346 _makeList<n + 1, Args...>(columnNames);
0347 }
0348
0349 template <typename... ColumnTypes>
0350 std::vector<std::string> makeList() {
0351 std::vector<std::string> columnList;
0352 _makeList<0, ColumnTypes...>(columnList);
0353 return columnList;
0354 }
0355
0356 private:
0357 coral::TableDescription m_description;
0358 };
0359
0360 template <typename T>
0361 struct GetFromRow {
0362 T operator()(const coral::AttributeList& row, const std::string& fullyQualifiedName) {
0363 return row[fullyQualifiedName].data<T>();
0364 }
0365 };
0366 template <>
0367 struct GetFromRow<cond::Binary> {
0368 cond::Binary operator()(const coral::AttributeList& row, const std::string& fullyQualifiedName) {
0369 return cond::Binary(row[fullyQualifiedName].data<coral::Blob>());
0370 }
0371 };
0372 template <>
0373 struct GetFromRow<boost::posix_time::ptime> {
0374 boost::posix_time::ptime operator()(const coral::AttributeList& row, const std::string& fullyQualifiedName) {
0375 return row[fullyQualifiedName].data<coral::TimeStamp>().time();
0376 }
0377 };
0378 template <>
0379 struct GetFromRow<cond::TimeType> {
0380 cond::TimeType operator()(const coral::AttributeList& row, const std::string& fullyQualifiedName) {
0381 return cond::time::timeTypeFromName(row[fullyQualifiedName].data<std::string>());
0382 }
0383 };
0384 template <>
0385 struct GetFromRow<cond::SynchronizationType> {
0386 cond::SynchronizationType operator()(const coral::AttributeList& row, const std::string& fullyQualifiedName) {
0387 return cond::synchronizationTypeFromName(row[fullyQualifiedName].data<std::string>());
0388 }
0389 };
0390 template <std::size_t n>
0391 struct GetFromRow<std::array<char, n> > {
0392 std::string operator()(const coral::AttributeList& row, const std::string& fullyQualifiedName) {
0393 std::string val = row[fullyQualifiedName].data<std::string>();
0394 if (val.size() != n)
0395 throwException("Retrieved string size does not match with the expected string size.", "getFromRow");
0396 std::array<char, n> ret;
0397 ::memcpy(ret.data(), val.c_str(), n);
0398 return ret;
0399 }
0400 };
0401
0402 template <typename... Types>
0403 class Query;
0404
0405 template <typename... Types>
0406 class QueryIterator {
0407 public:
0408
0409 using iterator_category = std::input_iterator_tag;
0410 using value_type = std::tuple<Types...>;
0411 using difference_type = void;
0412 using pointer = void;
0413 using reference = void;
0414
0415 QueryIterator() {}
0416
0417 QueryIterator(const QueryIterator& rhs) : m_query(rhs.m_query), m_currentRow(rhs.m_currentRow) {}
0418
0419 explicit QueryIterator(Query<Types...>* parent) : m_query(parent) {}
0420
0421 QueryIterator& operator=(const QueryIterator& rhs) {
0422 m_query = rhs.m_query;
0423 m_currentRow = rhs.m_currentRow;
0424 return *this;
0425 }
0426
0427 template <typename T>
0428 typename T::type get() const {
0429 return GetFromRow<typename T::type>()(*m_currentRow, T::fullyQualifiedName());
0430 }
0431
0432 auto operator*() -> decltype(std::make_tuple(this->get<Types>()...)) { return std::make_tuple(get<Types>()...); }
0433
0434 QueryIterator& operator++() {
0435 m_currentRow = m_query->next() ? &m_query->currentRow() : nullptr;
0436 return *this;
0437 }
0438
0439 QueryIterator operator++(int) {
0440 QueryIterator tmp(*this);
0441 operator++();
0442 return tmp;
0443 }
0444
0445 bool operator==(const QueryIterator& rhs) const {
0446 if (rhs.m_query == nullptr && m_query == nullptr)
0447 return true;
0448 return m_query == rhs.m_query && m_currentRow == rhs.m_currentRow;
0449 }
0450 bool operator!=(const QueryIterator& rhs) const { return !operator==(rhs); }
0451
0452 operator bool() const { return m_currentRow; }
0453
0454 private:
0455 Query<Types...>* m_query = nullptr;
0456 const coral::AttributeList* m_currentRow = nullptr;
0457 };
0458
0459 template <typename T>
0460 struct DefineQueryOutput {
0461 static void make(coral::IQuery& query, const std::string& fullyQualifiedName) {
0462 query.addToOutputList(fullyQualifiedName);
0463 query.defineOutputType(fullyQualifiedName, coral::AttributeSpecification::typeNameForType<T>());
0464 }
0465 };
0466 template <>
0467 struct DefineQueryOutput<cond::Binary> {
0468 static void make(coral::IQuery& query, const std::string& fullyQualifiedName) {
0469 query.addToOutputList(fullyQualifiedName);
0470 query.defineOutputType(fullyQualifiedName, coral::AttributeSpecification::typeNameForType<coral::Blob>());
0471 }
0472 };
0473 template <>
0474 struct DefineQueryOutput<boost::posix_time::ptime> {
0475 static void make(coral::IQuery& query, const std::string& fullyQualifiedName) {
0476 query.addToOutputList(fullyQualifiedName);
0477 query.defineOutputType(fullyQualifiedName, coral::AttributeSpecification::typeNameForType<coral::TimeStamp>());
0478 }
0479 };
0480 template <>
0481 struct DefineQueryOutput<cond::TimeType> {
0482 static void make(coral::IQuery& query, const std::string& fullyQualifiedName) {
0483 query.addToOutputList(fullyQualifiedName);
0484 query.defineOutputType(fullyQualifiedName, coral::AttributeSpecification::typeNameForType<std::string>());
0485 }
0486 };
0487 template <>
0488 struct DefineQueryOutput<cond::SynchronizationType> {
0489 static void make(coral::IQuery& query, const std::string& fullyQualifiedName) {
0490 query.addToOutputList(fullyQualifiedName);
0491 query.defineOutputType(fullyQualifiedName, coral::AttributeSpecification::typeNameForType<std::string>());
0492 }
0493 };
0494 template <std::size_t n>
0495 struct DefineQueryOutput<std::array<char, n> > {
0496 static void make(coral::IQuery& query, const std::string& fullyQualifiedName) {
0497 query.addToOutputList(fullyQualifiedName);
0498 query.defineOutputType(fullyQualifiedName, coral::AttributeSpecification::typeNameForType<std::string>());
0499 }
0500 };
0501
0502 template <typename... Types>
0503 class Query {
0504 public:
0505 Query(const coral::ISchema& schema, bool distinct = false)
0506 : m_coralQuery(schema.newQuery()), m_whereData(), m_whereClause(""), m_tables() {
0507 _Query<0, Types...>();
0508 if (distinct)
0509 m_coralQuery->setDistinct();
0510 }
0511
0512 ~Query() {}
0513
0514 template <typename Col>
0515 Query& addTable() {
0516 if (m_tables.find(Col::tableName()) == m_tables.end()) {
0517 m_coralQuery->addToTableList(Col::tableName());
0518 m_tables.insert(Col::tableName());
0519 }
0520 return *this;
0521 }
0522
0523 template <int n>
0524 void _Query() {}
0525
0526 template <int n, typename Arg1, typename... Args>
0527 void _Query() {
0528 addTable<Arg1>();
0529 DefineQueryOutput<typename Arg1::type>::make(*m_coralQuery, Arg1::fullyQualifiedName());
0530 _Query<n + 1, Args...>();
0531 }
0532
0533 template <typename C, typename T>
0534 Query& addCondition(const T& value, const std::string condition = "=") {
0535 addTable<C>();
0536 f_add_condition_data<C>(m_whereData, m_whereClause, value, condition);
0537 return *this;
0538 }
0539
0540 template <typename C1, typename C2>
0541 Query& addCondition(const std::string condition = "=") {
0542 addTable<C1>();
0543 addTable<C2>();
0544 f_add_condition<C1, C2>(m_whereClause, condition);
0545 return *this;
0546 }
0547
0548 template <typename C>
0549 Query& addOrderClause(bool ascending = true) {
0550 std::string orderClause(C::fullyQualifiedName());
0551 if (!ascending)
0552 orderClause += " DESC";
0553 m_coralQuery->addToOrderList(orderClause);
0554 return *this;
0555 }
0556
0557 Query& groupBy(const std::string& expression) {
0558 m_coralQuery->groupBy(expression);
0559 return *this;
0560 }
0561
0562 Query& setForUpdate() {
0563 m_coralQuery->setForUpdate();
0564 return *this;
0565 }
0566
0567 Query& limitReturnedRows(size_t nrows) {
0568 m_coralQuery->limitReturnedRows(nrows);
0569 return *this;
0570 }
0571
0572 bool next() {
0573 if (!m_cursor)
0574 throwException("The query has not been executed.", "Query::currentRow");
0575 bool ret = m_cursor->next();
0576 if (ret)
0577 m_retrievedRows++;
0578 return ret;
0579 }
0580
0581 const coral::AttributeList& currentRow() const {
0582 if (!m_cursor)
0583 throwException("The query has not been executed.", "Query::currentRow");
0584 return m_cursor->currentRow();
0585 }
0586
0587 const QueryIterator<Types...> begin() {
0588 m_coralQuery->setCondition(m_whereClause, m_whereData);
0589 m_cursor = &m_coralQuery->execute();
0590 m_retrievedRows = 0;
0591 QueryIterator<Types...> ret(this);
0592 return ++ret;
0593 }
0594
0595 const QueryIterator<Types...> end() { return QueryIterator<Types...>(this); }
0596
0597 size_t retrievedRows() const { return m_retrievedRows; }
0598
0599 private:
0600 std::unique_ptr<coral::IQuery> m_coralQuery;
0601 coral::ICursor* m_cursor = nullptr;
0602 size_t m_retrievedRows = 0;
0603 coral::AttributeList m_whereData;
0604 std::string m_whereClause;
0605 std::set<std::string> m_tables;
0606 };
0607
0608 class UpdateBuffer {
0609 private:
0610 template <typename Params, int n, typename C1, typename... Cs>
0611 void _set(const Params& params) {
0612 f_add_column_data<C1>(m_data, std::get<n>(params));
0613 if (!m_setClause.empty())
0614 m_setClause += ", ";
0615 m_setClause += std::string(C1::name) + " = :" + std::string(C1::name);
0616 _set<Params, n + 1, Cs...>(params);
0617 }
0618
0619 template <typename Params, int n>
0620 void _set(const Params&) {}
0621
0622 public:
0623 UpdateBuffer() : m_data(), m_setClause(""), m_whereClause("") {}
0624
0625 template <typename... Columns, typename Params>
0626 void setColumnData(const Params& params) {
0627 _set<Params, 0, Columns...>(params);
0628 }
0629
0630 template <typename Column1, typename Column2>
0631 void setColumnMatch() {
0632 if (!m_setClause.empty())
0633 m_setClause += ", ";
0634 m_setClause += std::string(Column1::name) + " = " + std::string(Column2::name);
0635 }
0636
0637 template <typename Column, typename P>
0638 void addWhereCondition(const P& param, const std::string condition = "=") {
0639 f_add_condition_data<Column>(m_data, m_whereClause, param, condition);
0640 }
0641
0642 template <typename Column1, typename Column2>
0643 void addWhereCondition(const std::string condition = "=") {
0644 f_add_condition<Column1, Column2>(m_whereClause, condition);
0645 }
0646
0647 const coral::AttributeList& get() const { return m_data; }
0648
0649 const std::string& setClause() const { return m_setClause; }
0650
0651 const std::string& whereClause() const { return m_whereClause; }
0652
0653 private:
0654 coral::AttributeList m_data;
0655 std::string m_setClause;
0656 std::string m_whereClause;
0657 };
0658
0659 class DeleteBuffer {
0660 public:
0661 DeleteBuffer() : m_data(), m_whereClause("") {}
0662
0663 template <typename Column, typename P>
0664 void addWhereCondition(const P& param, const std::string condition = "=") {
0665 f_add_condition_data<Column>(m_data, m_whereClause, param, condition);
0666 }
0667
0668 template <typename Column1, typename Column2>
0669 void addWhereCondition(const std::string condition = "=") {
0670 f_add_condition<Column1, Column2>(m_whereClause, condition);
0671 }
0672
0673 const coral::AttributeList& get() const { return m_data; }
0674
0675 const std::string& whereClause() const { return m_whereClause; }
0676
0677 private:
0678 coral::AttributeList m_data;
0679 std::string m_whereClause;
0680 };
0681
0682 template <typename... Types>
0683 class BulkInserter {
0684 public:
0685 static constexpr size_t cacheSize = 1000;
0686 BulkInserter(coral::ISchema& schema, const char* tableName)
0687 : m_schema(schema), m_tableName(tableName), m_buffer(), m_coralInserter() {
0688
0689
0690 }
0691
0692 template <typename P>
0693 void insert(const P& params) {
0694 m_buffer.set(params);
0695 if (!m_coralInserter.get())
0696 m_coralInserter.reset(m_schema.tableHandle(m_tableName).dataEditor().bulkInsert(m_buffer.get(), cacheSize));
0697 m_coralInserter->processNextIteration();
0698 }
0699
0700 void flush() {
0701 if (m_coralInserter.get())
0702 m_coralInserter->flush();
0703 }
0704
0705 private:
0706
0707 coral::ISchema& m_schema;
0708 std::string m_tableName;
0709
0710 RowBuffer<Types...> m_buffer;
0711 std::unique_ptr<coral::IBulkOperation> m_coralInserter;
0712 };
0713
0714 template <typename... Types>
0715 class BulkDeleter {
0716 public:
0717 static constexpr size_t cacheSize = 1000;
0718 explicit BulkDeleter(coral::ISchema& schema, const char* tableName)
0719 : m_schema(schema), m_tableName(tableName), m_buffer(), m_coralDeleter() {
0720
0721
0722 }
0723
0724 void addStaticCondition(const std::string& condition) { m_buffer.addStaticCondition(condition); }
0725
0726 template <typename P>
0727 void erase(const P& params) {
0728 m_buffer.set(params);
0729 if (!m_coralDeleter.get())
0730 m_coralDeleter.reset(m_schema.tableHandle(m_tableName)
0731 .dataEditor()
0732 .bulkDeleteRows(m_buffer.getClause(), m_buffer.get(), cacheSize));
0733 m_coralDeleter->processNextIteration();
0734 }
0735
0736 void flush() {
0737 if (m_coralDeleter.get())
0738 m_coralDeleter->flush();
0739 }
0740
0741 private:
0742
0743 coral::ISchema& m_schema;
0744 std::string m_tableName;
0745
0746 ConditionBuffer<Types...> m_buffer;
0747 std::unique_ptr<coral::IBulkOperation> m_coralDeleter;
0748 };
0749
0750 namespace {
0751
0752 inline bool existsTable(coral::ISchema& schema, const char* tableName) {
0753 return schema.existsTable(std::string(tableName));
0754 }
0755
0756 inline void createTable(coral::ISchema& schema, const coral::TableDescription& descr) {
0757 schema.createTable(descr);
0758 }
0759
0760 inline bool insertInTable(coral::ISchema& schema,
0761 const char* tableName,
0762 const coral::AttributeList& row,
0763 bool failOnDuplicate = true) {
0764 bool ret = false;
0765 try {
0766 schema.tableHandle(std::string(tableName)).dataEditor().insertRow(row);
0767 ret = true;
0768 } catch (const coral::DuplicateEntryInUniqueKeyException&) {
0769 if (failOnDuplicate)
0770 throw;
0771 }
0772 return ret;
0773 }
0774
0775 inline void updateTable(coral::ISchema& schema, const char* tableName, const UpdateBuffer& data) {
0776 schema.tableHandle(std::string(tableName))
0777 .dataEditor()
0778 .updateRows(data.setClause(), data.whereClause(), data.get());
0779 }
0780
0781 inline void deleteFromTable(coral::ISchema& schema, const char* tableName, const DeleteBuffer& data) {
0782 schema.tableHandle(std::string(tableName)).dataEditor().deleteRows(data.whereClause(), data.get());
0783 }
0784 }
0785
0786 }
0787
0788 }
0789
0790 #endif