MT Showcase SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
DatabaseGenerator.hpp
1 #pragma once
2 
3 #include <ChangeListener.hpp>
4 #include <Configuration.hpp>
5 #include <databases/DatabaseManager.hpp>
6 #include <databases/DatabaseUtils.hpp>
7 #include <Showcase.hpp>
8 #include <Utils.hpp>
9 #include <Export.hpp>
10 
11 #include <boost/expected/expected.hpp>
12 
13 namespace Showcase
14 {
15  template <typename GeneratorType>
16  class SHOWCASE_API DatabaseGenerator : public GeneratorType
17  {
18  public:
19  DatabaseGenerator();
20  virtual ~DatabaseGenerator();
21 
22  virtual QString protocol() const override;
23  virtual bool init(const GraphNode & node) override;
24  virtual bool isValidId(const NodeId & id) = 0;
25  ChangeListenerPtr changeListener();
26 
27  void doKeyValueQuery(const QString & command, PropertyMap & props,
28  const QStringList & columns);
29  boost::expected<QString> getTheme() const;
30 
31  QString connectionName();
32 
33  NodeId targetNode() const;
34  NodeId listenerId() const;
35 
36  private:
37  QString m_connectionName;
38  ChangeListener::Key m_key;
39  NodeId m_node;
40  };
41 
43 
44  template <typename GeneratorType>
45  DatabaseGenerator<GeneratorType>::DatabaseGenerator()
46  {
47  }
48 
49  template <typename GeneratorType>
50  DatabaseGenerator<GeneratorType>::~DatabaseGenerator()
51  {
52  auto listener = changeListener();
53  if(listener)
54  listener->unsubscribeToChanges(m_key);
55  }
56 
57  template <typename GeneratorType>
58  QString DatabaseGenerator<GeneratorType>::protocol() const
59  {
60  QString proto = Utils::protocol(targetNode());
62  return proto;
63  return "";
64  }
65 
66  template <typename GeneratorType>
67  bool DatabaseGenerator<GeneratorType>::init(const GraphNode & node)
68  {
69  if(!GeneratorType::init(node))
70  return false;
71  if (!isValidId(node.id))
72  return false;
73 
74  m_node = node.id;
75 
76  m_connectionName = DB::getServer(node.id);
77 
78  ChangeListener::NotifiableWeakPtr me =
79  std::dynamic_pointer_cast<Notifiable>(this->shared_from_this());
80 
81  auto listener = changeListener();
82  if(listener)
83  m_key = listener->subscribeToChanges(DB::getBaseNodeId(node.id), me);
84 
85  return true;
86  }
87 
88  template <typename GeneratorType>
89  ChangeListenerPtr DatabaseGenerator<GeneratorType>::changeListener()
90  {
91  if(auto s = Showcase::weakInstance().lock()) {
92  auto remoteControl = s->remoteControl();
93  return remoteControl->changeListener();
94  }
95 
96  return nullptr;
97  }
98 
99  template <typename GeneratorType>
100  void DatabaseGenerator<GeneratorType>::doKeyValueQuery(const QString & command, PropertyMap & props,
101  const QStringList & columns)
102  {
103  auto databaseConnection = DatabaseManager::connection(m_connectionName);
104  QSqlQuery query(databaseConnection);
105  query.prepare(command);
106  QList<QVariantMap> q = DB::query(query, columns);
107 
108  for (const auto & r : q) {
109  QByteArray key = r.value(columns.at(0)).toByteArray();
110  QVariant value = r.value(columns.at(1));
111  props[key] = value;
112  }
113  }
114 
115  template <typename GeneratorType>
116  boost::expected<QString> DatabaseGenerator<GeneratorType>::getTheme() const
117  {
118  RunConfigurationPtr config = Showcase::instance()->runConfiguration();
119  if (config) {
120  auto theme = config->theme.id;
121  if (!theme.isEmpty())
122  return QString(theme);
123  }
124  return boost::make_unexpected("No valid theme");
125  }
126 
127  template <typename GeneratorType>
128  QString DatabaseGenerator<GeneratorType>::connectionName()
129  {
130  return m_connectionName;
131  }
132 
133  template <typename GeneratorType>
134  NodeId DatabaseGenerator<GeneratorType>::targetNode() const
135  {
136  return m_node;
137  }
138 
139  template<typename GeneratorType>
140  NodeId DatabaseGenerator<GeneratorType>::listenerId() const
141  {
142  return m_key.first;
143  }
144 }