VLink 2.0.0
A high-performance communication middleware
载入中...
搜索中...
未找到
database_reader.h
浏览该文件的文档.
1/*
2 * Copyright (C) 2026 by Thun Lu. All rights reserved.
3 * Author: Thun Lu <thun.lu@zohomail.cn>
4 * Repo: https://github.com/thun-res/vlink
5 * _ __ __ _ __
6 * | | / / / / (_) ____ / /__
7 * | | / / / / / / / __ \ / //_/
8 * | |/ / / /___ / / / / / / / ,<
9 * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24/**
25 * @file database_reader.h
26 * @brief Concrete BagReader implementation for the SQLite-backed VLink bag format.
27 *
28 * @details
29 * @c DatabaseReader reads bag files in the SQLite-backed @c .vdb format and inherits all
30 * playback, seeking, fix, and reindex capabilities from @c BagReader.
31 *
32 * The @c .vdb format stores messages in a structured SQLite database, enabling efficient
33 * random-access queries, indexed playback, and in-place repair with @c fix().
34 *
35 * @par Usage
36 * @code
37 * auto reader = vlink::BagReader::create("/data/recording.vdb");
38 * // or explicitly:
39 * auto reader = std::make_shared<vlink::DatabaseReader>("/data/recording.vdb");
40 * reader->register_output_callback([](int64_t ts, const std::string& url,
41 * vlink::ActionType action, const vlink::Bytes& data) {
42 * // process message
43 * });
44 * reader->async_run();
45 * reader->play({});
46 * @endcode
47 *
48 * @see BagReader, McapReader
49 */
50
51#pragma once
52
53#include <future>
54#include <memory>
55#include <string>
56#include <vector>
57
58#include "./bag_reader.h"
59
60namespace vlink {
61
62/**
63 * @class DatabaseReader
64 * @brief Concrete SQLite-backed bag file player.
65 *
66 * @details
67 * All virtual methods from @c BagReader are implemented. Prefer using
68 * @c BagReader::create() for format-agnostic construction.
69 */
71 public:
72 /**
73 * @brief Constructs a @c DatabaseReader for the given @p path.
74 *
75 * @param path Path to the @c .vdb file.
76 * @param read_only Open in read-only mode (no write operations allowed).
77 * @param try_to_fix Attempt repair if the database is corrupt.
78 */
79 explicit DatabaseReader(const std::string& path, bool read_only = true, bool try_to_fix = false);
80
81 /**
82 * @brief Destructor -- stops playback and closes the SQLite database handle.
83 */
84 ~DatabaseReader() override;
85
86 /**
87 * @brief Attaches a @c BagReaderPluginInterface for custom URL/type conversion.
88 *
89 * @param plugin_interface Plugin to bind. May be @c nullptr to detach.
90 */
91 void bind_plugin_interface(const std::shared_ptr<BagReaderPluginInterface>& plugin_interface) override;
92
93 /**
94 * @brief Registers a callback fired whenever the playback status changes.
95 *
96 * @param status_callback Callback receiving the new @c Status value.
97 */
98 void register_status_callback(StatusCallback&& status_callback) override;
99
100 /**
101 * @brief Registers a callback fired when the reader is ready to start playing.
102 *
103 * @param ready_callback Callback invoked once the file is open and parsed.
104 */
105 void register_ready_callback(ReadyCallback&& ready_callback) override;
106
107 /**
108 * @brief Registers a callback fired when playback ends or is interrupted.
109 *
110 * @param finish_callback Callback receiving the @c is_interrupted flag.
111 */
112 void register_finish_callback(FinishCallback&& finish_callback) override;
113
114 /**
115 * @brief Registers the callback that receives replayed messages.
116 *
117 * @param output_callback Called for each message during playback.
118 */
119 void register_output_callback(OutputCallback&& output_callback) override;
120
121 /**
122 * @brief Starts playback with the given configuration.
123 *
124 * @param config Playback configuration (rate, times, filters, etc.).
125 */
126 void play(const Config& config) override;
127
128 /**
129 * @brief Stops playback and resets the reader to the beginning.
130 */
131 void stop() override;
132
133 /**
134 * @brief Pauses playback at the current position.
135 */
136 void pause() override;
137
138 /**
139 * @brief Resumes a paused playback from the current position.
140 */
141 void resume() override;
142
143 /**
144 * @brief Advances one message while paused, then pauses again.
145 */
146 void pause_to_next() override;
147
148 /**
149 * @brief Seeks to @p begin_time and resumes playback.
150 *
151 * @param begin_time Seek target timestamp in milliseconds (relative to recording start).
152 * @param rate New playback rate multiplier.
153 * @param times Number of loops after the jump.
154 * @param force_to_play If @c true, forces play state even if currently paused.
155 */
156 void jump(int64_t begin_time, double rate, int times, bool force_to_play = false) override;
157
158 /**
159 * @brief Verifies the integrity of the SQLite bag file asynchronously.
160 *
161 * @return @c std::future<bool> that resolves to @c true if the file is intact.
162 */
163 std::future<bool> check() override;
164
165 /**
166 * @brief Rebuilds the index tables asynchronously.
167 *
168 * @return @c std::future<bool> that resolves to @c true on success.
169 */
170 std::future<bool> reindex() override;
171
172 /**
173 * @brief Repairs a corrupt SQLite bag file asynchronously.
174 *
175 * @param rebuild If @c true, rebuilds the entire index from scratch.
176 * @return @c std::future<bool> that resolves to @c true if repair succeeded.
177 */
178 std::future<bool> fix(bool rebuild = false) override;
179
180 /**
181 * @brief Updates the tag name stored in the bag metadata.
182 *
183 * @param tag_name New tag name string.
184 */
185 void tag(const std::string& tag_name) override;
186
187 /**
188 * @brief Returns the current playback position as a recording-relative timestamp.
189 *
190 * @return Current position in milliseconds relative to the recording start.
191 */
192 [[nodiscard]] int64_t get_timestamp() const override;
193
194 /**
195 * @brief Returns the real elapsed wall-clock time since playback started.
196 *
197 * @return Elapsed wall-clock time in milliseconds.
198 */
199 [[nodiscard]] int64_t get_real_timestamp() const override;
200
201 /**
202 * @brief Returns the current playback status.
203 *
204 * @return One of @c kStopped, @c kPaused, or @c kPlaying.
205 */
206 [[nodiscard]] Status get_status() const override;
207
208 /**
209 * @brief Returns the bag file metadata and per-URL statistics.
210 *
211 * @return Const reference to the @c Info struct populated at open time.
212 */
213 [[nodiscard]] const Info& get_info() const override;
214
215 /**
216 * @brief Scans the SQLite bag and returns all embedded schemas.
217 *
218 * @return Vector of @c SchemaData descriptors found in the bag.
219 */
220 [[nodiscard]] std::vector<SchemaData> detect_schema() override;
221
222 /**
223 * @brief Returns the serialisation type string for a given URL.
224 *
225 * @param url Topic URL to look up.
226 * @return Serialisation type (e.g., @c "demo.proto.PointCloud"), or empty if unknown.
227 */
228 [[nodiscard]] std::string get_ser_type(const std::string& url) const override;
229
230 /**
231 * @brief Returns the coarse schema family for a given URL.
232 *
233 * @param url Topic URL to look up.
234 * @return Schema family, or @c SchemaType::kUnknown if unavailable.
235 */
236 [[nodiscard]] SchemaType get_schema_type(const std::string& url) const override;
237
238 /**
239 * @brief Returns @c true if the bag spans multiple split files.
240 */
241 [[nodiscard]] bool is_split_mode() const override;
242
243 /**
244 * @brief Returns the zero-based index of the current split file being read.
245 */
246 [[nodiscard]] int get_split_index() const override;
247
248 /**
249 * @brief Returns @c true if a jump-to-timestamp seek is currently in progress.
250 */
251 [[nodiscard]] bool is_jumping() const override;
252
253 protected:
254 size_t get_max_task_count() const override;
255
256 void on_begin() override;
257
258 void on_end() override;
259
260 private:
261 void update_status(Status status);
262
263 void do_stop();
264
265 void do_pause();
266
267 void prepare_file(void* file);
268
269 void open(const std::string& path);
270
271 void close();
272
273 int get_reset_index(const Config& config);
274
275 void read(const Config& config);
276
277 std::unique_ptr<struct DatabaseReaderImpl> impl_;
278
280};
281
282} // namespace vlink
Abstract base class for VLink bag file playback with time-based seeking and rate control.
#define VLINK_EXPORT
定义 macros.h:85
#define VLINK_DISALLOW_COPY_AND_ASSIGN(classname)
Deletes the copy constructor and copy-assignment operator of classname.
定义 macros.h:184