b2api
B2000++ API Reference Manual, VERSION 4.6
 
Loading...
Searching...
No Matches
b2database.H
1//------------------------------------------------------------------------
2// b2database.H --
3//
4//
5// written by Mathias Doreille
6//
7// Copyright (c) 2004-2015,2016,2017
8// SMR Engineering & Development SA
9// 2502 Bienne, Switzerland
10//
11// All Rights Reserved. Proprietary source code. The contents of
12// this file may not be disclosed to third parties, copied or
13// duplicated in any form, in whole or in part, without the prior
14// written permission of SMR.
15//------------------------------------------------------------------------
16
17#ifndef __B2DATABASE_H__
18#define __B2DATABASE_H__
19
20#include <fnmatch.h>
21#include <memcom.h>
22
23#include <complex>
24#include <map>
25#include <sstream>
26#include <string>
27#include <vector>
28
29#include "b2ppconfig.h"
30#include "utils/b2linear_algebra.H"
31#include "utils/b2logging.H"
32#include "utils/b2object.H"
33#include "utils/b2rtable.H"
34#include "utils/b2time.H"
35
36extern "C" int _mcDBopenFile(
37 int handle, const char* filename, const char* ftype, mcSize npage, mcSize lpage);
38
39inline std::string mcErrGetMsgAndReset(int code) {
40 const char* err_msg = mcErrGetMsg(code);
41 std::string res = err_msg ? err_msg : "Invalid MemCom error code";
42 mcErrReset();
43 return res;
44}
45
46namespace b2000 {
47
49class SetName : public std::string {
50public:
51 SetName() {}
52
53 SetName(const SetName& name) : std::string(name) {}
54
55 operator const char*() const { return c_str(); }
56 template <typename T1>
57 SetName(const T1& a1) {
58 std::ostringstream o;
59 o << a1;
60 std::string::operator=(o.str());
61 }
62 template <typename T1, typename T2>
63 SetName(const T1& a1, const T2& a2) {
64 std::ostringstream o;
65 o << a1 << "." << a2;
66 std::string::operator=(o.str());
67 }
68 template <typename T1, typename T2, typename T3>
69 SetName(const T1& a1, const T2& a2, const T3& a3) {
70 std::ostringstream o;
71 o << a1 << "." << a2 << "." << a3;
72 std::string::operator=(o.str());
73 }
74 template <typename T1, typename T2, typename T3, typename T4>
75 SetName(const T1& a1, const T2& a2, const T3& a3, const T4& a4) {
76 std::ostringstream o;
77 o << a1 << "." << a2 << "." << a3 << "." << a4;
78 std::string::operator=(o.str());
79 }
80 template <typename T1, typename T2, typename T3, typename T4, typename T5>
81 SetName(const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5) {
82 std::ostringstream o;
83 o << a1 << "." << a2 << "." << a3 << "." << a4 << "." << a5;
84 std::string::operator=(o.str());
85 }
86
87 SetName& gname(const std::string& gname_) {
88 replace_field(0, gname_);
89 return *this;
90 }
91
92 template <typename T>
93 SetName& gname(const T& gname_) {
94 std::ostringstream o;
95 o << gname_;
96 return gname(o.str());
97 }
98
99 std::string get_gname() const { return substr_field(0); }
100
101 bool gname_undef() const { return is_undef(0); }
102
103 SetName& branch(const std::string& branch_) {
104 replace_field(1, branch_);
105 return *this;
106 }
107
108 template <typename T>
109 SetName& branch(const T& branch_) {
110 std::ostringstream o;
111 o << branch_;
112 return branch(o.str());
113 }
114
115 std::string get_branch() const { return substr_field(1); }
116
117 bool branch_undef() const { return is_undef(1); }
118
119 SetName& cycle(const std::string& cycle_) {
120 replace_field(2, cycle_);
121 return *this;
122 }
123
124 template <typename T>
125 SetName& cycle(const T& cycle_) {
126 std::ostringstream o;
127 o << cycle_;
128 return cycle(o.str());
129 }
130
131 std::string get_cycle() const { return substr_field(2); }
132
133 bool cycle_undef() const { return is_undef(2); }
134
135 SetName& subcycle(const std::string& subcycle_) {
136 replace_field(3, subcycle_);
137 return *this;
138 }
139
140 template <typename T>
141 SetName& subcycle(const T& subcycle_) {
142 std::ostringstream o;
143 o << subcycle_;
144 return subcycle(o.str());
145 }
146
147 std::string get_subcycle() const { return substr_field(3); }
148
149 bool subcycle_undef() const { return is_undef(3); }
150
151 SetName& case_(const std::string& case__) {
152 replace_field(4, case__);
153 return *this;
154 }
155
156 template <typename T>
157 SetName& case_(const T& case__) {
158 std::ostringstream o;
159 o << case__;
160 return case_(o.str());
161 }
162
163 std::string get_case() const { return substr_field(4); }
164
165 bool case_undef() const { return is_undef(4); }
166
167 SetName& subcase(const std::string& subcase_) {
168 replace_field(5, subcase_);
169 return *this;
170 }
171
172 template <typename T>
173 SetName& subcase(const T& subcase_) {
174 std::ostringstream o;
175 o << subcase_;
176 return subcase(o.str());
177 }
178
179 std::string get_subcase() const { return substr_field(5); }
180
181 bool subcase_undef() const { return is_undef(5); }
182
183 bool match(const std::string& pattern) const {
184 return (fnmatch(pattern.c_str(), c_str(), 0) == 0);
185 }
186
187private:
188 void replace_field(int pos, const std::string& s) {
189 const int pos_save = pos;
190 int begin_ = 0;
191 while (pos--) {
192 if ((begin_ = std::string::find(".", begin_)) == -1) {
193 if (pos) {
194 *this += ".0";
195 begin_ = std::string::size() - 1;
196 } else {
197 *this += ".";
198 begin_ = std::string::size();
199 }
200 } else {
201 ++begin_;
202 }
203 }
204 int end_ = std::string::find(".", begin_);
205 std::string::replace(begin_, (end_ == -1 ? std::string::size() : end_) - begin_, s);
206
207 // Special rule for subcase/mode.
208 if (pos_save == 5 && s == "0") { resize(begin_ - 1); }
209 }
210
211 std::string substr_field(int pos) const {
212 int begin_ = 0;
213 while (pos--) {
214 if ((begin_ = std::string::find(".", begin_)) == -1) { return ""; }
215 ++begin_;
216 }
217 int end_ = std::string::find(".", begin_);
218 return std::string::substr(begin_, (end_ == -1 ? std::string::size() : end_) - begin_);
219 }
220
221 bool is_undef(int pos) const {
222 std::string tmp = substr_field(pos);
223 return tmp.empty() || tmp == "0" || tmp == "*";
224 }
225};
226
230template <typename T>
232 static const char* name;
233};
234
235template <typename T>
236const char* MemcomTypeName<T>::name = "U";
237
238template <>
240
241template <>
243
244template <>
246
247template <>
249
250template <>
252
253template <>
254const char* MemcomTypeName<b2000::csda<double> >::name;
255
256typedef std::vector<RTable> ArrayRTable;
257
260class DBSlice {
261public:
262 DBSlice(mcOff start_, mcOff end_ = 0, mcOff step_ = 1)
263 : start(start_), end(end_ == 0 ? start_ + 1 : end_), step(step_) {}
264
265 size_t size() const { return (end - start) / step; }
266
267 bool is_null() const { return this == &null; }
268
269 bool is_all() const { return this == &all; }
270
271 void set_mcslice(mcSlice* sl) const {
272 sl->start = start + 1;
273 sl->end = end;
274 sl->start = step;
275 }
276
277 static DBSlice null;
278 static DBSlice all;
279
280private:
281 friend class DataBase;
282 mcOff start;
283 mcOff end;
284 mcOff step;
285};
286
288class DataBase {
289public:
290 DataBase()
291 : handler(-1),
292 is_readonly(false),
293 close_db_on_delete(true),
294 logger(logging::get_logger("database.b2000db")),
295 time_sync(0) {}
296
297 virtual ~DataBase();
298
300 void init(const std::string& name);
301
303 std::string get_name() const { return name; }
304
305 std::string get_logging_directory();
306
308 void open(bool readonly = false);
309
311 virtual void close() {
312 if (handler != -1) {
313 int status = mcDBcloseFile(handler);
314 if (status < 0) { IOError() << mcErrGetMsgAndReset(status) << THROW; }
315 handler = -1;
316 }
317 }
318
320 int get_handle() { return handler; }
321
323 bool has_key(const std::string& key) const {
324 return (mcDBinqSetAtt(handler, key.c_str(), nullptr) == 1);
325 }
326
328 typedef std::set<SetName> SetNameSet;
329
332 void add_keys(const std::string& pattern, SetNameSet& set_names) const {
333 mcSetAttributes att;
334 for (int iter = 0; mcDBgetSetNextIter(handler, &iter, &att);) {
335 SetName set_name(att.name);
336 if (set_name.match(pattern)) { set_names.insert(set_name); }
337 }
338 }
339
341 virtual void sync() {
342 Time t1;
343 int status = mcDBsaveFileNoSync(handler);
344 if (status < 0) { IOError() << mcErrGetMsgAndReset(status) << THROW; }
345 Time t2;
346 time_sync = double(t2 - t1) * 10;
347 last_sync = t1;
348 }
349
354 if (double(Time() - last_sync) > time_sync) { sync(); }
355 }
356
357 virtual void temporary_close() {
358 int status = mcDBcloseFile(handler);
359 if (status < 0) { IOError() << mcErrGetMsgAndReset(status) << THROW; }
360 }
361
362 virtual void reopen() {
363 std::string arch_path = path::join(db_name, "archives.mc");
364 if (_mcDBopenFile(handler, arch_path.c_str(), (is_readonly ? "o" : "rw"), 0, 0)
365 != handler) {
366 IOError() << "Cannot reopen the B2000++ database \"" << db_name << "\"." << THROW;
367 }
368 }
369
370 class TemporaryClose {
371 public:
372 TemporaryClose(DataBase& db_) : db(db_) { db.temporary_close(); }
373 ~TemporaryClose() { db.reopen(); }
374
375 private:
376 DataBase& db;
377 };
378
380 size_t ndim(const std::string& key) const {
381 mcSetAttributes att;
382 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
383 DBError() << "The dataset " << key << " does not exist." << THROW;
384 }
385 return att.ndim;
386 }
387
389 const std::vector<size_t> dims(const std::string& key) const {
390 mcSetAttributes att;
391 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
392 DBError() << "The dataset " << key << " does not exist." << THROW;
393 }
394 return std::vector<size_t>(att.dim, att.dim + att.ndim);
395 }
396
398 const std::type_info& element_type(const std::string& key) const {
399 mcSetAttributes att;
400 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
401 DBError() << "The dataset " << key << " does not exist." << THROW;
402 }
403 switch (att.type[0]) {
404 case 'I':
405 return typeid(mcInt32);
406 case 'J':
407 return typeid(mcInt64);
408 case 'E':
409 return typeid(mcFloat32);
410 case 'F':
411 return typeid(mcFloat64);
412 case 'C':
413 return typeid(std::complex<mcFloat64>);
414 case 'Z':
415 return typeid(std::complex<mcFloat64>);
416 case 'K':
417 return typeid(std::string);
418 case '$':
419 return typeid(RTable);
420 default:
421 if (att.type[0] == 'S' && att.type[0] == 'T') { return typeid(ArrayRTable); }
422 DBError() << "The memcom type " << att.type << " is not supported by B2000++"
423 << THROW;
424 break;
425 }
426 return typeid(void);
427 }
428
430 void remove(const std::string& key) {
431 int status = mcDBdeleteSet(handler, key.c_str());
432 if (status) {
433 DBError() << "mcDBdeleteSet returns an unexpected error: "
434 << mcErrGetMsgAndReset(status) << "." << THROW;
435 }
436 }
437
439 void rename(const std::string& oldkey, const std::string& newkey) {
440 if (has_key(newkey) && has_key(oldkey)) { remove(newkey); }
441 int status = mcDBrenameSet(handler, oldkey.c_str(), newkey.c_str());
442 if (status) {
443 DBError() << "mcDBrenameSet returns an unexpected error: "
444 << mcErrGetMsgAndReset(status) << "." << THROW;
445 }
446 }
447
448 mcSetAttributes get_attributes(const std::string& key) const {
449 mcSetAttributes att;
450 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
451 DBError() << "The dataset " << key << " does not exist." << THROW;
452 }
453 return att;
454 }
455
457 template <typename T>
458 void get(const std::string& key, std::vector<T>& v, const DBSlice& s1 = DBSlice::all) const {
459 mcSetAttributes att;
460 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
461 DBError() << "Cannot read dataset " << key << ", it does not exist." << THROW;
462 }
463 if (att.ndim != 1 && att.dim[1] != 1) {
464 DBError() << "Cannot read dataset " << key << ", it has " << att.ndim
465 << " instead of 1 dimensions." << THROW;
466 }
467 bool convert = false;
468 if (MemcomTypeName<T>::name[0] != att.type[0]) {
469 if (!can_convert_data(att.type, MemcomTypeName<T>::name)) {
470 DBError() << "Cannot read dataset " << key << ", its type is " << att.type
471 << " instead of " << MemcomTypeName<T>::name << "." << THROW;
472 }
473 convert = true;
474 }
475
476 if (v.size() == 0) {
477 if (s1.is_all()) {
478 v.resize(att.dim[0]);
479 } else {
480 v.resize(s1.size());
481 }
482 } else if (s1.is_all()) {
483 if (mcOff(v.size()) != att.dim[0]) {
484 DBError() << "Cannot read dataset " << key << ", its first dimension is "
485 << att.dim[0] << " instead of " << v.size() << "." << THROW;
486 }
487 } else if (v.size() != s1.size()) {
488 DBError() << "Cannot read dataset " << key << ", the size of the vector is " << v.size()
489 << " but the size of the DBSlice is " << s1.size() << "." << THROW;
490 }
491
492 void* p = (void*)&v[0];
493 std::vector<char> tmp;
494 if (convert) {
495 tmp.resize(mcSizeof(att.type) * v.size());
496 p = (void*)&tmp[0];
497 }
498
499 if (s1.is_all()) {
500 int status = mcDBgetSetArray(handler, key.c_str(), v.size(), p);
501 if (status != 0) {
502 DBError() << "mcDBgetSetposArray returns an unexpected error: "
503 << mcErrGetMsgAndReset(status) << "." << THROW;
504 }
505 } else {
506 mcSlice sl;
507 s1.set_mcslice(&sl);
508 int status = mcDBgetSetsliceArray(handler, key.c_str(), 1, &sl, 0, nullptr, p);
509 if (status != 0) {
510 DBError() << "mcDBgetSetsliceArray returns an unexpected error: "
511 << mcErrGetMsgAndReset(status) << "." << THROW;
512 }
513 }
514
515 if (convert) { convert_data(v.size(), att.type, MemcomTypeName<T>::name, &tmp[0], &v[0]); }
516 }
517
519 template <typename T>
520 void get(const std::string& key, std::vector<T>& v, const DBSlice& s1, const DBSlice& s2) {
521 mcSetAttributes att;
522 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
523 DBError() << "Cannot read dataset " << key << ", it does not exist." << THROW;
524 }
525 if (att.ndim != 2) {
526 DBError() << "Cannot read dataset " << key << ", it has " << att.ndim
527 << " instead of 2 dimensions." << THROW;
528 }
529 bool convert = false;
530 if (MemcomTypeName<T>::name[0] != att.type[0]) {
531 if (!can_convert_data(att.type, MemcomTypeName<T>::name)) {
532 DBError() << "Cannot read dataset " << key << ", its type is " << att.type
533 << " instead of " << MemcomTypeName<T>::name << "." << THROW;
534 }
535 convert = true;
536 }
537 if (v.size() == 0) {
538 if (s1.is_all()) {
539 v.resize(att.dim[0]);
540 } else {
541 v.resize(s1.size());
542 }
543 } else if (s1.is_all()) {
544 if (mcOff(v.size()) != att.dim[0]) {
545 DBError() << "Cannot read dataset " << key << ", its first dimension is "
546 << att.dim[0] << " instead of " << v.size() << "." << THROW;
547 }
548 } else if (v.size() != s1.size()) {
549 DBError() << "Cannot read dataset " << key << ", the size of the vector is " << v.size()
550 << " but the size of the DBSlice is " << s1.size() << "." << THROW;
551 }
552 if (s2.is_all() || s2.size() != 1) {
553 DBError() << "The DBSlice " << key << " has not dimension 1." << THROW;
554 }
555
556 void* p = (void*)&v[0];
557 std::vector<char> tmp;
558 if (convert) {
559 tmp.resize(mcSizeof(att.type) * v.size());
560 p = (void*)&tmp[0];
561 }
562
563 if (s1.is_all()) {
564 int status =
565 mcDBgetSetposArray(handler, key.c_str(), att.dim[0] * s2.start + 1, v.size(), p);
566 if (status != 0) {
567 DBError() << "mcDBgetSetposArray returns an unexpected error: "
568 << mcErrGetMsgAndReset(status) << "." << THROW;
569 }
570 } else {
571 mcSlice sl[2];
572 s2.set_mcslice(sl);
573 s1.set_mcslice(sl + 1);
574 int status = mcDBgetSetsliceArray(handler, key.c_str(), 1, sl, 0, nullptr, p);
575 if (status != 0) {
576 DBError() << "mcDBgetSetsliceArray returns an unexpected error: "
577 << mcErrGetMsgAndReset(status) << "." << THROW;
578 }
579 }
580
581 if (convert) { convert_data(v.size(), att.type, MemcomTypeName<T>::name, &tmp[0], &v[0]); }
582 }
583
585 template <typename T>
586 void get(
587 const std::string& key, b2linalg::Vector<T, b2linalg::Vincrement_ref> v,
588 const DBSlice& s1 = DBSlice::all) {
589 mcSetAttributes att;
590 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
591 DBError() << "Cannot read dataset " << key << ", it does not exist." << THROW;
592 }
593 if (att.ndim != 1) {
594 DBError() << "Cannot read dataset " << key << ", it has " << att.ndim
595 << " instead of 1 dimensions." << THROW;
596 }
597 bool convert = false;
598 if (MemcomTypeName<T>::name[0] != att.type[0]) {
599 if (!can_convert_data(att.type, MemcomTypeName<T>::name)) {
600 DBError() << "Cannot read dataset " << key << ", its type is " << att.type
601 << " instead of " << MemcomTypeName<T>::name << "." << THROW;
602 }
603 convert = true;
604 }
605
606 if (s1.is_all()) {
607 if (mcOff(v.size()) != att.dim[0]) {
608 DBError() << "Cannot read dataset " << key << " its first dimension is "
609 << att.dim[0] << " instead of " << v.size() << "." << THROW;
610 }
611 } else if (v.size() != s1.size()) {
612 DBError() << "Cannot read dataset " << key << ", the size of the vector is " << v.size()
613 << " but the size of the DBSlice is " << s1.size() << "." << THROW;
614 }
615
616 void* p = (void*)&v[0];
617 std::vector<char> tmp;
618 if (convert) {
619 tmp.resize(mcSizeof(att.type) * v.size());
620 p = (void*)&tmp[0];
621 }
622
623 if (s1.is_all()) {
624 int status = mcDBgetSetArray(handler, key.c_str(), v.size(), p);
625 if (status != 0) {
626 DBError() << "mcDBgetSetposArray returns an unexpected error: "
627 << mcErrGetMsgAndReset(status) << "." << THROW;
628 }
629 } else {
630 mcSlice sl;
631 s1.set_mcslice(&sl);
632 int status = mcDBgetSetsliceArray(handler, key.c_str(), 1, &sl, 0, nullptr, p);
633 if (status != 0) {
634 DBError() << "mcDBgetSetsliceArray returns an unexpected error: "
635 << mcErrGetMsgAndReset(status) << "." << THROW;
636 }
637 }
638
639 if (convert) { convert_data(v.size(), att.type, MemcomTypeName<T>::name, &tmp[0], &v[0]); }
640 }
641
643 template <typename T>
644 void get(
645 const std::string& key, b2linalg::Vector<T, b2linalg::Vincrement_ref> v,
646 const DBSlice& s1, const DBSlice& s2) {
647 mcSetAttributes att;
648 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
649 DBError() << "Cannot read dataset " << key << ", it does not exist." << THROW;
650 }
651 if (att.ndim != 2) {
652 DBError() << "Cannot read dataset " << key << ", it has " << att.ndim
653 << " instead of 2 dimensions." << THROW;
654 }
655 bool convert = false;
656 if (MemcomTypeName<T>::name[0] != att.type[0]) {
657 if (!can_convert_data(att.type, MemcomTypeName<T>::name)) {
658 DBError() << "Cannot read dataset " << key << " its type is " << att.type
659 << " instead of " << MemcomTypeName<T>::name << "." << THROW;
660 }
661 convert = true;
662 }
663
664 if (s1.is_all()) {
665 if (mcOff(v.size()) != att.dim[0]) {
666 DBError() << "Cannot read dataset " << key << " its first dimension is "
667 << att.dim[0] << " instead of " << v.size() << "." << THROW;
668 }
669 } else if (v.size() != s1.size()) {
670 DBError() << "Cannot read dataset " << key << ", the size of the vector is " << v.size()
671 << " but the size of the DBSlice is " << s1.size() << "." << THROW;
672 }
673 if (s2.is_all() || s2.size() != 1) {
674 DBError() << "Cannot read dataset " << key << ", the DBSlice " << key
675 << " has not dimension 1." << THROW;
676 }
677
678 void* p = (void*)&v[0];
679 std::vector<char> tmp;
680 if (convert) {
681 tmp.resize(mcSizeof(att.type) * v.size());
682 p = (void*)&tmp[0];
683 }
684
685 if (s1.is_all()) {
686 int status =
687 mcDBgetSetposArray(handler, key.c_str(), att.dim[0] * s2.start + 1, v.size(), p);
688 if (status != 0) {
689 DBError() << "mcDBgetSetposArray returns an unexpected error: "
690 << mcErrGetMsgAndReset(status) << "." << THROW;
691 }
692 } else {
693 mcSlice sl[2];
694 s2.set_mcslice(sl);
695 s1.set_mcslice(sl + 1);
696 int status = mcDBgetSetsliceArray(handler, key.c_str(), 1, sl, 0, nullptr, p);
697 if (status != 0) {
698 DBError() << "mcDBgetSetsliceArray returns an unexpected error: "
699 << mcErrGetMsgAndReset(status) << "." << THROW;
700 }
701 }
702
703 if (convert) { convert_data(v.size(), att.type, MemcomTypeName<T>::name, &tmp[0], &v[0]); }
704 }
705
707 template <typename T>
708 void get(
709 const std::string& key, b2linalg::Matrix<T, b2linalg::Mrectangle>& m,
710 const DBSlice& s1 = DBSlice::all, const DBSlice& s2 = DBSlice::all) {
711 mcSetAttributes att;
712 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
713 DBError() << "Cannot read dataset " << key << ", it does not exist." << THROW;
714 }
715 if (att.ndim != 2) {
716 DBError() << "Cannot read dataset " << key << ", it has " << att.ndim
717 << " instead of 2 dimensions." << THROW;
718 }
719 bool convert = false;
720 if (MemcomTypeName<T>::name[0] != att.type[0]) {
721 if (!can_convert_data(att.type, MemcomTypeName<T>::name)) {
722 DBError() << "Cannot read dataset " << key << ", its type is " << att.type
723 << " instead of " << MemcomTypeName<T>::name << "." << THROW;
724 }
725 convert = true;
726 }
727
728 if (m.size1() != 0) {
729 if (s1.is_all()) {
730 if (mcOff(m.size1()) != att.dim[1]) {
731 DBError() << "Cannot read dataset set " << key << ", its first dimension is "
732 << att.dim[1] << " instead of " << m.size1() << "." << THROW;
733 }
734 } else if (m.size1() != s1.size()) {
735 DBError() << "Cannot read dataset " << key
736 << ", the first dimension of the matrix is " << m.size1()
737 << " but the size of the first DBSlice is " << s1.size() << "." << THROW;
738 }
739 }
740 if (m.size2() != 0) {
741 if (s2.is_all()) {
742 if (mcOff(m.size2()) != att.dim[0]) {
743 DBError() << "Cannot read dataset " << key << ", its second dimension is "
744 << att.dim[0] << " instead of " << m.size2() << "." << THROW;
745 }
746 } else if (m.size2() != s2.size()) {
747 DBError() << "Cannot read dataset " << key
748 << ", the second dimension of the matrix is " << m.size2()
749 << " but the size of the second DBSlice is " << s2.size() << "." << THROW;
750 }
751 }
752
753 if (s1.is_all() && s2.is_all()) {
754 m.resize(att.dim[1], att.dim[0]);
755 } else {
756 m.resize(s1.is_all() ? att.dim[1] : s1.size(), s2.is_all() ? att.dim[0] : s2.size());
757 }
758
759 void* p = (void*)&m(0, 0);
760 std::vector<char> tmp;
761 if (convert) {
762 tmp.resize(mcSizeof(att.type) * m.size1() * m.size2());
763 p = (void*)&tmp[0];
764 }
765
766 if (s1.is_all() && s2.is_all()) {
767 int status = mcDBgetSetArray(handler, key.c_str(), m.size1() * m.size2(), p);
768 if (status != 0) {
769 DBError() << "mcDBgetSetposArray returns an unexpected error: "
770 << mcErrGetMsgAndReset(status) << "." << THROW;
771 }
772 } else {
773 mcSlice sl[2];
774 if (s1.is_all()) {
775 sl[0].start = 1;
776 sl[0].end = att.dim[0];
777 sl[0].step = 1;
778 } else {
779 s2.set_mcslice(sl);
780 }
781 if (s2.is_all()) {
782 sl[1].start = 1;
783 sl[1].end = att.dim[1];
784 sl[1].step = 1;
785 } else {
786 s1.set_mcslice(sl + 1);
787 }
788 int status = mcDBgetSetsliceArray(handler, key.c_str(), 1, sl, 0, nullptr, p);
789 if (status != 0) {
790 DBError() << "mcDBgetSetsliceArray returns an unexpected error: "
791 << mcErrGetMsgAndReset(status) << "." << THROW;
792 }
793 }
794
795 if (convert) {
796 convert_data(
797 m.size1() * m.size2(), att.type, MemcomTypeName<T>::name, &tmp[0], &m(0, 0));
798 }
799 }
800
802 template <typename T>
803 void get(
804 const std::string& key, b2linalg::Matrix<T, b2linalg::Mrectangle_increment_ref> m,
805 const DBSlice& s1 = DBSlice::all, const DBSlice& s2 = DBSlice::all) {
806 mcSetAttributes att;
807 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
808 DBError() << "Cannot read dataset " << key << ", it does not exist." << THROW;
809 }
810 if (att.ndim != 2) {
811 DBError() << "Cannot read dataset " << key << ", it has " << att.ndim
812 << " instead of 2 dimensions." << THROW;
813 }
814 bool convert = false;
815 if (MemcomTypeName<T>::name[0] != att.type[0]) {
816 if (!can_convert_data(att.type, MemcomTypeName<T>::name)) {
817 DBError() << "Cannot read dataset " << key << " its type is" << att.type
818 << " instead of " << MemcomTypeName<T>::name << "." << THROW;
819 }
820 convert = true;
821 }
822
823 if (s1.is_all()) {
824 if (mcOff(m.size1()) != att.dim[1]) {
825 DBError() << "Cannot read dataset " << key << " its first dimension is "
826 << att.dim[1] << " instead of " << m.size1() << "." << THROW;
827 }
828 } else if (m.size1() != s1.size()) {
829 DBError() << "Cannot read dataset " << key << ", the first dimension of the matrix is "
830 << m.size1() << " but the size of the first DBSlice is " << s1.size() << "."
831 << THROW;
832 }
833 if (s2.is_all()) {
834 if (mcOff(m.size2()) != att.dim[0]) {
835 DBError() << "Cannot read dataset " << key << ", its second dimension is "
836 << att.dim[0] << " instead of " << m.size2() << "." << THROW;
837 }
838 } else if (m.size2() != s2.size()) {
839 DBError() << "Cannot read dataset " << key << ", the second dimension of the matrix is "
840 << m.size2() << " but the size of the second DBSlice is " << s2.size() << "."
841 << THROW;
842 }
843
844 void* p = (void*)&m(0, 0);
845 std::vector<char> tmp;
846 if (convert) {
847 tmp.resize(mcSizeof(att.type) * m.size1() * m.size2());
848 p = (void*)&tmp[0];
849 }
850
851 if (s1.is_all() && s2.is_all()) {
852 int status = mcDBgetSetArray(handler, key.c_str(), m.size1() * m.size2(), p);
853 if (status != 0) {
854 DBError() << "mcDBgetSetposArray returns an unexpected error: "
855 << mcErrGetMsgAndReset(status) << "." << THROW;
856 }
857 } else {
858 mcSlice sl[2];
859 if (s1.is_all()) {
860 sl[0].start = 1;
861 sl[0].end = att.dim[0];
862 sl[0].step = 1;
863 } else {
864 s2.set_mcslice(sl);
865 }
866 if (s2.is_all()) {
867 sl[1].start = 1;
868 sl[1].end = att.dim[1];
869 sl[1].step = 1;
870 } else {
871 s1.set_mcslice(sl + 1);
872 }
873 int status = mcDBgetSetsliceArray(handler, key.c_str(), 1, sl, 0, nullptr, p);
874 if (status != 0) {
875 DBError() << "mcDBgetSetsliceArray returns an unexpected error: "
876 << mcErrGetMsgAndReset(status) << "." << THROW;
877 }
878 }
879
880 if (convert) {
881 convert_data(
882 m.size1() * m.size2(), att.type, MemcomTypeName<T>::name, &tmp[0], &m(0, 0));
883 }
884 }
885
887 template <typename T>
888 void set(
889 const std::string& key, const std::vector<T>& v, const DBSlice& s1 = DBSlice::all,
890 bool new_set = false) {
891 set(key, b2linalg::Vector<T, b2linalg::Vincrement_constref>(v), s1, new_set);
892 }
893
895 template <typename T>
896 void set(
897 const std::string& key, const b2linalg::Vector<T, b2linalg::Vincrement_constref>& v,
898 const DBSlice& s1 = DBSlice::all, bool new_set = false) {
899 mcSetAttributes att;
900 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
901 if (!s1.is_all()) {
902 DBError() << "Cannot write dataset " << key
903 << " an existing dataset is requested, but the dataset "
904 "does not exist."
905 << THROW;
906 }
907 mcOff dim = v.size();
908 int status = mcDBcreateSet(handler, key.c_str(), MemcomTypeName<T>::name, 1, &dim);
909 if (status != 0) {
910 DBError() << "mcDBcreateSet returns an unexpected error: "
911 << mcErrGetMsgAndReset(status) << "." << THROW;
912 }
913 } else {
914 if (new_set) {
915 DBError() << "Cannot write dataset " << key
916 << ", a new dataset is requested but the dataset already "
917 "exists."
918 << THROW;
919 }
920 if (att.type[0] != MemcomTypeName<T>::name[0]) {
921 DBError() << "Cannot write dataset " << key << ", its type is " << att.type
922 << " instead of " << MemcomTypeName<T>::name[0] << "." << THROW;
923 }
924 if (att.ndim != 1) {
925 DBError() << "Cannot write dataset " << key << ", it has " << att.ndim
926 << " instead of 1 dimensions." << THROW;
927 }
928 if (att.dim[0] != mcOff((s1.is_all() ? v.size() : s1.size()))) {
929 DBError() << "Cannot write dataset " << key << ", its first dimension is "
930 << att.dim[0] << " instead of " << (s1.is_all() ? v.size() : s1.size())
931 << "." << THROW;
932 }
933 }
934 if (s1.is_all()) {
935 int status = mcDBputSet(
936 handler, key.c_str(), MemcomTypeName<T>::name, v.size(), const_cast<T*>(&v[0]));
937 if (status != 0) {
938 DBError() << "mcDBputSetpos returns an unexpected error: "
939 << mcErrGetMsgAndReset(status) << "." << THROW;
940 }
941 } else {
942 mcSlice sl;
943 s1.set_mcslice(&sl);
944 int status = mcDBputSetslice(
945 handler, key.c_str(), MemcomTypeName<T>::name, 1, &sl, 0, 0,
946 const_cast<T*>(&v[0]));
947 if (status != 0) {
948 DBError() << "mcDBputSetslice returns an unexpected error: "
949 << mcErrGetMsgAndReset(status) << "." << THROW;
950 }
951 }
952 }
953
955 template <typename T>
956 void set(
957 const std::string& key, const b2linalg::Vector<T, b2linalg::Vincrement_constref>& v,
958 const DBSlice& s1, const DBSlice& s2, bool new_set = false) {
959 mcSetAttributes att;
960 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
961 if (!s1.is_all() || !s2.is_all()) {
962 DBError() << "Cannot write dataset " << key
963 << ", an existing dataset is requested, but the dataset "
964 "does not exist."
965 << THROW;
966 }
967 mcOff dim = v.size();
968 int status = mcDBcreateSet(handler, key.c_str(), MemcomTypeName<T>::name, 1, &dim);
969 if (status != 0) {
970 DBError() << "mcDBcreateSet returns an unexpected error: "
971 << mcErrGetMsgAndReset(status) << "." << THROW;
972 }
973 } else {
974 if (new_set) {
975 DBError() << "Cannot write dataset " << key
976 << ", a new dataset is requested but the dataset already "
977 "exists."
978 << THROW;
979 }
980 if (att.type[0] != MemcomTypeName<T>::name[0]) {
981 DBError() << "Cannot write dataset " << key << ", its type is " << att.type
982 << " instead of " << MemcomTypeName<T>::name[0] << "." << THROW;
983 }
984 if (s2.is_null()) {
985 if (att.ndim != 1) {
986 DBError() << "Cannot write dataset" << key << ", it has " << att.ndim
987 << " instead of 1 dimensions." << THROW;
988 }
989 } else {
990 if (att.ndim != 2) {
991 DBError() << "Cannot write dataset " << key << ", it has " << att.ndim
992 << " instead of 2 dimensions." << THROW;
993 }
994 if (att.dim[1] > s2.end) {
995 DBError() << "Cannot write dataset " << key << ", its second dimension is "
996 << att.dim[0] << " but should be less than " << s2.end << "."
997 << THROW;
998 }
999 }
1000 if (att.dim[0] != mcOff(s1.is_all() ? v.size() : s1.size())) {
1001 DBError() << "Cannot write dataset " << key << ", its first dimension is "
1002 << att.dim[0] << " instead of " << (s1.is_all() ? v.size() : s1.size())
1003 << "." << THROW;
1004 }
1005 }
1006 if (s1.is_all() && s2.is_all()) {
1007 int status = mcDBputSet(
1008 handler, key.c_str(), MemcomTypeName<T>::name, v.size(), const_cast<T*>(&v[0]));
1009 if (status != 0) {
1010 DBError() << "mcDBputSetpos returns an unexpected error: "
1011 << mcErrGetMsgAndReset(status) << "." << THROW;
1012 }
1013 } else {
1014 mcSlice sl[2];
1015 s2.set_mcslice(sl);
1016 s1.set_mcslice(sl + 1);
1017 int status = mcDBputSetslice(
1018 handler, key.c_str(), MemcomTypeName<T>::name, 2, sl, 0, 0,
1019 const_cast<T*>(&v[0]));
1020 if (status != 0) {
1021 DBError() << "mcDBputSetslice returns an unexpected error: "
1022 << mcErrGetMsgAndReset(status) << "." << THROW;
1023 }
1024 }
1025 }
1026
1028 template <typename T>
1029 void set(
1030 const std::string& key, const b2linalg::Matrix<T, b2linalg::Mrectangle>& m,
1031 const DBSlice& s1 = DBSlice::all, const DBSlice& s2 = DBSlice::all,
1032 bool new_set = false) {
1033 set(key, b2linalg::Matrix<T, b2linalg::Mrectangle_constref>(m), s1, s2, new_set);
1034 }
1035
1037 template <typename T>
1038 void set(
1039 const std::string& key, const b2linalg::Matrix<T, b2linalg::Mrectangle_constref>& m,
1040 const DBSlice& s1 = DBSlice::all, const DBSlice& s2 = DBSlice::all,
1041 bool new_set = false) {
1042 mcSetAttributes att;
1043 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
1044 if (!s1.is_all() || !s2.is_all()) {
1045 DBError() << "Cannot write dataset " << key
1046 << ", an existing dataset is requested, but the dataset "
1047 "does not exist."
1048 << THROW;
1049 }
1050 mcOff dim[2] = {mcOff(m.size2()), mcOff(m.size1())};
1051 int status = mcDBcreateSet(handler, key.c_str(), MemcomTypeName<T>::name, 2, dim);
1052 if (status != 0) {
1053 DBError() << "mcDBcreateSet returns an unexpected error: "
1054 << mcErrGetMsgAndReset(status) << "." << THROW;
1055 }
1056 } else {
1057 if (new_set) {
1058 DBError() << "Cannot write dataset " << key
1059 << ", a new dataset is requested but the dataset already "
1060 "exists."
1061 << THROW;
1062 }
1063 if (att.type[0] != MemcomTypeName<T>::name[0]) {
1064 DBError() << "Cannot write dataset " << key << ", its type is " << att.type
1065 << " instead of " << MemcomTypeName<T>::name[0] << "." << THROW;
1066 }
1067 if (att.ndim != 2) {
1068 DBError() << "Cannot write dataset " << key << ", it has " << att.ndim
1069 << " instead of 2 dimensions." << THROW;
1070 }
1071 if (att.dim[0] != mcOff(s1.is_all() ? m.size2() : s2.size())) {
1072 DBError() << "Cannot write dataset " << key << ", its first dimension is "
1073 << att.dim[0] << " instead of " << (s1.is_all() ? m.size2() : s2.size())
1074 << "." << THROW;
1075 }
1076 if (att.dim[1] != mcOff(s2.is_all() ? m.size1() : s1.size())) {
1077 DBError() << "Cannot write dataset " << key << " its second dimension is "
1078 << att.dim[1] << " instead of " << (s2.is_all() ? m.size1() : s1.size())
1079 << "." << THROW;
1080 }
1081 }
1082 if (s1.is_all() && s2.is_all()) {
1083 int status = mcDBputSet(
1084 handler, key.c_str(), MemcomTypeName<T>::name, m.size1() * m.size2(),
1085 const_cast<T*>(&m(0, 0)));
1086 if (status != 0) {
1087 DBError() << "mcDBputSetpos returns an unexpected error: "
1088 << mcErrGetMsgAndReset(status) << "." << THROW;
1089 }
1090 } else {
1091 mcSlice sl[2];
1092 s2.set_mcslice(sl);
1093 s1.set_mcslice(sl + 1);
1094 int status = mcDBputSetslice(
1095 handler, key.c_str(), MemcomTypeName<T>::name, 2, sl, 0, 0,
1096 const_cast<T*>(&m(0, 0)));
1097 if (status != 0) {
1098 DBError() << "mcDBputSetslice returns an unexpected error: "
1099 << mcErrGetMsgAndReset(status) << "." << THROW;
1100 }
1101 }
1102 }
1103
1105 template <typename T>
1106 void set(
1107 const std::string& key, const b2linalg::Matrix<T, b2linalg::Mpacked>& m,
1108 bool new_set = false) {
1109 mcSetAttributes att;
1110 if (mcDBinqSetAtt(handler, key.c_str(), &att) == 0) {
1111 mcOff dim[1] = {mcOff(m.esize())};
1112 int status = mcDBcreateSet(handler, key.c_str(), MemcomTypeName<T>::name, 1, dim);
1113 if (status != 0) {
1114 DBError() << "mcDBcreateSet returns an unexpected error: "
1115 << mcErrGetMsgAndReset(status) << "." << THROW;
1116 }
1117 } else {
1118 if (new_set) {
1119 DBError() << "Cannot write dataset " << key
1120 << ", a new dataset is requested but the dataset already "
1121 "exists."
1122 << THROW;
1123 }
1124 if (att.type[0] != MemcomTypeName<T>::name[0]) {
1125 DBError() << "Cannot write dataset " << key << ", its type is " << att.type
1126 << " instead of " << MemcomTypeName<T>::name[0] << "." << THROW;
1127 }
1128 if (att.ndim != 1) {
1129 DBError() << "Cannot write dataset " << key << ", it has " << att.ndim
1130 << " instead of 1 dimensions." << THROW;
1131 }
1132 if (att.dim[0] != mcOff(m.esize())) {
1133 DBError() << "Cannot write dataset " << key << ", its first dimension is "
1134 << att.dim[0] << " instead of " << m.esize() << "." << THROW;
1135 }
1136 }
1137 int status = mcDBputSet(
1138 handler, key.c_str(), MemcomTypeName<T>::name, m.esize(), const_cast<T*>(&m(0, 0)));
1139 if (status != 0) {
1140 DBError() << "mcDBputSetpos returns an unexpected error: "
1141 << mcErrGetMsgAndReset(status) << "." << THROW;
1142 }
1143 }
1144
1146 void get(const std::string& key, RTable& rtable, const DBSlice& s1 = DBSlice::all) const;
1147
1149 void set(const std::string& key, const RTable& rtable, bool new_set = false);
1150
1152 void set(const std::string& key, const RTable& rtable, size_t pos);
1153
1155 bool get_desc(
1156 const std::string& key, RTable& rtable,
1157 bool raise_exception_on_missing_desc = true) const;
1158
1160 void set_desc(const std::string& key, const RTable& rtable);
1161
1163 void get(const std::string& key, ArrayRTable& rtable) const;
1164
1166 void set(
1167 const std::string& key, const std::vector<RTable>& array_rtable, bool new_set = false,
1168 bool new_sparse_table = false);
1169
1172 public:
1173 template <typename T>
1174 ArrayTableCol(const std::string& col_name, const b2linalg::Matrix<T>& mat)
1175 : name(col_name),
1176 ncol(mat.size2()),
1177 nrow(mat.size1()),
1178 step(1),
1179 type_name(MemcomTypeName<T>::name),
1180 value(&mat(0, 0)) {}
1181
1182 template <typename T>
1183 ArrayTableCol(const std::string& col_name, size_t col_size, const std::vector<T>& v)
1184 : name(col_name),
1185 ncol(col_size),
1186 nrow(v.size() / col_size),
1187 step(1),
1188 type_name(MemcomTypeName<T>::name),
1189 value(&v[0]) {}
1190
1191 template <typename T>
1193 const std::string& col_name, size_t col_size, size_t row_size, const T* v,
1194 size_t step)
1195 : name(col_name),
1196 ncol(col_size),
1197 nrow(row_size),
1198 step(step),
1199 type_name(MemcomTypeName<T>::name),
1200 value(v) {}
1201
1202 void init_mcATColIndBuf(int column, mcATColIndBuf& att) const {
1203 att.column = column + 1;
1204 att.buffer = const_cast<void*>(value);
1205 att.buffer_step = step;
1206 }
1207 std::string name;
1208 size_t ncol;
1209 size_t nrow;
1210 size_t step;
1211 const char* type_name;
1212 const void* value;
1213 };
1214
1216 void set(const std::string& key, const std::vector<ArrayTableCol>& cols, bool new_set = false) {
1217 {
1218 std::ostringstream o;
1219 o << cols[0].name << ":" << cols[0].ncol << cols[0].type_name;
1220 for (size_t i = 1; i < cols.size(); ++i) {
1221 if (cols[i].nrow != cols[0].nrow) { Exception() << THROW; }
1222 o << "." << cols[i].name << ":" << cols[i].ncol << cols[i].type_name;
1223 }
1224 std::string colspec = o.str();
1225 if (has_key(key)) {
1226 if (new_set) {
1227 DBError() << "Cannot write dataset " << key
1228 << ", a new dataset is requested but the dataset "
1229 "already exists."
1230 << THROW;
1231 } else {
1232 int status = mcDBdeleteSet(handler, key.c_str());
1233 if (status != 0) { DBError() << mcErrGetMsgAndReset(status) << THROW; }
1234 }
1235 }
1236 int status = mcATcreateTable(handler, key.c_str(), cols[0].nrow, colspec.c_str());
1237 if (status != 0) { DBError() << mcErrGetMsgAndReset(status) << THROW; }
1238 }
1239 {
1240 std::vector<mcATColIndBuf> col_att(cols.size());
1241 for (size_t i = 0; i < cols.size(); ++i) { cols[i].init_mcATColIndBuf(i, col_att[i]); }
1242 if (mcATputSlice(
1243 handler, key.c_str(), 1, cols[0].nrow, 1, col_att.size(), &col_att[0])) {
1244 DBError() << THROW;
1245 }
1246 }
1247 }
1248
1249protected:
1250 std::string name;
1251 std::string db_name;
1252 int handler;
1253 bool is_readonly;
1254 bool close_db_on_delete;
1255 logging::Logger logger;
1256 Time last_sync;
1257 double time_sync;
1258
1259 static bool can_convert_data(const std::string& type_from, const std::string& type_to) {
1260 if (type_from == "F") {
1261 if (type_to == "Z") { return true; }
1262 return false;
1263 } else if (type_from == "Z") {
1264 if (type_to == "F") { return true; }
1265 return false;
1266 }
1267 return false;
1268 }
1269
1270 static void convert_data(
1271 const size_t num_elements, const std::string& type_from, const std::string& type_to,
1272 const void* data_from, void* data_to) {
1273 if (type_from == "F") {
1274 const double* data_from_t = (const double*)data_from;
1275 if (type_to == "Z") {
1276 b2000::csda<double>* data_to_t = (b2000::csda<double>*)data_to;
1277 std::copy_n(data_from_t, num_elements, data_to_t);
1278 } else {
1279 assert(0);
1280 }
1281 } else if (type_from == "Z") {
1282 const b2000::csda<double>* data_from_t = (const b2000::csda<double>*)data_from;
1283 if (type_to == "F") {
1284 double* data_to_t = (double*)data_to;
1285 std::copy_n(data_from_t, num_elements, data_to_t);
1286 } else {
1287 assert(0);
1288 }
1289 } else {
1290 assert(0);
1291 }
1292 }
1293};
1294
1295class DataBaseFieldSet : public DataBase {
1296public:
1297 DataBaseFieldSet() : DataBase(), fields_loaded(false), fields_saved(true) {}
1298
1299 void add_field_entry(
1300 const std::string& title, const std::string& gname, const std::string& type,
1301 const std::string& csys, const bool indexed, const bool discrete, const bool additive);
1302
1303 void close() override {
1304 save_fields();
1306 }
1307
1308 void sync() override {
1309 save_fields();
1311 }
1312
1313 void temporary_close() override {
1314 save_fields();
1315 fields_loaded = false;
1316 fields_saved = true;
1317 fields_rtables.clear();
1318 fields_indices.clear();
1319 DataBase::temporary_close();
1320 }
1321
1322private:
1323 void save_fields();
1324
1325 typedef std::map<std::string, int> FieldsIndices;
1326
1327 bool fields_loaded;
1328 bool fields_saved;
1329 ArrayRTable fields_rtables;
1330 FieldsIndices fields_indices;
1331};
1332
1333void remove_database(const std::string& name, bool remove_directory);
1334
1335} // namespace b2000
1336
1337#endif
#define THROW
Definition b2exception.H:198
Definition b2database.H:260
A column in an array table dataset.
Definition b2database.H:1171
The object associated with the B2000++ database.
Definition b2database.H:288
void set(const std::string &key, const b2linalg::Vector< T, b2linalg::Vincrement_constref > &v, const DBSlice &s1, const DBSlice &s2, bool new_set=false)
Write a positional dataset.
Definition b2database.H:956
void set(const std::string &key, const b2linalg::Matrix< T, b2linalg::Mpacked > &m, bool new_set=false)
Write a positional dataset.
Definition b2database.H:1106
void sync_delayed()
Definition b2database.H:353
void get(const std::string &key, b2linalg::Vector< T, b2linalg::Vincrement_ref > v, const DBSlice &s1, const DBSlice &s2)
Read a positional dataset.
Definition b2database.H:644
void set(const std::string &key, const std::vector< ArrayTableCol > &cols, bool new_set=false)
Write an array table dataset.
Definition b2database.H:1216
const std::vector< size_t > dims(const std::string &key) const
Definition b2database.H:389
void get(const std::string &key, std::vector< T > &v, const DBSlice &s1, const DBSlice &s2)
Read a positional dataset.
Definition b2database.H:520
void rename(const std::string &oldkey, const std::string &newkey)
Rename a dataset.
Definition b2database.H:439
int get_handle()
Definition b2database.H:320
void set(const std::string &key, const b2linalg::Vector< T, b2linalg::Vincrement_constref > &v, const DBSlice &s1=DBSlice::all, bool new_set=false)
Write a positional dataset.
Definition b2database.H:896
bool has_key(const std::string &key) const
Definition b2database.H:323
void get(const std::string &key, std::vector< T > &v, const DBSlice &s1=DBSlice::all) const
Read a positional dataset.
Definition b2database.H:458
void init(const std::string &name)
Set the name of the MemCom database directory.
Definition b2database.C:105
std::string get_name() const
Definition b2database.H:303
void set(const std::string &key, const b2linalg::Matrix< T, b2linalg::Mrectangle_constref > &m, const DBSlice &s1=DBSlice::all, const DBSlice &s2=DBSlice::all, bool new_set=false)
Write a positional dataset.
Definition b2database.H:1038
void remove(const std::string &key)
Remove a dataset.
Definition b2database.H:430
void add_keys(const std::string &pattern, SetNameSet &set_names) const
Definition b2database.H:332
void open(bool readonly=false)
Open the database.
Definition b2database.C:140
void set(const std::string &key, const b2linalg::Matrix< T, b2linalg::Mrectangle > &m, const DBSlice &s1=DBSlice::all, const DBSlice &s2=DBSlice::all, bool new_set=false)
Write a positional dataset.
Definition b2database.H:1029
void set(const std::string &key, const std::vector< T > &v, const DBSlice &s1=DBSlice::all, bool new_set=false)
Write a positional dataset.
Definition b2database.H:888
virtual void sync()
Write all pending data to the files, in particular the index.
Definition b2database.H:341
bool get_desc(const std::string &key, RTable &rtable, bool raise_exception_on_missing_desc=true) const
Read the dataset descriptor.
Definition b2database.C:310
void set_desc(const std::string &key, const RTable &rtable)
Write the dataset descriptor.
Definition b2database.C:341
void get(const std::string &key, b2linalg::Matrix< T, b2linalg::Mrectangle_increment_ref > m, const DBSlice &s1=DBSlice::all, const DBSlice &s2=DBSlice::all)
Read a positional dataset.
Definition b2database.H:803
std::set< SetName > SetNameSet
A collection of dataset names.
Definition b2database.H:328
void get(const std::string &key, b2linalg::Vector< T, b2linalg::Vincrement_ref > v, const DBSlice &s1=DBSlice::all)
Read a positional dataset.
Definition b2database.H:586
size_t ndim(const std::string &key) const
Definition b2database.H:380
void get(const std::string &key, b2linalg::Matrix< T, b2linalg::Mrectangle > &m, const DBSlice &s1=DBSlice::all, const DBSlice &s2=DBSlice::all)
Read a positional dataset.
Definition b2database.H:708
virtual void close()
Flush all pending data and close the database.
Definition b2database.H:311
const std::type_info & element_type(const std::string &key) const
Definition b2database.H:398
Definition b2exception.H:131
const char * name() const noexcept
Definition b2exception.H:154
Definition b2rtable.H:427
MemCom dataset names according to the B2000++ conventions.
Definition b2database.H:49
Definition b2logging.H:495
Logger & get_logger(const std::string &logger_name="")
Definition b2logging.H:829
std::string join(const std::string &a, const std::string &b)
Definition b2path.C:165
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
GenericException< IOError_name > IOError
Definition b2exception.H:335
GenericException< DBError_name > DBError
Definition b2exception.H:340
Definition b2database.H:231