UNPKG

@foxglove/rosbag2-node

Version:

ROS 2 (Robot Operating System) bag reader and writer for node.js

140 lines 5.35 kB
"use strict"; 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