Skip to content

Commit

Permalink
vercel-postgres-to-neon codemod
Browse files Browse the repository at this point in the history
  • Loading branch information
adriancooney committed Feb 21, 2025
1 parent 02ca5df commit 3bb118d
Show file tree
Hide file tree
Showing 25 changed files with 1,890 additions and 385 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__testfixtures__
4 changes: 2 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ module.exports = {
extends: ['custom'],
parserOptions: {
project: [
resolve(__dirname, './packages/*/tsconfig.json'),
resolve(__dirname, './tooling/*/tsconfig.json'),
resolve(__dirname, './packages/**/*/tsconfig.json'),
resolve(__dirname, './tooling/**/*/tsconfig.json'),
],
},
};
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ pnpm-lock.yaml
.vercel
.vscode
.changeset
__testfixtures__
2 changes: 1 addition & 1 deletion packages/postgres-kysely/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# @vercel/postgres-kysely
# @vercel/postgres-kysely (deprecated)

A `@vercel/postgres` wrapper for the [Kysely](https://github.com/kysely-org/kysely) query builder.

Expand Down
1,674 changes: 1,293 additions & 381 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
packages:
- 'packages/*'
- 'tooling/*'
- 'tooling/codemods/*'
- 'test/*'
9 changes: 9 additions & 0 deletions tooling/codemods/vercel-postgres-to-neon/.codemodrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://codemod-utils.s3.us-west-1.amazonaws.com/configuration_schema.json",
"name": "vercel-postgres-to-neon",
"version": "1.0.0",
"engine": "jscodeshift",
"private": false,
"arguments": [],
"meta": {}
}
4 changes: 4 additions & 0 deletions tooling/codemods/vercel-postgres-to-neon/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
cdmd_dist
pnpm-lock.yaml
package-lock.json
57 changes: 57 additions & 0 deletions tooling/codemods/vercel-postgres-to-neon/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
This is a [codemod](https://codemod.com) created with [`codemod init`](https://docs.codemod.com/deploying-codemods/cli#codemod-init).

## Using this codemod

You can run this codemod with the following command:

```bash
npx codemod vercel-postgres-to-neon
```

### Before

```ts
import { sql } from '@vercel/postgres';
import { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {
try {
await sql`CREATE TABLE Pets ( Name varchar(255), Owner varchar(255) );`;
const names = ['Fiona', 'Lucy'];
await sql`INSERT INTO Pets (Name, Owner) VALUES (${names[0]}, ${names[1]});`;
} catch (error) {
return response.status(500).json({ error });
}

const pets = await sql`SELECT * FROM Pets;`;
return response.status(200).json({ pets });
}
```

### After

```ts
import { neon } from '@neondatabase/serverless';
import { NextApiRequest, NextApiResponse } from 'next';

const sql = neon(process.env.POSTGRES_URL);

export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {
try {
await sql`CREATE TABLE Pets ( Name varchar(255), Owner varchar(255) );`;
const names = ['Fiona', 'Lucy'];
await sql`INSERT INTO Pets (Name, Owner) VALUES (${names[0]}, ${names[1]});`;
} catch (error) {
return response.status(500).json({ error });
}

const pets = await sql`SELECT * FROM Pets;`;
return response.status(200).json({ pets });
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// https://github.com/sauravhathi/vercel-postgres/blob/main/pages/api/pets.ts

import { sql } from "@vercel/postgres";
import { NextApiRequest, NextApiResponse } from "next";

export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {
try {
await sql`CREATE TABLE Pets ( Name varchar(255), Owner varchar(255) );`;
const names = ["Fiona", "Lucy"];
await sql`INSERT INTO Pets (Name, Owner) VALUES (${names[0]}, ${names[1]});`;
} catch (error) {
return response.status(500).json({ error });
}

const pets = await sql`SELECT * FROM Pets;`;
return response.status(200).json({ pets });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// https://github.com/sauravhathi/vercel-postgres/blob/main/pages/api/pets.ts

import { neon } from "@neondatabase/serverless";
import { NextApiRequest, NextApiResponse } from "next";

const sql = neon(process.env.POSTGRES_URL);

export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {
try {
await sql`CREATE TABLE Pets ( Name varchar(255), Owner varchar(255) );`;
const names = ["Fiona", "Lucy"];
await sql`INSERT INTO Pets (Name, Owner) VALUES (${names[0]}, ${names[1]});`;
} catch (error) {
return response.status(500).json({ error });
}

const pets = await sql`SELECT * FROM Pets;`;
return response.status(200).json({ pets });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// https://github.com/sauravhathi/vercel-postgres/blob/main/pages/api/pets.ts

import { NextApiRequest, NextApiResponse } from "next";
import { sql } from "@vercel/postgres";

export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {
try {
await sql`CREATE TABLE Pets ( Name varchar(255), Owner varchar(255) );`;
const names = ["Fiona", "Lucy"];
await sql`INSERT INTO Pets (Name, Owner) VALUES (${names[0]}, ${names[1]});`;
} catch (error) {
return response.status(500).json({ error });
}

const pets = await sql`SELECT * FROM Pets;`;
return response.status(200).json({ pets });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// https://github.com/sauravhathi/vercel-postgres/blob/main/pages/api/pets.ts

import { NextApiRequest, NextApiResponse } from "next";
import { neon } from "@neondatabase/serverless";

const sql = neon(process.env.POSTGRES_URL);

export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {
try {
await sql`CREATE TABLE Pets ( Name varchar(255), Owner varchar(255) );`;
const names = ["Fiona", "Lucy"];
await sql`INSERT INTO Pets (Name, Owner) VALUES (${names[0]}, ${names[1]});`;
} catch (error) {
return response.status(500).json({ error });
}

const pets = await sql`SELECT * FROM Pets;`;
return response.status(200).json({ pets });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// https://github.com/sauravhathi/vercel-postgres/blob/main/pages/api/pets.ts

import { NextApiRequest, NextApiResponse } from "next";
import { createPool } from "@vercel/postgres";
import { sql } from "@vercel/postgres";

export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {
try {
await sql`CREATE TABLE Pets ( Name varchar(255), Owner varchar(255) );`;
const names = ["Fiona", "Lucy"];
await sql`INSERT INTO Pets (Name, Owner) VALUES (${names[0]}, ${names[1]});`;
} catch (error) {
return response.status(500).json({ error });
}

const pets = await sql`SELECT * FROM Pets;`;
return response.status(200).json({ pets });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// https://github.com/sauravhathi/vercel-postgres/blob/main/pages/api/pets.ts

import { NextApiRequest, NextApiResponse } from "next";
import { createPool } from "@vercel/postgres";
import { neon } from "@neondatabase/serverless";

const sql = neon(process.env.POSTGRES_URL);

export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {
try {
await sql`CREATE TABLE Pets ( Name varchar(255), Owner varchar(255) );`;
const names = ["Fiona", "Lucy"];
await sql`INSERT INTO Pets (Name, Owner) VALUES (${names[0]}, ${names[1]});`;
} catch (error) {
return response.status(500).json({ error });
}

const pets = await sql`SELECT * FROM Pets;`;
return response.status(200).json({ pets });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { createPool, sql } from "@vercel/postgres";

async function seed() {
const createTable = await sql`
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
image VARCHAR(255),
"createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
`

console.log(`Created "users" table`)

const users = await Promise.all([
sql`
INSERT INTO users (name, email, image)
VALUES ('Guillermo Rauch', '[email protected]', 'https://images.ctfassets.net/e5382hct74si/2P1iOve0LZJRZWUzfXpi9r/9d4d27765764fb1ad7379d7cbe5f1043/ucxb4lHy_400x400.jpg')
ON CONFLICT (email) DO NOTHING;
`,
sql`
INSERT INTO users (name, email, image)
VALUES ('Lee Robinson', '[email protected]', 'https://images.ctfassets.net/e5382hct74si/4BtM41PDNrx4z1ml643tdc/7aa88bdde8b5b7809174ea5b764c80fa/adWRdqQ6_400x400.jpg')
ON CONFLICT (email) DO NOTHING;
`,
sql`
INSERT INTO users (name, email, image)
VALUES ('Steven Tey', '[email protected]', 'https://images.ctfassets.net/e5382hct74si/4QEuVLNyZUg5X6X4cW4pVH/eb7cd219e21b29ae976277871cd5ca4b/profile.jpg')
ON CONFLICT (email) DO NOTHING;
`,
])
console.log(`Seeded ${users.length} users`)

return {
createTable,
users,
}
}
export default defineEventHandler(async () => {
const startTime = Date.now()
const db = createPool()
try {
const { rows: users } = await db.query('SELECT * FROM users')
const duration = Date.now() - startTime
return {
users: users,
duration: duration,
}
} catch (error) {
// @ts-ignore
if (error?.message === `relation "users" does not exist`) {
console.log(
'Table does not exist, creating and seeding it with dummy data now...'
)
// Table is not created yet
await seed()
const { rows: users } = await db.query('SELECT * FROM users')
const duration = Date.now() - startTime
return {
users: users,
duration: duration,
}
} else {
throw error
}
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { createPool } from "@vercel/postgres";

import { neon } from "@neondatabase/serverless";
const sql = neon(process.env.POSTGRES_URL);

async function seed() {
const createTable = await sql`
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
image VARCHAR(255),
"createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
`

console.log(`Created "users" table`)

const users = await Promise.all([
sql`
INSERT INTO users (name, email, image)
VALUES ('Guillermo Rauch', '[email protected]', 'https://images.ctfassets.net/e5382hct74si/2P1iOve0LZJRZWUzfXpi9r/9d4d27765764fb1ad7379d7cbe5f1043/ucxb4lHy_400x400.jpg')
ON CONFLICT (email) DO NOTHING;
`,
sql`
INSERT INTO users (name, email, image)
VALUES ('Lee Robinson', '[email protected]', 'https://images.ctfassets.net/e5382hct74si/4BtM41PDNrx4z1ml643tdc/7aa88bdde8b5b7809174ea5b764c80fa/adWRdqQ6_400x400.jpg')
ON CONFLICT (email) DO NOTHING;
`,
sql`
INSERT INTO users (name, email, image)
VALUES ('Steven Tey', '[email protected]', 'https://images.ctfassets.net/e5382hct74si/4QEuVLNyZUg5X6X4cW4pVH/eb7cd219e21b29ae976277871cd5ca4b/profile.jpg')
ON CONFLICT (email) DO NOTHING;
`,
])
console.log(`Seeded ${users.length} users`)

return {
createTable,
users,
}
}
export default defineEventHandler(async () => {
const startTime = Date.now()
const db = createPool()
try {
const { rows: users } = await db.query('SELECT * FROM users')
const duration = Date.now() - startTime
return {
users: users,
duration: duration,
}
} catch (error) {
// @ts-ignore
if (error?.message === `relation "users" does not exist`) {
console.log(
'Table does not exist, creating and seeding it with dummy data now...'
)
// Table is not created yet
await seed()
const { rows: users } = await db.query('SELECT * FROM users')
const duration = Date.now() - startTime
return {
users: users,
duration: duration,
}
} else {
throw error
}
}
})
Loading

0 comments on commit 3bb118d

Please sign in to comment.