1 |
/*************************************************************************** |
/*************************************************************************** |
2 |
* * |
* * |
3 |
* Copyright (C) 2007-2009 Grigor Iliev, Benno Senoner * |
* Copyright (C) 2007-2013 Grigor Iliev, Benno Senoner * |
4 |
* * |
* * |
5 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
6 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
41 |
InstrumentsDb InstrumentsDb::instance; |
InstrumentsDb InstrumentsDb::instance; |
42 |
|
|
43 |
void InstrumentsDb::CreateInstrumentsDb(String FilePath) { |
void InstrumentsDb::CreateInstrumentsDb(String FilePath) { |
44 |
|
if (FilePath.empty()) { |
45 |
|
FilePath = GetDefaultDBLocation(); |
46 |
|
dmsg(0,("InstrumentsDb: Creating database at default location '%s'\n", FilePath.c_str())); |
47 |
|
} |
48 |
|
|
49 |
File f = File(FilePath); |
File f = File(FilePath); |
50 |
if (f.Exist()) { |
if (f.Exist()) { |
51 |
throw Exception("File exists: " + FilePath); |
throw Exception("File exists: " + FilePath); |
52 |
} |
} |
53 |
|
|
54 |
GetInstrumentsDb()->SetDbFile(FilePath); |
SetDbFile(FilePath); |
55 |
|
|
56 |
String sql = |
String sql = |
57 |
" CREATE TABLE instr_dirs ( " |
" CREATE TABLE instr_dirs ( " |
65 |
" UNIQUE (parent_dir_id,dir_name) " |
" UNIQUE (parent_dir_id,dir_name) " |
66 |
" ); "; |
" ); "; |
67 |
|
|
68 |
GetInstrumentsDb()->ExecSql(sql); |
ExecSql(sql); |
69 |
|
|
70 |
sql = "INSERT INTO instr_dirs (dir_id, parent_dir_id, dir_name) VALUES (0, -2, '/');"; |
sql = "INSERT INTO instr_dirs (dir_id, parent_dir_id, dir_name) VALUES (0, -2, '/');"; |
71 |
GetInstrumentsDb()->ExecSql(sql); |
ExecSql(sql); |
72 |
|
|
73 |
sql = |
sql = |
74 |
" CREATE TABLE instruments ( " |
" CREATE TABLE instruments ( " |
91 |
" UNIQUE (dir_id,instr_name) " |
" UNIQUE (dir_id,instr_name) " |
92 |
" ); "; |
" ); "; |
93 |
|
|
94 |
GetInstrumentsDb()->ExecSql(sql); |
ExecSql(sql); |
95 |
} |
} |
96 |
|
|
97 |
InstrumentsDb::InstrumentsDb() { |
InstrumentsDb::InstrumentsDb() { |
116 |
} |
} |
117 |
|
|
118 |
void InstrumentsDb::SetDbFile(String File) { |
void InstrumentsDb::SetDbFile(String File) { |
119 |
DbInstrumentsMutex.Lock(); |
LockGuard lock(DbInstrumentsMutex); |
120 |
if (File.empty() || DbFile.length() > 0) { |
if (File.empty() || DbFile.length() > 0) { |
|
DbInstrumentsMutex.Unlock(); |
|
121 |
throw Exception("Failed to set the database file"); |
throw Exception("Failed to set the database file"); |
122 |
} |
} |
123 |
DbFile = File; |
DbFile = File; |
|
DbInstrumentsMutex.Unlock(); |
|
124 |
} |
} |
125 |
|
|
126 |
sqlite3* InstrumentsDb::GetDb() { |
String InstrumentsDb::GetDefaultDBLocation() { |
127 |
if ( db != NULL) return db; |
#ifdef WIN32 |
128 |
|
char* userprofile = getenv("USERPROFILE"); |
129 |
|
if (userprofile) { |
130 |
|
String s = userprofile; |
131 |
|
s += "\\.linuxsampler\\instruments.db"; |
132 |
|
return s; |
133 |
|
} else { |
134 |
|
// in case USERPROFILE is not set (which should not occur) |
135 |
|
return "instruments.db"; |
136 |
|
} |
137 |
|
#else // POSIX ... |
138 |
|
String s = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION; |
139 |
|
# if defined(__APPLE__) |
140 |
|
if (s.find("~") == 0) |
141 |
|
s.replace(0, 1, getenv("HOME")); |
142 |
|
# endif |
143 |
|
return s; |
144 |
|
#endif |
145 |
|
} |
146 |
|
|
147 |
if (DbFile.empty()) { |
void InstrumentsDb::EnsureDBFileExists() { |
148 |
#ifndef WIN32 |
if (DbFile.empty()) |
149 |
DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION; |
DbFile = GetDefaultDBLocation(); |
|
#else |
|
|
char *userprofile = getenv("USERPROFILE"); |
|
|
if(userprofile) { |
|
|
String DbPath = userprofile; |
|
|
DbPath += "\\.linuxsampler"; |
|
|
DbFile = DbPath + "\\instruments.db"; |
|
|
File InstrumentsDbFile(DbFile); |
|
|
// if no DB exists create the subdir and then the DB |
|
|
if( !InstrumentsDbFile.Exist() ) { |
|
|
_mkdir( DbPath.c_str() ); |
|
|
// formats the DB, which creates a new instruments.db file |
|
|
Format(); |
|
|
} |
|
|
} |
|
|
else { |
|
|
// in case USERPROFILE is not set (which should not occur) |
|
|
DbFile = "instruments.db"; |
|
|
} |
|
|
#endif |
|
|
} |
|
150 |
#if defined(__APPLE__) /* 20071224 Toshi Nagata */ |
#if defined(__APPLE__) /* 20071224 Toshi Nagata */ |
151 |
if (DbFile.find("~") == 0) |
if (DbFile.find("~") == 0) |
152 |
DbFile.replace(0, 1, getenv("HOME")); |
DbFile.replace(0, 1, getenv("HOME")); |
153 |
#endif |
#endif |
154 |
|
Path DbPath(DbFile); |
155 |
|
String DbDir = DbPath.stripLastName(); |
156 |
|
// create directory if it does not exist yet |
157 |
|
if (!DbPath.nodes().empty()) { |
158 |
|
File d(DbDir); |
159 |
|
if (!d.Exist()) { |
160 |
|
#ifdef WIN32 |
161 |
|
if (_mkdir(DbDir.c_str())) |
162 |
|
throw Exception("Could not create instruments DB directory '" + DbDir + "'"); |
163 |
|
#else |
164 |
|
if (mkdir(DbDir.c_str(), S_IRWXU)) |
165 |
|
throw Exception("Could not create instruments DB directory '" + DbDir + "'"); |
166 |
|
#endif |
167 |
|
} |
168 |
|
} |
169 |
|
// create database file if it does not exist yet |
170 |
|
File f(DbFile); |
171 |
|
if (!f.Exist()) { |
172 |
|
// formats the DB, which creates a new instruments.db file |
173 |
|
Format(); |
174 |
|
} |
175 |
|
} |
176 |
|
|
177 |
|
sqlite3* InstrumentsDb::GetDb() { |
178 |
|
if ( db != NULL) return db; |
179 |
|
|
180 |
|
if (DbFile.empty()) |
181 |
|
DbFile = GetDefaultDBLocation(); |
182 |
|
|
183 |
|
{ |
184 |
|
// first check if the instruments DB's directory exists, if not give up |
185 |
|
Path path(DbFile); |
186 |
|
String sDir = path.stripLastName(); |
187 |
|
File d(sDir); |
188 |
|
if (!d.Exist()) |
189 |
|
throw Exception("Instruments DB directory '" + sDir + "' does not exist!"); |
190 |
|
|
191 |
|
// just to give the user a notice about the DB file being created in case it does not exist yet |
192 |
|
File f(DbFile); |
193 |
|
if (!f.Exist()) |
194 |
|
dmsg(0,("Instruments DB file '%s' does not exist yet. Trying to create it now.\n", DbFile.c_str())); |
195 |
|
} |
196 |
|
|
197 |
|
dmsg(0,("Opening instruments DB at '%s'\n", DbFile.c_str())); |
198 |
int rc = sqlite3_open(DbFile.c_str(), &db); |
int rc = sqlite3_open(DbFile.c_str(), &db); |
199 |
if (rc) { |
if (rc) { |
200 |
sqlite3_close(db); |
sqlite3_close(db); |
509 |
|
|
510 |
bool InstrumentsDb::DirectoryExist(String Dir) { |
bool InstrumentsDb::DirectoryExist(String Dir) { |
511 |
dmsg(2,("InstrumentsDb: DirectoryExist(Dir=%s)\n", Dir.c_str())); |
dmsg(2,("InstrumentsDb: DirectoryExist(Dir=%s)\n", Dir.c_str())); |
512 |
bool b; |
{ |
513 |
|
LockGuard lock(DbInstrumentsMutex); |
514 |
DbInstrumentsMutex.Lock(); |
return GetDirectoryId(Dir) != -1; |
|
try { b = GetDirectoryId(Dir) != -1; } |
|
|
catch (Exception e) { |
|
|
DbInstrumentsMutex.Unlock(); |
|
|
throw e; |
|
515 |
} |
} |
|
DbInstrumentsMutex.Unlock(); |
|
|
|
|
|
return b; |
|
516 |
} |
} |
517 |
|
|
518 |
DbDirectory InstrumentsDb::GetDirectoryInfo(String Dir) { |
DbDirectory InstrumentsDb::GetDirectoryInfo(String Dir) { |
752 |
dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,insDir=%d,FilePath=%s,Index=%d)\n", DbDir.c_str(), insDir, FilePath.c_str(), Index)); |
dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,insDir=%d,FilePath=%s,Index=%d)\n", DbDir.c_str(), insDir, FilePath.c_str(), Index)); |
753 |
if (DbDir.empty() || FilePath.empty()) return; |
if (DbDir.empty() || FilePath.empty()) return; |
754 |
|
|
755 |
DbInstrumentsMutex.Lock(); |
{ |
756 |
try { |
LockGuard lock(DbInstrumentsMutex); |
757 |
|
|
758 |
int dirId = GetDirectoryId(DbDir); |
int dirId = GetDirectoryId(DbDir); |
759 |
if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedText(DbDir)); |
if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedText(DbDir)); |
760 |
|
|
773 |
|
|
774 |
String dir = insDir ? PrepareSubdirectory(DbDir, FilePath) : DbDir; |
String dir = insDir ? PrepareSubdirectory(DbDir, FilePath) : DbDir; |
775 |
AddInstrumentsFromFile(dir, FilePath, Index, pProgress); |
AddInstrumentsFromFile(dir, FilePath, Index, pProgress); |
|
} catch (Exception e) { |
|
|
DbInstrumentsMutex.Unlock(); |
|
|
throw e; |
|
776 |
} |
} |
|
|
|
|
DbInstrumentsMutex.Unlock(); |
|
777 |
} |
} |
778 |
|
|
779 |
void InstrumentsDb::AddInstrumentsNonrecursive(String DbDir, String FsDir, bool insDir, ScanProgress* pProgress) { |
void InstrumentsDb::AddInstrumentsNonrecursive(String DbDir, String FsDir, bool insDir, ScanProgress* pProgress) { |
780 |
dmsg(2,("InstrumentsDb: AddInstrumentsNonrecursive(DbDir=%s,FsDir=%s,insDir=%d)\n", DbDir.c_str(), FsDir.c_str(), insDir)); |
dmsg(2,("InstrumentsDb: AddInstrumentsNonrecursive(DbDir=%s,FsDir=%s,insDir=%d)\n", DbDir.c_str(), FsDir.c_str(), insDir)); |
781 |
if (DbDir.empty() || FsDir.empty()) return; |
if (DbDir.empty() || FsDir.empty()) return; |
782 |
|
|
783 |
DbInstrumentsMutex.Lock(); |
{ |
784 |
try { |
LockGuard lock(DbInstrumentsMutex); |
785 |
|
|
786 |
int dirId = GetDirectoryId(DbDir); |
int dirId = GetDirectoryId(DbDir); |
787 |
if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir)); |
if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir)); |
788 |
|
|
809 |
} |
} |
810 |
} catch(Exception e) { |
} catch(Exception e) { |
811 |
e.PrintMessage(); |
e.PrintMessage(); |
|
DbInstrumentsMutex.Unlock(); |
|
|
return; |
|
812 |
} |
} |
|
} catch (Exception e) { |
|
|
DbInstrumentsMutex.Unlock(); |
|
|
throw e; |
|
813 |
} |
} |
|
|
|
|
DbInstrumentsMutex.Unlock(); |
|
814 |
} |
} |
815 |
|
|
816 |
void InstrumentsDb::AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat, bool insDir, ScanProgress* pProgress) { |
void InstrumentsDb::AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat, bool insDir, ScanProgress* pProgress) { |
1191 |
FireInstrumentInfoChanged(Instr); |
FireInstrumentInfoChanged(Instr); |
1192 |
} |
} |
1193 |
|
|
1194 |
void InstrumentsDb::AddInstrumentsFromFile(String DbDir, String File, int Index, ScanProgress* pProgress) { |
void InstrumentsDb::AddInstrumentsFromFile(String DbDir, String file, int Index, ScanProgress* pProgress) { |
1195 |
dmsg(2,("InstrumentsDb: AddInstrumentsFromFile(DbDir=%s,File=%s,Index=%d)\n", DbDir.c_str(), File.c_str(), Index)); |
dmsg(2,("InstrumentsDb: AddInstrumentsFromFile(DbDir=%s,File=%s,Index=%d)\n", DbDir.c_str(), file.c_str(), Index)); |
1196 |
|
|
1197 |
if(File.length() < 4) return; |
if (!InstrumentFileInfo::isSupportedFile(file)) return; |
1198 |
|
|
1199 |
try { |
try { |
1200 |
if(!strcasecmp(".gig", File.substr(File.length() - 4).c_str())) { |
if (pProgress != NULL) { |
1201 |
if (pProgress != NULL) { |
pProgress->SetStatus(0); |
1202 |
pProgress->SetStatus(0); |
pProgress->CurrentFile = file; |
1203 |
pProgress->CurrentFile = File; |
} |
|
} |
|
1204 |
|
|
1205 |
AddGigInstruments(DbDir, File, Index, pProgress); |
int dirId = GetDirectoryId(DbDir); |
1206 |
|
if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir)); |
1207 |
|
|
1208 |
if (pProgress != NULL) { |
File f = File(file); |
1209 |
pProgress->SetScannedFileCount(pProgress->GetScannedFileCount() + 1); |
if (!f.Exist()) { |
1210 |
} |
std::stringstream ss; |
1211 |
|
ss << "Fail to stat `" << file << "`: " << f.GetErrorMsg(); |
1212 |
|
throw Exception(ss.str()); |
1213 |
|
} |
1214 |
|
|
1215 |
|
if (!f.IsFile()) { |
1216 |
|
std::stringstream ss; |
1217 |
|
ss << "`" << file << "` is not a regular file"; |
1218 |
|
throw Exception(ss.str()); |
1219 |
|
} |
1220 |
|
|
1221 |
|
AddInstrumentsFromFilePriv(DbDir, dirId, file, f, Index, pProgress); |
1222 |
|
|
1223 |
|
if (pProgress != NULL) { |
1224 |
|
pProgress->SetScannedFileCount(pProgress->GetScannedFileCount() + 1); |
1225 |
} |
} |
1226 |
} catch(Exception e) { |
} catch(Exception e) { |
1227 |
e.PrintMessage(); |
e.PrintMessage(); |
1228 |
} |
} |
1229 |
} |
} |
1230 |
|
|
1231 |
void InstrumentsDb::AddGigInstruments(String DbDir, String FilePath, int Index, ScanProgress* pProgress) { |
void InstrumentsDb::AddInstrumentsFromFilePriv(String DbDir, const int dirId, String FilePath, File file, int Index, ScanProgress* pProgress) { |
1232 |
dmsg(2,("InstrumentsDb: AddGigInstruments(DbDir=%s,FilePath=%s,Index=%d)\n", DbDir.c_str(), FilePath.c_str(), Index)); |
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)); |
|
|
|
|
|
File f = File(FilePath); |
|
|
if (!f.Exist()) { |
|
|
std::stringstream ss; |
|
|
ss << "Fail to stat `" << FilePath << "`: " << f.GetErrorMsg(); |
|
|
throw Exception(ss.str()); |
|
|
} |
|
|
|
|
|
if (!f.IsFile()) { |
|
|
std::stringstream ss; |
|
|
ss << "`" << FilePath << "` is not a regular file"; |
|
|
throw Exception(ss.str()); |
|
|
} |
|
1233 |
|
|
1234 |
bool unlocked = false; |
bool unlocked = false; |
1235 |
RIFF::File* riff = NULL; |
InstrumentFileInfo* fileInfo = NULL; |
1236 |
gig::File* gig = NULL; |
sqlite3_stmt* pStmt = NULL; |
1237 |
try { |
try { |
1238 |
riff = new RIFF::File(FilePath); |
fileInfo = InstrumentFileInfo::getFileInfoFor(FilePath); |
1239 |
gig::File* gig = new gig::File(riff); |
if (!fileInfo) return; |
|
gig->SetAutoLoad(false); // avoid time consuming samples scanning |
|
1240 |
|
|
1241 |
std::stringstream sql; |
std::stringstream sql; |
1242 |
sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,"; |
sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,"; |
1243 |
sql << "instr_nr,format_family,format_version,instr_size,"; |
sql << "instr_nr,format_family,format_version,instr_size,"; |
1244 |
sql << "description,is_drum,product,artists,keywords) VALUES ("; |
sql << "description,is_drum,product,artists,keywords) VALUES ("; |
1245 |
sql << dirId << ",?,?,?,'GIG',?," << f.GetSize() << ",?,?,?,?,?)"; |
sql << dirId << ",?,?,?,?,?," << file.GetSize() << ",?,?,?,?,?)"; |
1246 |
|
|
1247 |
sqlite3_stmt* pStmt = NULL; |
// instr_name 1 |
1248 |
|
// instr_file 2 |
1249 |
|
// instr_nr 3 |
1250 |
|
// format_family 4 |
1251 |
|
// format_version 5 |
1252 |
|
// description 6 |
1253 |
|
// is_drum 7 |
1254 |
|
// product 8 |
1255 |
|
// artists 9 |
1256 |
|
// keywords 10 |
1257 |
|
|
1258 |
int res = sqlite3_prepare(GetDb(), sql.str().c_str(), -1, &pStmt, NULL); |
int res = sqlite3_prepare(GetDb(), sql.str().c_str(), -1, &pStmt, NULL); |
1259 |
if (res != SQLITE_OK) { |
if (res != SQLITE_OK) { |
1260 |
throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); |
throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); |
1261 |
} |
} |
1262 |
|
|
1263 |
String s = FilePath; |
BindTextParam(pStmt, 2, toEscapedFsPath(FilePath)); |
1264 |
s = toEscapedFsPath(s); |
BindTextParam(pStmt, 4, fileInfo->formatName()); |
1265 |
BindTextParam(pStmt, 2, s); |
BindTextParam(pStmt, 5, fileInfo->formatVersion()); |
1266 |
String ver = ""; |
|
1267 |
if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major); |
int instrIndex = (Index == -1) ? 0 : Index; |
1268 |
BindTextParam(pStmt, 4, ver); |
|
1269 |
|
// Assume that it's locked and should be unlocked at this point |
1270 |
if (Index == -1) { |
// to be able to use the database from another threads |
1271 |
int instrIndex = 0; |
if (!InTransaction) { |
1272 |
// Assume that it's locked and should be unlocked at this point |
DbInstrumentsMutex.Unlock(); |
1273 |
// to be able to use the database from another threads |
unlocked = true; |
1274 |
if (!InTransaction) { |
} else { |
1275 |
DbInstrumentsMutex.Unlock(); |
std::cerr << "Shouldn't be in transaction when adding instruments." << std::endl; |
1276 |
unlocked = true; |
} |
|
} else { |
|
|
std::cerr << "Shouldn't be in transaction when adding instruments." << std::endl; |
|
|
} |
|
1277 |
|
|
1278 |
if (pProgress != NULL) gig->GetInstrument(0, &(pProgress->GigFileProgress)); // TODO: this workaround should be fixed |
optional<InstrumentInfo> info = fileInfo->getInstrumentInfo(0, pProgress); |
1279 |
gig::Instrument* pInstrument = gig->GetFirstInstrument(); |
if (!InTransaction) DbInstrumentsMutex.Lock(); |
1280 |
|
while (info) { |
1281 |
|
String instrumentName = info->instrumentName; |
1282 |
|
if (instrumentName.empty()) |
1283 |
|
instrumentName = Path::getBaseName(FilePath); |
1284 |
|
instrumentName = GetUniqueName(dirId, instrumentName); |
1285 |
|
|
1286 |
|
BindTextParam(pStmt, 8, info->product); |
1287 |
|
BindTextParam(pStmt, 9, info->artists); |
1288 |
|
BindTextParam(pStmt, 10, info->keywords); |
1289 |
|
|
1290 |
|
std::stringstream sql2; |
1291 |
|
sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND "; |
1292 |
|
sql2 << "instr_nr=" << instrIndex; |
1293 |
|
String s = toEscapedFsPath(FilePath); |
1294 |
|
if (ExecSqlInt(sql2.str(), s) > 0) goto next; |
1295 |
|
|
1296 |
if (!InTransaction) DbInstrumentsMutex.Lock(); |
BindTextParam(pStmt, 1, instrumentName); |
1297 |
while (pInstrument) { |
BindIntParam(pStmt, 3, instrIndex); |
|
BindTextParam(pStmt, 7, gig->pInfo->Product); |
|
|
BindTextParam(pStmt, 8, gig->pInfo->Artists); |
|
|
BindTextParam(pStmt, 9, gig->pInfo->Keywords); |
|
|
AddGigInstrument(pStmt, DbDir, dirId, FilePath, pInstrument, instrIndex); |
|
1298 |
|
|
1299 |
instrIndex++; |
BindTextParam(pStmt, 6, info->comments); |
1300 |
pInstrument = gig->GetNextInstrument(); |
BindIntParam(pStmt, 7, info->isDrum); |
1301 |
} |
|
1302 |
} else { |
res = sqlite3_step(pStmt); |
1303 |
gig::Instrument* pInstrument; |
if (res != SQLITE_DONE) { |
1304 |
if (pProgress == NULL) pInstrument = gig->GetInstrument(Index); |
throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); |
|
else pInstrument = gig->GetInstrument(Index, &(pProgress->GigFileProgress)); |
|
|
if (pInstrument != NULL) { |
|
|
BindTextParam(pStmt, 7, gig->pInfo->Product); |
|
|
BindTextParam(pStmt, 8, gig->pInfo->Artists); |
|
|
BindTextParam(pStmt, 9, gig->pInfo->Keywords); |
|
|
AddGigInstrument(pStmt, DbDir, dirId, FilePath, pInstrument, Index); |
|
1305 |
} |
} |
1306 |
} |
res = sqlite3_reset(pStmt); |
1307 |
|
FireInstrumentCountChanged(DbDir); |
1308 |
|
|
1309 |
sqlite3_finalize(pStmt); |
next: |
1310 |
delete gig; |
if (Index != -1) break; |
1311 |
delete riff; |
|
1312 |
} catch (RIFF::Exception e) { |
instrIndex++; |
1313 |
if (gig != NULL) delete gig; |
info = fileInfo->getInstrumentInfo(instrIndex, pProgress); |
1314 |
if (riff != NULL) delete riff; |
} |
1315 |
|
} catch (Exception e) { |
1316 |
|
if (pStmt) sqlite3_finalize(pStmt); |
1317 |
|
if (fileInfo) delete fileInfo; |
1318 |
if (unlocked) DbInstrumentsMutex.Lock(); |
if (unlocked) DbInstrumentsMutex.Lock(); |
1319 |
std::stringstream ss; |
std::stringstream ss; |
1320 |
ss << "Failed to scan `" << FilePath << "`: " << e.Message; |
ss << "Failed to scan `" << FilePath << "`: " << e.Message(); |
|
|
|
1321 |
throw Exception(ss.str()); |
throw Exception(ss.str()); |
|
} catch (Exception e) { |
|
|
if (gig != NULL) delete gig; |
|
|
if (riff != NULL) delete riff; |
|
|
if (unlocked) DbInstrumentsMutex.Lock(); |
|
|
throw e; |
|
1322 |
} catch (...) { |
} catch (...) { |
1323 |
if (gig != NULL) delete gig; |
if (pStmt) sqlite3_finalize(pStmt); |
1324 |
if (riff != NULL) delete riff; |
if (fileInfo) delete fileInfo; |
1325 |
if (unlocked) DbInstrumentsMutex.Lock(); |
if (unlocked) DbInstrumentsMutex.Lock(); |
1326 |
throw Exception("Failed to scan `" + FilePath + "`"); |
throw Exception("Failed to scan `" + FilePath + "`"); |
1327 |
} |
} |
1328 |
} |
if (pStmt) sqlite3_finalize(pStmt); |
1329 |
|
if (fileInfo) delete fileInfo; |
1330 |
void InstrumentsDb::AddGigInstrument(sqlite3_stmt* pStmt, String DbDir, int DirId, String File, gig::Instrument* pInstrument, int Index) { |
if (unlocked) DbInstrumentsMutex.Lock(); |
|
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 = GetUniqueName(DirId, name); |
|
|
|
|
|
std::stringstream sql2; |
|
|
sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND "; |
|
|
sql2 << "instr_nr=" << Index; |
|
|
String s = toEscapedFsPath(File); |
|
|
if (ExecSqlInt(sql2.str(), s) > 0) return; |
|
|
|
|
|
BindTextParam(pStmt, 1, name); |
|
|
BindIntParam(pStmt, 3, Index); |
|
|
|
|
|
BindTextParam(pStmt, 5, pInstrument->pInfo->Comments); |
|
|
BindIntParam(pStmt, 6, pInstrument->IsDrum); |
|
|
|
|
|
if (!pInstrument->pInfo->Product.empty()) { |
|
|
BindTextParam(pStmt, 7, pInstrument->pInfo->Product); |
|
|
} |
|
|
if (!pInstrument->pInfo->Artists.empty()) { |
|
|
BindTextParam(pStmt, 8, pInstrument->pInfo->Artists); |
|
|
} |
|
|
|
|
|
if (!pInstrument->pInfo->Keywords.empty()) { |
|
|
BindTextParam(pStmt, 9, pInstrument->pInfo->Keywords); |
|
|
} |
|
|
|
|
|
int res = sqlite3_step(pStmt); |
|
|
if(res != SQLITE_DONE) { |
|
|
sqlite3_finalize(pStmt); |
|
|
throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); |
|
|
} |
|
|
|
|
|
res = sqlite3_reset(pStmt); |
|
|
FireInstrumentCountChanged(DbDir); |
|
1331 |
} |
} |
1332 |
|
|
1333 |
void InstrumentsDb::DirectoryTreeWalk(String AbstractPath, DirectoryHandler* pHandler) { |
void InstrumentsDb::DirectoryTreeWalk(String AbstractPath, DirectoryHandler* pHandler) { |
1465 |
} |
} |
1466 |
InTransaction = false; |
InTransaction = false; |
1467 |
|
|
1468 |
if(db == NULL) { |
if (db == NULL) { |
1469 |
DbInstrumentsMutex.Unlock(); |
DbInstrumentsMutex.Unlock(); |
1470 |
return; |
return; |
1471 |
} |
} |
1669 |
|
|
1670 |
void InstrumentsDb::BindTextParam(sqlite3_stmt* pStmt, int Index, String Text) { |
void InstrumentsDb::BindTextParam(sqlite3_stmt* pStmt, int Index, String Text) { |
1671 |
if (pStmt == NULL) return; |
if (pStmt == NULL) return; |
1672 |
int res = sqlite3_bind_text(pStmt, Index, Text.c_str(), -1, SQLITE_STATIC); |
int res = sqlite3_bind_text(pStmt, Index, Text.c_str(), -1, SQLITE_TRANSIENT); |
1673 |
if (res != SQLITE_OK) { |
if (res != SQLITE_OK) { |
1674 |
sqlite3_finalize(pStmt); |
sqlite3_finalize(pStmt); |
1675 |
throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); |
throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); |
1740 |
} |
} |
1741 |
|
|
1742 |
void InstrumentsDb::Format() { |
void InstrumentsDb::Format() { |
1743 |
DbInstrumentsMutex.Lock(); |
{ |
1744 |
if (db != NULL) { |
LockGuard lock(DbInstrumentsMutex); |
|
sqlite3_close(db); |
|
|
db = NULL; |
|
|
} |
|
1745 |
|
|
1746 |
if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION; |
if (db != NULL) { |
1747 |
String bkp = DbFile + ".bkp"; |
sqlite3_close(db); |
1748 |
remove(bkp.c_str()); |
db = NULL; |
1749 |
if (rename(DbFile.c_str(), bkp.c_str()) && errno != ENOENT) { |
} |
1750 |
DbInstrumentsMutex.Unlock(); |
|
1751 |
throw Exception(String("Failed to backup database: ") + strerror(errno)); |
if (DbFile.empty()) DbFile = GetDefaultDBLocation(); |
1752 |
} |
String bkp = DbFile + ".bkp"; |
1753 |
|
remove(bkp.c_str()); |
1754 |
|
if (rename(DbFile.c_str(), bkp.c_str()) && errno != ENOENT) { |
1755 |
|
throw Exception(String("Failed to backup database: ") + strerror(errno)); |
1756 |
|
} |
1757 |
|
|
1758 |
String f = DbFile; |
String f = DbFile; |
1759 |
DbFile = ""; |
DbFile = ""; |
1760 |
try { CreateInstrumentsDb(f); } |
CreateInstrumentsDb(f); |
|
catch(Exception e) { |
|
|
DbInstrumentsMutex.Unlock(); |
|
|
throw e; |
|
1761 |
} |
} |
|
DbInstrumentsMutex.Unlock(); |
|
|
|
|
1762 |
FireDirectoryCountChanged("/"); |
FireDirectoryCountChanged("/"); |
1763 |
FireInstrumentCountChanged("/"); |
FireInstrumentCountChanged("/"); |
1764 |
} |
} |