@@ -12,6 +12,7 @@ import { fromFileUrl, isAbsolute } from "../deps.ts";
1212 * - application_name
1313 * - dbname
1414 * - host
15+ * - options
1516 * - password
1617 * - port
1718 * - sslmode
@@ -27,12 +28,13 @@ export type ConnectionString = string;
2728 */
2829function getPgEnv ( ) : ClientOptions {
2930 return {
31+ applicationName : Deno . env . get ( "PGAPPNAME" ) ,
3032 database : Deno . env . get ( "PGDATABASE" ) ,
3133 hostname : Deno . env . get ( "PGHOST" ) ,
34+ options : Deno . env . get ( "PGOPTIONS" ) ,
35+ password : Deno . env . get ( "PGPASSWORD" ) ,
3236 port : Deno . env . get ( "PGPORT" ) ,
3337 user : Deno . env . get ( "PGUSER" ) ,
34- password : Deno . env . get ( "PGPASSWORD" ) ,
35- applicationName : Deno . env . get ( "PGAPPNAME" ) ,
3638 } ;
3739}
3840
@@ -84,6 +86,7 @@ export interface ClientOptions {
8486 database ?: string ;
8587 hostname ?: string ;
8688 host_type ?: "tcp" | "socket" ;
89+ options ?: string | Record < string , string > ;
8790 password ?: string ;
8891 port ?: string | number ;
8992 tls ?: Partial < TLSOptions > ;
@@ -96,6 +99,7 @@ export interface ClientConfiguration {
9699 database : string ;
97100 hostname : string ;
98101 host_type : "tcp" | "socket" ;
102+ options : Record < string , string > ;
99103 password ?: string ;
100104 port : number ;
101105 tls : TLSOptions ;
@@ -152,21 +156,67 @@ interface PostgresUri {
152156 dbname ?: string ;
153157 driver : string ;
154158 host ?: string ;
159+ options ?: string ;
155160 password ?: string ;
156161 port ?: string ;
157162 sslmode ?: TLSModes ;
158163 user ?: string ;
159164}
160165
161- function parseOptionsFromUri ( connString : string ) : ClientOptions {
166+ function parseOptionsArgument ( options : string ) : Record < string , string > {
167+ const args = options . split ( " " ) ;
168+
169+ const transformed_args = [ ] ;
170+ for ( let x = 0 ; x < args . length ; x ++ ) {
171+ if ( / ^ - \w / . test ( args [ x ] ) ) {
172+ if ( args [ x ] === "-c" ) {
173+ if ( args [ x + 1 ] === undefined ) {
174+ throw new Error (
175+ `No provided value for "${ args [ x ] } " in options parameter` ,
176+ ) ;
177+ }
178+
179+ // Skip next iteration
180+ transformed_args . push ( args [ x + 1 ] ) ;
181+ x ++ ;
182+ } else {
183+ throw new Error (
184+ `Argument "${ args [ x ] } " is not supported in options parameter` ,
185+ ) ;
186+ }
187+ } else if ( / ^ - - \w / . test ( args [ x ] ) ) {
188+ transformed_args . push ( args [ x ] . slice ( 2 ) ) ;
189+ } else {
190+ throw new Error (
191+ `Value "${ args [ x ] } " is not a valid options argument` ,
192+ ) ;
193+ }
194+ }
195+
196+ return transformed_args . reduce ( ( options , x ) => {
197+ if ( ! / .+ = .+ / . test ( x ) ) {
198+ throw new Error ( `Value "${ x } " is not a valid options argument` ) ;
199+ }
200+
201+ const key = x . slice ( 0 , x . indexOf ( "=" ) ) ;
202+ const value = x . slice ( x . indexOf ( "=" ) + 1 ) ;
203+
204+ options [ key ] = value ;
205+
206+ return options ;
207+ } , { } as Record < string , string > ) ;
208+ }
209+
210+ function parseOptionsFromUri ( connection_string : string ) : ClientOptions {
162211 let postgres_uri : PostgresUri ;
163212 try {
164- const uri = parseConnectionUri ( connString ) ;
213+ const uri = parseConnectionUri ( connection_string ) ;
165214 postgres_uri = {
166215 application_name : uri . params . application_name ,
167216 dbname : uri . path || uri . params . dbname ,
168217 driver : uri . driver ,
169218 host : uri . host || uri . params . host ,
219+ options : uri . params . options ,
170220 password : uri . password || uri . params . password ,
171221 port : uri . port || uri . params . port ,
172222 // Compatibility with JDBC, not standard
@@ -194,6 +244,10 @@ function parseOptionsFromUri(connString: string): ClientOptions {
194244 ? ( isAbsolute ( postgres_uri . host ) ? "socket" : "tcp" )
195245 : "socket" ;
196246
247+ const options = postgres_uri . options
248+ ? parseOptionsArgument ( postgres_uri . options )
249+ : { } ;
250+
197251 let tls : TLSOptions | undefined ;
198252 switch ( postgres_uri . sslmode ) {
199253 case undefined : {
@@ -223,6 +277,7 @@ function parseOptionsFromUri(connString: string): ClientOptions {
223277 database : postgres_uri . dbname ,
224278 hostname : postgres_uri . host ,
225279 host_type,
280+ options,
226281 password : postgres_uri . password ,
227282 port : postgres_uri . port ,
228283 tls,
@@ -240,6 +295,7 @@ const DEFAULT_OPTIONS:
240295 host : "127.0.0.1" ,
241296 socket : "/tmp" ,
242297 host_type : "socket" ,
298+ options : { } ,
243299 port : 5432 ,
244300 tls : {
245301 enabled : true ,
@@ -304,6 +360,27 @@ export function createParams(
304360 host = provided_host ?? DEFAULT_OPTIONS . host ;
305361 }
306362
363+ const provided_options = params . options ?? pgEnv . options ;
364+
365+ let options : Record < string , string > ;
366+ if ( provided_options ) {
367+ if ( typeof provided_options === "string" ) {
368+ options = parseOptionsArgument ( provided_options ) ;
369+ } else {
370+ options = provided_options ;
371+ }
372+ } else {
373+ options = { } ;
374+ }
375+
376+ for ( const key in options ) {
377+ if ( ! / ^ \w + $ / . test ( key ) ) {
378+ throw new Error ( `The "${ key } " key in the options argument is invalid` ) ;
379+ }
380+
381+ options [ key ] = options [ key ] . replaceAll ( " " , "\\ " ) ;
382+ }
383+
307384 let port : number ;
308385 if ( params . port ) {
309386 port = Number ( params . port ) ;
@@ -344,6 +421,7 @@ export function createParams(
344421 database : params . database ?? pgEnv . database ,
345422 hostname : host ,
346423 host_type,
424+ options,
347425 password : params . password ?? pgEnv . password ,
348426 port,
349427 tls : {
0 commit comments