Skip to content

Commit

Permalink
[SQLite] Added type tests and integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Angelelz committed Dec 27, 2023
1 parent 92bd784 commit cfa1c1d
Show file tree
Hide file tree
Showing 4 changed files with 812 additions and 17 deletions.
161 changes: 161 additions & 0 deletions drizzle-orm/type-tests/sqlite/db-rel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import Database from 'better-sqlite3';
import { type Equal, Expect } from 'type-tests/utils';
import { drizzle } from '~/better-sqlite3';
import { sql } from '~/index';
import * as schema from './tables-rel';

const client = new Database(':memory:');

const db = drizzle(client, { schema });

{
const result = await db.query.users.findMany({
where: (users, { sql }) => sql`char_length(${users.name} > 1)`,
limit: sql.placeholder('l'),
orderBy: (users, { asc, desc }) => [asc(users.name), desc(users.id)],
with: {
posts: {
where: (posts, { sql }) => sql`char_length(${posts.title} > 1)`,
limit: sql.placeholder('l'),
columns: {
id: false,
title: undefined,
},
with: {
author: true,
comments: {
where: (comments, { sql }) => sql`char_length(${comments.text} > 1)`,
limit: sql.placeholder('l'),
columns: {
text: true,
},
with: {
author: {
columns: {
id: undefined,
},
with: {
city: {
with: {
users: true,
},
},
},
},
},
},
},
},
},
});

Expect<
Equal<{
id: number;
name: string;
cityId: number;
homeCityId: number | null;
createdAt: Date;
posts: {
title: string;
authorId: number | null;
comments: {
text: string;
author: {
city: {
id: number;
name: string;
users: {
id: number;
name: string;
cityId: number;
homeCityId: number | null;
createdAt: Date;
}[];
};
} | null;
}[];
author: {
id: number;
name: string;
cityId: number;
homeCityId: number | null;
createdAt: Date;
} | null;
}[];
}[], typeof result>
>;
}

{
const result = await db.query.users.findMany({
columns: {
id: true,
name: true,
},
with: {
posts: {
columns: {
authorId: true,
},
extras: {
lower: sql<string>`lower(${schema.posts.title})`.as('lower_name'),
},
},
},
});

Expect<
Equal<
{
id: number;
name: string;
posts: {
authorId: number | null;
lower: string;
}[];
}[],
typeof result
>
>;
}

{ // One relations can be null even if the foreign key is not nullable if they have a where clause
const result = await db.query.notes.findMany({
with: {
users: true,
posts: true,
comments: true,
},
});

Expect<
Equal<
{
id: number;
text: string;
notableId: number;
notableType: 'User' | 'Post' | 'Comment';
users: {
id: number;
name: string;
cityId: number;
homeCityId: number | null;
createdAt: Date;
} | null; // users can be null due to the where condition
posts: {
id: number;
title: string;
authorId: number | null;
};
comments: {
id: number;
text: string;
authorId: number | null;
postId: number;
};
}[],
typeof result
>
>;
}
93 changes: 93 additions & 0 deletions drizzle-orm/type-tests/sqlite/tables-rel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { eq, sql } from '~/index';
import { relations } from '~/relations.ts';
import { integer, sqliteTable, text } from '~/sqlite-core';

export const users = sqliteTable('users', {
id: integer('id').primaryKey(),
name: text('name').notNull(),
cityId: integer('city_id').references(() => cities.id).notNull(),
homeCityId: integer('home_city_id').references(() => cities.id),
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
});
export const usersConfig = relations(users, ({ one, many }) => ({
city: one(cities, { relationName: 'UsersInCity', fields: [users.cityId], references: [cities.id] }),
homeCity: one(cities, { fields: [users.homeCityId], references: [cities.id] }),
posts: many(posts),
comments: many(comments),
notes: many(notes, { where: eq(notes.notableType, 'User') }),
}));

export const cities = sqliteTable('cities', {
id: integer('id').primaryKey(),
name: text('name').notNull(),
});
export const citiesConfig = relations(cities, ({ many }) => ({
users: many(users, { relationName: 'UsersInCity' }),
}));

export const posts = sqliteTable('posts', {
id: integer('id').primaryKey(),
title: text('title').notNull(),
authorId: integer('author_id').references(() => users.id),
});
export const postsConfig = relations(posts, ({ one, many }) => ({
author: one(users, { fields: [posts.authorId], references: [users.id] }),
comments: many(comments),
notes: many(notes, { where: eq(notes.notableType, 'Post') }),
}));

export const comments = sqliteTable('comments', {
id: integer('id').primaryKey(),
postId: integer('post_id').references(() => posts.id).notNull(),
authorId: integer('author_id').references(() => users.id),
text: text('text').notNull(),
});
export const commentsConfig = relations(comments, ({ one, many }) => ({
post: one(posts, { fields: [comments.postId], references: [posts.id] }),
author: one(users, { fields: [comments.authorId], references: [users.id] }),
notes: many(notes, { where: eq(notes.notableType, 'Comment') }),
}));

export const books = sqliteTable('books', {
id: integer('id').primaryKey(),
name: text('name').notNull(),
});
export const booksConfig = relations(books, ({ many }) => ({
authors: many(bookAuthors),
}));

export const bookAuthors = sqliteTable('book_authors', {
bookId: integer('book_id').references(() => books.id).notNull(),
authorId: integer('author_id').references(() => users.id).notNull(),
role: text('role').notNull(),
});
export const bookAuthorsConfig = relations(bookAuthors, ({ one }) => ({
book: one(books, { fields: [bookAuthors.bookId], references: [books.id] }),
author: one(users, { fields: [bookAuthors.authorId], references: [users.id] }),
}));

export const node = sqliteTable('node', {
id: integer('id').primaryKey(),
parentId: integer('parent_id'),
leftId: integer('left_id'),
rightId: integer('right_id'),
});
export const nodeRelations = relations(node, ({ one }) => ({
parent: one(node, { fields: [node.parentId], references: [node.id] }),
left: one(node, { fields: [node.leftId], references: [node.id] }),
right: one(node, { fields: [node.rightId], references: [node.id] }),
}));

export const notes = sqliteTable('note', {
id: integer('id').primaryKey(),
text: text('text').notNull(),
notableId: integer('notable_id').notNull(),
notableType: text('notable_type', { enum: ['User', 'Post', 'Comment'] }).notNull(),
});

export const noteRelations = relations(notes, ({ one }) => ({
// users should be inferred as User | null due to the where
users: one(users, { fields: [notes.notableId], references: [users.id], where: sql`` }),
posts: one(posts, { fields: [notes.notableId], references: [posts.id] }),
comments: one(comments, { fields: [notes.notableId], references: [comments.id] }),
}));
Loading

0 comments on commit cfa1c1d

Please sign in to comment.