Skip to content

Commit

Permalink
Merge branch 'beta' into generated-not-null
Browse files Browse the repository at this point in the history
  • Loading branch information
AndriiSherman authored Aug 26, 2024
2 parents 46b60e6 + 3629b65 commit 6d18f26
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 23 deletions.
1 change: 1 addition & 0 deletions drizzle-kit/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const driversPackages = [
'postgres',
'@vercel/postgres',
'@neondatabase/serverless',
'@electric-sql/pglite',
// mysql drivers
'mysql2',
'@planetscale/database',
Expand Down
2 changes: 1 addition & 1 deletion drizzle-kit/src/cli/commands/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const safeRegister = async () => {
export const prepareCheckParams = async (
options: {
config?: string;
dialect: Dialect;
dialect?: Dialect;
out?: string;
},
from: 'cli' | 'config',
Expand Down
64 changes: 61 additions & 3 deletions drizzle-kit/src/cli/connections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import fetch from 'node-fetch';
import ws from 'ws';
import { assertUnreachable } from '../global';
import type { ProxyParams } from '../serializer/studio';
import { type DB, normaliseSQLiteUrl, type Proxy, type SQLiteDB, type SqliteProxy } from '../utils';
import { type DB, normalisePGliteUrl, normaliseSQLiteUrl, type Proxy, type SQLiteDB, type SqliteProxy } from '../utils';
import { assertPackages, checkPackage } from './utils';
import type { MysqlCredentials } from './validations/mysql';
import { withStyle } from './validations/outputs';
Expand All @@ -21,7 +21,8 @@ export const preparePostgresDB = async (
}
> => {
if ('driver' in credentials) {
if (credentials.driver === 'aws-data-api') {
const { driver } = credentials;
if (driver === 'aws-data-api') {
assertPackages('@aws-sdk/client-rds-data');
const { RDSDataClient, ExecuteStatementCommand, TypeHint } = await import(
'@aws-sdk/client-rds-data'
Expand Down Expand Up @@ -92,7 +93,45 @@ export const preparePostgresDB = async (
};
}

assertUnreachable(credentials.driver);
if (driver === 'pglite') {
assertPackages('@electric-sql/pglite');
const { PGlite } = await import('@electric-sql/pglite');
const { drizzle } = await import('drizzle-orm/pglite');
const { migrate } = await import('drizzle-orm/pglite/migrator');

const pglite = new PGlite(normalisePGliteUrl(credentials.url));
await pglite.waitReady;
const drzl = drizzle(pglite);
const migrateFn = async (config: MigrationConfig) => {
return migrate(drzl, config);
};

const query = async <T>(sql: string, params: any[] = []) => {
const result = await pglite.query(sql, params);
return result.rows as T[];
};

const proxy = async (params: ProxyParams) => {
const preparedParams = preparePGliteParams(params.params);
if (
params.method === 'values'
|| params.method === 'get'
|| params.method === 'all'
) {
const result = await pglite.query(params.sql, preparedParams, {
rowMode: params.mode,
});
return result.rows;
}

const result = await pglite.query(params.sql, preparedParams);
return result.rows;
};

return { query, proxy, migrate: migrateFn };
}

assertUnreachable(driver);
}

if (await checkPackage('pg')) {
Expand Down Expand Up @@ -415,6 +454,25 @@ const prepareSqliteParams = (params: any[], driver?: string) => {
});
};

const preparePGliteParams = (params: any[]) => {
return params.map((param) => {
if (
param
&& typeof param === 'object'
&& 'type' in param
&& 'value' in param
&& param.type === 'binary'
) {
const value = typeof param.value === 'object'
? JSON.stringify(param.value)
: (param.value as string);

return value;
}
return param;
});
};

export const connectToSQLite = async (
credentials: SqliteCredentials,
): Promise<
Expand Down
48 changes: 40 additions & 8 deletions drizzle-kit/src/cli/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,23 @@ export const migrate = command({
try {
if (dialect === 'postgresql') {
if ('driver' in credentials) {
if (credentials.driver === 'aws-data-api') {
const { driver } = credentials;
if (driver === 'aws-data-api') {
if (!(await ormVersionGt('0.30.10'))) {
console.log(
"To use 'aws-data-api' driver - please update drizzle-orm to the latest version",
);
process.exit(1);
}
} else if (driver === 'pglite') {
if (!(await ormVersionGt('0.30.6'))) {
console.log(
"To use 'pglite' driver - please update drizzle-orm to the latest version",
);
process.exit(1);
}
} else {
assertUnreachable(credentials.driver);
assertUnreachable(driver);
}
}
const { preparePostgresDB } = await import('./connections');
Expand Down Expand Up @@ -256,15 +264,23 @@ export const push = command({
);
} else if (dialect === 'postgresql') {
if ('driver' in credentials) {
if (credentials.driver === 'aws-data-api') {
const { driver } = credentials;
if (driver === 'aws-data-api') {
if (!(await ormVersionGt('0.30.10'))) {
console.log(
"To use 'aws-data-api' driver - please update drizzle-orm to the latest version",
);
process.exit(1);
}
} else if (driver === 'pglite') {
if (!(await ormVersionGt('0.30.6'))) {
console.log(
"To use 'pglite' driver - please update drizzle-orm to the latest version",
);
process.exit(1);
}
} else {
assertUnreachable(credentials.driver);
assertUnreachable(driver);
}
}

Expand Down Expand Up @@ -417,15 +433,23 @@ export const pull = command({
try {
if (dialect === 'postgresql') {
if ('driver' in credentials) {
if (credentials.driver === 'aws-data-api') {
const { driver } = credentials;
if (driver === 'aws-data-api') {
if (!(await ormVersionGt('0.30.10'))) {
console.log(
"To use 'aws-data-api' driver - please update drizzle-orm to the latest version",
);
process.exit(1);
}
} else if (driver === 'pglite') {
if (!(await ormVersionGt('0.30.6'))) {
console.log(
"To use 'pglite' driver - please update drizzle-orm to the latest version",
);
process.exit(1);
}
} else {
assertUnreachable(credentials.driver);
assertUnreachable(driver);
}
}

Expand Down Expand Up @@ -525,15 +549,23 @@ export const studio = command({
try {
if (dialect === 'postgresql') {
if ('driver' in credentials) {
if (credentials.driver === 'aws-data-api') {
const { driver } = credentials;
if (driver === 'aws-data-api') {
if (!(await ormVersionGt('0.30.10'))) {
console.log(
"To use 'aws-data-api' driver - please update drizzle-orm to the latest version",
);
process.exit(1);
}
} else if (driver === 'pglite') {
if (!(await ormVersionGt('0.30.6'))) {
console.log(
"To use 'pglite' driver - please update drizzle-orm to the latest version",
);
process.exit(1);
}
} else {
assertUnreachable(credentials.driver);
assertUnreachable(driver);
}
}

Expand Down
9 changes: 7 additions & 2 deletions drizzle-kit/src/cli/validations/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ export const sqliteDriversLiterals = [
literal('expo'),
] as const;

export const postgresqlDriversLiterals = [
literal('aws-data-api'),
literal('pglite'),
] as const;

export const prefixes = [
'index',
'timestamp',
Expand All @@ -81,7 +86,7 @@ export type Prefix = (typeof prefixes)[number];
}

export const sqliteDriver = union(sqliteDriversLiterals);
export const postgresDriver = literal('aws-data-api');
export const postgresDriver = union(postgresqlDriversLiterals);
export const driver = union([sqliteDriver, postgresDriver]);

export const configMigrations = object({
Expand Down Expand Up @@ -151,7 +156,7 @@ export const configPushSchema = object({
});

export type CliConfig = TypeOf<typeof configCommonSchema>;
export const drivers = ['turso', 'd1-http', 'expo', 'aws-data-api'] as const;
export const drivers = ['turso', 'd1-http', 'expo', 'aws-data-api', 'pglite'] as const;
export type Driver = (typeof drivers)[number];
const _: Driver = '' as TypeOf<typeof driver>;

Expand Down
4 changes: 4 additions & 0 deletions drizzle-kit/src/cli/validations/postgres.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export const postgresCredentials = union([
secretArn: string().min(1),
resourceArn: string().min(1),
}),
object({
driver: literal('pglite'),
url: string().min(1),
}),
]);

export type PostgresCredentials = TypeOf<typeof postgresCredentials>;
Expand Down
13 changes: 10 additions & 3 deletions drizzle-kit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type Verify<T, U extends T> = U;
*
* ---
* `driver` - optional param that is responsible for explicitly providing a driver to use when accessing a database
* *Possible values*: `aws-data-api`, `d1-http`, `expo`, `turso`
* *Possible values*: `aws-data-api`, `d1-http`, `expo`, `turso`, `pglite`
* If you don't use AWS Data API, D1, Turso or Expo - ypu don't need this driver. You can check a driver strategy choice here: https://orm.drizzle.team/kit-docs/upgrade-21
*
* See https://orm.drizzle.team/kit-docs/config-reference#driver
Expand Down Expand Up @@ -136,7 +136,7 @@ export type Config =
};
}
| {
dialect: 'sqlite';
dialect: Verify<Dialect, 'sqlite'>;
dbCredentials: {
url: string;
};
Expand Down Expand Up @@ -171,6 +171,13 @@ export type Config =
resourceArn: string;
};
}
| {
dialect: Verify<Dialect, 'postgresql'>;
driver: Verify<Driver, 'pglite'>;
dbCredentials: {
url: string;
};
}
| {
dialect: Verify<Dialect, 'mysql'>;
dbCredentials:
Expand Down Expand Up @@ -226,7 +233,7 @@ export type Config =
*
* ---
* `driver` - optional param that is responsible for explicitly providing a driver to use when accessing a database
* *Possible values*: `aws-data-api`, `d1-http`, `expo`, `turso`
* *Possible values*: `aws-data-api`, `d1-http`, `expo`, `turso`, `pglite`
* If you don't use AWS Data API, D1, Turso or Expo - ypu don't need this driver. You can check a driver strategy choice here: https://orm.drizzle.team/kit-docs/upgrade-21
*
* See https://orm.drizzle.team/kit-docs/config-reference#driver
Expand Down
10 changes: 6 additions & 4 deletions drizzle-kit/src/serializer/studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type SchemaFile = {
export type Setup = {
dbHash: string;
dialect: 'postgresql' | 'mysql' | 'sqlite';
driver?: 'aws-data-api' | 'd1-http' | 'turso';
driver?: 'aws-data-api' | 'd1-http' | 'turso' | 'pglite';
proxy: (params: ProxyParams) => Promise<any[] | any>;
customDefaults: CustomDefault[];
schema: Record<string, Record<string, AnyTable<any>>>;
Expand Down Expand Up @@ -218,11 +218,13 @@ export const drizzleForPostgres = async (
let dbUrl: string;

if ('driver' in credentials) {
// aws-data-api
if (credentials.driver === 'aws-data-api') {
const { driver } = credentials;
if (driver === 'aws-data-api') {
dbUrl = `aws-data-api://${credentials.database}/${credentials.secretArn}/${credentials.resourceArn}`;
} else if (driver === 'pglite') {
dbUrl = credentials.url;
} else {
assertUnreachable(credentials.driver);
assertUnreachable(driver);
}
} else if ('url' in credentials) {
dbUrl = credentials.url;
Expand Down
10 changes: 10 additions & 0 deletions drizzle-kit/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,16 @@ export const normaliseSQLiteUrl = (
assertUnreachable(type);
};

export const normalisePGliteUrl = (
it: string,
) => {
if (it.startsWith('file:')) {
return it.substring(5);
}

return it;
};

export function isPgArrayType(sqlType: string) {
return sqlType.match(/.*\[\d*\].*|.*\[\].*/g) !== null;
}
4 changes: 2 additions & 2 deletions drizzle-kit/tests/introspect/pg.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ test('instrospect all column types', async () => {
const myEnum = pgEnum('my_enum', ['a', 'b', 'c']);
const schema = {
enum_: myEnum,
// NOTE: Types from extensions aren't tested due to PGLite not supporting at the moment
// NOTE: Types from extensions aren't tested due to PGlite not supporting at the moment
columns: pgTable('columns', {
enum: myEnum('my_enum').default('a'),
smallint: smallint('smallint').default(10),
Expand Down Expand Up @@ -271,7 +271,7 @@ test('instrospect all column array types', async () => {
const myEnum = pgEnum('my_enum', ['a', 'b', 'c']);
const schema = {
enum_: myEnum,
// NOTE: Types from extensions aren't tested due to PGLite not supporting at the moment
// NOTE: Types from extensions aren't tested due to PGlite not supporting at the moment
columns: pgTable('columns', {
enum: myEnum('my_enum').array().default(['a', 'b']),
smallint: smallint('smallint').array().default([10, 20]),
Expand Down
32 changes: 32 additions & 0 deletions drizzle-kit/tests/validations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,38 @@ test('AWS Data API #8', () => {
}).toThrowError();
});

test('PGlite #1', () => {
expect(
postgresCredentials.parse({
dialect: 'postgres',
driver: 'pglite',
url: './my.db',
}),
).toStrictEqual({
driver: 'pglite',
url: './my.db',
});
});

test('PGlite #2', () => {
expect(() => {
postgresCredentials.parse({
dialect: 'postgres',
driver: 'pglite',
url: '',
});
}).toThrowError();
});

test('PGlite #3', () => {
expect(() => {
postgresCredentials.parse({
dialect: 'postgres',
driver: 'pglite',
});
}).toThrowError();
});

test('postgres #1', () => {
expect(
postgresCredentials.parse({
Expand Down

0 comments on commit 6d18f26

Please sign in to comment.