|
1 | | -//! Conversions between Rust, WIT and **Postgres** types. |
| 1 | +//! Postgres relational database storage. |
| 2 | +//! |
| 3 | +//! You can use the [`into()`](std::convert::Into) method to convert |
| 4 | +//! a Rust value into a [`ParameterValue`]. You can use the |
| 5 | +//! [`Decode`] trait to convert a [`DbValue`] to a suitable Rust type. |
| 6 | +//! The following table shows available conversions. |
2 | 7 | //! |
3 | 8 | //! # Types |
4 | 9 | //! |
|
17 | 22 | //! | `chrono::NaiveDateTime` | datetime(tuple<s32, u8, u8, u8, u8, u8, u32>) | TIMESTAMP | |
18 | 23 | //! | `chrono::Duration` | timestamp(s64) | BIGINT | |
19 | 24 |
|
| 25 | +/// An open connection to a PostgreSQL database. |
| 26 | +/// |
| 27 | +/// # Examples |
| 28 | +/// |
| 29 | +/// Load a set of rows from a local PostgreSQL database, and iterate over them. |
| 30 | +/// |
| 31 | +/// ```no_run |
| 32 | +/// use spin_sdk::pg3::{Connection, Decode}; |
| 33 | +/// |
| 34 | +/// # fn main() -> anyhow::Result<()> { |
| 35 | +/// # let min_age = 0; |
| 36 | +/// let db = Connection::open("host=localhost user=postgres password=my_password dbname=mydb")?; |
| 37 | +/// |
| 38 | +/// let query_result = db.query( |
| 39 | +/// "SELECT * FROM users WHERE age >= $1", |
| 40 | +/// &[min_age.into()] |
| 41 | +/// )?; |
| 42 | +/// |
| 43 | +/// let name_index = query_result.columns.iter().position(|c| c.name == "name").unwrap(); |
| 44 | +/// |
| 45 | +/// for row in &query_result.rows { |
| 46 | +/// let name = String::decode(&row[name_index])?; |
| 47 | +/// println!("Found user {name}"); |
| 48 | +/// } |
| 49 | +/// # Ok(()) |
| 50 | +/// # } |
| 51 | +/// ``` |
| 52 | +/// |
| 53 | +/// Perform an aggregate (scalar) operation over a table. The result set |
| 54 | +/// contains a single column, with a single row. |
| 55 | +/// |
| 56 | +/// ```no_run |
| 57 | +/// use spin_sdk::pg3::{Connection, Decode}; |
| 58 | +/// |
| 59 | +/// # fn main() -> anyhow::Result<()> { |
| 60 | +/// let db = Connection::open("host=localhost user=postgres password=my_password dbname=mydb")?; |
| 61 | +/// |
| 62 | +/// let query_result = db.query("SELECT COUNT(*) FROM users", &[])?; |
| 63 | +/// |
| 64 | +/// assert_eq!(1, query_result.columns.len()); |
| 65 | +/// assert_eq!("count", query_result.columns[0].name); |
| 66 | +/// assert_eq!(1, query_result.rows.len()); |
| 67 | +/// |
| 68 | +/// let count = i64::decode(&query_result.rows[0][0])?; |
| 69 | +/// # Ok(()) |
| 70 | +/// # } |
| 71 | +/// ``` |
| 72 | +/// |
| 73 | +/// Delete rows from a PostgreSQL table. This uses [Connection::execute()] |
| 74 | +/// instead of the `query` method. |
| 75 | +/// |
| 76 | +/// ```no_run |
| 77 | +/// use spin_sdk::pg3::Connection; |
| 78 | +/// |
| 79 | +/// # fn main() -> anyhow::Result<()> { |
| 80 | +/// let db = Connection::open("host=localhost user=postgres password=my_password dbname=mydb")?; |
| 81 | +/// |
| 82 | +/// let rows_affected = db.execute( |
| 83 | +/// "DELETE FROM users WHERE name = $1", |
| 84 | +/// &["Baldrick".to_owned().into()] |
| 85 | +/// )?; |
| 86 | +/// # Ok(()) |
| 87 | +/// # } |
| 88 | +/// ``` |
| 89 | +#[doc(inline)] |
| 90 | +pub use super::wit::pg3::Connection; |
| 91 | + |
| 92 | +/// The result of a database query. |
| 93 | +/// |
| 94 | +/// # Examples |
| 95 | +/// |
| 96 | +/// Load a set of rows from a local PostgreSQL database, and iterate over them |
| 97 | +/// selecting one field from each. The columns collection allows you to find |
| 98 | +/// column indexes for column names; you can bypass this lookup if you name |
| 99 | +/// specific columns in the query. |
| 100 | +/// |
| 101 | +/// ```no_run |
| 102 | +/// use spin_sdk::pg3::{Connection, Decode}; |
| 103 | +/// |
| 104 | +/// # fn main() -> anyhow::Result<()> { |
| 105 | +/// # let min_age = 0; |
| 106 | +/// let db = Connection::open("host=localhost user=postgres password=my_password dbname=mydb")?; |
| 107 | +/// |
| 108 | +/// let query_result = db.query( |
| 109 | +/// "SELECT * FROM users WHERE age >= $1", |
| 110 | +/// &[min_age.into()] |
| 111 | +/// )?; |
| 112 | +/// |
| 113 | +/// let name_index = query_result.columns.iter().position(|c| c.name == "name").unwrap(); |
| 114 | +/// |
| 115 | +/// for row in &query_result.rows { |
| 116 | +/// let name = String::decode(&row[name_index])?; |
| 117 | +/// println!("Found user {name}"); |
| 118 | +/// } |
| 119 | +/// # Ok(()) |
| 120 | +/// # } |
| 121 | +/// ``` |
| 122 | +pub use super::wit::pg3::RowSet; |
| 123 | + |
20 | 124 | #[doc(inline)] |
21 | 125 | pub use super::wit::pg3::{Error as PgError, *}; |
22 | 126 |
|
23 | 127 | use chrono::{Datelike, Timelike}; |
24 | 128 |
|
25 | | -/// A pg error |
| 129 | +/// A Postgres error |
26 | 130 | #[derive(Debug, thiserror::Error)] |
27 | 131 | pub enum Error { |
28 | 132 | /// Failed to deserialize [`DbValue`] |
29 | 133 | #[error("error value decoding: {0}")] |
30 | 134 | Decode(String), |
31 | | - /// Pg query failed with an error |
| 135 | + /// Postgres query failed with an error |
32 | 136 | #[error(transparent)] |
33 | 137 | PgError(#[from] PgError), |
34 | 138 | } |
|
0 commit comments