実装 0513-02

実装 0513-02

#include <iostream>
#include <vector>
#include <cstring>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <sstream>
#include <iomanip>

namespace tsssqldb {


    struct TssFile {
        int FileNo;
        char FileHash[128] = {};
        TssFile() {
            memset(FileHash, 0, sizeof(FileHash));
        }
    };


    struct TssStatus {
        char Token[8000] = {};
        char TsaCert[8000] = {};
        char FixHash[128] = {};
        std::vector<TssFile> files;
        TssStatus() {
            memset(Token, 0, sizeof(Token));
            memset(TsaCert, 0, sizeof(TsaCert));
            memset(FixHash, 0, sizeof(FixHash));
        }
    };


    SQLRETURN setupDatabase(SQLHENV& env, SQLHDBC& dbc) {
        SQLWCHAR outstr[1024];
        SQLSMALLINT outstrlen;
        SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
        SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
        SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
        return SQLDriverConnect(dbc, NULL, (SQLWCHAR*)L"DSN=ODBC_MSSQL;", SQL_NTS, outstr, sizeof(outstr) / sizeof(SQLWCHAR), &outstrlen, SQL_DRIVER_COMPLETE);
    }


    void closeDatabase(SQLHDBC dbc, SQLHENV env) {
        SQLDisconnect(dbc);
        SQLFreeHandle(SQL_HANDLE_DBC, dbc);
        SQLFreeHandle(SQL_HANDLE_ENV, env);
    }


    std::vector<TssStatus> fetchData(SQLHDBC dbc) {
        SQLHSTMT stmt;
        SQLRETURN ret;
        const wchar_t* sqlQuery = L" SELECT s.Token, s.TsaCert, s.FixHash, f.FileNo, f.FileHash "
            L" FROM TimestampStatus s "
            L" JOIN TimestampFile f ON f.TSSOrderNo = s.TSSOrderNo";

        SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
        ret = SQLExecDirect(stmt, (SQLWCHAR*)sqlQuery, SQL_NTS);

        std::vector<TssStatus> allData;
        if (SQL_SUCCEEDED(ret)) {
            TssStatus data;
            SQLLEN indicator;
            while (SQLFetch(stmt) == SQL_SUCCESS) {
                TssFile file;
                SQLGetData(stmt, 1, SQL_C_BINARY, data.Token, sizeof(data.Token), &indicator);
                SQLGetData(stmt, 2, SQL_C_BINARY, data.TsaCert, sizeof(data.TsaCert), &indicator);
                SQLGetData(stmt, 3, SQL_C_BINARY, data.FixHash, sizeof(data.FixHash), &indicator);
                SQLGetData(stmt, 4, SQL_C_SLONG, &file.FileNo, sizeof(file.FileNo), &indicator);
                SQLGetData(stmt, 5, SQL_C_BINARY, file.FileHash, sizeof(file.FileHash), &indicator);
                data.files.push_back(file);
            }
            allData.push_back(data);
        }
        else {
            std::cerr << "Failed to execute SQL query.\n";
        }
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
        return allData;
    }


    std::string ConvertCharPointerToString(const char* data, size_t size) {
        std::ostringstream oss;
        oss << std::hex << std::setfill('0');
        for (size_t i = 0; i < size; ++i) {
            oss << std::setw(2) << (static_cast<unsigned int>(static_cast<unsigned char>(data[i])) & 0xff);
        }
    }


    std::string ConvertCharPointerToString(unsigned char* data, size_t size) {
        std::ostringstream oss;
        oss << std::hex << std::setfill('0');
        for (size_t i = 0; i < size; ++i) {
            oss << std::setw(2) << (static_cast<unsigned int>(static_cast<unsigned char>(data[i])) & 0xff);
        }
    }
}


int main() {

    SQLHENV env;
    SQLHDBC dbc;

    if (SQL_SUCCEEDED(tsssqldb::setupDatabase(env, dbc))) {
        std::vector<tsssqldb::TssStatus> allData = tsssqldb::fetchData(dbc);
        for (auto& status : allData) {
            for (auto& file : status.files) {
                //memcpy(status.FixHash, file.FileHash, sizeof(file.FileHash)); // Copy hash
                tsssqldb::ConvertCharPointerToString(file.FileHash, sizeof(file.FileHash));

            }
            tsssqldb::ConvertCharPointerToString(status.Token, sizeof(status.Token));
            tsssqldb::ConvertCharPointerToString(status.TsaCert, sizeof(status.TsaCert));
            tsssqldb::ConvertCharPointerToString(status.FixHash, sizeof(status.FixHash));
        }
        tsssqldb::closeDatabase(dbc, env);
    }
    return 0;
}