fhir-persistence 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -324,7 +324,7 @@ export declare function buildWhereClauseV2(params: ParsedSearchParam[], registry
324
324
  * - SQLite: json_each() for array columns
325
325
  * - PostgreSQL: native ARRAY operators
326
326
  */
327
- export declare function buildWhereFragmentV2(impl: SearchParameterImpl, param: ParsedSearchParam, dialect?: SqlDialect): WhereFragment | null;
327
+ export declare function buildWhereFragmentV2(impl: SearchParameterImpl, param: ParsedSearchParam, dialect?: SqlDialect, resourceType?: string): WhereFragment | null;
328
328
 
329
329
  declare interface BundleLink {
330
330
  relation: string;
@@ -324,7 +324,7 @@ export declare function buildWhereClauseV2(params: ParsedSearchParam[], registry
324
324
  * - SQLite: json_each() for array columns
325
325
  * - PostgreSQL: native ARRAY operators
326
326
  */
327
- export declare function buildWhereFragmentV2(impl: SearchParameterImpl, param: ParsedSearchParam, dialect?: SqlDialect): WhereFragment | null;
327
+ export declare function buildWhereFragmentV2(impl: SearchParameterImpl, param: ParsedSearchParam, dialect?: SqlDialect, resourceType?: string): WhereFragment | null;
328
328
 
329
329
  declare interface BundleLink {
330
330
  relation: string;
@@ -5077,12 +5077,12 @@ function arrayContainsLikeV2(col, value, dialect) {
5077
5077
  }
5078
5078
  return { sql: `EXISTS (SELECT 1 FROM json_each(${col}) WHERE json_each.value LIKE ?)`, values: [value] };
5079
5079
  }
5080
- function buildWhereFragmentV2(impl, param, dialect) {
5080
+ function buildWhereFragmentV2(impl, param, dialect, resourceType) {
5081
5081
  if (param.modifier === "missing") {
5082
5082
  return buildMissingFragmentV2(impl, param);
5083
5083
  }
5084
5084
  if (impl.strategy === "lookup-table") {
5085
- return buildLookupTableFragmentV2(impl, param);
5085
+ return buildLookupTableFragmentV2(impl, param, resourceType ?? "Resource");
5086
5086
  }
5087
5087
  if (impl.strategy === "token-column") {
5088
5088
  return buildTokenColumnFragmentV2(impl, param, dialect);
@@ -5110,7 +5110,7 @@ function buildMissingFragmentV2(impl, param) {
5110
5110
  const col = quoteColumn(impl.columnName);
5111
5111
  return { sql: isMissing ? `${col} IS NULL` : `${col} IS NOT NULL`, values: [] };
5112
5112
  }
5113
- function buildLookupTableFragmentV2(impl, param) {
5113
+ function buildLookupTableFragmentV2(impl, param, resourceType) {
5114
5114
  const mapping = LOOKUP_TABLE_MAP[impl.code];
5115
5115
  if (!mapping) {
5116
5116
  const sortCol = quoteColumn(`__${impl.columnName}Sort`);
@@ -5120,25 +5120,26 @@ function buildLookupTableFragmentV2(impl, param) {
5120
5120
  }
5121
5121
  const { table, column } = mapping;
5122
5122
  const colRef = `__lookup."${column}"`;
5123
+ const outerIdRef = `"${resourceType}"."id"`;
5123
5124
  if (param.modifier === "exact") {
5124
5125
  if (param.values.length === 1) {
5125
- return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = "id" AND ${colRef} = ?)`, values: [param.values[0]] };
5126
+ return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = ${outerIdRef} AND ${colRef} = ?)`, values: [param.values[0]] };
5126
5127
  }
5127
5128
  const conds2 = param.values.map(() => `${colRef} = ?`);
5128
- return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = "id" AND (${conds2.join(" OR ")}))`, values: [...param.values] };
5129
+ return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = ${outerIdRef} AND (${conds2.join(" OR ")}))`, values: [...param.values] };
5129
5130
  }
5130
5131
  if (param.modifier === "contains") {
5131
5132
  if (param.values.length === 1) {
5132
- return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = "id" AND LOWER(${colRef}) LIKE ?)`, values: [`%${param.values[0].toLowerCase()}%`] };
5133
+ return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = ${outerIdRef} AND LOWER(${colRef}) LIKE ?)`, values: [`%${param.values[0].toLowerCase()}%`] };
5133
5134
  }
5134
5135
  const conds2 = param.values.map(() => `LOWER(${colRef}) LIKE ?`);
5135
- return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = "id" AND (${conds2.join(" OR ")}))`, values: param.values.map((v) => `%${v.toLowerCase()}%`) };
5136
+ return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = ${outerIdRef} AND (${conds2.join(" OR ")}))`, values: param.values.map((v) => `%${v.toLowerCase()}%`) };
5136
5137
  }
5137
5138
  if (param.values.length === 1) {
5138
- return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = "id" AND LOWER(${colRef}) LIKE ?)`, values: [`${param.values[0].toLowerCase()}%`] };
5139
+ return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = ${outerIdRef} AND LOWER(${colRef}) LIKE ?)`, values: [`${param.values[0].toLowerCase()}%`] };
5139
5140
  }
5140
5141
  const conds = param.values.map(() => `LOWER(${colRef}) LIKE ?`);
5141
- return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = "id" AND (${conds.join(" OR ")}))`, values: param.values.map((v) => `${v.toLowerCase()}%`) };
5142
+ return { sql: `EXISTS (SELECT 1 FROM "${table}" __lookup WHERE __lookup."resourceId" = ${outerIdRef} AND (${conds.join(" OR ")}))`, values: param.values.map((v) => `${v.toLowerCase()}%`) };
5142
5143
  }
5143
5144
  function buildStringFragmentV2(impl, param) {
5144
5145
  const col = quoteColumn(impl.columnName);
@@ -5307,7 +5308,7 @@ function buildWhereClauseV2(params, registry, resourceType, dialect) {
5307
5308
  }
5308
5309
  const impl = resolveImplV2(param, registry, resourceType);
5309
5310
  if (!impl) continue;
5310
- const fragment = buildWhereFragmentV2(impl, param, dialect);
5311
+ const fragment = buildWhereFragmentV2(impl, param, dialect, resourceType);
5311
5312
  if (fragment) {
5312
5313
  fragments.push(fragment);
5313
5314
  }
@@ -7155,6 +7156,14 @@ function generateMigration(deltas, dialect) {
7155
7156
  const down = [];
7156
7157
  const reindexDeltas = [];
7157
7158
  const descriptions = [];
7159
+ const needsPgExtensions = deltas.some((d) => d.kind === "ADD_TABLE" || d.kind === "ADD_INDEX");
7160
+ if (dialect === "postgres" && needsPgExtensions) {
7161
+ up.push("CREATE EXTENSION IF NOT EXISTS pg_trgm;");
7162
+ up.push("CREATE EXTENSION IF NOT EXISTS btree_gin;");
7163
+ up.push(
7164
+ `CREATE OR REPLACE FUNCTION token_array_to_text(arr text[]) RETURNS text LANGUAGE sql IMMUTABLE AS $$ SELECT array_to_string(arr, ' ') $$;`
7165
+ );
7166
+ }
7158
7167
  for (const delta of deltas) {
7159
7168
  switch (delta.kind) {
7160
7169
  case "ADD_TABLE": {