<commit_before>#include "sqlstorage_base.h"
#include "storage_exception.h"

#include <sys/stat.h>

boost::filesystem::path SQLStorageBase::dbPath() const { return sqldb_path_; }

StorageLock::StorageLock(boost::filesystem::path path) : lock_path(std::move(path)) {
  {
    std::fstream fs;
    fs.open(lock_path.c_str(), std::fstream::in | std::fstream::out | std::fstream::app);
  }
  fl_ = lock_path.c_str();
  if (!fl_.try_lock()) {
    throw StorageLock::locked_exception();
  }
}

StorageLock::~StorageLock() {
  try {
    if (!lock_path.empty()) {
      fl_.unlock();
      std::remove(lock_path.c_str());
    }
  } catch (std::exception& e) {
  }
}

SQLStorageBase::SQLStorageBase(boost::filesystem::path sqldb_path, bool readonly,
                               std::vector<std::string> schema_migrations,
                               std::vector<std::string> schema_rollback_migrations, std::string current_schema,
                               int current_schema_version)
    : sqldb_path_(std::move(sqldb_path)),
      readonly_(readonly),
      schema_migrations_(std::move(schema_migrations)),
      schema_rollback_migrations_(std::move(schema_rollback_migrations)),
      current_schema_(std::move(current_schema)),
      current_schema_version_(current_schema_version) {
  boost::filesystem::path db_parent_path = dbPath().parent_path();
  if (!boost::filesystem::is_directory(db_parent_path)) {
    Utils::createDirectories(db_parent_path, S_IRWXU);
  } else {
    struct stat st {};
    if (stat(db_parent_path.c_str(), &st) < 0) {
      throw StorageException(std::string("Could not check storage directory permissions: ") + std::strerror(errno));
    }
    if ((st.st_mode & (S_IWGRP | S_IWOTH)) != 0) {
      throw StorageException("Storage directory has unsafe permissions");
    }
    if ((st.st_mode & (S_IRGRP | S_IROTH)) != 0) {
      // Remove read permissions for group and others
      if (chmod(db_parent_path.c_str(), S_IRWXU) < 0) {
        throw StorageException("Storage directory has unsafe permissions");
      }
    }
  }

  try {
    lock = StorageLock(db_parent_path / "storage.lock");
  } catch (StorageLock::locked_exception& e) {
    LOG_WARNING << "\033[31m"
                << "Storage in " << db_parent_path
                << " is already in use, running several instances concurrently may result in data corruption!"
                << "\033[0m";
  }

  if (!dbMigrate()) {
    throw StorageException("SQLite database migration failed");
  }
}

SQLite3Guard SQLStorageBase::dbConnection() const {
  SQLite3Guard db(dbPath(), readonly_);
  if (db.get_rc() != SQLITE_OK) {
    throw SQLException(std::string("Can't open database: ") + db.errmsg());
  }
  return db;
}<commit_msg>Do not detect concurrent storage in readonly mode<commit_after>#include "sqlstorage_base.h"
#include "storage_exception.h"

#include <sys/stat.h>

boost::filesystem::path SQLStorageBase::dbPath() const { return sqldb_path_; }

StorageLock::StorageLock(boost::filesystem::path path) : lock_path(std::move(path)) {
  {
    std::fstream fs;
    fs.open(lock_path.c_str(), std::fstream::in | std::fstream::out | std::fstream::app);
  }
  fl_ = lock_path.c_str();
  if (!fl_.try_lock()) {
    throw StorageLock::locked_exception();
  }
}

StorageLock::~StorageLock() {
  try {
    if (!lock_path.empty()) {
      fl_.unlock();
      std::remove(lock_path.c_str());
    }
  } catch (std::exception& e) {
  }
}

SQLStorageBase::SQLStorageBase(boost::filesystem::path sqldb_path, bool readonly,
                               std::vector<std::string> schema_migrations,
                               std::vector<std::string> schema_rollback_migrations, std::string current_schema,
                               int current_schema_version)
    : sqldb_path_(std::move(sqldb_path)),
      readonly_(readonly),
      schema_migrations_(std::move(schema_migrations)),
      schema_rollback_migrations_(std::move(schema_rollback_migrations)),
      current_schema_(std::move(current_schema)),
      current_schema_version_(current_schema_version) {
  boost::filesystem::path db_parent_path = dbPath().parent_path();
  if (!boost::filesystem::is_directory(db_parent_path)) {
    Utils::createDirectories(db_parent_path, S_IRWXU);
  } else {
    struct stat st {};
    if (stat(db_parent_path.c_str(), &st) < 0) {
      throw StorageException(std::string("Could not check storage directory permissions: ") + std::strerror(errno));
    }
    if ((st.st_mode & (S_IWGRP | S_IWOTH)) != 0) {
      throw StorageException("Storage directory has unsafe permissions");
    }
    if ((st.st_mode & (S_IRGRP | S_IROTH)) != 0) {
      // Remove read permissions for group and others
      if (chmod(db_parent_path.c_str(), S_IRWXU) < 0) {
        throw StorageException("Storage directory has unsafe permissions");
      }
    }
  }

  if (!readonly) {
    try {
      lock = StorageLock(db_parent_path / "storage.lock");
    } catch (StorageLock::locked_exception& e) {
      LOG_WARNING << "\033[31m"
                  << "Storage in " << db_parent_path
                  << " is already in use, running several instances concurrently may result in data corruption!"
                  << "\033[0m";
    }
  }

  if (!dbMigrate()) {
    throw StorageException("SQLite database migration failed");
  }
}

SQLite3Guard SQLStorageBase::dbConnection() const {
  SQLite3Guard db(dbPath(), readonly_);
  if (db.get_rc() != SQLITE_OK) {
    throw SQLException(std::string("Can't open database: ") + db.errmsg());
  }
  return db;
}
{'fraction_non_alphanumeric': 0.14125519985530838, 'fraction_numerical': 0.005425935973955507, 'mean_word_length': 3.5327868852459017, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '242412', 'n_tokens_mistral': 1788, 'n_tokens_neox': 1752, 'n_words': 325}