> 백엔드 개발 > C++ > 본문

D로 PostgreSQL 라이브러리 구축

Patricia Arquette
풀어 주다: 2024-10-24 06:16:30
원래의
932명이 탐색했습니다.

Building a PostgreSQL Library in D

저는 항상 새로운 프로그래밍 언어와 프레임워크에 대해 호기심이 많았습니다. 그동안 내 경험과 호기심은 프론트엔드 개발에만 퍼졌습니다(백엔드도 좀 해봤죠?). 기술을 확장하기 위해 도전했고 D 프로그래밍 언어를 발견했습니다. D는 쉽게 말하면 C와 CPP의 고급 버전입니다.

D란 무엇인가요? 웹사이트에는 '**D 는 정적 타이핑, 시스템 수준 액세스 및 C와 유사한 구문을 갖춘 범용 프로그래밍 언어입니다. D 프로그래밍 언어를 사용하면 빠르게 쓰고, 빠르게 읽고, 빠르게 실행할 수 있습니다.

저는 작품의 데이터베이스로 PostgreSQL을 사용해왔고, 그래서 이 라이브러리에도 PostgreSQL을 선택했습니다. PostgreSQL은 현재 기업들이 사용하고 있는 주요 오픈소스 SQL 데이터베이스 시스템 중 하나이며 그 기능은 더욱 확장되고 있습니다.

맞춤형 ORM 라이브러리를 구축하는 이유는 무엇입니까?

D 언어를 망칠 때 내 요구 사항을 충족하는 패키지 하나를 찾을 수 없었습니다. 패키지가 유지 관리를 중지했거나 직접 쿼리용으로 사용할 수 있었습니다. JavaScript 배경에서 Sequalize ORM을 사용했습니다. 저에게 아이디어가 생겼는데, D에서도 비슷한 아이디어는 어떠세요?

그래서 좀 조사한 결과 Postgres가 C용 라이브러리를 제공한다는 것을 알게 되었습니다. 그러던 중 D에서 C 바인딩을 사용하고 이를 ORM 개발에 사용하면 어떨까 하는 생각이 들었습니다. C 라이브러리를 D에 바인딩하기 위한 소스 코드는 https://github.com/adamdruppe/arsd/blob/master/postgres.d에서 찾았습니다.

시작하기

요구사항:

  • 시스템에 PostgreSQL이 설치되어 있어야 합니다. ( 저는 PostgreSQL 16용으로 개발했습니다)
  • IDE(Zed/ VSCode/Vim)
  • DMD - d 언어 컴파일러

새 프로젝트를 만들려면 터미널에서 다음 명령을 사용하세요.

  1. 터미널이나 명령 프롬프트를 엽니다.
  2. 프로젝트를 생성하려는 디렉토리로 이동하세요.
  3. 다음 명령을 실행하세요.
dub init <project_name>
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 명령은 지정된 이름으로 새 프로젝트 디렉터리를 생성하고 D 프로젝트의 기본 구조를 설정합니다.

  1. 다음 정보를 입력하라는 메시지가 표시됩니다.
    • 형식 - .sdl 또는 .json(저는 json을 선택했습니다)
    • 프로젝트 설명(선택)
    • 저자 이름
    • 라이센스(예: MIT, BSD 등)
    • 저작권 문자열
    • 종속성 추가(선택 사항)
  2. 정보를 제공한 후 dub은 프로젝트 이름으로 새 디렉터리를 만들고 다음 파일을 생성합니다.
    • dub.json: 프로젝트 구성 파일
    • source/app.d: 메인 소스 파일
    • .gitignore: Git 무시 파일
  3. 새 프로젝트 디렉토리로 이동합니다: cd
  4. 이제 D 프로젝트 개발을 시작할 수 있습니다!

이 단계를 완료하면 기본 D 프로젝트 구조가 설정되고 개발 준비가 완료됩니다.

Windows에서는 dub.json에 아래 섹션을 추가해야 합니다.

dub init <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"
    ]
로그인 후 복사
로그인 후 복사
로그인 후 복사

필요한 라이브러리를 설치하고 올바르게 연결한 후에는 PostgreSQL과 작동하도록 D 프로젝트 설정을 진행할 수 있습니다.

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 예외 클래스에서 상속되는 사용자 정의 예외 클래스입니다. PostgreSQL 관련 오류를 처리하도록 설계되었습니다.
  • 필드:
    • 코드: 오류 코드를 저장합니다
    • 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>
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

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 템플릿의 주요 기능:

  1. 컴파일 시간 유형 검사: 템플릿은 컴파일 시간에 검사되어 유형 안전성을 보장합니다.
  2. 코드 생성: 템플릿을 사용하여 다양한 유형이나 값에 대한 특수 코드를 생성할 수 있습니다.
  3. Variadic 템플릿: D는 유형과 값을 포함하여 임의 개수의 인수를 취할 수 있는 템플릿을 지원합니다.
  4. 정적 ifs 및 믹스인: 이를 사용하면 컴파일 중에 조건에 따라 코드를 생성 및 조작하거나 문자열 기반 코드(믹스인 사용)를 삽입할 수도 있습니다.

이제 템플릿 클래스를 만들어 보겠습니다.

model.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을 정의합니다. 주요 구성 요소에 대한 분석은 다음과 같습니다.

  1. 모듈 선언: 코드는 postgres.model 모듈의 일부입니다.
  2. 가져오기: 수업에 사용하기 위해 다양한 표준 D 라이브러리와 사용자 정의 모듈을 가져옵니다.
  3. 템플릿 클래스: Model 클래스는 유형 매개변수 T가 있는 템플릿으로 정의됩니다. 이를 통해 클래스는 다양한 유형과 작업할 수 있습니다.
  4. 클래스 메소드: 클래스에는 save(), update(), delete() 및 find()와 같은 데이터베이스 작업을 위한 여러 메소드가 포함되어 있습니다.
  5. 컴파일 시간 반영: 코드는 D의 컴파일 시간 기능을 사용하여 T 유형의 필드를 검사하고 적절한 SQL 쿼리를 생성합니다.
  6. SQL 쿼리 생성: getInsertQuery() 및 getUpdateQuery()와 같은 메소드는 T 유형의 구조를 기반으로 SQL 쿼리를 동적으로 생성합니다.
  7. 데이터베이스 상호 작용: 클래스는 연결 개체를 사용하여 PostgreSQL 데이터베이스와 상호 작용합니다.

작업을 위한 모든 코드를 작성했습니다. 이것을 도서관으로 만들어 보겠습니다. 이것을 dub.json에 추가하세요

dub init <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: 라이브러리에서 사용되는 상수 값을 포함합니다

주요 기능

주 함수는 Sequalized 라이브러리를 사용하는 방법을 보여줍니다.

  • 연결 세부정보가 포함된 DatabaseConnectionOption 개체를 생성합니다
  • 이러한 옵션을 사용하여 Postgres 객체를 초기화합니다
  • Example 클래스의 인스턴스를 생성합니다
  • sync()를 호출하여 데이터베이스에 해당 테이블을 생성합니다
  • textField의 값을 설정하고 데이터베이스에 레코드를 삽입합니다

예제 클래스

이 클래스는 데이터베이스 테이블의 모델을 정의합니다.

  • 모델 믹스인을 사용하여 ORM 기능을 상속합니다
  • id와 textField라는 두 개의 필드를 정의합니다
  • @Type, @PmKey 및 @unique와 같은 속성을 사용하여 필드 속성을 지정합니다

전체 과정은 포함하지 않았으니 알아보시기 바랍니다 :)

내 프로젝트에 기여하고 싶다면 저장소 링크를 확인하세요.
https://github.com/rodevasia/sequelized

위 내용은 D로 PostgreSQL 라이브러리 구축의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿