| PostgreSQL 7.4 文檔 | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Fast Forward | Next | |
libpq 是PostgreSQL的 C 應用程序接口。 libpq 是一套允許客戶程序向 PostgreSQL 服務器服務進程發送查詢 並且獲得查詢返回的庫函數. libpq 同時也是其他幾個 PostgreSQL 應用接口下面的引擎, 包括 libpq++ (C++), libpgtcl(Tcl),Perl,和 ECPG.所以如果你使用這些軟件包,libpq某些方面的特性會對你非常重要.
本章末尾有三個小程序顯示如何利用 libpq 書寫程序。 (Section 27.14) 在源代碼發布的 src/test/examples 目錄裡面有幾個完整的 libpq 應用的例子。
使用 libpq 的前端程序必須包括頭文件 libpq-fe.h 並且必須與 libpq 庫鏈接。
下面的函數處理與 PostgreSQL 服務器服務器聯接的事情。 一個應用程序一次可以與多個服務器建立聯接。(這麼做的原因之一是訪問多于一個數據庫。) 每個連接都是用一個從函數PQconnectdb()或 PQsetdbLogin() 獲得的PGconn 對象表示。 注意,這些函數總是返回一個非空的對象指針,除非存儲器少得連個PGconn對象都分配不出來。 在把查詢發送給聯接對象之前,可以調用PQstatus函數來檢查一下聯接是否成功.
與服務器數據庫服務器建立一個新的聯接.
PGconn *PQconnectdb(const char *conninfo);
這個函數用從一個字符串 conninfo來的參數與數據庫打開一個新的聯接。 與下面的PQsetdbLogin()不同的是, 我們可以不必更換函數簽名(名字)就可以擴展參數集, 所以我們建議應用程序中使用這個函數(或者是它的類似的非阻塞的變種 PQconnectStart 和 PQconnectPoll)。
傳入的參數可以為空,表明使用所有缺省的參數, 或者可以包含一個或更多個用空白間隔的參數設置。 每個參數以 關鍵字 = 數值的形式設置。 (要寫一個空值或者一個包含空白的值,你可以用一對單引號包圍它們,例如, keyword = 'a value' 。數值內部的單引號和反斜扛必須用一個反斜扛逃逸, 比如, \'或\\。)等號週圍的空白是可選的。
目前可識別的參數鍵字是:
要聯接的主機名。 如果主機名以斜扛開頭,則它聲明使用 Unix 域套接字通訊而不是 TCP/IP 通訊; 該值就是套接字文件所存儲的目錄。 缺省時是與位于 /tmp 裡面的 Unix-域套接字聯接。
與之聯接的主機的 IP 地址。這個應該是標準的IPv4 地址格式, 比如,172.28.40.9。如果你的機器支持 IPv6, 那麼你也可以使用 IPv6 的地址。如果聲明了一個非空的字符串,那麼使用 TCP/IP 通訊機制。
使用hostaddr取代host可以讓應用避免一次主機名查找, 這一點對于那些有時間約束的應用來說可能是非常重要的。 不過,Kerberos 認證系統要求主機(host)名。因此,應用下面的規則: 如果聲明了不帶hostaddr的host那麼就強制進行主機名查找。 如果聲明中沒有host,hostaddr 的值給出遠端的地址; 如果使用了 Kerberos, 將導致一次反向名字查詢。如果同時聲明了 host 和hostaddr, 除非使用了 Kerberos,否則將使用hostaddr的值作為遠端地址; host 的值將被忽略,如果使用了 Kerberos,host 的值用于 Kerberos 認證。 (要注意如果傳遞給libpq的主機名(host) 不是地址hostaddr處的機器名,那麼認證很有可能失敗。) 同樣,在 $HOME/.pgpass 中是使用 host 而不是 hostaddr 來標識連接。
如果主機名(host)和主機地址都沒有, 那麼libpq將使用一個本地的 Unix 域套接字進行通訊。
數據庫名。缺省和用戶名相同。
要聯接的 PostgreSQL 用戶名。
如果服務器要求口令認證,所用的口令。
連接的最大等待時間,以秒計(用十進制整數字串書寫)。 零或者不聲明表示無窮。我們不建議把連接超時的值設置得小于 2 秒。
發送給服務器的命令行選項。
忽略(以前,這個選項聲明服務器日志的輸出方向)。
這個選項決定是否需要和服務器協商一個 SSL 連接, 以及以什麼樣的優先級與服務器進行 SSL 連接。 有四種模式可供選擇:disable 將只進行一個沒有加密的非 SSL 連接; allow 將和服務器進行協商,首先嘗試一個非 SSL 連接, 如果失敗,嘗試一個 SSL 連接;prefer (缺省) 將進行協商, 首先嘗試 SSL 連接,如果失敗,嘗試一個正常的非 SSL 連接; require 將只進行 SSL 連接。
如果 PostgreSQL 編譯時沒有打開 SSL 支持,那麼使用 require 將導致一個錯誤, 而 libpq 將容忍 allow 和 prefer,但是它無法協商一個 SSL 連接。
這個選項因為有了 sslmode 設置之後已經廢棄了。
如果設為 1 ,則要求與服務器進行SSL聯接(等效于 sslmode require)。 如果服務器不支持SSL,那麼libpq將馬上拒絕聯接。 設置為 0 (缺省)與服務器進行協商連接類型(等效于 sslmode prefer)。 這個選項只有在編譯 PostgreSQL 時打開了 SSL 支持才有效。
用于額外參數的服務名。它在pg_service.conf裡面聲明一個服務名, 這個配置文件保存額外的連接參數。這樣就允許應用應用只聲明一個服務名, 而連接參數就可以在一個地方維護了。參閱 PREFIX/share/pg_service.conf.sample 獲取如何設置這個文件的信息。
如果有任何沒有聲明的參數,那麼將檢查對應的環境變量(參閱Section 27.10 小節)。 如果環境變量也沒有設置,那麼使用編譯時的內置缺省。
與服務器數據庫服務器建立一個新的聯接。
PGconn *PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd);
這個函數是 PQconnectdb 前身, 它有固定個數的參數。它有相同的功能,只是在調用中那些它缺少的參數總是用缺省值。 如果麼給任意的固定參數設置缺省值,那麼寫一個 NULL 或者一個空字串給它們。
與服務器數據庫服務器建立一個新的聯接。
PGconn *PQsetdb(char *pghost, char *pgport, char *pgoptions, char *pgtty, char *dbName);
這是一個調用 PQsetdbLogin() 的宏,只是login和pwd參數用空(null )代替。 提供這個函數是為了與非常老版本的程序兼容。
PGconn *PQconnectStart(const char *conninfo);
PostgreSQLPollingStatusType PQconnectPoll(PGconn *conn);
這兩個函數用于打開一個與數據庫服務器之間的非阻塞的聯接: 你的應用的執行線索在執行它的時候不會因遠端的 I/O 而阻塞。 這個方法的要點是等待 I/O 結束可以發生在應用的主循環裡, 而不是在 PQconnectdb 裡,這樣應用可以把這件事與其它操作並發起來一起執行。
數據庫聯接是用從 conninfo 字符串裡取得的參數傳遞給 PQconnectStart 進行的。 這個字符串的格式與上面PQconnectdb裡描述的一樣。
PQconnectStart 和PQconnectPoll 都不會阻塞(進程),不過有一些條件:
必須正確提供hostaddr和host 參數以確保不會發生正向或者反向的名字查找。 參閱上面PQconnectdb裡的這些參數的文檔獲取細節。
如果你調用了PQtrace, 確保你跟蹤進入的流對象不會阻塞。
你必須在調用PQconnectPoll之前確保 socket 處于正確的狀態,象下面描述的那樣。
要開始一次非阻塞連接請求,調用 conn=PQconnectStart("connection_info_string")。 如果conn是空,表明libpq無法分配一個新的PGconn結構。 否則,返回一個有效的PGconn指針(盡管還不一定代表一個與數據庫有效聯接)。 PQconnectStart 一返回,調用status=PQstatus(conn)。 如果status等于CONNECTION_BAD,PQconnectStart 失敗。
如果PQconnectStart成功了,下一個階段是輪詢 libpq, 這樣它就可以繼續連接序列動作。使用 PQsocket(conn) 獲取數據庫鏈接下層的套接字描述符。 象這樣循環:如果PQconnectPoll(conn)的最後一個返回是PGRES_POLLING_READING, 那麼就等到套接字準備好被讀取了的時候(就像系統函數 select(),poll(),或者類似的系統調用聲明的那樣)。 然後再次調用 PQconnectPoll(conn)。 同樣,如果 PQconnectPoll(conn) 最後返回 PGRES_POLLING_WRITING, 那麼就等到套接字準備好可以寫了,然後再次調用 PQconnectPoll(conn)。 如果你還沒調用 PQconnectPoll,比如,剛剛調用完 PQconnectStart, 那麼按照它剛返回 PGRES_POLLING_WRITING 的原則行動。 繼續這個循環直到 PQconnectPoll(conn) 返回 PGRES_POLLING_FAILED, 表明連接失敗,或者 PGRES_POLLING_OK,表明連接成功建立。
在聯接的任意時刻,我們都可以通過調用PQstatus 來檢查聯接的狀態。 如果這是CONNECTION_BAD, 那麼聯接過程失敗;如果是CONNECTION_OK, 那麼聯接已經做好。 這兩種狀態同樣也可以從上面的PQconnectPoll 的返回值裡檢測到。 其他狀態可能(也只能)在一次異步聯接過程中發生。 這些標識聯接過程的當前狀態,因而可能對給用戶提供反饋有幫助。這些狀態可能包括:
等待進行聯接。
聯接成功;等待發送。
等待來自服務器的響應。
已收到認證;等待聯接啟動繼續進行。
協商 SSL 加密。
協商環境驅動的參數設置。
注意,盡管這些常量將保持下去(為了維持兼容性), 應用決不應該依賴于這些常量以某種特定順序出現, 或者是根本不應依賴于這些常量, 或者是不應該依賴于這些狀態總是某個文檔聲明的值。 一個應用可能象象下面這樣:
switch(PQstatus(conn))
{
case CONNECTION_STARTED:
feedback = "正在連接...";
break;
case CONNECTION_MADE:
feedback = "與服務器連接已建立...";
break;
.
.
.
default:
feedback = "正在連接...";
}
在使用 PQconnectPoll 的時候,連接參數 connect_timeout 將被忽略;判斷是否超時是應用的責任。否則,後面跟著一個 PQconnectPoll 循環的 PQconnectStart 等效于 PQconnectdb。
要注意如果PQconnectStart返回一個非空的指針, 你必須在使用完它(指針)之後調用PQfinish, 以處理那些結構和所有相關的存儲塊。 甚至調用PQconnectStart或者 PQconnectPoll失敗時也要這樣處理。
返回缺省的聯接選項。
PQconninfoOption *PQconndefaults(void);
typedef struct PQconninfoOption
{
char *keyword; /* 選項的鍵字 */
char *envvar; /* 退守的環境變量名 */
char *compiled; /* 退守的編譯時缺省值 */
char *val; /* 選項的當前值,或者 NULL */
char *label; /* 連接對話裡字段的標識 */
char *dispchar; /* 在連接對話裡為此字段顯示的字符。
數值有:
"" 原樣現實輸入的數值
"*" 口令字段 - 隱藏數值
"D" 調試選項 - 缺省的時候不顯示 */
int dispsize; /* 對話中字段的以字符計的大小 */
}PQconninfoOption;
返回一個連接選項數組。 可以用于獲取所有可能的PQconnectdb選項和它們的當前缺省值。 返回值指向一個PQconninfoOption 結構的數組, 該數組以一個有 NULL keyword 指針的條目結束。注意缺省值(val 域)將依賴于環境變量和其他環境。 調用者必須把連接選項當作只讀對待。
在處理完選項數組後,把數組交給PQconninfoFree()釋放。 如果沒有這麼做,每次調用PQconndefaults()都會有一小部分內存洩漏。
關閉與服務器的連接。同時釋放被PGconn 對象使用的存儲器。
void PQfinish(PGconn *conn);
注意,即使與服務器的連接嘗試失敗(可由PQstatus判斷), 應用也要調用PQfinish釋放被PGconn對象使用的存儲器。 不應該在調用PQfinish後再使用PGconn 指針。
重置與服務器的通訊端口。
void PQreset(PGconn *conn);
此函數將關閉與服務器的連接並且試圖與同一個服務器重建新的連接, 使用所有前面使用過的參數。這在失去工作連接後進行故障恢復時很有用。
以非阻塞模式重置與服務器的通訊端口。
int PQresetStart(PGconn *conn);
PostgreSQLPollingStatusType PQresetPoll(PGconn *conn);
此函數將關閉與服務器的連接並且試圖與同一個服務器重建新的連接, 使用所有前面使用過的參數。這在失去工作連接後進行故障恢復時很有用。 它們和上面的PQreset的區別是它們工作在非阻塞模式。 這些函數的使用有與上面PQconnectStart和 PQconnectPoll一樣的限制。
要發起一次連接重置,調用PQresetStart。如果它返回 0,那麼重置失敗。 如果返回 1,用與使用PQconnectPoll 建立連接的同樣的方法使用PQresetPoll重置連接。