0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-03-10 23:01:26 -05:00

fix(db): validate column type before column schema (#10409)

* fix(db): validate column type before column schema

* add changeset

* Add test for text foreign keys

---------

Co-authored-by: Matthew Phillips <matthew@skypack.dev>
This commit is contained in:
Arsh 2024-03-13 19:19:28 +05:30 committed by GitHub
parent c9cde7e8e0
commit 96c8bca19a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 64 additions and 4 deletions

View file

@ -0,0 +1,5 @@
---
"@astrojs/db": patch
---
Fixes an issue where one table schema could not reference text fields of another table schema.

View file

@ -145,7 +145,7 @@ export const jsonColumnSchema = z.object({
}),
});
export const columnSchema = z.union([
export const columnSchema = z.discriminatedUnion("type", [
booleanColumnSchema,
numberColumnSchema,
textColumnSchema,

View file

@ -64,5 +64,13 @@ describe('astro:db', () => {
const themeDark = $($('.themes-list .theme-dark')[0]).text();
expect(themeDark).to.equal('dark mode');
});
it('text fields an be used as references', async () => {
const html = await fixture.fetch('/login').then((res) => res.text());
const $ = cheerioLoad(html);
expect($('.session-id').text()).to.equal('12345');
expect($('.username').text()).to.equal('Mario');
});
});
});

View file

@ -4,4 +4,7 @@ import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({
integrations: [db()],
devToolbar: {
enabled: false,
}
});

View file

@ -8,6 +8,22 @@ const Author = defineTable({
},
});
export default defineDb({
tables: { Author, Themes },
const User = defineTable({
columns: {
id: column.text({ primaryKey: true, optional: false }),
username: column.text({ optional: false, unique: true }),
password: column.text({ optional: false }),
},
});
const Session = defineTable({
columns: {
id: column.text({ primaryKey: true, optional: false }),
expiresAt: column.number({ optional: false, name: "expires_at" }),
userId: column.text({ optional: false, references: () => User.columns.id, name: "user_id" }),
},
});
export default defineDb({
tables: { Author, Themes, User, Session },
});

View file

@ -1,6 +1,6 @@
import { asDrizzleTable } from '@astrojs/db/utils';
import { Themes as ThemesConfig } from './theme';
import { Author, db } from 'astro:db';
import { Author, User, Session, db } from 'astro:db';
const Themes = asDrizzleTable('Themes', ThemesConfig);
export default async function () {
@ -18,5 +18,15 @@ export default async function () {
{ name: 'Bjorn' },
{ name: 'Sarah' },
]),
db
.insert(User)
.values([
{ id: 'mario', username: 'Mario', password: 'itsame' }
]),
db
.insert(Session)
.values([
{ id: '12345', expiresAt: new Date().valueOf(), userId: 'mario' }
]),
]);
}

View file

@ -0,0 +1,18 @@
---
import { db, Session, User, eq } from 'astro:db';
const users = await db.select().from(User);
const sessions = await db.select()
.from(Session)
.innerJoin(User, eq(Session.userId, User.id));
---
<h2>Sessions</h2>
<ul class="sessions-list">
{sessions.map(({ Session, User }) => (
<li>
<div class="session-id">{Session.id}</div>
<div class="username">{User.username}</div>
</li>
))}
</ul>