24 auto tables =
db.get_tables();
29#include "joedb/journal/Writable_Journal.h"
30#include "joedb/journal/Memory_File.h"
31#include "joedb/error/Out_Of_Date.h"
46 extern const char * schema_string;
47 inline constexpr size_t schema_string_size = )RRR";
49 out << options.schema_file.get_size() << ";\n }\n\n";
51 for (
const auto &[tid, tname]: tables)
52 out <<
" class container_of_" << tname <<
";\n";
56 class Database_Writable: public Database, public joedb::Writable
59 joedb::index_t max_record_id;
60 Table_Id current_table_id = Table_Id{0};
67 out <<
" void delete_from(Table_Id table_id, Record_Id record_id) override\n";
71 for (
const auto &[tid, tname]: tables)
79 out <<
"if (table_id == Table_Id(" << tid <<
"))\n";
80 out <<
" internal_delete_" << tname <<
"(record_id);\n";
89 out <<
" void insert_into(Table_Id table_id, Record_Id record_id) override\n";
91 out <<
" if (to_underlying(record_id) < 0 || (max_record_id && to_underlying(record_id) >= max_record_id))\n";
92 out <<
" throw_exception(\"insert_into: too big\");\n";
95 for (
const auto &[tid, tname]: tables)
103 out <<
"if (table_id == Table_Id(" << tid <<
"))\n";
105 out <<
" if (is_valid_record_id_for_" << tname <<
"(record_id))\n";
106 out <<
" throw_exception(\"Duplicate insert into table " << tname <<
"\");\n";
107 out <<
" if (storage_of_" << tname <<
".size() <= size_t(record_id))\n";
108 out <<
" storage_of_" << tname <<
".resize(to_underlying(record_id) + 1);\n";
109 out <<
" internal_insert_" << tname <<
"(record_id);\n";
126 joedb::Freedom_Keeper *fk = nullptr;
132 for (
const auto &[tid, tname]: tables)
140 out <<
"if (table_id == Table_Id(" << tid <<
"))\n";
141 out <<
" fk = &storage_of_" << tname <<
".freedom_keeper;\n";
148 JOEDB_RELEASE_ASSERT(fk->is_used_vector(record_id, size));
149 joedb::Writable::delete_vector(table_id, record_id, size);
162 to_underlying(record_id) < 0 ||
163 (max_record_id && (to_underlying(record_id) >= max_record_id || joedb::index_t(size) >= max_record_id))
166 throw_exception("insert_vector: null record_id, or too big");
172 for (
const auto &[tid, tname]: tables)
180 out <<
"if (table_id == Table_Id(" << tid <<
"))\n";
182 out <<
" if (storage_of_" << tname <<
".size() < size_t(record_id) + size)\n";
183 out <<
" storage_of_" << tname <<
".resize(to_underlying(record_id) + size);\n";
184 out <<
" internal_vector_insert_" << tname <<
"(record_id, size);\n";
193 std::set<Type::Type_Id> db_types;
195 for (
const auto &[tid, tname]: tables)
196 for (
const auto &[fid, fname]:
db.get_fields(tid))
197 db_types.insert(
db.get_field_type(tid, fid).get_type_id());
203 for (
int type_index = 1; type_index < int(
Type::type_ids); type_index++)
206 if (db_types.find(type_id) == db_types.end())
212 out <<
" Table_Id table_id,\n";
213 out <<
" Record_Id record_id,\n";
214 out <<
" Field_Id field_id,\n";
217 out <<
" override\n";
220 for (
const auto &[tid, tname]: tables)
224 out <<
" if (table_id == Table_Id(" << tid <<
"))\n";
227 for (
const auto &[fid, fname]:
db.get_fields(tid))
229 const Type &type =
db.get_field_type(tid, fid);
232 out <<
" if (field_id == Field_Id(" << fid <<
"))\n";
234 out <<
" internal_update_" << tname;
235 out <<
"__" << fname <<
"(record_id, ";
262 for (
int type_index = 1; type_index < int(
Type::type_ids); type_index++)
271 out <<
" Table_Id table_id,\n";
272 out <<
" Record_Id record_id,\n";
273 out <<
" Field_Id field_id,\n";
274 out <<
" size_t size,\n";
277 out <<
" override\n";
280 for (
const auto &[tid, tname]: tables)
284 out <<
" if (table_id == Table_Id(" << tid <<
"))\n";
287 for (
const auto &[fid, fname]:
db.get_fields(tid))
289 const Type &type =
db.get_field_type(tid, fid);
292 out <<
" if (field_id == Field_Id(" << fid <<
"))\n";
294 out <<
" internal_update_vector_" << tname;
295 out <<
"__" << fname <<
"(record_id, size, ";
301 out <<
"reinterpret_cast<const ";
325 for (
int type_index = 1; type_index < int(
Type::type_ids); type_index++)
335 out <<
" Table_Id table_id,\n";
336 out <<
" Record_Id record_id,\n";
337 out <<
" Field_Id field_id,\n";
338 out <<
" size_t &capacity\n";
340 out <<
" override\n";
343 for (
const auto &[tid, tname]: tables)
347 out <<
" if (table_id == Table_Id(" << tid <<
"))\n";
349 out <<
" capacity = size_t(storage_of_" << tname <<
".freedom_keeper.size());\n";
351 for (
const auto &[fid, fname]:
db.get_fields(tid))
353 const Type &type =
db.get_field_type(tid, fid);
356 out <<
" if (field_id == Field_Id(" << fid <<
"))\n"
361 out <<
"reinterpret_cast<Record_Id *>";
363 out <<
"(storage_of_" << tname;
364 out <<
".field_value_of_" << fname <<
".data() + to_underlying(record_id));\n"
369 out <<
" return nullptr;\n";
374 out <<
" return nullptr;\n";
383 void comment(const std::string &comment) override {}
384 void timestamp(int64_t timestamp) override {}
385 void valid_data() override {}
392 bool upgrading_schema = false;
393 joedb::Memory_File schema_file;
394 joedb::Writable_Journal schema_journal;
396 bool requires_schema_upgrade() const
398 return schema_file.get_data().size() < detail::schema_string_size;
403 constexpr size_t pos = joedb::Header::size;
404 const size_t schema_file_size = schema_file.get_data().size();
408 schema_file_size < pos ||
409 schema_file_size > detail::schema_string_size ||
412 detail::schema_string + pos,
413 schema_file.get_data().data() + pos,
414 schema_file_size - pos
418 throw_exception("Trying to open a file with incompatible schema");
422 void create_table(const std::string &name) override
425 schema_journal.create_table(name);
426 schema_journal.soft_checkpoint();
429 void drop_table(Table_Id table_id) override
431 schema_journal.drop_table(table_id);
432 schema_journal.soft_checkpoint();
438 const std::string &name
441 schema_journal.rename_table(table_id, name);
442 schema_journal.soft_checkpoint();
448 const std::string &name,
452 schema_journal.add_field(table_id, name, type);
453 schema_journal.soft_checkpoint();
456 void drop_field(Table_Id table_id, Field_Id field_id) override
458 schema_journal.drop_field(table_id, field_id);
459 schema_journal.soft_checkpoint();
466 const std::string &name
469 schema_journal.rename_field(table_id, field_id, name);
470 schema_journal.soft_checkpoint();
473 void custom(const std::string &name) override
475 schema_journal.custom(name);
476 schema_journal.soft_checkpoint();
487 schema_journal(schema_file)
490 void set_max_record_id(joedb::index_t record_id)
492 max_record_id = record_id;
495 int64_t get_schema_checkpoint() const
497 return schema_journal.get_checkpoint();
500 void initialize_with_readonly_journal(joedb::Readonly_Journal &journal)
502 max_record_id = journal.get_checkpoint();
503 journal.replay_log(*this);
508 if (requires_schema_upgrade())
509 throw_exception<joedb::Out_Of_Date>("Schema is out of date. Can't upgrade a read-only database.");
Table_Id get_table_id() const
Type_Id get_type_id() const
Database_Writable_h(const Compiler_Options &options)
void write(std::ostream &out) override
static const char * get_storage_type_string(Type type)
static const char * get_type_string(Type type)
static const char * get_cpp_type_string(Type type)
const Compiler_Options & options
bool table_has_field_type(Table_Id table_id, Type::Type_Id type_id) const
Generator(std::string dir_name, std::string file_name, const Compiler_Options &options)
void write_type(std::ostream &out, Type type, bool return_type, bool setter_type)
void namespace_open(std::ostream &out, const std::vector< std::string > &n)
void namespace_close(std::ostream &out, const std::vector< std::string > &n)
void namespace_include_guard_open(std::ostream &out, const char *name, const std::vector< std::string > &n)
void namespace_include_guard_close(std::ostream &out)
One code generator for each of the file generated by joedbc.