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 joedb_db_multi_server_Database_declared
13#define joedb_db_multi_server_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
39{
40 /// @namespace joedb::db::multi_server
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 = 81;
52 }
53 class container_of_server;
54
55 namespace detail
56 {
57 struct data_of_server
58 {
59 std::vector<std::string> field_value_of_file_name;
60 std::vector<int32_t> field_value_of_port;
61 std::vector<int32_t> field_value_of_timeout;
62 std::vector<std::map<int32_t, id_of_server>::iterator> iterator_over_server_by_port;
63
64 joedb::Compact_Freedom_Keeper freedom_keeper;
65
66 size_t size() const {return freedom_keeper.size();}
67
68 void resize(size_t new_size)
69 {
70 field_value_of_file_name.resize(new_size);
71 field_value_of_port.resize(new_size);
72 field_value_of_timeout.resize(new_size);
73 iterator_over_server_by_port.resize(new_size);
74 freedom_keeper.resize(new_size);
75 }
76 };
77 }
78
79
80 /// Store all the tables of the database
82 {
83 friend class Readable;
84 friend class id_of_server;
85 friend class container_of_server;
86
87 public:
88 template<typename E = joedb::Exception>
89 static void throw_exception(const std::string &message)
90 {
91 throw E("joedb::db::multi_server: " + message);
92 }
93
96
97 void set_max_record_id(size_t record_id)
98 {
99 max_record_id = record_id;
100 }
101
102 bool is_valid(id_of_server id) const {return is_valid_record_id_for_server(id.get_record_id());}
103
104 protected:
105 detail::data_of_server storage_of_server;
106 bool is_valid_record_id_for_server(Record_Id record_id) const {return storage_of_server.freedom_keeper.is_used(size_t(record_id) + 1);}
107
108 std::map<int32_t, id_of_server> index_of_server_by_port;
109 void remove_index_of_server_by_port(Record_Id record_id)
110 {
111 auto &iterator = storage_of_server.iterator_over_server_by_port[size_t(record_id) - 1];
112 if (iterator != index_of_server_by_port.end())
113 {
114 index_of_server_by_port.erase(iterator);
115 iterator = index_of_server_by_port.end();
116 }
117 }
118 void add_index_of_server_by_port(Record_Id record_id)
119 {
120 auto result = index_of_server_by_port.insert
121 (
122 std::map<int32_t, id_of_server>::value_type
123 (
124 int32_t(storage_of_server.field_value_of_port[size_t(record_id) - 1]),
125 id_of_server(record_id)
126 )
127 );
128 if (!result.second)
129 {
130 std::ostringstream out;
131 out << "server_by_port unique index failure: (";
132 joedb::write_int32(out, storage_of_server.field_value_of_port[size_t(record_id) - 1]);
133 out << ") at id = " << record_id << ' ';
134 out << "was already at id = " << result.first->second.get_id();
135 throw_exception(out.str());
136 }
137 storage_of_server.iterator_over_server_by_port[size_t(record_id) - 1] = result.first;
138 }
139
140 void internal_delete_server(Record_Id record_id)
141 {
144 storage_of_server.field_value_of_file_name[size_t(record_id) - 1].clear();
145 storage_of_server.field_value_of_port[size_t(record_id) - 1] = 0;
146 storage_of_server.field_value_of_timeout[size_t(record_id) - 1] = 0;
147 storage_of_server.freedom_keeper.free(size_t(record_id) + 1);
148 }
149
150 void internal_insert_server(Record_Id record_id)
151 {
152 storage_of_server.iterator_over_server_by_port[size_t(record_id) - 1] = index_of_server_by_port.end();
153 storage_of_server.freedom_keeper.use(size_t(record_id) + 1);
154 }
155
156 void internal_vector_insert_server(Record_Id record_id, size_t size)
157 {
158 storage_of_server.freedom_keeper.use_vector(size_t(record_id) + 1, size);
159 std::fill_n
160 (
161 &storage_of_server.iterator_over_server_by_port[size_t(record_id) - 1],
162 size,
164 );
165 }
166
168 (
169 Record_Id record_id,
170 const std::string& field_value_of_file_name
171 )
172 {
174 storage_of_server.field_value_of_file_name[size_t(record_id) - 1] = field_value_of_file_name;
175 }
176
178 (
179 Record_Id record_id,
180 size_t size,
181 const std::string *value
182 )
183 {
184 for (size_t i = 0; i < size; i++)
186 std::string *target = &storage_of_server.field_value_of_file_name[size_t(record_id) - 1];
187 if (target != value)
188 std::copy_n(value, size, target);
189 }
190
192 (
193 Record_Id record_id,
194 int32_t field_value_of_port
195 )
196 {
198 storage_of_server.field_value_of_port[size_t(record_id) - 1] = field_value_of_port;
201 }
202
204 (
205 Record_Id record_id,
206 size_t size,
207 const int32_t *value
208 )
209 {
210 for (size_t i = 0; i < size; i++)
212 int32_t *target = &storage_of_server.field_value_of_port[size_t(record_id) - 1];
213 if (target != value)
214 std::copy_n(value, size, target);
215 for (size_t i = 0; i < size; i++)
216 remove_index_of_server_by_port(record_id + i);
217 for (size_t i = 0; i < size; i++)
218 add_index_of_server_by_port(record_id + i);
219 }
220
222 (
223 Record_Id record_id,
224 int32_t field_value_of_timeout
225 )
226 {
228 storage_of_server.field_value_of_timeout[size_t(record_id) - 1] = field_value_of_timeout;
229 }
230
232 (
233 Record_Id record_id,
234 size_t size,
235 const int32_t *value
236 )
237 {
238 for (size_t i = 0; i < size; i++)
240 int32_t *target = &storage_of_server.field_value_of_timeout[size_t(record_id) - 1];
241 if (target != value)
242 std::copy_n(value, size, target);
243 }
244
245
246 void delete_from(Table_Id table_id, Record_Id record_id) final
247 {
248 if (table_id == Table_Id(1))
249 internal_delete_server(record_id);
250 }
251
252 void insert_into(Table_Id table_id, Record_Id record_id) final
253 {
254 if (size_t(record_id) <= 0 || (max_record_id && size_t(record_id) > max_record_id))
255 throw_exception("insert_into: too big");
256 if (table_id == Table_Id(1))
257 {
258 if (is_valid_record_id_for_server(record_id))
259 throw_exception("Duplicate insert into table server");
260 if (storage_of_server.size() < size_t(record_id))
261 storage_of_server.resize(size_t(record_id));
262 internal_insert_server(record_id);
263 }
264 }
265
266
268 (
269 Table_Id table_id,
270 Record_Id record_id,
271 size_t size
272 ) final
273 {
274 if
275 (
276 size_t(record_id) <= 0 ||
277 (max_record_id && (size_t(record_id) > max_record_id || size > max_record_id))
278 )
279 {
280 throw_exception("insert_vector: null record_id, or too big");
281 }
282 if (table_id == Table_Id(1))
283 {
284 if (storage_of_server.size() < size_t(record_id) + size - 1)
285 storage_of_server.resize(size_t(record_id) + size - 1);
286 internal_vector_insert_server(record_id, size);
287 }
288 }
289
291 (
292 Table_Id table_id,
293 Record_Id record_id,
294 Field_Id field_id,
295 const std::string& value
296 )
297 final
298 {
299 if (table_id == Table_Id(1))
300 {
301 if (field_id == Field_Id(1))
302 {
303 internal_update_server__file_name(record_id, value);
304 return;
305 }
306 return;
307 }
308 }
309
311 (
312 Table_Id table_id,
313 Record_Id record_id,
314 Field_Id field_id,
315 int32_t value
316 )
317 final
318 {
319 if (table_id == Table_Id(1))
320 {
321 if (field_id == Field_Id(2))
322 {
323 internal_update_server__port(record_id, value);
324 return;
325 }
326 if (field_id == Field_Id(3))
327 {
328 internal_update_server__timeout(record_id, value);
329 return;
330 }
331 return;
332 }
333 }
334
336 (
337 Table_Id table_id,
338 Record_Id record_id,
339 Field_Id field_id,
340 size_t size,
341 const std::string *value
342 )
343 final
344 {
345 if (table_id == Table_Id(1))
346 {
347 if (field_id == Field_Id(1))
348 {
349 internal_update_vector_server__file_name(record_id, size, value);
350 return;
351 }
352 return;
353 }
354 }
355
357 (
358 Table_Id table_id,
359 Record_Id record_id,
360 Field_Id field_id,
361 size_t size,
362 const int32_t *value
363 )
364 final
365 {
366 if (table_id == Table_Id(1))
367 {
368 if (field_id == Field_Id(2))
369 {
370 internal_update_vector_server__port(record_id, size, value);
371 return;
372 }
373 if (field_id == Field_Id(3))
374 {
375 internal_update_vector_server__timeout(record_id, size, value);
376 return;
377 }
378 return;
379 }
380 }
381
383 (
384 Table_Id table_id,
385 Record_Id record_id,
386 Field_Id field_id,
387 size_t &capacity
388 )
389 final
390 {
391 if (table_id == Table_Id(1))
392 {
393 capacity = size_t(storage_of_server.freedom_keeper.size());
394 if (field_id == Field_Id(1))
395 {
396 return (storage_of_server.field_value_of_file_name.data() + size_t(record_id) - 1);
397 }
398 return nullptr;
399 }
400 return nullptr;
401 }
402
404 (
405 Table_Id table_id,
406 Record_Id record_id,
407 Field_Id field_id,
408 size_t &capacity
409 )
410 final
411 {
412 if (table_id == Table_Id(1))
413 {
414 capacity = size_t(storage_of_server.freedom_keeper.size());
415 if (field_id == Field_Id(2))
416 {
417 return (storage_of_server.field_value_of_port.data() + size_t(record_id) - 1);
418 }
419 if (field_id == Field_Id(3))
420 {
421 return (storage_of_server.field_value_of_timeout.data() + size_t(record_id) - 1);
422 }
423 return nullptr;
424 }
425 return nullptr;
426 }
427
428 void comment(const std::string &comment) override {}
429 void timestamp(int64_t timestamp) override {}
430 void valid_data() final {}
431
432 bool upgrading_schema = false;
435
437 {
438 return schema_file.get_data().size() < detail::schema_string_size;
439 }
440
442 {
443 constexpr size_t pos = size_t(joedb::Writable_Journal::header_size);
444 const size_t schema_file_size = schema_file.get_data().size();
445
446 if
447 (
448 schema_file_size < pos ||
449 schema_file_size > detail::schema_string_size ||
450 std::memcmp
451 (
452 schema_file.get_data().data() + pos,
453 detail::schema_string + pos,
454 schema_file_size - pos
455 ) != 0
456 )
457 {
458 throw_exception("Trying to open a file with incompatible schema");
459 }
460 }
461
462 void create_table(const std::string &name) override
463 {
467 }
468
469 void drop_table(Table_Id table_id) final
470 {
471 schema_journal.drop_table(table_id);
473 }
474
476 (
477 Table_Id table_id,
478 const std::string &name
479 ) final
480 {
481 schema_journal.rename_table(table_id, name);
483 }
484
486 (
487 Table_Id table_id,
488 const std::string &name,
489 joedb::Type type
490 ) override
491 {
492 schema_journal.add_field(table_id, name, type);
494 }
495
496 void drop_field(Table_Id table_id, Field_Id field_id) final
497 {
498 schema_journal.drop_field(table_id, field_id);
500 }
501
503 (
504 Table_Id table_id,
505 Field_Id field_id,
506 const std::string &name
507 ) final
508 {
509 schema_journal.rename_field(table_id, field_id, name);
511 }
512
513 void custom(const std::string &name) override
514 {
517 }
518
519 public:
524
525 int64_t get_schema_checkpoint() const
526 {
528 }
529
531 {
532 max_record_id = size_t(journal.get_checkpoint_position());
533 journal.replay_log(*this);
534 max_record_id = 0;
535
536 check_schema();
537
539 throw_exception<joedb::Out_Of_Date>("Schema is out of date. Can't upgrade a read-only database.");
540 }
541
543
545 {
546 return id_of_server
547 (
548 Record_Id(storage_of_server.freedom_keeper.get_next(id.get_id() + 1) - 1)
549 );
550 }
551
553 {
554 return id_of_server
555 (
556 Record_Id(storage_of_server.freedom_keeper.get_previous(id.get_id() + 1) - 1)
557 );
558 }
559
560 template<class Comparator>
561 std::vector<id_of_server> sorted_server(Comparator comparator) const;
562
564 {
565 return id_of_server();
566 }
567
568 const std::string& get_file_name(id_of_server record) const
569 {
571 return (const std::string&)(storage_of_server.field_value_of_file_name[record.get_id() - 1]);
572 }
573
574 int32_t get_port(id_of_server record) const
575 {
577 return (int32_t)(storage_of_server.field_value_of_port[record.get_id() - 1]);
578 }
579
580 int32_t get_timeout(id_of_server record) const
581 {
583 return (int32_t)(storage_of_server.field_value_of_timeout[record.get_id() - 1]);
584 }
585
586 const std::map<int32_t, id_of_server> &get_index_of_server_by_port()
587 {
589 }
590
592 {
593 JOEDB_ASSERT(is_valid_record_id_for_server(id.get_record_id()));
594 auto iterator = storage_of_server.iterator_over_server_by_port[id.get_id() - 1];
595 ++iterator;
596 if (iterator != index_of_server_by_port.end())
597 return iterator->second;
598 else
599 return id_of_server();
600 }
602 {
603 JOEDB_ASSERT(is_valid_record_id_for_server(id.get_record_id()));
604 auto iterator = storage_of_server.iterator_over_server_by_port[id.get_id() - 1];
605 if (iterator != index_of_server_by_port.begin())
606 return (--iterator)->second;
607 else
608 return id_of_server();
609 }
610 id_of_server find_server_by_port(int32_t field_value_of_port) const
611 {
612 const auto i = index_of_server_by_port.find(int32_t(field_value_of_port));
613 if (i == index_of_server_by_port.end())
614 return id_of_server();
615 else
616 return i->second;
617 }
618 };
619 /// returned by @ref Database::get_server_table
621 {
622 friend class Database;
623
624 private:
625 const Database &db;
626 container_of_server(const Database &db): db(db) {}
627
628 public:
630 {
632 private:
634 size_t index;
635 iterator(const detail::data_of_server &data): fk(&data.freedom_keeper), index(0) {}
636 public:
637 typedef std::forward_iterator_tag iterator_category;
639 typedef std::ptrdiff_t difference_type;
642
643 bool operator==(const iterator &i) const {return index == i.index;}
644 bool operator!=(const iterator &i) const {return index != i.index;}
645 iterator &operator++() {index = fk->get_next(index); return *this;}
646 iterator operator++(int) {auto copy = *this; index = fk->get_next(index); return copy;}
647 iterator &operator--() {index = fk->get_previous(index); return *this;}
648 iterator operator--(int) {auto copy = *this; index = fk->get_previous(index); return copy;}
649 id_of_server operator*() const {return id_of_server(Record_Id(index - 1));}
650 };
651
652 iterator begin() const {return ++iterator(db.storage_of_server);}
654 bool is_empty() const {return db.storage_of_server.freedom_keeper.is_empty();}
655 size_t get_size() const {return db.storage_of_server.freedom_keeper.get_used_count();}
656 static id_of_server get_at(size_t i) {return id_of_server(Record_Id(i));}
657 bool is_valid_at(size_t i) {return db.storage_of_server.freedom_keeper.is_used(i + 1);}
658 id_of_server first() const {return *begin();}
659 id_of_server last() const {return *--end();}
660 id_of_server get_end() const {return *end();}
661 };
662
664 {
665 return container_of_server(*this);
666 }
667
668 template<class Comparator>
669 std::vector<id_of_server> Database::sorted_server(Comparator comparator) const
670 {
671 std::vector<id_of_server> result;
672 for (auto x: get_server_table())
673 result.emplace_back(x);
674 std::sort(result.begin(), result.end(), comparator);
675 return result;
676 }
677}
678
679#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:82
void comment(const std::string &comment) override
Definition Database.h:428
void create_table(const std::string &name) override
Definition Database.h:462
void delete_from(Table_Id table_id, Record_Id record_id) final
Definition Database.h:246
void set_max_record_id(size_t record_id)
Definition Database.h:97
void update_vector_int32(Table_Id table_id, Record_Id record_id, Field_Id field_id, size_t size, const int32_t *value) final
Definition Database.h:357
void insert_vector(Table_Id table_id, Record_Id record_id, size_t size) final
Definition Database.h:268
void internal_update_vector_server__timeout(Record_Id record_id, size_t size, const int32_t *value)
Definition Database.h:232
const std::map< int32_t, id_of_server > & get_index_of_server_by_port()
Definition Database.h:586
static id_of_server null_server()
Definition Database.h:563
void drop_table(Table_Id table_id) final
Definition Database.h:469
bool is_valid(id_of_server id) const
Definition Database.h:102
void rename_field(Table_Id table_id, Field_Id field_id, const std::string &name) final
Definition Database.h:503
joedb::Memory_File schema_file
Definition Database.h:433
int64_t get_schema_checkpoint() const
Definition Database.h:525
void internal_update_server__port(Record_Id record_id, int32_t field_value_of_port)
Definition Database.h:192
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:383
void update_string(Table_Id table_id, Record_Id record_id, Field_Id field_id, const std::string &value) final
Definition Database.h:291
void remove_index_of_server_by_port(Record_Id record_id)
Definition Database.h:109
void internal_update_server__timeout(Record_Id record_id, int32_t field_value_of_timeout)
Definition Database.h:222
std::vector< id_of_server > sorted_server(Comparator comparator) const
Definition Database.h:669
void drop_field(Table_Id table_id, Field_Id field_id) final
Definition Database.h:496
container_of_server get_server_table() const
Definition Database.h:663
int32_t * get_own_int32_storage(Table_Id table_id, Record_Id record_id, Field_Id field_id, size_t &capacity) final
Definition Database.h:404
void custom(const std::string &name) override
Definition Database.h:513
void insert_into(Table_Id table_id, Record_Id record_id) final
Definition Database.h:252
int32_t get_timeout(id_of_server record) const
Definition Database.h:580
void add_index_of_server_by_port(Record_Id record_id)
Definition Database.h:118
void internal_insert_server(Record_Id record_id)
Definition Database.h:150
void internal_delete_server(Record_Id record_id)
Definition Database.h:140
int32_t get_port(id_of_server record) const
Definition Database.h:574
const std::string & get_file_name(id_of_server record) const
Definition Database.h:568
void timestamp(int64_t timestamp) override
Definition Database.h:429
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:336
void update_int32(Table_Id table_id, Record_Id record_id, Field_Id field_id, int32_t value) final
Definition Database.h:311
void internal_update_server__file_name(Record_Id record_id, const std::string &field_value_of_file_name)
Definition Database.h:168
id_of_server find_server_by_port(int32_t field_value_of_port) const
Definition Database.h:610
void rename_table(Table_Id table_id, const std::string &name) final
Definition Database.h:476
void add_field(Table_Id table_id, const std::string &name, joedb::Type type) override
Definition Database.h:486
joedb::Writable_Journal schema_journal
Definition Database.h:434
id_of_server next_server_by_port(id_of_server id)
Definition Database.h:591
id_of_server previous_server_by_port(id_of_server id)
Definition Database.h:601
void internal_update_vector_server__port(Record_Id record_id, size_t size, const int32_t *value)
Definition Database.h:204
id_of_server next(id_of_server id) const
Definition Database.h:544
void initialize_with_readonly_journal(joedb::Readonly_Journal &journal)
Definition Database.h:530
detail::data_of_server storage_of_server
Definition Database.h:105
void internal_vector_insert_server(Record_Id record_id, size_t size)
Definition Database.h:156
std::map< int32_t, id_of_server > index_of_server_by_port
Definition Database.h:108
bool is_valid_record_id_for_server(Record_Id record_id) const
Definition Database.h:106
void internal_update_vector_server__file_name(Record_Id record_id, size_t size, const std::string *value)
Definition Database.h:178
id_of_server previous(id_of_server id) const
Definition Database.h:552
static void throw_exception(const std::string &message)
Definition Database.h:89
Implement the joedb::Readable interface for a compiled database.
Definition Readable.h:27
returned by Database::get_server_table
Definition Database.h:621
static id_of_server get_at(size_t i)
Definition Database.h:656
Strongly-typed wrapper around an integer representing a row of the server 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
#define JOEDB_ASSERT(x)
Definition assert.h:18
void write_int32(std::ostream &out, int32_t value)
Definition type_io.h:75
Automatically generated by joedbc.
Definition Client.h:19
constexpr const char * get_version()
Definition get_version.h:6