Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/docs/00100-intro/00200-quickstarts/00600-c-sharp.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ cd my-spacetime-app
spacetime call add Alice

# Query the person table
spacetime sql "SELECT * FROM Person"
spacetime sql "SELECT * FROM person"
name
---------
"Alice"
Expand Down Expand Up @@ -219,7 +219,7 @@ cd my-spacetime-app
spacetime call add Alice

# Query the person table
spacetime sql "SELECT * FROM Person"
spacetime sql "SELECT * FROM person"
name
---------
"Alice"
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/00100-intro/00300-tutorials/00100-chat-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ spacetime call --server local quickstart-chat send_message 'Hello, World!'
<TabItem value="csharp" label="C#">

```bash
spacetime call --server local quickstart-chat SendMessage 'Hello, World!'
spacetime call --server local quickstart-chat send_message 'Hello, World!'
```

</TabItem>
Expand Down Expand Up @@ -848,7 +848,7 @@ spacetime sql --server local quickstart-chat "SELECT * FROM message"
<TabItem value="csharp" label="C#">

```bash
spacetime sql --server local quickstart-chat "SELECT * FROM Message"
spacetime sql --server local quickstart-chat "SELECT * FROM message"
```

</TabItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ We'll play around a bit with `spacetime call` to set up a character:
```sh
$ spacetime logs incr-migration-demo -f &

$ spacetime call incr-migration-demo create_character '{ "Fighter": {} }' "Phoebe"
$ spacetime call incr-migration-demo create_character '{ "fighter": {} }' "Phoebe"

2025-01-07T15:32:57.447286Z INFO: src/lib.rs:21: Creating new level 1 Fighter named Phoebe

Expand All @@ -122,7 +122,7 @@ $ spacetime sql incr-migration-demo 'SELECT * FROM character'

player_id | nickname | level | class
-----------+----------+-------+----------------
<snip> | "Gefjon" | 2 | (Fighter = ())
<snip> | "Gefjon" | 2 | (fighter = ())
```

See [the SATS JSON reference](../../../00300-resources/00200-reference/00300-internals/00200-sats-json.md) for more on the encoding of arguments to `spacetime call`.
Expand Down Expand Up @@ -323,7 +323,7 @@ $ spacetime sql incr-migration-demo 'SELECT * FROM character'

player_id | nickname | level | class
-----------+----------+-------+----------------
<snip> | "Gefjon" | 2 | (Fighter = ())
<snip> | "Gefjon" | 2 | (fighter = ())

# We haven't triggered the "Gefjon" row to migrate yet, so `character_v2` is empty:
$ spacetime sql -s local incr-migration-demo 'SELECT * FROM character_v2'
Expand All @@ -341,18 +341,18 @@ $ spacetime sql incr-migration-demo 'SELECT * FROM character_v2'

player_id | nickname | level | class | alliance
-----------+----------+-------+----------------+----------------
<snip> | "Gefjon" | 3 | (Fighter = ()) | (Neutral = ())
<snip> | "Gefjon" | 3 | (fighter = ()) | (neutral = ())

# The original row in `character` still got updated by `level_up_character`,
# so outdated clients can continue to function:
$ spacetime sql incr-migration-demo 'SELECT * FROM character'

player_id | nickname | level | class
-----------+----------+-------+----------------
<snip> | "Gefjon" | 3 | (Fighter = ())
<snip> | "Gefjon" | 3 | (fighter = ())

# We can set our alliance:
$ spacetime call incr-migration-demo choose_alliance '{ "Good": {} }'
$ spacetime call incr-migration-demo choose_alliance '{ "good": {} }'

2025-01-07T16:13:53.816501Z INFO: src/lib.rs:129: Setting alliance of Gefjon to Good

Expand All @@ -361,14 +361,14 @@ $ spacetime sql incr-migration-demo 'SELECT * FROM character_v2'

player_id | nickname | level | class | alliance
-----------+----------+-------+----------------+-------------
<snip> | "Gefjon" | 3 | (Fighter = ()) | (Good = ())
<snip> | "Gefjon" | 3 | (fighter = ()) | (good = ())

# But `character` is not changed, since it doesn't know about alliances:
$ spacetime sql incr-migration-demo 'SELECT * FROM character'

player_id | nickname | level | class
-----------+----------+-------+----------------
<snip> | "Gefjon" | 3 | (Fighter = ())
<snip> | "Gefjon" | 3 | (fighter = ())
```

Now that we know how to define incremental migrations, we can add new features that would seem to require breaking schema changes without cumbersome external migration tools and while maintaining compatibility of outdated clients! The complete for this tutorial is on GitHub in the `clockworklabs/incr-migration-demo` repository, in branches [`v1`](https://github.com/clockworklabs/incr-migration-demo/tree/v1), [`fails-publish`](https://github.com/clockworklabs/incr-migration-demo/tree/fails-publish) and [`v2`](https://github.com/clockworklabs/incr-migration-demo/tree/v2).
Original file line number Diff line number Diff line change
Expand Up @@ -1088,9 +1088,9 @@ All [`IDbContext`](#interface-idbcontext) implementors, including [`DbConnection

Each reducer defined by the module has three methods on the `.Reducers`:

- An invoke method, whose name is the reducer's name converted to snake case, like `set_name`. This requests that the module run the reducer.
- A callback registation method, whose name is prefixed with `on_`, like `on_set_name`. This registers a callback to run whenever we are notified that the reducer ran, including successfully committed runs and runs we requested which failed. This method returns a callback id, which can be passed to the callback remove method.
- A callback remove method, whose name is prefixed with `remove_on_`, like `remove_on_set_name`. This cancels a callback previously registered via the callback registration method.
- An invoke method, whose name is the reducer's accessor name converted to PascalCase, like `SetName`. This requests that the module run the reducer.
- A callback registration event, whose name is prefixed with `On`, like `OnSetName`. This registers a callback to run whenever we are notified that the reducer ran, including successfully committed runs and runs we requested which failed.
- A callback remove method, whose name is prefixed with `RemoveOn`, like `RemoveOnSetName`. This cancels a callback previously registered via the callback registration event.

## Identify a client

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,7 @@ The `reducers` field of the context provides access to reducers exposed by the r

All [`DbContext`](#interface-dbcontext) implementors, including [`DbConnection`](#type-dbconnection) and [`EventContext`](#type-eventcontext), have fields `.db`, which in turn has methods for accessing tables and views in the client cache.

Each table or view defined by a module has an accessor method, whose name is the table or view name converted to `camelCase`, on this `.db` field. The accessor methods return table handles. Table handles have methods for [accessing rows](#accessing-rows) and [registering `onInsert`](#callback-oninsert) and [`onDelete` callbacks](#callback-ondelete). Handles with a known primary key also expose [`onUpdate` callbacks](#callback-onupdate). Table handles also offer the ability to find subscribed rows by unique index.
Each table or view defined by a module has an accessor method, whose name is the table or view accessor converted to `camelCase`, on this `.db` field. For example, a module accessor `logged_out_player` is exposed as `loggedOutPlayer`; generated clients may also include deprecated aliases for older snake_case handles. The accessor methods return table handles. Table handles have methods for [accessing rows](#accessing-rows) and [registering `onInsert`](#callback-oninsert) and [`onDelete` callbacks](#callback-ondelete). Handles with a known primary key also expose [`onUpdate` callbacks](#callback-onupdate). Table handles also offer the ability to find subscribed rows by unique index.

| Name | Description |
| ------------------------------------------------------ | -------------------------------------------------------------------------------- |
Expand Down
94 changes: 47 additions & 47 deletions docs/docs/00300-resources/00200-reference/00400-sql-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,19 @@ otherwise it must be qualified with the appropriate table name.

```sql
-- Subscribe to all rows of a table
SELECT * FROM Inventory
SELECT * FROM inventory

-- Qualify the `*` projection with the table
SELECT item.* from Inventory item
SELECT item.* from inventory item

-- Subscribe to all customers who have orders totaling more than $1000
SELECT customer.*
FROM Customers customer JOIN Orders o ON customer.id = o.customer_id
FROM customers customer JOIN orders o ON customer.id = o.customer_id
WHERE o.amount > 1000

-- INVALID: Must return `Customers` or `Orders`, but not both
-- INVALID: Must return `customers` or `orders`, but not both
SELECT *
FROM Customers customer JOIN Orders o ON customer.id = o.customer_id
FROM customers customer JOIN orders o ON customer.id = o.customer_id
WHERE o.amount > 1000
```

Expand All @@ -87,18 +87,18 @@ subscriptions require an index to be defined on both join columns.

```sql
-- Subscribe to all orders of products with less than 10 items in stock.
-- Must have an index on the `product_id` column of the `Orders` table,
-- as well as the `id` column of the `Product` table.
-- Must have an index on the `product_id` column of the `orders` table,
-- as well as the `id` column of the `inventory` table.
SELECT o.*
FROM Orders o JOIN Inventory product ON o.product_id = product.id
FROM orders o JOIN inventory product ON o.product_id = product.id
WHERE product.quantity < 10

-- Subscribe to all products that have at least one purchase
SELECT product.*
FROM Orders o JOIN Inventory product ON o.product_id = product.id
FROM orders o JOIN inventory product ON o.product_id = product.id

-- INVALID: Must qualify the column names referenced in `ON`
SELECT product.* FROM Orders JOIN Inventory product ON product_id = id
SELECT product.* FROM orders JOIN inventory product ON product_id = id
```

### WHERE
Expand Down Expand Up @@ -144,10 +144,10 @@ Arithmetic expressions are not supported.

```sql
-- Find products that sell for more than $X
SELECT * FROM Inventory WHERE price > {X}
SELECT * FROM inventory WHERE price > {X}

-- Find products that sell for more than $X and have fewer than Y items in stock
SELECT * FROM Inventory WHERE price > {X} AND amount < {Y}
SELECT * FROM inventory WHERE price > {X} AND amount < {Y}
```

## Query and DML (Data Manipulation Language)
Expand Down Expand Up @@ -203,10 +203,10 @@ The `SELECT` clause determines the columns that are returned.

```sql
-- Select the items in my inventory
SELECT * FROM Inventory;
SELECT * FROM inventory;

-- Select the names and prices of the items in my inventory
SELECT item_name, price FROM Inventory
SELECT item_name, price FROM inventory
```

It also allows for counting the number of input rows via the `COUNT` function.
Expand All @@ -216,7 +216,7 @@ It also allows for counting the number of input rows via the `COUNT` function.

```sql
-- Count the items in my inventory
SELECT COUNT(*) AS n FROM Inventory
SELECT COUNT(*) AS n FROM inventory
```

#### FROM Clause
Expand All @@ -232,9 +232,9 @@ Unlike [subscriptions](#from), the query api supports joining more than two tabl
```sql
-- Find all customers who ordered a particular product and when they ordered it
SELECT customer.first_name, customer.last_name, o.date
FROM Customers customer
JOIN Orders o ON customer.id = o.customer_id
JOIN Inventory product ON o.product_id = product.id
FROM customers customer
JOIN orders o ON customer.id = o.customer_id
JOIN inventory product ON o.product_id = product.id
WHERE product.name = {product_name}
```

Expand All @@ -252,7 +252,7 @@ The `LIMIT` may return fewer rows if the query itself returns fewer rows.

```sql
-- Fetch an example row from my inventory
SELECT * FROM Inventory LIMIT 1
SELECT * FROM inventory LIMIT 1
```

### INSERT
Expand All @@ -265,10 +265,10 @@ INSERT INTO table [ '(' column { ',' column } ')' ] VALUES '(' literal { ',' lit

```sql
-- Inserting one row
INSERT INTO Inventory (item_id, item_name) VALUES (1, 'health1');
INSERT INTO inventory (item_id, item_name) VALUES (1, 'health1');

-- Inserting two rows
INSERT INTO Inventory (item_id, item_name) VALUES (1, 'health1'), (2, 'health2');
INSERT INTO inventory (item_id, item_name) VALUES (1, 'health1'), (2, 'health2');
```

### DELETE
Expand All @@ -286,10 +286,10 @@ If `WHERE` is specified, only the matching rows are deleted.

```sql
-- Delete all rows
DELETE FROM Inventory;
DELETE FROM inventory;

-- Delete all rows with a specific item_id
DELETE FROM Inventory WHERE item_id = 1;
DELETE FROM inventory WHERE item_id = 1;
```

### UPDATE
Expand All @@ -309,7 +309,7 @@ The rows are updated after the `WHERE` condition is evaluated for all rows.

```sql
-- Update the item_name for all rows with a specific item_id
UPDATE Inventory SET item_name = 'new name' WHERE item_id = 1;
UPDATE inventory SET item_name = 'new name' WHERE item_id = 1;
```

### SET
Expand Down Expand Up @@ -393,9 +393,9 @@ The concrete type of a literal is inferred from the context.

```sql
-- All products that sell for more than $1000
SELECT * FROM Inventory WHERE price > 1000
SELECT * FROM Inventory WHERE price > 1e3
SELECT * FROM Inventory WHERE price > 1E3
SELECT * FROM inventory WHERE price > 1000
SELECT * FROM inventory WHERE price > 1e3
SELECT * FROM inventory WHERE price > 1E3
```

### Floats
Expand All @@ -414,9 +414,9 @@ The concrete type of a literal is inferred from the context.

```sql
-- All measurements where the temperature is greater than 105.3
SELECT * FROM Measurements WHERE temperature > 105.3
SELECT * FROM Measurements WHERE temperature > 1053e-1
SELECT * FROM Measurements WHERE temperature > 1053E-1
SELECT * FROM measurements WHERE temperature > 105.3
SELECT * FROM measurements WHERE temperature > 1053e-1
SELECT * FROM measurements WHERE temperature > 1053E-1
```

### Strings
Expand All @@ -432,7 +432,7 @@ STRING
#### Examples

```sql
SELECT * FROM Customers WHERE first_name = 'John'
SELECT * FROM customers WHERE first_name = 'John'
```

### Hex
Expand All @@ -454,7 +454,7 @@ The type is ultimately inferred from the context.
#### Examples

```sql
SELECT * FROM Program WHERE hash_value = 0xABCD1234
SELECT * FROM program WHERE hash_value = 0xABCD1234
```

## Identifiers
Expand Down Expand Up @@ -526,20 +526,20 @@ Take the following query that was used in a previous example:
```sql
-- Find all customers who ordered a particular product and when they ordered it
SELECT customer.first_name, customer.last_name, o.date
FROM Customers customer
JOIN Orders o ON customer.id = o.customer_id
JOIN Inventory product ON o.product_id = product.id
FROM customers customer
JOIN orders o ON customer.id = o.customer_id
JOIN inventory product ON o.product_id = product.id
WHERE product.name = {product_name}
```

In order to conform with the best practices for optimizing performance and scalability:

- An index should be defined on `Inventory.name` because we are filtering on that column.
- `Inventory.id` and `Customers.id` should be defined as primary keys.
- Additionally non-unique indexes should be defined on `Orders.product_id` and `Orders.customer_id`.
- `Inventory` should appear first in the `FROM` clause because it is the only table mentioned in the `WHERE` clause.
- `Orders` should come next because it joins directly with `Inventory`.
- `Customers` should come next because it joins directly with `Orders`.
- An index should be defined on `inventory.name` because we are filtering on that column.
- `inventory.id` and `customers.id` should be defined as primary keys.
- Additionally non-unique indexes should be defined on `orders.product_id` and `orders.customer_id`.
- `inventory` should appear first in the `FROM` clause because it is the only table mentioned in the `WHERE` clause.
- `orders` should come next because it joins directly with `inventory`.
- `customers` should come next because it joins directly with `orders`.

<Tabs groupId="server-language" defaultValue="rust">
<TabItem value="csharp" label="C#">
Expand Down Expand Up @@ -583,7 +583,7 @@ public partial struct Orders

```rust
#[table(
accessor = Inventory,
accessor = inventory,
index(accessor = product_name, btree = [name]),
public
)]
Expand All @@ -595,7 +595,7 @@ struct Inventory {
}

#[table(
accessor = Customers,
accessor = customers,
public
)]
struct Customers {
Expand All @@ -607,7 +607,7 @@ struct Customers {
}

#[table(
accessor = Orders,
accessor = orders,
public
)]
struct Orders {
Expand All @@ -627,9 +627,9 @@ struct Orders {
```sql
-- Find all customers who ordered a particular product and when they ordered it
SELECT c.first_name, c.last_name, o.date
FROM Inventory product
JOIN Orders o ON product.id = o.product_id
JOIN Customers c ON c.id = o.customer_id
FROM inventory product
JOIN orders o ON product.id = o.product_id
JOIN customers c ON c.id = o.customer_id
WHERE product.name = {product_name};
```

Expand Down
Loading