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