feat: Implement 'Like' predicate in entity storage

This acts like the SQL 'LIKE' keyword, allowing partial string matches.
This commit is contained in:
Sam Atkins 2024-04-24 12:27:26 +01:00
parent d733119456
commit a854a0dc0a
2 changed files with 27 additions and 1 deletions

View File

@ -22,7 +22,7 @@ const { BaseES } = require("./BaseES");
const APIError = require("../../api/APIError"); const APIError = require("../../api/APIError");
const { Entity } = require("./Entity"); const { Entity } = require("./Entity");
const { WeakConstructorTrait } = require("../../traits/WeakConstructorTrait"); const { WeakConstructorTrait } = require("../../traits/WeakConstructorTrait");
const { And, Or, Eq, Predicate, Null, PredicateUtil } = require("../query/query"); const { And, Or, Eq, Like, Null, Predicate, PredicateUtil } = require("../query/query");
const { DB_WRITE } = require("../../services/database/consts"); const { DB_WRITE } = require("../../services/database/consts");
class RawCondition extends AdvancedBase { class RawCondition extends AdvancedBase {
@ -355,6 +355,22 @@ class SQLES extends BaseES {
return new RawCondition({ sql, values }); return new RawCondition({ sql, values });
} }
if ( om_query instanceof Like ) {
const key = om_query.key;
let value = om_query.value;
const prop = this.om.properties[key];
value = await prop.sql_reference(value);
const options = prop.descriptor.sql ?? {};
const col_name = options.column_name ?? prop.name;
const sql = `${col_name} LIKE ?`;
const values = [value];
return new RawCondition({ sql, values });
}
} }
} }
} }

View File

@ -50,6 +50,15 @@ class Eq extends Predicate {
} }
} }
class Like extends Predicate {
async check (entity) {
// Convert SQL LIKE pattern to RegExp
// TODO: Support escaping the pattern characters
const regex = new RegExp(this.value.replaceAll('%', '.*').replaceAll('_', '.'), 'i');
return regex.test(await entity.get(this.key));
}
}
Predicate.prototype.and = function (other) { Predicate.prototype.and = function (other) {
return new And({ children: [this, other] }); return new And({ children: [this, other] });
} }
@ -105,4 +114,5 @@ module.exports = {
And, And,
Or, Or,
Eq, Eq,
Like,
}; };