@foxglove/rosbag2-node
Version:
ROS 2 (Robot Operating System) bag reader and writer for node.js
140 lines • 5.35 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SqliteNodejs = void 0;
const rosbag2_1 = require("@foxglove/rosbag2");
const rostime_1 = require("@foxglove/rostime");
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
class SqliteNodejs {
constructor(filename) {
this.filename = filename;
}
async open() {
if (this.context != undefined) {
return;
}
const db = new better_sqlite3_1.default(this.filename, { fileMustExist: true, readonly: true });
db.defaultSafeIntegers(); // return bigints by default
const timeRangeStatement = db.prepare("select min(timestamp) as start, max(timestamp) as end from messages");
const messageCountsStatement = db.prepare(`
select topics.name as name,count(*) as count
from messages
inner join topics on messages.topic_id = topics.id
group by topics.id`);
// Retrieve all of the topics
const idToTopic = new Map();
const topicNameToId = new Map();
const topicRows = db.prepare("select * from topics").all();
for (const row of topicRows) {
const { id, name, type, serialization_format, offered_qos_profiles } = row;
const offeredQosProfiles = (0, rosbag2_1.parseQosProfiles)(offered_qos_profiles ?? "[]");
const topic = { name, type, serializationFormat: serialization_format, offeredQosProfiles };
idToTopic.set(id, topic);
topicNameToId.set(name, id);
}
this.context = {
db,
timeRangeStatement,
messageCountsStatement,
idToTopic,
topicNameToId,
};
}
async close() {
if (this.context != undefined) {
this.context.db.close();
this.context = undefined;
}
}
async readTopics() {
if (this.context == undefined) {
throw new Error(`Call open() before reading topics`);
}
return Array.from(this.context.idToTopic.values());
}
readMessages(opts = {}) {
if (this.context == undefined) {
throw new Error(`Call open() before reading messages`);
}
const db = this.context.db;
const idToTopic = this.context.idToTopic;
const topicNameToId = this.context.topicNameToId;
// Build a SQL query and bind parameters
let args = [];
let query = `select topic_id,timestamp,data from messages`;
if (opts.startTime != undefined) {
query += ` where timestamp >= ?`;
args.push((0, rostime_1.toNanoSec)(opts.startTime));
}
if (opts.endTime != undefined) {
if (args.length === 0) {
query += ` where timestamp < ?`;
}
else {
query += ` and timestamp < ?`;
}
args.push((0, rostime_1.toNanoSec)(opts.endTime));
}
if (opts.topics != undefined) {
// Map topics to topic_ids
const topicIds = [];
for (const topicName of opts.topics) {
const topicId = topicNameToId.get(topicName);
if (topicId != undefined) {
topicIds.push(topicId);
}
}
if (topicIds.length === 0) {
if (args.length === 0) {
query += ` where topic_id = NULL`;
}
else {
query += ` and topic_id = NULL`;
}
}
else if (topicIds.length === 1) {
if (args.length === 0) {
query += ` where topic_id = ?`;
}
else {
query += ` and topic_id = ?`;
}
args.push(topicIds[0]);
}
else {
if (args.length === 0) {
query += ` where topic_id in (${topicIds.map(() => "?").join(",")})`;
}
else {
query += ` and topic_id in (${topicIds.map(() => "?").join(",")})`;
}
args = args.concat(topicIds);
}
}
const statement = db.prepare(query);
const iterator = statement.iterate(args);
return new rosbag2_1.RawMessageIterator(iterator, idToTopic);
}
async timeRange() {
if (this.context == undefined) {
throw new Error(`Call open() before retrieving the time range`);
}
const res = this.context.timeRangeStatement.get();
return [(0, rostime_1.fromNanoSec)(res.start ?? 0n), (0, rostime_1.fromNanoSec)(res.end ?? 0n)];
}
async messageCounts() {
if (this.context == undefined) {
throw new Error(`Call open() before retrieving message counts`);
}
const rows = this.context.messageCountsStatement.all();
const counts = new Map();
for (const { name, count } of rows) {
counts.set(name, Number(count));
}
return counts;
}
}
exports.SqliteNodejs = SqliteNodejs;
//# sourceMappingURL=SqliteNodejs.js.map