Rust PostgreSQL扩展开发库pgrx-sql-entity-graph的使用,为PostgreSQL提供Rust语言绑定与实体映射功能
pgrx-sql-entity-graph
用于pgrx的SQL实体图生成。这个crate被各种pgrx crate内部使用。
元数据
- 版本: 0.16.0
- 发布时间: 15天前
- 版本: 2021 edition
- 许可证: MIT
- 大小: 74.1 KiB
安装
在项目目录中运行以下Cargo命令:
cargo add pgrx-sql-entity-graph
或者在Cargo.toml中添加以下行:
pgrx-sql-entity-graph = "0.16.0"
所有者
- Eric Ridge
- Jubilee
- PgCentral Foundation, Inc.
完整示例代码
以下是一个使用pgrx-sql-entity-graph开发PostgreSQL扩展的完整示例:
use pgrx::prelude::*;
use pgrx_sql_entity_graph::PostgresType;
// 定义一个PostgreSQL函数
#[pg_extern]
fn hello_pgrx(name: String) -> String {
format!("Hello, {}!", name)
}
// 定义一个复合类型
#[derive(PostgresType)]
struct Person {
name: String,
age: i32,
}
// 定义一个返回复合类型的函数
#[pg_extern]
fn create_person(name: String, age: i32) -> Person {
Person { name, age }
}
// 定义一个返回表的函数
#[pg_extern]
fn generate_series(start: i32, end: i32, step: i32) ->
TableIterator<'static, (name!(value, i32),)>
{
TableIterator::new((start..=end).step_by(step as usize).map(|i| (i,)))
}
// 定义扩展入口点
#[cfg(any(test, feature = "pg_test"))]
#[pg_schema]
mod tests {
use pgrx::prelude::*;
#[pg_test]
fn test_hello_pgrx() {
assert_eq!("Hello, pgrx!", crate::hello_pgrx("pgrx".into()));
}
}
#[allow(dead_code)]
#[cfg(not(target_os = "windows"))]
#[cfg(any(test, feature = "pg_test"))]
#[pg_schema]
mod pg_test {
pub fn setup(_options: Vec<&str>) {
// 执行一次性测试设置
}
pub fn postgresql_conf_options() -> Vec<&'static str> {
// 返回要在测试期间设置的Postgres配置选项
vec![]
}
}
这个示例展示了:
- 定义基本的PostgreSQL函数
- 定义和使用复合类型
- 定义返回表的函数
- 包含测试模块
- 支持测试配置
要使用这个扩展,你需要配置Cargo.toml添加pgrx和pgrx-sql-entity-graph作为依赖项。
1 回复
pgrx-sql-entity-graph: Rust PostgreSQL扩展开发库
概述
pgrx-sql-entity-graph 是一个用于开发 PostgreSQL 扩展的 Rust 库,它为 PostgreSQL 提供了 Rust 语言绑定和实体映射功能。这个库是 pgrx 生态系统的一部分,旨在简化使用 Rust 编写 PostgreSQL 扩展的过程。
主要功能
- 提供 Rust 与 PostgreSQL 之间的类型映射
- 简化实体关系映射 (ORM-like 功能)
- 支持 PostgreSQL 扩展开发
- 自动生成 SQL 定义
安装与配置
首先,确保你已经安装了 pgrx 工具链:
cargo install --locked cargo-pgrx
cargo pgrx init
然后在你的 Cargo.toml 中添加依赖:
[dependencies]
pgrx = "0.7"
pgrx-sql-entity-graph = "0.7"
基本使用方法
1. 定义实体
use pgrx::prelude::*;
use pgrx_sql_entity_graph::PostgresType;
#[derive(PostgresType)]
pub struct Person {
name: String,
age: i32,
email: Option<String>,
}
2. 实现 PostgreSQL 函数
use pgrx::prelude::*;
#[pg_extern]
fn create_person(name: String, age: i32) -> Person {
Person {
name,
age,
email: None,
}
}
#[pg_extern]
fn get_person_age(person: Person) -> i32 {
person.age
}
3. 使用实体关系映射
use pgrx::prelude::*;
use pgrx_sql_entity_graph::{PostgresType, PostgresEnum};
#[derive(PostgresEnum)]
pub enum Gender {
Male,
Female,
Other,
}
#[derive(PostgresType)]
pub struct Employee {
person: Person,
gender: Gender,
salary: f64,
}
高级功能示例
自定义类型转换
use pgrx::prelude::*;
use pgrx_sql_entity_graph::PostgresType;
#[derive(PostgresType)]
#[pgvarlena_inoutfuncs]
pub struct ComplexNumber {
real: f64,
imaginary: f64,
}
impl ComplexNumber {
#[pg_extern]
pub fn new(real: f64, imaginary: f64) -> Self {
Self { real, imaginary }
}
#[pg_extern]
pub fn add(&self, other: &ComplexNumber) -> ComplexNumber {
ComplexNumber {
real: self.real + other.real,
imaginary: self.imaginary + other.imaginary,
}
}
}
生成表定义
use pgrx::prelude::*;
use pgrx_sql_entity_graph::{PostgresType, PgCatalog};
#[derive(PostgresType, PgCatalog)]
pub struct Product {
id: i64,
name: String,
price: f64,
in_stock: bool,
}
#[pg_extern]
fn get_expensive_products(price_threshold: f64) -> Vec<Product> {
// 这里实现从数据库获取高价产品的逻辑
vec![]
}
完整示例代码
以下是一个完整的 PostgreSQL 扩展示例,实现了一个简单的用户管理系统:
use pgrx::prelude::*;
use pgrx_sql_entity_graph::{PostgresType, PostgresEnum, PgCatalog};
use serde::{Serialize, Deserialize};
// 定义用户角色枚举
#[derive(PostgresEnum, Serialize, Deserialize)]
pub enum UserRole {
Guest,
User,
Admin,
}
// 定义用户实体
#[derive(PostgresType, PgCatalog, Serialize, Deserialize)]
pub struct User {
id: i64, // 用户ID
username: String, // 用户名
password_hash: String, // 密码哈希
email: Option<String>, // 可选邮箱
role: UserRole, // 用户角色
created_at: Timestamp, // 创建时间
last_login: Option<Timestamp>, // 最后登录时间
}
// 用户管理功能实现
#[pg_extern]
fn create_user(
username: String,
password: String,
email: Option<String>,
role: UserRole
) -> User {
// 在实际应用中应该对密码进行哈希处理
let password_hash = format!("hashed_{}", password);
User {
id: nextval("user_id_seq"), // 使用序列生成ID
username,
password_hash,
email,
role,
created_at: Timestamp::now(),
last_login: None,
}
}
#[pg_extern]
fn update_user_role(user_id: i64, new_role: UserRole) -> Result<User, String> {
// 实际应用中这里会查询并更新数据库中的用户
// 这里简化实现返回一个模拟用户
Ok(User {
id: user_id,
username: "updated_user".into(),
password_hash: "hashed_password".into(),
email: Some("updated@example.com".into()),
role: new_role,
created_at: Timestamp::now(),
last_login: Some(Timestamp::now()),
})
}
#[pg_extern]
fn get_users_by_role(role: UserRole) -> Vec<User> {
// 实际应用中这里会查询数据库
// 这里返回模拟数据
vec![
User {
id: 1,
username: "admin_user".into(),
password_hash: "hashed_admin".into(),
email: Some("admin@example.com".into()),
role: UserRole::Admin,
created_at: Timestamp::now(),
last_login: Some(Timestamp::now()),
},
User {
id: 2,
username: "regular_user".into(),
password_hash: "hashed_regular".into(),
email: Some("user@example.com".into()),
role: UserRole::User,
created_at: Timestamp::now(),
last_login: Some(Timestamp::now()),
}
]
.into_iter()
.filter(|user| user.role == role)
.collect()
}
// 扩展入口点
#[pg_module]
pub mod user_management {
pub fn setup() {
// 模块初始化代码
}
}
注意事项
- 确保你的 Rust 类型与 PostgreSQL 类型兼容
- 复杂类型需要实现适当的转换 trait
- 在开发过程中使用
cargo pgrx run
测试你的扩展 - 生产环境部署前进行充分的测试
pgrx-sql-entity-graph 为 Rust 开发者提供了强大的工具来构建高性能的 PostgreSQL 扩展,同时保持类型安全和代码可维护性。