sqlite: Escape '%' and '_' in search queries. (#4487)
I picked '@' arbitrarily, it doesn't matter much. I just don't like '\' because it needs to be escaped itself in the JS code, which is annoying.
This commit is contained in:
parent
e4840b4d75
commit
20ed3e6dc5
@ -205,9 +205,12 @@ class MessageStorage {
|
|||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Using the '@' character to escape '%' and '_' in patterns.
|
||||||
|
const escapedSearchTerm = query.searchTerm.replace(/([%_@])/g, "@$1");
|
||||||
|
|
||||||
let select =
|
let select =
|
||||||
'SELECT msg, type, time, network, channel FROM messages WHERE type = "message" AND json_extract(msg, "$.text") LIKE ?';
|
'SELECT msg, type, time, network, channel FROM messages WHERE type = "message" AND json_extract(msg, "$.text") LIKE ? ESCAPE \'@\'';
|
||||||
const params = [`%${query.searchTerm}%`];
|
const params = [`%${escapedSearchTerm}%`];
|
||||||
|
|
||||||
if (query.networkUuid) {
|
if (query.networkUuid) {
|
||||||
select += " AND network = ? ";
|
select += " AND network = ? ";
|
||||||
|
@ -181,6 +181,68 @@ describe("SQLite Message Storage", function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should search messages with escaped wildcards", function () {
|
||||||
|
function assertResults(query, expected) {
|
||||||
|
return store
|
||||||
|
.search({
|
||||||
|
searchTerm: query,
|
||||||
|
networkUuid: "this-is-a-network-guid2",
|
||||||
|
})
|
||||||
|
.then((messages) => {
|
||||||
|
expect(messages.results.map((i) => i.text)).to.deep.equal(expected);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const originalMaxHistory = Helper.config.maxHistory;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Helper.config.maxHistory = 3;
|
||||||
|
|
||||||
|
store.index(
|
||||||
|
{uuid: "this-is-a-network-guid2"},
|
||||||
|
{name: "#channel"},
|
||||||
|
new Msg({
|
||||||
|
time: 123456790,
|
||||||
|
text: `foo % bar _ baz`,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
store.index(
|
||||||
|
{uuid: "this-is-a-network-guid2"},
|
||||||
|
{name: "#channel"},
|
||||||
|
new Msg({
|
||||||
|
time: 123456791,
|
||||||
|
text: `foo bar x baz`,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
store.index(
|
||||||
|
{uuid: "this-is-a-network-guid2"},
|
||||||
|
{name: "#channel"},
|
||||||
|
new Msg({
|
||||||
|
time: 123456792,
|
||||||
|
text: `bar @ baz`,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
store
|
||||||
|
.getMessages({uuid: "this-is-a-network-guid2"}, {name: "#channel"})
|
||||||
|
// .getMessages() waits for store.index() transactions to commit
|
||||||
|
.then(() => assertResults("foo", ["foo % bar _ baz", "foo bar x baz"]))
|
||||||
|
.then(() => assertResults("%", ["foo % bar _ baz"]))
|
||||||
|
.then(() => assertResults("foo % bar ", ["foo % bar _ baz"]))
|
||||||
|
.then(() => assertResults("_", ["foo % bar _ baz"]))
|
||||||
|
.then(() => assertResults("bar _ baz", ["foo % bar _ baz"]))
|
||||||
|
.then(() => assertResults("%%", []))
|
||||||
|
.then(() => assertResults("@%", []))
|
||||||
|
.then(() => assertResults("@", ["bar @ baz"]))
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
Helper.config.maxHistory = originalMaxHistory;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it("should close database", function (done) {
|
it("should close database", function (done) {
|
||||||
store.close((err) => {
|
store.close((err) => {
|
||||||
expect(err).to.be.null;
|
expect(err).to.be.null;
|
||||||
|
Loading…
Reference in New Issue
Block a user