Joedb 10.4.3
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
Database.h
Go to the documentation of this file.
1/////////////////////////////////////////////////////////////////////////////
2//
3// This code was automatically generated by the joedb compiler
4// https://www.joedb.org/
5//
6// Path to compiler: /home/rcoulom/repos/joedb/doc/source/tutorial/build/joedbc
7// Version: 10.4.3
8// joedbc compilation time: Jul 14 2026 13:07:22
9// Generation of this file: 2026-07-14 11:07:28 GMT
10//
11/////////////////////////////////////////////////////////////////////////////
12#ifndef tutorial_Database_declared
13#define tutorial_Database_declared
14
17#include "joedb/error/assert.h"
18#include "joedb/get_version.h"
19#include "joedb/hash_combine.h"
20#include "ids.h"
21
22#include <string>
23#include <cstring>
24#include <vector>
25#include <algorithm>
26#include <string_view>
27
28#include "joedb/ui/type_io.h"
29#include <sstream>
30#include <map>
31
32static_assert(std::string_view(joedb::get_version()) == "10.4.3");
33
34namespace tutorial
35{
36 /// @namespace tutorial
37 ///
38 /// Automatically generated by joedbc
39
40 using joedb::Record_Id;
41 using joedb::Table_Id;
42 using joedb::Field_Id;
43
44 class container_of_city;
45 class container_of_person;
46
47 using type_of_index_of_city_by_name = std::map<std::string, id_of_city, std::less<>>;
48 using type_of_index_of_person_by_name = std::multimap<std::tuple<std::string, std::string>, id_of_person, std::less<>>;
49
50 namespace detail
51 {
52 struct data_of_city
53 {
54 std::vector<std::string> field_value_of_name;
55 std::vector<type_of_index_of_city_by_name::iterator> iterator_over_city_by_name;
56
57 joedb::Freedom_Keeper freedom_keeper;
58
59 size_t size() const {return freedom_keeper.size();}
60
61 void resize(size_t new_size)
62 {
63 field_value_of_name.resize(new_size);
64 iterator_over_city_by_name.resize(new_size);
65 freedom_keeper.resize(new_size);
66 }
67 };
68
69 struct data_of_person
70 {
71 std::vector<std::string> field_value_of_first_name;
72 std::vector<std::string> field_value_of_last_name;
73 std::vector<id_of_city> field_value_of_home;
74 std::vector<type_of_index_of_person_by_name::iterator> iterator_over_person_by_name;
75
76 joedb::Freedom_Keeper freedom_keeper;
77
78 size_t size() const {return freedom_keeper.size();}
79
80 void resize(size_t new_size)
81 {
82 field_value_of_first_name.resize(new_size);
83 field_value_of_last_name.resize(new_size);
84 field_value_of_home.resize(new_size);
85 iterator_over_person_by_name.resize(new_size);
86 freedom_keeper.resize(new_size);
87 }
88 };
89 }
90
91 class range_of_person_by_name;
92
93 /// Store all the tables of the database
95 {
96 friend class Readable;
97 friend class container_of_city;
98 friend class container_of_person;
100
101 public:
102 template<typename E = joedb::Exception>
103 static void throw_exception(std::string_view message)
104 {
105 std::string s("tutorial: ");
106 s += message;
107 throw E(s);
108 }
109
110 bool is_valid(id_of_city id) const {return is_valid_record_id_for_city(id.get_record_id());}
111 bool is_valid(id_of_person id) const {return is_valid_record_id_for_person(id.get_record_id());}
112
113 protected:
114 detail::data_of_city storage_of_city;
115 bool is_valid_record_id_for_city(Record_Id record_id) const {return storage_of_city.freedom_keeper.is_used(record_id);}
116 detail::data_of_person storage_of_person;
117 bool is_valid_record_id_for_person(Record_Id record_id) const {return storage_of_person.freedom_keeper.is_used(record_id);}
118
121 {
122 auto &iterator = storage_of_city.iterator_over_city_by_name[to_underlying(record_id)];
123 if (iterator != index_of_city_by_name.end())
124 {
125 index_of_city_by_name.erase(iterator);
126 iterator = index_of_city_by_name.end();
127 }
128 }
130 {
131 auto result = index_of_city_by_name.insert
132 (
133 type_of_index_of_city_by_name::value_type
134 (
135 (storage_of_city.field_value_of_name[to_underlying(record_id)]),
136 id_of_city(record_id)
137 )
138 );
139 if (!result.second)
140 {
141 std::ostringstream out;
142 out << "city_by_name unique index failure: (";
143 joedb::write_string(out, storage_of_city.field_value_of_name[to_underlying(record_id)]);
144 out << ") at id = " << record_id << ' ';
145 out << "was already at id = " << result.first->second.get_id();
146 throw_exception(out.str());
147 }
148 storage_of_city.iterator_over_city_by_name[to_underlying(record_id)] = result.first;
149 }
152 {
153 auto &iterator = storage_of_person.iterator_over_person_by_name[to_underlying(record_id)];
154 if (iterator != index_of_person_by_name.end())
155 {
156 index_of_person_by_name.erase(iterator);
157 iterator = index_of_person_by_name.end();
158 }
159 }
161 {
162 auto result = index_of_person_by_name.insert
163 (
164 type_of_index_of_person_by_name::value_type
165 (
166 std::tuple<std::string, std::string>(storage_of_person.field_value_of_last_name[to_underlying(record_id)], storage_of_person.field_value_of_first_name[to_underlying(record_id)]),
167 id_of_person(record_id)
168 )
169 );
170 storage_of_person.iterator_over_person_by_name[to_underlying(record_id)] = result;
171 }
172
174 {
177 storage_of_city.field_value_of_name[to_underlying(record_id)].clear();
178 storage_of_city.freedom_keeper.free(record_id);
179 }
181 {
184 storage_of_person.field_value_of_first_name[to_underlying(record_id)].clear();
185 storage_of_person.field_value_of_last_name[to_underlying(record_id)].clear();
186 storage_of_person.field_value_of_home[to_underlying(record_id)] = id_of_city(joedb::Record_Id::null);
187 storage_of_person.freedom_keeper.free(record_id);
188 }
189
191 {
192 storage_of_city.iterator_over_city_by_name[to_underlying(record_id)] = index_of_city_by_name.end();
193 storage_of_city.freedom_keeper.use(record_id);
194 }
195
196 void internal_vector_insert_city(Record_Id record_id, size_t size)
197 {
198 JOEDB_RELEASE_ASSERT(storage_of_city.freedom_keeper.is_free_vector(record_id, size));
199 storage_of_city.freedom_keeper.use_vector(record_id, size);
200 std::fill_n
201 (
202 &storage_of_city.iterator_over_city_by_name[to_underlying(record_id)],
203 size,
205 );
206 }
208 {
209 storage_of_person.iterator_over_person_by_name[to_underlying(record_id)] = index_of_person_by_name.end();
210 storage_of_person.freedom_keeper.use(record_id);
211 }
212
213 void internal_vector_insert_person(Record_Id record_id, size_t size)
214 {
215 JOEDB_RELEASE_ASSERT(storage_of_person.freedom_keeper.is_free_vector(record_id, size));
216 storage_of_person.freedom_keeper.use_vector(record_id, size);
217 std::fill_n
218 (
219 &storage_of_person.iterator_over_person_by_name[to_underlying(record_id)],
220 size,
222 );
223 }
224
226 (
227 Record_Id record_id,
228 std::string_view field_value_of_name
229 )
230 {
232 storage_of_city.field_value_of_name[to_underlying(record_id)] = field_value_of_name;
234 add_index_of_city_by_name(record_id);
235 }
236
238 (
239 Record_Id record_id,
240 size_t size,
241 const std::string *value
242 )
243 {
244 JOEDB_RELEASE_ASSERT(storage_of_city.freedom_keeper.is_used_vector(record_id, size));
245 std::string *target = &storage_of_city.field_value_of_name.data()[to_underlying(record_id)];
246 if (target != value)
247 std::copy_n(value, size, target);
248 for (size_t i = 0; i < size; i++)
249 remove_index_of_city_by_name(record_id + i);
250 for (size_t i = 0; i < size; i++)
251 add_index_of_city_by_name(record_id + i);
252 }
253
255 (
256 Record_Id record_id,
257 std::string_view field_value_of_first_name
258 )
259 {
261 storage_of_person.field_value_of_first_name[to_underlying(record_id)] = field_value_of_first_name;
264 }
265
267 (
268 Record_Id record_id,
269 size_t size,
270 const std::string *value
271 )
272 {
273 JOEDB_RELEASE_ASSERT(storage_of_person.freedom_keeper.is_used_vector(record_id, size));
274 std::string *target = &storage_of_person.field_value_of_first_name.data()[to_underlying(record_id)];
275 if (target != value)
276 std::copy_n(value, size, target);
277 for (size_t i = 0; i < size; i++)
278 remove_index_of_person_by_name(record_id + i);
279 for (size_t i = 0; i < size; i++)
280 add_index_of_person_by_name(record_id + i);
281 }
282
284 (
285 Record_Id record_id,
286 std::string_view field_value_of_last_name
287 )
288 {
290 storage_of_person.field_value_of_last_name[to_underlying(record_id)] = field_value_of_last_name;
293 }
294
296 (
297 Record_Id record_id,
298 size_t size,
299 const std::string *value
300 )
301 {
302 JOEDB_RELEASE_ASSERT(storage_of_person.freedom_keeper.is_used_vector(record_id, size));
303 std::string *target = &storage_of_person.field_value_of_last_name.data()[to_underlying(record_id)];
304 if (target != value)
305 std::copy_n(value, size, target);
306 for (size_t i = 0; i < size; i++)
307 remove_index_of_person_by_name(record_id + i);
308 for (size_t i = 0; i < size; i++)
309 add_index_of_person_by_name(record_id + i);
310 }
311
313 (
314 Record_Id record_id,
315 id_of_city field_value_of_home
316 )
317 {
319 storage_of_person.field_value_of_home[to_underlying(record_id)] = field_value_of_home;
320 }
321
323 (
324 Record_Id record_id,
325 size_t size,
326 const id_of_city *value
327 )
328 {
329 JOEDB_RELEASE_ASSERT(storage_of_person.freedom_keeper.is_used_vector(record_id, size));
330 id_of_city *target = &storage_of_person.field_value_of_home.data()[to_underlying(record_id)];
331 if (target != value)
332 std::copy_n(value, size, target);
333 }
334
335 public:
337
339 {
340 return id_of_city
341 (
342 Record_Id(storage_of_city.freedom_keeper.get_next(id.get_record_id()))
343 );
344 }
345
347 {
348 return id_of_city
349 (
350 Record_Id(storage_of_city.freedom_keeper.get_previous(id.get_record_id()))
351 );
352 }
353
354 template<class Comparator>
355 std::vector<id_of_city> sorted_city(Comparator comparator) const;
356
358 {
359 return id_of_city();
360 }
361
362 const std::string & get_name(id_of_city record) const
363 {
365 return (const std::string &)(storage_of_city.field_value_of_name[record.get_id()]);
366 }
367
369
371 {
372 return id_of_person
373 (
374 Record_Id(storage_of_person.freedom_keeper.get_next(id.get_record_id()))
375 );
376 }
377
379 {
380 return id_of_person
381 (
382 Record_Id(storage_of_person.freedom_keeper.get_previous(id.get_record_id()))
383 );
384 }
385
386 template<class Comparator>
387 std::vector<id_of_person> sorted_person(Comparator comparator) const;
388
390 {
391 return id_of_person();
392 }
393
394 const std::string & get_first_name(id_of_person record) const
395 {
397 return (const std::string &)(storage_of_person.field_value_of_first_name[record.get_id()]);
398 }
399
400 const std::string & get_last_name(id_of_person record) const
401 {
403 return (const std::string &)(storage_of_person.field_value_of_last_name[record.get_id()]);
404 }
405
407 {
409 return (id_of_city)(storage_of_person.field_value_of_home[record.get_id()]);
410 }
411
416
421
423 {
425 auto iterator = storage_of_city.iterator_over_city_by_name[id.get_id()];
426 ++iterator;
427 if (iterator != index_of_city_by_name.end())
428 return iterator->second;
429 else
430 return id_of_city();
431 }
433 {
435 auto iterator = storage_of_city.iterator_over_city_by_name[id.get_id()];
436 if (iterator != index_of_city_by_name.begin())
437 return (--iterator)->second;
438 else
439 return id_of_city();
440 }
441 id_of_city find_city_by_name(std::string_view field_value_of_name) const
442 {
443 const auto i = index_of_city_by_name.find((field_value_of_name));
444 if (i == index_of_city_by_name.end())
445 return id_of_city();
446 else
447 return i->second;
448 }
449 range_of_person_by_name find_person_by_name(std::string_view field_value_of_last_name, std::string_view field_value_of_first_name) const;
450 };
451 /// returned by @ref Database::get_city_table
453 {
454 friend class Database;
455
456 private:
457 const Database &db;
458 container_of_city(const Database &db): db(db) {}
459
460 public:
462 {
463 friend class container_of_city;
464 private:
465 const joedb::Freedom_Keeper *fk;
466 Record_Id index;
467 iterator(const detail::data_of_city &data): fk(&data.freedom_keeper), index(joedb::Freedom_Keeper_Constants::used_list) {}
468 public:
469 using iterator_category = std::forward_iterator_tag;
471 using difference_type = std::ptrdiff_t;
474
475 bool operator==(const iterator &i) const {return index == i.index;}
476 bool operator!=(const iterator &i) const {return index != i.index;}
477 iterator &operator++() {index = fk->get_next(index); return *this;}
478 iterator operator++(int) {auto copy = *this; index = fk->get_next(index); return copy;}
479 iterator &operator--() {index = fk->get_previous(index); return *this;}
480 iterator operator--(int) {auto copy = *this; index = fk->get_previous(index); return copy;}
481 id_of_city operator*() const {return id_of_city(Record_Id(index));}
482 };
483
484 iterator begin() const {return ++iterator(db.storage_of_city);}
485 iterator end() const {return iterator(db.storage_of_city);}
486 bool is_empty() const {return db.storage_of_city.freedom_keeper.get_used_count() == Record_Id{0};}
487 joedb::index_t get_size() const {return to_underlying(db.storage_of_city.freedom_keeper.get_used_count());}
488 static id_of_city get_at(size_t i) {return id_of_city(Record_Id(i));}
489 bool is_valid_at(size_t i) {return db.storage_of_city.freedom_keeper.is_used(Record_Id(i));}
490 id_of_city first() const {return *begin();}
491 id_of_city last() const {return *--end();}
492 id_of_city get_end() const {return *end();}
493 };
494
496 {
497 return container_of_city(*this);
498 }
499
500 template<class Comparator>
501 std::vector<id_of_city> Database::sorted_city(Comparator comparator) const
502 {
503 std::vector<id_of_city> result;
504 for (auto x: get_city_table())
505 result.emplace_back(x);
506 std::sort(result.begin(), result.end(), comparator);
507 return result;
508 }
509 /// returned by @ref Database::get_person_table
511 {
512 friend class Database;
513
514 private:
515 const Database &db;
516 container_of_person(const Database &db): db(db) {}
517
518 public:
520 {
522 private:
523 const joedb::Freedom_Keeper *fk;
524 Record_Id index;
525 iterator(const detail::data_of_person &data): fk(&data.freedom_keeper), index(joedb::Freedom_Keeper_Constants::used_list) {}
526 public:
527 using iterator_category = std::forward_iterator_tag;
529 using difference_type = std::ptrdiff_t;
532
533 bool operator==(const iterator &i) const {return index == i.index;}
534 bool operator!=(const iterator &i) const {return index != i.index;}
535 iterator &operator++() {index = fk->get_next(index); return *this;}
536 iterator operator++(int) {auto copy = *this; index = fk->get_next(index); return copy;}
537 iterator &operator--() {index = fk->get_previous(index); return *this;}
538 iterator operator--(int) {auto copy = *this; index = fk->get_previous(index); return copy;}
540 };
541
542 iterator begin() const {return ++iterator(db.storage_of_person);}
544 bool is_empty() const {return db.storage_of_person.freedom_keeper.get_used_count() == Record_Id{0};}
545 joedb::index_t get_size() const {return to_underlying(db.storage_of_person.freedom_keeper.get_used_count());}
546 static id_of_person get_at(size_t i) {return id_of_person(Record_Id(i));}
547 bool is_valid_at(size_t i) {return db.storage_of_person.freedom_keeper.is_used(Record_Id(i));}
548 id_of_person first() const {return *begin();}
549 id_of_person last() const {return *--end();}
550 id_of_person get_end() const {return *end();}
551 };
552
554 {
555 return container_of_person(*this);
556 }
557
558 template<class Comparator>
559 std::vector<id_of_person> Database::sorted_person(Comparator comparator) const
560 {
561 std::vector<id_of_person> result;
562 for (auto x: get_person_table())
563 result.emplace_back(x);
564 std::sort(result.begin(), result.end(), comparator);
565 return result;
566 }
567 /// returned by @ref Database::find_person_by_name
569 {
570 friend class Database;
571 private:
572 std::pair<type_of_index_of_person_by_name::const_iterator, type_of_index_of_person_by_name::const_iterator> range;
573 range_of_person_by_name(const Database &db, std::string_view last_name, std::string_view first_name)
574 {
575 range = db.index_of_person_by_name.equal_range(std::tuple<std::string, std::string>(last_name, first_name));
576 }
577 public:
579 {
581 private:
582 type_of_index_of_person_by_name::const_iterator map_iterator;
583 iterator(type_of_index_of_person_by_name::const_iterator map_iterator): map_iterator(map_iterator) {}
584 public:
585 bool operator !=(const iterator &i) const
586 {
587 return map_iterator != i.map_iterator;
588 }
589 iterator &operator++() {map_iterator++; return *this;}
590 id_of_person operator*() const {return map_iterator->second;}
591 };
592 iterator begin() const {return range.first;}
593 iterator end() const {return range.second;}
594 bool empty() const {return range.first == range.second;}
595 size_t size() const {return size_t(std::distance(range.first, range.second));}
596 };
597
598 inline range_of_person_by_name Database::find_person_by_name(std::string_view field_value_of_last_name, std::string_view field_value_of_first_name) const
599 {
600 return range_of_person_by_name(*this, field_value_of_last_name, field_value_of_first_name);
601 }
602}
603
604#endif
void resize(Record_Id new_size)
Record_Id get_previous(Record_Id index) const
Record_Id get_next(Record_Id index) const
static const Record_Id null
Definition index_types.h:44
Store all the tables of the database.
Definition Database.h:95
void internal_update_person__last_name(Record_Id record_id, std::string_view field_value_of_last_name)
Definition Database.h:284
void internal_update_vector_person__first_name(Record_Id record_id, size_t size, const std::string *value)
Definition Database.h:267
id_of_person previous(id_of_person id) const
Definition Database.h:378
bool is_valid(id_of_city id) const
Definition Database.h:110
const std::string & get_last_name(id_of_person record) const
Definition Database.h:400
void internal_update_vector_city__name(Record_Id record_id, size_t size, const std::string *value)
Definition Database.h:238
container_of_person get_person_table() const
Definition Database.h:553
friend class container_of_city
Definition Database.h:97
void internal_insert_person(Record_Id record_id)
Definition Database.h:207
const std::string & get_first_name(id_of_person record) const
Definition Database.h:394
static void throw_exception(std::string_view message)
Definition Database.h:103
friend class container_of_person
Definition Database.h:98
void internal_update_vector_person__home(Record_Id record_id, size_t size, const id_of_city *value)
Definition Database.h:323
void add_index_of_person_by_name(Record_Id record_id)
Definition Database.h:160
void remove_index_of_person_by_name(Record_Id record_id)
Definition Database.h:151
void internal_update_person__first_name(Record_Id record_id, std::string_view field_value_of_first_name)
Definition Database.h:255
detail::data_of_city storage_of_city
Definition Database.h:114
void internal_update_city__name(Record_Id record_id, std::string_view field_value_of_name)
Definition Database.h:226
void add_index_of_city_by_name(Record_Id record_id)
Definition Database.h:129
friend class range_of_person_by_name
Definition Database.h:99
detail::data_of_person storage_of_person
Definition Database.h:116
void internal_update_vector_person__last_name(Record_Id record_id, size_t size, const std::string *value)
Definition Database.h:296
range_of_person_by_name find_person_by_name(std::string_view field_value_of_last_name, std::string_view field_value_of_first_name) const
Definition Database.h:598
type_of_index_of_city_by_name index_of_city_by_name
Definition Database.h:119
id_of_city get_home(id_of_person record) const
Definition Database.h:406
id_of_city previous_city_by_name(id_of_city id) const
Definition Database.h:432
const std::string & get_name(id_of_city record) const
Definition Database.h:362
void internal_update_person__home(Record_Id record_id, id_of_city field_value_of_home)
Definition Database.h:313
bool is_valid_record_id_for_city(Record_Id record_id) const
Definition Database.h:115
std::vector< id_of_city > sorted_city(Comparator comparator) const
Definition Database.h:501
bool is_valid_record_id_for_person(Record_Id record_id) const
Definition Database.h:117
static id_of_person null_person()
Definition Database.h:389
void internal_insert_city(Record_Id record_id)
Definition Database.h:190
container_of_city get_city_table() const
Definition Database.h:495
id_of_city find_city_by_name(std::string_view field_value_of_name) const
Definition Database.h:441
bool is_valid(id_of_person id) const
Definition Database.h:111
void internal_delete_person(Record_Id record_id)
Definition Database.h:180
const type_of_index_of_city_by_name & get_index_of_city_by_name()
Definition Database.h:412
type_of_index_of_person_by_name index_of_person_by_name
Definition Database.h:150
id_of_city next(id_of_city id) const
Definition Database.h:338
std::vector< id_of_person > sorted_person(Comparator comparator) const
Definition Database.h:559
void internal_delete_city(Record_Id record_id)
Definition Database.h:173
const type_of_index_of_person_by_name & get_index_of_person_by_name()
Definition Database.h:417
void remove_index_of_city_by_name(Record_Id record_id)
Definition Database.h:120
void internal_vector_insert_city(Record_Id record_id, size_t size)
Definition Database.h:196
id_of_city previous(id_of_city id) const
Definition Database.h:346
id_of_city next_city_by_name(id_of_city id) const
Definition Database.h:422
id_of_person next(id_of_person id) const
Definition Database.h:370
static id_of_city null_city()
Definition Database.h:357
void internal_vector_insert_person(Record_Id record_id, size_t size)
Definition Database.h:213
Implement the joedb::Readable interface for a compiled database.
Definition Readable.h:27
bool operator==(const iterator &i) const
Definition Database.h:475
bool operator!=(const iterator &i) const
Definition Database.h:476
std::forward_iterator_tag iterator_category
Definition Database.h:469
returned by Database::get_city_table
Definition Database.h:453
bool is_valid_at(size_t i)
Definition Database.h:489
iterator begin() const
Definition Database.h:484
iterator end() const
Definition Database.h:485
joedb::index_t get_size() const
Definition Database.h:487
id_of_city get_end() const
Definition Database.h:492
id_of_city first() const
Definition Database.h:490
id_of_city last() const
Definition Database.h:491
static id_of_city get_at(size_t i)
Definition Database.h:488
bool operator==(const iterator &i) const
Definition Database.h:533
bool operator!=(const iterator &i) const
Definition Database.h:534
std::forward_iterator_tag iterator_category
Definition Database.h:527
returned by Database::get_person_table
Definition Database.h:511
id_of_person first() const
Definition Database.h:548
id_of_person last() const
Definition Database.h:549
id_of_person get_end() const
Definition Database.h:550
joedb::index_t get_size() const
Definition Database.h:545
static id_of_person get_at(size_t i)
Definition Database.h:546
Strongly-typed wrapper around an integer representing a row of the city table.
Definition ids.h:25
constexpr auto get_id() const
Definition ids.h:35
constexpr Record_Id get_record_id() const
Definition ids.h:36
Strongly-typed wrapper around an integer representing a row of the person table.
Definition ids.h:48
constexpr Record_Id get_record_id() const
Definition ids.h:59
constexpr auto get_id() const
Definition ids.h:58
bool operator!=(const iterator &i) const
Definition Database.h:585
returned by Database::find_person_by_name
Definition Database.h:569
#define JOEDB_RELEASE_ASSERT(x)
always-tested assertion (release and debug mode)
Definition assert.h:24
ptrdiff_t index_t
Definition index_types.h:18
constexpr const char * get_version()
Definition get_version.h:7
void write_string(std::ostream &out, std::string_view s, bool json)
Automatically generated by joedbc.
Definition Client.h:19
std::map< std::string, id_of_city, std::less<> > type_of_index_of_city_by_name
Definition Database.h:47
std::multimap< std::tuple< std::string, std::string >, id_of_person, std::less<> > type_of_index_of_person_by_name
Definition Database.h:48