Skip to content

Commit

Permalink
fix(dbpull): fix url parsing (related #6546) (#6900)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jolg42 committed May 3, 2021
1 parent 82a7537 commit d367426
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 29 deletions.
62 changes: 37 additions & 25 deletions src/packages/migrate/src/__tests__/DbPull.test.ts
Expand Up @@ -63,20 +63,32 @@ test('introspection --force', async () => {
test('basic introspection with --url', async () => {
ctx.fixture('introspection/sqlite')
const introspect = new DbPull()
await introspect.parse(['--print', '--url', 'file:dev.db'])
const result = introspect.parse(['--print', '--url', 'file:dev.db'])
await expect(result).resolves.toBe('')
expect(ctx.mocked['console.log'].mock.calls.join('\n')).toMatchSnapshot()
})

test('basic introspection with invalid --url', async () => {
test('basic introspection with invalid --url - empty host', async () => {
ctx.fixture('introspection/sqlite')
const introspect = new DbPull()
const result = introspect.parse([
'--print',
'--url',
'postgresql://root:prisma@/prisma',
])
await expect(result).rejects.toThrowErrorMatchingInlineSnapshot(`
Error parsing connection string: empty host in database URL
`)
expect(ctx.mocked['console.log'].mock.calls.join('\n')).toMatchSnapshot()
})

test('basic introspection with invalid --url', async () => {
ctx.fixture('introspection/sqlite')
const introspect = new DbPull()
const result = introspect.parse(['--print', '--url', 'invalidstring'])
await expect(result).rejects.toThrowErrorMatchingInlineSnapshot(
`Invalid data source URL, see https://www.prisma.io/docs/reference/database-reference/connection-urls`,
`Unknown database type invalidstring:`,
)
expect(ctx.mocked['console.log'].mock.calls.join('\n')).toMatchSnapshot()
})
Expand Down Expand Up @@ -223,14 +235,14 @@ it('should succeed and keep changes to valid schema and output warnings when usi
expect(ctx.mocked['console.error'].mock.calls.join('\n'))
.toMatchInlineSnapshot(`
// *** WARNING ***
//
// These models were enriched with \`@@map\` information taken from the previous Prisma schema.
// - Model "AwesomeNewPost"
// - Model "AwesomeProfile"
// - Model "AwesomeUser"
//
`)
// *** WARNING ***
//
// These models were enriched with \`@@map\` information taken from the previous Prisma schema.
// - Model "AwesomeNewPost"
// - Model "AwesomeProfile"
// - Model "AwesomeUser"
//
`)

expect(ctx.fs.read('prisma/reintrospection.prisma')).toStrictEqual(
originalSchema,
Expand Down Expand Up @@ -262,18 +274,18 @@ it('should fail when db is missing', async () => {
const result = DbPull.new().parse([])
await expect(result).rejects.toThrowErrorMatchingInlineSnapshot(`
P4001 The introspected database was empty:
P4001 The introspected database was empty:
prisma db pull could not create any models in your schema.prisma file and you will not be able to generate Prisma Client with the prisma generate command.
prisma db pull could not create any models in your schema.prisma file and you will not be able to generate Prisma Client with the prisma generate command.
To fix this, you have two options:
To fix this, you have two options:
- manually create a table in your database (using SQL).
- make sure the database connection URL inside the datasource block in schema.prisma points to a database that is not empty (it must contain at least one table).
- manually create a table in your database (using SQL).
- make sure the database connection URL inside the datasource block in schema.prisma points to a database that is not empty (it must contain at least one table).
Then you can run prisma db pull again.
Then you can run prisma db pull again.
`)
`)
})

it('should fail when db is empty', async () => {
Expand All @@ -282,18 +294,18 @@ it('should fail when db is empty', async () => {
const result = DbPull.new().parse([])
await expect(result).rejects.toThrowErrorMatchingInlineSnapshot(`
P4001 The introspected database was empty:
P4001 The introspected database was empty:
prisma db pull could not create any models in your schema.prisma file and you will not be able to generate Prisma Client with the prisma generate command.
prisma db pull could not create any models in your schema.prisma file and you will not be able to generate Prisma Client with the prisma generate command.
To fix this, you have two options:
To fix this, you have two options:
- manually create a table in your database (using SQL).
- make sure the database connection URL inside the datasource block in schema.prisma points to a database that is not empty (it must contain at least one table).
- manually create a table in your database (using SQL).
- make sure the database connection URL inside the datasource block in schema.prisma points to a database that is not empty (it must contain at least one table).
Then you can run prisma db pull again.
Then you can run prisma db pull again.
`)
`)
})

it('should fail when Prisma schema is missing', async () => {
Expand Down
Expand Up @@ -80,6 +80,8 @@ model User {
// introspectionSchemaVersion: Prisma2,
`;
exports[`basic introspection with invalid --url - empty host 2`] = `Prisma schema loaded from schema.prisma`;
exports[`basic introspection with invalid --url 2`] = `Prisma schema loaded from schema.prisma`;
exports[`introspection --force 1`] = `
Expand Down
10 changes: 7 additions & 3 deletions src/packages/migrate/src/commands/DbPull.ts
Expand Up @@ -14,11 +14,13 @@ import {
IntrospectionEngine,
IntrospectionWarnings,
IntrospectionSchemaVersion,
uriToCredentials,
} from '@prisma/sdk'
import { formatms } from '../utils/formatms'
import fs from 'fs'
import { databaseTypeToConnectorType } from '@prisma/sdk/dist/convertCredentials'
import {
protocolToDatabaseType,
databaseTypeToConnectorType,
} from '@prisma/sdk/dist/convertCredentials'
import { printDatasources } from '../utils/printDatasources'
import { removeDatasource } from '../utils/removeDatasource'

Expand Down Expand Up @@ -55,7 +57,9 @@ Instead of saving the result to the filesystem, you can also print it to stdout
`)

private printUrlAsDatasource(url: string): string {
const provider = databaseTypeToConnectorType(uriToCredentials(url).type)
const provider = databaseTypeToConnectorType(
protocolToDatabaseType(`${url.split(':')[0]}:`),
)

return printDatasources([
{
Expand Down
2 changes: 1 addition & 1 deletion src/packages/sdk/src/convertCredentials.ts
Expand Up @@ -161,7 +161,7 @@ function databaseTypeToProtocol(databaseType: ConnectorType): string {
}
}

function protocolToDatabaseType(protocol: string): ConnectorType {
export function protocolToDatabaseType(protocol: string): ConnectorType {
switch (protocol) {
case 'postgresql:':
case 'postgres:':
Expand Down

0 comments on commit d367426

Please sign in to comment.