Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Membina Perpustakaan PostgreSQL dalam D

Membina Perpustakaan PostgreSQL dalam D

Patricia Arquette
Patricia Arquetteasal
2024-10-24 06:16:30866semak imbas

Building a PostgreSQL Library in D

Saya sentiasa ingin tahu tentang bahasa pengaturcaraan baharu dan rangka kerjanya. Selama ini pengalaman dan rasa ingin tahu saya tersebar hanya dalam pembangunan bahagian hadapan (saya telah melakukan beberapa bahagian belakang sekalipun?). Saya mencabar diri saya untuk mengembangkan kemahiran saya dan saya menemui bahasa pengaturcaraan D. D dalam perkataan mudah ialah versi lanjutan C dan CPP.

Apakah itu D? tapak web menyatakan “**D adalah bahasa pengaturcaraan tujuan umum dengan penaipan statik, akses peringkat sistem dan sintaks seperti C. Dengan Bahasa Pengaturcaraan D, tulis dengan pantas, baca dengan pantas dan lari dengan pantas.

Saya telah menggunakan PostgreSQL sebagai pangkalan data saya untuk kerja saya, dan itulah sebabnya saya memilihnya untuk perpustakaan ini juga. PostgreSQL ialah salah satu sistem pangkalan data SQL sumber terbuka utama yang digunakan oleh syarikat sekarang dan ciri-cirinya semakin berkembang.

Mengapa Membina Perpustakaan ORM Tersuai?

Apabila bermain-main dengan bahasa D saya tidak dapat mencari satu pakej yang memuaskan hati saya, sama ada pakej dihentikan penyelenggaraan atau boleh digunakan sebagai pertanyaan terus. Dari latar belakang JavaScript saya menggunakan Sequalize ORM. Itu memberi saya idea, Bagaimana pula dengan yang serupa dalam D.

Jadi, saya melakukan penyelidikan dan saya dapati Postgres menyediakan perpustakaan untuk C. Kemudian saya fikir, bagaimana pula dengan menggunakan pengikatan C dalam D dan menggunakannya untuk membangunkan ORM. Saya menemui kod sumber daripada https://github.com/adamdruppe/arsd/blob/master/postgres.d untuk mengikat perpustakaan C kepada D.

Bermula

Keperluan:

  • PostgreSQL mesti dipasang dalam sistem anda. ( Saya membangunkan untuk PostgreSQL 16)
  • IDE (Zed/ VSCode/Vim)
  • DMD - pengkompil bahasa d

Untuk mencipta projek baharu, gunakan arahan berikut dalam terminal anda:

  1. Buka terminal atau gesaan arahan anda.
  2. Navigasi ke direktori tempat anda ingin mencipta projek anda.
  3. Jalankan arahan:
dub init <project_name>

Arahan ini akan mencipta direktori projek baharu dengan nama yang ditentukan dan menyediakan struktur asas untuk projek D.

  1. Anda akan digesa untuk memasukkan maklumat berikut:
    • Format - .sdl atau .json ( saya pilih json )
    • Penerangan projek (pilihan)
    • Nama pengarang
    • Lesen (cth., MIT, BSD, dsb.)
    • Rentetan hak cipta
    • Tambah pergantungan (pilihan)
  2. Selepas memberikan maklumat, alih suara akan mencipta direktori baharu dengan nama projek anda dan menjana fail berikut:
    • dub.json: Fail konfigurasi untuk projek anda
    • sumber/app.d: Fail sumber utama
    • .gitignore: Git abaikan fail
  3. Navigasi ke dalam direktori projek baharu anda: cd
  4. Anda kini boleh mula membangunkan projek D anda!

Dengan langkah-langkah ini selesai, anda akan menyediakan struktur projek D asas dan sedia untuk pembangunan.

Dalam Windows bahagian di bawah perlu ditambah pada dub.json.

dub init <project_name>

atau

Cara yang saya lakukan ialah menyalin semua fail DLL yang diperlukan ke folder lib (dicipta secara manual) dan kemudian menambah kod di bawah:

"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"
    ],

Dalam Linux atau macOS, anda perlu memastikan bahawa perpustakaan pembangunan PostgreSQL dipasang dan dipautkan dengan betul. Anda biasanya boleh melakukan ini dengan memasang pakej yang sesuai melalui pengurus pakej sistem anda. Contohnya, pada sistem berasaskan Ubuntu atau Debian, anda mungkin menggunakan:

"copyFiles-windows": [
        "libs/*.dll"
    ],
    "lflags-windows": [
        "/LIBPATH:$PACKAGE_DIR/libs"
    ],
    "libs": [
        "pq"
    ]

Setelah anda memasang perpustakaan yang diperlukan dan dipautkan dengan betul, anda boleh meneruskan dengan menyediakan projek D anda untuk berfungsi dengan PostgreSQL.

Melaksanakan pengikatan C:

Berikut ialah pengikatan C untuk D.

sudo apt-get install libpq-dev

Kini kita boleh menggunakan fungsi ini dengan mudah dalam D.
Ini ialah kod untuk beberapa pengendalian pengecualian asas:

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: Kelas pengecualian tersuai yang mewarisi daripada kelas D Exception standard. Ia direka untuk mengendalikan ralat khusus PostgreSQL.
  • Bidang:
    • kod: Menyimpan kod ralat
    • sqlState: Menyimpan keadaan SQL
    • mesej: Menyimpan mesej ralat
  • Pembina: Mengambil PGconn* (sambungan PostgreSQL) dan PGresult* (hasil pertanyaan). PQresultVerboseErrorMessage dan PQerrorMessage untuk mengekstrak maklumat ralat terperinci.
  • DuplicateKeyException: Kelas pengecualian mudah untuk mengendalikan ralat kunci pendua. Ia hanya mengambil parameter mesej dan menghantarnya ke kelas Pengecualian asas.

Saya akan menambah lebih banyak pengecualian dan situasi lain semasa saya mengusahakan projek ini

Sekarang buat cipta fail pelaksanaan/teras/teras.d untuk menulis kod sambungan.

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);
    }
}

Isi utama kod di atas:

  • Kelas Postgres: Mewakili sambungan pangkalan data PostgreSQL.
    • Mengurus penciptaan sambungan, pertanyaan dan pelaksanaan pernyataan yang disediakan.
    • Menggunakan pengikatan C yang ditakrifkan sebelum ini untuk berinteraksi dengan pustaka PostgreSQL.
  • Kelas QueryResult: Merangkumkan hasil pertanyaan pangkalan data.
    • Menyimpan hasil pertanyaan dalam format berstruktur.
    • Mengendalikan jenis data dan format berbeza yang dikembalikan oleh PostgreSQL.
  • Pengendalian ralat: Melaksanakan pengendalian pengecualian tersuai untuk ralat PostgreSQL.
  • Pengurusan sambungan: Termasuk percubaan penyambungan semula automatik pada kehilangan sambungan.
  • Pernyataan yang disediakan: Menyokong pelaksanaan pernyataan SQL yang disediakan dengan pengikatan parameter.
  • Pengurusan memori: Membebaskan sumber dengan betul menggunakan pemusnah (~ini()).
  • Sokongan UTF-8: Tetapkan pengekodan sambungan kepada UTF-8 secara lalai.

Pelaksanaan ini menyediakan antara muka peringkat tinggi untuk aplikasi D untuk berinteraksi dengan pangkalan data PostgreSQL, menghilangkan banyak butiran peringkat rendah C API.

Anda mungkin mempunyai amaran/ralat IDE sekarang bahawa "modul sambungan tidak ditemui"

Mari buat modul sambungan:

Buat fail _internal/connection.d tambah kod ini:

dub init <project_name>

Tambah pemalar dan pilihan lain untuk SQL:

_dalaman/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"
    ],

Mencipta Templat Model

D menyokong metaprogramming templat, ciri yang membolehkan anda menulis kod yang sangat generik. Ini bermakna D mempunyai templat serupa dengan templat dalam C tetapi lebih berkuasa dan fleksibel.
Templat ABC dalam D | Blog D

Ciri utama templat D:

  1. Pemeriksaan jenis masa kompilasi: Templat disemak pada masa penyusunan, memastikan keselamatan jenis.
  2. Penjanaan kod: Anda boleh menggunakan templat untuk menjana kod khusus untuk jenis atau nilai yang berbeza.
  3. Templat pelbagai: D menyokong templat yang boleh mengambil bilangan hujah yang sewenang-wenangnya, termasuk jenis dan nilai.
  4. Jika dan campuran statik: Ini membolehkan anda menjana dan memanipulasi kod semasa penyusunan berdasarkan syarat atau menyuntik kod berasaskan rentetan (dengan campuran).

Sekarang mari buat kelas templat.

model.d

Sekarang gunakan kod daripada https://github.com/rodevasia/sequelized/blob/main/source/postgres/model.d tampal pada fail anda

Mari kita periksa kod daripada pautan GitHub yang disediakan:

"copyFiles-windows": [
        "libs/*.dll"
    ],
    "lflags-windows": [
        "/LIBPATH:$PACKAGE_DIR/libs"
    ],
    "libs": [
        "pq"
    ]

Kod ini mentakrifkan Model kelas templat dalam D. Berikut ialah pecahan komponen utamanya:

  1. Pengisytiharan modul: Kod adalah sebahagian daripada modul postgres.model.
  2. Import: Pelbagai perpustakaan D standard dan modul tersuai diimport untuk digunakan dalam kelas.
  3. Kelas templat: Kelas Model ditakrifkan sebagai templat dengan parameter jenis T. Ini membolehkan kelas berfungsi dengan jenis yang berbeza.
  4. Kaedah kelas: Kelas termasuk beberapa kaedah untuk operasi pangkalan data seperti save(), kemas kini(), delete(), dan find().
  5. Refleksi masa kompilasi: Kod menggunakan ciri masa kompilasi D untuk memeriksa medan jenis T dan menjana pertanyaan SQL yang sesuai.
  6. Penjanaan pertanyaan SQL: Kaedah seperti getInsertQuery() dan getUpdateQuery() mencipta pertanyaan SQL secara dinamik berdasarkan struktur jenis T.
  7. Interaksi pangkalan data: Kelas menggunakan objek Sambungan untuk berinteraksi dengan pangkalan data PostgreSQL.

Kami menulis semua kod untuk berfungsi. Mari jadikan ini sebagai perpustakaan. tambahkan ini pada dub.json
anda

dub init <project_name>

Menggunakan Perpustakaan:

Biar buat projek baharu:

"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"
    ],

tambah pustaka sebagai kebergantungan dalam dub.json

"copyFiles-windows": [
        "libs/*.dll"
    ],
    "lflags-windows": [
        "/LIBPATH:$PACKAGE_DIR/libs"
    ],
    "libs": [
        "pq"
    ]

app.d

sudo apt-get install libpq-dev

Mari pecahkan kod dan terangkan komponen utamanya:

Import

Kod mengimport modul yang diperlukan daripada perpustakaan standard dan perpustakaan Sequalized:

  • std.stdio: Untuk operasi input/output asas
  • postgres._internal.connection: Mengendalikan butiran sambungan pangkalan data
  • postgres.implementation.core: Fungsi teras untuk operasi PostgreSQL
  • postgres.model: Menyediakan campuran Model untuk menentukan model pangkalan data
  • postgres._internal.consts: Mengandungi nilai tetap yang digunakan dalam perpustakaan

Fungsi Utama

Fungsi utama menunjukkan cara menggunakan perpustakaan Sequalized:

  • Ia mencipta objek DatabaseConnectionOption dengan butiran sambungan
  • Memulakan objek Postgres dengan pilihan ini
  • Mencipta contoh kelas Contoh
  • Panggilan sync() untuk mencipta jadual yang sepadan dalam pangkalan data
  • Menetapkan nilai untuk TextField dan memasukkan rekod ke dalam pangkalan data

Kelas Contoh

Kelas ini mentakrifkan model untuk jadual pangkalan data:

  • Ia menggunakan campuran Model untuk mewarisi fungsi ORM
  • Mentakrifkan dua medan: id dan textField
  • Menggunakan atribut seperti @Type, @PmKey dan @unique untuk menentukan sifat medan

Saya belum memasukkan proses penuh, dan itu adalah untuk anda ketahui :)

Jika anda ingin menyumbang kepada projek saya di sini ialah pautan untuk repo:
https://github.com/rodevasia/sequelized

Atas ialah kandungan terperinci Membina Perpustakaan PostgreSQL dalam D. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn