docs: website docs structure + first content pages
Phase D foundation. Configures the pragmatic four-section sidebar (Getting started / Guides / Reference / Concepts) and replaces the template example pages with grounded content built on the shared "library" example database (authors/books/members/loans): - Getting started: installation, first project, simple vs advanced, the example library. - Reference: Types (all ten + serial/shortid + advanced aliases), Tables (create/drop, compound PK, advanced CREATE TABLE). - Concepts: projects & storage (readable files, derived database, autosave, temp projects). - Guides: Build the library (draft, to be refined for teaching). Command syntax grounded in en-US.yaml usage/help, command.rs, and types.rs (verified against tests). Records the settled doc decisions in STYLE.md. Build green (10 pages, Pagefind); content clean of "DSL"/engine-name.
This commit is contained in:
+70
-26
@@ -39,22 +39,63 @@ Status tags used below: **[DECIDED]** (binding or settled) ·
|
|||||||
instructions ("Create a table…").
|
instructions ("Create a table…").
|
||||||
- Prefer short sentences and concrete examples over abstract prose.
|
- Prefer short sentences and concrete examples over abstract prose.
|
||||||
|
|
||||||
|
## Structure [DECIDED]
|
||||||
|
|
||||||
|
Pragmatic, Diátaxis-influenced split (four top-level sidebar sections,
|
||||||
|
autogenerated per directory under `src/content/docs/`):
|
||||||
|
|
||||||
|
- **Getting started** — install, first project, simple vs. advanced, the
|
||||||
|
example database.
|
||||||
|
- **Guides** — task-oriented how-tos. *These are the most important didactic
|
||||||
|
content and will be iterated for teaching quality before publication.*
|
||||||
|
- **Reference** — the exhaustive command/SQL/type surface. **Page
|
||||||
|
granularity: one page per topic / command-family** (Tables, Columns,
|
||||||
|
Relationships, Indexes, Constraints, Inserting & editing data, Querying,
|
||||||
|
Types, …), each covering the simple-mode and advanced-mode forms where
|
||||||
|
both apply. Hand-written now (the command surface is settled bar H1a
|
||||||
|
output); small post-release adjustments are expected and fine.
|
||||||
|
- **Concepts** — the "why": projects & storage, undo & history, etc.
|
||||||
|
|
||||||
|
Ground every reference page in source — `parse.usage.*` and `help.*` in
|
||||||
|
`src/friendly/strings/en-US.yaml`, `src/dsl/command.rs`, `src/dsl/types.rs`
|
||||||
|
— never paraphrase grammar from memory.
|
||||||
|
|
||||||
## "Planned / not yet available" callouts [DECIDED — ADR-0042 §7]
|
## "Planned / not yet available" callouts [DECIDED — ADR-0042 §7]
|
||||||
|
|
||||||
Any capability that is not yet fully implemented is **omitted** or carries a
|
Any capability that is not yet fully implemented is **omitted** or carries a
|
||||||
clear **"planned / not yet available"** callout — never presented as
|
clear callout — never presented as shipped. Standard form: a Starlight aside
|
||||||
shipped. Use a Starlight aside (`:::caution` or a custom badge). **[OPEN]**:
|
|
||||||
exact component + wording (see log).
|
|
||||||
|
|
||||||
## Examples & code [OPEN]
|
```md
|
||||||
|
:::caution[Planned]
|
||||||
|
This is planned and not yet available.
|
||||||
|
:::
|
||||||
|
```
|
||||||
|
|
||||||
Direction (to confirm in the log):
|
## Examples & code [DECIDED]
|
||||||
- A single **standard example schema/dataset** reused across pages so
|
|
||||||
readers build familiarity (candidate: a small, recognisable domain).
|
- **Shared example database: a small library** — `authors`, `books`,
|
||||||
|
`members`, `loans` (see the canonical schema below). Reuse it across all
|
||||||
|
pages so readers build familiarity; it models 1:n (an author has many
|
||||||
|
books) and m:n (books ↔ members, through loans).
|
||||||
- Where both modes apply, show the **simple-mode** form and its
|
- Where both modes apply, show the **simple-mode** form and its
|
||||||
**advanced-mode (SQL)** equivalent — the in-app teaching echo already
|
**advanced-mode (SQL)** equivalent — the in-app teaching echo already
|
||||||
pairs these, so docs can mirror it.
|
pairs these, so docs mirror it.
|
||||||
- Code blocks for input/output; reserve casts for motion/flow (see below).
|
- Code blocks for exact input/output; reserve casts for motion/flow.
|
||||||
|
|
||||||
|
### Canonical library schema (source of truth for examples)
|
||||||
|
|
||||||
|
Use these exact names/types in every example:
|
||||||
|
|
||||||
|
| Table | Columns (playground types) |
|
||||||
|
|-----------|---------------------------------------------------------------------------------------------|
|
||||||
|
| `authors` | `author_id` serial (pk) · `name` text (not null) · `birth_year` int |
|
||||||
|
| `books` | `book_id` serial (pk) · `title` text (not null) · `author_id` int (→ authors) · `published` int · `isbn` text (unique) |
|
||||||
|
| `members` | `member_id` serial (pk) · `name` text (not null) · `joined` date |
|
||||||
|
| `loans` | `loan_id` serial (pk) · `book_id` int (→ books) · `member_id` int (→ members) · `loaned_on` date · `returned_on` date |
|
||||||
|
|
||||||
|
Relationships: `books.author_id → authors.author_id` (1:n); `loans` joins
|
||||||
|
`books` and `members` (the m:n bridge). Show `shortid` on the Types page via
|
||||||
|
a small standalone example, not by complicating this schema.
|
||||||
|
|
||||||
## asciinema casts [DECIDED, details OPEN]
|
## asciinema casts [DECIDED, details OPEN]
|
||||||
|
|
||||||
@@ -81,20 +122,23 @@ Direction (to confirm in the log):
|
|||||||
Decide these as we write; record the outcome (and escalate to an ADR if
|
Decide these as we write; record the outcome (and escalate to an ADR if
|
||||||
significant).
|
significant).
|
||||||
|
|
||||||
1. **Depth / organising spine.** Adopt **Diátaxis** (tutorial / how-to /
|
**Resolved (2026-06-05):**
|
||||||
reference / explanation) as the structure, or a lighter
|
1. ~~Depth / organising spine~~ → **Pragmatic** four-section split (see
|
||||||
getting-started + reference + concepts split? Affects the whole sidebar.
|
Structure above).
|
||||||
2. **Page granularity & splitting.** One page per command, per
|
2. ~~Page granularity~~ → **one page per topic / command-family**, both
|
||||||
command-family, or per task? When does a page split?
|
modes per page (see Structure).
|
||||||
3. **Standard example schema/dataset.** What domain + tables do all examples
|
3. ~~Standard example dataset~~ → **the library** (schema above).
|
||||||
share?
|
4. ~~Simple-vs-advanced pairing~~ → **show both where both apply** (see
|
||||||
4. **Simple-vs-advanced pairing.** Always show both forms, or only where
|
Examples).
|
||||||
instructive? How to present the pairing visually.
|
5. ~~"Planned" callout~~ → standard `:::caution[Planned]` aside (see above).
|
||||||
5. **"Planned" callout component & wording.** Exact Starlight component and
|
6. ~~Reference generation vs hand-writing~~ → **hand-write now** (command
|
||||||
standard sentence.
|
surface is settled bar H1a output; small later adjustments expected).
|
||||||
6. **Reference generation vs hand-writing.** Generate the command reference
|
|
||||||
from source (the `help` REGISTRY / `en-US.yaml`) to avoid drift, or
|
**Still open:**
|
||||||
author by hand? (Flagged in the plan's notes.)
|
7. **Versioning.** Version selectors at/after v1, or single-version for
|
||||||
7. **Versioning.** Do docs need version selectors at/after v1, or is
|
launch? (Leaning single-version for launch.)
|
||||||
single-version fine for launch?
|
8. **SEO/meta conventions.** Title/description patterns, Open Graph — settle
|
||||||
8. **SEO/meta conventions.** Title/description patterns, Open Graph.
|
with Phase B (landing) and the `site` URL.
|
||||||
|
9. **Cast scripting toolchain.** Confirm the scripted-input driver
|
||||||
|
(`asciinema-automation`/autocast vs alternative) via a test run; define
|
||||||
|
the `.cast` script format + storage location. (Execution task, in flight.)
|
||||||
|
|||||||
+25
-23
@@ -6,28 +6,30 @@ import tailwindcss from '@tailwindcss/vite';
|
|||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
// TODO(Phase B/SEO): set `site` to the production URL once the domain is
|
||||||
starlight({
|
// known — enables the sitemap and canonical/OG URLs.
|
||||||
title: 'My Docs',
|
integrations: [
|
||||||
social: [{ icon: 'github', label: 'GitHub', href: 'https://github.com/withastro/starlight' }],
|
starlight({
|
||||||
customCss: ['./src/styles/global.css'],
|
title: 'RDBMS Playground',
|
||||||
sidebar: [
|
tagline: 'Learn relational databases by doing.',
|
||||||
{
|
// TODO(Phase B): point at the real repository once it moves to its
|
||||||
label: 'Guides',
|
// public home. Omitted for now rather than linking the wrong repo.
|
||||||
items: [
|
// social: [{ icon: 'github', label: 'GitHub', href: '…' }],
|
||||||
// Each item here is one entry in the navigation menu.
|
customCss: ['./src/styles/global.css'],
|
||||||
{ label: 'Example Guide', slug: 'guides/example' },
|
// Pragmatic structure (ADR-0042 §7 / website/STYLE.md): Getting
|
||||||
],
|
// started, Guides, Reference, Concepts. Autogenerated per directory;
|
||||||
},
|
// in-section order is controlled by each page's `sidebar.order`
|
||||||
{
|
// frontmatter.
|
||||||
label: 'Reference',
|
sidebar: [
|
||||||
items: [{ autogenerate: { directory: 'reference' } }],
|
{ label: 'Getting started', items: [{ autogenerate: { directory: 'getting-started' } }] },
|
||||||
},
|
{ label: 'Guides', items: [{ autogenerate: { directory: 'guides' } }] },
|
||||||
],
|
{ label: 'Reference', items: [{ autogenerate: { directory: 'reference' } }] },
|
||||||
}),
|
{ label: 'Concepts', items: [{ autogenerate: { directory: 'concepts' } }] },
|
||||||
|
],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
|
|
||||||
vite: {
|
vite: {
|
||||||
plugins: [tailwindcss()],
|
plugins: [tailwindcss()],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
---
|
||||||
|
title: Projects and storage
|
||||||
|
description: How the playground stores your work — readable files, a derived database, autosave, and temporary projects.
|
||||||
|
sidebar:
|
||||||
|
order: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
Everything you do in the playground lives in a **project** — a folder on
|
||||||
|
disk. Understanding what is in that folder explains why your work is safe,
|
||||||
|
shareable, and easy to inspect.
|
||||||
|
|
||||||
|
## What a project contains
|
||||||
|
|
||||||
|
| File / folder | Role |
|
||||||
|
|---|---|
|
||||||
|
| `project.yaml` | The schema: your tables, columns, keys, relationships, and indexes. |
|
||||||
|
| `data/<table>.csv` | One file per table holding its rows, as plain CSV. |
|
||||||
|
| `history.log` | An append-only journal of every command you have run. |
|
||||||
|
| the database file | The working database the playground queries. **Derived** — see below. |
|
||||||
|
|
||||||
|
The first three are the **authoritative, human-readable** record of your
|
||||||
|
project. You can open them in any editor, diff them in version control, and
|
||||||
|
read them without the playground.
|
||||||
|
|
||||||
|
## The database is derived
|
||||||
|
|
||||||
|
The database file the playground queries is built *from* `project.yaml` and
|
||||||
|
the CSV files. Because it is derived, it never needs to be shared or backed
|
||||||
|
up separately — and if it is ever missing or stale, the `rebuild` command
|
||||||
|
regenerates it from the readable files:
|
||||||
|
|
||||||
|
```text
|
||||||
|
rebuild
|
||||||
|
```
|
||||||
|
|
||||||
|
## Your work saves itself
|
||||||
|
|
||||||
|
There is no "save" step to remember. Every command writes through to the
|
||||||
|
files as it runs, so a project is always up to date on disk. (The `save`
|
||||||
|
command exists for a different purpose: giving a temporary project a
|
||||||
|
permanent name — see below.)
|
||||||
|
|
||||||
|
## Temporary vs. named projects
|
||||||
|
|
||||||
|
When you start the playground without naming a project, it creates a
|
||||||
|
**temporary** project with an automatic name. Temporary projects are perfect
|
||||||
|
for quick experiments. When you want to keep one, give it a name:
|
||||||
|
|
||||||
|
```text
|
||||||
|
save
|
||||||
|
```
|
||||||
|
|
||||||
|
Empty, untouched temporary projects are cleaned up automatically, so casual
|
||||||
|
experimenting never leaves clutter behind.
|
||||||
|
|
||||||
|
## Where projects live
|
||||||
|
|
||||||
|
Projects are stored in a standard per-user location for your operating
|
||||||
|
system. Override it for a single run with `--data-dir <PATH>` — handy for
|
||||||
|
keeping a course's projects together, or for testing.
|
||||||
|
|
||||||
|
## Sharing a project
|
||||||
|
|
||||||
|
The `export` command packages a project as a zip you can send to anyone:
|
||||||
|
|
||||||
|
```text
|
||||||
|
export
|
||||||
|
```
|
||||||
|
|
||||||
|
The zip contains the readable files (`project.yaml` and `data/`) but **not**
|
||||||
|
the derived database or your private `history.log`. The recipient opens it
|
||||||
|
and the playground rebuilds the database for them. Exporting and
|
||||||
|
importing has its own reference page.
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
title: The example library
|
||||||
|
description: The small library database used throughout these docs.
|
||||||
|
sidebar:
|
||||||
|
order: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
Most examples in this documentation use the same small database: a library
|
||||||
|
with **authors**, **books**, **members**, and **loans**. Keeping one
|
||||||
|
familiar set of tables makes it easier to focus on the concept each page is
|
||||||
|
teaching.
|
||||||
|
|
||||||
|
## The tables
|
||||||
|
|
||||||
|
| Table | Columns |
|
||||||
|
|---|---|
|
||||||
|
| `authors` | `author_id` (serial, primary key), `name` (text), `birth_year` (int) |
|
||||||
|
| `books` | `book_id` (serial, primary key), `title` (text), `author_id` (int → authors), `published` (int), `isbn` (text, unique) |
|
||||||
|
| `members` | `member_id` (serial, primary key), `name` (text), `joined` (date) |
|
||||||
|
| `loans` | `loan_id` (serial, primary key), `book_id` (int → books), `member_id` (int → members), `loaned_on` (date), `returned_on` (date) |
|
||||||
|
|
||||||
|
## The relationships
|
||||||
|
|
||||||
|
- **An author has many books.** `books.author_id` points at
|
||||||
|
`authors.author_id` — a one-to-many relationship.
|
||||||
|
- **Members borrow books.** Each row in `loans` ties one book to one member,
|
||||||
|
so `loans` connects `books` and `members` — a many-to-many relationship
|
||||||
|
expressed through a bridging table.
|
||||||
|
|
||||||
|
You will build these tables and relationships step by step in
|
||||||
|
[Build the library](/guides/build-the-library/). Individual reference pages
|
||||||
|
use whichever part of this schema illustrates the command at hand.
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
title: Your first project
|
||||||
|
description: Create a table, add a row, and look at it — a two-minute tour of the playground.
|
||||||
|
sidebar:
|
||||||
|
order: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
This is the shortest possible tour: create a table, put a row in it, and
|
||||||
|
look at the result. Everything here is in **simple mode**, which is how the
|
||||||
|
playground starts.
|
||||||
|
|
||||||
|
When you launch `rdbms-playground` with no arguments, it opens a fresh
|
||||||
|
temporary project for you. Type commands into the input field at the bottom
|
||||||
|
and press <kbd>Enter</kbd> to run them.
|
||||||
|
|
||||||
|
## Create a table
|
||||||
|
|
||||||
|
A table needs at least a primary key. The `with pk` clause names the
|
||||||
|
primary-key column and its type:
|
||||||
|
|
||||||
|
```text
|
||||||
|
create table authors with pk author_id(serial)
|
||||||
|
```
|
||||||
|
|
||||||
|
`serial` is an auto-incrementing number — you will not have to fill it in
|
||||||
|
yourself.
|
||||||
|
|
||||||
|
## Add a couple of columns
|
||||||
|
|
||||||
|
In simple mode you create a table with its key, then add the other columns
|
||||||
|
one at a time:
|
||||||
|
|
||||||
|
```text
|
||||||
|
add column to authors: name (text)
|
||||||
|
add column to authors: birth_year (int)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Add a row
|
||||||
|
|
||||||
|
`insert` adds a row. List the columns you are supplying — the `author_id`
|
||||||
|
fills itself in because it is a `serial`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
insert into authors (name, birth_year) values ('Ada Lovelace', 1815)
|
||||||
|
```
|
||||||
|
|
||||||
|
The playground shows the row it just inserted, including the generated
|
||||||
|
`author_id`.
|
||||||
|
|
||||||
|
## Look at the data
|
||||||
|
|
||||||
|
```text
|
||||||
|
show data authors
|
||||||
|
```
|
||||||
|
|
||||||
|
That is the whole loop: **create → add columns → insert → show**. From here:
|
||||||
|
|
||||||
|
- Build the full example database in [Build the library](/guides/build-the-library/).
|
||||||
|
- Learn how [simple and advanced modes](/getting-started/modes/) differ.
|
||||||
|
- Look up any command in the [Reference](/reference/types/).
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
---
|
||||||
|
title: Installation
|
||||||
|
description: Install RDBMS Playground from a prebuilt binary or a package manager, and run it for the first time.
|
||||||
|
sidebar:
|
||||||
|
order: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
RDBMS Playground is a single self-contained program. There is nothing to
|
||||||
|
configure and no separate database to install — everything it needs is
|
||||||
|
built in.
|
||||||
|
|
||||||
|
## Prebuilt binaries
|
||||||
|
|
||||||
|
Download the binary for your platform, make it executable if needed, and
|
||||||
|
put it somewhere on your `PATH`.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Download links are published with each release. They are added here when the
|
||||||
|
first public version ships.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Package managers
|
||||||
|
|
||||||
|
Once published, the playground will be installable through common package
|
||||||
|
managers:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# macOS / Linux (Homebrew)
|
||||||
|
brew install rdbms-playground
|
||||||
|
|
||||||
|
# Windows (Scoop)
|
||||||
|
scoop install rdbms-playground
|
||||||
|
```
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Package-manager availability lands with the first public release; the exact
|
||||||
|
names are confirmed here at that time.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Run it
|
||||||
|
|
||||||
|
Start the playground with no arguments and it opens a fresh, automatically
|
||||||
|
named temporary project so you can start experimenting immediately:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
rdbms-playground
|
||||||
|
```
|
||||||
|
|
||||||
|
To open an existing project, pass its path:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
rdbms-playground path/to/project
|
||||||
|
```
|
||||||
|
|
||||||
|
Useful options (run `rdbms-playground --help` for the full list):
|
||||||
|
|
||||||
|
| Option | What it does |
|
||||||
|
|---|---|
|
||||||
|
| `--resume` | Reopen the most recently used project. |
|
||||||
|
| `--data-dir <PATH>` | Use a different location for stored projects. |
|
||||||
|
| `--theme <light\|dark>` | Force a theme instead of auto-detecting. |
|
||||||
|
| `--mode <simple\|advanced>` | Start in a specific input mode. |
|
||||||
|
|
||||||
|
Next: [create your first project](/getting-started/first-project/).
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
title: Simple and advanced modes
|
||||||
|
description: How the playground's two input modes differ, how to switch, and the one-line escape hatch.
|
||||||
|
sidebar:
|
||||||
|
order: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
The playground has two input modes. You can do everything a beginner needs
|
||||||
|
in **simple mode**, and reach for **advanced mode** when you want full SQL.
|
||||||
|
|
||||||
|
## Simple mode (the default)
|
||||||
|
|
||||||
|
Simple mode is a friendly, keyword-based command language designed for
|
||||||
|
learning. Commands read close to English:
|
||||||
|
|
||||||
|
```text
|
||||||
|
create table authors with pk author_id(serial)
|
||||||
|
show data authors
|
||||||
|
```
|
||||||
|
|
||||||
|
Simple mode accepts these learning commands plus the app-level commands
|
||||||
|
(like `save`, `undo`, and `help`). If you type raw SQL here, the playground
|
||||||
|
gently points you at advanced mode instead of failing silently.
|
||||||
|
|
||||||
|
## Advanced mode (SQL)
|
||||||
|
|
||||||
|
Advanced mode accepts standard SQL — `SELECT`, `INSERT`, `CREATE TABLE`, and
|
||||||
|
more — alongside the same app-level commands:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
select title, published from books where published >= 2000 order by published;
|
||||||
|
```
|
||||||
|
|
||||||
|
Switch modes with the `mode` command:
|
||||||
|
|
||||||
|
```text
|
||||||
|
mode advanced
|
||||||
|
mode simple
|
||||||
|
```
|
||||||
|
|
||||||
|
The mode you leave a project in is remembered and restored the next time you
|
||||||
|
open it, so a project set up for SQL practice reopens in advanced mode.
|
||||||
|
|
||||||
|
## The one-line escape
|
||||||
|
|
||||||
|
When you are in simple mode and want to run a single SQL statement without
|
||||||
|
switching, prefix the line with a colon:
|
||||||
|
|
||||||
|
```text
|
||||||
|
:select count(*) from books
|
||||||
|
```
|
||||||
|
|
||||||
|
That runs just this one line as SQL; you stay in simple mode afterwards.
|
||||||
|
|
||||||
|
## Seeing the SQL behind a command
|
||||||
|
|
||||||
|
When you run a simple-mode command in advanced mode, the playground prints
|
||||||
|
the equivalent SQL beneath your command. It is a built-in way to learn how
|
||||||
|
the friendly commands map onto real SQL — the same statements you could type
|
||||||
|
yourself in advanced mode.
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
title: Build the library
|
||||||
|
description: Build the example library database step by step — tables, a relationship, and some rows.
|
||||||
|
sidebar:
|
||||||
|
order: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
:::note[Draft]
|
||||||
|
This guide is an early draft. The walkthrough is correct, but the wording
|
||||||
|
and pacing will be refined for teaching before the docs are published.
|
||||||
|
:::
|
||||||
|
|
||||||
|
This guide builds the [example library](/getting-started/example-library/)
|
||||||
|
from scratch in simple mode: two tables, a relationship between them, and a
|
||||||
|
few rows. By the end you will have used the create → add column → relate →
|
||||||
|
insert → query loop end to end.
|
||||||
|
|
||||||
|
## 1. Create the authors table
|
||||||
|
|
||||||
|
```text
|
||||||
|
create table authors with pk author_id(serial)
|
||||||
|
add column to authors: name (text)
|
||||||
|
add column to authors: birth_year (int)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Create the books table
|
||||||
|
|
||||||
|
```text
|
||||||
|
create table books with pk book_id(serial)
|
||||||
|
add column to books: title (text)
|
||||||
|
add column to books: author_id (int)
|
||||||
|
add column to books: published (int)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Relate books to authors
|
||||||
|
|
||||||
|
An author has many books, so `books.author_id` should point at
|
||||||
|
`authors.author_id`. Declare that one-to-many relationship:
|
||||||
|
|
||||||
|
```text
|
||||||
|
add 1:n relationship from authors.author_id to books.author_id
|
||||||
|
```
|
||||||
|
|
||||||
|
The relationship reads parent-to-child: **from** the `authors` side **to**
|
||||||
|
the `books` side.
|
||||||
|
|
||||||
|
## 4. Add some rows
|
||||||
|
|
||||||
|
`author_id` and `book_id` are `serial`, so they fill themselves in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
insert into authors (name, birth_year) values ('Ada Lovelace', 1815)
|
||||||
|
insert into authors (name, birth_year) values ('Alan Turing', 1912)
|
||||||
|
insert into books (title, author_id, published) values ('Notes on the Analytical Engine', 1, 1843)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Look at your data
|
||||||
|
|
||||||
|
```text
|
||||||
|
show data authors
|
||||||
|
show data books
|
||||||
|
```
|
||||||
|
|
||||||
|
## Where to go next
|
||||||
|
|
||||||
|
- Add the `members` and `loans` tables the same way to model borrowing — a
|
||||||
|
many-to-many relationship through `loans`.
|
||||||
|
- Try the same steps in advanced mode to see the SQL form of each command.
|
||||||
|
- Look up any command in detail in the Reference section.
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
title: Example Guide
|
|
||||||
description: A guide in my new Starlight docs site.
|
|
||||||
---
|
|
||||||
|
|
||||||
Guides lead a user through a specific task they want to accomplish, often with a sequence of steps.
|
|
||||||
Writing a good guide requires thinking about what your users are trying to do.
|
|
||||||
|
|
||||||
## Further reading
|
|
||||||
|
|
||||||
- Read [about how-to guides](https://diataxis.fr/how-to-guides/) in the Diátaxis framework
|
|
||||||
@@ -1,40 +1,50 @@
|
|||||||
---
|
---
|
||||||
title: Welcome to Starlight
|
title: RDBMS Playground
|
||||||
description: Get started building your docs site with Starlight.
|
description: A terminal playground for learning relational databases — tables, keys, relationships, indexes, queries, and query plans, hands-on.
|
||||||
template: splash # Remove or comment out this line to display the site sidebar on this page.
|
template: splash
|
||||||
hero:
|
hero:
|
||||||
tagline: Congrats on setting up a new Starlight project!
|
tagline: Learn relational databases by doing — in your terminal.
|
||||||
image:
|
|
||||||
file: ../../assets/houston.webp
|
|
||||||
actions:
|
actions:
|
||||||
- text: Example Guide
|
- text: Get started
|
||||||
link: /guides/example/
|
link: /getting-started/installation/
|
||||||
icon: right-arrow
|
icon: right-arrow
|
||||||
- text: Read the Starlight docs
|
- text: Browse the reference
|
||||||
link: https://starlight.astro.build
|
link: /reference/types/
|
||||||
icon: external
|
|
||||||
variant: minimal
|
variant: minimal
|
||||||
---
|
---
|
||||||
|
|
||||||
import { Card, CardGrid } from '@astrojs/starlight/components';
|
import { Card, CardGrid, LinkCard } from '@astrojs/starlight/components';
|
||||||
|
|
||||||
## Next steps
|
RDBMS Playground is a cross-platform terminal app that gives you a safe
|
||||||
|
sandbox for exploring relational database concepts: tables, columns,
|
||||||
|
primary and foreign keys, relationships, indexes, queries, and query
|
||||||
|
plans. It is built for learning — from your first table to writing raw
|
||||||
|
SQL.
|
||||||
|
|
||||||
<CardGrid stagger>
|
<CardGrid>
|
||||||
<Card title="Update content" icon="pencil">
|
<Card title="Two ways to work" icon="seti:db">
|
||||||
Edit `src/content/docs/index.mdx` to see this page change.
|
Start in **simple mode** — a friendly, keyword-based command language —
|
||||||
|
and switch to **advanced mode** for standard SQL whenever you are ready.
|
||||||
</Card>
|
</Card>
|
||||||
<Card title="Change page layout" icon="document">
|
<Card title="Learn the SQL underneath" icon="open-book">
|
||||||
Delete `template: splash` in `src/content/docs/index.mdx` to display a
|
Run a simple-mode command in advanced mode and the playground shows you
|
||||||
sidebar on this page.
|
the equivalent SQL, so the bridge from concepts to SQL is always visible.
|
||||||
</Card>
|
</Card>
|
||||||
<Card title="Add new content" icon="add-document">
|
<Card title="Safe to experiment" icon="approve-check">
|
||||||
Add Markdown or MDX files to `src/content/docs` to create new pages.
|
Every change can be undone, your work is saved as you go, and you can
|
||||||
|
rebuild the whole database from plain, readable files.
|
||||||
</Card>
|
</Card>
|
||||||
<Card title="Configure your site" icon="setting">
|
<Card title="See how queries run" icon="rocket">
|
||||||
Edit your `sidebar` and other config in `astro.config.mjs`.
|
Ask the playground to explain any query and it renders the database's
|
||||||
</Card>
|
plan as an annotated tree — so indexes and scans stop being a mystery.
|
||||||
<Card title="Read the docs" icon="open-book">
|
|
||||||
Learn more in [the Starlight Docs](https://starlight.astro.build/).
|
|
||||||
</Card>
|
</Card>
|
||||||
</CardGrid>
|
</CardGrid>
|
||||||
|
|
||||||
|
## Start here
|
||||||
|
|
||||||
|
<CardGrid>
|
||||||
|
<LinkCard title="Install" href="/getting-started/installation/" description="Get the playground running on your machine." />
|
||||||
|
<LinkCard title="Your first project" href="/getting-started/first-project/" description="Create a table, add a row, and see it." />
|
||||||
|
<LinkCard title="The example library" href="/getting-started/example-library/" description="The small database used throughout these docs." />
|
||||||
|
<LinkCard title="Reference" href="/reference/types/" description="Every command, type, and constraint in detail." />
|
||||||
|
</CardGrid>
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
title: Example Reference
|
|
||||||
description: A reference page in my new Starlight docs site.
|
|
||||||
---
|
|
||||||
|
|
||||||
Reference pages are ideal for outlining how things work in terse and clear terms.
|
|
||||||
Less concerned with telling a story or addressing a specific use case, they should give a comprehensive outline of what you're documenting.
|
|
||||||
|
|
||||||
## Further reading
|
|
||||||
|
|
||||||
- Read [about reference](https://diataxis.fr/reference/) in the Diátaxis framework
|
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
---
|
||||||
|
title: Tables
|
||||||
|
description: Create and drop tables in simple mode and in advanced-mode SQL, including compound primary keys.
|
||||||
|
sidebar:
|
||||||
|
order: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
A table is the core building block. This page covers creating and removing
|
||||||
|
tables; changing a table's columns after it exists is covered under Columns
|
||||||
|
in the Reference.
|
||||||
|
|
||||||
|
## Create a table (simple mode)
|
||||||
|
|
||||||
|
Every table is created with its primary key. The `with pk` clause lists the
|
||||||
|
primary-key column(s):
|
||||||
|
|
||||||
|
```text
|
||||||
|
create table authors with pk author_id(serial)
|
||||||
|
```
|
||||||
|
|
||||||
|
Other columns are added afterwards with `add column`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
add column to authors: name (text)
|
||||||
|
add column to authors: birth_year (int)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compound primary keys
|
||||||
|
|
||||||
|
To make the primary key span more than one column, list them, comma
|
||||||
|
separated:
|
||||||
|
|
||||||
|
```text
|
||||||
|
create table loans with pk book_id(int), member_id(int)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Syntax**
|
||||||
|
|
||||||
|
```text
|
||||||
|
create table <Name> with pk <col>(<type>)[, ...]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create a table (advanced mode)
|
||||||
|
|
||||||
|
In advanced mode you write a full `CREATE TABLE` with every column and
|
||||||
|
constraint inline:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
create table authors (
|
||||||
|
author_id serial primary key,
|
||||||
|
name text not null,
|
||||||
|
birth_year int
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
The advanced form also accepts table-level constraints and inline foreign
|
||||||
|
keys — see the Constraints and Relationships references.
|
||||||
|
|
||||||
|
**Syntax**
|
||||||
|
|
||||||
|
```text
|
||||||
|
create table [if not exists] <Name> (<col> <type> [constraints], ...)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Drop a table
|
||||||
|
|
||||||
|
```text
|
||||||
|
drop table authors
|
||||||
|
```
|
||||||
|
|
||||||
|
In advanced mode you may add `if exists` so removing a table that is not
|
||||||
|
there succeeds quietly:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
drop table if exists authors
|
||||||
|
```
|
||||||
|
|
||||||
|
:::caution
|
||||||
|
Dropping a table removes its rows as well. Use `undo` if you drop one by
|
||||||
|
mistake.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Renaming a table
|
||||||
|
|
||||||
|
Renaming a table is available in advanced mode:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
alter table authors rename to writers
|
||||||
|
```
|
||||||
|
|
||||||
|
There is no simple-mode rename verb — switch to advanced mode (or use the
|
||||||
|
one-line `:` escape) to rename a table.
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
---
|
||||||
|
title: Types
|
||||||
|
description: The ten column types, what they store, and the auto-generating serial and shortid types.
|
||||||
|
sidebar:
|
||||||
|
order: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
Every column has a type. The playground offers ten, chosen to cover what a
|
||||||
|
learner needs without the sprawl of a production database.
|
||||||
|
|
||||||
|
## The ten types
|
||||||
|
|
||||||
|
| Type | Stores |
|
||||||
|
|---|---|
|
||||||
|
| `text` | Text of any length. |
|
||||||
|
| `int` | A whole number (64-bit signed). |
|
||||||
|
| `real` | A floating-point number. |
|
||||||
|
| `decimal` | An exact decimal number, kept precise (see note below). |
|
||||||
|
| `bool` | A truth value, shown as `true` / `false`. |
|
||||||
|
| `date` | A calendar date, `YYYY-MM-DD`. |
|
||||||
|
| `datetime` | A date and time, `YYYY-MM-DDTHH:MM:SS`. |
|
||||||
|
| `blob` | Arbitrary binary data. |
|
||||||
|
| `serial` | An auto-incrementing whole number — see below. |
|
||||||
|
| `shortid` | A short random identifier — see below. |
|
||||||
|
|
||||||
|
:::note
|
||||||
|
`decimal`, `date`, and `datetime` are compared as text, so they sort in the
|
||||||
|
expected order when written in their standard form. Arithmetic on a
|
||||||
|
`decimal` needs an explicit cast — they are stored exactly rather than as
|
||||||
|
approximate floating point.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Auto-generated types: `serial` and `shortid`
|
||||||
|
|
||||||
|
Two types fill themselves in when you insert a row, so you never supply them
|
||||||
|
by hand.
|
||||||
|
|
||||||
|
- **`serial`** — the next number in sequence (one more than the current
|
||||||
|
maximum). It is the natural choice for a primary key. Outside a primary
|
||||||
|
key, a `serial` column is kept unique.
|
||||||
|
- **`shortid`** — a short, random, base58 identifier (10–12 characters,
|
||||||
|
avoiding easily-confused characters). Always kept unique. Useful when you
|
||||||
|
want an identifier that is compact but not guessable or sequential.
|
||||||
|
|
||||||
|
```text
|
||||||
|
create table members with pk member_id(serial)
|
||||||
|
add column to members: member_code (shortid)
|
||||||
|
insert into members (name) values ('Grace Hopper')
|
||||||
|
```
|
||||||
|
|
||||||
|
Both the `member_id` and the `member_code` are generated for you.
|
||||||
|
|
||||||
|
If you add a `serial` or `shortid` column to a table that already has rows —
|
||||||
|
or change an existing column to one of these types — the empty cells are
|
||||||
|
filled with freshly generated values in the same step.
|
||||||
|
|
||||||
|
## Keys that point at these types
|
||||||
|
|
||||||
|
A foreign key stores a plain looked-up value, not a new generated one. So a
|
||||||
|
column that references a `serial` primary key is itself an `int`, and one
|
||||||
|
that references a `shortid` is a `text`. The playground handles this for you
|
||||||
|
when you declare a relationship; it is worth knowing why the child column's
|
||||||
|
type differs from the parent key's.
|
||||||
|
|
||||||
|
## Type names in advanced mode
|
||||||
|
|
||||||
|
In advanced mode you may also use familiar standard-SQL spellings, which map
|
||||||
|
onto the types above — for example `integer`, `bigint`, and `smallint` are
|
||||||
|
all `int`; `varchar` and `char` are `text`; `boolean` is `bool`; `timestamp`
|
||||||
|
is `datetime`; `numeric` is `decimal`; `float` and `double precision` are
|
||||||
|
`real`. Simple mode uses only the ten names in the table, so it teaches one
|
||||||
|
clear vocabulary.
|
||||||
Reference in New Issue
Block a user