Skip to content

Commit e52c46b

Browse files
authored
Merge branch 'master' into pg_textsearch
2 parents 9f2d127 + 621d996 commit e52c46b

10 files changed

Lines changed: 1236 additions & 0 deletions

File tree

CN/modules/ROOT/nav.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
*** xref:master/ecosystem_components/wal2json.adoc[wal2json]
5454
*** xref:master/ecosystem_components/pg_stat_monitor.adoc[pg_stat_monitor]
5555
*** xref:master/ecosystem_components/pg_ai_query.adoc[pg_ai_query]
56+
*** xref:master/ecosystem_components/pg_partman.adoc[pg_partman]
57+
*** xref:master/ecosystem_components/pgbouncer.adoc[pgbouncer]
58+
*** xref:master/ecosystem_components/pg_curl.adoc[pg_curl]
5659
*** xref:master/ecosystem_components/pg_textsearch.adoc[pg_textsearch]
5760
* 监控运维
5861
** xref:master/getting-started/daily_monitoring.adoc[日常监控]

CN/modules/ROOT/pages/master/ecosystem_components/ecosystem_overview.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ IvorySQL 作为一款兼容 Oracle 且基于 PostgreSQL 的高级开源数据库
2323
| 10 | xref:master/ecosystem_components/system_stats.adoc[system_stats] | 3.2 | 提供用于访问系统级统计信息的函数 | 系统监控
2424
| 11 | xref:master/ecosystem_components/pg_ai_query.adoc[pg_ai_query] | 0.1.1 | AI驱动的自然语言转SQL扩展,支持多种大语言模型 | AI辅助查询、自然语言数据库交互
2525
| 12 | xref:master/ecosystem_components/pg_stat_monitor.adoc[pg_stat_monitor] | 2.3.1 | 收集性能统计数据,并通过统一视图和直方图形式直观展示查询性能指标。 | 性能监控
26+
| 13 | xref:master/ecosystem_components/pg_partman.adoc[pg_partman] | 5.2 | 辅助管理原生分区表,自动创建、维护、清理分区子表 | 海量数据存储管理
27+
| 14 | xref:master/ecosystem_components/pg_curl.adoc[pg_curl] | 2.4 | 基于 libcurl 的网络传输扩展,支持 HTTP/HTTPS、FTP、SMTP、IMAP 等二十余种协议,可在 SQL 中完成各类网络数据传输操作 | REST API 集成、邮件发送、文件传输、外部系统通知
2628
|====
2729

2830
这些插件均经过 IvorySQL 团队的测试和适配,确保在 IvorySQL 环境下稳定运行。用户可以根据业务需求选择合适的插件,进一步提升数据库系统的能力和灵活性。
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
2+
:sectnums:
3+
:sectnumlevels: 5
4+
5+
= pg_curl
6+
7+
== 概述
8+
9+
pg_curl 是一个基于 libcurl 的 PostgreSQL 扩展,它将 cURL 的强大数据传输能力直接引入数据库内部,允许用户通过 SQL 函数调用完成各种网络协议的数据传输操作,无需借助外部程序或中间件。
10+
11+
与只支持 HTTP 的轻量级扩展不同,pg_curl 全面封装了 libcurl 的 easy interface API,支持 DICT、FILE、FTP、FTPS、GOPHER、HTTP、HTTPS、IMAP、IMAPS、LDAP、LDAPS、MQTT、POP3、POP3S、RTMP、RTMPS、RTSP、SCP、SFTP、SMB、SMBS、SMTP、SMTPS、TELNET、TFTP、WS 和 WSS 等二十余种协议,提供了极为丰富的网络交互能力。
12+
13+
典型应用场景包括:在触发器或存储过程中向外部系统发送 HTTP 通知;直接从数据库发送邮件;通过 FTP/SFTP 上传或下载文件;调用第三方 REST API 并将结果写回数据库表;以及在数据处理流程中与 MQTT 消息代理、LDAP 目录等各类后端服务进行集成。
14+
15+
pg_curl 采用 MIT 许可证,项目地址:https://github.com/RekGRpth/pg_curl 。
16+
17+
== 功能特点
18+
19+
* *多协议支持*:基于 libcurl,支持 HTTP/HTTPS、FTP/FTPS、SMTP/SMTPS、IMAP、POP3、SCP、SFTP、MQTT、LDAP 等二十余种协议,覆盖绝大多数网络集成场景。
20+
* *完整的 HTTP 方法支持*:支持 GET、POST(URL 编码、JSON、multipart/form-data)、PUT、DELETE、PATCH 等标准 HTTP 方法,并可通过 `curl_easy_setopt_customrequest` 指定任意自定义方法。
21+
* *灵活的请求构造*:提供细粒度的 `curl_easy_setopt_*` 系列函数,可精确控制请求头、认证信息、超时、代理、TLS 证书、Cookie 等各项参数。
22+
* *多种认证方式*:支持 Basic Auth(用户名/密码)、Bearer Token、NTLM、Digest、OAuth 等多种认证机制。
23+
* *文件传输*:支持通过 FTP/FTPS/SFTP/SCP 上传(`curl_easy_setopt_readdata`)和下载文件,上传数据以 `bytea` 类型直接传入。
24+
* *邮件发送*:通过 SMTP/SMTPS 直接在数据库内发送邮件,支持设置发件人、收件人、邮件头及 MIME 正文。
25+
* *响应解析*:提供 `curl_easy_getinfo_data_in()`、`curl_easy_getinfo_header_in()` 等函数获取响应体和响应头,并可通过正则表达式将头信息解析为键值表。
26+
* *错误处理*:`curl_easy_getinfo_errcode()`、`curl_easy_getinfo_errdesc()` 及 `curl_easy_getinfo_errbuf()` 提供完整的错误码和错误描述,便于调试。
27+
* *超时与中断*:通过向 libcurl 注册进度回调并周期性检查 PostgreSQL 的取消标志(`QueryCancelPending`),支持被 `statement_timeout`、`pg_cancel_backend()` 等方式中断,防止长时间请求阻塞连接。
28+
* *URL 编码工具*:内置 `curl_easy_escape()` 和 `curl_easy_unescape()` 函数,方便在 SQL 中进行 URL 编码和解码。
29+
30+
== 安装
31+
32+
[TIP]
33+
以下示例环境为 Ubuntu 24.04(x86_64),已安装 IvorySQL 5 及以上版本,安装路径为 `/usr/local/ivorysql/ivorysql-5`。
34+
35+
=== 安装依赖
36+
37+
pg_curl 依赖系统的 libcurl 开发库,安装前需确认已安装该依赖:
38+
39+
[source,shell]
40+
----
41+
sudo apt install libcurl4-openssl-dev
42+
----
43+
44+
=== 源码编译安装
45+
46+
从 https://github.com/RekGRpth/pg_curl 获取源码,然后执行编译安装:
47+
48+
[source,shell]
49+
----
50+
git clone https://github.com/RekGRpth/pg_curl.git
51+
cd pg_curl
52+
# 确保 pg_config 可访问,或通过 PG_CONFIG 显式指定
53+
PG_CONFIG=/usr/local/ivorysql/ivorysql-5/bin/pg_config make
54+
PG_CONFIG=/usr/local/ivorysql/ivorysql-5/bin/pg_config make install
55+
----
56+
57+
安装成功后,`pg_curl.so` 及对应的 SQL 脚本会被放置到 IvorySQL 的扩展目录中。
58+
59+
== 创建 Extension 并验证版本
60+
61+
使用 psql 连接到数据库(PG 模式端口 5432 或 Oracle 模式端口 1521 均可),执行如下命令:
62+
63+
[source,sql]
64+
----
65+
CREATE EXTENSION pg_curl;
66+
67+
SELECT name, default_version, installed_version, comment
68+
FROM pg_available_extensions
69+
WHERE name = 'pg_curl';
70+
----
71+
72+
预期输出类似:
73+
74+
[source,text]
75+
----
76+
name | default_version | installed_version | comment
77+
---------+-----------------+-------------------+----------------------------------------------------------------------------------------------------------------------------------------
78+
pg_curl | 2.4 | 2.4 | PostgreSQL cURL allows most curl actions, including data transfer with URL syntax via HTTP, HTTPS, FTP, FTPS, GOPHER, TFTP, SCP, ...
79+
(1 row)
80+
----
81+
82+
== 使用
83+
84+
pg_curl 采用"先配置、再执行、后取结果"的调用模式,核心流程如下:
85+
86+
. 调用 `curl_easy_reset()` 初始化(或重置)当前 cURL 会话。
87+
. 调用各 `curl_easy_setopt_*`、`curl_header_append`、`curl_postfield_append` 等函数配置请求参数。
88+
. 调用 `curl_easy_perform()` 执行请求。
89+
. 调用 `curl_easy_getinfo_*` 系列函数获取响应结果或错误信息。
90+
91+
=== HTTP GET
92+
93+
[source,sql]
94+
----
95+
BEGIN;
96+
SELECT curl_easy_reset();
97+
SELECT curl_easy_setopt_url('https://httpbin.org/get?');
98+
SELECT curl_url_append('key1', 'value1');
99+
SELECT curl_url_append('key2', 'hello world'); -- 自动 URL 编码
100+
SELECT curl_easy_perform();
101+
SELECT convert_from(curl_easy_getinfo_data_in(), 'utf-8');
102+
END;
103+
----
104+
105+
=== HTTP POST(JSON)
106+
107+
POST 表单(`curl_postfield_append`)和 multipart(`curl_mime_data`)的用法与此类似,替换数据设置函数即可。
108+
109+
[source,sql]
110+
----
111+
BEGIN;
112+
SELECT curl_easy_reset();
113+
SELECT curl_easy_setopt_postfields(convert_to('{"name":"IvorySQL"}', 'utf-8'));
114+
SELECT curl_easy_setopt_url('https://httpbin.org/post');
115+
SELECT curl_header_append('Content-Type', 'application/json; charset=utf-8');
116+
SELECT curl_easy_perform();
117+
SELECT convert_from(curl_easy_getinfo_data_in(), 'utf-8');
118+
END;
119+
----
120+
121+
=== 认证与请求头
122+
123+
Basic Auth 使用 `curl_easy_setopt_username` / `curl_easy_setopt_password`;Bearer Token 及其他自定义头均通过 `curl_header_append` 添加:
124+
125+
[source,sql]
126+
----
127+
BEGIN;
128+
SELECT curl_easy_reset();
129+
SELECT curl_easy_setopt_url('https://httpbin.org/bearer');
130+
SELECT curl_header_append('Authorization', 'Bearer <your_token>');
131+
SELECT curl_easy_perform();
132+
SELECT convert_from(curl_easy_getinfo_data_in(), 'utf-8')::jsonb;
133+
END;
134+
----
135+
136+
=== 错误处理与超时
137+
138+
`curl_easy_perform()` 成功返回后,可通过以下函数检查执行状态(`errcode` 为 0 表示成功):
139+
140+
[source,sql]
141+
----
142+
BEGIN;
143+
SELECT curl_easy_reset();
144+
SELECT curl_easy_setopt_url('https://httpbin.org/get');
145+
SELECT curl_easy_perform();
146+
SELECT
147+
curl_easy_getinfo_errcode() AS errcode,
148+
curl_easy_getinfo_errdesc() AS errdesc;
149+
END;
150+
----
151+
152+
pg_curl 通过 libcurl 进度回调检查 PostgreSQL 取消标志,`statement_timeout` 触发时请求会被立即中止并回滚当前事务:
153+
154+
[source,sql]
155+
----
156+
BEGIN;
157+
SET LOCAL statement_timeout = '3s';
158+
SELECT curl_easy_reset();
159+
SELECT curl_easy_setopt_url('https://httpbin.org/delay/10');
160+
SELECT curl_easy_perform(); -- 超时后抛出 query_canceled,事务回滚
161+
END;
162+
----
163+
164+
== IvorySQL 适配说明
165+
166+
=== 双端口兼容
167+
168+
IvorySQL 采用双端口架构,同时支持 PostgreSQL 模式(默认端口 *5432*)和 Oracle 兼容模式(默认端口 *1521*):
169+
170+
* 连接 *5432* 端口(PG 模式):接受标准 PostgreSQL SQL 语法。
171+
* 连接 *1521* 端口(Oracle 模式):接受 Oracle 兼容 SQL 语法。
172+
173+
pg_curl 在两种模式下均可正常使用,`CREATE EXTENSION pg_curl` 在 1521 和 5432 端口均能成功执行。
174+
175+
=== Oracle 模式注意事项
176+
177+
在 Oracle 模式(1521 端口)下使用 pg_curl 时,以下几点需要注意:
178+
179+
* pg_curl 的所有函数均通过普通 `SELECT` 语句调用(如 `SELECT curl_easy_reset()`),在 Oracle 模式下同样有效;也可以使用 Oracle 惯用的 `SELECT curl_easy_reset() FROM DUAL` 写法。
180+
* `ivorysql.enable_emptystring_to_NULL` 参数会影响空字符串的处理行为。回归测试中已设置 `SET ivorysql.enable_emptystring_to_NULL = 'off'` 以确保空值参数(如空表单字段)按预期传递,生产环境中需根据实际需求配置该参数。
181+
182+
=== 在 PL/iSQL 中使用
183+
184+
pg_curl 可在 IvorySQL 的 PL/iSQL(Oracle 兼容存储过程语言)中调用,实现数据变更时自动推送外部通知。PL/iSQL 使用 Oracle 风格的 `IS` 关键字声明存储过程,调用返回值的函数时通过赋值给局部变量来丢弃结果:
185+
186+
[source,sql]
187+
----
188+
-- 在 PL/iSQL 存储过程中调用 pg_curl(Oracle 模式,IS 语法)
189+
CREATE OR REPLACE PROCEDURE notify_external(p_payload IN VARCHAR2) IS
190+
v_ok BOOLEAN;
191+
BEGIN
192+
v_ok := curl_easy_reset();
193+
v_ok := curl_easy_setopt_postfields(convert_to(p_payload, 'utf-8'));
194+
v_ok := curl_easy_setopt_url('https://hooks.example.com/notify');
195+
v_ok := curl_header_append('Content-Type', 'application/json');
196+
v_ok := curl_easy_perform();
197+
END;
198+
----

0 commit comments

Comments
 (0)