File indexing completed on 2024-04-06 12:01:27
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 {
0408 public:
0409
0410 using iterator_category = std::input_iterator_tag;
0411 using value_type = std::tuple<Types...>;
0412 using difference_type = void;
0413 using pointer = void;
0414 using reference = void;
0415
0416 QueryIterator() {}
0417
0418 QueryIterator(const QueryIterator& rhs) : m_query(rhs.m_query), m_currentRow(rhs.m_currentRow) {}
0419
0420 explicit QueryIterator(Query<Types...>* parent) : m_query(parent) {}
0421
0422 QueryIterator& operator=(const QueryIterator& rhs) {
0423 m_query = rhs.m_query;
0424 m_currentRow = rhs.m_currentRow;
0425 return *this;
0426 }
0427
0428 template <typename T>
0429 typename T::type get() const {
0430 return GetFromRow<typename T::type>()(*m_currentRow, T::fullyQualifiedName());
0431 }
0432
0433 auto operator*() -> decltype(std::make_tuple(this->get<Types>()...)) { return std::make_tuple(get<Types>()...); }
0434
0435 QueryIterator& operator++() {
0436 m_currentRow = m_query->next() ? &m_query->currentRow() : nullptr;
0437 return *this;
0438 }
0439
0440 QueryIterator operator++(int) {
0441 QueryIterator tmp(*this);
0442 operator++();
0443 return tmp;
0444 }
0445
0446 bool operator==(const QueryIterator& rhs) const {
0447 if (rhs.m_query == nullptr && m_query == nullptr)
0448 return true;
0449 return m_query == rhs.m_query && m_currentRow == rhs.m_currentRow;
0450 }
0451 bool operator!=(const QueryIterator& rhs) const { return !operator==(rhs); }
0452
0453 operator bool() const { return m_currentRow; }
0454
0455 private:
0456 Query<Types...>* m_query = nullptr;
0457 const coral::AttributeList* m_currentRow = nullptr;
0458 };
0459
0460 template <typename T>
0461 struct DefineQueryOutput {
0462 static void make(coral::IQuery& query, const std::string& fullyQualifiedName) {
0463 query.addToOutputList(fullyQualifiedName);
0464 query.defineOutputType(fullyQualifiedName, coral::AttributeSpecification::typeNameForType<T>());
0465 }
0466 };
0467 template <>
0468 struct DefineQueryOutput<cond::Binary> {
0469 static void make(coral::IQuery& query, const std::string& fullyQualifiedName) {
0470 query.addToOutputList(fullyQualifiedName);
0471 query.defineOutputType(fullyQualifiedName, coral::AttributeSpecification::typeNameForType<coral::Blob>());
0472 }
0473 };
0474 template <>
0475 struct DefineQueryOutput<boost::posix_time::ptime> {
0476 static void make(coral::IQuery& query, const std::string& fullyQualifiedName) {
0477 query.addToOutputList(fullyQualifiedName);
0478 query.defineOutputType(fullyQualifiedName, coral::AttributeSpecification::typeNameForType<coral::TimeStamp>());
0479 }
0480 };
0481 template <>
0482 struct DefineQueryOutput<cond::TimeType> {
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 <>
0489 struct DefineQueryOutput<cond::SynchronizationType> {
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 template <std::size_t n>
0496 struct DefineQueryOutput<std::array<char, n> > {
0497 static void make(coral::IQuery& query, const std::string& fullyQualifiedName) {
0498 query.addToOutputList(fullyQualifiedName);
0499 query.defineOutputType(fullyQualifiedName, coral::AttributeSpecification::typeNameForType<std::string>());
0500 }
0501 };
0502
0503 template <typename... Types>
0504 class Query {
0505 public:
0506 Query(const coral::ISchema& schema, bool distinct = false)
0507 : m_coralQuery(schema.newQuery()), m_whereData(), m_whereClause(""), m_tables() {
0508 _Query<0, Types...>();
0509 if (distinct)
0510 m_coralQuery->setDistinct();
0511 }
0512
0513 ~Query() {}
0514
0515 template <typename Col>
0516 Query& addTable() {
0517 if (m_tables.find(Col::tableName()) == m_tables.end()) {
0518 m_coralQuery->addToTableList(Col::tableName());
0519 m_tables.insert(Col::tableName());
0520 }
0521 return *this;
0522 }
0523
0524 template <int n>
0525 void _Query() {}
0526
0527 template <int n, typename Arg1, typename... Args>
0528 void _Query() {
0529 addTable<Arg1>();
0530 DefineQueryOutput<typename Arg1::type>::make(*m_coralQuery, Arg1::fullyQualifiedName());
0531 _Query<n + 1, Args...>();
0532 }
0533
0534 template <typename C, typename T>
0535 Query& addCondition(const T& value, const std::string condition = "=") {
0536 addTable<C>();
0537 f_add_condition_data<C>(m_whereData, m_whereClause, value, condition);
0538 return *this;
0539 }
0540
0541 template <typename C1, typename C2>
0542 Query& addCondition(const std::string condition = "=") {
0543 addTable<C1>();
0544 addTable<C2>();
0545 f_add_condition<C1, C2>(m_whereClause, condition);
0546 return *this;
0547 }
0548
0549 template <typename C>
0550 Query& addOrderClause(bool ascending = true) {
0551 std::string orderClause(C::fullyQualifiedName());
0552 if (!ascending)
0553 orderClause += " DESC";
0554 m_coralQuery->addToOrderList(orderClause);
0555 return *this;
0556 }
0557
0558 Query& groupBy(const std::string& expression) {
0559 m_coralQuery->groupBy(expression);
0560 return *this;
0561 }
0562
0563 Query& setForUpdate() {
0564 m_coralQuery->setForUpdate();
0565 return *this;
0566 }
0567
0568 Query& limitReturnedRows(size_t nrows) {
0569 m_coralQuery->limitReturnedRows(nrows);
0570 return *this;
0571 }
0572
0573 bool next() {
0574 if (!m_cursor)
0575 throwException("The query has not been executed.", "Query::currentRow");
0576 bool ret = m_cursor->next();
0577 if (ret)
0578 m_retrievedRows++;
0579 return ret;
0580 }
0581
0582 const coral::AttributeList& currentRow() const {
0583 if (!m_cursor)
0584 throwException("The query has not been executed.", "Query::currentRow");
0585 return m_cursor->currentRow();
0586 }
0587
0588 const QueryIterator<Types...> begin() {
0589 m_coralQuery->setCondition(m_whereClause, m_whereData);
0590 m_cursor = &m_coralQuery->execute();
0591 m_retrievedRows = 0;
0592 QueryIterator<Types...> ret(this);
0593 return ++ret;
0594 }
0595
0596 const QueryIterator<Types...> end() { return QueryIterator<Types...>(this); }
0597
0598 size_t retrievedRows() const { return m_retrievedRows; }
0599
0600 private:
0601 std::unique_ptr<coral::IQuery> m_coralQuery;
0602 coral::ICursor* m_cursor = nullptr;
0603 size_t m_retrievedRows = 0;
0604 coral::AttributeList m_whereData;
0605 std::string m_whereClause;
0606 std::set<std::string> m_tables;
0607 };
0608
0609 class UpdateBuffer {
0610 private:
0611 template <typename Params, int n, typename C1, typename... Cs>
0612 void _set(const Params& params) {
0613 f_add_column_data<C1>(m_data, std::get<n>(params));
0614 if (!m_setClause.empty())
0615 m_setClause += ", ";
0616 m_setClause += std::string(C1::name) + " = :" + std::string(C1::name);
0617 _set<Params, n + 1, Cs...>(params);
0618 }
0619
0620 template <typename Params, int n>
0621 void _set(const Params&) {}
0622
0623 public:
0624 UpdateBuffer() : m_data(), m_setClause(""), m_whereClause("") {}
0625
0626 template <typename... Columns, typename Params>
0627 void setColumnData(const Params& params) {
0628 _set<Params, 0, Columns...>(params);
0629 }
0630
0631 template <typename Column1, typename Column2>
0632 void setColumnMatch() {
0633 if (!m_setClause.empty())
0634 m_setClause += ", ";
0635 m_setClause += std::string(Column1::name) + " = " + std::string(Column2::name);
0636 }
0637
0638 template <typename Column, typename P>
0639 void addWhereCondition(const P& param, const std::string condition = "=") {
0640 f_add_condition_data<Column>(m_data, m_whereClause, param, condition);
0641 }
0642
0643 template <typename Column1, typename Column2>
0644 void addWhereCondition(const std::string condition = "=") {
0645 f_add_condition<Column1, Column2>(m_whereClause, condition);
0646 }
0647
0648 const coral::AttributeList& get() const { return m_data; }
0649
0650 const std::string& setClause() const { return m_setClause; }
0651
0652 const std::string& whereClause() const { return m_whereClause; }
0653
0654 private:
0655 coral::AttributeList m_data;
0656 std::string m_setClause;
0657 std::string m_whereClause;
0658 };
0659
0660 class DeleteBuffer {
0661 public:
0662 DeleteBuffer() : m_data(), m_whereClause("") {}
0663
0664 template <typename Column, typename P>
0665 void addWhereCondition(const P& param, const std::string condition = "=") {
0666 f_add_condition_data<Column>(m_data, m_whereClause, param, condition);
0667 }
0668
0669 template <typename Column1, typename Column2>
0670 void addWhereCondition(const std::string condition = "=") {
0671 f_add_condition<Column1, Column2>(m_whereClause, condition);
0672 }
0673
0674 const coral::AttributeList& get() const { return m_data; }
0675
0676 const std::string& whereClause() const { return m_whereClause; }
0677
0678 private:
0679 coral::AttributeList m_data;
0680 std::string m_whereClause;
0681 };
0682
0683 template <typename... Types>
0684 class BulkInserter {
0685 public:
0686 static constexpr size_t cacheSize = 1000;
0687 BulkInserter(coral::ISchema& schema, const char* tableName)
0688 : m_schema(schema), m_tableName(tableName), m_buffer(), m_coralInserter() {
0689
0690
0691 }
0692
0693 template <typename P>
0694 void insert(const P& params) {
0695 m_buffer.set(params);
0696 if (!m_coralInserter.get())
0697 m_coralInserter.reset(m_schema.tableHandle(m_tableName).dataEditor().bulkInsert(m_buffer.get(), cacheSize));
0698 m_coralInserter->processNextIteration();
0699 }
0700
0701 void flush() {
0702 if (m_coralInserter.get())
0703 m_coralInserter->flush();
0704 }
0705
0706 private:
0707
0708 coral::ISchema& m_schema;
0709 std::string m_tableName;
0710
0711 RowBuffer<Types...> m_buffer;
0712 std::unique_ptr<coral::IBulkOperation> m_coralInserter;
0713 };
0714
0715 template <typename... Types>
0716 class BulkDeleter {
0717 public:
0718 static constexpr size_t cacheSize = 1000;
0719 explicit BulkDeleter(coral::ISchema& schema, const char* tableName)
0720 : m_schema(schema), m_tableName(tableName), m_buffer(), m_coralDeleter() {
0721
0722
0723 }
0724
0725 void addStaticCondition(const std::string& condition) { m_buffer.addStaticCondition(condition); }
0726
0727 template <typename P>
0728 void erase(const P& params) {
0729 m_buffer.set(params);
0730 if (!m_coralDeleter.get())
0731 m_coralDeleter.reset(m_schema.tableHandle(m_tableName)
0732 .dataEditor()
0733 .bulkDeleteRows(m_buffer.getClause(), m_buffer.get(), cacheSize));
0734 m_coralDeleter->processNextIteration();
0735 }
0736
0737 void flush() {
0738 if (m_coralDeleter.get())
0739 m_coralDeleter->flush();
0740 }
0741
0742 private:
0743
0744 coral::ISchema& m_schema;
0745 std::string m_tableName;
0746
0747 ConditionBuffer<Types...> m_buffer;
0748 std::unique_ptr<coral::IBulkOperation> m_coralDeleter;
0749 };
0750
0751 namespace {
0752
0753 inline bool existsTable(coral::ISchema& schema, const char* tableName) {
0754 return schema.existsTable(std::string(tableName));
0755 }
0756
0757 inline void createTable(coral::ISchema& schema, const coral::TableDescription& descr) {
0758 schema.createTable(descr);
0759 }
0760
0761 inline bool insertInTable(coral::ISchema& schema,
0762 const char* tableName,
0763 const coral::AttributeList& row,
0764 bool failOnDuplicate = true) {
0765 bool ret = false;
0766 try {
0767 schema.tableHandle(std::string(tableName)).dataEditor().insertRow(row);
0768 ret = true;
0769 } catch (const coral::DuplicateEntryInUniqueKeyException&) {
0770 if (failOnDuplicate)
0771 throw;
0772 }
0773 return ret;
0774 }
0775
0776 inline void updateTable(coral::ISchema& schema, const char* tableName, const UpdateBuffer& data) {
0777 schema.tableHandle(std::string(tableName))
0778 .dataEditor()
0779 .updateRows(data.setClause(), data.whereClause(), data.get());
0780 }
0781
0782 inline void deleteFromTable(coral::ISchema& schema, const char* tableName, const DeleteBuffer& data) {
0783 schema.tableHandle(std::string(tableName)).dataEditor().deleteRows(data.whereClause(), data.get());
0784 }
0785 }
0786
0787 }
0788
0789 }
0790
0791 #endif