Joedb 10.4.3
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
Client_Command_Processor.cpp
Go to the documentation of this file.
7#include "joedb/ui/type_io.h"
12#include "joedb/Signal.h"
13
14namespace joedb
15{
16 ////////////////////////////////////////////////////////////////////////////
17 static std::chrono::milliseconds to_milliseconds(float seconds)
18 ////////////////////////////////////////////////////////////////////////////
19 {
20 return std::chrono::milliseconds(int64_t(seconds * 1000.0f));
21 }
22
23 ////////////////////////////////////////////////////////////////////////////
24 void Client_Command_Processor::write_prompt(std::ostream &out) const
25 ////////////////////////////////////////////////////////////////////////////
26 {
27 out << get_name() << '(';
28
29 const int64_t journal_checkpoint = client.get_journal_checkpoint();
30 const int64_t connection_checkpoint = client.get_connection_checkpoint();
31 const int64_t diff = connection_checkpoint - journal_checkpoint;
32
33 out << journal_checkpoint;
34 if (diff > 0)
35 out << '+' << diff << ")(pull to sync)";
36 else if (diff < 0)
37 {
38 out << diff << ')';
39
40 if (client.is_pullonly())
41 out << "(cannot push)";
42 else
43 out << "(push to sync)";
44 }
45 else
46 {
47 out << ')';
48 if (client.get_journal().get_position() > journal_checkpoint)
49 out << '*';
50 }
51 }
52
53 ////////////////////////////////////////////////////////////////////////////
55 ////////////////////////////////////////////////////////////////////////////
56 (
57 std::ostream &out,
58 std::chrono::milliseconds wait
59 )
60 {
61 const int64_t byte_count = client.pull(wait);
62 if (byte_count > 0)
63 {
64 out << "pulled " << byte_count << " bytes, checkpoint = ";
65 out << client.get_journal_checkpoint() << '\n';
66 }
67
68 return byte_count;
69 }
70
71 ////////////////////////////////////////////////////////////////////////////
72 int64_t Writable_Client_Command_Processor::pull
73 ////////////////////////////////////////////////////////////////////////////
74 (
75 std::ostream &out,
76 std::chrono::milliseconds wait
77 )
78 {
79 const int64_t byte_count = Client_Command_Processor::pull(out, wait);
80
81 if (byte_count == 0)
82 get_writable_client().touch();
83
84 return byte_count;
85 }
86
87 ////////////////////////////////////////////////////////////////////////////
88 bool Client_Command_Processor::sleep(float seconds, std::ostream &out)
89 ////////////////////////////////////////////////////////////////////////////
90 {
91 if (seconds > 0)
92 {
94 out << ". Sleeping for " << seconds << " seconds...\n";
95 out.flush();
96 return interruptible_sleep(to_milliseconds(seconds));
97 }
98
99 return Signal::get_signal() != SIGINT;
100 }
101
102 ////////////////////////////////////////////////////////////////////////////
104 ////////////////////////////////////////////////////////////////////////////
105 (
106 const std::string_view command,
107 std::istream &parameters,
108 std::istream &in,
109 std::ostream &out
110 )
111 {
112 if (command == "help") ////////////////////////////////////////////////////
113 {
114 Command_Interpreter::process_command(command, parameters, in, out);
115
116 out << R"RRR(Client
117~~~~~~
118 db
119 pull [<wait_seconds>]
120 pull_every [<wait_seconds>] [<sleep_seconds>]
121)RRR";
122 if (!client.is_pullonly())
123 out << " push\n push_every [<sleep_seconds>]\n";
124 out << '\n';
125
126 return Status::ok;
127 }
128 else if (command == "db") /////////////////////////////////////////////////
129 {
130 const Database *database = nullptr;
131
132 {
133 auto * const rdc = dynamic_cast<Readonly_Database_Client *>(&client);
134 auto * const wdc = dynamic_cast<Writable_Database_Client *>(&client);
135
136 if (rdc)
137 database = &rdc->get_database();
138 else if (wdc)
139 database = &wdc->get_database();
140 }
141
142 if (database)
143 {
144 Readable_Interpreter interpreter(*database);
145 interpreter.set_prompt_string("db");
146 run_interpreter(interpreter, in, out);
147 }
148 else
149 {
150 Command_Interpreter interpreter;
151 interpreter.set_prompt_string("db(blobs)");
152 run_interpreter(interpreter, in, out);
153 }
154 }
155 else if (command == "pull") ///////////////////////////////////////////////
156 {
157 float wait_seconds = 0;
158 parameters >> wait_seconds;
159 pull(out, to_milliseconds(wait_seconds));
160 }
161 else if (command == "pull_every") /////////////////////////////////////////
162 {
163 float wait_seconds = 1;
164 float sleep_seconds = 0;
165 parameters >> wait_seconds >> sleep_seconds;
166
168
169 do
170 pull(out, to_milliseconds(wait_seconds));
171 while (sleep(sleep_seconds, out));
172 }
173 else if (command == "push" && !client.is_pullonly()) //////////////////////
174 {
175 client.push_if_ahead();
176 }
177 else if (command == "push_every" && !client.is_pullonly()) ////////////////
178 {
179 float sleep_seconds = 1.0f;
180 parameters >> sleep_seconds;
181
183
184 do
185 client.push_if_ahead();
186 while (sleep(sleep_seconds, out));
187 }
188 else //////////////////////////////////////////////////////////////////////
189 return Command_Interpreter::process_command(command, parameters, in, out);
191 return Status::done;
192 }
193
194 ////////////////////////////////////////////////////////////////////////////
196 ////////////////////////////////////////////////////////////////////////////
197 (
198 const std::string_view command,
199 std::istream &parameters,
200 std::istream &in,
201 std::ostream &out
202 )
203 {
204 if (command == "help") ////////////////////////////////////////////////////
205 {
206 Client_Command_Processor::process_command(command, parameters, in, out);
207
208 out << R"RRR(Writable Client
209~~~~~~~~~~~~~~~
210 transaction
211 set_valid_data <true|false>
212 set_timestamp <true|false>
213 set_hard_checkpoint <true|false>
214
215)RRR";
216
217 return Status::ok;
218 }
219 else if (command == "transaction") ////////////////////////////////////////
220 {
221 auto * const wdc = dynamic_cast<Writable_Database_Client *>(&client);
222 auto * const wjc = dynamic_cast<Writable_Journal_Client *>(&client);
223
224 if (wdc)
225 {
226 wdc->transaction([&](const Readable &readable, Writable &writable)
227 {
228 Interpreter interpreter(readable, writable, Record_Id::null);
229 interpreter.set_prompt_string("transaction");
230 run_interpreter(interpreter, in, out);
231 });
232 }
233 else if (wjc)
234 {
235 wjc->transaction([&](Writable_Journal &journal)
236 {
237 Writable_Interpreter interpreter(journal);
238 interpreter.set_prompt_string("transaction(journal)");
239 run_interpreter(interpreter, in, out);
240 });
241 }
242 else
243 out << "Client is not writable, cannot run transaction\n";
244 }
245 else if (command == "set_valid_data") /////////////////////////////////////
246 {
247 get_writable_client().set_valid_data(read_boolean(parameters));
248 }
249 else if (command == "set_timestamp") //////////////////////////////////////
250 {
251 get_writable_client().set_timestamp(read_boolean(parameters));
252 }
253 else if (command == "set_hard_checkpoint") ////////////////////////////////
254 {
255 get_writable_client().set_hard_checkpoint(read_boolean(parameters));
256 }
257 else //////////////////////////////////////////////////////////////////////
258 return Client_Command_Processor::process_command(command, parameters, in, out);
259
260 return Status::done;
261 }
262}
virtual int64_t pull(std::ostream &out, std::chrono::milliseconds wait)
static bool sleep(float seconds, std::ostream &out)
void write_prompt(std::ostream &out) const override
Status process_command(std::string_view command, std::istream &parameters, std::istream &in, std::ostream &out) override
void set_prompt_string(std::string s)
Status process_command(std::string_view command, std::istream &parameters, std::istream &in, std::ostream &out) override
static const Record_Id null
Definition index_types.h:44
static int get_signal()
Definition Signal.cpp:27
static void start()
Definition Signal.cpp:34
Status process_command(std::string_view command, std::istream &parameters, std::istream &in, std::ostream &out) override
bool interruptible_sleep(std::chrono::milliseconds duration)
std::string get_time_string_of_now()
bool read_boolean(std::istream &in)
Definition type_io.cpp:215