Skip to content

Commit 8f2ada1

Browse files
committed
Guard queue replay migration edge cases
1 parent d7ebe6d commit 8f2ada1

3 files changed

Lines changed: 38 additions & 9 deletions

File tree

brain-bar/Sources/BrainBar/BrainDatabase.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,7 +1469,8 @@ final class BrainDatabase: @unchecked Sendable {
14691469
try execute("""
14701470
CREATE INDEX IF NOT EXISTS idx_chunks_brainbar_queue_id
14711471
ON chunks(json_extract(metadata, '$.brainbar_queue_id'))
1472-
WHERE json_extract(metadata, '$.brainbar_queue_id') IS NOT NULL
1472+
WHERE json_valid(metadata)
1473+
AND json_extract(metadata, '$.brainbar_queue_id') IS NOT NULL
14731474
""")
14741475
}
14751476

@@ -1579,11 +1580,7 @@ final class BrainDatabase: @unchecked Sendable {
15791580
queueID: queueID,
15801581
queuedAt: item.queuedAt
15811582
)
1582-
guard var data = try? JSONEncoder().encode(replayItem) else {
1583-
return nil
1584-
}
1585-
data.append(0x0A)
1586-
return data
1583+
return try? JSONEncoder().encode(replayItem)
15871584
}
15881585

15891586
private static func deterministicPendingStoreQueueID(
@@ -1648,7 +1645,8 @@ final class BrainDatabase: @unchecked Sendable {
16481645
let sql = """
16491646
SELECT 1
16501647
FROM chunks
1651-
WHERE json_extract(metadata, '$.brainbar_queue_id') = ?
1648+
WHERE json_valid(metadata)
1649+
AND json_extract(metadata, '$.brainbar_queue_id') = ?
16521650
LIMIT 1
16531651
"""
16541652
let rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nil)

brain-bar/Tests/BrainBarTests/DatabaseTests.swift

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ final class DatabaseTests: XCTestCase {
9191
let sql = try sqliteMasterSQL(name: "idx_chunks_brainbar_queue_id", path: tempDBPath)
9292

9393
XCTAssertTrue(sql.contains("json_extract(metadata, '$.brainbar_queue_id')"))
94-
XCTAssertTrue(sql.contains("WHERE json_extract(metadata, '$.brainbar_queue_id') IS NOT NULL"))
94+
XCTAssertTrue(sql.contains("json_valid(metadata)"))
95+
XCTAssertTrue(sql.contains("json_extract(metadata, '$.brainbar_queue_id') IS NOT NULL"))
9596
}
9697

9798
func testQueueIDExpressionIndexMigratesExistingSchema() throws {
@@ -119,6 +120,34 @@ final class DatabaseTests: XCTestCase {
119120
XCTAssertTrue(sql.contains("json_extract(metadata, '$.brainbar_queue_id')"))
120121
}
121122

123+
func testQueueIDExpressionIndexMigratesExistingSchemaWithMalformedMetadata() throws {
124+
let legacyPath = NSTemporaryDirectory() + "brainbar-legacy-malformed-\(UUID().uuidString).db"
125+
try sqliteExecWrite(
126+
path: legacyPath,
127+
sql: """
128+
CREATE TABLE chunks (
129+
id TEXT PRIMARY KEY,
130+
content TEXT NOT NULL,
131+
metadata TEXT NOT NULL DEFAULT '{}'
132+
);
133+
INSERT INTO chunks (id, content, metadata)
134+
VALUES ('legacy-bad-metadata', 'Legacy malformed metadata row', '{not json');
135+
"""
136+
)
137+
defer {
138+
try? FileManager.default.removeItem(atPath: legacyPath)
139+
try? FileManager.default.removeItem(atPath: legacyPath + "-wal")
140+
try? FileManager.default.removeItem(atPath: legacyPath + "-shm")
141+
}
142+
143+
let legacyDB = BrainDatabase(path: legacyPath)
144+
defer { legacyDB.close() }
145+
146+
XCTAssertTrue(legacyDB.isOpen)
147+
let sql = try sqliteMasterSQL(name: "idx_chunks_brainbar_queue_id", path: legacyPath)
148+
XCTAssertTrue(sql.contains("json_valid(metadata)"))
149+
}
150+
122151
func testQueueIDLookupUsesExpressionIndex() throws {
123152
db.exec("""
124153
INSERT INTO chunks (
@@ -144,7 +173,8 @@ final class DatabaseTests: XCTestCase {
144173
EXPLAIN QUERY PLAN
145174
SELECT 1
146175
FROM chunks
147-
WHERE json_extract(metadata, '$.brainbar_queue_id') = ?
176+
WHERE json_valid(metadata)
177+
AND json_extract(metadata, '$.brainbar_queue_id') = ?
148178
LIMIT 1
149179
""",
150180
binds: ["brainbar-pending-lookup"]

brain-bar/Tests/BrainBarTests/MCPRouterTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,7 @@ final class MCPRouterTests: XCTestCase {
765765
XCTAssertTrue(FileManager.default.fileExists(atPath: queuePath.path))
766766
let compactedQueue = try String(contentsOf: queuePath, encoding: .utf8)
767767
XCTAssertTrue(compactedQueue.contains("queue_id"))
768+
XCTAssertFalse(compactedQueue.contains("\n\n"))
768769

769770
try sqliteExec(path: dbPath, sql: "DROP TRIGGER fail_second_repeated_legacy_insert")
770771

0 commit comments

Comments
 (0)