Joedb 9.1.4
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: 9.1.4
8// joedbc compilation time: Apr 15 2025 14:46:29
9// Generation of this file: 2025-04-15 12:46:31 GMT
10//
11/////////////////////////////////////////////////////////////////////////////
12#ifndef tutorial_Database_declared
13#define tutorial_Database_declared
14
20#include "joedb/error/assert.h"
21#include "joedb/get_version.h"
22#include "ids.h"
23
24#include <string>
25#include <cstdint>
26#include <cstring>
27#include <vector>
28#include <algorithm>
29#include <string_view>
30
31#include <map>
32
33#include "joedb/ui/type_io.h"
34#include <sstream>
35
36static_assert(std::string_view(joedb::get_version()) == "9.1.4");
37
38namespace tutorial
39{
40 /// @namespace tutorial
41 ///
42 /// Automatically generated by joedbc
43
44 using joedb::Record_Id;
45 using joedb::Table_Id;
46 using joedb::Field_Id;
47
48 namespace detail
49 {
50 extern const char * schema_string;
51 inline constexpr size_t schema_string_size = 99;
52 }
53 class container_of_city;
54 class container_of_person;
55
56 namespace detail
57 {
58 struct data_of_city
59 {
60 std::vector<std::string> field_value_of_name;
61 std::vector<std::map<std::string, id_of_city>::iterator> iterator_over_city_by_name;
62
63 joedb::Compact_Freedom_Keeper freedom_keeper;
64
65 size_t size() const {return freedom_keeper.size();}
66
67 void resize(size_t new_size)
68 {
69 field_value_of_name.resize(new_size);
70 iterator_over_city_by_name.resize(new_size);
71 freedom_keeper.resize(new_size);
72 }
73 };
74
75 struct data_of_person
76 {
77 std::vector<std::string> field_value_of_first_name;
78 std::vector<std::string> field_value_of_last_name;
79 std::vector<id_of_city> field_value_of_home;
80 std::vector<std::multimap<std::tuple<std::string, std::string>, id_of_person>::iterator> iterator_over_person_by_name;
81
82 joedb::Compact_Freedom_Keeper freedom_keeper;
83
84 size_t size() const {return freedom_keeper.size();}
85
86 void resize(size_t new_size)
87 {
88 field_value_of_first_name.resize(new_size);
89 field_value_of_last_name.resize(new_size);
90 field_value_of_home.resize(new_size);
91 iterator_over_person_by_name.resize(new_size);
92 freedom_keeper.resize(new_size);
93 }
94 };
95 }
96
97 class range_of_person_by_name;
98
99 /// Store all the tables of the database
101 {
102 friend class Readable;
103 friend class id_of_city;
104 friend class container_of_city;
105 friend class id_of_person;
108
109 public:
110 template<typename E = joedb::Exception>
111 static void throw_exception(const std::string &message)
112 {
113 throw E("tutorial: " + message);
114 }
115
117 Table_Id current_table_id = Table_Id{0};
118
119 void set_max_record_id(size_t record_id)
120 {
121 max_record_id = record_id;
122 }
123
124 bool is_valid(id_of_city id) const {return is_valid_record_id_for_city(id.get_record_id());}
125 bool is_valid(id_of_person id) const {return is_valid_record_id_for_person(id.get_record_id());}
126
127 protected:
128 detail::data_of_city storage_of_city;
129 bool is_valid_record_id_for_city(Record_Id record_id) const {return storage_of_city.freedom_keeper.is_used(size_t(record_id) + 1);}
130 detail::data_of_person storage_of_person;
131 bool is_valid_record_id_for_person(Record_Id record_id) const {return storage_of_person.freedom_keeper.is_used(size_t(record_id) + 1);}
132
133 std::map<std::string, id_of_city> index_of_city_by_name;
134 void remove_index_of_city_by_name(Record_Id record_id)
135 {
136 auto &iterator = storage_of_city.iterator_over_city_by_name[size_t(record_id) - 1];
137 if (iterator != index_of_city_by_name.end())
138 {
139 index_of_city_by_name.erase(iterator);
140 iterator = index_of_city_by_name.end();
141 }
142 }
143 void add_index_of_city_by_name(Record_Id record_id)
144 {
145 auto result = index_of_city_by_name.insert
146 (
147 std::map<std::string, id_of_city>::value_type
148 (
149 std::string(storage_of_city.field_value_of_name[size_t(record_id) - 1]),
150 id_of_city(record_id)
151 )
152 );
153 if (!result.second)
154 {
155 std::ostringstream out;
156 out << "city_by_name unique index failure: (";
157 joedb::write_string(out, storage_of_city.field_value_of_name[size_t(record_id) - 1]);
158 out << ") at id = " << record_id << ' ';
159 out << "was already at id = " << result.first->second.get_id();
160 throw_exception(out.str());
161 }
162 storage_of_city.iterator_over_city_by_name[size_t(record_id) - 1] = result.first;
163 }
164 std::multimap<std::tuple<std::string, std::string>, id_of_person> index_of_person_by_name;
165 void remove_index_of_person_by_name(Record_Id record_id)
166 {
167 auto &iterator = storage_of_person.iterator_over_person_by_name[size_t(record_id) - 1];
168 if (iterator != index_of_person_by_name.end())
169 {
170 index_of_person_by_name.erase(iterator);
171 iterator = index_of_person_by_name.end();
172 }
173 }
174 void add_index_of_person_by_name(Record_Id record_id)
175 {
176 auto result = index_of_person_by_name.insert
177 (
178 std::multimap<std::tuple<std::string, std::string>, id_of_person>::value_type
179 (
180 std::tuple<std::string, std::string>(storage_of_person.field_value_of_last_name[size_t(record_id) - 1], storage_of_person.field_value_of_first_name[size_t(record_id) - 1]),
181 id_of_person(record_id)
182 )
183 );
184 storage_of_person.iterator_over_person_by_name[size_t(record_id) - 1] = result;
185 }
186
187 void internal_delete_city(Record_Id record_id)
188 {
191 storage_of_city.field_value_of_name[size_t(record_id) - 1].clear();
192 storage_of_city.freedom_keeper.free(size_t(record_id) + 1);
193 }
194 void internal_delete_person(Record_Id record_id)
195 {
198 storage_of_person.field_value_of_first_name[size_t(record_id) - 1].clear();
199 storage_of_person.field_value_of_last_name[size_t(record_id) - 1].clear();
200 storage_of_person.field_value_of_home[size_t(record_id) - 1] = id_of_city(Record_Id(0));
201 storage_of_person.freedom_keeper.free(size_t(record_id) + 1);
202 }
203
204 void internal_insert_city(Record_Id record_id)
205 {
206 storage_of_city.iterator_over_city_by_name[size_t(record_id) - 1] = index_of_city_by_name.end();
207 storage_of_city.freedom_keeper.use(size_t(record_id) + 1);
208 }
209
210 void internal_vector_insert_city(Record_Id record_id, size_t size)
211 {
212 storage_of_city.freedom_keeper.use_vector(size_t(record_id) + 1, size);
213 std::fill_n
214 (
215 &storage_of_city.iterator_over_city_by_name[size_t(record_id) - 1],
216 size,
218 );
219 }
220 void internal_insert_person(Record_Id record_id)
221 {
222 storage_of_person.iterator_over_person_by_name[size_t(record_id) - 1] = index_of_person_by_name.end();
223 storage_of_person.freedom_keeper.use(size_t(record_id) + 1);
224 }
225
226 void internal_vector_insert_person(Record_Id record_id, size_t size)
227 {
228 storage_of_person.freedom_keeper.use_vector(size_t(record_id) + 1, size);
229 std::fill_n
230 (
231 &storage_of_person.iterator_over_person_by_name[size_t(record_id) - 1],
232 size,
234 );
235 }
236
238 (
239 Record_Id record_id,
240 const std::string& field_value_of_name
241 )
242 {
244 storage_of_city.field_value_of_name[size_t(record_id) - 1] = field_value_of_name;
246 add_index_of_city_by_name(record_id);
247 }
248
250 (
251 Record_Id record_id,
252 size_t size,
253 const std::string *value
254 )
255 {
256 for (size_t i = 0; i < size; i++)
258 std::string *target = &storage_of_city.field_value_of_name[size_t(record_id) - 1];
259 if (target != value)
260 std::copy_n(value, size, target);
261 for (size_t i = 0; i < size; i++)
262 remove_index_of_city_by_name(record_id + i);
263 for (size_t i = 0; i < size; i++)
264 add_index_of_city_by_name(record_id + i);
265 }
266
268 (
269 Record_Id record_id,
270 const std::string& field_value_of_first_name
271 )
272 {
274 storage_of_person.field_value_of_first_name[size_t(record_id) - 1] = field_value_of_first_name;
277 }
278
280 (
281 Record_Id record_id,
282 size_t size,
283 const std::string *value
284 )
285 {
286 for (size_t i = 0; i < size; i++)
288 std::string *target = &storage_of_person.field_value_of_first_name[size_t(record_id) - 1];
289 if (target != value)
290 std::copy_n(value, size, target);
291 for (size_t i = 0; i < size; i++)
292 remove_index_of_person_by_name(record_id + i);
293 for (size_t i = 0; i < size; i++)
294 add_index_of_person_by_name(record_id + i);
295 }
296
298 (
299 Record_Id record_id,
300 const std::string& field_value_of_last_name
301 )
302 {
304 storage_of_person.field_value_of_last_name[size_t(record_id) - 1] = field_value_of_last_name;
307 }
308
310 (
311 Record_Id record_id,
312 size_t size,
313 const std::string *value
314 )
315 {
316 for (size_t i = 0; i < size; i++)
318 std::string *target = &storage_of_person.field_value_of_last_name[size_t(record_id) - 1];
319 if (target != value)
320 std::copy_n(value, size, target);
321 for (size_t i = 0; i < size; i++)
322 remove_index_of_person_by_name(record_id + i);
323 for (size_t i = 0; i < size; i++)
324 add_index_of_person_by_name(record_id + i);
325 }
326
328 (
329 Record_Id record_id,
330 id_of_city field_value_of_home
331 )
332 {
334 storage_of_person.field_value_of_home[size_t(record_id) - 1] = field_value_of_home;
335 }
336
338 (
339 Record_Id record_id,
340 size_t size,
341 const id_of_city *value
342 )
343 {
344 for (size_t i = 0; i < size; i++)
346 id_of_city *target = &storage_of_person.field_value_of_home[size_t(record_id) - 1];
347 if (target != value)
348 std::copy_n(value, size, target);
349 }
350
351
352 void delete_from(Table_Id table_id, Record_Id record_id) final
353 {
354 if (table_id == Table_Id(1))
355 internal_delete_city(record_id);
356 else if (table_id == Table_Id(2))
357 internal_delete_person(record_id);
358 }
359
360 void insert_into(Table_Id table_id, Record_Id record_id) final
361 {
362 if (size_t(record_id) <= 0 || (max_record_id && size_t(record_id) > max_record_id))
363 throw_exception("insert_into: too big");
364 if (table_id == Table_Id(1))
365 {
366 if (is_valid_record_id_for_city(record_id))
367 throw_exception("Duplicate insert into table city");
368 if (storage_of_city.size() < size_t(record_id))
369 storage_of_city.resize(size_t(record_id));
370 internal_insert_city(record_id);
371 }
372 else if (table_id == Table_Id(2))
373 {
374 if (is_valid_record_id_for_person(record_id))
375 throw_exception("Duplicate insert into table person");
376 if (storage_of_person.size() < size_t(record_id))
377 storage_of_person.resize(size_t(record_id));
378 internal_insert_person(record_id);
379 }
380 }
381
382
384 (
385 Table_Id table_id,
386 Record_Id record_id,
387 size_t size
388 ) final
389 {
390 if
391 (
392 size_t(record_id) <= 0 ||
393 (max_record_id && (size_t(record_id) > max_record_id || size > max_record_id))
394 )
395 {
396 throw_exception("insert_vector: null record_id, or too big");
397 }
398 if (table_id == Table_Id(1))
399 {
400 if (storage_of_city.size() < size_t(record_id) + size - 1)
401 storage_of_city.resize(size_t(record_id) + size - 1);
402 internal_vector_insert_city(record_id, size);
403 }
404 else if (table_id == Table_Id(2))
405 {
406 if (storage_of_person.size() < size_t(record_id) + size - 1)
407 storage_of_person.resize(size_t(record_id) + size - 1);
408 internal_vector_insert_person(record_id, size);
409 }
410 }
411
413 (
414 Table_Id table_id,
415 Record_Id record_id,
416 Field_Id field_id,
417 const std::string& value
418 )
419 final
420 {
421 if (table_id == Table_Id(1))
422 {
423 if (field_id == Field_Id(1))
424 {
425 internal_update_city__name(record_id, value);
426 return;
427 }
428 return;
429 }
430 if (table_id == Table_Id(2))
431 {
432 if (field_id == Field_Id(1))
433 {
434 internal_update_person__first_name(record_id, value);
435 return;
436 }
437 if (field_id == Field_Id(2))
438 {
439 internal_update_person__last_name(record_id, value);
440 return;
441 }
442 return;
443 }
444 }
445
447 (
448 Table_Id table_id,
449 Record_Id record_id,
450 Field_Id field_id,
451 joedb::Record_Id value
452 )
453 final
454 {
455 if (table_id == Table_Id(2))
456 {
457 if (field_id == Field_Id(3))
458 {
459 internal_update_person__home(record_id, id_of_city(value));
460 return;
461 }
462 return;
463 }
464 }
465
467 (
468 Table_Id table_id,
469 Record_Id record_id,
470 Field_Id field_id,
471 size_t size,
472 const std::string *value
473 )
474 final
475 {
476 if (table_id == Table_Id(1))
477 {
478 if (field_id == Field_Id(1))
479 {
480 internal_update_vector_city__name(record_id, size, value);
481 return;
482 }
483 return;
484 }
485 if (table_id == Table_Id(2))
486 {
487 if (field_id == Field_Id(1))
488 {
489 internal_update_vector_person__first_name(record_id, size, value);
490 return;
491 }
492 if (field_id == Field_Id(2))
493 {
494 internal_update_vector_person__last_name(record_id, size, value);
495 return;
496 }
497 return;
498 }
499 }
500
502 (
503 Table_Id table_id,
504 Record_Id record_id,
505 Field_Id field_id,
506 size_t size,
507 const joedb::Record_Id *value
508 )
509 final
510 {
511 if (table_id == Table_Id(2))
512 {
513 if (field_id == Field_Id(3))
514 {
515 internal_update_vector_person__home(record_id, size, reinterpret_cast<const id_of_city*>(value));
516 return;
517 }
518 return;
519 }
520 }
521
523 (
524 Table_Id table_id,
525 Record_Id record_id,
526 Field_Id field_id,
527 size_t &capacity
528 )
529 final
530 {
531 if (table_id == Table_Id(1))
532 {
533 capacity = size_t(storage_of_city.freedom_keeper.size());
534 if (field_id == Field_Id(1))
535 {
536 return (storage_of_city.field_value_of_name.data() + size_t(record_id) - 1);
537 }
538 return nullptr;
539 }
540 if (table_id == Table_Id(2))
541 {
542 capacity = size_t(storage_of_person.freedom_keeper.size());
543 if (field_id == Field_Id(1))
544 {
545 return (storage_of_person.field_value_of_first_name.data() + size_t(record_id) - 1);
546 }
547 if (field_id == Field_Id(2))
548 {
549 return (storage_of_person.field_value_of_last_name.data() + size_t(record_id) - 1);
550 }
551 return nullptr;
552 }
553 return nullptr;
554 }
555
557 (
558 Table_Id table_id,
559 Record_Id record_id,
560 Field_Id field_id,
561 size_t &capacity
562 )
563 final
564 {
565 if (table_id == Table_Id(2))
566 {
567 capacity = size_t(storage_of_person.freedom_keeper.size());
568 if (field_id == Field_Id(3))
569 {
570 return reinterpret_cast<Record_Id *>(storage_of_person.field_value_of_home.data() + size_t(record_id) - 1);
571 }
572 return nullptr;
573 }
574 return nullptr;
575 }
576
577 void comment(const std::string &comment) override {}
578 void timestamp(int64_t timestamp) override {}
579 void valid_data() final {}
580
581 bool upgrading_schema = false;
584
586 {
587 return schema_file.get_data().size() < detail::schema_string_size;
588 }
589
591 {
592 constexpr size_t pos = size_t(joedb::Writable_Journal::header_size);
593 const size_t schema_file_size = schema_file.get_data().size();
594
595 if
596 (
597 schema_file_size < pos ||
598 schema_file_size > detail::schema_string_size ||
599 std::memcmp
600 (
601 schema_file.get_data().data() + pos,
602 detail::schema_string + pos,
603 schema_file_size - pos
604 ) != 0
605 )
606 {
607 throw_exception("Trying to open a file with incompatible schema");
608 }
609 }
610
611 void create_table(const std::string &name) override
612 {
616 }
617
618 void drop_table(Table_Id table_id) final
619 {
620 schema_journal.drop_table(table_id);
622 }
623
625 (
626 Table_Id table_id,
627 const std::string &name
628 ) final
629 {
630 schema_journal.rename_table(table_id, name);
632 }
633
635 (
636 Table_Id table_id,
637 const std::string &name,
638 joedb::Type type
639 ) override
640 {
641 schema_journal.add_field(table_id, name, type);
643 }
644
645 void drop_field(Table_Id table_id, Field_Id field_id) final
646 {
647 schema_journal.drop_field(table_id, field_id);
649 }
650
652 (
653 Table_Id table_id,
654 Field_Id field_id,
655 const std::string &name
656 ) final
657 {
658 schema_journal.rename_field(table_id, field_id, name);
660 }
661
662 void custom(const std::string &name) override
663 {
666 }
667
668 public:
673
674 int64_t get_schema_checkpoint() const
675 {
677 }
678
680 {
681 max_record_id = size_t(journal.get_checkpoint_position());
682 journal.replay_log(*this);
683 max_record_id = 0;
684
685 check_schema();
686
688 throw_exception<joedb::Out_Of_Date>("Schema is out of date. Can't upgrade a read-only database.");
689 }
690
692
694 {
695 return id_of_city
696 (
697 Record_Id(storage_of_city.freedom_keeper.get_next(id.get_id() + 1) - 1)
698 );
699 }
700
702 {
703 return id_of_city
704 (
705 Record_Id(storage_of_city.freedom_keeper.get_previous(id.get_id() + 1) - 1)
706 );
707 }
708
709 template<class Comparator>
710 std::vector<id_of_city> sorted_city(Comparator comparator) const;
711
713 {
714 return id_of_city();
715 }
716
717 const std::string& get_name(id_of_city record) const
718 {
720 return (const std::string&)(storage_of_city.field_value_of_name[record.get_id() - 1]);
721 }
722
724
726 {
727 return id_of_person
728 (
729 Record_Id(storage_of_person.freedom_keeper.get_next(id.get_id() + 1) - 1)
730 );
731 }
732
734 {
735 return id_of_person
736 (
737 Record_Id(storage_of_person.freedom_keeper.get_previous(id.get_id() + 1) - 1)
738 );
739 }
740
741 template<class Comparator>
742 std::vector<id_of_person> sorted_person(Comparator comparator) const;
743
745 {
746 return id_of_person();
747 }
748
749 const std::string& get_first_name(id_of_person record) const
750 {
752 return (const std::string&)(storage_of_person.field_value_of_first_name[record.get_id() - 1]);
753 }
754
755 const std::string& get_last_name(id_of_person record) const
756 {
758 return (const std::string&)(storage_of_person.field_value_of_last_name[record.get_id() - 1]);
759 }
760
762 {
764 return (id_of_city)(storage_of_person.field_value_of_home[record.get_id() - 1]);
765 }
766
767 const std::map<std::string, id_of_city> &get_index_of_city_by_name()
768 {
770 }
771
772 const std::multimap<std::tuple<std::string, std::string>, id_of_person> &get_index_of_person_by_name()
773 {
775 }
776
778 {
779 JOEDB_ASSERT(is_valid_record_id_for_city(id.get_record_id()));
780 auto iterator = storage_of_city.iterator_over_city_by_name[id.get_id() - 1];
781 ++iterator;
782 if (iterator != index_of_city_by_name.end())
783 return iterator->second;
784 else
785 return id_of_city();
786 }
788 {
789 JOEDB_ASSERT(is_valid_record_id_for_city(id.get_record_id()));
790 auto iterator = storage_of_city.iterator_over_city_by_name[id.get_id() - 1];
791 if (iterator != index_of_city_by_name.begin())
792 return (--iterator)->second;
793 else
794 return id_of_city();
795 }
796 id_of_city find_city_by_name(const std::string& field_value_of_name) const
797 {
798 const auto i = index_of_city_by_name.find(std::string(field_value_of_name));
799 if (i == index_of_city_by_name.end())
800 return id_of_city();
801 else
802 return i->second;
803 }
804 range_of_person_by_name find_person_by_name(const std::string& field_value_of_last_name, const std::string& field_value_of_first_name) const;
805 };
806 /// returned by @ref Database::get_city_table
808 {
809 friend class Database;
810
811 private:
812 const Database &db;
813 container_of_city(const Database &db): db(db) {}
814
815 public:
817 {
818 friend class container_of_city;
819 private:
821 size_t index;
822 iterator(const detail::data_of_city &data): fk(&data.freedom_keeper), index(0) {}
823 public:
824 typedef std::forward_iterator_tag iterator_category;
826 typedef std::ptrdiff_t difference_type;
829
830 bool operator==(const iterator &i) const {return index == i.index;}
831 bool operator!=(const iterator &i) const {return index != i.index;}
832 iterator &operator++() {index = fk->get_next(index); return *this;}
833 iterator operator++(int) {auto copy = *this; index = fk->get_next(index); return copy;}
834 iterator &operator--() {index = fk->get_previous(index); return *this;}
835 iterator operator--(int) {auto copy = *this; index = fk->get_previous(index); return copy;}
836 id_of_city operator*() const {return id_of_city(Record_Id(index - 1));}
837 };
838
839 iterator begin() const {return ++iterator(db.storage_of_city);}
840 iterator end() const {return iterator(db.storage_of_city);}
841 bool is_empty() const {return db.storage_of_city.freedom_keeper.is_empty();}
842 size_t get_size() const {return db.storage_of_city.freedom_keeper.get_used_count();}
843 static id_of_city get_at(size_t i) {return id_of_city(Record_Id(i));}
844 bool is_valid_at(size_t i) {return db.storage_of_city.freedom_keeper.is_used(i + 1);}
845 id_of_city first() const {return *begin();}
846 id_of_city last() const {return *--end();}
847 id_of_city get_end() const {return *end();}
848 };
849
851 {
852 return container_of_city(*this);
853 }
854
855 template<class Comparator>
856 std::vector<id_of_city> Database::sorted_city(Comparator comparator) const
857 {
858 std::vector<id_of_city> result;
859 for (auto x: get_city_table())
860 result.emplace_back(x);
861 std::sort(result.begin(), result.end(), comparator);
862 return result;
863 }
864 /// returned by @ref Database::get_person_table
866 {
867 friend class Database;
868
869 private:
870 const Database &db;
871 container_of_person(const Database &db): db(db) {}
872
873 public:
875 {
877 private:
879 size_t index;
880 iterator(const detail::data_of_person &data): fk(&data.freedom_keeper), index(0) {}
881 public:
882 typedef std::forward_iterator_tag iterator_category;
884 typedef std::ptrdiff_t difference_type;
887
888 bool operator==(const iterator &i) const {return index == i.index;}
889 bool operator!=(const iterator &i) const {return index != i.index;}
890 iterator &operator++() {index = fk->get_next(index); return *this;}
891 iterator operator++(int) {auto copy = *this; index = fk->get_next(index); return copy;}
892 iterator &operator--() {index = fk->get_previous(index); return *this;}
893 iterator operator--(int) {auto copy = *this; index = fk->get_previous(index); return copy;}
894 id_of_person operator*() const {return id_of_person(Record_Id(index - 1));}
895 };
896
897 iterator begin() const {return ++iterator(db.storage_of_person);}
899 bool is_empty() const {return db.storage_of_person.freedom_keeper.is_empty();}
900 size_t get_size() const {return db.storage_of_person.freedom_keeper.get_used_count();}
901 static id_of_person get_at(size_t i) {return id_of_person(Record_Id(i));}
902 bool is_valid_at(size_t i) {return db.storage_of_person.freedom_keeper.is_used(i + 1);}
903 id_of_person first() const {return *begin();}
904 id_of_person last() const {return *--end();}
905 id_of_person get_end() const {return *end();}
906 };
907
909 {
910 return container_of_person(*this);
911 }
912
913 template<class Comparator>
914 std::vector<id_of_person> Database::sorted_person(Comparator comparator) const
915 {
916 std::vector<id_of_person> result;
917 for (auto x: get_person_table())
918 result.emplace_back(x);
919 std::sort(result.begin(), result.end(), comparator);
920 return result;
921 }
922 /// returned by @ref Database::find_person_by_name
924 {
925 friend class Database;
926 private:
927 std::pair<std::multimap<std::tuple<std::string, std::string>, id_of_person>::const_iterator, std::multimap<std::tuple<std::string, std::string>, id_of_person>::const_iterator> range;
928 range_of_person_by_name(const Database &db, const std::string& last_name, const std::string& first_name)
929 {
930 range = db.index_of_person_by_name.equal_range(std::tuple<std::string, std::string>(last_name, first_name));
931 }
932 public:
934 {
936 private:
937 std::multimap<std::tuple<std::string, std::string>, id_of_person>::const_iterator map_iterator;
938 iterator(std::multimap<std::tuple<std::string, std::string>, id_of_person>::const_iterator map_iterator): map_iterator(map_iterator) {}
939 public:
940 bool operator !=(const iterator &i) const
941 {
942 return map_iterator != i.map_iterator;
943 }
944 iterator &operator++() {map_iterator++; return *this;}
945 id_of_person operator*() const {return map_iterator->second;}
946 };
947 iterator begin() const {return range.first;}
948 iterator end() const {return range.second;}
949 bool empty() const {return range.first == range.second;}
950 size_t size() const {return size_t(std::distance(range.first, range.second));}
951 };
952
953 inline range_of_person_by_name Database::find_person_by_name(const std::string& field_value_of_last_name, const std::string& field_value_of_first_name) const
954 {
955 return range_of_person_by_name(*this, field_value_of_last_name, field_value_of_first_name);
956 }
957}
958
959#endif
size_t get_previous(size_t index) const
size_t get_next(size_t index) const
std::string & get_data()
Definition Memory_File.h:20
void replay_log(Writable &writable)
int64_t get_checkpoint_position() const
static constexpr int64_t header_size
void rename_field(Table_Id table_id, Field_Id field_id, const std::string &name) final
void create_table(const std::string &name) final
void drop_field(Table_Id table_id, Field_Id field_id) final
void custom(const std::string &name) final
void rename_table(Table_Id table_id, const std::string &name) final
void add_field(Table_Id table_id, const std::string &name, Type type) final
void drop_table(Table_Id table_id) final
void default_checkpoint()
Definition Writable.cpp:32
Store all the tables of the database.
Definition Database.h:101
void insert_into(Table_Id table_id, Record_Id record_id) final
Definition Database.h:360
void internal_update_vector_person__first_name(Record_Id record_id, size_t size, const std::string *value)
Definition Database.h:280
id_of_person previous(id_of_person id) const
Definition Database.h:733
bool is_valid(id_of_city id) const
Definition Database.h:124
const std::string & get_last_name(id_of_person record) const
Definition Database.h:755
void internal_update_vector_city__name(Record_Id record_id, size_t size, const std::string *value)
Definition Database.h:250
container_of_person get_person_table() const
Definition Database.h:908
friend class container_of_city
Definition Database.h:104
void delete_from(Table_Id table_id, Record_Id record_id) final
Definition Database.h:352
void internal_insert_person(Record_Id record_id)
Definition Database.h:220
const std::string & get_first_name(id_of_person record) const
Definition Database.h:749
friend class id_of_city
Definition Database.h:103
void custom(const std::string &name) override
Definition Database.h:662
Table_Id current_table_id
Definition Database.h:117
const std::map< std::string, id_of_city > & get_index_of_city_by_name()
Definition Database.h:767
void update_vector_string(Table_Id table_id, Record_Id record_id, Field_Id field_id, size_t size, const std::string *value) final
Definition Database.h:467
friend class container_of_person
Definition Database.h:106
void create_table(const std::string &name) override
Definition Database.h:611
void internal_update_vector_person__home(Record_Id record_id, size_t size, const id_of_city *value)
Definition Database.h:338
void add_index_of_person_by_name(Record_Id record_id)
Definition Database.h:174
void remove_index_of_person_by_name(Record_Id record_id)
Definition Database.h:165
friend class id_of_person
Definition Database.h:105
range_of_person_by_name find_person_by_name(const std::string &field_value_of_last_name, const std::string &field_value_of_first_name) const
Definition Database.h:953
std::map< std::string, id_of_city > index_of_city_by_name
Definition Database.h:133
detail::data_of_city storage_of_city
Definition Database.h:128
void rename_field(Table_Id table_id, Field_Id field_id, const std::string &name) final
Definition Database.h:652
void set_max_record_id(size_t record_id)
Definition Database.h:119
void add_field(Table_Id table_id, const std::string &name, joedb::Type type) override
Definition Database.h:635
void add_index_of_city_by_name(Record_Id record_id)
Definition Database.h:143
id_of_city find_city_by_name(const std::string &field_value_of_name) const
Definition Database.h:796
friend class range_of_person_by_name
Definition Database.h:107
detail::data_of_person storage_of_person
Definition Database.h:130
void internal_update_vector_person__last_name(Record_Id record_id, size_t size, const std::string *value)
Definition Database.h:310
void comment(const std::string &comment) override
Definition Database.h:577
void timestamp(int64_t timestamp) override
Definition Database.h:578
int64_t get_schema_checkpoint() const
Definition Database.h:674
void drop_field(Table_Id table_id, Field_Id field_id) final
Definition Database.h:645
id_of_city get_home(id_of_person record) const
Definition Database.h:761
const std::string & get_name(id_of_city record) const
Definition Database.h:717
void internal_update_person__home(Record_Id record_id, id_of_city field_value_of_home)
Definition Database.h:328
void valid_data() final
Definition Database.h:579
bool is_valid_record_id_for_city(Record_Id record_id) const
Definition Database.h:129
joedb::Record_Id * get_own_reference_storage(Table_Id table_id, Record_Id record_id, Field_Id field_id, size_t &capacity) final
Definition Database.h:557
static void throw_exception(const std::string &message)
Definition Database.h:111
std::vector< id_of_city > sorted_city(Comparator comparator) const
Definition Database.h:856
joedb::Memory_File schema_file
Definition Database.h:582
void rename_table(Table_Id table_id, const std::string &name) final
Definition Database.h:625
bool is_valid_record_id_for_person(Record_Id record_id) const
Definition Database.h:131
static id_of_person null_person()
Definition Database.h:744
void insert_vector(Table_Id table_id, Record_Id record_id, size_t size) final
Definition Database.h:384
void internal_update_person__first_name(Record_Id record_id, const std::string &field_value_of_first_name)
Definition Database.h:268
void update_vector_reference(Table_Id table_id, Record_Id record_id, Field_Id field_id, size_t size, const joedb::Record_Id *value) final
Definition Database.h:502
void internal_update_person__last_name(Record_Id record_id, const std::string &field_value_of_last_name)
Definition Database.h:298
void drop_table(Table_Id table_id) final
Definition Database.h:618
void internal_insert_city(Record_Id record_id)
Definition Database.h:204
container_of_city get_city_table() const
Definition Database.h:850
void internal_update_city__name(Record_Id record_id, const std::string &field_value_of_name)
Definition Database.h:238
bool is_valid(id_of_person id) const
Definition Database.h:125
void internal_delete_person(Record_Id record_id)
Definition Database.h:194
std::string * get_own_string_storage(Table_Id table_id, Record_Id record_id, Field_Id field_id, size_t &capacity) final
Definition Database.h:523
id_of_city next(id_of_city id) const
Definition Database.h:693
std::vector< id_of_person > sorted_person(Comparator comparator) const
Definition Database.h:914
void internal_delete_city(Record_Id record_id)
Definition Database.h:187
void initialize_with_readonly_journal(joedb::Readonly_Journal &journal)
Definition Database.h:679
void remove_index_of_city_by_name(Record_Id record_id)
Definition Database.h:134
joedb::Writable_Journal schema_journal
Definition Database.h:583
void internal_vector_insert_city(Record_Id record_id, size_t size)
Definition Database.h:210
bool requires_schema_upgrade() const
Definition Database.h:585
id_of_city previous(id_of_city id) const
Definition Database.h:701
void update_string(Table_Id table_id, Record_Id record_id, Field_Id field_id, const std::string &value) final
Definition Database.h:413
id_of_person next(id_of_person id) const
Definition Database.h:725
static id_of_city null_city()
Definition Database.h:712
void update_reference(Table_Id table_id, Record_Id record_id, Field_Id field_id, joedb::Record_Id value) final
Definition Database.h:447
id_of_city next_city_by_name(id_of_city id)
Definition Database.h:777
void internal_vector_insert_person(Record_Id record_id, size_t size)
Definition Database.h:226
id_of_city previous_city_by_name(id_of_city id)
Definition Database.h:787
std::multimap< std::tuple< std::string, std::string >, id_of_person > index_of_person_by_name
Definition Database.h:164
const std::multimap< std::tuple< std::string, std::string >, id_of_person > & get_index_of_person_by_name()
Definition Database.h:772
Implement the joedb::Readable interface for a compiled database.
Definition Readable.h:27
bool operator==(const iterator &i) const
Definition Database.h:830
bool operator!=(const iterator &i) const
Definition Database.h:831
std::forward_iterator_tag iterator_category
Definition Database.h:824
returned by Database::get_city_table
Definition Database.h:808
size_t get_size() const
Definition Database.h:842
bool is_valid_at(size_t i)
Definition Database.h:844
iterator begin() const
Definition Database.h:839
iterator end() const
Definition Database.h:840
id_of_city get_end() const
Definition Database.h:847
id_of_city first() const
Definition Database.h:845
id_of_city last() const
Definition Database.h:846
static id_of_city get_at(size_t i)
Definition Database.h:843
bool operator==(const iterator &i) const
Definition Database.h:888
std::forward_iterator_tag iterator_category
Definition Database.h:882
bool operator!=(const iterator &i) const
Definition Database.h:889
returned by Database::get_person_table
Definition Database.h:866
id_of_person first() const
Definition Database.h:903
id_of_person last() const
Definition Database.h:904
id_of_person get_end() const
Definition Database.h:905
static id_of_person get_at(size_t i)
Definition Database.h:901
Strongly-typed wrapper around an integer representing a row of the city table.
Definition ids.h:25
constexpr Record_Id get_record_id() const
Definition ids.h:36
constexpr size_t get_id() const
Definition ids.h:35
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 size_t get_id() const
Definition ids.h:58
bool operator!=(const iterator &i) const
Definition Database.h:940
returned by Database::find_person_by_name
Definition Database.h:924
#define JOEDB_ASSERT(x)
Definition assert.h:18
void write_string(std::ostream &out, const std::string &s, bool json)
constexpr const char * get_version()
Definition get_version.h:6
Automatically generated by joedbc.
Definition Client.h:19