<commit_before>/*******************************************************************************
 * Copyright 2014, 2018 MINRES Technologies GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
#include "sqlite3.h"
#include <array>
#include <cstdio>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
#ifdef WITH_SCV
#include <scv.h>
#else
#include <scv-tr.h>
namespace scv_tr {
#endif
// ----------------------------------------------------------------------------
constexpr auto SQLITEWRAPPER_ERROR = 1000;
// ----------------------------------------------------------------------------
using namespace std;

class SQLiteDB {
public:
    class SQLiteException : public runtime_error {
    public:
        SQLiteException(const int nErrCode, const char* msg, bool doFree = true)
        : runtime_error(msg)
        , mnErrCode(0) {
            if(doFree && msg)
                sqlite3_free(const_cast<char*>(msg));
        }
        const int errorCode() { return mnErrCode; }
        const char* errorMessage() { return what(); }

    private:
        int mnErrCode;
    };

    SQLiteDB() = default;

    void open(const string szFile) {
        int nRet = sqlite3_open(szFile.c_str(), &db);
        if(nRet != SQLITE_OK)
            throw SQLiteException(nRet, sqlite3_errmsg(db), false);
        sqlite3_busy_timeout(db, busyTimeoutMs);
    }

    inline bool isOpen() { return db != nullptr; }

    void close() {
        if(db) {
            int nRet = sqlite3_close(db);
            if(nRet == SQLITE_OK)
                db = nullptr;
            else if(nRet == SQLITE_BUSY) {
                while(nRet == SQLITE_BUSY) { // maybe include _LOCKED
                    sqlite3_stmt* stmt = sqlite3_next_stmt(db, nullptr);
                    if(stmt)
                        sqlite3_finalize(stmt); // don't trap, can't handle it anyway
                    nRet = sqlite3_close(db);
                }
                if(nRet != SQLITE_OK)
                    throw SQLiteException(SQLITEWRAPPER_ERROR, "Unable to close database", false);
            } else
                throw SQLiteException(SQLITEWRAPPER_ERROR, "Unable to close database", false);
        }
    }

    inline int exec(const string szSQL) { return exec(szSQL.c_str()); }
    inline sqlite3_stmt* prepare(const string szSQL) {
        sqlite3_stmt* ret = nullptr;
        const char* tail;
        sqlite3_prepare_v2(db, szSQL.c_str(), szSQL.size(), &ret, &tail);
        return ret;
    }

    int exec(const char* szSQL) {
        checkDB();
        char* szError = nullptr;
        int nRet = sqlite3_exec(db, szSQL, nullptr, nullptr, &szError);
        if(nRet == SQLITE_OK)
            return sqlite3_changes(db);
        else
            throw SQLiteException(nRet, szError);
    }

    int exec(sqlite3_stmt* stmt) {
        checkDB();
        int nRet = sqlite3_step(stmt);
        if(nRet == SQLITE_OK || nRet == SQLITE_DONE) {
            sqlite3_reset(stmt);<commit_msg>fix: mark the db as nullptr after close<commit_after>/*******************************************************************************
 * Copyright 2014, 2018 MINRES Technologies GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
#include "sqlite3.h"
#include <array>
#include <cstdio>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
#ifdef WITH_SCV
#include <scv.h>
#else
#include <scv-tr.h>
namespace scv_tr {
#endif
// ----------------------------------------------------------------------------
constexpr auto SQLITEWRAPPER_ERROR = 1000;
// ----------------------------------------------------------------------------
using namespace std;

class SQLiteDB {
public:
    class SQLiteException : public runtime_error {
    public:
        SQLiteException(const int nErrCode, const char* msg, bool doFree = true)
        : runtime_error(msg)
        , mnErrCode(0) {
            if(doFree && msg)
                sqlite3_free(const_cast<char*>(msg));
        }
        const int errorCode() { return mnErrCode; }
        const char* errorMessage() { return what(); }

    private:
        int mnErrCode;
    };

    SQLiteDB() = default;

    void open(const string szFile) {
        int nRet = sqlite3_open(szFile.c_str(), &db);
        if(nRet != SQLITE_OK)
            throw SQLiteException(nRet, sqlite3_errmsg(db), false);
        sqlite3_busy_timeout(db, busyTimeoutMs);
    }

    inline bool isOpen() { return db != nullptr; }

    void close() {
        if(db) {
            int nRet = sqlite3_close(db);
            if(nRet == SQLITE_OK)
                db = nullptr;
            else if(nRet == SQLITE_BUSY) {
                while(nRet == SQLITE_BUSY) { // maybe include _LOCKED
                    sqlite3_stmt* stmt = sqlite3_next_stmt(db, nullptr);
                    if(stmt)
                        sqlite3_finalize(stmt); // don't trap, can't handle it anyway
                    nRet = sqlite3_close(db);
                }
                if(nRet != SQLITE_OK)
                    throw SQLiteException(SQLITEWRAPPER_ERROR, "Unable to close database", false);
                db = nullptr;
            } else
                throw SQLiteException(SQLITEWRAPPER_ERROR, "Unable to close database", false);
        }
    }

    inline int exec(const string szSQL) { return exec(szSQL.c_str()); }
    inline sqlite3_stmt* prepare(const string szSQL) {
        sqlite3_stmt* ret = nullptr;
        const char* tail;
        sqlite3_prepare_v2(db, szSQL.c_str(), szSQL.size(), &ret, &tail);
        return ret;
    }

    int exec(const char* szSQL) {
        checkDB();
        char* szError = nullptr;
        int nRet = sqlite3_exec(db, szSQL, nullptr, nullptr, &szError);
        if(nRet == SQLITE_OK)
            return sqlite3_changes(db);
        else
            throw SQLiteException(nRet, szError);
    }

    int exec(sqlite3_stmt* stmt) {
        checkDB();
        int nRet = sqlite3_step(stmt);
        if(nRet == SQLITE_OK || nRet == SQLITE_DONE) {
            sqlite3_reset(stmt);
{'fraction_non_alphanumeric': 0.17844327905051063, 'fraction_numerical': 0.009936516698868341, 'mean_word_length': 2.1577342047930284, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1989922', 'n_tokens_mistral': 2102, 'n_tokens_neox': 1992, 'n_words': 580}