@@ -82,7 +82,7 @@ class PuddySqlTags {
8282 #parseLimit = - 1 ;
8383
8484 /** @type {string|null } */
85- #defaultValueName = null ;
85+ #defaultTableName = null ;
8686
8787 /**
8888 * Creates an instance of the PuddySqlTags class.
@@ -356,13 +356,13 @@ class PuddySqlTags {
356356 }
357357
358358 /**
359- * Sets the alias name used in `EXISTS` subqueries, typically referencing `value`.
359+ * Sets the external table name name used in `EXISTS` subqueries, typically referencing `value`.
360360 *
361361 * @param {string } value - The alias to use in SQL subqueries (e.g. 'value').
362362 */
363- setValueName ( value ) {
363+ setTableName ( value ) {
364364 if ( typeof value !== 'string' ) throw new Error ( 'value must be a string' ) ;
365- this . #defaultValueName = value ;
365+ this . #defaultTableName = value ;
366366 }
367367
368368 /**
@@ -376,6 +376,30 @@ class PuddySqlTags {
376376 this . #jsonEach = value ;
377377 }
378378
379+ #isPgMode = false ;
380+
381+ /**
382+ * Sets whether the engine is running in PostgreSQL mode.
383+ *
384+ * @param {boolean } value - Must be a boolean true/false.
385+ * @throws {TypeError } If the value is not a boolean.
386+ */
387+ setIsPgMode ( value ) {
388+ if ( typeof value !== 'boolean' ) {
389+ throw new TypeError ( `setIsPgMode() expects a boolean, but received: ${ typeof value } ` ) ;
390+ }
391+ this . #isPgMode = value ;
392+ }
393+
394+ /**
395+ * Gets whether the engine is currently in PostgreSQL mode.
396+ *
397+ * @returns {boolean }
398+ */
399+ getIsPgMode ( ) {
400+ return this . #isPgMode;
401+ }
402+
379403 /**
380404 * Builds an SQL WHERE clause from a structured tag group definition.
381405 *
@@ -407,7 +431,7 @@ class PuddySqlTags {
407431
408432 const where = [ ] ;
409433 const tagsColumn = group . column || this . getColumnName ( ) ;
410- const tagsValue = group . valueName || this . #defaultValueName ;
434+ const tagsTable = group . tableName || this . #defaultTableName ;
411435 const allowWildcards = typeof group . allowWildcards === 'boolean' ? group . allowWildcards : false ;
412436
413437 if ( ! Array . isArray ( group . include ) )
@@ -417,17 +441,21 @@ class PuddySqlTags {
417441 const include = group . include ;
418442
419443 /**
420- * @param {string } funcName
444+ * @param {boolean } not
421445 * @param {string } param
422446 * @param {boolean } [useLike=false]
423447 * @returns {string }
424448 */
425- const createQuery = ( funcName , param , useLike = false ) =>
426- `${ funcName } (SELECT 1 FROM ${
427- this . #useJsonEach
428- ? `${ this . #jsonEach} (${ tagsColumn } ) WHERE value ${ useLike ? 'LIKE' : '=' } ${ param } `
429- : `${ tagsColumn } WHERE ${ tagsColumn } .${ tagsValue } ${ useLike ? 'LIKE' : '=' } ${ param } `
430- } )`;
449+ const createQuery = ( not , param , useLike = false ) =>
450+ // Sqlite3
451+ ! this . #isPgMode
452+ ? `${ not ? 'NOT ' : '' } EXISTS (SELECT 1 FROM ${
453+ this . #useJsonEach
454+ ? `${ this . #jsonEach} (${ tagsColumn } ) WHERE value ${ useLike ? 'LIKE' : '=' } ${ param } `
455+ : `${ tagsColumn } WHERE ${ tagsTable } .${ tagsColumn } ${ useLike ? 'LIKE' : '=' } ${ param } `
456+ } )`
457+ : // Postgre
458+ `${ not ? 'NOT (' : '' } ${ param } = ANY(${ tagsColumn } )${ not ? ')' : '' } ` ;
431459
432460 /**
433461 * @param {string } tag
@@ -464,12 +492,12 @@ class PuddySqlTags {
464492 // if (!clause.length) throw new SyntaxError('Empty OR group inside "include" array');
465493 const ors = clause . map ( ( tag ) => {
466494 const { param, usesWildcard, not } = filterTag ( tag ) ;
467- return createQuery ( ` ${ not ? 'NOT ' : '' } EXISTS` , param , usesWildcard ) ;
495+ return createQuery ( not , param , usesWildcard ) ;
468496 } ) ;
469497 if ( ors . length ) where . push ( `(${ ors . join ( ' OR ' ) } )` ) ;
470498 } else {
471499 const { param, usesWildcard, not } = filterTag ( clause ) ;
472- where . push ( createQuery ( ` ${ not ? 'NOT ' : '' } EXISTS` , param , usesWildcard ) ) ;
500+ where . push ( createQuery ( not , param , usesWildcard ) ) ;
473501 }
474502 }
475503
0 commit comments