Joedb 9.6.2
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
Writable_Database_cpp.cpp
Go to the documentation of this file.
3#include "joedb/ui/type_io.h"
5
6namespace joedb::generator
7{
8 ////////////////////////////////////////////////////////////////////////////
10 ////////////////////////////////////////////////////////////////////////////
11 (
12 const Compiler_Options &options
13 ):
14 Generator(".", "Writable_Database.cpp", options)
15 {
16 }
17
18 ////////////////////////////////////////////////////////////////////////////
20 ////////////////////////////////////////////////////////////////////////////
21 {
22 const auto &db = options.get_db();
23 const auto &tables = db.get_tables();
24
25 out << "#include \"Writable_Database.h\"\n";
26 out << "#include \"joedb/journal/Readonly_Memory_File.h\"\n";
27 out << '\n';
28 out << "#include <ctime>\n\n";
29
31
32 out << R"RRR(
33 ////////////////////////////////////////////////////////////////////////////
34 void Writable_Database::write_comment(const std::string &comment)
35 ////////////////////////////////////////////////////////////////////////////
36 {
37 journal.comment(comment);
38 }
39
40 ////////////////////////////////////////////////////////////////////////////
41 void Writable_Database::write_timestamp()
42 ////////////////////////////////////////////////////////////////////////////
43 {
44 journal.timestamp(std::time(nullptr));
45 }
46
47 ////////////////////////////////////////////////////////////////////////////
48 void Writable_Database::write_timestamp(int64_t timestamp)
49 ////////////////////////////////////////////////////////////////////////////
50 {
51 journal.timestamp(timestamp);
52 }
53
54 ////////////////////////////////////////////////////////////////////////////
55 void Writable_Database::write_valid_data()
56 ////////////////////////////////////////////////////////////////////////////
57 {
58 journal.valid_data();
59 }
60
61 ////////////////////////////////////////////////////////////////////////////
62 void Writable_Database::play_journal()
63 ////////////////////////////////////////////////////////////////////////////
64 {
65 max_record_id = size_t(journal.get_checkpoint());
66 ready_to_write = false;
67 journal.play_until_checkpoint(*this);
68 ready_to_write = true;
69 max_record_id = 0;
70 }
71
72 ////////////////////////////////////////////////////////////////////////////
73 void Writable_Database::auto_upgrade()
74 ////////////////////////////////////////////////////////////////////////////
75 {
76 const size_t file_schema_size = size_t(schema_file.get_size());
77
78 if (file_schema_size < detail::schema_string_size)
79 {
80 journal.comment("Automatic schema upgrade");
81
82 joedb::Readonly_Memory_File schema_file(detail::schema_string, detail::schema_string_size);
83 joedb::Readonly_Journal schema_journal(schema_file);
84
85 schema_journal.skip_directly_to(int64_t(file_schema_size));
86 schema_journal.raw_play_until(journal, detail::schema_string_size);
87
88 schema_journal.skip_directly_to(int64_t(file_schema_size));
89 upgrading_schema = true;
90 schema_journal.raw_play_until(*this, detail::schema_string_size);
91 upgrading_schema = false;
92
93 journal.valid_data();
94 journal.soft_checkpoint();
95 }
96 }
97
98 ////////////////////////////////////////////////////////////////////////////
99 void Writable_Database::initialize()
100 ////////////////////////////////////////////////////////////////////////////
101 {
102 play_journal();
103 check_schema();
104 auto_upgrade();
105 check_single_row();
106 }
107
108 ////////////////////////////////////////////////////////////////////////////
109 Writable_Database::Writable_Database
110 ////////////////////////////////////////////////////////////////////////////
111 (
112 joedb::Buffered_File &file,
113 joedb::Construction_Flags flags,
114 bool perform_initialization
115 ):
116 journal(joedb::Journal_Construction_Lock(file, flags))
117 {
118 journal.rewind();
119
120 if (perform_initialization)
121 initialize();
122 }
123
124 ////////////////////////////////////////////////////////////////////////////
125 Writable_Database::Writable_Database(joedb::Buffered_File &file):
126 ////////////////////////////////////////////////////////////////////////////
127 Writable_Database(file, joedb::Construction_Flags::none, true)
128 {
129 }
130
131 ////////////////////////////////////////////////////////////////////////////
132 Writable_Database::Writable_Database
133 ////////////////////////////////////////////////////////////////////////////
134 (
135 joedb::Buffered_File &file,
136 joedb::Construction_Flags flags
137 ):
138 Writable_Database(file, flags, true)
139 {
140 }
141
142 ////////////////////////////////////////////////////////////////////////////
143 void Writable_Database::check_single_row()
144 ////////////////////////////////////////////////////////////////////////////
145 {
146)RRR";
147
148 for (const auto &[tid, tname]: tables)
149 {
151 {
152 out << " {\n";
153 out << " const auto table = get_" << tname << "_table();\n";
154 out << " if (table.first() != the_" <<tname << "() || table.last() != the_" << tname << "())\n";
155 out << " throw joedb::Exception(\"Single-row constraint failure for table " << tname << "\");\n";
156 out << " }\n";
157 }
158 }
159 out << " }\n";
160
162 {
163 out << R"RRR(
164 ////////////////////////////////////////////////////////////////////////////
165 void Writable_Database::create_table(const std::string &name)
166 ////////////////////////////////////////////////////////////////////////////
167 {
168 Database_Writable::create_table(name);
169
170 if (upgrading_schema)
171 {
172 )RRR";
173
174 for (const auto &[tid, tname]: tables)
175 {
177 {
178 out << " if (current_table_id == Table_Id{" << tid << "})\n";
179 out << " new_" << tname << "();\n";
180 }
181 }
182
183 out << " }\n }\n";
184 }
185
186 if (db_has_values())
187 {
188 out << R"RRR(
189 ////////////////////////////////////////////////////////////////////////////
190 void Writable_Database::add_field
191 ////////////////////////////////////////////////////////////////////////////
192 (
193 Table_Id table_id,
194 const std::string &name,
195 joedb::Type type
196 )
197 {
198 Database_Writable::add_field(table_id, name, type);
199 )RRR";
200
201 for (const auto &[tid, tname]: tables)
202 {
203 if (db.get_freedom(tid).get_used_count() > Record_Id{0})
204 {
205 const Record_Id record_id{db.get_freedom(tid).get_first_used()};
206
207 out << "\n if (table_id == Table_Id{" << tid << "})\n";
208 out << " {\n";
209 out << " const auto field_id = ++storage_of_" << tname << ".current_field_id;\n";
210 out << " if (upgrading_schema)\n";
211 out << " {\n";
212
213 for (const auto &[fid, fname]: db.get_fields(tid))
214 {
215 out << " if (field_id == Field_Id{" << fid << "})\n";
216 out << " {\n";
217 out << " for (const auto record: get_" << tname << "_table())\n";
218 out << " set_" << fname << "(record, ";
219
220 const auto &type = db.get_field_type(tid, fid);
221 const bool reference = type.get_type_id() == joedb::Type::Type_Id::reference;
222
223 if (reference)
224 {
225 const auto it = tables.find(type.get_table_id());
226 if (it != tables.end())
227 out << "id_of_" << it->second;
228 out << "(";
229 }
230
231 joedb::write_value(out, db, tid, record_id, fid);
232
233 if (reference)
234 out << ")";
235
236 out <<");\n";
237 out << " }\n";
238 }
239
240 out << " }\n";
241 out << " }\n";
242 }
243 }
244 out << " }\n";
245 }
246
247 for (const auto &[tid, tname]: tables)
248 {
249 const bool single_row = options.get_table_options(tid).single_row;
250
251 if (!single_row)
252 {
253 out << '\n';
254 out << " /////////////////////////////////////////////////////////////////////////////\n";
255 out << " void Writable_Database::clear_" << tname << "_table()\n";
256 out << " /////////////////////////////////////////////////////////////////////////////\n";
257 out << " {\n";
258 out << " while (!get_" << tname << "_table().is_empty())\n";
259 out << " delete_" << tname << "(get_" << tname << "_table().last());\n";
260 out << " }\n";
261 }
262 }
263
265 }
266}
const std::vector< std::string > & get_name_space() const
const Table_Options & get_table_options(Table_Id table_id) const
const Database & get_db() const
const std::map< Table_Id, std::string > & get_tables() const override
const Compiler_Options & options
Definition Generator.h:14
Writable_Database_cpp(const Compiler_Options &options)
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 write_value(std::ostream &out, const Readable &readable, Table_Id table_id, Record_Id record_id, Field_Id field_id)
One code generator for each of the file generated by joedbc.
Definition Client_h.cpp:5