Skip to content

Commit 70e833a

Browse files
committed
feat(spin_sdk::pg): Improve pg type's conversion in Rust SDK
- Add conversion support for: int16, int32, int64, floating32, floating64, binary, boolean; - Add support for nullable variants; - Introduce spin_sdk::pg::Error; Signed-off-by: Konstantin Shabanov <[email protected]>
1 parent a4c5b54 commit 70e833a

File tree

15 files changed

+579
-84
lines changed

15 files changed

+579
-84
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/outbound-pg/src/lib.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,7 @@ fn convert_data_type(pg_type: &Type) -> DbDataType {
139139
Type::INT2 => DbDataType::Int16,
140140
Type::INT4 => DbDataType::Int32,
141141
Type::INT8 => DbDataType::Int64,
142-
Type::TEXT => DbDataType::Str,
143-
Type::VARCHAR => DbDataType::Str,
142+
Type::TEXT | Type::VARCHAR | Type::BPCHAR => DbDataType::Str,
144143
_ => {
145144
tracing::debug!("Couldn't convert Postgres type {} to WIT", pg_type.name(),);
146145
DbDataType::Other
@@ -208,17 +207,10 @@ fn convert_entry(row: &Row, index: usize) -> Result<DbValue, tokio_postgres::Err
208207
None => DbValue::DbNull,
209208
}
210209
}
211-
&Type::TEXT => {
212-
let value: Option<&str> = row.try_get(index)?;
210+
&Type::TEXT | &Type::VARCHAR | &Type::BPCHAR => {
211+
let value: Option<String> = row.try_get(index)?;
213212
match value {
214-
Some(v) => DbValue::Str(v.to_owned()),
215-
None => DbValue::DbNull,
216-
}
217-
}
218-
&Type::VARCHAR => {
219-
let value: Option<&str> = row.try_get(index)?;
220-
match value {
221-
Some(v) => DbValue::Str(v.to_owned()),
213+
Some(v) => DbValue::Str(v),
222214
None => DbValue::DbNull,
223215
}
224216
}

examples/config-rust/Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/http-rust-outbound-http/Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/http-rust/Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/redis-rust/Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/rust-outbound-pg/Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/rust-outbound-pg/db/testdata.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ CREATE TABLE articletest (
22
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
33
title varchar(40) NOT NULL,
44
content text NOT NULL,
5-
authorname varchar(40) NOT NULL
5+
authorname varchar(40) NOT NULL,
6+
coauthor text
67
);
78

89
INSERT INTO articletest (title, content, authorname) VALUES

examples/rust-outbound-pg/src/lib.rs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#![allow(dead_code)]
2-
use anyhow::{anyhow, Result};
2+
use anyhow::Result;
33
use spin_sdk::{
44
http::{Request, Response},
55
http_component,
6-
pg,
6+
pg::{self, Decode},
77
};
88

99
// The environment variable set in `spin.toml` that points to the
@@ -16,22 +16,25 @@ struct Article {
1616
title: String,
1717
content: String,
1818
authorname: String,
19+
coauthor: Option<String>,
1920
}
2021

2122
impl TryFrom<&pg::Row> for Article {
2223
type Error = anyhow::Error;
2324

2425
fn try_from(row: &pg::Row) -> Result<Self, Self::Error> {
25-
let id: i32 = (&row[0]).try_into()?;
26-
let title: String = (&row[1]).try_into()?;
27-
let content: String = (&row[2]).try_into()?;
28-
let authorname: String = (&row[3]).try_into()?;
26+
let id = i32::decode(&row[0])?;
27+
let title = String::decode(&row[1])?;
28+
let content = String::decode(&row[2])?;
29+
let authorname = String::decode(&row[3])?;
30+
let coauthor = Option::<String>::decode(&row[4])?;
2931

3032
Ok(Self {
3133
id,
3234
title,
3335
content,
3436
authorname,
37+
coauthor,
3538
})
3639
}
3740
}
@@ -51,9 +54,8 @@ fn process(req: Request) -> Result<Response> {
5154
fn read(_req: Request) -> Result<Response> {
5255
let address = std::env::var(DB_URL_ENV)?;
5356

54-
let sql = "SELECT id, title, content, authorname FROM articletest";
55-
let rowset = pg::query(&address, sql, &[])
56-
.map_err(|e| anyhow!("Error executing Postgres query: {:?}", e))?;
57+
let sql = "SELECT id, title, content, authorname, coauthor FROM articletest";
58+
let rowset = pg::query(&address, sql, &[])?;
5759

5860
let column_summary = rowset
5961
.columns
@@ -89,16 +91,14 @@ fn write(_req: Request) -> Result<Response> {
8991
let address = std::env::var(DB_URL_ENV)?;
9092

9193
let sql = "INSERT INTO articletest (title, content, authorname) VALUES ('aaa', 'bbb', 'ccc')";
92-
let nrow_executed =
93-
pg::execute(&address, sql, &[]).map_err(|_| anyhow!("Error execute pg command"))?;
94+
let nrow_executed = pg::execute(&address, sql, &[])?;
9495

9596
println!("nrow_executed: {}", nrow_executed);
9697

9798
let sql = "SELECT COUNT(id) FROM articletest";
98-
let rowset = pg::query(&address, sql, &[])
99-
.map_err(|e| anyhow!("Error executing Postgres query: {:?}", e))?;
99+
let rowset = pg::query(&address, sql, &[])?;
100100
let row = &rowset.rows[0];
101-
let count: i64 = (&row[0]).try_into()?;
101+
let count = i64::decode(&row[0])?;
102102
let response = format!("Count: {}\n", count);
103103

104104
Ok(http::Response::builder()
@@ -111,12 +111,10 @@ fn pg_backend_pid(_req: Request) -> Result<Response> {
111111
let sql = "SELECT pg_backend_pid()";
112112

113113
let get_pid = || {
114-
let rowset = pg::query(&address, sql, &[])
115-
.map_err(|e| anyhow!("Error executing Postgres query: {:?}", e))?;
116-
114+
let rowset = pg::query(&address, sql, &[])?;
117115
let row = &rowset.rows[0];
118116

119-
i32::try_from(&row[0])
117+
i32::decode(&row[0])
120118
};
121119

122120
assert_eq!(get_pid()?, get_pid()?);

examples/rust-outbound-redis/Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/rust/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ bytes = "1"
1313
form_urlencoded = "1.0"
1414
http = "0.2"
1515
spin-macro = { path = "macro" }
16+
thiserror = "1.0.37"
1617
wit-bindgen-rust = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "cb871cfa1ee460b51eb1d144b175b9aab9c50aba" }

0 commit comments

Comments
 (0)