<Ubuntu> MariaDB, C/C++ 빌드 테스트

1. MariaDB, DBeaver 설치 & 사용
MariaDB (재)설치
최초 설치인 경우, 2번부터 시작하세요. 1. 설치된 MariaDB 제거더보기1.1 DB 정지sudo service mysql stop && sudo systemctl stop mysql 1.2 MariaDB 제거sudo apt purge mariadb-server -y && sudo apt purge mariadb-common -y && sudo apt
basiclike.tistory.com
05 [Ubuntu] DBeaver 설치
방법1 sudo snap install dbeaver-ce 방법2 1. dbeaver 다운로드 접속, package 로 설치 2. 다운로드 받은 패키지로 설치 우분투 설치 패키지 참고 sudo dpkg -i ~/Downloads/dbeaver-ce*.deb
basiclike.tistory.com
DBeaver 에서 MariaDB 테이블과 컬럼 생성 후, 데이터 입력
MariaDB & DBeaver, 테이블과 컬럼 생성
basiclike.tistory.com
1.1 MariaDB, C/C++ 빌드 예제, 데이터베이스 생성
CREATE DATABASE IF NOT EXISTS todo;

1.2 MariaDB, C/C++ 빌드 예제, 테이블 생성
CREATE TABLE todo.tasks (
  id INT(11) unsigned NOT NULL AUTO_INCREMENT,
  description VARCHAR(500) NOT NULL,
  completed BOOLEAN NOT NULL DEFAULT 0,
  PRIMARY KEY (id)
);

1.3 MariaDB, C/C++ 빌드 예제, 생성된 테이블 확인

1.4 MariaDB, C/C++ 빌드 예제, 생성된 테이블에 데이터 추가하기

2. C/C++ MariaDB 라이브러리 설치
1. MariaDB, C/C++ Connectors 다운로드 페이지 이동
- MariaDB Connector, 공식 홈페이지 다운로드 링크로 이동
 
library
- header 파일과 다르다.
- 컴파일된(기계어로 번역) *.o(오브젝트)파일을 여러개 모아 놓은 것이다.
- 라이브러리를 사용하기 위해서 해당 라이브러리의 헤더파일이 있어야한다.
링커가 심볼네임으로 라이브러리를 링크한다.
header
- library와 다르다.
- 컴파일 전, 프로그래머가 이해 가능한 선언 집합이다.
- 헤더파일로 컴파일러가 심볼네임을 오브젝트 파일에 넣어준다.
링커가 해당 심볼네임을 가지고 라이브러리를 뒤져서 링크를 하게 된다.
2. 설치 파일 다운로드
- Connectors 탭 이동
 - Product C++ connector 선택
 - Version 선택
 - OS 선택
- 다운로드 파일명
mariadb-connector-cpp-1.1.5-ubuntu-jammy-amd64.tar.gz (2024.09.26 기준) 
 - 다운로드 파일명
 

3. 다운받은 설치 파일 압축 해제
tar -xvzf mariadb-connector-cpp*
4. 파일 디렉토리 이동
cd mariadb-connector-cpp-*/
5. 헤더 파일 설치할 디렉터리 지정
- -d --directory : 대상 디렉터리를 지정을 하고, 지정한 디렉터리가 없다면 만든다.
 
sudo install -d /usr/include/mariadb/conncpp
sudo install -d /usr/include/mariadb/conncpp/compat
6. 지정한 디렉터리에 헤더 파일 설치
sudo install include/mariadb/* /usr/include/mariadb/
sudo install include/mariadb/conncpp/* /usr/include/mariadb/conncpp
sudo install include/mariadb/conncpp/compat/* /usr/include/mariadb/conncpp/compat
7. 지정한 디렉터리에 공유 라이브러리
- /lib: 커널 모듈 파일과 라이브러리 파일(C, C++등)들이 존재하는 디렉터리
 - /lib64(64bit)와 /lib(32bit)로 하드웨어 아키텍쳐에 따라 구분하여 공유 라이브러리를 저장한다.
 
sudo install -d /usr/lib/mariadb
sudo install -d /usr/lib/mariadb/plugin
sudo install lib/mariadb/libmariadbcpp.so /usr/lib
sudo install lib/mariadb/plugin/* /usr/lib/mariadb/plugin
8. 추가
sudo install -d /usr/lib64/mariadb
sudo install -d /usr/lib64/mariadb/plugin
sudo install lib/mariadb/libmariadbcpp.so /usr/lib64
sudo install lib/mariadb/plugin/* /usr/lib64/mariadb/plugin
4. MariaDB, C/C++ 소스코드 빌드 테스트 (VSCode)
깃허브에서 MariaDB C/C++ 테스트 소스코드 깃허브에서 복사


#include <iostream>
#include <cstring>
#include <mariadb/conncpp.hpp>
// Delete a task record (indicated by id)
void deleteTask(std::unique_ptr<sql::Connection> &conn, int id) {
    try {
        // Create a new PreparedStatement
        std::unique_ptr<sql::PreparedStatement> stmnt(conn->prepareStatement("delete from tasks where id = ?"));
        // Bind values to SQL statement
        stmnt->setInt(1, id);
        // Execute query
        stmnt->executeQuery();
    }
    catch(sql::SQLException& e){
      std::cerr << "Error deleting task: " << e.what() << std::endl;
   }
}
// Update the completed value of a task record (indicated by id)
void updateTaskStatus(std::unique_ptr<sql::Connection> &conn, int id, bool completed) {
    try {
        // Create a new PreparedStatement
        std::unique_ptr<sql::PreparedStatement> stmnt(conn->prepareStatement("update tasks set completed = ? where id = ?"));
        // Bind values to SQL statement
        stmnt->setBoolean(1, completed);
        stmnt->setInt(2, id);
        // Execute query
        stmnt->executeQuery();
    }
    catch(sql::SQLException& e){
      std::cerr << "Error updating task status: " << e.what() << std::endl;
   }
}
// Create a new task record
void addTask(std::unique_ptr<sql::Connection> &conn, std::string description) {
    try {
        // Create a new PreparedStatement
        std::unique_ptr<sql::PreparedStatement> stmnt(conn->prepareStatement("insert into tasks (description) values (?)"));
        // Bind values to SQL statement
        stmnt->setString(1, description);
        // Execute query
        stmnt->executeQuery();
    }
    catch(sql::SQLException& e){
      std::cerr << "Error inserting new task: " << e.what() << std::endl;
   }
}
// Print all records in tasks table 
void showTasks(std::unique_ptr<sql::Connection> &conn) {
    try {
        // Create a new Statement
        std::unique_ptr<sql::Statement> stmnt(conn->createStatement());
        // Execute query
        sql::ResultSet *res = stmnt->executeQuery("select * from tasks");
        // Loop through and print results
        while (res->next()) {
            std::cout << "id = " << res->getInt(1);
            std::cout << ", description = " << res->getString(2);
            std::cout << ", completed = " << res->getBoolean(3) << "\n";
        }
    }
    catch(sql::SQLException& e){
      std::cerr << "Error selecting tasks: " << e.what() << std::endl;
   }
}
// Main Process
int main(int argc, char **argv){
    if (argc==1){
        std::cout << "Please provide an argument.\n";
    }
    else {
        try {
            // Instantiate Driver
            sql::Driver* driver = sql::mariadb::get_driver_instance();
            // Configure Connection
            sql::SQLString url("jdbc:mariadb://localhost:3306/todo");
            sql::Properties properties({{"user", "app_user"}, {"password", "Password123!"}});
            // Establish Connection
            std::unique_ptr<sql::Connection> conn(driver->connect(url, properties));
            // Use arguments to determine execution next steps
            if (!strcmp(argv[1],"showTasks")) {
                showTasks(conn);
            }
            else if (!strcmp(argv[1],"addTask")) {
                if (argc != 3) {
                    std::cout << "Invalid arguments";
                    return 1;
                }
                addTask(conn, argv[2]);
            }
            else if (!strcmp(argv[1],"updateTaskStatus")) {
                if (argc != 4) {
                    std::cout << "Invalid arguments";
                    return 1;
                }
                updateTaskStatus(conn, atoi(argv[2]), argv[3]);
            }
            else if (!strcmp(argv[1],"deleteTask")) {
                if (argc != 3) {
                    std::cout << "Invalid arguments";
                    return 1;
                }
                deleteTask(conn, atoi(argv[2]));
            }
            // Close Connection
            conn->close();
        }
        catch(sql::SQLException& e){
            std::cerr << "Error Connecting to MariaDB Platform: " << e.what() << std::endl;
            // Exit (Failed)
            return 1;
        }
    }
    // Exit (Success)
    return 0;
}
소스코드 예제에서 MariaDB에 접속할 계정의 ID, PW 수정

빌드 명령
g++ -o tasks tasks.cpp -std=c++11 -lmariadbcpp

 
실행 명령 테스트

DBeaver 에서 소스코드에서 실행한 명령, MariaDB 테이블에서 업데이트 확인

5. MariaDB, C/C++ 소스코드 빌드 테스트 (C++ Qt Creator, qmake 빌드)
pro 파일에 MariaDB, C/C++ connector 라이브러리 경로 추가
LIBS += -L/usr/lib64 -lmariadbcpp
INCLUDEPATH += /usr/include/mariadb -I..include
DEPENDPATH += /usr/include/mariadb -I..include

깃허브에서 MariaDB C/C++ 테스트 소스코드 복사

빌드시 에러가 없으면, MariaDB, C/C++ connector 라이브러리가 정상 링크 된것이다.

6. MariaDB, C/C++ 소스코드 빌드 테스트 (C++ Qt Creator, 터미널 빌드)
터미널로 빌드가 가능하긴 하다.
