我總是對新的程式語言及其框架感到好奇。一直以來,我的經驗和好奇心都只集中在前端開發(不過我也做過一些後端開發?)。我挑戰自己以擴展我的技能,並找到了 D 程式語言。 D簡單來說就是C和CPP的進階版。
D是什麼?網站稱「**D 是一種通用程式語言,具有靜態類型、系統級存取和類似C 的語法。使用D 程式語言,快速寫入、快速讀取和快速運行。 我使用 PostgreSQL 作為我作品的資料庫,這也是我為這個函式庫選擇它的原因。 PostgreSQL 是該公司現在使用的主要開源 SQL 資料庫系統之一,其功能正在不斷擴展。
為什麼要建立自訂 ORM 庫?
在搞D語言的時候找不到一個能滿足我需求的包,要嘛是停止維護了,要嘛是可以直接查詢。我有 JavaScript 背景,使用 Sequalize ORM。這讓我想到了一個主意,D 中類似的怎麼樣。
所以,我做了一些研究,發現 Postgres 為 C 提供了函式庫。然後我想,如何在 D 中使用 C 綁定並使用它來開發 ORM。 我從 https://github.com/adamdruppe/arsd/blob/master/postgres.d 找到了用於將 C 程式庫綁定到 D 的原始程式碼。
入門
要求:
您的系統中必須安裝 PostgreSQL。 (
- 我為 PostgreSQL 16 開發)
- IDE(Zed/ VSCode/Vim)
- DMD - d 語言編譯器
- 要建立新項目,請在終端機中使用以下命令:
開啟終端機或命令提示字元。
- 導航到您要建立專案的目錄。
- 運行指令:
dub init <project_name> </project_name>
- 系統將提示您輸入以下資訊:
- 格式 - .sdl 或 .json(我選了 json )
- 項目描述(可選)
- 作者姓名
- 許可證(例如 MIT、BSD 等)
- 版權字串
- 新增相依性(可選)
- 提供資訊後,dub 將以您的專案名稱建立一個新目錄並產生以下檔案:
- dub.json:專案的設定檔
- source/app.d:主要來源檔案
- .gitignore:Git 忽略檔案
- 導航到新專案目錄:cd
; - 您現在可以開始開發您的 D 專案了!
完成這些步驟後,您將建立一個基本的 D 專案結構並準備好進行開發。
在 Windows 中,需要將以下部分加入 dub.json。
dub init <project_name> </project_name>
或
我的方法是將所有必需的 DLL 檔案複製到 lib(手動建立)資料夾,然後新增以下程式碼:
"libs": [ "pq" ], "lflags-windows-x86_64": [ "-LIBPATH:C:/Program Files/PostgreSQL/16/lib/" ], "copyFiles-windows-x86_64": [ "C:/Program Files/PostgreSQL/16/lib/libpq.dll", "C:/Program Files/PostgreSQL/16/bin/libintl-9.dll", "C:/Program Files/PostgreSQL/16/bin/libssl-3-x64.dll", "C:/Program Files/PostgreSQL/16/bin/libcrypto-3-x64.dll", "C:/Program Files/PostgreSQL/16/bin/libwinpthread-1.dll", "C:/Program Files/PostgreSQL/16/bin/libiconv-2.dll" ],
在 Linux 或 macOS 中,您需要確保 PostgreSQL 開發庫已安裝並正確連結。通常,您可以透過系統的套件管理器安裝適當的套件來完成此操作。例如,在基於 Ubuntu 或 Debian 的系統上,您可以使用:
"copyFiles-windows": [ "libs/*.dll" ], "lflags-windows": [ "/LIBPATH:$PACKAGE_DIR/libs" ], "libs": [ "pq" ]
安裝並正確連結必要的程式庫後,您可以繼續設定 D 專案以使用 PostgreSQL。
實作 C 綁定:
這是 D 的 C 綁定。
sudo apt-get install libpq-dev
現在我們可以在D中輕鬆使用這些函數了。
這是一些基本異常處理的程式碼:
module postgres.implementation.implementationc; extern (C) { struct PGconn { } struct PGresult { } void PQfinish(PGconn*); PGconn* PQconnectdb(const char*); int PQstatus(PGconn*); // FIXME check return value const(char*) PQerrorMessage(PGconn*); char* PQresultVerboseErrorMessage(const PGresult* res, PGVerbosity verbosity, PGContextVisibility show_context); PGresult* PQexec(PGconn*, const char*); void PQclear(PGresult*); PGresult* PQprepare(PGconn*, const char* stmtName, const char* query, ulong nParams, const void* paramTypes); PGresult* PQexecPrepared(PGconn*, const char* stmtName, int nParams, const char** paramValues, const int* paramLengths, const int* paramFormats, int resultFormat); int PQresultStatus(PGresult*); // FIXME check return value int PQnfields(PGresult*); // number of fields in a result const(char*) PQfname(PGresult*, int); // name of field int PQntuples(PGresult*); // number of rows in result const(char*) PQgetvalue(PGresult*, int row, int column); size_t PQescapeString(char* to, const char* from, size_t length); enum int CONNECTION_OK = 0; enum int PGRES_COMMAND_OK = 1; enum int PGRES_TUPLES_OK = 2; enum int PGRES_FATAL_ERROR = 7; enum PGContextVisibility { PQSHOW_CONTEXT_NEVER, PQSHOW_CONTEXT_ERRORS, PQSHOW_CONTEXT_ALWAYS } enum PGVerbosity { PQERRORS_TERSE, PQERRORS_DEFAULT, PQERRORS_VERBOSE, PQERRORS_SQLSTATE } int PQgetlength(const PGresult* res, int row_number, int column_number); int PQgetisnull(const PGresult* res, int row_number, int column_number); int PQfformat(const PGresult* res, int column_number); alias Oid = int; enum BYTEAOID = 17; Oid PQftype(const PGresult* res, int column_number); char* PQescapeByteaConn(PGconn* conn, const ubyte* from, size_t from_length, size_t* to_length); char* PQunescapeBytea(const char* from, size_t* to_length); void PQfreemem(void* ptr); char* PQcmdTuples(PGresult* res); }
- PGSqlException: 繼承自標準 D Exception 類別的自訂異常類別。它旨在處理 PostgreSQL 特定的錯誤。
-
欄位:
- code:儲存錯誤代碼
- sqlState:儲存 SQL 狀態
- message:儲存錯誤訊息
- 建構子: 採用 PGconn* (PostgreSQL 連線)和可選的 PGresult* (查詢結果)。 PQresultVerboseErrorMessage 和 PQerrorMessage 用於提取詳細的錯誤訊息。
- DuplicateKeyException: 一個用來處理重複鍵錯誤的簡單異常類別。它只接受一個訊息參數並將其傳遞給 Exception 基底類別。
當我從事這個專案時,我將添加更多例外和其他情況
現在建立一個implementation/core/core.d 檔案用來編寫連接程式碼。
module postgres.implementation.exception; public: import std.conv; private import postgres.implementation.implementationc; class PGSqlException : Exception { string code; string sqlState; string message; this(PGconn* conn, PGresult* res = null) { if (res != null) { char* c = PQresultVerboseErrorMessage(res, PGVerbosity.PQERRORS_VERBOSE, PGContextVisibility .PQSHOW_CONTEXT_ALWAYS); char* s = PQresultVerboseErrorMessage(res, PGVerbosity.PQERRORS_SQLSTATE, PGContextVisibility .PQSHOW_CONTEXT_ALWAYS); string ss = to!string(c); import std.string:split; this.code = to!string(ss.split(':')[1]); this.sqlState = to!string(s); } const char* m = PQerrorMessage(conn); this.message = to!string(m); super(this.message); } } class DuplicateKeyException : Exception { this(string message) { super(message); } }
上述程式碼重點:
-
Postgres 類別: 表示 PostgreSQL 資料庫連線。
- 管理連線建立、查詢和準備語句執行。
- 使用先前定義的 C 綁定與 PostgreSQL 函式庫互動。
-
QueryResult 類別: 封裝資料庫查詢的結果。
- 以結構化格式儲存查詢結果。
- 處理 PostgreSQL 傳回的不同資料類型和格式。
- 錯誤處理: 實作 PostgreSQL 錯誤的自訂例外處理。
- 連線管理:包含連線遺失時的自動重新連線嘗試。
- 準備好的語句:支援執行帶有參數綁定的準備好的SQL語句。
- 記憶體管理:使用析構函數(~this())正確釋放資源。
- UTF-8 支援: 預設將連線編碼設定為 UTF-8。
此實作為 D 應用程式提供了與 PostgreSQL 資料庫互動的高級接口,抽象化了 C API 的許多低階細節。
現在您可能會收到 IDE 警告/錯誤「找不到連接模組」
讓我們建立連接模組:
建立 _internal/connection.d 檔案加入以下程式碼:
dub init <project_name> </project_name>
為 SQL 新增常數和其他選項:
_internal/consts.d
"libs": [ "pq" ], "lflags-windows-x86_64": [ "-LIBPATH:C:/Program Files/PostgreSQL/16/lib/" ], "copyFiles-windows-x86_64": [ "C:/Program Files/PostgreSQL/16/lib/libpq.dll", "C:/Program Files/PostgreSQL/16/bin/libintl-9.dll", "C:/Program Files/PostgreSQL/16/bin/libssl-3-x64.dll", "C:/Program Files/PostgreSQL/16/bin/libcrypto-3-x64.dll", "C:/Program Files/PostgreSQL/16/bin/libwinpthread-1.dll", "C:/Program Files/PostgreSQL/16/bin/libiconv-2.dll" ],
建立模型模板
D 支援模板元程式設計,此功能可讓您編寫高度通用的程式碼。這意味著 D 的模板與 C 中的相似,但更強大、更靈活。
D 中模板的 ABC | D 部落格
D 模板的主要特點:
- 編譯時類型檢查:模板在編譯時進行檢查,確保型別安全。
- 程式碼產生:您可以使用範本為不同類型或值產生專門的程式碼。
- 可變參數模板: D 支援可以採用任意數量參數的模板,包括類型和值。
- 靜態 if 和 mixin: 這些允許您在編譯期間根據條件產生和操作程式碼,甚至注入基於字串的程式碼(使用 mixin)。
現在讓我們建立一個模板類別。
模型.d
現在使用 https://github.com/rodevasia/sequelized/blob/main/source/postgres/model.d 中的程式碼貼到您的檔案
讓我們檢查一下所提供的 GitHub 連結中的程式碼:
"copyFiles-windows": [ "libs/*.dll" ], "lflags-windows": [ "/LIBPATH:$PACKAGE_DIR/libs" ], "libs": [ "pq" ]
此程式碼在 D 中定義了一個模板類別 Model。以下是其關鍵組件的細分:
- 模組宣告:程式碼是postgres.model模組的一部分。
- 導入:導入各種標準 D 庫和自訂模組以在類別中使用。
- 模板類別: Model 類別被定義為具有類型參數 T 的模板。這允許該類別使用不同的類型。
- 類別方法: 這類包含幾個用於資料庫操作的方法,例如 save()、update()、delete() 和 find()。
- 編譯時反射:程式碼使用 D 的編譯時功能來檢查 T 類型的欄位並產生適當的 SQL 查詢。
- SQL 查詢產生: getInsertQuery() 和 getUpdateQuery() 等方法根據類型 T 的結構動態建立 SQL 查詢。
- 資料庫互動: 該類別使用 Connection 物件與 PostgreSQL 資料庫互動。
我們寫了所有工作程式碼。讓我們把它變成一個圖書館。將其添加到您的 dub.json
dub init <project_name> </project_name>
使用圖書館:
讓我們建立一個新專案:
"libs": [ "pq" ], "lflags-windows-x86_64": [ "-LIBPATH:C:/Program Files/PostgreSQL/16/lib/" ], "copyFiles-windows-x86_64": [ "C:/Program Files/PostgreSQL/16/lib/libpq.dll", "C:/Program Files/PostgreSQL/16/bin/libintl-9.dll", "C:/Program Files/PostgreSQL/16/bin/libssl-3-x64.dll", "C:/Program Files/PostgreSQL/16/bin/libcrypto-3-x64.dll", "C:/Program Files/PostgreSQL/16/bin/libwinpthread-1.dll", "C:/Program Files/PostgreSQL/16/bin/libiconv-2.dll" ],
將庫加入為 dub.json 中的依賴項
"copyFiles-windows": [ "libs/*.dll" ], "lflags-windows": [ "/LIBPATH:$PACKAGE_DIR/libs" ], "libs": [ "pq" ]
app.d
sudo apt-get install libpq-dev
讓我們分解程式碼並解釋其主要組件:
進口
程式碼從標準函式庫和Sequalized函式庫導入必要的模組:
- std.stdio:用於基本輸入/輸出操作
- postgres._internal.connection:處理資料庫連線詳細資訊
- postgres.implementation.core:PostgreSQL 操作的核心功能
- postgres.model:提供用於定義資料庫模型的模型混合
- postgres._internal.consts:包含庫中使用的常數值
主要功能
main函數示範如何使用Sequalized函式庫:
- 它會建立一個包含連接詳細資訊的 DatabaseConnectionOption 物件
- 使用這些選項初始化 Postgres 物件
- 建立Example類別的實例
- 呼叫sync()在資料庫中建立對應的表
- 設定文字欄位的值並將記錄插入資料庫
範例類
此類定義資料庫表的模型:
- 它使用 Model mixin 來繼承 ORM 功能
- 定義兩個欄位:id 和 textField
- 使用 @Type、@PmKey 和 @unique 等屬性指定欄位屬性
我沒有包含完整的過程,供你了解:)
如果您願意為我的專案做出貢獻,這裡是儲存庫的連結:
https://github.com/rodevasia/sequelized
以上是用 D 建構 PostgreSQL 函式庫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

C#和C 的学习曲线和开发者体验有显著差异。1)C#的学习曲线较平缓,适合快速开发和企业级应用。2)C 的学习曲线较陡峭,适用于高性能和低级控制的场景。

C#和C 在面向对象编程(OOP)中的实现方式和特性上有显著差异。1)C#的类定义和语法更为简洁,支持如LINQ等高级特性。2)C 提供更细粒度的控制,适用于系统编程和高性能需求。两者各有优势,选择应基于具体应用场景。

從XML轉換到C 並進行數據操作可以通過以下步驟實現:1)使用tinyxml2庫解析XML文件,2)將數據映射到C 的數據結構中,3)使用C 標準庫如std::vector進行數據操作。通過這些步驟,可以高效地處理和操作從XML轉換過來的數據。

C#使用自動垃圾回收機制,而C 採用手動內存管理。 1.C#的垃圾回收器自動管理內存,減少內存洩漏風險,但可能導致性能下降。 2.C 提供靈活的內存控制,適合需要精細管理的應用,但需謹慎處理以避免內存洩漏。

C 在現代編程中仍然具有重要相關性。 1)高性能和硬件直接操作能力使其在遊戲開發、嵌入式系統和高性能計算等領域佔據首選地位。 2)豐富的編程範式和現代特性如智能指針和模板編程增強了其靈活性和效率,儘管學習曲線陡峭,但其強大功能使其在今天的編程生態中依然重要。

C 學習者和開發者可以從StackOverflow、Reddit的r/cpp社區、Coursera和edX的課程、GitHub上的開源項目、專業諮詢服務以及CppCon等會議中獲得資源和支持。 1.StackOverflow提供技術問題的解答;2.Reddit的r/cpp社區分享最新資訊;3.Coursera和edX提供正式的C 課程;4.GitHub上的開源項目如LLVM和Boost提陞技能;5.專業諮詢服務如JetBrains和Perforce提供技術支持;6.CppCon等會議有助於職業

C#適合需要高開發效率和跨平台支持的項目,而C 適用於需要高性能和底層控制的應用。 1)C#簡化開發,提供垃圾回收和豐富類庫,適合企業級應用。 2)C 允許直接內存操作,適用於遊戲開發和高性能計算。

C 持續使用的理由包括其高性能、廣泛應用和不斷演進的特性。 1)高效性能:通過直接操作內存和硬件,C 在系統編程和高性能計算中表現出色。 2)廣泛應用:在遊戲開發、嵌入式系統等領域大放異彩。 3)不斷演進:自1983年發布以來,C 持續增加新特性,保持其競爭力。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用