--- linuxsampler/trunk/src/db/InstrumentsDb.cpp 2007/12/31 10:17:51 1603 +++ linuxsampler/trunk/src/db/InstrumentsDb.cpp 2008/12/14 22:33:46 1810 @@ -1,6 +1,6 @@ /*************************************************************************** * * - * Copyright (C) 2007 Grigor Iliev * + * Copyright (C) 2007, 2008 Grigor Iliev * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -20,12 +20,13 @@ #include "InstrumentsDb.h" +#include "../common/File.h" +#include "../common/Path.h" #include "../common/global_private.h" #include #include #include -#include #include #include @@ -33,16 +34,15 @@ namespace LinuxSampler { - InstrumentsDb* InstrumentsDb::pInstrumentsDb = new InstrumentsDb; + InstrumentsDb InstrumentsDb::instance; - void InstrumentsDb::CreateInstrumentsDb(String File) { - struct stat statBuf; - int res = stat(File.c_str(), &statBuf); - if (!res) { - throw Exception("File exists: " + File); + void InstrumentsDb::CreateInstrumentsDb(String FilePath) { + File f = File(FilePath); + if (f.Exist()) { + throw Exception("File exists: " + FilePath); } - GetInstrumentsDb()->SetDbFile(File); + GetInstrumentsDb()->SetDbFile(FilePath); String sql = " CREATE TABLE instr_dirs ( " @@ -95,13 +95,6 @@ if (db != NULL) sqlite3_close(db); } - void InstrumentsDb::Destroy() { - if (pInstrumentsDb != NULL) { - delete pInstrumentsDb; - pInstrumentsDb = NULL; - } - } - void InstrumentsDb::AddInstrumentsDbListener(InstrumentsDb::Listener* l) { llInstrumentsDbListeners.AddListener(l); } @@ -111,7 +104,7 @@ } InstrumentsDb* InstrumentsDb::GetInstrumentsDb() { - return pInstrumentsDb; + return &instance; } void InstrumentsDb::SetDbFile(String File) { @@ -128,6 +121,10 @@ if ( db != NULL) return db; if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION; + #if defined(__APPLE__) /* 20071224 Toshi Nagata */ + if (DbFile.find("~") == 0) + DbFile.replace(0, 1, getenv("HOME")); + #endif int rc = sqlite3_open(DbFile.c_str(), &db); if (rc) { sqlite3_close(db); @@ -264,6 +261,13 @@ return ExecSqlInt(sql.str(), DirName); } + int InstrumentsDb::GetDirectoryId(int InstrId) { + dmsg(2,("InstrumentsDb: GetDirectoryId(InstrId=%d)\n", InstrId)); + std::stringstream sql; + sql << "SELECT dir_id FROM instruments WHERE instr_id=" << InstrId; + return ExecSqlInt(sql.str()); + } + String InstrumentsDb::GetDirectoryName(int DirId) { String sql = "SELECT dir_name FROM instr_dirs WHERE dir_id=" + ToString(DirId); String name = ExecSqlString(sql); @@ -288,7 +292,7 @@ path = "/" + path; break; } - path = GetDirectoryName(DirId) + path; + path = GetDirectoryName(DirId) + "/" + path; DirId = GetParentDirectoryId(DirId); } @@ -296,6 +300,30 @@ return path; } + + StringListPtr InstrumentsDb::GetInstrumentsByFile(String File) { + dmsg(2,("InstrumentsDb: GetInstrumentsByFile(File=%s)\n", File.c_str())); + + StringListPtr instrs(new std::vector); + + BeginTransaction(); + try { + File = toEscapedFsPath(File); + IntListPtr ids = ExecSqlIntList("SELECT instr_id FROM instruments WHERE instr_file=?", File); + + for (int i = 0; i < ids->size(); i++) { + String name = GetInstrumentName(ids->at(i)); + String dir = GetDirectoryPath(GetDirectoryId(ids->at(i))); + instrs->push_back(dir + name); + } + } catch (Exception e) { + EndTransaction(); + throw e; + } + EndTransaction(); + + return instrs; + } void InstrumentsDb::AddDirectory(String Dir) { dmsg(2,("InstrumentsDb: AddDirectory(Dir=%s)\n", Dir.c_str())); @@ -614,18 +642,18 @@ FireDirectoryInfoChanged(Dir); } - int InstrumentsDb::AddInstruments(ScanMode Mode, String DbDir, String FsDir, bool bBackground) { - dmsg(2,("InstrumentsDb: AddInstruments(Mode=%d,DbDir=%s,FsDir=%s,bBackground=%d)\n", Mode, DbDir.c_str(), FsDir.c_str(), bBackground)); + int InstrumentsDb::AddInstruments(ScanMode Mode, String DbDir, String FsDir, bool bBackground, bool insDir) { + dmsg(2,("InstrumentsDb: AddInstruments(Mode=%d,DbDir=%s,FsDir=%s,bBackground=%d,insDir=%d)\n", Mode, DbDir.c_str(), FsDir.c_str(), bBackground, insDir)); if(!bBackground) { switch (Mode) { case NON_RECURSIVE: - AddInstrumentsNonrecursive(DbDir, FsDir); + AddInstrumentsNonrecursive(DbDir, FsDir, insDir); break; case RECURSIVE: - AddInstrumentsRecursive(DbDir, FsDir); + AddInstrumentsRecursive(DbDir, FsDir, false, insDir); break; case FLAT: - AddInstrumentsRecursive(DbDir, FsDir, true); + AddInstrumentsRecursive(DbDir, FsDir, true, insDir); break; default: throw Exception("Unknown scan mode"); @@ -636,7 +664,7 @@ ScanJob job; int jobId = Jobs.AddJob(job); - InstrumentsDbThread.Execute(new AddInstrumentsJob(jobId, Mode, DbDir, FsDir)); + InstrumentsDbThread.Execute(new AddInstrumentsJob(jobId, Mode, DbDir, FsDir, insDir)); return jobId; } @@ -644,19 +672,19 @@ int InstrumentsDb::AddInstruments(String DbDir, String FilePath, int Index, bool bBackground) { dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,FilePath=%s,Index=%d,bBackground=%d)\n", DbDir.c_str(), FilePath.c_str(), Index, bBackground)); if(!bBackground) { - AddInstruments(DbDir, FilePath, Index); + AddInstruments(DbDir, false, FilePath, Index); return -1; } ScanJob job; int jobId = Jobs.AddJob(job); - InstrumentsDbThread.Execute(new AddInstrumentsFromFileJob(jobId, DbDir, FilePath, Index)); + InstrumentsDbThread.Execute(new AddInstrumentsFromFileJob(jobId, DbDir, FilePath, Index, false)); return jobId; - } + } - void InstrumentsDb::AddInstruments(String DbDir, String FilePath, int Index, ScanProgress* pProgress) { - dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,FilePath=%s,Index=%d)\n", DbDir.c_str(), FilePath.c_str(), Index)); + void InstrumentsDb::AddInstruments(String DbDir, bool insDir, String FilePath, int Index, ScanProgress* pProgress) { + dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,insDir=%d,FilePath=%s,Index=%d)\n", DbDir.c_str(), insDir, FilePath.c_str(), Index)); if (DbDir.empty() || FilePath.empty()) return; DbInstrumentsMutex.Lock(); @@ -664,21 +692,21 @@ int dirId = GetDirectoryId(DbDir); if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedText(DbDir)); - struct stat statBuf; - int res = stat(FilePath.c_str(), &statBuf); - if (res) { + File f = File(FilePath); + if (!f.Exist()) { std::stringstream ss; - ss << "Fail to stat `" << FilePath << "`: " << strerror(errno); + ss << "Fail to stat `" << FilePath << "`: " << f.GetErrorMsg(); throw Exception(ss.str()); } - if (!S_ISREG(statBuf.st_mode)) { + if (!f.IsFile()) { std::stringstream ss; ss << "`" << FilePath << "` is not an instrument file"; throw Exception(ss.str()); } - AddInstrumentsFromFile(DbDir, FilePath, Index, pProgress); + String dir = insDir ? PrepareSubdirectory(DbDir, FilePath) : DbDir; + AddInstrumentsFromFile(dir, FilePath, Index, pProgress); } catch (Exception e) { DbInstrumentsMutex.Unlock(); throw e; @@ -687,8 +715,8 @@ DbInstrumentsMutex.Unlock(); } - void InstrumentsDb::AddInstrumentsNonrecursive(String DbDir, String FsDir, ScanProgress* pProgress) { - dmsg(2,("InstrumentsDb: AddInstrumentsNonrecursive(DbDir=%s,FsDir=%s)\n", DbDir.c_str(), FsDir.c_str())); + void InstrumentsDb::AddInstrumentsNonrecursive(String DbDir, String FsDir, bool insDir, ScanProgress* pProgress) { + dmsg(2,("InstrumentsDb: AddInstrumentsNonrecursive(DbDir=%s,FsDir=%s,insDir=%d)\n", DbDir.c_str(), FsDir.c_str(), insDir)); if (DbDir.empty() || FsDir.empty()) return; DbInstrumentsMutex.Lock(); @@ -696,46 +724,31 @@ int dirId = GetDirectoryId(DbDir); if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir)); - struct stat statBuf; - int res = stat(FsDir.c_str(), &statBuf); - if (res) { + File f = File(FsDir); + if (!f.Exist()) { std::stringstream ss; - ss << "Fail to stat `" << FsDir << "`: " << strerror(errno); + ss << "Fail to stat `" << FsDir << "`: " << f.GetErrorMsg(); throw Exception(ss.str()); } - if (!S_ISDIR(statBuf.st_mode)) { - throw Exception("Directory expected"); + if (!f.IsDirectory()) { + throw Exception("Directory expected: " + FsDir); } - if (FsDir.at(FsDir.length() - 1) != '/') FsDir.append("/"); - - DIR* pDir = opendir(FsDir.c_str()); - if (pDir == NULL) { - std::stringstream ss; - ss << "The scanning of directory `" << FsDir << "` failed: "; - ss << strerror(errno); - std::cerr << ss.str(); - DbInstrumentsMutex.Unlock(); - return; + if (FsDir.at(FsDir.length() - 1) != File::DirSeparator) { + FsDir.push_back(File::DirSeparator); } - - struct dirent* pEnt = readdir(pDir); - while (pEnt != NULL) { - if (pEnt->d_type != DT_REG) { - pEnt = readdir(pDir); - continue; + + try { + FileListPtr fileList = File::GetFiles(FsDir); + for (int i = 0; i < fileList->size(); i++) { + String dir = insDir ? PrepareSubdirectory(DbDir, fileList->at(i)) : DbDir; + AddInstrumentsFromFile(dir, FsDir + fileList->at(i), -1, pProgress); } - - AddInstrumentsFromFile(DbDir, FsDir + String(pEnt->d_name), -1, pProgress); - pEnt = readdir(pDir); - } - - if (closedir(pDir)) { - std::stringstream ss; - ss << "Failed to close directory `" << FsDir << "`: "; - ss << strerror(errno); - std::cerr << ss.str(); + } catch(Exception e) { + e.PrintMessage(); + DbInstrumentsMutex.Unlock(); + return; } } catch (Exception e) { DbInstrumentsMutex.Unlock(); @@ -745,13 +758,15 @@ DbInstrumentsMutex.Unlock(); } - void InstrumentsDb::AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat, ScanProgress* pProgress) { - dmsg(2,("InstrumentsDb: AddInstrumentsRecursive(DbDir=%s,FsDir=%s,Flat=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat)); + void InstrumentsDb::AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat, bool insDir, ScanProgress* pProgress) { + dmsg(2,("InstrumentsDb: AddInstrumentsRecursive(DbDir=%s,FsDir=%s,Flat=%d,insDir=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat, insDir)); if (pProgress != NULL) { - pProgress->SetTotalFileCount(InstrumentFileCounter::Count(FsDir)); + InstrumentFileCounter c; + pProgress->SetTotalFileCount(c.Count(FsDir)); } - DirectoryScanner::Scan(DbDir, FsDir, Flat, pProgress); + DirectoryScanner d; + d.Scan(DbDir, FsDir, Flat, insDir, pProgress); } int InstrumentsDb::GetInstrumentCount(int DirId) { @@ -1140,33 +1155,32 @@ } } } catch(Exception e) { - std::cerr << e.Message() << std::endl; + e.PrintMessage(); } } - void InstrumentsDb::AddGigInstruments(String DbDir, String File, int Index, ScanProgress* pProgress) { - dmsg(2,("InstrumentsDb: AddGigInstruments(DbDir=%s,File=%s,Index=%d)\n", DbDir.c_str(), File.c_str(), Index)); + void InstrumentsDb::AddGigInstruments(String DbDir, String FilePath, int Index, ScanProgress* pProgress) { + dmsg(2,("InstrumentsDb: AddGigInstruments(DbDir=%s,FilePath=%s,Index=%d)\n", DbDir.c_str(), FilePath.c_str(), Index)); int dirId = GetDirectoryId(DbDir); if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir)); - struct stat statBuf; - int res = stat(File.c_str(), &statBuf); - if (res) { + File f = File(FilePath); + if (!f.Exist()) { std::stringstream ss; - ss << "Fail to stat `" << File << "`: " << strerror(errno); + ss << "Fail to stat `" << FilePath << "`: " << f.GetErrorMsg(); throw Exception(ss.str()); } - if (!S_ISREG(statBuf.st_mode)) { + if (!f.IsFile()) { std::stringstream ss; - ss << "`" << File << "` is not a regular file"; + ss << "`" << FilePath << "` is not a regular file"; throw Exception(ss.str()); } RIFF::File* riff = NULL; gig::File* gig = NULL; try { - riff = new RIFF::File(File); + riff = new RIFF::File(FilePath); gig::File* gig = new gig::File(riff); gig->SetAutoLoad(false); // avoid time consuming samples scanning @@ -1174,7 +1188,7 @@ sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,"; sql << "instr_nr,format_family,format_version,instr_size,"; sql << "description,is_drum,product,artists,keywords) VALUES ("; - sql << dirId << ",?,?,?,'GIG',?," << statBuf.st_size << ",?,?,?,?,?)"; + sql << dirId << ",?,?,?,'GIG',?," << f.GetSize() << ",?,?,?,?,?)"; sqlite3_stmt* pStmt = NULL; @@ -1183,7 +1197,7 @@ throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); } - String s = toEscapedFsPath(File); + String s = toEscapedFsPath(FilePath); BindTextParam(pStmt, 2, s); String ver = ""; if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major); @@ -1197,7 +1211,7 @@ BindTextParam(pStmt, 7, gig->pInfo->Product); BindTextParam(pStmt, 8, gig->pInfo->Artists); BindTextParam(pStmt, 9, gig->pInfo->Keywords); - AddGigInstrument(pStmt, DbDir, dirId, File, pInstrument, instrIndex); + AddGigInstrument(pStmt, DbDir, dirId, FilePath, pInstrument, instrIndex); instrIndex++; pInstrument = gig->GetNextInstrument(); @@ -1210,7 +1224,7 @@ BindTextParam(pStmt, 7, gig->pInfo->Product); BindTextParam(pStmt, 8, gig->pInfo->Artists); BindTextParam(pStmt, 9, gig->pInfo->Keywords); - AddGigInstrument(pStmt, DbDir, dirId, File, pInstrument, Index); + AddGigInstrument(pStmt, DbDir, dirId, FilePath, pInstrument, Index); } } @@ -1221,7 +1235,7 @@ if (gig != NULL) delete gig; if (riff != NULL) delete riff; std::stringstream ss; - ss << "Failed to scan `" << File << "`: " << e.Message; + ss << "Failed to scan `" << FilePath << "`: " << e.Message; throw Exception(ss.str()); } catch (Exception e) { @@ -1231,14 +1245,15 @@ } catch (...) { if (gig != NULL) delete gig; if (riff != NULL) delete riff; - throw Exception("Failed to scan `" + File + "`"); + throw Exception("Failed to scan `" + FilePath + "`"); } } void InstrumentsDb::AddGigInstrument(sqlite3_stmt* pStmt, String DbDir, int DirId, String File, gig::Instrument* pInstrument, int Index) { + dmsg(2,("InstrumentsDb: AddGigInstrument(DbDir=%s,DirId=%d,File=%s,Index=%d)\n", DbDir.c_str(), DirId, File.c_str(), Index)); String name = pInstrument->pInfo->Name; if (name == "") return; - name = GetUniqueInstrumentName(DirId, name); + name = GetUniqueName(DirId, name); std::stringstream sql2; sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND "; @@ -1334,6 +1349,46 @@ return instrumentFinder.GetInstruments(); } + + StringListPtr InstrumentsDb::FindLostInstrumentFiles() { + dmsg(2,("InstrumentsDb: FindLostInstrumentFiles()\n")); + + BeginTransaction(); + try { + StringListPtr files = ExecSqlStringList("SELECT DISTINCT instr_file FROM instruments"); + StringListPtr result(new std::vector); + for (int i = 0; i < files->size(); i++) { + File f(toNonEscapedFsPath(files->at(i))); + if (!f.Exist()) result->push_back(files->at(i)); + } + return result; + } catch (Exception e) { + EndTransaction(); + throw e; + } + EndTransaction(); + } + + void InstrumentsDb::SetInstrumentFilePath(String OldPath, String NewPath) { + if (OldPath == NewPath) return; + StringListPtr instrs; + BeginTransaction(); + try { + std::vector params(2); + params[0] = toEscapedFsPath(NewPath); + params[1] = toEscapedFsPath(OldPath); + instrs = GetInstrumentsByFile(OldPath); + ExecSql("UPDATE instruments SET instr_file=? WHERE instr_file=?", params); + } catch (Exception e) { + EndTransaction(); + throw e; + } + EndTransaction(); + + for (int i = 0; i < instrs->size(); i++) { + FireInstrumentInfoChanged(instrs->at(i)); + } + } void InstrumentsDb::BeginTransaction() { dmsg(2,("InstrumentsDb: BeginTransaction(InTransaction=%d)\n", InTransaction)); @@ -1395,24 +1450,19 @@ void InstrumentsDb::ExecSql(String Sql) { dmsg(2,("InstrumentsDb: ExecSql(Sql=%s)\n", Sql.c_str())); - sqlite3_stmt *pStmt = NULL; - - int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL); - if (res != SQLITE_OK) { - throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); - } - - res = sqlite3_step(pStmt); - if(res != SQLITE_DONE) { - sqlite3_finalize(pStmt); - throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); - } - - sqlite3_finalize(pStmt); + std::vector Params; + ExecSql(Sql, Params); } void InstrumentsDb::ExecSql(String Sql, String Param) { dmsg(2,("InstrumentsDb: ExecSql(Sql=%s,Param=%s)\n", Sql.c_str(), Param.c_str())); + std::vector Params; + Params.push_back(Param); + ExecSql(Sql, Params); + } + + void InstrumentsDb::ExecSql(String Sql, std::vector& Params) { + dmsg(2,("InstrumentsDb: ExecSql(Sql=%s,Params)\n", Sql.c_str())); sqlite3_stmt *pStmt = NULL; int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL); @@ -1421,7 +1471,9 @@ throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); } - BindTextParam(pStmt, 1, Param); + for(int i = 0; i < Params.size(); i++) { + BindTextParam(pStmt, i + 1, Params[i]); + } res = sqlite3_step(pStmt); if (res != SQLITE_DONE) { @@ -1503,6 +1555,20 @@ } IntListPtr InstrumentsDb::ExecSqlIntList(String Sql) { + dmsg(2,("InstrumentsDb: ExecSqlIntList(Sql=%s)\n", Sql.c_str())); + std::vector Params; + return ExecSqlIntList(Sql, Params); + } + + IntListPtr InstrumentsDb::ExecSqlIntList(String Sql, String Param) { + dmsg(2,("InstrumentsDb: ExecSqlIntList(Sql=%s,Param=%s)\n", Sql.c_str(), Param.c_str())); + std::vector Params; + Params.push_back(Param); + return ExecSqlIntList(Sql, Params); + } + + IntListPtr InstrumentsDb::ExecSqlIntList(String Sql, std::vector& Params) { + dmsg(2,("InstrumentsDb: ExecSqlIntList(Sql=%s)\n", Sql.c_str())); IntListPtr intList(new std::vector); sqlite3_stmt *pStmt = NULL; @@ -1512,6 +1578,10 @@ throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); } + for(int i = 0; i < Params.size(); i++) { + BindTextParam(pStmt, i + 1, Params[i]); + } + res = sqlite3_step(pStmt); while(res == SQLITE_ROW) { intList->push_back(sqlite3_column_int(pStmt, 0)); @@ -1529,6 +1599,7 @@ } StringListPtr InstrumentsDb::ExecSqlStringList(String Sql) { + dmsg(2,("InstrumentsDb: ExecSqlStringList(Sql=%s)\n", Sql.c_str())); StringListPtr stringList(new std::vector); sqlite3_stmt *pStmt = NULL; @@ -1656,7 +1727,7 @@ if (File.empty()) throw Exception("Invalid file name: " + File); } - String InstrumentsDb::GetUniqueInstrumentName(int DirId, String Name) { + String InstrumentsDb::GetUniqueName(int DirId, String Name) { dmsg(2,("InstrumentsDb: GetUniqueInstrumentName(DirId=%d,Name=%s)\n", DirId, Name.c_str())); if (GetInstrumentId(DirId, Name) == -1 && GetDirectoryId(DirId, Name) == -1) return Name; @@ -1671,6 +1742,22 @@ throw Exception("Unable to find an unique name: " + Name); } + + String InstrumentsDb::PrepareSubdirectory(String DbDir, String FsPath) { + std::string dir = Path::getBaseName(FsPath); + dir = toAbstractName(dir); + if(dir.empty()) dir = "New Directory"; + dir = GetUniqueName(GetDirectoryId(DbDir), dir); + dir = AppendNode(DbDir, dir); + AddDirectory(dir); + return dir; + } + + String InstrumentsDb::AppendNode(String DbDir, String Node) { + if(DbDir.length() == 1 && DbDir.at(0) == '/') return DbDir + Node; + if(DbDir.at(DbDir.length() - 1) == '/') return DbDir + Node; + return DbDir + "/" + Node; + } String InstrumentsDb::toDbName(String AbstractName) { for (int i = 0; i < AbstractName.length(); i++) { @@ -1702,10 +1789,37 @@ return text; } + String InstrumentsDb::toNonEscapedText(String text) { + String sb; + for (int i = 0; i < text.length(); i++) { + char c = text.at(i); + if(c == '\\') { + if(i >= text.length()) { + std::cerr << "Broken escape sequence!" << std::endl; + break; + } + char c2 = text.at(++i); + if(c2 == '\'') sb.push_back('\''); + else if(c2 == '"') sb.push_back('"'); + else if(c2 == '\\') sb.push_back('\\'); + else if(c2 == 'r') sb.push_back('\r'); + else if(c2 == 'n') sb.push_back('\n'); + else std::cerr << "Unknown escape sequence \\" << c2 << std::endl; + } else { + sb.push_back(c); + } + } + return sb; + } + String InstrumentsDb::toEscapedFsPath(String FsPath) { return toEscapedText(FsPath); } + String InstrumentsDb::toNonEscapedFsPath(String FsPath) { + return toNonEscapedText(FsPath); + } + String InstrumentsDb::toAbstractName(String DbName) { for (int i = 0; i < DbName.length(); i++) { if (DbName.at(i) == '/') DbName.at(i) = '\0';