Joedb 10.5.0
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
dump.cpp
Go to the documentation of this file.
1#include "joedb/ui/dump.h"
3#include "joedb/Writable.h"
4
6#include "joedb/Multiplexer.h"
8
9namespace joedb
10{
11 /////////////////////////////////////////////////////////////////////////////
12 void dump(const Readable &db, Writable &writable, bool schema_only)
13 /////////////////////////////////////////////////////////////////////////////
14 {
15 //
16 // Dump tables
17 //
18 std::map<Table_Id, Table_Id> table_map;
19 {
20 Table_Id mapped_tid = Table_Id(0);
21 for (const auto &[tid, tname]: db.get_tables())
22 {
23 ++mapped_tid;
24 table_map[tid] = mapped_tid;
25 writable.create_table(tname);
26 }
27 }
28
29 //
30 // Dump fields
31 //
32 std::map<Table_Id, std::map<Field_Id, Field_Id>> field_maps;
33 {
34 for (const auto &[tid, tname]: db.get_tables())
35 {
36 Field_Id mapped_fid = Field_Id(0);
37 for (const auto &[fid, fname]: db.get_fields(tid))
38 {
39 ++mapped_fid;
40 Type type = db.get_field_type(tid, fid);
42 type = Type::reference(table_map[type.get_table_id()]);
43 field_maps[tid][fid] = mapped_fid;
44
45 writable.add_field(table_map[tid], fname, type);
46 }
47 }
48 }
49
50 //
51 // Dump records
52 //
53 if (schema_only)
54 return;
55
56 for (const auto &[tid, tname]: db.get_tables())
57 {
58 const Record_Id table_size = db.get_size(tid);
59
60 for (Record_Id record_id{0}; record_id < table_size;)
61 {
62 while (record_id < table_size && !db.is_used(tid, record_id))
63 ++record_id;
64
65 size_t size = 0;
66
67 while
68 (
69 record_id + size < table_size &&
70 db.is_used(tid, record_id + size)
71 )
72 {
73 size++;
74 }
75
76 if (size)
77 {
78 writable.insert_vector(table_map[tid], record_id, size);
79 record_id = record_id + size;
80 }
81 }
82
83 for (const auto &[fid, fname]: db.get_fields(tid))
84 {
85 for (Record_Id record_id{0}; record_id < table_size; ++record_id)
86 {
87 if (db.is_used(tid, record_id))
88 {
89 Table_Id mapped_tid = table_map[tid];
90 Field_Id mapped_fid = field_maps[tid][fid];
91
92 switch (db.get_field_type(tid, fid).get_type_id())
93 {
95 break;
96
97 #define TYPE_MACRO(type, return_type, type_id, R, W)\
98 case Type::Type_Id::type_id:\
99 writable.update_##type_id\
100 (\
101 mapped_tid, record_id, mapped_fid, db.get_##type_id(tid, record_id, fid)\
102 );\
103 break;
104 #include "joedb/TYPE_MACRO.h"
105 }
106 }
107 }
108 }
109 }
110 }
111
112 /////////////////////////////////////////////////////////////////////////////
113 void dump_data(const Readable &db, Writable &writable)
114 /////////////////////////////////////////////////////////////////////////////
115 {
116 for (const auto &[tid, tname]: db.get_tables())
117 {
118 const Freedom_Keeper &freedom_keeper = db.get_freedom(tid);
119 const Record_Id table_size{freedom_keeper.get_size()};
120
121 for (Record_Id record_id{0}; record_id < table_size;)
122 {
123 while
124 (
125 record_id < table_size &&
126 !freedom_keeper.is_used(record_id)
127 )
128 {
129 ++record_id;
130 }
131
132 size_t size = 0;
133
134 while
135 (
136 record_id + size < table_size &&
137 freedom_keeper.is_used(record_id + size)
138 )
139 {
140 size++;
141 }
142
143 if (size > 1)
144 writable.insert_vector(tid, record_id, size);
145 else if (size == 1)
146 writable.insert_into(tid, record_id);
147
148 if (size > 0)
149 {
150 for (const auto &[fid, fname]: db.get_fields(tid))
151 {
152 switch(db.get_field_type(tid, fid).get_type_id())
153 {
155 break;
156
157 #define TYPE_MACRO(type, return_type, type_id, R, W)\
158 case Type::Type_Id::type_id:\
159 {\
160 const type &value = db.get_##type_id(tid, record_id, fid);\
161 if (size > 1)\
162 writable.update_vector_##type_id(tid, record_id, fid, size, &value);\
163 else\
164 writable.update_##type_id(tid, record_id, fid, value);\
165 }\
166 break;
167 #include "joedb/TYPE_MACRO.h"
168 }
169 }
170 }
171
172 record_id = record_id + size;
173 }
174 }
175 writable.soft_checkpoint();
176 }
177
178 /////////////////////////////////////////////////////////////////////////////
179 void pack(Readonly_Journal &input_journal, Writable &writable)
180 /////////////////////////////////////////////////////////////////////////////
181 {
182 Database db;
183
184 {
186 Multiplexer multiplexer{db, schema_filter};
187
188 input_journal.raw_play_until_checkpoint(multiplexer);
189
190 if (schema_filter.has_blobs())
191 throw Exception("can't pack blobs");
192 }
193
194 dump_data(db, writable);
195 }
196}
Record_Id get_size() const
bool is_used(Record_Id index) const
void raw_play_until_checkpoint(Writable &writable)
Table_Id get_table_id() const
Definition Type.h:42
Type_Id get_type_id() const
Definition Type.h:41
Superclass with all joedb journal event listeners as virtual functions.
Definition Writable.h:17
virtual void insert_vector(Table_Id table_id, Record_Id record_id, size_t size)=0
Definition Writable.cpp:33
virtual void insert_into(Table_Id table_id, Record_Id record_id)
Definition Writable.h:50
virtual void create_table(const std::string &name)
Definition Writable.h:26
virtual void soft_checkpoint()
Definition Writable.h:23
virtual void add_field(Table_Id table_id, const std::string &name, Type type)
Definition Writable.h:31
void pack(Readonly_Journal &input_journal, Writable &writable)
Definition dump.cpp:179
void dump_data(const Readable &db, Writable &writable)
Definition dump.cpp:113
void dump(const Readable &db, Writable &writable, bool schema_only)
Definition dump.cpp:12