From 607b23792d2ece3b9a87b477ab1a25852a00d8b5 Mon Sep 17 00:00:00 2001 From: Harminder Virk Date: Fri, 8 Nov 2024 17:31:20 +0530 Subject: [PATCH 1/2] fix: define ssl options when specified in the connection string --- packages/medusa/src/commands/db/create.ts | 65 +++++++++++++++++++---- 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/packages/medusa/src/commands/db/create.ts b/packages/medusa/src/commands/db/create.ts index 09aa268369dc8..9e7f862a5f87d 100644 --- a/packages/medusa/src/commands/db/create.ts +++ b/packages/medusa/src/commands/db/create.ts @@ -10,6 +10,15 @@ import { parseConnectionString, } from "@medusajs/framework/utils" +async function connectClient(client: ReturnType) { + try { + await client.connect() + return { connected: true, error: null } + } catch (error) { + return { connected: false, error } + } +} + /** * A low-level utility to create the database. This util should * never exit the process implicitly. @@ -69,28 +78,62 @@ export async function dbCreate({ /** * Parse connection string specified as "DATABASE_URL" inside the * .env file and create a client instance from it. - * - * Remember we should not specify the database name from the - * connection string, because this database might not - * exist */ const connectionOptions = parseConnectionString(dbConnectionString) - const client = createClient({ + + /** + * The following client config is without any database name. This is because + * we want to connect to the default database (whatever it is) and create + * a new database that we expect not to exist. + */ + const clientConfig = { host: connectionOptions.host!, port: connectionOptions.port ? Number(connectionOptions.port) : undefined, user: connectionOptions.user, password: connectionOptions.password, - }) + ...(connectionOptions.ssl ? { ssl: connectionOptions.ssl as any } : {}), + } - try { - await client.connect() - logger.info(`Connection established with the database "${dbName}"`) - } catch (error) { + /** + * In some case the default database (which is same as the username) does + * not exist. For example: With Neon, there is no database name after + * the connection username. Hence, we will have to connect with the + * postgres database. + */ + const clientConfigWithPostgresDB = { + host: connectionOptions.host!, + port: connectionOptions.port ? Number(connectionOptions.port) : undefined, + user: connectionOptions.user, + database: "postgres", + password: connectionOptions.password, + ...(connectionOptions.ssl ? { ssl: connectionOptions.ssl as any } : {}), + } + + /** + * First connect with the default DB + */ + let client = createClient(clientConfig) + let connectionState = await connectClient(client) + + /** + * In case of an error, connect with the postgres DB + */ + if (!connectionState.connected) { + client = createClient(clientConfigWithPostgresDB) + connectionState = await connectClient(client) + } + + /** + * Notify user about the connection state + */ + if (!connectionState.connected) { logger.error( "Unable to establish database connection because of the following error" ) - logger.error(error) + logger.error(connectionState.error) return false + } else { + logger.info(`Connection established with the database "${dbName}"`) } if (await dbExists(client, dbName)) { From 20df1da20d46babadad91be4335473264f0d72b5 Mon Sep 17 00:00:00 2001 From: Harminder Virk Date: Fri, 8 Nov 2024 17:34:36 +0530 Subject: [PATCH 2/2] refactor: remove redundant else conditional --- packages/medusa/src/commands/db/create.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/medusa/src/commands/db/create.ts b/packages/medusa/src/commands/db/create.ts index 9e7f862a5f87d..d8aac928e806b 100644 --- a/packages/medusa/src/commands/db/create.ts +++ b/packages/medusa/src/commands/db/create.ts @@ -132,10 +132,9 @@ export async function dbCreate({ ) logger.error(connectionState.error) return false - } else { - logger.info(`Connection established with the database "${dbName}"`) } + logger.info(`Connection established with the database "${dbName}"`) if (await dbExists(client, dbName)) { logger.info(`Database "${dbName}" already exists`)