1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
#ifndef CondTools_L1Trigger_WriterProxy_h
#define CondTools_L1Trigger_WriterProxy_h
#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/Framework/interface/ESHandle.h"
#include "FWCore/Framework/interface/ConsumesCollector.h"
#include "FWCore/PluginManager/interface/PluginFactory.h"
#include "FWCore/ServiceRegistry/interface/Service.h"
#include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
#include "CondTools/L1Trigger/interface/Exception.h"
#include <string>
namespace l1t {
/* This is class that is used to save data to DB. Saving requires that we should know types at compile time.
* This means that I cannot create simple class that saves all records. So, I create a base class, and template
* version of it, that will procede with saving. This approach is the same as used in DataProxy.
*/
class WriterProxy {
public:
virtual ~WriterProxy() {}
/* Saves record and type from given event setup to pool DB. This method should not worry
* about such things as IOV and so on. It should return new payload token and then
* the framework would take care of it.
*
* This method should not care of pool transactions and connections management.
* In case some need other methods, like delete and update, one should add more abstract
* methods here.
*/
virtual void setToken(edm::ConsumesCollector cc) = 0;
virtual std::string save(const edm::EventSetup& setup) const = 0;
protected:
};
/* Concrete implementation of WriteProxy. This will do all the saving, also user of new types that should be saved
* should instaciate a new version of this class and register it in plugin system.
*/
template <class Record, class Type>
class WriterProxyT : public WriterProxy {
private:
edm::ESGetToken<Type, Record> rcdToken;
public:
~WriterProxyT() override {}
void setToken(edm::ConsumesCollector cc) override { rcdToken = cc.esConsumes(); }
/* This method requires that Record and Type supports copy constructor */
std::string save(const edm::EventSetup& setup) const override {
// load record and type from EventSetup and save them in db
edm::ESHandle<Type> handle;
try {
handle = setup.getHandle(rcdToken);
} catch (l1t::DataAlreadyPresentException& ex) {
return std::string();
}
// If handle is invalid, then data is already in DB
edm::Service<cond::service::PoolDBOutputService> poolDb;
if (!poolDb.isAvailable()) {
throw cond::Exception("DataWriter: PoolDBOutputService not available.");
}
poolDb->forceInit();
cond::persistency::Session session = poolDb->session();
if (not session.transaction().isActive())
session.transaction().start(false); // true: read only, false: read-write
std::shared_ptr<Type> pointer = std::make_shared<Type>(*(handle.product()));
std::string payloadToken = session.storePayload(*pointer);
session.transaction().commit();
return payloadToken;
}
};
typedef edmplugin::PluginFactory<l1t::WriterProxy*()> WriterFactory;
// Defines new type, creates static instance of this class and register it for plugin
#define REGISTER_L1_WRITER(record, type) \
template class l1t::WriterProxyT<record, type>; \
typedef l1t::WriterProxyT<record, type> record##_##type##_Writer; \
DEFINE_EDM_PLUGIN(l1t::WriterFactory, record##_##type##_Writer, #record "@" #type "@Writer")
} // namespace l1t
#endif
|