YARP
Yet Another Robot Platform
SqliteTripleSource.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 
8 
10 
11 #include <cstdlib>
12 #include <cstdio>
13 
17 
18 namespace {
19 YARP_SERVERSQL_LOG_COMPONENT(SQLITETRIPLESOURCE, "yarp.serversql.impl.SqliteTripleSource")
20 } // namespace
21 
22 SqliteTripleSource::SqliteTripleSource(sqlite3 *db) : db(db)
23 {
24 }
25 
27 {
28  int rid = (context != nullptr) ? context->rid : -1;
29  std::string cond = "";
30  if (rid==-1) {
31  cond = "rid IS NULL";
32  } else {
33  cond = "rid = " + expressContext(context);
34  }
35  if (t.hasNs) {
36  if (t.ns!="*") {
37  char *query = nullptr;
38  query = sqlite3_mprintf(" AND ns = %Q",t.getNs());
39  cond = cond + query;
40  sqlite3_free(query);
41  }
42  } else {
43  cond += " AND ns IS NULL";
44  }
45  if (t.hasName) {
46  if (t.name!="*") {
47  char *query = nullptr;
48  query = sqlite3_mprintf(" AND name = %Q",t.getName());
49  cond = cond + query;
50  sqlite3_free(query);
51  }
52  } else {
53  cond += " AND name IS NULL";
54  }
55  if (t.hasValue) {
56  if (t.value!="*") {
57  char *query = nullptr;
58  query = sqlite3_mprintf(" AND value = %Q",t.getValue());
59  cond = cond + query;
60  sqlite3_free(query);
61  }
62  } else {
63  cond += " AND value IS NULL";
64  }
65  return cond;
66 }
67 
69 {
70  int out = -1;
71  sqlite3_stmt *statement = nullptr;
72  char *query = nullptr;
73  query = sqlite3_mprintf("SELECT id FROM tags WHERE %s",
74  condition(t,context).c_str());
75  yCDebug(SQLITETRIPLESOURCE, "Query: %s", query);
76  int result = sqlite3_prepare_v2(db, query, -1, &statement, nullptr);
77  if (result!=SQLITE_OK) {
78  yCWarning(SQLITETRIPLESOURCE, "Error in query");
79  }
80  while (result == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW) {
81  if (out!=-1) {
82  yCWarning(SQLITETRIPLESOURCE, "WARNING: multiple matches ignored");
83  }
84  out = sqlite3_column_int(statement,0);
85  yCTrace(SQLITETRIPLESOURCE, "Match %d", out);
86  }
87 
88  sqlite3_finalize(statement);
89  sqlite3_free(query);
90  return out;
91 }
92 
94 {
95  char *query = nullptr;
96  query = sqlite3_mprintf("DELETE FROM tags WHERE %s",condition(ti,context).c_str());
97  yCDebug(SQLITETRIPLESOURCE, "Query: %s", query);
98  int result = sqlite3_exec(db, query, nullptr, nullptr, nullptr);
99  if (result!=SQLITE_OK) {
100  yCWarning(SQLITETRIPLESOURCE, "Error in query");
101  }
102  sqlite3_free(query);
103 }
104 
106 {
107  char *query = nullptr;
108  query = sqlite3_mprintf("DELETE FROM tags WHERE rid IS NOT NULL AND rid NOT IN (SELECT id FROM tags)");
109  yCDebug(SQLITETRIPLESOURCE, "Query: %s", query);
110  int result = sqlite3_exec(db, query, nullptr, nullptr, nullptr);
111  if (result!=SQLITE_OK) {
112  yCWarning(SQLITETRIPLESOURCE, "Error in query");
113  }
114  sqlite3_free(query);
115 }
116 
117 std::list<Triple> SqliteTripleSource::query(Triple& ti, TripleContext *context)
118 {
119  std::list<Triple> q;
120  sqlite3_stmt *statement = nullptr;
121  char *query = nullptr;
122  query = sqlite3_mprintf("SELECT id, ns, name, value FROM tags WHERE %s",condition(ti,context).c_str());
123  yCDebug(SQLITETRIPLESOURCE, "Query: %s", query);
124  int result = sqlite3_prepare_v2(db, query, -1, &statement, nullptr);
125  if (result!=SQLITE_OK) {
126  yCWarning(SQLITETRIPLESOURCE, "Error in query");
127  }
128  while (result == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW) {
129  //int id = sqlite3_column_int(statement,0);
130  char *ns = (char *)sqlite3_column_text(statement,1);
131  char *name = (char *)sqlite3_column_text(statement,2);
132  char *value = (char *)sqlite3_column_text(statement,3);
133  Triple t;
134  if (ns != nullptr) {
135  t.ns = ns;
136  t.hasNs = true;
137  }
138  if (name != nullptr) {
139  t.name = name;
140  t.hasName = true;
141  }
142  if (value != nullptr) {
143  t.value = value;
144  t.hasValue = true;
145  }
146  q.push_back(t);
147  }
148  sqlite3_finalize(statement);
149  sqlite3_free(query);
150  return q;
151 }
152 
154 {
155  int rid = (context != nullptr)?context->rid:-1;
156  char buf[100] = "NULL";
157  if (rid!=-1) {
158  std::snprintf(buf, 100, "%d", rid);
159  }
160  return buf;
161 }
162 
164 {
165  char *msg = nullptr;
166  char *query = sqlite3_mprintf("INSERT INTO tags (rid,ns,name,value) VALUES(%s,%Q,%Q,%Q)",
167  expressContext(context).c_str(),
168  t.getNs(),t.getName(),t.getValue());
169  yCDebug(SQLITETRIPLESOURCE, "Query: %s", query);
170  int result = sqlite3_exec(db, query, nullptr, nullptr, &msg);
171  if (result!=SQLITE_OK) {
172  if (msg != nullptr) {
173  yCError(SQLITETRIPLESOURCE, "Error: %s", msg);
174  yCError(SQLITETRIPLESOURCE, "(Query was): %s", query);
175  yCError(SQLITETRIPLESOURCE, "(Location): %s:%d", __FILE__, __LINE__);
176  sqlite3_free(msg);
177  }
178  }
179  sqlite3_free(query);
180 }
181 
183 {
184  char *msg = nullptr;
185  char *query = nullptr;
186  if (t.hasName||t.hasNs) {
187  Triple t2(t);
188  t2.value = "*";
189  query = sqlite3_mprintf("UPDATE tags SET value = %Q WHERE %s",
190  t.getValue(),
191  condition(t2,context).c_str());
192  } else {
193  query = sqlite3_mprintf("UPDATE tags SET value = %Q WHERE id = %Q",
194  t.getValue(),
195  expressContext(context).c_str());
196  }
197  yCDebug(SQLITETRIPLESOURCE, "Query: %s", query);
198  int result = sqlite3_exec(db, query, nullptr, nullptr, &msg);
199  if (result!=SQLITE_OK) {
200  if (msg != nullptr) {
201  yCError(SQLITETRIPLESOURCE, "Error: %s", msg);
202  sqlite3_free(msg);
203  }
204  }
205  int ct = sqlite3_changes(db);
206  if (ct==0 && (t.hasName||t.hasNs)) {
207  insert(t,context);
208  }
209  sqlite3_free(query);
210 }
211 
213 {
214  int result = sqlite3_exec(db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr);
215  yCDebug(SQLITETRIPLESOURCE, "Query: BEGIN TRANSACTION;");
216  if (result!=SQLITE_OK) {
217  yCWarning(SQLITETRIPLESOURCE, "Error in BEGIN query");
218  }
219 }
220 
222 {
223  int result = sqlite3_exec(db, "END TRANSACTION;", nullptr, nullptr, nullptr);
224  yCDebug(SQLITETRIPLESOURCE, "Query: END TRANSACTION;");
225  if (result!=SQLITE_OK) {
226  yCWarning(SQLITETRIPLESOURCE, "Error in END query");
227  }
228 }
float t
Sqlite database, viewed as a collection of triples.
std::string condition(Triple &t, TripleContext *context)
std::string expressContext(TripleContext *context)
void prune(TripleContext *context) override
std::list< Triple > query(Triple &ti, TripleContext *context) override
void insert(Triple &t, TripleContext *context) override
int find(Triple &t, TripleContext *context) override
void remove_query(Triple &ti, TripleContext *context) override
void begin(TripleContext *context) override
void end(TripleContext *context) override
void update(Triple &t, TripleContext *context) override
Side information for controlling access to triples.
Definition: TripleSource.h:24
The basic unit of data the name server works with.
Definition: Triple.h:25
#define yCError(component,...)
Definition: LogComponent.h:154
#define yCTrace(component,...)
Definition: LogComponent.h:85
#define yCWarning(component,...)
Definition: LogComponent.h:143
#define yCDebug(component,...)
Definition: LogComponent.h:109
#define YARP_SERVERSQL_LOG_COMPONENT(name, name_string)
Definition: LogComponent.h:34