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

fix: define ssl options when specified in the connection string #9992

Merged
merged 2 commits into from
Nov 8, 2024
Merged
Changes from all 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
64 changes: 53 additions & 11 deletions packages/medusa/src/commands/db/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ import {
parseConnectionString,
} from "@medusajs/framework/utils"

async function connectClient(client: ReturnType<typeof createClient>) {
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.
Expand Down Expand Up @@ -69,30 +78,63 @@ 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
}

logger.info(`Connection established with the database "${dbName}"`)
if (await dbExists(client, dbName)) {
logger.info(`Database "${dbName}" already exists`)

Expand Down
Loading