Skip to content

Commit

Permalink
add type-tests for SingleStore dialect
Browse files Browse the repository at this point in the history
  • Loading branch information
Rodriguespn committed Aug 20, 2024
1 parent bee314c commit ae78e04
Show file tree
Hide file tree
Showing 11 changed files with 3,118 additions and 0 deletions.
904 changes: 904 additions & 0 deletions drizzle-orm/type-tests/singlestore/1000columns.ts

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions drizzle-orm/type-tests/singlestore/db.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createPool } from 'mysql2/promise';
import { drizzle } from '~/singlestore/index.ts';

const pool = createPool({});

export const db = drizzle(pool);

{
drizzle(pool);
// @ts-expect-error - missing mode
drizzle(pool, { schema: {} });
drizzle(pool, { schema: {}, mode: 'default' });
drizzle(pool, { mode: 'default' });
}
61 changes: 61 additions & 0 deletions drizzle-orm/type-tests/singlestore/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { Equal } from 'type-tests/utils.ts';
import { Expect } from 'type-tests/utils.ts';
import { eq } from '~/expressions.ts';
import type { SingleStoreDelete } from '~/singlestore-core/index.ts';
import type { SingleStoreRawQueryResult } from '~/singlestore/index.ts';
import { sql } from '~/sql/sql.ts';
import { db } from './db.ts';
import { users } from './tables.ts';

const deleteAll = await db.delete(users);
Expect<Equal<SingleStoreRawQueryResult, typeof deleteAll>>;

const deleteAllStmt = db.delete(users).prepare();
const deleteAllPrepared = await deleteAllStmt.execute();
Expect<Equal<SingleStoreRawQueryResult, typeof deleteAllPrepared>>;

const deleteWhere = await db.delete(users).where(eq(users.id, 1));
Expect<Equal<SingleStoreRawQueryResult, typeof deleteWhere>>;

const deleteWhereStmt = db.delete(users).where(eq(users.id, 1)).prepare();
const deleteWherePrepared = await deleteWhereStmt.execute();
Expect<Equal<SingleStoreRawQueryResult, typeof deleteWherePrepared>>;

const deleteReturningAll = await db.delete(users);
Expect<Equal<SingleStoreRawQueryResult, typeof deleteReturningAll>>;

const deleteReturningAllStmt = db.delete(users).prepare();
const deleteReturningAllPrepared = await deleteReturningAllStmt.execute();
Expect<Equal<SingleStoreRawQueryResult, typeof deleteReturningAllPrepared>>;

const deleteReturningPartial = await db.delete(users);
Expect<Equal<SingleStoreRawQueryResult, typeof deleteReturningPartial>>;

const deleteReturningPartialStmt = db.delete(users).prepare();
const deleteReturningPartialPrepared = await deleteReturningPartialStmt.execute();
Expect<Equal<SingleStoreRawQueryResult, typeof deleteReturningPartialPrepared>>;

{
function dynamic<T extends SingleStoreDelete>(qb: T) {
return qb.where(sql``);
}

const qbBase = db.delete(users).$dynamic();
const qb = dynamic(qbBase);
const result = await qb;
Expect<Equal<SingleStoreRawQueryResult, typeof result>>;
}

{
db
.delete(users)
.where(sql``)
// @ts-expect-error method was already called
.where(sql``);

db
.delete(users)
.$dynamic()
.where(sql``)
.where(sql``);
}
158 changes: 158 additions & 0 deletions drizzle-orm/type-tests/singlestore/generated-columns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { type Equal, Expect } from 'type-tests/utils';
import { type InferInsertModel, type InferSelectModel, sql } from '~/index';
import { drizzle } from '~/singlestore';
import { serial, singlestoreTable, text, varchar } from '~/singlestore-core';
import { db } from './db';

const users = singlestoreTable(
'users',
{
id: serial('id').primaryKey(),
firstName: varchar('first_name', { length: 255 }),
lastName: varchar('last_name', { length: 255 }),
email: text('email').notNull(),
fullName: text('full_name').generatedAlwaysAs(sql`concat_ws(first_name, ' ', last_name)`),
upperName: text('upper_name').generatedAlwaysAs(
sql` case when first_name is null then null else upper(first_name) end `,
).$type<string | null>(), // There is no way for drizzle to detect nullability in these cases. This is how the user can work around it
},
);
{
type User = typeof users.$inferSelect;
type NewUser = typeof users.$inferInsert;

Expect<
Equal<
{
id: number;
firstName: string | null;
lastName: string | null;
email: string;
fullName: string | null;
upperName: string | null;
},
User
>
>();

Expect<
Equal<
{
email: string;
id?: number | undefined;
firstName?: string | null | undefined;
lastName?: string | null | undefined;
},
NewUser
>
>();
}

{
type User = InferSelectModel<typeof users>;
type NewUser = InferInsertModel<typeof users>;

Expect<
Equal<
{
id: number;
firstName: string | null;
lastName: string | null;
email: string;
fullName: string | null;
upperName: string | null;
},
User
>
>();

Expect<
Equal<
{
email: string;
id?: number | undefined;
firstName?: string | null | undefined;
lastName?: string | null | undefined;
},
NewUser
>
>();
}

{
const dbUsers = await db.select().from(users);

Expect<
Equal<
{
id: number;
firstName: string | null;
lastName: string | null;
email: string;
fullName: string | null;
upperName: string | null;
}[],
typeof dbUsers
>
>();
}

{
const db = drizzle({} as any, { schema: { users }, mode: 'default' });

const dbUser = await db.query.users.findFirst();

Expect<
Equal<
{
id: number;
firstName: string | null;
lastName: string | null;
email: string;
fullName: string | null;
upperName: string | null;
} | undefined,
typeof dbUser
>
>();
}

{
const db = drizzle({} as any, { schema: { users }, mode: 'default' });

const dbUser = await db.query.users.findMany();

Expect<
Equal<
{
id: number;
firstName: string | null;
lastName: string | null;
email: string;
fullName: string | null;
upperName: string | null;
}[],
typeof dbUser
>
>();
}

{
// @ts-expect-error - Can't use the fullName because it's a generated column
await db.insert(users).values({
firstName: 'test',
lastName: 'test',
email: 'test',
fullName: 'test',
});
}

{
await db.update(users).set({
firstName: 'test',
lastName: 'test',
email: 'test',
// @ts-expect-error - Can't use the fullName because it's a generated column
fullName: 'test',
});
}
135 changes: 135 additions & 0 deletions drizzle-orm/type-tests/singlestore/insert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import type { Equal } from 'type-tests/utils.ts';
import { Expect } from 'type-tests/utils.ts';
import { int, singlestoreTable, text } from '~/singlestore-core/index.ts';
import type { SingleStoreInsert } from '~/singlestore-core/index.ts';
import type { SingleStoreRawQueryResult } from '~/singlestore/index.ts';
import { sql } from '~/sql/sql.ts';
import { db } from './db.ts';
import { users } from './tables.ts';

const singlestoreInsertReturning = await db.insert(users).values({
// ^?
homeCity: 1,
class: 'A',
age1: 1,
enumCol: 'a',
}).$returningId();

Expect<Equal<{ id: number; serialNullable: number; serialNotNull: number }[], typeof singlestoreInsertReturning>>;

const insert = await db.insert(users).values({
homeCity: 1,
class: 'A',
age1: 1,
enumCol: 'a',
});
Expect<Equal<SingleStoreRawQueryResult, typeof insert>>;

const insertStmt = db.insert(users).values({
homeCity: 1,
class: 'A',
age1: 1,
enumCol: 'a',
}).prepare();
const insertPrepared = await insertStmt.execute();
Expect<Equal<SingleStoreRawQueryResult, typeof insertPrepared>>;

const insertSql = await db.insert(users).values({
homeCity: sql`123`,
class: 'A',
age1: 1,
enumCol: sql`foobar`,
});
Expect<Equal<SingleStoreRawQueryResult, typeof insertSql>>;

const insertSqlStmt = db.insert(users).values({
homeCity: sql`123`,
class: 'A',
age1: 1,
enumCol: sql`foobar`,
}).prepare();
const insertSqlPrepared = await insertSqlStmt.execute();
Expect<Equal<SingleStoreRawQueryResult, typeof insertSqlPrepared>>;

const insertReturning = await db.insert(users).values({
homeCity: 1,
class: 'A',
age1: 1,
enumCol: 'a',
});
Expect<Equal<SingleStoreRawQueryResult, typeof insertReturning>>;

const insertReturningStmt = db.insert(users).values({
homeCity: 1,
class: 'A',
age1: 1,
enumCol: 'a',
}).prepare();
const insertReturningPrepared = await insertReturningStmt.execute();
Expect<Equal<SingleStoreRawQueryResult, typeof insertReturningPrepared>>;

const insertReturningPartial = await db.insert(users).values({
homeCity: 1,
class: 'A',
age1: 1,
enumCol: 'a',
});
Expect<Equal<SingleStoreRawQueryResult, typeof insertReturningPartial>>;

const insertReturningPartialStmt = db.insert(users).values({
homeCity: 1,
class: 'A',
age1: 1,
enumCol: 'a',
}).prepare();
const insertReturningPartialPrepared = await insertReturningPartialStmt.execute();
Expect<Equal<SingleStoreRawQueryResult, typeof insertReturningPartialPrepared>>;

const insertReturningSql = await db.insert(users).values({
homeCity: 1,
class: 'A',
age1: sql`2 + 2`,
enumCol: 'a',
});
Expect<Equal<SingleStoreRawQueryResult, typeof insertReturningSql>>;

const insertReturningSqlStmt = db.insert(users).values({
homeCity: 1,
class: 'A',
age1: sql`2 + 2`,
enumCol: 'a',
}).prepare();
const insertReturningSqlPrepared = await insertReturningSqlStmt.execute();
Expect<Equal<SingleStoreRawQueryResult, typeof insertReturningSqlPrepared>>;

{
const users = singlestoreTable('users', {
id: int('id').autoincrement().primaryKey(),
name: text('name').notNull(),
age: int('age'),
occupation: text('occupation'),
});

await db.insert(users).values({ name: 'John Wick', age: 58, occupation: 'housekeeper' });
}

{
function dynamic<T extends SingleStoreInsert>(qb: T) {
return qb.onDuplicateKeyUpdate({ set: {} });
}

const qbBase = db.insert(users).values({ age1: 0, class: 'A', enumCol: 'a', homeCity: 0 }).$dynamic();
const qb = dynamic(qbBase);
const result = await qb;

Expect<Equal<SingleStoreRawQueryResult, typeof result>>;
}

{
db
.insert(users)
.values({ age1: 0, class: 'A', enumCol: 'a', homeCity: 0 })
.onDuplicateKeyUpdate({ set: {} })
// @ts-expect-error method was already called
.onDuplicateKeyUpdate({ set: {} });
}
Loading

0 comments on commit ae78e04

Please sign in to comment.