Skip to content

Commit

Permalink
fix sql.type(...) bug with identifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
mmkal committed Sep 12, 2024
1 parent bc44508 commit bbf05b9
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 30 deletions.
17 changes: 7 additions & 10 deletions packages/client/src/sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,16 @@ const sqlMethodHelpers: SQLMethodHelpers = {
cause: type,
})
}
return (strings, ...parameters) => {
return {
parse: parseAsync,
name: nameQuery(strings),
sql: strings.join(''),
token: 'sql',
values: parameters,
templateArgs: () => [strings, ...parameters],
}
}
return (strings, ...parameters) => ({
...sqlFn(strings, ...parameters),
parse: parseAsync,
})
},
}

/**
* Template tag function. Walks through each string segment and parameter, and concatenates them into a valid SQL query.
*/
const sqlFn: SQLTagFunction = (strings, ...inputParameters) => {
let sql = ''
const values: unknown[] = []
Expand Down
10 changes: 4 additions & 6 deletions packages/client/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,15 @@ export type TypeNameIdentifier =
/* eslint-enable @typescript-eslint/no-redundant-type-constituents */

export type ZodesqueType<T> =
| ZodesqueTypeUnsafe<T>
| ZodesqueTypeSafe<T>
| ZodesqueTypeAsyncUnsafe<T>
| ZodesqueTypeAsyncSafe<T>
| ZodesqueTypeAsyncUnsafe<T>
| ZodesqueTypeUnsafe<T>
export type ZodesqueTypeUnsafe<T> = {parse: (input: unknown) => T}
export type ZodesqueTypeSafe<T> = {safeParse: (input: unknown) => ZodesqueResult<T>}
export type ZodesqueTypeAsyncUnsafe<T> = {parseAsync: (input: unknown) => Promise<T>}
export type ZodesqueTypeAsyncSafe<T> = {safeParseAsync: (input: unknown) => Promise<ZodesqueResult<T>>}
export type ZodesqueResult<T> =
| {success: true; data: T; error: undefined}
| {success: false; error: Error; data: undefined}
export type ZodesqueResult<T> = {success: true; data: T} | {success: false; error: Error}

export type SQLTagHelperParameters = {
array: [values: readonly PrimitiveValueExpression[], memberType: MemberType]
Expand Down Expand Up @@ -152,7 +150,7 @@ export type SQLTagFunction = <Row = Record<string, unknown>, Parameters extends

export type SQLMethodHelpers = {
raw: <T>(query: string) => SQLQuery<T, []>
type: <Row extends Record<string, unknown>>(
type: <Row>(
parser: ZodesqueType<Row>,
) => <Parameters extends SQLParameter[] = SQLParameter[]>(
strings: TemplateStringsArray,
Expand Down
3 changes: 0 additions & 3 deletions packages/client/test/pgp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ test('type parsers', async () => {
{"oid":194,"typname":"pg_node_tree","regtype":"pg_node_tree"},
{"oid":20,"typname":"int8","regtype":"bigint"},
{"oid":21,"typname":"int2","regtype":"smallint"},
{"oid":210,"typname":"_pg_type","regtype":"pg_type[]"},
{"oid":2202,"typname":"regprocedure","regtype":"regprocedure"},
{"oid":2203,"typname":"regoper","regtype":"regoper"},
{"oid":2204,"typname":"regoperator","regtype":"regoperator"},
Expand Down Expand Up @@ -298,8 +297,6 @@ test('type parsers', async () => {
{
"name": "SMGR",
"oid": 210,
"regtype": "pg_type[]",
"typname": "_pg_type",
},
{
"name": "PATH",
Expand Down
20 changes: 13 additions & 7 deletions packages/client/test/zod.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {beforeAll, beforeEach, expect, test} from 'vitest'
import {beforeAll, beforeEach, expect, expectTypeOf, test} from 'vitest'
import {z} from 'zod'
import {createClient, sql} from '../src'

Expand All @@ -16,14 +16,15 @@ beforeAll(async () => {
beforeEach(async () => {
await client.query(sql`
drop table if exists zod_test;
create table zod_test(id int, location text);
insert into zod_test values (1, '70,-108'), (2, '71,-102'), (3, '66,-90');
create table zod_test(id int, location text, label text);
insert into zod_test values (1, '70,-108', 'a'), (2, '71,-102', 'b'), (3, '66,-90', null);
`)
})

test('Transform rows', async () => {
const Row = z.object({
id: z.number(),
label: z.string().nullable(),
location: z
.string()
.regex(/^-?\d+,-?\d+$/)
Expand All @@ -37,30 +38,35 @@ test('Transform rows', async () => {
select * from zod_test
`)

// const result2 = await client.any(sql.type(Row)`
// select * from ${sql.identifier(['zod_test'])}
// `)
expectTypeOf(result).toEqualTypeOf<{id: number; label: string | null; location: {lat: number; lon: number}}[]>()

// expect(result2).toEqual(result)
const result2 = await client.any(sql.type(Row)`
select * from ${sql.identifier(['zod_test'])}
`)

expect(result2).toEqual(result)

expect(result).toMatchInlineSnapshot(`
[
{
"id": 1,
"label": "a",
"location": {
"lat": 70,
"lon": -108
}
},
{
"id": 2,
"label": "b",
"location": {
"lat": 71,
"lon": -102
}
},
{
"id": 3,
"label": null,
"location": {
"lat": 66,
"lon": -90
Expand Down
6 changes: 2 additions & 4 deletions packages/typegen/src/query/column-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,12 @@ export const analyzeAST = async (
}
}

const AnalyzeSelectStatementColumnsQuery = (statmentSql: string) => sql`
const AnalyzeSelectStatementColumnsQuery = (statmentSql: string) => sql.type(SelectStatementAnalyzedColumnSchema)`
--typegen-ignore
select * from ${sql.identifier([schemaName, 'analyze_select_statement_columns'])}(${statmentSql})
`
// todo: figure out why sql.type(MyZodType) isn't working here
let results = SelectStatementAnalyzedColumnSchema.array().parse(
await tx.any(AnalyzeSelectStatementColumnsQuery(astSql)),
)
let results = await tx.any(AnalyzeSelectStatementColumnsQuery(astSql))

results = lodash.uniqBy<SelectStatementAnalyzedColumn>(results, JSON.stringify)

Expand Down

0 comments on commit bbf05b9

Please sign in to comment.