14 if (
file.is_readonly())
15 throw Exception(
"Cannot create Writable_Journal with read-only file");
16 else if (lock.size == 0)
19 header.checkpoint.fill(Header::size);
20 header.version = format_version;
21 header.signature = Header::joedb;
22 file_buffer.File_Iterator::write(reinterpret_cast<const char *>(&header), Header::size);
24 else if (lock.size > 0)
28 lock.size > checkpoint_position &&
29 lock.recovery != Recovery::overwrite
34 "Checkpoint (" + std::to_string(checkpoint_position) +
35 ") is smaller than file size (" + std::to_string(lock.size) +
36 "). This file may contain an aborted transaction. "
37 "'joedb_push file.joedb file fixed.joedb' can be used to truncate it."
43 for (
size_t i = 0; i < lock.header.checkpoint.size(); ++i)
45 if (
neg(lock.header.checkpoint[i]) > lock.size)
51 reinterpret_cast<const char *
>(&fixed),
53 int64_t(
sizeof(fixed)) * i
92 throw Exception(
"writing must start at checkpoint position");
100 throw Exception(
"end_writing position is not matching file position");
123 reinterpret_cast<const char *
>(&soft),
197 const std::string &name
210 const std::string &name,
241 const std::string &name
352 void Writable_Journal::generic_update
358 operation_t operation
363 table_id == table_of_last_operation &&
364 record_id == record_of_last_operation
368 int(operation_t::update_last_int8) -
369 int(operation_t::update_int8);
371 file_buffer.write<operation_t>(operation_t(
int(operation) + last));
373 field_of_last_update = field_id;
377 table_id == table_of_last_operation &&
378 record_id == record_of_last_operation + 1 &&
379 field_id == field_of_last_update
383 int(operation_t::update_next_int8) -
384 int(operation_t::update_int8);
385 file_buffer.write<operation_t>(operation_t(
int(operation) + next));
386 ++record_of_last_operation;
390 file_buffer.write<operation_t>(operation);
392 file_buffer.write_reference(record_id);
394 table_of_last_operation = table_id;
395 record_of_last_operation = record_id;
396 field_of_last_update = field_id;
401 #define TYPE_MACRO(type, return_type, type_id, R, write_method)\
402 void Writable_Journal::update_##type_id\
405 Record_Id record_id,\
410 generic_update(table_id, record_id, field_id, operation_t::update_##type_id);\
411 file_buffer.write_method(value);\
413 void Writable_Journal::update_vector_##type_id\
416 Record_Id record_id,\
422 file_buffer.write<operation_t>(operation_t::update_vector_##type_id);\
423 file_buffer.compact_write<>(to_underlying(table_id));\
424 file_buffer.write_reference(record_id);\
425 file_buffer.compact_write<>(to_underlying(field_id));\
426 file_buffer.compact_write<>(size);\
427 table_of_last_operation = table_id;\
428 record_of_last_operation = record_id;\
429 field_of_last_update = field_id;\
433 Type::Type_Id::type_id == Type::Type_Id::blob ||\
434 Type::Type_Id::type_id == Type::Type_Id::string ||\
435 Type::Type_Id::type_id == Type::Type_Id::reference\
438 for (size_t i = 0; i < size; i++)\
439 file_buffer.write_method(value[i]);\
442 file_buffer.write_data(reinterpret_cast<const char *>(value), size * sizeof(type));\
454 file_buffer.File_Iterator::write(data.data(), data.size());
455 return Blob(blob_position, int64_t(data.size()));
462 if (
file.is_shared())
465 pull_without_locking();
474 if (
file.is_shared())
486 offsetof(
Header, signature)
503 if (journal.get_position() > journal.get_checkpoint())
504 throw Exception(
"locking journal with uncheckpointed data (try rollback?)");
511 journal(other.journal)
513 other.journal =
nullptr;
static void warning(beman::cstring_view message) noexcept
Record_Id record_of_last_operation
friend class Writable_Journal
int64_t hard_checkpoint_position
int64_t checkpoint_position
Readonly_Journal(Journal_Construction_Lock &lock)
Table_Id table_of_last_operation
Tail_Exclusive_Lock(Writable_Journal &journal)
int64_t pull_from(const Readonly_Journal &journal, int64_t until)
void add_field(Table_Id table_id, const std::string &name, Type type) override
void delete_vector(Table_Id table_id, Record_Id record_id, size_t size) override
void delete_from(Table_Id table_id, Record_Id record_id) override
void valid_data() override
void soft_checkpoint() override
int64_t ahead_of_checkpoint() const noexcept
void insert_vector(Table_Id table_id, Record_Id record_id, size_t size) override
void soft_checkpoint_at(int64_t position)
void start_writing(int64_t position) override
int64_t get_position() const override
void custom(const std::string &name) override
void end_writing(int64_t position) override
~Writable_Journal() override
void create_table(const std::string &name) override
void rename_table(Table_Id table_id, const std::string &name) override
void hard_checkpoint() override
void drop_table(Table_Id table_id) override
void rename_field(Table_Id table_id, Field_Id field_id, const std::string &name) override
void insert_into(Table_Id table_id, Record_Id record_id) override
Blob write_blob(std::string_view data) override
void timestamp(int64_t timestamp) override
void drop_field(Table_Id table_id, Field_Id field_id) override
void hard_checkpoint_at(int64_t position)
void comment(const std::string &comment) override
#define JOEDB_DEBUG_ASSERT(x)
assertion tested in debug mode
constexpr index_t to_underlying(Record_Id id)