Allow RenameFile to overwrite existing files

custom
jacqueline 2 years ago
parent 7972bd4567
commit 2be4d4204c
  1. 2
      src/database/database.cpp
  2. 88
      src/database/env_esp.cpp
  3. 18
      src/main/main.cpp

@ -23,7 +23,7 @@ auto Database::Open() -> cpp::result<Database*, DatabaseError> {
auto status = leveldb::DB::Open(options, "/.db", &db); auto status = leveldb::DB::Open(options, "/.db", &db);
if (!status.ok()) { if (!status.ok()) {
delete cache; delete cache;
ESP_LOGE("DB", "failed to open db"); ESP_LOGE("DB", "failed to open db, status %s", status.ToString().c_str());
return cpp::fail(FAILED_TO_OPEN); return cpp::fail(FAILED_TO_OPEN);
} }

@ -230,7 +230,6 @@ class EspFileLock : public FileLock {
const std::string filename_; const std::string filename_;
}; };
class EspLogger final : public Logger { class EspLogger final : public Logger {
public: public:
explicit EspLogger(FIL file) : file_(file) {} explicit EspLogger(FIL file) : file_(file) {}
@ -247,8 +246,8 @@ class EspLogger final : public Logger {
snprintf(output, bytes_needed, format, args_copy); snprintf(output, bytes_needed, format, args_copy);
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
va_end(args_copy); va_end(args_copy);
ESP_LOGV("LEVELDB", "%s", output); ESP_LOGI("LEVELDB", "%s", output);
//f_puts(output, &file_); // f_puts(output, &file_);
free(reinterpret_cast<void*>(output)); free(reinterpret_cast<void*>(output));
} }
@ -256,11 +255,11 @@ class EspLogger final : public Logger {
FIL file_; FIL file_;
}; };
EspEnv::~EspEnv() { EspEnv::~EspEnv() {
ESP_LOGE("LEVELDB", "EspEnv singleton destroyed. Unsupported behavior!"); ESP_LOGE("LEVELDB", "EspEnv singleton destroyed. Unsupported behavior!");
} }
Status EspEnv::NewSequentialFile(const std::string& filename, Status EspEnv::NewSequentialFile(const std::string& filename,
SequentialFile** result) { SequentialFile** result) {
FIL file; FIL file;
FRESULT res = f_open(&file, filename.c_str(), FA_READ); FRESULT res = f_open(&file, filename.c_str(), FA_READ);
@ -271,9 +270,9 @@ class EspLogger final : public Logger {
*result = new EspSequentialFile(filename, file); *result = new EspSequentialFile(filename, file);
return Status::OK(); return Status::OK();
} }
Status EspEnv::NewRandomAccessFile(const std::string& filename, Status EspEnv::NewRandomAccessFile(const std::string& filename,
RandomAccessFile** result) { RandomAccessFile** result) {
// EspRandomAccessFile doesn't try to open the file until it's needed, so // EspRandomAccessFile doesn't try to open the file until it's needed, so
// we need to first ensure the file exists to handle the NotFound case // we need to first ensure the file exists to handle the NotFound case
@ -287,9 +286,9 @@ class EspLogger final : public Logger {
*result = new EspRandomAccessFile(filename); *result = new EspRandomAccessFile(filename);
return Status::OK(); return Status::OK();
} }
Status EspEnv::NewWritableFile(const std::string& filename, Status EspEnv::NewWritableFile(const std::string& filename,
WritableFile** result) { WritableFile** result) {
FIL file; FIL file;
FRESULT res = f_open(&file, filename.c_str(), FA_WRITE | FA_CREATE_ALWAYS); FRESULT res = f_open(&file, filename.c_str(), FA_WRITE | FA_CREATE_ALWAYS);
@ -300,9 +299,9 @@ class EspLogger final : public Logger {
*result = new EspWritableFile(filename, file); *result = new EspWritableFile(filename, file);
return Status::OK(); return Status::OK();
} }
Status EspEnv::NewAppendableFile(const std::string& filename, Status EspEnv::NewAppendableFile(const std::string& filename,
WritableFile** result) { WritableFile** result) {
FIL file; FIL file;
FRESULT res = f_open(&file, filename.c_str(), FA_WRITE | FA_OPEN_APPEND); FRESULT res = f_open(&file, filename.c_str(), FA_WRITE | FA_OPEN_APPEND);
@ -313,14 +312,14 @@ class EspLogger final : public Logger {
*result = new EspWritableFile(filename, file); *result = new EspWritableFile(filename, file);
return Status::OK(); return Status::OK();
} }
bool EspEnv::FileExists(const std::string& filename) { bool EspEnv::FileExists(const std::string& filename) {
FILINFO info; FILINFO info;
return f_stat(filename.c_str(), &info) == FR_OK; return f_stat(filename.c_str(), &info) == FR_OK;
} }
Status EspEnv::GetChildren(const std::string& directory_path, Status EspEnv::GetChildren(const std::string& directory_path,
std::vector<std::string>* result) { std::vector<std::string>* result) {
result->clear(); result->clear();
@ -348,29 +347,29 @@ class EspLogger final : public Logger {
} }
return Status::OK(); return Status::OK();
} }
Status EspEnv::RemoveFile(const std::string& filename) { Status EspEnv::RemoveFile(const std::string& filename) {
FRESULT res = f_unlink(filename.c_str()); FRESULT res = f_unlink(filename.c_str());
if (res != FR_OK) { if (res != FR_OK) {
return EspError(filename, res); return EspError(filename, res);
} }
return Status::OK(); return Status::OK();
} }
Status EspEnv::CreateDir(const std::string& dirname) { Status EspEnv::CreateDir(const std::string& dirname) {
FRESULT res = f_mkdir(dirname.c_str()); FRESULT res = f_mkdir(dirname.c_str());
if (res != FR_OK) { if (res != FR_OK) {
return EspError(dirname, res); return EspError(dirname, res);
} }
return Status::OK(); return Status::OK();
} }
Status EspEnv::RemoveDir(const std::string& dirname) { Status EspEnv::RemoveDir(const std::string& dirname) {
return RemoveFile(dirname); return RemoveFile(dirname);
} }
Status EspEnv::GetFileSize(const std::string& filename, uint64_t* size) { Status EspEnv::GetFileSize(const std::string& filename, uint64_t* size) {
FILINFO info; FILINFO info;
FRESULT res = f_stat(filename.c_str(), &info); FRESULT res = f_stat(filename.c_str(), &info);
if (res != FR_OK) { if (res != FR_OK) {
@ -379,17 +378,24 @@ class EspLogger final : public Logger {
} }
*size = info.fsize; *size = info.fsize;
return Status::OK(); return Status::OK();
} }
Status EspEnv::RenameFile(const std::string& from, const std::string& to) { Status EspEnv::RenameFile(const std::string& from, const std::string& to) {
// Match the POSIX behaviour of replacing any existing file.
if (FileExists(to)) {
Status s = RemoveFile(to);
if (!s.ok()) {
return s;
}
}
FRESULT res = f_rename(from.c_str(), to.c_str()); FRESULT res = f_rename(from.c_str(), to.c_str());
if (res != FR_OK) { if (res != FR_OK) {
return EspError(from, res); return EspError(from, res);
} }
return Status::OK(); return Status::OK();
} }
Status EspEnv::LockFile(const std::string& filename, FileLock** lock) { Status EspEnv::LockFile(const std::string& filename, FileLock** lock) {
*lock = nullptr; *lock = nullptr;
if (!locks_.Insert(filename)) { if (!locks_.Insert(filename)) {
@ -398,28 +404,28 @@ class EspLogger final : public Logger {
*lock = new EspFileLock(filename); *lock = new EspFileLock(filename);
return Status::OK(); return Status::OK();
} }
Status EspEnv::UnlockFile(FileLock* lock) { Status EspEnv::UnlockFile(FileLock* lock) {
EspFileLock* posix_file_lock = static_cast<EspFileLock*>(lock); EspFileLock* posix_file_lock = static_cast<EspFileLock*>(lock);
locks_.Remove(posix_file_lock->filename()); locks_.Remove(posix_file_lock->filename());
delete posix_file_lock; delete posix_file_lock;
return Status::OK(); return Status::OK();
} }
void EspEnv::StartThread(void (*thread_main)(void* thread_main_arg), void EspEnv::StartThread(void (*thread_main)(void* thread_main_arg),
void* thread_main_arg) { void* thread_main_arg) {
std::thread new_thread(thread_main, thread_main_arg); std::thread new_thread(thread_main, thread_main_arg);
new_thread.detach(); new_thread.detach();
} }
Status EspEnv::GetTestDirectory(std::string* result) { Status EspEnv::GetTestDirectory(std::string* result) {
CreateDir("/tmp"); CreateDir("/tmp");
*result = "/tmp"; *result = "/tmp";
return Status::OK(); return Status::OK();
} }
Status EspEnv::NewLogger(const std::string& filename, Logger** result) { Status EspEnv::NewLogger(const std::string& filename, Logger** result) {
FIL file; FIL file;
FRESULT res = f_open(&file, filename.c_str(), FA_WRITE | FA_OPEN_APPEND); FRESULT res = f_open(&file, filename.c_str(), FA_WRITE | FA_OPEN_APPEND);
if (res != FR_OK) { if (res != FR_OK) {
@ -429,17 +435,17 @@ class EspLogger final : public Logger {
*result = new EspLogger(file); *result = new EspLogger(file);
return Status::OK(); return Status::OK();
} }
uint64_t EspEnv::NowMicros() { uint64_t EspEnv::NowMicros() {
struct timeval tv_now; struct timeval tv_now;
gettimeofday(&tv_now, NULL); gettimeofday(&tv_now, NULL);
return (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec; return (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec;
} }
void EspEnv::SleepForMicroseconds(int micros) { void EspEnv::SleepForMicroseconds(int micros) {
vTaskDelay(pdMS_TO_TICKS(micros / 1000)); vTaskDelay(pdMS_TO_TICKS(micros / 1000));
} }
extern "C" void BackgroundThreadEntryPoint(EspEnv* env) { extern "C" void BackgroundThreadEntryPoint(EspEnv* env) {
env->BackgroundThreadMain(); env->BackgroundThreadMain();

@ -37,15 +37,17 @@
static const char* TAG = "MAIN"; static const char* TAG = "MAIN";
void db_main(void *whatever) { void db_main(void* whatever) {
ESP_LOGI(TAG, "Init database"); ESP_LOGI(TAG, "Init database");
std::unique_ptr<database::Database> db;
auto db_res = database::Database::Open(); auto db_res = database::Database::Open();
if (db_res.has_error()) { if (db_res.has_error()) {
ESP_LOGE(TAG, "Failed!"); ESP_LOGE(TAG, "database failed :(");
} else {
db.reset(db_res.value());
ESP_LOGI(TAG, "database good :)");
} }
std::unique_ptr<database::Database> db(db_res.value());
ESP_LOGI(TAG, "database good :)");
vTaskDelay(pdMS_TO_TICKS(10000)); vTaskDelay(pdMS_TO_TICKS(10000));
vTaskDelete(NULL); vTaskDelete(NULL);
@ -79,9 +81,10 @@ extern "C" void app_main(void) {
ESP_LOGI(TAG, "Launch database task"); ESP_LOGI(TAG, "Launch database task");
std::size_t db_stack_size = 256 * 1024; std::size_t db_stack_size = 256 * 1024;
StaticTask_t database_task_buffer = {}; StaticTask_t database_task_buffer = {};
StackType_t *database_stack = StackType_t* database_stack = reinterpret_cast<StackType_t*>(
reinterpret_cast<StackType_t*>(heap_caps_malloc(db_stack_size, MALLOC_CAP_SPIRAM)); heap_caps_malloc(db_stack_size, MALLOC_CAP_SPIRAM));
xTaskCreateStatic(&db_main, "LEVELDB", db_stack_size, NULL, 1, database_stack, &database_task_buffer); xTaskCreateStatic(&db_main, "LEVELDB", db_stack_size, NULL, 1, database_stack,
&database_task_buffer);
ESP_LOGI(TAG, "Init touch wheel"); ESP_LOGI(TAG, "Init touch wheel");
std::shared_ptr<drivers::TouchWheel> touchwheel = std::shared_ptr<drivers::TouchWheel> touchwheel =
@ -115,4 +118,3 @@ extern "C" void app_main(void) {
vTaskDelay(pdMS_TO_TICKS(100)); vTaskDelay(pdMS_TO_TICKS(100));
} }
} }

Loading…
Cancel
Save