0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-06 22:10:10 -05:00
astro/packages/db/README.md
2024-01-24 16:29:45 -06:00

4.1 KiB
Raw Blame History

@astrojs/db

Astro DB helps you create a SQLite database with powerful query APIs.

Installation

@astrojs/db is an Astro integration you can install with the astro add command:

# npm
npm run astro add db

# pnpm
pnpm astro add db

Configure your first collection

“Collections” are database tables you can query from your Astro project. To create a collection, you can use the defineCollection() and field utilities provided by @astrojs/db. All collections should be applied to the db object in your astro.config.mjs file:

import { defineCollection, field } from '@astrojs/db';
import { defineConfig } from 'astro/config';

const Author = defineCollection({
	fields: {
		name: field.text(),
		socialLink: field.text({ optional: true }),
		isFeatured: field.boolean(),
	}
});

export default defineConfig({
	db: {
		collections: { Author },
	}
});

📚 See the defineCollection() API reference for all supported fields and configuration options.

Default id field

All collections will be created with a generated id field. This can be used to fetch individual entries or “join” related tables. This id will be be of type “text” with a generated nanoid.

Pass collection data

Collections are considered “read-only” by default. To set collection data, you can add the data() function to your collection config. This should return an array of objects to insert into the database, with keys matching your collection fields:

import { defineCollection, field } from '@astrojs/db';
import { defineConfig } from 'astro/config';

const Author = defineCollection({
	fields: {},
	data() {
		return [
			{ name: 'Fred K Schott' },
			{ name: 'Ben Holmes', isFeatured: true },
			{ name: 'ThePrimeagen', socialLink: 'https://twitch.tv/ThePrimeagen' },
		]
	}
});

export default defineConfig({
	db: {
		collections: { Author },
	}
});

Glob data from the filesystem

You may want to glob a directory of files (say .json) to insert as database rows. You can install the fast-glob package to glob from your astro.config.mjs file:

# npm
npm i fast-glob
# pnpm
pnpm i fast-glob

Then, call glob() over your directory of choice, and parse each files contents using Node readFile() and JSON.parse():

import { glob } from 'fast-glob';
import { readFile } from 'node:fs/promises';
import { defineCollection, field } from '@astrojs/db';
import { defineConfig } from 'astro/config';

const Author = defineCollection({
	fields: {},
	async data() {
		const authors = await glob(authors/**/*.json);
		return Promise.all(authors.map(async (author => {
			const contents = await readfile(author);
			return JSON.parse(contents);		
		})));
	}
});

export default defineConfig({
	db: {
		collections: { Author },
	}
});

Query data

You can query collection data using the @astrojs/db SQL ORM. This is powered by Drizzle ORM, exposing collections as Drizzle objects you can use to construct type-safe SQL queries.

You can create queries using the db object provided by the astro:db module. This example selects all entries in the Authors collection and renders the results to a list:

---
import { db, Author } from 'astro:db';
const authors = await db.select().from(Author);
---

<h2>Authors</h2>
<ul>
	{authors.map(({ name, socialLink }) => (
    <li>
	    socialLink ? <a href={socialLink}>{name}</a> : name
    </li>
  ))}
</ul>

Filter data

You can filter entries using a where() clause. This accepts conditional functions like eq(), which can be used to assert a field has a particular value. This example filters for “featured” authors in the Authors collection:

---
import { db, eq, Author } from 'astro:db';

const authors = await db.select().from(Author).where(
  eq(Author.isFeatured, true),
);
---

You may want to join related collections by id. You can handle joins using a SQL join operator like innerJoin().