YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
SubscriberOnSql.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <cstdlib>
8#include <cstdio>
9
10#include <sqlite3.h>
11
15
16#if !defined(_WIN32)
17#include <unistd.h>
18#else
19#include <io.h>
20#define access(f,a) _access(f,a)
21#endif
22
23#include <vector>
24#include <string>
25
26#ifndef F_OK
27#define F_OK 0
28#endif
29
30#define SQLDB(x) ((sqlite3*)(x))
31
32using namespace yarp::os;
33using namespace yarp::serversql::impl;
34
35namespace {
36YARP_SERVERSQL_LOG_COMPONENT(SUBSCRIBERONSQL, "yarp.serversql.impl.SubscriberOnSql")
37} // namespace
38
39
40bool SubscriberOnSql::open(const std::string& filename, bool fresh) {
41 sqlite3 *db = nullptr;
42 if (fresh) {
43 int result = access(filename.c_str(),F_OK);
44 if (result==0) {
45 yCWarning(SUBSCRIBERONSQL, "Database needs to be recreated.");
46 yCWarning(SUBSCRIBERONSQL, "Please move %s out of the way.", filename.c_str());
47 return false;
48 }
49
50 }
51 int result = sqlite3_open_v2(filename.c_str(),
52 &db,
54 nullptr);
55 if (result!=SQLITE_OK) {
56 yCError(SUBSCRIBERONSQL, "Failed to open database %s", filename.c_str());
57 if (db != nullptr) {
58 sqlite3_close(db);
59 }
60 return false;
61 }
62
63 const char *create_subscribe_table = "CREATE TABLE IF NOT EXISTS subscriptions (\n\
64 id INTEGER PRIMARY KEY,\n\
65 src TEXT,\n\
66 dest TEXT,\n\
67 srcFull TEXT,\n\
68 destFull TEXT,\n\
69 mode TEXT);";
70
71 result = sqlite3_exec(db, create_subscribe_table, nullptr, nullptr, nullptr);
72 if (result!=SQLITE_OK) {
73 sqlite3_close(db);
74 yCError(SUBSCRIBERONSQL, "Failed to set up subscriptions table");
75 std::exit(1);
76 }
77
78 const char *check_subscriptions_size = "PRAGMA table_info(subscriptions)";
79
80 sqlite3_stmt *statement = nullptr;
81 result = sqlite3_prepare_v2(db, check_subscriptions_size, -1, &statement, nullptr);
82 if (result!=SQLITE_OK) {
83 yCError(SUBSCRIBERONSQL, "Failed to set up subscriptions table");
84 std::exit(1);
85 }
86
87 int count = 0;
89 count++;
90 }
92
93 if (count==5) {
94 const char *add_structure = "ALTER TABLE subscriptions ADD COLUMN mode";
95 result = sqlite3_exec(db, add_structure, nullptr, nullptr, nullptr);
96 if (result!=SQLITE_OK) {
97 sqlite3_close(db);
98 yCError(SUBSCRIBERONSQL, "Failed to set up subscriptions table");
99 std::exit(1);
100 }
101 }
102
103 const char *create_topic_table = "CREATE TABLE IF NOT EXISTS topics (\n\
104 id INTEGER PRIMARY KEY,\n\
105 topic TEXT,\n\
106 structure TEXT);";
107
108 result = sqlite3_exec(db, create_topic_table, nullptr, nullptr, nullptr);
109 if (result!=SQLITE_OK) {
110 sqlite3_close(db);
111 yCError(SUBSCRIBERONSQL, "Failed to set up topics table");
112 std::exit(1);
113 }
114
115 const char *check_topic_size = "PRAGMA table_info(topics)";
116
117 statement = nullptr;
118 result = sqlite3_prepare_v2(db, check_topic_size, -1, &statement, nullptr);
119 if (result!=SQLITE_OK) {
120 yCError(SUBSCRIBERONSQL, "Failed to set up topics table");
121 std::exit(1);
122 }
123
124 count = 0;
125 while (sqlite3_step(statement) == SQLITE_ROW) {
126 //sqlite3_column_text(statement,1);
127 count++;
128 }
130
131 if (count==2) {
132 const char *add_structure = "ALTER TABLE topics ADD COLUMN structure";
133 result = sqlite3_exec(db, add_structure, nullptr, nullptr, nullptr);
134 if (result!=SQLITE_OK) {
135 sqlite3_close(db);
136 yCError(SUBSCRIBERONSQL, "Failed to set up topics table");
137 std::exit(1);
138 }
139 }
140
141 const char *create_live_table = "CREATE TABLE IF NOT EXISTS live (\n\
142 id INTEGER PRIMARY KEY,\n\
143 name TEXT UNIQUE,\n\
144 stamp DATETIME);";
145
146 result = sqlite3_exec(db, create_live_table, nullptr, nullptr, nullptr);
147 if (result!=SQLITE_OK) {
148 sqlite3_close(db);
149 yCError(SUBSCRIBERONSQL, "Failed to set up live table");
150 std::exit(1);
151 }
152
153 const char *create_struct_table = "CREATE TABLE IF NOT EXISTS structures (\n\
154 name TEXT PRIMARY KEY,\n\
155 yarp TEXT);";
156
157 result = sqlite3_exec(db, create_struct_table, nullptr, nullptr, nullptr);
158 if (result!=SQLITE_OK) {
159 sqlite3_close(db);
160 yCError(SUBSCRIBERONSQL, "Failed to set up structures table");
161 std::exit(1);
162 }
163
164 implementation = db;
165 return true;
166}
167
168
170 if (implementation != nullptr) {
171 auto* db = (sqlite3 *)implementation;
172 sqlite3_close(db);
173 implementation = nullptr;
174 }
175 return true;
176}
177
178bool SubscriberOnSql::addSubscription(const std::string& src,
179 const std::string& dest,
180 const std::string& mode) {
181 removeSubscription(src,dest);
183 psrc.apply(src);
184 pdest.apply(dest);
185 if (psrc.getCarrier()=="topic") {
186 setTopic(psrc.getPortName(),"",true);
187 }
188 if (pdest.getCarrier()=="topic") {
189 setTopic(pdest.getPortName(),"",true);
190 }
191 char *msg = nullptr;
192 const char *zmode = mode.c_str();
193 if (mode == "") {
194 zmode = nullptr;
195 }
196 char *query = sqlite3_mprintf("INSERT INTO subscriptions (src,dest,srcFull,destFull,mode) VALUES(%Q,%Q,%Q,%Q,%Q)",
197 psrc.getPortName().c_str(),
198 pdest.getPortName().c_str(),
199 src.c_str(),
200 dest.c_str(),
201 zmode);
202 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
203
204 bool ok = true;
205 int result = sqlite3_exec(SQLDB(implementation), query, nullptr, nullptr, &msg);
206 if (result!=SQLITE_OK) {
207 ok = false;
208 if (msg != nullptr) {
211 }
212 }
214 if (ok) {
215 if (psrc.getCarrier()!="topic") {
216 if (pdest.getCarrier()!="topic") {
217 checkSubscription(psrc.getPortName(),
218 pdest.getPortName(),
219 src,
220 dest,
221 mode);
222 } else {
223 hookup(psrc.getPortName());
224 }
225 } else {
226 if (pdest.getCarrier()!="topic") {
227 hookup(pdest.getPortName());
228 }
229 }
230 }
231 return ok;
232}
233
234bool SubscriberOnSql::removeSubscription(const std::string& src,
235 const std::string& dest) {
237 psrc.apply(src);
238 pdest.apply(dest);
239 char *query = sqlite3_mprintf("DELETE FROM subscriptions WHERE src = %Q AND dest = %Q",
240 psrc.getPortName().c_str(),
241 pdest.getPortName().c_str());
242 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
243
244 int result = sqlite3_exec(SQLDB(implementation), query, nullptr, nullptr, nullptr);
245 bool ok = true;
246 if (result!=SQLITE_OK) {
247 yCError(SUBSCRIBERONSQL, "Error in query");
248 ok = false;
249 }
251
252 return ok;
253}
254
255
256bool SubscriberOnSql::welcome(const std::string& port, int activity) {
257 mutex.lock();
258
259 NameSpace *ns = getDelegate();
260 if (ns) {
261 NestedContact nc(port);
262 if (nc.getNestedName().size()>0) {
263 NameStore *store = getStore();
264 if (store != nullptr) {
265 Contact node = store->query(nc.getNodeName());
266 Contact me = store->query(port);
267 if (node.isValid() && me.isValid()) {
268 if (activity>0) {
269 ns->registerAdvanced(me,store);
270 } else {
271 ns->unregisterAdvanced(port,store);
272 }
273 }
274 }
275 }
276 }
277
278 char *msg = nullptr;
279 char *query;
280 if (activity>0) {
281 query = sqlite3_mprintf("INSERT OR IGNORE INTO live (name,stamp) VALUES(%Q,DATETIME('now'))",
282 port.c_str());
283 } else {
284 // Port not responding. Mark as non-live.
285 if (activity==0) {
286 query = sqlite3_mprintf("DELETE FROM live WHERE name=%Q AND stamp < DATETIME('now','-30 seconds')",
287 port.c_str());
288 } else {
289 // activity = -1 -- definite dodo
290 query = sqlite3_mprintf("DELETE FROM live WHERE name=%Q",
291 port.c_str());
292 }
293 }
294 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
295
296 bool ok = true;
297 int result = sqlite3_exec(SQLDB(implementation), query, nullptr, nullptr, &msg);
298 if (result!=SQLITE_OK) {
299 ok = false;
300 if (msg != nullptr) {
303 }
304 }
306 mutex.unlock();
307
308 if (activity>0) {
309 hookup(port);
310 } else if (activity<0) {
311 breakdown(port);
312 }
313 return ok;
314}
315
316bool SubscriberOnSql::hookup(const std::string& port) {
317 if (getDelegate()) {
318 NestedContact nc(port);
319 if (nc.getNestedName().size()>0) {
320 return false;
321 }
322 }
323 mutex.lock();
324 sqlite3_stmt *statement = nullptr;
325 char *query = nullptr;
326 //query = sqlite3_mprintf("SELECT * FROM subscriptions WHERE src = %Q OR dest= %Q",port, port);
327 query = sqlite3_mprintf("SELECT src,dest,srcFull,destFull FROM subscriptions WHERE (src = %Q OR dest= %Q) AND EXISTS (SELECT NULL FROM live WHERE name=src) AND EXISTS (SELECT NULL FROM live WHERE name=dest) UNION SELECT s1.src, s2.dest, s1.srcFull, s2.destFull FROM subscriptions s1, subscriptions s2, topics t WHERE (s1.dest = t.topic AND s2.src = t.topic) AND (s1.src = %Q OR s2.dest = %Q) AND EXISTS (SELECT NULL FROM live WHERE name=s1.src) AND EXISTS (SELECT NULL FROM live WHERE name=s2.dest)",port.c_str(), port.c_str(), port.c_str(), port.c_str());
328 //
329 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
330
331 int result = sqlite3_prepare_v2(SQLDB(implementation), query, -1, &statement, nullptr);
332 if (result!=SQLITE_OK) {
333 const char *msg = sqlite3_errmsg(SQLDB(implementation));
334 if (msg != nullptr) {
336 }
337 }
338 while (result == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW) {
339 char *src = (char *)sqlite3_column_text(statement,0);
340 char *dest = (char *)sqlite3_column_text(statement,1);
341 char *srcFull = (char *)sqlite3_column_text(statement,2);
342 char *destFull = (char *)sqlite3_column_text(statement,3);
343 char *mode = (char *)sqlite3_column_text(statement,4);
345 }
348 mutex.unlock();
349
350 return false;
351}
352
353
354bool SubscriberOnSql::breakdown(const std::string& port) {
355 if (getDelegate()) {
356 NestedContact nc(port);
357 if (nc.getNestedName().size()>0) {
358 return false;
359 }
360 }
361 mutex.lock();
362 sqlite3_stmt *statement = nullptr;
363 char *query = nullptr;
364 // query = sqlite3_mprintf("SELECT src,dest,srcFull,destFull,mode FROM subscriptions WHERE ((src = %Q AND EXISTS (SELECT NULL FROM live WHERE name=dest)) OR (dest = %Q AND EXISTS (SELECT NULL FROM live WHERE name=src))) UNION SELECT s1.src, s2.dest, s1.srcFull, s2.destFull, NULL FROM subscriptions s1, subscriptions s2, topics t WHERE (s1.dest = t.topic AND s2.src = t.topic AND ((s1.src = %Q AND EXISTS (SELECT NULL FROM live WHERE name=s2.dest)) OR (s2.dest = %Q AND EXISTS (SELECT NULL FROM live WHERE name=s1.src))))",port, port, port, port);
365 query = sqlite3_mprintf("SELECT src,dest,srcFull,destFull,mode FROM subscriptions WHERE ((src = %Q AND (mode IS NOT NULL OR EXISTS (SELECT NULL FROM live WHERE name=dest))) OR (dest = %Q AND (mode IS NOT NULL OR EXISTS (SELECT NULL FROM live WHERE name=src)))) UNION SELECT s1.src, s2.dest, s1.srcFull, s2.destFull, NULL FROM subscriptions s1, subscriptions s2, topics t WHERE (s1.dest = t.topic AND s2.src = t.topic AND ((s1.src = %Q AND EXISTS (SELECT NULL FROM live WHERE name=s2.dest)) OR (s2.dest = %Q AND EXISTS (SELECT NULL FROM live WHERE name=s1.src))))",port.c_str(), port.c_str(), port.c_str(), port.c_str());
366 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
367
368 int result = sqlite3_prepare_v2(SQLDB(implementation), query, -1, &statement, nullptr);
369 if (result!=SQLITE_OK) {
370 const char *msg = sqlite3_errmsg(SQLDB(implementation));
371 if (msg != nullptr) {
373 }
374 }
375 while (result == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW) {
376 char *src = (char *)sqlite3_column_text(statement,0);
377 char *dest = (char *)sqlite3_column_text(statement,1);
378 char *srcFull = (char *)sqlite3_column_text(statement,2);
379 char *destFull = (char *)sqlite3_column_text(statement,3);
380 char *mode = (char *)sqlite3_column_text(statement,4);
381 breakSubscription(port,src,dest,srcFull,destFull,mode?mode:"");
382 }
385 mutex.unlock();
386
387 return false;
388}
389
390
391bool SubscriberOnSql::checkSubscription(const std::string& src,const std::string& dest,
392 const std::string& srcFull,
393 const std::string& destFull,
394 const std::string& mode) {
395 if (getDelegate()) {
396 NestedContact nc(src);
397 if (nc.getNestedName().size()>0) {
398 NestedContact nc(dest);
399 if (nc.getNestedName().size()>0) {
400 return false;
401 }
402 }
403 }
405 "+++ Checking %s %s / %s %s",
406 src.c_str(),
407 dest.c_str(),
408 srcFull.c_str(),
409 destFull.c_str());
410
411 NameStore *store = getStore();
412 if (store != nullptr) {
413 Contact csrc = store->query(src);
414 Contact cdest = store->query(dest);
415 if (csrc.isValid()&&cdest.isValid()) {
416 bool srcTopic = (csrc.getCarrier()=="topic");
417 bool destTopic = (cdest.getCarrier()=="topic");
418 if (!(srcTopic||destTopic)) {
420 "++> check connection %s %s",
421 srcFull.c_str(),
422 destFull.c_str());
424 }
425 }
426 if (mode!="") {
427 std::string mode_name = mode;
428 if (mode_name=="from") {
429 if (!csrc.isValid()) {
430 removeSubscription(src,dest);
431 }
432 } else if (mode_name=="to") {
433 if (!cdest.isValid()) {
434 removeSubscription(src,dest);
435 }
436 }
437 }
438 }
439 return false;
440}
441
442
444 const std::string& src, const std::string& dest,
445 const std::string& srcFull,
446 const std::string& destFull,
447 const std::string& mode) {
448 if (getDelegate()) {
449 NestedContact nc(src);
450 if (nc.getNestedName().size()>0) {
451 NestedContact nc(dest);
452 if (nc.getNestedName().size()>0) {
453 return false;
454 }
455 }
456 }
458 "--- Checking %s %s / %s %s",
459 src.c_str(),
460 dest.c_str(),
461 srcFull.c_str(),
462 destFull.c_str());
463 NameStore *store = getStore();
464 if (store != nullptr) {
465 bool srcDrop = std::string(dropper) == src;
466 Contact contact;
467 if (srcDrop) {
468 contact = store->query(src);
469 } else {
470 contact = store->query(dest);
471 }
472 if (contact.isValid()) {
474 "--> check connection %s %s",
475 srcFull.c_str(),
476 destFull.c_str());
478 }
479 if (mode!="") {
480 std::string mode_name = mode;
481 if (mode_name=="from") {
482 if (srcDrop) {
483 removeSubscription(src,dest);
484 }
485 } else if (mode_name=="to") {
486 if (!srcDrop) {
487 removeSubscription(src,dest);
488 }
489 }
490 }
491 }
492 return false;
493}
494
495
496
497bool SubscriberOnSql::listSubscriptions(const std::string& port,
498 yarp::os::Bottle& reply) {
499 mutex.lock();
500 sqlite3_stmt *statement = nullptr;
501 char *query = nullptr;
502 if (std::string(port)!="") {
503 query = sqlite3_mprintf("SELECT s.srcFull, s.DestFull, EXISTS(SELECT topic FROM topics WHERE topic = s.src), EXISTS(SELECT topic FROM topics WHERE topic = s.dest), s.mode FROM subscriptions s WHERE s.src = %Q OR s.dest= %Q ORDER BY s.src, s.dest",port.c_str(),port.c_str());
504 } else {
505 query = sqlite3_mprintf("SELECT s.srcFull, s.destFull, EXISTS(SELECT topic FROM topics WHERE topic = s.src), EXISTS(SELECT topic FROM topics WHERE topic = s.dest), s.mode FROM subscriptions s ORDER BY s.src, s.dest");
506 }
507 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
508
509 int result = sqlite3_prepare_v2(SQLDB(implementation), query, -1, &statement, nullptr);
510 if (result!=SQLITE_OK) {
511 const char *msg = sqlite3_errmsg(SQLDB(implementation));
512 if (msg != nullptr) {
514 }
515 }
516 reply.addString("subscriptions");
517 while (result == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW) {
518 char *src = (char *)sqlite3_column_text(statement,0);
519 char *dest = (char *)sqlite3_column_text(statement,1);
522 char *mode = (char *)sqlite3_column_text(statement,4);
523 Bottle& b = reply.addList();
524 b.addString("subscription");
525 Bottle bsrc;
526 bsrc.addString("src");
527 bsrc.addString(src);
529 bdest.addString("dest");
530 bdest.addString(dest);
531 b.addList() = bsrc;
532 b.addList() = bdest;
533 if (mode != nullptr) {
534 if (mode[0]!='\0') {
536 bmode.addString("mode");
537 bmode.addString(mode);
538 b.addList() = bmode;
539 }
540 }
541 if (srcTopic||destTopic) {
543 btopic.addString("topic");
544 btopic.addInt32(srcTopic);
545 btopic.addInt32(destTopic);
546 b.addList() = btopic;
547 }
548 }
551 mutex.unlock();
552
553 return true;
554}
555
556
557bool SubscriberOnSql::setTopic(const std::string& port, const std::string& structure,
558 bool active) {
559 if (structure!="" || !active) {
560 mutex.lock();
561 char *query = sqlite3_mprintf("DELETE FROM topics WHERE topic = %Q",
562 port.c_str());
563 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
564
565 int result = sqlite3_exec(SQLDB(implementation), query, nullptr, nullptr, nullptr);
566 bool ok = true;
567 if (result!=SQLITE_OK) {
568 yCError(SUBSCRIBERONSQL, "Error in query");
569 ok = false;
570 }
572 mutex.unlock();
573 if (!ok) {
574 return false;
575 }
576 if (!active) {
577 return true;
578 }
579 }
580
581 bool have_topic = false;
582 if (structure=="") {
583 mutex.lock();
584 sqlite3_stmt *statement = nullptr;
585 char *query = nullptr;
586 query = sqlite3_mprintf("SELECT topic FROM topics WHERE topic = %Q",
587 port.c_str());
588 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
589
590 int result = sqlite3_prepare_v2(SQLDB(implementation), query, -1, &statement, nullptr);
591 if (result!=SQLITE_OK) {
592 yCError(SUBSCRIBERONSQL, "Error in query");
593 }
594 if (result == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW) {
595 have_topic = true;
596 }
599 mutex.unlock();
600 }
601
602 if (structure!="" || !have_topic) {
603 mutex.lock();
604 char *msg = nullptr;
605 const char *pstructure = structure.c_str();
606 if (structure == "") {
607 pstructure = nullptr;
608 }
609 char *query = sqlite3_mprintf("INSERT INTO topics (topic,structure) VALUES(%Q,%Q)",
610 port.c_str(),pstructure);
611 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
612
613 bool ok = true;
614 int result = sqlite3_exec(SQLDB(implementation), query, nullptr, nullptr, &msg);
615 if (result!=SQLITE_OK) {
616 ok = false;
617 if (msg != nullptr) {
620 }
621 }
623 mutex.unlock();
624 if (!ok) {
625 return false;
626 }
627 }
628
629 std::vector<std::vector<std::string> > subs;
630
631 // go ahead and connect anything needed
632 mutex.lock();
633 sqlite3_stmt *statement = nullptr;
634 char *query = sqlite3_mprintf("SELECT s1.src, s2.dest, s1.srcFull, s2.destFull FROM subscriptions s1, subscriptions s2, topics t WHERE (t.topic = %Q AND s1.dest = t.topic AND s2.src = t.topic)", port.c_str());
635 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
636
637 int result = sqlite3_prepare_v2(SQLDB(implementation), query, -1, &statement, nullptr);
638 if (result!=SQLITE_OK) {
639 const char *msg = sqlite3_errmsg(SQLDB(implementation));
640 if (msg != nullptr) {
642 }
643 }
644 while (result == SQLITE_OK &&
646 char *src = (char *)sqlite3_column_text(statement,0);
647 char *dest = (char *)sqlite3_column_text(statement,1);
648 char *srcFull = (char *)sqlite3_column_text(statement,2);
649 char *destFull = (char *)sqlite3_column_text(statement,3);
650 char *mode = (char *)sqlite3_column_text(statement,4);
651 std::vector<std::string> sub;
652 sub.emplace_back(src);
653 sub.emplace_back(dest);
654 sub.emplace_back(srcFull);
655 sub.emplace_back(destFull);
656 sub.emplace_back(mode?mode:"");
657 subs.push_back(sub);
658 }
661 mutex.unlock();
662
663 for (auto& sub : subs) {
664 checkSubscription(sub[0],sub[1],sub[2],sub[3],sub[4]);
665 }
666
667 return true;
668}
669
670
672 mutex.lock();
673 sqlite3_stmt *statement = nullptr;
674 char *query = nullptr;
675 query = sqlite3_mprintf("SELECT topic FROM topics");
676 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
677
678 int result = sqlite3_prepare_v2(SQLDB(implementation), query, -1, &statement, nullptr);
679 if (result!=SQLITE_OK) {
680 yCError(SUBSCRIBERONSQL, "Error in query");
681 }
682 while (result == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW) {
683 char *topic = (char *)sqlite3_column_text(statement,0);
684 topics.addString(topic);
685 }
688 mutex.unlock();
689
690 return true;
691}
692
693
694bool SubscriberOnSql::setType(const std::string& family,
695 const std::string& structure,
696 const std::string& value) {
697 mutex.lock();
698 char *msg = nullptr;
699 char *query = sqlite3_mprintf("INSERT OR REPLACE INTO structures (name,%Q) VALUES(%Q,%Q)",
700 family.c_str(),
701 (structure=="") ? nullptr : structure.c_str(),
702 value.c_str());
703 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
704
705 bool ok = true;
706 int result = sqlite3_exec(SQLDB(implementation), query, nullptr, nullptr, &msg);
707 if (result!=SQLITE_OK) {
708 ok = false;
709 if (msg != nullptr) {
712 }
713 }
715 mutex.unlock();
716 return ok;
717}
718
719std::string SubscriberOnSql::getType(const std::string& family,
720 const std::string& structure) {
721 mutex.lock();
722 sqlite3_stmt *statement = nullptr;
723 char *query = nullptr;
724 query = sqlite3_mprintf("SELECT %s FROM structures WHERE name = %Q",
725 family.c_str(), structure.c_str());
726 yCDebug(SUBSCRIBERONSQL, "Query: %s", query);
727
728 int result = sqlite3_prepare_v2(SQLDB(implementation), query, -1, &statement, nullptr);
729 std::string sresult;
730 if (result!=SQLITE_OK) {
731 yCError(SUBSCRIBERONSQL, "Error in query");
732 }
733 if (result == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW) {
734 sresult = (const char *)sqlite3_column_text(statement,0);
735 }
738 mutex.unlock();
739
740 return sresult;
741}
FeatureMode mode
#define SQLDB(x)
#define F_OK
yarp::os::Contact query(const std::string &name) override
Definition NameService.h:40
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:65
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
Definition Bottle.cpp:188
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition Bottle.cpp:176
A mini-server for performing network communication in the background.
Represents how to reach a part of a YARP network.
Definition Contact.h:33
bool isValid() const
Checks if a Contact is tagged as valid.
Definition Contact.cpp:298
An abstract name space for ports.
Definition NameSpace.h:22
virtual Contact unregisterAdvanced(const std::string &name, NameStore *store)
Remove contact information, with access to the contact information of other ports for cross-referenci...
Definition NameSpace.h:103
virtual Contact registerAdvanced(const Contact &contact, NameStore *store)
Record contact information, with access to the contact information of other ports for cross-referenci...
Definition NameSpace.h:92
Abstract interface for a database of port names.
Definition NameStore.h:19
virtual Contact query(const std::string &name)=0
A placeholder for rich contact information.
bool checkSubscription(const std::string &src, const std::string &dest, const std::string &srcFull, const std::string &destFull, const std::string &mode)
bool removeSubscription(const std::string &src, const std::string &dest) override
bool open(const std::string &filename, bool fresh=false)
bool hookup(const std::string &port)
bool welcome(const std::string &port, int activity) override
bool breakSubscription(const std::string &dropper, const std::string &src, const std::string &dest, const std::string &srcFull, const std::string &destFull, const std::string &mode)
bool addSubscription(const std::string &src, const std::string &dest, const std::string &mode) override
bool listSubscriptions(const std::string &port, yarp::os::Bottle &reply) override
std::string getType(const std::string &family, const std::string &structure) override
bool breakdown(const std::string &port)
bool setTopic(const std::string &port, const std::string &structure, bool active) override
bool listTopics(yarp::os::Bottle &topics) override
bool setType(const std::string &family, const std::string &structure, const std::string &value) override
void disconnect(const std::string &src, const std::string &dest, bool srcDrop)
Definition Subscriber.h:55
yarp::os::NameStore * getStore()
Definition Subscriber.h:39
yarp::os::NameSpace * getDelegate()
Definition Subscriber.h:106
void connect(const std::string &src, const std::string &dest)
Definition Subscriber.h:49
#define yCError(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_SERVERSQL_LOG_COMPONENT(name, name_string)
An interface to the operating system, including Port based communication.