天天看點

任意程式設計語言通路PostgreSQL:C++接口

今天将介紹如何使用C++通路PostgreSQL。

  官方PostgreSQL用戶端的C++接口API稱為libpqxx,但沒有與PostgreSQL源碼進行綁定,使用者可以從産品分發庫或單獨下載下傳進行安裝。README檔案提到使用者可以在Linux、BSD、Solaris、Irix、HP-UX、AIX和安裝Cygwin的Windows上使用libpqxx。安裝libpqxx前要先安裝libpq,因為前者是基于後者的。

  在C++中,namespace被命名為pqxx,使用者必須包含以該名稱命名的頭檔案。以下為一個簡單連接配接與查詢的例子:

#include <iostream>

#include <pqxx/pqxx>

using namespace std;

int main()

{

    pqxx::connection conn;

    pqxx::work w(conn);

    pqxx::result res = w.exec("SELECT 1");

    w.commit();

    cout << res[0][0].as<int>() << endl;

}

如果運作正确,則該程式會列印出“1”,可以使用try/catch關鍵字來處理連接配接中可能出現的錯誤。如果要像在C語言中那樣使用argv[x],可以像如下方法連接配接字元串:

pqxx::result res = w.exec("SELECT" + w.quote(argv[1]));

那麼,該如何對資料進行查詢與傳回呢?由于儲存資料的res變量是一個數組,是以可以利用循環來讀取res中的資料元素:

for (int rownr=0; rownr < res.size(); ++rownr)

    const result::tuple row = res[rownr];

    for (int colnr=0; colnr < row.size(); ++colnr)

    {

        const result::field = row[colnr];

        cout << field.c_str() << \t;

    }

    cout << endl;

要記得在寫代碼的時候加上using namespace std;,如果不加的話在編譯時會在使用cout與endl的行顯示警告。

  libpqxx在字元串轉換方面提供大量函數,最有意思的函數為from_string與to_string,第一個函數隻有一個字元串參數和一個 T& obj參數,T表示已存在的内置類型,第二個函數隻有一個T& obj變量,函數将其轉換為字元串。更多詳細内容可以閱讀相關文檔。

  連接配接,查詢與事務處理

  本節的其餘部分代碼,讀者最好使用using namespace pqxx;,因為可以在寫代碼時免去寫一些資料類型,省去一些不必要的麻煩,如可以不必寫pqxx::...。現在連接配接一個資料庫,執行一次事務處理,之後進行一次查詢,讀者會看到代碼與前文的C代碼不太一樣。

  可以使用隻包含一個參數的結構,如定義了連接配接選項(資料庫名、使用者名等)的字元串。由于預設使用者名為postgres,是以本例代碼沒有包含使用者名:

connection Conn("dbname=testdb1 hostaddr=192.168.0.101");

現在已經打開了一個連接配接,執行沒有出錯。不過到目前為止還不能進行查詢,還需要使用transactor來打開一個事務處理,這樣可以在連接配接突然斷開時省去一些麻煩與時間。transactor是一個functor,如果在建立連接配接時需要知道連接配接的狀态,則該運算符非常有效,而不能僅僅使用簡單的函數或函數指針。

  functor是一個函數對象,可以将其看成一個狀态查詢函數。例如在C++中操作符“()”可以被重載,是以可以将任意數量的資料元素放到括号中。也許有讀者會認為functor是定義操作符()的類,如果想要設計一個函數使兩個給定的作為參數的值相加,則必須要對這些值進行寫死。functor考慮到寫死的限制,允許使用者使用一個結構體,并将一個新對象“覆寫”要相加的第一個值,給開發者更多的靈活性。

  下面看如何使用transactor:

  // 假設已經打開一個連接配接

class Transaction : public transactor<>

public:

     void operator () (transaction<> & t)

     {

         t.exec ("INSERT INTO mytable VALUES(val1,val2)");

     }

     void on_abort (const string & msg)

         cout << "Transaction failed with message: " << msg << endl;

};

//在 main()函數中

conn.perform (Transaction());

通過本節内容可以看到,用C++代碼對資料庫進行查詢并不難,使用者可以通過定義事務處理(transactions)并适當規範化查詢結果(參考stringstream),其餘部分可以使用循環來實作。

本文轉自 wws5201985 51CTO部落格,原文連結:http://blog.51cto.com/wws5201985/804114,如需轉載請自行聯系原作者