Joedb 10.3.0
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
joedbc.cpp
Go to the documentation of this file.
2#include "joedb/get_version.h"
3#include "joedb/Multiplexer.h"
11
20
30
34
38
43
44#include <iostream>
45#include <filesystem>
46#include <regex>
47
48namespace joedb
49{
50 ////////////////////////////////////////////////////////////////////////////
52 ////////////////////////////////////////////////////////////////////////////
53 {
54 private:
55 std::vector<std::string> &names;
56
57 public:
58 explicit Custom_Collector(std::vector<std::string> &names): names(names)
59 {
60 }
61
62 void custom(const std::string &name) override
63 {
64 if (!is_identifier(name))
65 throw Exception("custom: invalid identifier");
66 names.emplace_back(name);
67 }
68 };
69
70 ////////////////////////////////////////////////////////////////////////////
71 static void compile
72 ////////////////////////////////////////////////////////////////////////////
73 (
74 Compiler_Options &options,
75 Compiler_Options *parent_options
76 )
77 {
78 const std::string joedbi_file_name = options.base_name + ".joedbi";
79 const std::string joedbc_file_name = options.base_name + ".joedbc";
80
81 //
82 // Read file.joedbi
83 //
84 joedb::ifstream joedbi_file(joedbi_file_name, Open_Mode::read_existing);
85
86 {
87 Writable_Journal journal(options.schema_file);
88 Selective_Writable schema_writable(journal, Selective_Writable::schema);
89 Custom_Collector custom_collector(options.custom_names);
90
91 Multiplexer multiplexer{options.db, schema_writable, custom_collector};
92 Interpreter interpreter(options.db, multiplexer, Record_Id::null);
93 interpreter.set_echo(false);
94 interpreter.set_rethrow(true);
95 interpreter.main_loop(joedbi_file, std::cerr);
96 multiplexer.soft_checkpoint();
97 }
98
99 for (const auto &[tid, tname]: options.db.get_tables())
100 options.table_options[tid];
101
102 //
103 // Read file.joedbc
104 //
105 {
106 joedb::ifstream joedbc_file(joedbc_file_name, Open_Mode::read_existing);
107 parse_compiler_options(joedbc_file, options);
108 }
109
110 //
111 // Generate code
112 //
113 generator::Database_h(options).generate();
114 generator::Database_Writable_h(options).generate();
115 generator::Database_Writable_cpp(options).generate();
116 generator::Readonly_Database_h(options).generate();
117 generator::Types_h(options).generate();
118 generator::Readable_h(options).generate();
119
120 generator::readonly_h(options).generate();
121 generator::readonly_cpp(options).generate();
122
123 generator::Writable_Database_h(options).generate();
124 generator::Writable_Database_cpp(options).generate();
125 generator::File_Database_h(options).generate();
126 generator::Memory_Database_h(options).generate();
127 generator::Readonly_Interpreted_File_Database_h(options).generate();
128 generator::Interpreted_File_Database_h(options).generate();
129 generator::Multiplexer_h(options).generate();
130
131 generator::writable_h(options).generate();
132 generator::writable_cpp(options).generate();
133
134 generator::Client_h(options).generate();
135 generator::File_Client_h(options).generate();
136 generator::Readonly_Client_h(options).generate();
137
138 generator::ids_h(options, parent_options).generate();
139 generator::print_table_h(options).generate();
140
141 if (parent_options)
142 generator::Procedure_h(options, *parent_options).generate();
143 else
144 generator::Procedure_h(options, options).generate();
145
146 for (const auto &table: options.db.get_tables())
147 generator::introspection_h(options, table).generate();
148
149 //
150 // .gitignore
151 //
152 {
153 joedb::File file
154 (
155 options.output_path + "/" + options.get_name_space_back() + "/.gitignore",
157 );
158 file.pwrite("*\n", 2, 0);
159 }
160 }
161
162 ////////////////////////////////////////////////////////////////////////////
163 static int joedbc(Arguments &arguments)
164 ////////////////////////////////////////////////////////////////////////////
165 {
166 if (arguments.has_flag("version"))
167 {
168 std::cout << joedb::get_version();
169 std::cout << ", compiled " << __DATE__ " " __TIME__ "\n";
170 return 0;
171 }
172
173 const std::string_view base_name = arguments.get_next("<base_name>");
174
175 if (arguments.missing())
176 {
177 arguments.print_help(std::cerr);
178 std::cerr << "joedbc will read:\n";
179 std::cerr << " <base_name>.joedbi for the schema definition\n";
180 std::cerr << " <base_name>.joedbc for compiler options\n";
181 std::cerr << " <base_name>.rpc (optional) directory for RPC\n";
182 return 1;
183 }
184
185 Compiler_Options options;
186 options.exe_path = arguments[0];
187 options.output_path = ".";
188 options.base_name = std::string(base_name);
189
190 compile(options, nullptr);
191
192 //
193 // Generate code for procedure message schemas
194 //
195 {
196 std::error_code error_code;
197
198 std::filesystem::directory_iterator iterator
199 (
200 std::string(base_name) + ".rpc",
201 error_code
202 );
203
204 if (!error_code)
205 {
206 for (const auto &dir_entry: iterator)
207 {
208 if (dir_entry.path().extension() == ".joedbi")
209 {
210 auto path = dir_entry.path();
211 const std::string procedure_name = path.replace_extension("").string();
212
213 Compiler_Options procedure_options;
214 procedure_options.exe_path = arguments[0];
215 procedure_options.output_path = std::string(base_name) + "/rpc";
216 procedure_options.base_name = procedure_name;
217
218 compile(procedure_options, &options);
219 }
220 }
221 }
222 }
223
224 //
225 // Find list of procedures in Service.h
226 //
227 joedb::Memory_File memory_file;
228
229 try
230 {
231 joedb::File file
232 (
233 options.base_name + ".rpc/Service.h",
235 );
236 file.copy_to(memory_file);
237 }
238 catch (...)
239 {
240 }
241
242 if (memory_file.get_size())
243 {
244 std::filesystem::copy
245 (
246 options.base_name + ".rpc/Service.h",
247 options.base_name + "/rpc/Service.h",
248 std::filesystem::copy_options::overwrite_existing
249 );
250
251 const std::string &s = memory_file.get_data();
252
253 std::vector<generator::Procedure> procedures;
254
255 {
256 const std::regex pattern("void\\s+(\\w+)\\s*\\(\\s*(\\w+)\\s*::\\s*Writable_Database\\s*&\\s*\\w+\\s*\\)");
257
258 for
259 (
260 std::sregex_iterator i{s.begin(), s.end(), pattern};
261 i != std::sregex_iterator();
262 ++i
263 )
264 {
265 procedures.push_back({(*i)[1], (*i)[2]});
266 }
267 }
268
269 if (!procedures.empty())
270 {
271 generator::Procedures_h(options, procedures).generate();
272 generator::Signatures_h(options, procedures).generate();
273 generator::RPC_Client_h(options, procedures).generate();
274 }
275 }
276
277 return 0;
278 }
279}
280
281/////////////////////////////////////////////////////////////////////////////
282int main(int argc, char **argv)
283/////////////////////////////////////////////////////////////////////////////
284{
285 return joedb::main_wrapper(joedb::joedbc, argc, argv);
286}
void custom(const std::string &name) override
Definition joedbc.cpp:62
Custom_Collector(std::vector< std::string > &names)
Definition joedbc.cpp:58
Writable with empty insert_vector and delete_vector.
Definition Writable.h:120
std::string & get_data()
Definition Memory_File.h:23
int64_t get_size() const override
Get the size of the file, or -1 if it is unknown.
Definition Memory_File.h:27
static const Record_Id null
Definition index_types.h:44
int main()
void parse_compiler_options(std::istream &in, Compiler_Options &compiler_options)
bool is_identifier(const std::string &s)
constexpr const char * get_version()
Definition get_version.h:7
@ write_lock
like write_existing_or_create_new, but waits instead of failing if already locked
@ read_existing
fails if does not exist
int main_wrapper(int(*main)(Arguments &), int argc, char **argv)
Process command-line arguments and catch exceptions from main.
JOEDB_FILE File
Definition File.h:23