37 #include <boost/make_shared.hpp>
46 sqlite3_stmt* stmt =
nullptr;
47 std::ostringstream query_builder;
50 const auto query = query_builder.str();
51 if (sqlite3_prepare_v2(
db_.get(),
query.c_str(),
query.size() + 1, &stmt,
nullptr) != SQLITE_OK)
53 throw InternalError(
"Prepare statement for findAndMatchMd5Sum() failed",
db_.get());
58 throw InternalError(
"Bind parameter for findAndMatchMd5Sum() failed",
db_.get());
60 switch (sqlite3_step(stmt))
67 throw InternalError(
"Fetch result for findAndMatchMd5Sum() failed",
db_.get());
70 if (std::size_t(sqlite3_column_bytes(stmt, 0)) != md5_bytes.size())
72 throw std::invalid_argument(
"invalid md5 value");
74 if (std::memcmp(&md5_bytes[0], sqlite3_column_blob(stmt, 0), md5_bytes.size()) == 0)
84 const auto current_md5_state = findAndMatchMd5Sum(md5_bytes);
85 if (current_md5_state != Md5CompareResult::EMPTY)
87 return current_md5_state == Md5CompareResult::MATCH;
90 std::ostringstream query_builder;
98 << esc(collection_name_) <<
"', '" << esc(db_name_) <<
"' , x'" << md5 <<
"' , '" << esc(
datatype)
99 <<
"'); COMMIT TRANSACTION;";
100 const auto query = query_builder.str();
101 ROS_DEBUG_NAMED(
"warehouse_ros_sqlite",
"initialize query: %s", query.c_str());
102 if (sqlite3_exec(db_.get(), query.c_str(),
nullptr,
nullptr,
nullptr) != SQLITE_OK)
104 ROS_ERROR_NAMED(
"warehouse_ros_sqlite",
"Database initialization failed: %s", sqlite3_errmsg(db_.get()));
105 sqlite3_exec(db_.get(),
"ROLLBACK;",
nullptr,
nullptr,
nullptr);
115 if (!meta || !msg || !msg_size)
116 throw std::invalid_argument(
"meta, msg or msg_size is 0");
117 meta->ensureColumns(db_.get(), mangled_tablename_);
118 std::ostringstream query;
121 const auto& data = meta->data();
122 for (
const auto& kv : data)
126 query <<
") VALUES ( ? ";
127 for (
size_t i = 0; i < data.size(); ++i)
131 sqlite3_stmt* stmt =
nullptr;
132 const auto query_str = query.str();
133 ROS_DEBUG_NAMED(
"warehouse_ros_sqlite",
"insert query: %s", query_str.c_str());
134 if (sqlite3_prepare_v2(db_.get(), query_str.c_str(), query_str.size() + 1, &stmt,
nullptr) != SQLITE_OK)
135 throw InternalError(
"Prepare statement for insert() failed", db_.get());
138 if (sqlite3_bind_blob(stmt, 1, msg, msg_size, SQLITE_STATIC) != SQLITE_OK)
139 throw InternalError(
"Bind parameter for insert() failed", db_.get());
141 for (
const auto& kv : data)
143 if (boost::apply_visitor(visitor, std::get<1>(kv)) != SQLITE_OK)
144 throw InternalError(
"Bind parameter for insert() failed", db_.get());
147 assert(sqlite3_bind_parameter_count(stmt) == visitor.
getTotalBinds());
148 if (sqlite3_step(stmt) != SQLITE_DONE)
154 bool ascending)
const
157 if (!sort_by.empty())
163 std::ostringstream intro;
164 intro <<
"SELECT * FROM " << escaped_mangled_name_;
165 if (!query_ptr->empty())
169 auto stmt = query_ptr->prepare(db_.get(), intro.str(), outro);
172 switch (sqlite3_step(stmt.get()))
181 return boost::make_shared<warehouse_ros_sqlite::ResultIteratorHelper>(std::move(stmt));
188 throw std::invalid_argument(
"Query was not initialized by createQuery()");
189 auto stmt = pquery->prepare(db_.get(),
"DELETE FROM " + escaped_mangled_name_ +
" WHERE ");
190 if (sqlite3_step(stmt.get()) != SQLITE_DONE)
192 throw InternalError(
"Prepare statement for removeMessages() failed", db_.get());
194 return sqlite3_changes(db_.get());
199 template <
typename It>
200 void comma_concat_meta_column_names(std::ostringstream& buf, It it, It end)
221 if (!query || !metadata)
222 throw std::invalid_argument(
"q or m not created by createQuery() or createMetadata()");
223 metadata->ensureColumns(db_.get(), mangled_tablename_);
224 const int mt_count = metadata->data().size();
228 std::ostringstream query_builder;
229 query_builder <<
"UPDATE " << escaped_mangled_name_ <<
" SET ";
231 comma_concat_meta_column_names(query_builder, metadata->data().begin(), metadata->data().end());
232 query_builder <<
" WHERE ";
233 auto stmt = query->prepare(db_.get(), query_builder.str(),
"", mt_count + 1);
237 for (
const auto& kv : metadata->data())
239 if (boost::apply_visitor(visitor, std::get<1>(kv)) != SQLITE_OK)
240 throw InternalError(
"Bind parameter failed for modifyMetadata()", db_.get());
243 if (sqlite3_step(stmt.get()) != SQLITE_DONE)
249 const std::string query =
"SELECT COUNT(*) FROM " + escaped_mangled_name_ +
";";
250 sqlite3_stmt* stmt =
nullptr;
251 if (sqlite3_prepare_v2(db_.get(), query.c_str(), query.size() + 1, &stmt,
nullptr) != SQLITE_OK)
252 throw InternalError(
"Prepare statement for count() failed", db_.get());
255 if (sqlite3_step(stmt) != SQLITE_ROW)
258 assert(sqlite3_column_count(stmt) == 1);
260 return sqlite3_column_int(stmt, 0);
264 return boost::make_shared<warehouse_ros_sqlite::Query>();
268 return boost::make_shared<warehouse_ros_sqlite::Metadata>();