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

Feature: Implement overriding postgres types using a custom type map #45

Merged
merged 3 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
11 changes: 11 additions & 0 deletions examples/hello-custom-type/input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface test_type {
name: string
age: number
}

export function hello(test: test_type[]): test_type {
return {
name: `Hello ${test[0].name}`,
age: test[0].age,
}
}
14 changes: 14 additions & 0 deletions examples/hello-custom-type/plv8ify-dist/plv8ify_hello.plv8.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
DROP FUNCTION IF EXISTS plv8ify_hello(test test_type[]);
CREATE OR REPLACE FUNCTION plv8ify_hello(test test_type[]) RETURNS test_type AS $plv8ify$
// input.ts
function hello(test) {
return {
name: `Hello ${test[0].name}`,
age: test[0].age
};
}


return hello(test)

$plv8ify$ LANGUAGE plv8 IMMUTABLE STRICT;
8 changes: 8 additions & 0 deletions examples/hello-custom-type/types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
typeMap = {
number: 'float8',
string: 'text',
boolean: 'boolean',
Uint8: 'bytea',
test_type: 'test_type',
'test_type[]': 'test_type[]',
}
3 changes: 2 additions & 1 deletion src/commands/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ export async function generateCommand(
fallbackReturnType,
mode,
defaultVolatility,
typesFilePath,
} = CLI.config

fs.mkdirSync(outputFolderPath, { recursive: true })

const plv8ify = new PLV8ifyCLI(bundler)
plv8ify.init(inputFilePath)
plv8ify.init(inputFilePath, typesFilePath)

const bundledJs = await plv8ify.build({
mode,
Expand Down
3 changes: 3 additions & 0 deletions src/helpers/ParseCLI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export class ParseCLI {
const args = arg({
'--input-file': String,
'--output-folder': String,
'--types-config-file': String,
'--bundler': String, // 'esbuild' or 'bun'
'--write-bundler-output': Boolean,
'--scope-prefix': String,
Expand Down Expand Up @@ -40,6 +41,7 @@ Please specify a command. Available commands: generate, version, deploy
const mode = (args['--mode'] || 'inline') as Mode
const defaultVolatility = (args['--volatility'] ||
'IMMUTABLE') as Volatility
const typesFilePath = args['--types-config-file'] || 'types.ts'

return {
command: args._[0] as Command,
Expand All @@ -54,6 +56,7 @@ Please specify a command. Available commands: generate, version, deploy
fallbackReturnType,
mode,
defaultVolatility,
typesFilePath,
},
}
}
Expand Down
27 changes: 27 additions & 0 deletions src/impl/PLV8ifyCLI.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,31 @@ function test() {
})
expect(sql).toMatchSnapshot()
})

it('getSQLFunction with custom type', async () => {
const plv8ify = new PLV8ifyCLI()
plv8ify.init('', './src/test-fixtures/types-custom.fixture.js')

const sql = plv8ify.getPLV8SQLFunction({
fn: {
name: 'test',
parameters: [{ name: 'test', type: 'test_type[]' }],
comments: [],
} as TSFunction,
scopePrefix: 'plv8ify',
mode: 'inline',
defaultVolatility: 'IMMUTABLE',
bundledJs: `
export function hello(test: test_type[]) {
return {
name: "Hello" + test[0].name,
age: test[0].age,
}
}
`,
pgFunctionDelimiter: '$plv8ify$',
fallbackReturnType: 'JSONB',
})
expect(sql).toMatchSnapshot()
})
})
32 changes: 28 additions & 4 deletions src/impl/PLV8ifyCLI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,14 @@ export class PLV8ifyCLI implements PLV8ify {
this._tsCompiler = new TsMorph()
}

init(inputFilePath: string) {
this._tsCompiler.createSourceFile(inputFilePath)
init(inputFilePath: string, typesFilePath?: string) {
if (fs.existsSync(inputFilePath)) {
this._tsCompiler.createSourceFile(inputFilePath)
}
this._typeMap = {
...this._typeMap,
...this.getCustomTypeMap(typesFilePath),
}
}

private removeExportBlock(bundledJs: string) {
Expand Down Expand Up @@ -93,6 +99,19 @@ export class PLV8ifyCLI implements PLV8ify {
this.writeFile(path, string)
}

private getCustomTypeMap(typesFilePath: string) {
let customTypeMap = null
let typeMap = {}
if (fs.existsSync(typesFilePath)) {
customTypeMap = fs.readFileSync(typesFilePath, 'utf8')
eval(customTypeMap)
return typeMap
} else {
console.log(`Not found types file: ${typesFilePath}`)
}
return {}
}

private getScopedName(fn: TSFunction, scopePrefix: string) {
const scopedName = scopePrefix + '_' + fn.name
return scopedName
Expand All @@ -106,6 +125,11 @@ export class PLV8ifyCLI implements PLV8ify {
const scopedName = this.getScopedName(fn, scopePrefix)
return `${outputFolder}/${scopedName}.plv8.sql`
}
private getTypeFromMap(type: string) {
const typeLocal = type.split('.').pop()
//console.log(`Original type: ${type}, Converted type: ${typeLocal} `)
mattiarossi marked this conversation as resolved.
Show resolved Hide resolved
return this._typeMap[typeLocal ?? type]
}

private getFunctions() {
return this._tsCompiler.getFunctions().map((fn) => {
Expand All @@ -114,7 +138,7 @@ export class PLV8ifyCLI implements PLV8ify {
}
return {
...fn,
returnType: this._typeMap[fn.returnType],
returnType: this.getTypeFromMap(fn.returnType),
}
})
}
Expand Down Expand Up @@ -161,7 +185,7 @@ export class PLV8ifyCLI implements PLV8ify {
return parameters
.map((p) => {
const { name, type } = p
const mappedType = this._typeMap[type] || fallbackReturnType
const mappedType = this.getTypeFromMap(type) || fallbackReturnType
return `${name} ${mappedType}`
})
.join(',')
Expand Down
16 changes: 16 additions & 0 deletions src/impl/__snapshots__/PLV8ifyCLI.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,19 @@ return test()

$plv8ify$ LANGUAGE plv8 IMMUTABLE STRICT;"
`;

exports[`PLV8ifyCLI tests getSQLFunction with custom type 1`] = `
"DROP FUNCTION IF EXISTS plv8ify_test(test test_type[]);
CREATE OR REPLACE FUNCTION plv8ify_test(test test_type[]) RETURNS JSONB AS $plv8ify$

export function hello(test: test_type[]) {
return {
name: "Hello" + test[0].name,
age: test[0].age,
}
}

return test(test)

$plv8ify$ LANGUAGE plv8 IMMUTABLE STRICT;"
`;
4 changes: 4 additions & 0 deletions src/test-fixtures/types-custom.fixture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
typeMap = {
test_type: 'test_type',
'test_type[]': 'test_type[]',
}
Loading