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