-
Notifications
You must be signed in to change notification settings - Fork 149
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
feat (client): make converter API public #1397
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
elixir 1.17.0-otp-27 | ||
erlang 27.0 | ||
nodejs 20.2.0 | ||
nodejs 21.4.0 | ||
pnpm 9.4.0 | ||
# keep synchronised with version pinned in .github/workflows/satellite_proto.yml | ||
protoc 26.1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
import { Row } from '../../util' | ||
import { AnyTableSchema } from '../model' | ||
import { PgType } from './types' | ||
|
||
export interface Converter { | ||
|
@@ -7,12 +9,48 @@ export interface Converter { | |
* @param pgType The Postgres type of the column in which to store the value. | ||
*/ | ||
encode(v: any, pgType: PgType): any | ||
/** | ||
* Encodes the provided row for storing in the database. | ||
* @param row The row to encode | ||
* @param tableSchema The schema of the table for this row. | ||
*/ | ||
encodeRow( | ||
row: Record<string, unknown>, | ||
tableSchema: Pick<AnyTableSchema, 'fields'> | ||
): Row | ||
/** | ||
* Encodes the provided rows for storing in the database. | ||
* @param rows The rows to encode | ||
* @param tableSchema The schema of the table for these rows. | ||
*/ | ||
encodeRows( | ||
rows: Array<Record<string, unknown>>, | ||
tableSchema: Pick<AnyTableSchema, 'fields'> | ||
): Array<Row> | ||
/** | ||
* Decodes the provided value from the database. | ||
* @param v The value to decode. | ||
* @param pgType The Postgres type of the column from which to decode the value. | ||
*/ | ||
decode(v: any, pgType: PgType): any | ||
/** | ||
* Decodes the provided row from the database. | ||
* @param row The row to decode | ||
* @param tableSchema The schema of the table for this row. | ||
*/ | ||
decodeRow<T extends Record<string, any> = Record<string, any>>( | ||
row: Record<string, unknown>, | ||
tableSchema: Pick<AnyTableSchema, 'fields'> | ||
): T | ||
/** | ||
* Decodes the provided rows from the database. | ||
* @param rows The rows to decode | ||
* @param tableSchema The schema of the table for these rows. | ||
*/ | ||
decodeRows<T extends Record<string, any> = Record<string, any>>( | ||
rows: Array<Record<string, unknown>>, | ||
tableSchema: Pick<AnyTableSchema, 'fields'> | ||
): Array<T> | ||
} | ||
|
||
/** | ||
|
@@ -26,3 +64,34 @@ export interface Converter { | |
export function isDataObject(v: unknown): boolean { | ||
return v instanceof Date || typeof v === 'bigint' || ArrayBuffer.isView(v) | ||
} | ||
|
||
export function mapRow< | ||
T extends Record<string, unknown> = Record<string, unknown> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: might be worth extracting |
||
>( | ||
row: Record<string, unknown>, | ||
tableSchema: Pick<AnyTableSchema, 'fields'>, | ||
f: (v: any, pgType: PgType) => any | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: more explicit name like |
||
): T { | ||
const mappedRow = {} as T | ||
|
||
for (const [key, value] of Object.entries(row)) { | ||
const pgType = tableSchema.fields[key] | ||
const mappedValue = | ||
pgType === undefined | ||
? value // it's an unknown column, leave it as is | ||
: f(value, pgType) | ||
mappedRow[key as keyof T] = mappedValue | ||
} | ||
|
||
return mappedRow | ||
} | ||
|
||
export function mapRows< | ||
T extends Record<string, unknown> = Record<string, unknown> | ||
>( | ||
rows: Array<Record<string, unknown>>, | ||
tableSchema: Pick<AnyTableSchema, 'fields'>, | ||
f: (v: any, pgType: PgType) => any | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: same as above |
||
): T[] { | ||
return rows.map((row) => mapRow<T>(row, tableSchema, f)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export { postgresConverter } from './postgres' | ||
export type { Converter } from './converter' | ||
export { sqliteConverter } from './sqlite' | ||
export { postgresConverter } from './postgres' | ||
export { PgBasicType } from './types' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,9 @@ | ||
import { InvalidArgumentError } from '../validation/errors/invalidArgumentError' | ||
import { Converter } from './converter' | ||
import { Converter, mapRow, mapRows } from './converter' | ||
import { deserialiseDate, serialiseDate } from './datatypes/date' | ||
import { isJsonNull } from './datatypes/json' | ||
import { PgBasicType, PgDateType, PgType } from './types' | ||
import { AnyTableSchema } from '../model/schema' | ||
|
||
/** | ||
* This module takes care of converting TypeScript values to a Postgres storeable value and back. | ||
|
@@ -11,7 +12,7 @@ import { PgBasicType, PgDateType, PgType } from './types' | |
* Currently, no conversions are needed for the data types we support. | ||
*/ | ||
|
||
function toPostgres(v: any, pgType: PgType): any { | ||
export function toPostgres(v: any, pgType: PgType): any { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: why are these exported, they are exported via the converter interface no? (same for SQLite) |
||
if (v === null) { | ||
// don't transform null values | ||
return v | ||
|
@@ -52,7 +53,7 @@ function toPostgres(v: any, pgType: PgType): any { | |
} | ||
} | ||
|
||
function fromPostgres(v: any, pgType: PgType): any { | ||
export function fromPostgres(v: any, pgType: PgType): any { | ||
if (v === null) { | ||
// don't transform null values | ||
return v | ||
|
@@ -97,5 +98,21 @@ function fromPostgres(v: any, pgType: PgType): any { | |
|
||
export const postgresConverter: Converter = { | ||
encode: toPostgres, | ||
encodeRow: <T extends Record<string, unknown> = Record<string, unknown>>( | ||
row: Record<string, unknown>, | ||
tableSchema: AnyTableSchema | ||
) => mapRow<T>(row, tableSchema, toPostgres), | ||
encodeRows: <T extends Record<string, unknown> = Record<string, unknown>>( | ||
rows: Array<Record<string, unknown>>, | ||
tableSchema: AnyTableSchema | ||
) => mapRows<T>(rows, tableSchema, toPostgres), | ||
decode: fromPostgres, | ||
decodeRow: <T extends Record<string, any> = Record<string, any>>( | ||
row: Record<string, unknown>, | ||
tableSchema: AnyTableSchema | ||
) => mapRow<T>(row, tableSchema, fromPostgres), | ||
decodeRows: <T extends Record<string, any> = Record<string, any>>( | ||
rows: Array<Record<string, unknown>>, | ||
tableSchema: AnyTableSchema | ||
) => mapRows<T>(rows, tableSchema, fromPostgres), | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might need to update the CI workflows to use this version as well in the test matrix, build, etc