From 23231ae3ee22e66d8310d0b24059c712f64d892c Mon Sep 17 00:00:00 2001 From: itowlson Date: Tue, 19 Aug 2025 11:21:28 +1200 Subject: [PATCH] New database APIs for Spin 3.4 Signed-off-by: itowlson --- content/v3/rdbms-storage.md | 24 +++++++++++++++++++++++- content/v3/sqlite-api-guide.md | 10 ++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/content/v3/rdbms-storage.md b/content/v3/rdbms-storage.md index 6368d909..c9aaf568 100644 --- a/content/v3/rdbms-storage.md +++ b/content/v3/rdbms-storage.md @@ -7,6 +7,8 @@ url = "https://github.com/spinframework/spin-docs/blob/main/content/v3/rdbms-sto --- - [Using MySQL and PostgreSQL From Applications](#using-mysql-and-postgresql-from-applications) +- [Application Development Considerations](#application-development-considerations) + - [PostgreSQL Range Queries](#postgresql-range-queries) - [Granting Network Permissions to Components](#granting-network-permissions-to-components) - [Configuration-Based Permissions](#configuration-based-permissions) @@ -37,7 +39,11 @@ The exact detail of calling these operations from your application depends on yo > [**Want to go straight to the reference documentation?** Find it here.](https://docs.rs/spin-sdk/latest/spin_sdk/index.html) -MySQL functions are available in the `spin_sdk::mysql` module, and PostgreSQL functions in the `spin_sdk::pg` module. The function names match the operations above. This example shows MySQL: +MySQL functions are available in the `spin_sdk::mysql` module, and PostgreSQL functions in the `spin_sdk::pg4` module. + +> If you want to be compatible with Spin 3.3 or earlier, or with downstream hosts that have not yet rolled out Spin 3.4 support, you should use the `spin_sdk::pg3` module for PostgreSQL. The module interfaces are identical, but `pg3` does not support all the data types in `pg4`. + +The function names match the operations above. This example shows MySQL: ```rust // For PostgreSQL, use `spin_sdk::pg` or `spin_sdk::pg3` @@ -207,6 +213,22 @@ func init() { {{ blockEnd }} +## Application Development Considerations + +This section contains notes and gotchas for developers using Spin's relational database APIs. + +### PostgreSQL Range Queries + +The PostgreSQL "range contains" operator, `<@`, is overloaded for "contains value" and "contains another range." This ambiguity can result in "wrong type" errors when executing "range contains" queries where the left hand side is parameterised. + +To avoid this, use a type annotation on the parameter placeholder, e.g.: + +``` +SELECT name FROM cats WHERE $1::int4 <@ reign +``` + +The ambiguity is tracked at https://github.com/sfackler/rust-postgres/issues/1258. + ## Granting Network Permissions to Components By default, Spin components are not allowed to make outgoing network requests, including MySQL or PostgreSQL. This follows the general Wasm rule that modules must be explicitly granted capabilities, which is important to sandboxing. To grant a component permission to make network requests to a particular host, use the `allowed_outbound_hosts` field in the component manifest, specifying the host and allowed port: diff --git a/content/v3/sqlite-api-guide.md b/content/v3/sqlite-api-guide.md index 987d817c..2dc6ae27 100644 --- a/content/v3/sqlite-api-guide.md +++ b/content/v3/sqlite-api-guide.md @@ -37,6 +37,8 @@ The set of operations is common across all SDKs: |------------|------------|---------|----------| | `open` | name | connection | Open the database with the specified name. If `name` is the string "default", the default database is opened, provided that the component that was granted access in the component manifest from `spin.toml`. Otherwise, `name` must refer to a store defined and configured in a [runtime configuration file](./dynamic-configuration.md#sqlite-storage-runtime-configuration) supplied with the application.| | `execute` | connection, sql, parameters | database records | Executes the SQL statement and returns the results of the statement. SELECT statements typically return records or scalars. INSERT, UPDATE, and DELETE statements typically return empty result sets, but may return values in some cases. The `execute` operation recognizes the [SQLite dialect of SQL](https://www.sqlite.org/lang.html). | +| `last-insert-rowid` | connection | integer | The SQLite rowid of the recent successful INSERT on the connection, or 0 if there has not yet been an INSERT on the connection. | +| `changes` | connection | integer | The number of rows modified, inserted or deleted by the most recently completed INSERT, UPDATE or DELETE statement on the connection. | The exact detail of calling these operations from your application depends on your language: @@ -52,9 +54,13 @@ serde = {version = "1.0", features = ["derive"]} serde_json = "1.0" ``` -> [**Want to go straight to the reference documentation?** Find it here.](https://docs.rs/spin-sdk/latest/spin_sdk/sqlite/index.html) +> [**Want to go straight to the reference documentation?** Find it here.](https://docs.rs/spin-sdk/latest/spin_sdk/sqlite3/index.html) -SQLite functions are available in the `spin_sdk::sqlite` module. The function names match the operations above. For example: +SQLite functions are available in the `spin_sdk::sqlite3` module + +> If you want to be compatible with Spin 3.1 or earlier, or with downstream hosts that have not yet rolled out Spin 3.2 support, you should use the `spin_sdk::sqlite` module for PostgreSQL. The only difference is that `sqlite` doesn't provide the `Connection::last_insert_rowid` and `Connection::changes` functions. + +The function names match the operations above. For example: ```rust use anyhow::Result;