Skip to content

Commit add3641

Browse files
committed
adding json selector support per dialect
1 parent 37e9cba commit add3641

4 files changed

Lines changed: 62 additions & 0 deletions

File tree

packages/inquire/src/dialect/Mysql.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,30 @@ const Mysql: Dialect = {
557557

558558
return { query: query.join(' '), values };
559559
},
560+
561+
/**
562+
* Converts to proper JSON selector
563+
*/
564+
json(column: string, path: string, separator = '.') {
565+
if (path.length === 0) {
566+
return `JSON_UNQUOTE(JSON_EXTRACT(${q}${column}${q}, '$'))`;
567+
}
568+
//path examples to consider:
569+
// - 0: array root: JSON_EXTRACT(column, '$[0]')
570+
// - id: object key: JSON_EXTRACT(column, '$.id')
571+
// - 0.id: array of objects: JSON_EXTRACT(column, '$[0].id')
572+
// - ids.0: object with array value: JSON_EXTRACT(column, '$.ids[0]')
573+
const selector = path
574+
.split(separator)
575+
.filter(Boolean)
576+
.map(path => (
577+
/^\d+$/.test(path)
578+
? `[${path}]`
579+
: `."${path.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`
580+
))
581+
.join('');
582+
return `JSON_UNQUOTE(JSON_EXTRACT(${q}${column}${q}, '$${selector}'))`;
583+
}
560584
};
561585

562586
export default Mysql;

packages/inquire/src/dialect/Pgsql.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,27 @@ const Pgsql: Dialect = {
593593

594594
return { query: query.join(' '), values };
595595
},
596+
597+
/**
598+
* Converts to proper JSON selector
599+
*/
600+
json(column: string, path: string, separator = '.') {
601+
if (path.length === 0) {
602+
return `${q}${column}${q}::text`;
603+
}
604+
//path examples to consider:
605+
// - 0: array root: column->0
606+
// - id: object key: column->'id'
607+
// - 0.id: array of objects: column->0->'id'
608+
// - ids.0: object with array value: column->'ids'->0
609+
const paths = path.split(separator).filter(Boolean);
610+
const last = paths.pop()!;
611+
const selector = paths.map(
612+
part => /^\d+$/.test(part) ? `->${part}` : `->$$${part}$$`
613+
);
614+
selector.push(/^\d+$/.test(last) ? `->>${last}` : `->>$$${last}$$`)
615+
return `${q}${column}${q}${selector.join('')}`;
616+
}
596617
};
597618

598619
export default Pgsql;

packages/inquire/src/dialect/Sqlite.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,22 @@ const Sqlite: Dialect = {
504504

505505
return { query: query.join(' '), values };
506506
},
507+
508+
/**
509+
* Converts to proper JSON selector
510+
*/
511+
json(column: string, path: string, separator = '.') {
512+
if (path.length === 0) {
513+
return `json_extract(${q}${column}${q}, '$')`;
514+
}
515+
const selector = path
516+
.split(separator)
517+
.filter(Boolean)
518+
.map(path => /^\d+$/.test(path) ? `[${path}]` : `.${path}`)
519+
.join('');
520+
521+
return `json_extract(${q}${column}${q}, '$${selector}')`;
522+
}
507523
};
508524

509525
export default Sqlite;

packages/inquire/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export type Dialect = {
105105
select(builder: Select): QueryObject;
106106
truncate(table: string, cascade?: boolean): QueryObject;
107107
update(builder: Update): QueryObject;
108+
json(column: string, path: string, separator?: string): string;
108109
};
109110

110111
//--------------------------------------------------------------------//

0 commit comments

Comments
 (0)