RDB 2
transactions.hpp
Go to the documentation of this file.
1 /*
2  *******************************************************************************
3  *
4  * Copyright 2021 RIEGL Laser Measurement Systems
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  *
20  *******************************************************************************
21  */
22 /*!
23  *******************************************************************************
24  *
25  * \file transactions.hpp
26  * \author RIEGL LMS GmbH, Austria
27  * \brief Manage point cloud transactions
28  * \version 2015-10-14/AW: Initial version
29  * \version 2017-11-24/AW: Constructors declared as "explicit" (#2825)
30  *
31  *******************************************************************************
32  */
33 
34 #ifndef RIEGL_RDB_POINTCLOUD_TRANSACTIONS_HPP
35 #define RIEGL_RDB_POINTCLOUD_TRANSACTIONS_HPP
36 
37 //---< INCLUDES >---------------------------------------------------------------
38 
39 #include <memory>
40 #include <string>
41 #include <vector>
42 #include <utility>
45 #include "riegl/rdb/progress.hpp"
46 
47 //---< NAMESPACE >--------------------------------------------------------------
48 
49 namespace riegl {
50 namespace rdb {
51 namespace pointcloud {
52 
53 //---< CLASS Transactions >-----------------------------------------------------
54 /*!
55  * \brief Manage point cloud transactions
56  *
57  * Modifying the point cloud database means to execute a transaction.
58  *
59  * This class allows to start new transactions (see begin()) and to
60  * browse past (already executed) transactions.
61  *
62  * \see riegl::rdb::Pointcloud::transaction()
63  */
65 {
66 public:
67  /*!
68  * \brief Constructor
69  * \note You cannot create new Transactions objects directly,
70  * use riegl::rdb::Pointcloud::transaction() instead.
71  */
72  explicit Transactions(riegl::rdb::PointcloudData* pointcloud);
73 
74  /*!
75  * \brief Create new transaction
76  *
77  * Whenever you are going to modify the point cloud, you must create a
78  * transaction by using this function. Without a transaction, any function
79  * that modifies the point cloud will fail (i.e. it throws an exception).
80  *
81  * A transaction automatically locks the database so that other users
82  * can query data but can __NOT__ add or modify data. Please note that
83  * only __one transaction at a time__ is allowed. If there is already
84  * a transaction pending, this function will raise an exception (see
85  * Error::TransactionPending).
86  *
87  * To finish a transaction either call commit() or rollback().
88  *
89  * \note Parameters 'title' and 'agent' are required - i.e. creating
90  * a new transaction will fail if empty strings are provided.
91  * All other parameters are optional.
92  *
93  * \note Parameters 'comments' and 'settings' serve the user and client
94  * application for information, e.g. to repeat processing steps
95  * later on. They have no influence on the transaction itself. The
96  * client application is free to store information in any format
97  * that is string-compatible (e.g. plain text, INI, XML, JSON).
98  *
99  * \note The total size of the 'title', 'agent', 'comments' and 'settings'
100  * strings must not exceed 500 MB (bytes, not characters).
101  */
103  const std::string &title, //!< [in] short description, e.g. "Import"
104  const std::string &agent, //!< [in] software name, e.g. "rdbimport v1.0"
105  const std::string &comments = "", //!< [in] e.g. process details for humans
106  const std::string &settings = "" //!< [in] e.g. process settings for software
107  );
108 
109  /*!
110  * \brief Commit current transaction
111  *
112  * This function commits the current transaction. All changes made by the
113  * transaction become visible to others.
114  */
115  void commit(
116  Progress progress = nullptr, //!< [in] commit progress callback function
117  void *userdata = nullptr, //!< [in] progress callback function user data
118  const uint32_t signature = 0, //!< [in] signature method (0: none, 1: default)
119  const uint32_t key_size = 0, //!< [in] signature encryption key size (at least 32 byte)
120  const void* const key_data = nullptr //!< [in] signature encryption key buffer
121  );
122 
123  /*!
124  * \brief Commit current transaction
125  *
126  * Overloaded commit() that takes any callable type as progress callback.
127  */
128  template<typename Callable>
129  void commit(
130  Callable &&progress, //!< [in] progress callback function
131  const uint32_t signature = 0, //!< [in] signature method (0: none, 1: default)
132  const uint32_t key_size = 0, //!< [in] signature encryption key size (at least 32 byte)
133  const void* const key_data = nullptr //!< [in] signature encryption key buffer
134  )
135  {
136  typedef typename std::decay<Callable>::type CallableType;
137  this->commit(
138  &progress_proxy_callable<CallableType>,
139  const_cast<CallableType*>(&progress),
140  signature, key_size, key_data
141  );
142  }
143 
144  /*!
145  * \brief Commit current transaction
146  *
147  * Overloaded commit() that takes a progress callback method of an object.
148  */
149  template<typename Receiver>
150  void commit(
151  void (Receiver::*progress)(uint8_t), Receiver &receiver,
152  const uint32_t signature = 0, //!< [in] signature method (0: none, 1: default)
153  const uint32_t key_size = 0, //!< [in] signature encryption key size (at least 32 byte)
154  const void* const key_data = nullptr //!< [in] signature encryption key buffer
155  )
156  {
157  auto userdata = std::make_pair(progress, &receiver);
158  this->commit(
159  &progress_proxy_receiver<Receiver>, &userdata,
160  signature, key_size, key_data
161  );
162  }
163 
164  /*!
165  * \brief Commit current transaction
166  *
167  * Overloaded commit() that takes a constant progress callback method
168  * of a constant object.
169  */
170  template<typename Receiver>
171  void commit(
172  void (Receiver::*progress)(uint8_t) const, const Receiver &receiver,
173  const uint32_t signature = 0, //!< [in] signature method (0: none, 1: default)
174  const uint32_t key_size = 0, //!< [in] signature encryption key size (at least 32 byte)
175  const void* const key_data = nullptr //!< [in] signature encryption key buffer
176  )
177  {
178  auto userdata = std::make_pair(progress, &receiver);
179  this->commit(
180  &progress_proxy_receiver<Receiver>, &userdata,
181  signature, key_size, key_data
182  );
183  }
184 
185  /*!
186  * \brief Abort current transaction
187  *
188  * This function rolls back the current transaction and causes all changes
189  * made by the transaction to be discarded.
190  */
191  void rollback();
192 
193  /*!
194  * \brief Get list of transactions
195  *
196  * The database keeps a log (journal) of all transactions. This function
197  * returns a list of identifiers (IDs) for all recorded transactions.
198  */
199  std::vector<Transaction::ID> list() const;
200 
201  /*!
202  * \brief ID of current transaction
203  *
204  * This function returns the ID of the current transaction. Usually this
205  * is the transaction that was committed at last. However, if restore() is
206  * used to return to a previous database state, the current transaction is
207  * the restored transaction.
208  *
209  * \note This function does not return the ID of a pending transaction.
210  */
211  Transaction::ID current() const;
212 
213  /*!
214  * \brief Check if transaction is pending
215  *
216  * This function checks whether there is a pending transaction that was
217  * started by __this__ database instance. This function does __not__ check
218  * whether a transaction was started by a different database instance of
219  * the current or different thread or process.
220  */
221  bool pending() const;
222 
223  /*!
224  * \brief Query transaction details
225  */
227  const Transaction::ID transaction //!< [in] transaction identifier
228  ) const;
229 
230  /*!
231  * \brief Restore database state
232  *
233  * This function restores the database state that was current at the end
234  * of the transaction. Those transactions that were created after the
235  * restored transaction remain valid until a new transaction is created.
236  * This offers some simple undo/redo functionality.
237  */
238  void restore(
239  const Transaction::ID transaction //!< [in] transaction identifier
240  );
241 
242 private:
243  riegl::rdb::PointcloudData *data;
244 
245  template<typename Callable>
246  static void progress_proxy_callable(uint8_t progress, void *userdata)
247  {
248  try
249  {
250  Callable &callback = *reinterpret_cast<Callable*>(userdata);
251  callback(progress); // = invoke original callback
252  }
253  catch(...)
254  {
255  // ignore all errors
256  }
257  }
258 
259  template<typename Receiver>
260  static void progress_proxy_receiver(uint8_t progress, void *userdata)
261  {
262  try
263  {
264  typedef void (Receiver::*Function)(uint8_t); // just a shortcut...
265  auto data(reinterpret_cast<std::pair<Function, Receiver*>*>(userdata));
266  (*data->second.*data->first)(progress); // = invoke original callback
267  }
268  catch(...)
269  {
270  // ignore all errors
271  }
272  }
273 };
274 
275 }}} // namespace riegl::rdb::pointcloud
276 
277 #endif // RIEGL_RDB_POINTCLOUD_TRANSACTIONS_HPP
riegl::rdb::pointcloud::Transactions::commit
void commit(Progress progress=nullptr, void *userdata=nullptr, const uint32_t signature=0, const uint32_t key_size=0, const void *const key_data=nullptr)
Commit current transaction.
progress.hpp
Operation progress feedback tools.
riegl::rdb::pointcloud::Transactions::Transactions
Transactions(riegl::rdb::PointcloudData *pointcloud)
Constructor.
riegl
RIEGL Laser Measurement Systems GmbH, Austria.
Definition: context.hpp:48
riegl::rdb::pointcloud::Transaction::ID
uint32_t ID
Definition: transaction.hpp:58
riegl::rdb::pointcloud::Transactions::current
Transaction::ID current() const
ID of current transaction.
riegl::rdb::pointcloud::Transaction
Point cloud transaction.
Definition: transaction.hpp:55
riegl::rdb::pointcloud::Transactions::pending
bool pending() const
Check if transaction is pending.
riegl::rdb::pointcloud::Transactions::restore
void restore(const Transaction::ID transaction)
Restore database state.
riegl::rdb::pointcloud::Transactions
Manage point cloud transactions.
Definition: transactions.hpp:64
transaction.hpp
Point cloud transaction.
riegl::rdb::pointcloud::Transactions::begin
Transaction::ID begin(const std::string &title, const std::string &agent, const std::string &comments="", const std::string &settings="")
Create new transaction.
riegl::rdb::pointcloud::Transactions::list
std::vector< Transaction::ID > list() const
Get list of transactions.
riegl::rdb::Progress
void(* Progress)(uint8_t progress, void *userdata)
Progress callback function type.
Definition: progress.hpp:66
riegl::rdb::pointcloud::Transactions::commit
void commit(void(Receiver::*progress)(uint8_t) const, const Receiver &receiver, const uint32_t signature=0, const uint32_t key_size=0, const void *const key_data=nullptr)
Commit current transaction.
Definition: transactions.hpp:171
riegl::rdb::pointcloud::Transactions::commit
void commit(Callable &&progress, const uint32_t signature=0, const uint32_t key_size=0, const void *const key_data=nullptr)
Commit current transaction.
Definition: transactions.hpp:129
pointcloudData.hpp
Pointcloud class implementation details.
riegl::rdb::pointcloud::Transactions::rollback
void rollback()
Abort current transaction.
riegl::rdb::pointcloud::Transactions::commit
void commit(void(Receiver::*progress)(uint8_t), Receiver &receiver, const uint32_t signature=0, const uint32_t key_size=0, const void *const key_data=nullptr)
Commit current transaction.
Definition: transactions.hpp:150
riegl::rdb::pointcloud::Transactions::details
Transaction details(const Transaction::ID transaction) const
Query transaction details.