Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix aws-data-api mapping in relational queries #677

Merged
merged 1 commit into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions drizzle-orm/.madgerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"detectiveOptions": {
"ts": {
"skipTypeImports": true
}
}
}
2 changes: 1 addition & 1 deletion drizzle-orm/src/alias.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { AnyColumn } from './column';
import { Column } from './column';
import { type Relation } from './relations';
import type { Relation } from './relations';
import { SQL, sql } from './sql';
import { Table } from './table';
import { type View, ViewBaseConfig } from './view';
Expand Down
30 changes: 15 additions & 15 deletions drizzle-orm/src/aws-data-api/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@ import type { Field } from '@aws-sdk/client-rds-data';
import { TypeHint } from '@aws-sdk/client-rds-data';
import type { QueryTypingsValue } from '~/sql';

export function getValueFromDataApi(row: Field) {
if (row.stringValue !== undefined) {
return row.stringValue;
} else if (row.booleanValue !== undefined) {
return row.booleanValue;
} else if (row.doubleValue !== undefined) {
return row.doubleValue;
} else if (row.isNull !== undefined) {
export function getValueFromDataApi(field: Field) {
if (field.stringValue !== undefined) {
return field.stringValue;
} else if (field.booleanValue !== undefined) {
return field.booleanValue;
} else if (field.doubleValue !== undefined) {
return field.doubleValue;
} else if (field.isNull !== undefined) {
return null;
} else if (row.longValue !== undefined) {
return row.longValue;
} else if (row.blobValue !== undefined) {
return row.blobValue;
} else if (field.longValue !== undefined) {
return field.longValue;
} else if (field.blobValue !== undefined) {
return field.blobValue;
// eslint-disable-next-line unicorn/no-negated-condition
} else if (row.arrayValue !== undefined) {
if (row.arrayValue.stringValues !== undefined) {
return row.arrayValue.stringValues;
} else if (field.arrayValue !== undefined) {
if (field.arrayValue.stringValues !== undefined) {
return field.arrayValue.stringValues;
}
throw new Error('Unknown array type');
} else {
Expand Down
12 changes: 6 additions & 6 deletions drizzle-orm/src/aws-data-api/pg/session.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ExecuteStatementCommandOutput, RDSDataClient } from '@aws-sdk/client-rds-data';
import type { ExecuteStatementCommandOutput, Field, RDSDataClient } from '@aws-sdk/client-rds-data';
import {
BeginTransactionCommand,
CommitTransactionCommand,
Expand Down Expand Up @@ -35,7 +35,7 @@ export class AwsDataApiPreparedQuery<T extends PreparedQueryConfig> extends Prep
private fields: SelectedFieldsOrdered | undefined,
/** @internal */
readonly transactionId: string | undefined,
private customResultMapper?: (rows: unknown[][]) => T['execute'],
private customResultMapper?: (rows: unknown[][], mapColumnValue: (value: unknown) => unknown) => T['execute'],
) {
super();
this.rawQuery = new ExecuteStatementCommand({
Expand All @@ -56,7 +56,7 @@ export class AwsDataApiPreparedQuery<T extends PreparedQueryConfig> extends Prep
return rows as T['execute'];
}
return customResultMapper
? customResultMapper(rows)
? customResultMapper(rows, (field) => getValueFromDataApi(field as Field))
: rows.map((row) => mapResultRow<T['execute']>(fields!, row, joinsNotNullableMap));
}

Expand All @@ -82,8 +82,8 @@ export class AwsDataApiPreparedQuery<T extends PreparedQueryConfig> extends Prep

const result = await client.send(rawQuery);

return result.records?.map((result: any) => {
return result.map((res: any) => getValueFromDataApi(res));
return result.records?.map((row: any) => {
return row.map((field: Field) => getValueFromDataApi(field));
});
}
}
Expand Down Expand Up @@ -129,7 +129,7 @@ export class AwsDataApiSession<
query: Query,
fields: SelectedFieldsOrdered | undefined,
transactionId?: string,
customResultMapper?: (rows: unknown[][]) => T['execute'],
customResultMapper?: (rows: unknown[][], mapColumnValue: (value: unknown) => unknown) => T['execute'],
): PreparedQuery<T> {
return new AwsDataApiPreparedQuery(
this.client,
Expand Down
14 changes: 8 additions & 6 deletions drizzle-orm/src/pg-core/query-builders/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import {
type TableRelationalConfig,
type TablesRelationalConfig,
} from '~/relations';
import { type SQL } from '~/sql';
import type { SQL } from '~/sql';
import { tracer } from '~/tracing';
import { type KnownKeysOnly } from '~/utils';
import { type PgDialect } from '../dialect';
import { type PgSession, type PreparedQuery, type PreparedQueryConfig } from '../session';
import type { KnownKeysOnly } from '~/utils';
import type { PgDialect } from '../dialect';
import type { PgSession, PreparedQuery, PreparedQueryConfig } from '../session';
import { type AnyPgTable } from '../table';

export class RelationalQueryBuilder<TSchema extends TablesRelationalConfig, TFields extends TableRelationalConfig> {
Expand Down Expand Up @@ -93,8 +93,10 @@ export class PgRelationalQuery<TResult> extends QueryPromise<TResult> {
builtQuery,
undefined,
name,
(rawRows) => {
const rows = rawRows.map((row) => mapRelationalRow(this.schema, this.tableConfig, row, query.selection));
(rawRows, mapColumnValue) => {
const rows = rawRows.map((row) =>
mapRelationalRow(this.schema, this.tableConfig, row, query.selection, mapColumnValue)
);
if (this.mode === 'first') {
return rows[0] as TResult;
}
Expand Down
2 changes: 1 addition & 1 deletion drizzle-orm/src/pg-core/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export abstract class PgSession<
query: Query,
fields: SelectedFieldsOrdered | undefined,
name: string | undefined,
customResultMapper?: (rows: unknown[][]) => T['execute'],
customResultMapper?: (rows: unknown[][], mapColumnValue?: (value: unknown) => unknown) => T['execute'],
): PreparedQuery<T>;

execute<T>(query: SQL): Promise<T> {
Expand Down
8 changes: 4 additions & 4 deletions drizzle-orm/src/pg-core/table.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { BuildColumns } from '~/column-builder';
import { type AnyTableHKT, Table, type TableConfig as TableConfigBase, type UpdateTableConfig } from '~/table';
import { type Assume } from '~/utils';
import { type CheckBuilder } from './checks';
import type { Assume } from '~/utils';
import type { CheckBuilder } from './checks';
import type { AnyPgColumn, AnyPgColumnBuilder } from './columns/common';
import type { ForeignKey, ForeignKeyBuilder } from './foreign-keys';
import { type AnyIndexBuilder } from './indexes';
import { type PrimaryKeyBuilder } from './primary-keys';
import type { AnyIndexBuilder } from './indexes';
import type { PrimaryKeyBuilder } from './primary-keys';

export type PgTableExtraConfig = Record<
string,
Expand Down
9 changes: 4 additions & 5 deletions drizzle-orm/src/relations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,25 +493,23 @@ export function mapRelationalRow(
tableConfig: TableRelationalConfig,
row: unknown[],
buildQueryResultSelection: BuildRelationalQueryResult['selection'],
jsonParseRelationalFields = false,
mapColumnValue: (value: unknown) => unknown = (value) => value,
): Record<string, unknown> {
const result: Record<string, unknown> = {};

for (const [selectionItemIndex, selectionItem] of buildQueryResultSelection.entries()) {
if (selectionItem.isJson) {
const relation = tableConfig.relations[selectionItem.tsKey]!;
let subRows = row[selectionItemIndex] as unknown[][];
if (jsonParseRelationalFields) {
subRows = JSON.parse(subRows as unknown as string);
}
const rawSubRows = row[selectionItemIndex] as unknown[][] | string;
const subRows = typeof rawSubRows === 'string' ? JSON.parse(rawSubRows) as unknown[][] : rawSubRows;
if (relation instanceof One) {
result[selectionItem.tsKey] = subRows[0]
? mapRelationalRow(
tablesConfig,
tablesConfig[selectionItem.tableTsKey!]!,
subRows[0],
selectionItem.selection,
mapColumnValue,
)
: null;
} else {
Expand All @@ -521,6 +519,7 @@ export function mapRelationalRow(
tablesConfig[selectionItem.tableTsKey!]!,
subRow as unknown[],
selectionItem.selection,
mapColumnValue,
)
);
}
Expand Down
2 changes: 1 addition & 1 deletion drizzle-orm/src/sqlite-core/query-builders/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export class SQLiteRelationalQuery<TResultKind extends 'sync' | 'async', TResult
undefined,
(rawRows, mapColumnValue) => {
const rows = rawRows.map((row) =>
mapRelationalRow(this.schema, this.tableConfig, row, query.selection, true, mapColumnValue)
mapRelationalRow(this.schema, this.tableConfig, row, query.selection, mapColumnValue)
);
if (this.mode === 'first') {
return rows[0] as TResult;
Expand Down
101 changes: 93 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.