/[svn]/linuxsampler/trunk/src/db/InstrumentsDb.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/db/InstrumentsDb.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1345 - (hide annotations) (download)
Thu Sep 13 21:46:25 2007 UTC (16 years, 7 months ago) by iliev
File size: 65083 byte(s)
* added support for escape sequences to the instruments database

1 iliev 1161 /***************************************************************************
2     * *
3     * Copyright (C) 2007 Grigor Iliev *
4     * *
5     * 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 *
7     * the Free Software Foundation; either version 2 of the License, or *
8     * (at your option) any later version. *
9     * *
10     * This program is distributed in the hope that it will be useful, *
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13     * GNU General Public License for more details. *
14     * *
15     * You should have received a copy of the GNU General Public License *
16     * along with this program; if not, write to the Free Software *
17     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
18     * MA 02110-1301 USA *
19     ***************************************************************************/
20    
21     #include "InstrumentsDb.h"
22    
23     #if HAVE_SQLITE3
24    
25     #include <iostream>
26     #include <sstream>
27 iliev 1200 #include <vector>
28 iliev 1161 #include <dirent.h>
29     #include <errno.h>
30 iliev 1187 #include <fnmatch.h>
31 iliev 1200
32 iliev 1161 #include "../common/Exception.h"
33    
34     namespace LinuxSampler {
35    
36     InstrumentsDb* InstrumentsDb::pInstrumentsDb = new InstrumentsDb;
37    
38 iliev 1187 void InstrumentsDb::CreateInstrumentsDb(String File) {
39     struct stat statBuf;
40     int res = stat(File.c_str(), &statBuf);
41     if (!res) {
42     throw Exception("File exists: " + File);
43     }
44    
45     GetInstrumentsDb()->SetDbFile(File);
46    
47     String sql =
48     " CREATE TABLE instr_dirs ( "
49     " dir_id INTEGER PRIMARY KEY AUTOINCREMENT, "
50     " parent_dir_id INTEGER DEFAULT 0, "
51     " dir_name TEXT, "
52     " created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
53     " modified TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
54     " description TEXT, "
55     " FOREIGN KEY(parent_dir_id) REFERENCES instr_dirs(dir_id), "
56     " UNIQUE (parent_dir_id,dir_name) "
57     " ); ";
58    
59     GetInstrumentsDb()->ExecSql(sql);
60    
61     sql = "INSERT INTO instr_dirs (dir_id, parent_dir_id, dir_name) VALUES (0, 0, '/');";
62     GetInstrumentsDb()->ExecSql(sql);
63    
64     sql =
65     " CREATE TABLE instruments ( "
66     " instr_id INTEGER PRIMARY KEY AUTOINCREMENT, "
67     " dir_id INTEGER DEFAULT 0, "
68     " instr_name TEXT, "
69     " instr_file TEXT, "
70     " instr_nr INTEGER, "
71     " format_family TEXT, "
72     " format_version TEXT, "
73     " instr_size INTEGER, "
74     " created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
75     " modified TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
76     " description TEXT, "
77     " is_drum INTEGER(1), "
78     " product TEXT, "
79     " artists TEXT, "
80     " keywords TEXT, "
81     " FOREIGN KEY(dir_id) REFERENCES instr_dirs(dir_id), "
82     " UNIQUE (dir_id,instr_name) "
83     " ); ";
84    
85     GetInstrumentsDb()->ExecSql(sql);
86     }
87    
88 iliev 1161 InstrumentsDb::InstrumentsDb() {
89     db = NULL;
90     DbInstrumentsMutex = Mutex();
91 iliev 1187 InTransaction = false;
92 iliev 1161 }
93    
94     InstrumentsDb::~InstrumentsDb() {
95     if (db != NULL) sqlite3_close(db);
96     }
97    
98     void InstrumentsDb::Destroy() {
99     if (pInstrumentsDb != NULL) {
100     delete pInstrumentsDb;
101     pInstrumentsDb = NULL;
102     }
103     }
104    
105     void InstrumentsDb::AddInstrumentsDbListener(InstrumentsDb::Listener* l) {
106     llInstrumentsDbListeners.AddListener(l);
107     }
108    
109     void InstrumentsDb::RemoveInstrumentsDbListener(InstrumentsDb::Listener* l) {
110     llInstrumentsDbListeners.RemoveListener(l);
111     }
112    
113     InstrumentsDb* InstrumentsDb::GetInstrumentsDb() {
114     return pInstrumentsDb;
115     }
116    
117     void InstrumentsDb::SetDbFile(String File) {
118     DbInstrumentsMutex.Lock();
119     if (File.empty() || DbFile.length() > 0) {
120     DbInstrumentsMutex.Unlock();
121     throw Exception("Failed to set the database file");
122     }
123     DbFile = File;
124     DbInstrumentsMutex.Unlock();
125     }
126    
127     sqlite3* InstrumentsDb::GetDb() {
128     if ( db != NULL) return db;
129    
130     if (DbFile.empty()) DbFile = "/var/lib/linuxsampler/instruments.db";
131     int rc = sqlite3_open(DbFile.c_str(), &db);
132     if (rc) {
133     sqlite3_close(db);
134     db = NULL;
135     throw Exception("Cannot open instruments database: " + DbFile);
136     }
137 iliev 1187 rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, NULL, Regexp, NULL, NULL);
138     if (rc) { throw Exception("Failed to add user function for handling regular expressions."); }
139 iliev 1161
140     return db;
141     }
142    
143     int InstrumentsDb::GetDirectoryCount(int DirId) {
144     dmsg(2,("InstrumentsDb: GetDirectoryCount(DirId=%d)\n", DirId));
145     if(DirId == -1) return -1;
146    
147     std::stringstream sql;
148     sql << "SELECT COUNT(*) FROM instr_dirs WHERE parent_dir_id=" << DirId;
149    
150     int count = ExecSqlInt(sql.str());
151    
152     // While the root dir has ID 0 and parent ID 0, the directory
153     // count for the root dir will be incorrect, so we should fix it.
154     if (count != -1 && DirId == 0) count--;
155     return count;
156     }
157    
158 iliev 1187 int InstrumentsDb::GetDirectoryCount(String Dir, bool Recursive) {
159     dmsg(2,("InstrumentsDb: GetDirectoryCount(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
160 iliev 1161 int i;
161    
162 iliev 1187 BeginTransaction();
163     try {
164     if (Recursive) {
165     DirectoryCounter directoryCounter;
166     DirectoryTreeWalk(Dir, &directoryCounter);
167     i = directoryCounter.GetDirectoryCount();
168     } else {
169     i = GetDirectoryCount(GetDirectoryId(Dir));
170     }
171     } catch (Exception e) {
172     EndTransaction();
173 iliev 1161 throw e;
174     }
175 iliev 1187 EndTransaction();
176 iliev 1345 if (i == -1) throw Exception("Unkown DB directory: " + toEscapedPath(Dir));
177 iliev 1161
178     return i;
179     }
180    
181     IntListPtr InstrumentsDb::GetDirectoryIDs(int DirId) {
182     std::stringstream sql;
183     sql << "SELECT dir_id FROM instr_dirs ";
184     sql << "WHERE parent_dir_id=" << DirId << " AND dir_id!=0";
185    
186     return ExecSqlIntList(sql.str());
187     }
188    
189 iliev 1187 StringListPtr InstrumentsDb::GetDirectories(String Dir, bool Recursive) {
190     dmsg(2,("InstrumentsDb: GetDirectories(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
191 iliev 1161
192 iliev 1187 BeginTransaction();
193 iliev 1161 try {
194     int dirId = GetDirectoryId(Dir);
195 iliev 1345 if(dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
196 iliev 1161
197 iliev 1187 StringListPtr pDirs;
198     if (Recursive) {
199     SearchQuery q;
200     DirectoryFinder directoryFinder(&q);
201     DirectoryTreeWalk(Dir, &directoryFinder);
202     pDirs = directoryFinder.GetDirectories();
203     } else {
204     pDirs = GetDirectories(dirId);
205     }
206     EndTransaction();
207     return pDirs;
208 iliev 1161 } catch (Exception e) {
209 iliev 1187 EndTransaction();
210 iliev 1161 throw e;
211     }
212     }
213 iliev 1187
214     StringListPtr InstrumentsDb::GetDirectories(int DirId) {
215     std::stringstream sql;
216     sql << "SELECT dir_name FROM instr_dirs ";
217     sql << "WHERE parent_dir_id=" << DirId << " AND dir_id!=0";
218 iliev 1345 StringListPtr dirs = ExecSqlStringList(sql.str());
219    
220     for (int i = 0; i < dirs->size(); i++) {
221     for (int j = 0; j < dirs->at(i).length(); j++) {
222     if (dirs->at(i).at(j) == '/') dirs->at(i).at(j) = '\0';
223     }
224     }
225    
226     return dirs;
227 iliev 1187 }
228 iliev 1161
229     int InstrumentsDb::GetDirectoryId(String Dir) {
230     dmsg(2,("InstrumentsDb: GetDirectoryId(Dir=%s)\n", Dir.c_str()));
231     CheckPathName(Dir);
232    
233     if (Dir.empty() || Dir.at(0) != '/') {
234     return -1;
235     } else if (Dir.length() == 1) {
236     // We expect the root directory id to be always 0.
237     return 0;
238     }
239    
240     int id = 0, i = 1;
241     int j = Dir.find('/', i);
242    
243     while(j != std::string::npos) {
244     id = GetDirectoryId(id, Dir.substr(i, j - i));
245     i = j + 1;
246     if (i >= Dir.length()) return id;
247     j = Dir.find('/', i);
248     }
249    
250     return GetDirectoryId(id, Dir.substr(i));
251     }
252    
253     int InstrumentsDb::GetDirectoryId(int ParentDirId, String DirName) {
254     dmsg(2,("InstrumentsDb: GetDirectoryId(ParentDirId=%d, DirName=%s)\n", ParentDirId, DirName.c_str()));
255 iliev 1345 DirName = toDbName(DirName);
256 iliev 1161 std::stringstream sql;
257     sql << "SELECT dir_id FROM instr_dirs WHERE parent_dir_id=";
258     sql << ParentDirId << " AND dir_name=?";
259     return ExecSqlInt(sql.str(), DirName);
260     }
261    
262 iliev 1187 String InstrumentsDb::GetDirectoryName(int DirId) {
263     String sql = "SELECT dir_name FROM instr_dirs WHERE dir_id=" + ToString(DirId);
264     String name = ExecSqlString(sql);
265     if (name.empty()) throw Exception("Directory ID not found");
266     return name;
267     }
268    
269     int InstrumentsDb::GetParentDirectoryId(int DirId) {
270     if (DirId == 0) throw Exception("The root directory is specified");
271     String sql = "SELECT parent_dir_id FROM instr_dirs WHERE dir_id=" + ToString(DirId);
272     int parentId = ExecSqlInt(sql);
273     if (parentId == -1) throw Exception("DB directory not found");
274     return parentId;
275     }
276    
277     String InstrumentsDb::GetDirectoryPath(int DirId) {
278     String path = "";
279     int count = 1000; // used to prevent infinite loops
280    
281     while(--count) {
282     if (DirId == 0) {
283     path = "/" + path;
284     break;
285     }
286     path = GetDirectoryName(DirId) + path;
287     DirId = GetParentDirectoryId(DirId);
288     }
289    
290     if (!count) throw Exception("Possible infinite loop detected");
291    
292     return path;
293     }
294    
295 iliev 1161 void InstrumentsDb::AddDirectory(String Dir) {
296     dmsg(2,("InstrumentsDb: AddDirectory(Dir=%s)\n", Dir.c_str()));
297     CheckPathName(Dir);
298     String ParentDir = GetParentDirectory(Dir);
299    
300 iliev 1187 BeginTransaction();
301 iliev 1161 try {
302     if (Dir.length() > 1) {
303     if (Dir.at(Dir.length() - 1) == '/') Dir.erase(Dir.length() - 1);
304     }
305    
306     String dirName = GetFileName(Dir);
307     if(ParentDir.empty() || dirName.empty()) {
308 iliev 1345 throw Exception("Failed to add DB directory: " + toEscapedPath(Dir));
309 iliev 1161 }
310    
311     int id = GetDirectoryId(ParentDir);
312 iliev 1345 if (id == -1) throw Exception("DB directory doesn't exist: " + toEscapedPath(ParentDir));
313 iliev 1161 int id2 = GetDirectoryId(id, dirName);
314 iliev 1345 if (id2 != -1) throw Exception("DB directory already exist: " + toEscapedPath(Dir));
315 iliev 1187 id2 = GetInstrumentId(id, dirName);
316 iliev 1345 if (id2 != -1) throw Exception("Instrument with that name exist: " + toEscapedPath(Dir));
317 iliev 1161
318     std::stringstream sql;
319     sql << "INSERT INTO instr_dirs (parent_dir_id, dir_name) VALUES (";
320     sql << id << ", ?)";
321    
322 iliev 1345 ExecSql(sql.str(), toDbName(dirName));
323 iliev 1161 } catch (Exception e) {
324 iliev 1187 EndTransaction();
325 iliev 1161 throw e;
326     }
327    
328 iliev 1187 EndTransaction();
329 iliev 1161
330     FireDirectoryCountChanged(ParentDir);
331     }
332    
333     void InstrumentsDb::RemoveDirectory(String Dir, bool Force) {
334     dmsg(2,("InstrumentsDb: RemoveDirectory(Dir=%s,Force=%d)\n", Dir.c_str(), Force));
335    
336     String ParentDir = GetParentDirectory(Dir);
337    
338 iliev 1187 BeginTransaction();
339 iliev 1161 try {
340     int dirId = GetDirectoryId(Dir);
341 iliev 1345 if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
342 iliev 1161 if (dirId == 0) throw Exception("Cannot delete the root directory: " + Dir);
343     if(ParentDir.empty()) throw Exception("Unknown parent directory");
344     if (Force) RemoveDirectoryContent(dirId);
345     RemoveDirectory(dirId);
346     } catch (Exception e) {
347 iliev 1187 EndTransaction();
348 iliev 1161 throw e;
349     }
350    
351 iliev 1187 EndTransaction();
352 iliev 1161 FireDirectoryCountChanged(ParentDir);
353     }
354    
355     void InstrumentsDb::RemoveDirectoryContent(int DirId, int Level) {
356     dmsg(2,("InstrumentsDb: RemoveDirectoryContent(DirId=%d,Level=%d)\n", DirId, Level));
357     if (Level > 1000) throw Exception("Directory level too deep: " + ToString(Level));
358     IntListPtr dirIds = GetDirectoryIDs(DirId);
359    
360     for (int i = 0; i < dirIds->size(); i++) {
361     RemoveDirectoryContent(dirIds->at(i), Level + 1);
362     }
363    
364     RemoveAllDirectories(DirId);
365     RemoveAllInstruments(DirId);
366     }
367    
368     void InstrumentsDb::RemoveDirectory(int DirId) {
369     dmsg(2,("InstrumentsDb: RemoveDirectory(DirId=%d)\n", DirId));
370     if (GetInstrumentCount(DirId) > 0 || GetDirectoryCount(DirId) > 0) {
371     throw Exception("The specified DB directory is not empty");
372     }
373    
374     std::stringstream sql;
375     sql << "DELETE FROM instr_dirs WHERE dir_id=" << DirId;
376    
377     ExecSql(sql.str());
378     }
379    
380     void InstrumentsDb::RemoveAllDirectories(int DirId) {
381     dmsg(2,("InstrumentsDb: RemoveAllDirectories(DirId=%d)\n", DirId));
382     IntListPtr dirIds = GetDirectoryIDs(DirId);
383    
384     for (int i = 0; i < dirIds->size(); i++) {
385     if (!IsDirectoryEmpty(dirIds->at(i))) {
386     throw Exception("DB directory not empty!");
387     }
388     }
389     std::stringstream sql;
390     sql << "DELETE FROM instr_dirs WHERE parent_dir_id=" << DirId;
391     sql << " AND dir_id!=0";
392    
393     ExecSql(sql.str());
394     }
395    
396     bool InstrumentsDb::IsDirectoryEmpty(int DirId) {
397     dmsg(2,("InstrumentsDb: IsDirectoryEmpty(DirId=%d)\n", DirId));
398     int dirCount = GetDirectoryCount(DirId);
399     int instrCount = GetInstrumentCount(DirId);
400     dmsg(3,("InstrumentsDb: IsDirectoryEmpty: dirCount=%d,instrCount=%d\n", dirCount, instrCount));
401     if (dirCount == -1 || instrCount == -1) return false;
402     return dirCount == 0 && instrCount == 0;
403     }
404    
405     bool InstrumentsDb::DirectoryExist(String Dir) {
406     dmsg(2,("InstrumentsDb: DirectoryExist(Dir=%s)\n", Dir.c_str()));
407     bool b;
408    
409     DbInstrumentsMutex.Lock();
410     try { b = GetDirectoryId(Dir) != -1; }
411     catch (Exception e) {
412     DbInstrumentsMutex.Unlock();
413     throw e;
414     }
415     DbInstrumentsMutex.Unlock();
416    
417     return b;
418     }
419    
420     DbDirectory InstrumentsDb::GetDirectoryInfo(String Dir) {
421     dmsg(2,("InstrumentsDb: GetDirectoryInfo(Dir=%s)\n", Dir.c_str()));
422     DbDirectory d;
423    
424 iliev 1187 BeginTransaction();
425 iliev 1161
426     try {
427     int id = GetDirectoryId(Dir);
428 iliev 1345 if(id == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
429 iliev 1161
430     sqlite3_stmt *pStmt = NULL;
431     std::stringstream sql;
432     sql << "SELECT created,modified,description FROM instr_dirs ";
433     sql << "WHERE dir_id=" << id;
434    
435     int res = sqlite3_prepare(GetDb(), sql.str().c_str(), -1, &pStmt, NULL);
436     if (res != SQLITE_OK) {
437     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
438     }
439    
440     res = sqlite3_step(pStmt);
441     if(res == SQLITE_ROW) {
442     d.Created = ToString(sqlite3_column_text(pStmt, 0));
443     d.Modified = ToString(sqlite3_column_text(pStmt, 1));
444     d.Description = ToString(sqlite3_column_text(pStmt, 2));
445     } else {
446     sqlite3_finalize(pStmt);
447    
448     if (res != SQLITE_DONE) {
449     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
450     } else {
451 iliev 1345 throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
452 iliev 1161 }
453     }
454    
455     sqlite3_finalize(pStmt);
456     } catch (Exception e) {
457 iliev 1187 EndTransaction();
458 iliev 1161 throw e;
459     }
460    
461 iliev 1187 EndTransaction();
462 iliev 1161 return d;
463     }
464    
465     void InstrumentsDb::RenameDirectory(String Dir, String Name) {
466     dmsg(2,("InstrumentsDb: RenameDirectory(Dir=%s,Name=%s)\n", Dir.c_str(), Name.c_str()));
467     CheckFileName(Name);
468 iliev 1345 String dbName = toDbName(Name);
469 iliev 1161
470 iliev 1187 BeginTransaction();
471 iliev 1161 try {
472     int dirId = GetDirectoryId(Dir);
473 iliev 1345 if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedText(Dir));
474 iliev 1161
475     std::stringstream sql;
476     sql << "SELECT parent_dir_id FROM instr_dirs WHERE dir_id=" << dirId;
477    
478     int parent = ExecSqlInt(sql.str());
479 iliev 1345 if (parent == -1) throw Exception("Unknown parent directory: " + toEscapedPath(Dir));
480    
481     if (GetDirectoryId(parent, dbName) != -1) {
482     String s = toEscapedPath(Name);
483     throw Exception("Cannot rename. Directory with that name already exists: " + s);
484 iliev 1161 }
485    
486 iliev 1345 if (GetInstrumentId(parent, dbName) != -1) {
487     throw Exception("Cannot rename. Instrument with that name exist: " + toEscapedPath(Dir));
488 iliev 1187 }
489    
490 iliev 1161 sql.str("");
491     sql << "UPDATE instr_dirs SET dir_name=? WHERE dir_id=" << dirId;
492 iliev 1345 ExecSql(sql.str(), dbName);
493 iliev 1161 } catch (Exception e) {
494 iliev 1187 EndTransaction();
495 iliev 1161 throw e;
496     }
497    
498 iliev 1187 EndTransaction();
499 iliev 1161 FireDirectoryNameChanged(Dir, Name);
500     }
501    
502     void InstrumentsDb::MoveDirectory(String Dir, String Dst) {
503     dmsg(2,("InstrumentsDb: MoveDirectory(Dir=%s,Dst=%s)\n", Dir.c_str(), Dst.c_str()));
504    
505 iliev 1187 if(Dir.compare("/") == 0) throw Exception("Cannot move the root directory");
506 iliev 1161 String ParentDir = GetParentDirectory(Dir);
507     if(ParentDir.empty()) throw Exception("Unknown parent directory");
508    
509 iliev 1187 BeginTransaction();
510 iliev 1161 try {
511     int dirId = GetDirectoryId(Dir);
512 iliev 1345 if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
513 iliev 1161 int dstId = GetDirectoryId(Dst);
514 iliev 1345 if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
515 iliev 1161 if (dirId == dstId) {
516     throw Exception("Cannot move directory to itself");
517     }
518    
519     if (Dir.at(Dir.length() - 1) != '/') Dir.append("/");
520     if (Dst.length() > Dir.length()) {
521     if (Dir.compare(Dst.substr(0, Dir.length())) == 0) {
522     throw Exception("Cannot move a directory to a subdirectory of itself.");
523     }
524     }
525 iliev 1187
526     Dir.erase(Dir.length() - 1);
527     String dirName = GetFileName(Dir);
528 iliev 1161
529 iliev 1187 int id2 = GetDirectoryId(dstId, dirName);
530 iliev 1345 if (id2 != -1) throw Exception("DB directory already exist: " + toEscapedPath(dirName));
531 iliev 1187 id2 = GetInstrumentId(dstId, dirName);
532 iliev 1345 if (id2 != -1) throw Exception("Instrument with that name exist: " + toEscapedPath(dirName));
533 iliev 1187
534 iliev 1161 std::stringstream sql;
535     sql << "UPDATE instr_dirs SET parent_dir_id=" << dstId;
536     sql << " WHERE dir_id=" << dirId;
537     ExecSql(sql.str());
538     } catch (Exception e) {
539 iliev 1187 EndTransaction();
540 iliev 1161 throw e;
541     }
542    
543 iliev 1187 EndTransaction();
544 iliev 1161 FireDirectoryCountChanged(ParentDir);
545     FireDirectoryCountChanged(Dst);
546     }
547    
548 iliev 1187 void InstrumentsDb::CopyDirectory(String Dir, String Dst) {
549     dmsg(2,("InstrumentsDb: CopyDirectory(Dir=%s,Dst=%s)\n", Dir.c_str(), Dst.c_str()));
550    
551     if(Dir.compare("/") == 0) throw Exception("Cannot copy the root directory");
552     String ParentDir = GetParentDirectory(Dir);
553     if(ParentDir.empty()) throw Exception("Unknown parent directory");
554    
555     BeginTransaction();
556     try {
557     int dirId = GetDirectoryId(Dir);
558 iliev 1345 if (dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
559 iliev 1187 int dstId = GetDirectoryId(Dst);
560 iliev 1345 if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
561 iliev 1187 if (dirId == dstId) {
562     throw Exception("Cannot copy directory to itself");
563     }
564    
565     if (Dir.at(Dir.length() - 1) != '/') Dir.append("/");
566     if (Dst.length() > Dir.length()) {
567     if (Dir.compare(Dst.substr(0, Dir.length())) == 0) {
568     throw Exception("Cannot copy a directory to a subdirectory of itself.");
569     }
570     }
571    
572     Dir.erase(Dir.length() - 1);
573     String dirName = GetFileName(Dir);
574    
575     int id2 = GetDirectoryId(dstId, dirName);
576 iliev 1345 if (id2 != -1) throw Exception("DB directory already exist: " + toEscapedPath(dirName));
577 iliev 1187 id2 = GetInstrumentId(dstId, dirName);
578 iliev 1345 if (id2 != -1) throw Exception("Instrument with that name exist: " + toEscapedPath(dirName));
579 iliev 1187
580     DirectoryCopier directoryCopier(ParentDir, Dst);
581     DirectoryTreeWalk(Dir, &directoryCopier);
582     } catch (Exception e) {
583     EndTransaction();
584     throw e;
585     }
586    
587     EndTransaction();
588     }
589    
590 iliev 1161 void InstrumentsDb::SetDirectoryDescription(String Dir, String Desc) {
591     dmsg(2,("InstrumentsDb: SetDirectoryDescription(Dir=%s,Desc=%s)\n", Dir.c_str(), Desc.c_str()));
592    
593 iliev 1187 BeginTransaction();
594 iliev 1161 try {
595     int id = GetDirectoryId(Dir);
596 iliev 1345 if(id == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
597 iliev 1161
598     std::stringstream sql;
599     sql << "UPDATE instr_dirs SET description=?,modified=CURRENT_TIMESTAMP ";
600     sql << "WHERE dir_id="<< id;
601    
602     ExecSql(sql.str(), Desc);
603     } catch (Exception e) {
604 iliev 1187 EndTransaction();
605 iliev 1161 throw e;
606     }
607 iliev 1187 EndTransaction();
608 iliev 1161
609     FireDirectoryInfoChanged(Dir);
610     }
611    
612 iliev 1200 int InstrumentsDb::AddInstruments(ScanMode Mode, String DbDir, String FsDir, bool bBackground) {
613     dmsg(2,("InstrumentsDb: AddInstruments(Mode=%d,DbDir=%s,FsDir=%s,bBackground=%d)\n", Mode, DbDir.c_str(), FsDir.c_str(), bBackground));
614     if(!bBackground) {
615     switch (Mode) {
616     case NON_RECURSIVE:
617     AddInstrumentsNonrecursive(DbDir, FsDir);
618     break;
619     case RECURSIVE:
620     AddInstrumentsRecursive(DbDir, FsDir);
621     break;
622     case FLAT:
623     AddInstrumentsRecursive(DbDir, FsDir, true);
624     break;
625     default:
626     throw Exception("Unknown scan mode");
627     }
628    
629     return -1;
630     }
631    
632     ScanJob job;
633     int jobId = Jobs.AddJob(job);
634     InstrumentsDbThread.Execute(new AddInstrumentsJob(jobId, Mode, DbDir, FsDir));
635    
636     return jobId;
637     }
638    
639     int InstrumentsDb::AddInstruments(String DbDir, String FilePath, int Index, bool bBackground) {
640     dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,FilePath=%s,Index=%d,bBackground=%d)\n", DbDir.c_str(), FilePath.c_str(), Index, bBackground));
641     if(!bBackground) {
642     AddInstruments(DbDir, FilePath, Index);
643     return -1;
644     }
645    
646     ScanJob job;
647     int jobId = Jobs.AddJob(job);
648     InstrumentsDbThread.Execute(new AddInstrumentsFromFileJob(jobId, DbDir, FilePath, Index));
649    
650     return jobId;
651     }
652    
653     void InstrumentsDb::AddInstruments(String DbDir, String FilePath, int Index, ScanProgress* pProgress) {
654 iliev 1161 dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,FilePath=%s,Index=%d)\n", DbDir.c_str(), FilePath.c_str(), Index));
655     if (DbDir.empty() || FilePath.empty()) return;
656    
657     DbInstrumentsMutex.Lock();
658     try {
659     int dirId = GetDirectoryId(DbDir);
660 iliev 1345 if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedText(DbDir));
661 iliev 1161
662     struct stat statBuf;
663     int res = stat(FilePath.c_str(), &statBuf);
664     if (res) {
665     std::stringstream ss;
666     ss << "Fail to stat `" << FilePath << "`: " << strerror(errno);
667     throw Exception(ss.str());
668     }
669    
670 iliev 1200 if (!S_ISREG(statBuf.st_mode)) {
671 iliev 1161 std::stringstream ss;
672 iliev 1200 ss << "`" << FilePath << "` is not an instrument file";
673 iliev 1161 throw Exception(ss.str());
674     }
675 iliev 1200
676     AddInstrumentsFromFile(DbDir, FilePath, Index, pProgress);
677 iliev 1161 } catch (Exception e) {
678     DbInstrumentsMutex.Unlock();
679     throw e;
680     }
681    
682     DbInstrumentsMutex.Unlock();
683     }
684    
685 iliev 1200 void InstrumentsDb::AddInstrumentsNonrecursive(String DbDir, String FsDir, ScanProgress* pProgress) {
686 iliev 1161 dmsg(2,("InstrumentsDb: AddInstrumentsNonrecursive(DbDir=%s,FsDir=%s)\n", DbDir.c_str(), FsDir.c_str()));
687     if (DbDir.empty() || FsDir.empty()) return;
688    
689     DbInstrumentsMutex.Lock();
690     try {
691     int dirId = GetDirectoryId(DbDir);
692 iliev 1345 if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));
693 iliev 1161
694     struct stat statBuf;
695     int res = stat(FsDir.c_str(), &statBuf);
696     if (res) {
697     std::stringstream ss;
698     ss << "Fail to stat `" << FsDir << "`: " << strerror(errno);
699     throw Exception(ss.str());
700     }
701    
702     if (!S_ISDIR(statBuf.st_mode)) {
703     throw Exception("Directory expected");
704     }
705    
706     if (FsDir.at(FsDir.length() - 1) != '/') FsDir.append("/");
707    
708     DIR* pDir = opendir(FsDir.c_str());
709     if (pDir == NULL) {
710     std::stringstream ss;
711     ss << "The scanning of directory `" << FsDir << "` failed: ";
712     ss << strerror(errno);
713 iliev 1187 std::cerr << ss.str();
714 iliev 1161 DbInstrumentsMutex.Unlock();
715     return;
716     }
717    
718     struct dirent* pEnt = readdir(pDir);
719     while (pEnt != NULL) {
720     if (pEnt->d_type != DT_REG) {
721     pEnt = readdir(pDir);
722     continue;
723     }
724    
725 iliev 1200 AddInstrumentsFromFile(DbDir, FsDir + String(pEnt->d_name), -1, pProgress);
726 iliev 1161 pEnt = readdir(pDir);
727     }
728    
729     if (closedir(pDir)) {
730     std::stringstream ss;
731     ss << "Failed to close directory `" << FsDir << "`: ";
732     ss << strerror(errno);
733 iliev 1187 std::cerr << ss.str();
734 iliev 1161 }
735     } catch (Exception e) {
736     DbInstrumentsMutex.Unlock();
737     throw e;
738     }
739    
740     DbInstrumentsMutex.Unlock();
741     }
742    
743 iliev 1200 void InstrumentsDb::AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat, ScanProgress* pProgress) {
744 iliev 1161 dmsg(2,("InstrumentsDb: AddInstrumentsRecursive(DbDir=%s,FsDir=%s,Flat=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat));
745 iliev 1200 if (pProgress != NULL) {
746     pProgress->SetTotalFileCount(InstrumentFileCounter::Count(FsDir));
747     }
748    
749     DirectoryScanner::Scan(DbDir, FsDir, Flat, pProgress);
750 iliev 1161 }
751    
752     int InstrumentsDb::GetInstrumentCount(int DirId) {
753     dmsg(2,("InstrumentsDb: GetInstrumentCount(DirId=%d)\n", DirId));
754     if(DirId == -1) return -1;
755    
756     std::stringstream sql;
757     sql << "SELECT COUNT(*) FROM instruments WHERE dir_id=" << DirId;
758    
759     return ExecSqlInt(sql.str());
760     }
761    
762 iliev 1187 int InstrumentsDb::GetInstrumentCount(String Dir, bool Recursive) {
763     dmsg(2,("InstrumentsDb: GetInstrumentCount(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
764 iliev 1161 int i;
765    
766 iliev 1187 BeginTransaction();
767     try {
768     if (Recursive) {
769     InstrumentCounter instrumentCounter;
770     DirectoryTreeWalk(Dir, &instrumentCounter);
771     i = instrumentCounter.GetInstrumentCount();
772     } else {
773     i = GetInstrumentCount(GetDirectoryId(Dir));
774     }
775     } catch (Exception e) {
776     EndTransaction();
777 iliev 1161 throw e;
778     }
779 iliev 1187 EndTransaction();
780 iliev 1161
781 iliev 1345 if (i == -1) throw Exception("Unknown Db directory: " + toEscapedPath(Dir));
782 iliev 1161 return i;
783     }
784    
785     IntListPtr InstrumentsDb::GetInstrumentIDs(int DirId) {
786     std::stringstream sql;
787     sql << "SELECT instr_id FROM instruments WHERE dir_id=" << DirId;
788    
789     return ExecSqlIntList(sql.str());
790     }
791    
792 iliev 1187 StringListPtr InstrumentsDb::GetInstruments(String Dir, bool Recursive) {
793     dmsg(2,("InstrumentsDb: GetInstruments(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
794     BeginTransaction();
795 iliev 1161 try {
796     int dirId = GetDirectoryId(Dir);
797 iliev 1345 if(dirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
798 iliev 1161
799 iliev 1187 StringListPtr pInstrs;
800 iliev 1161
801 iliev 1187 if(Recursive) {
802     SearchQuery q;
803     InstrumentFinder instrumentFinder(&q);
804     DirectoryTreeWalk(Dir, &instrumentFinder);
805     pInstrs = instrumentFinder.GetInstruments();
806     } else {
807     std::stringstream sql;
808     sql << "SELECT instr_name FROM instruments WHERE dir_id=" << dirId;
809    
810     pInstrs = ExecSqlStringList(sql.str());
811     }
812     EndTransaction();
813     return pInstrs;
814 iliev 1161 } catch (Exception e) {
815 iliev 1187 EndTransaction();
816 iliev 1161 throw e;
817     }
818     }
819    
820     int InstrumentsDb::GetInstrumentId(String Instr) {
821     dmsg(2,("InstrumentsDb: GetInstrumentId(Instr=%s)\n", Instr.c_str()));
822     String Dir = GetDirectoryPath(Instr);
823     if (Dir.empty()) return -1;
824    
825     return GetInstrumentId(GetDirectoryId(Dir), GetFileName(Instr));
826     }
827    
828     int InstrumentsDb::GetInstrumentId(int DirId, String InstrName) {
829     dmsg(2,("InstrumentsDb: GetInstrumentId(DirId=%d,InstrName=%s)\n", DirId, InstrName.c_str()));
830     if (DirId == -1 || InstrName.empty()) return -1;
831    
832     std::stringstream sql;
833     sql << "SELECT instr_id FROM instruments WHERE dir_id=";
834     sql << DirId << " AND instr_name=?";
835 iliev 1345 return ExecSqlInt(sql.str(), toDbName(InstrName));
836 iliev 1161 }
837 iliev 1187
838     String InstrumentsDb::GetInstrumentName(int InstrId) {
839     dmsg(2,("InstrumentsDb: GetInstrumentName(InstrId=%d)\n", InstrId));
840     std::stringstream sql;
841     sql << "SELECT instr_name FROM instruments WHERE instr_id=" << InstrId;
842 iliev 1345 return toAbstractName(ExecSqlString(sql.str()));
843 iliev 1187 }
844 iliev 1161
845     void InstrumentsDb::RemoveInstrument(String Instr) {
846     dmsg(2,("InstrumentsDb: RemoveInstrument(Instr=%s)\n", Instr.c_str()));
847     String ParentDir = GetDirectoryPath(Instr);
848     if(ParentDir.empty()) throw Exception("Unknown parent directory");
849    
850 iliev 1187 BeginTransaction();
851 iliev 1161 try {
852     int instrId = GetInstrumentId(Instr);
853     if(instrId == -1) {
854 iliev 1345 throw Exception("The specified instrument does not exist: " + toEscapedPath(Instr));
855 iliev 1161 }
856     RemoveInstrument(instrId);
857     } catch (Exception e) {
858 iliev 1187 EndTransaction();
859 iliev 1161 throw e;
860     }
861 iliev 1187 EndTransaction();
862 iliev 1161 FireInstrumentCountChanged(ParentDir);
863     }
864    
865     void InstrumentsDb::RemoveInstrument(int InstrId) {
866     dmsg(2,("InstrumentsDb: RemoveInstrument(InstrId=%d)\n", InstrId));
867    
868     std::stringstream sql;
869     sql << "DELETE FROM instruments WHERE instr_id=" << InstrId;
870    
871     ExecSql(sql.str());
872     }
873    
874     void InstrumentsDb::RemoveAllInstruments(int DirId) {
875     dmsg(2,("InstrumentsDb: RemoveAllInstruments(DirId=%d)\n", DirId));
876    
877     std::stringstream sql;
878     sql << "DELETE FROM instruments WHERE dir_id=" << DirId;
879     ExecSql(sql.str());
880     }
881    
882     DbInstrument InstrumentsDb::GetInstrumentInfo(String Instr) {
883     dmsg(2,("InstrumentsDb: GetInstrumentInfo(Instr=%s)\n", Instr.c_str()));
884     DbInstrument i;
885    
886 iliev 1187 BeginTransaction();
887 iliev 1161 try {
888     int id = GetInstrumentId(Instr);
889 iliev 1345 if(id == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
890 iliev 1187 i = GetInstrumentInfo(id);
891     } catch (Exception e) {
892     EndTransaction();
893     throw e;
894     }
895     EndTransaction();
896 iliev 1161
897 iliev 1187 return i;
898     }
899 iliev 1161
900 iliev 1187 DbInstrument InstrumentsDb::GetInstrumentInfo(int InstrId) {
901     sqlite3_stmt *pStmt = NULL;
902     std::stringstream sql;
903     sql << "SELECT instr_file,instr_nr,format_family,format_version,";
904     sql << "instr_size,created,modified,description,is_drum,product,";
905     sql << "artists,keywords FROM instruments WHERE instr_id=" << InstrId;
906    
907     int res = sqlite3_prepare(GetDb(), sql.str().c_str(), -1, &pStmt, NULL);
908     if (res != SQLITE_OK) {
909     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
910     }
911    
912     DbInstrument i;
913     res = sqlite3_step(pStmt);
914     if(res == SQLITE_ROW) {
915     i.InstrFile = ToString(sqlite3_column_text(pStmt, 0));
916     i.InstrNr = sqlite3_column_int(pStmt, 1);
917     i.FormatFamily = ToString(sqlite3_column_text(pStmt, 2));
918     i.FormatVersion = ToString(sqlite3_column_text(pStmt, 3));
919     i.Size = sqlite3_column_int64(pStmt, 4);
920     i.Created = ToString(sqlite3_column_text(pStmt, 5));
921     i.Modified = ToString(sqlite3_column_text(pStmt, 6));
922     i.Description = ToString(sqlite3_column_text(pStmt, 7));
923     i.IsDrum = sqlite3_column_int(pStmt, 8);
924     i.Product = ToString(sqlite3_column_text(pStmt, 9));
925     i.Artists = ToString(sqlite3_column_text(pStmt, 10));
926     i.Keywords = ToString(sqlite3_column_text(pStmt, 11));
927     } else {
928     sqlite3_finalize(pStmt);
929    
930     if (res != SQLITE_DONE) {
931 iliev 1161 throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
932     } else {
933 iliev 1187 throw Exception("Unknown DB instrument");
934 iliev 1161 }
935 iliev 1187 }
936 iliev 1161
937 iliev 1187 sqlite3_finalize(pStmt);
938 iliev 1161 return i;
939     }
940    
941     void InstrumentsDb::RenameInstrument(String Instr, String Name) {
942     dmsg(2,("InstrumentsDb: RenameInstrument(Instr=%s,Name=%s)\n", Instr.c_str(), Name.c_str()));
943     CheckFileName(Name);
944    
945 iliev 1187 BeginTransaction();
946 iliev 1161 try {
947     int dirId = GetDirectoryId(GetDirectoryPath(Instr));
948 iliev 1345 if (dirId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
949 iliev 1161
950     int instrId = GetInstrumentId(dirId, GetFileName(Instr));
951 iliev 1345 if (instrId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
952 iliev 1161
953     if (GetInstrumentId(dirId, Name) != -1) {
954 iliev 1345 String s = toEscapedPath(Name);
955     throw Exception("Cannot rename. Instrument with that name already exists: " + s);
956 iliev 1161 }
957    
958 iliev 1187 if (GetDirectoryId(dirId, Name) != -1) {
959 iliev 1345 String s = toEscapedPath(Name);
960     throw Exception("Cannot rename. Directory with that name already exists: " + s);
961 iliev 1187 }
962    
963 iliev 1161 std::stringstream sql;
964     sql << "UPDATE instruments SET instr_name=? WHERE instr_id=" << instrId;
965 iliev 1345 ExecSql(sql.str(), toDbName(Name));
966 iliev 1161 } catch (Exception e) {
967 iliev 1187 EndTransaction();
968 iliev 1161 throw e;
969     }
970 iliev 1187 EndTransaction();
971 iliev 1161 FireInstrumentNameChanged(Instr, Name);
972     }
973    
974     void InstrumentsDb::MoveInstrument(String Instr, String Dst) {
975     dmsg(2,("InstrumentsDb: MoveInstrument(Instr=%s,Dst=%s)\n", Instr.c_str(), Dst.c_str()));
976     String ParentDir = GetDirectoryPath(Instr);
977     if(ParentDir.empty()) throw Exception("Unknown parent directory");
978    
979 iliev 1187 BeginTransaction();
980 iliev 1161 try {
981 iliev 1345 int dirId = GetDirectoryId(ParentDir);
982     if (dirId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
983 iliev 1161
984     String instrName = GetFileName(Instr);
985     int instrId = GetInstrumentId(dirId, instrName);
986 iliev 1345 if (instrId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
987 iliev 1161
988     int dstId = GetDirectoryId(Dst);
989 iliev 1345 if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
990 iliev 1161 if (dirId == dstId) {
991 iliev 1187 EndTransaction();
992 iliev 1161 return;
993     }
994    
995     if (GetInstrumentId(dstId, instrName) != -1) {
996 iliev 1345 String s = toEscapedPath(instrName);
997     throw Exception("Cannot move. Instrument with that name already exists: " + s);
998 iliev 1161 }
999    
1000 iliev 1187 if (GetDirectoryId(dstId, instrName) != -1) {
1001 iliev 1345 String s = toEscapedPath(instrName);
1002     throw Exception("Cannot move. Directory with that name already exists: " + s);
1003 iliev 1187 }
1004    
1005 iliev 1161 std::stringstream sql;
1006     sql << "UPDATE instruments SET dir_id=" << dstId;
1007     sql << " WHERE instr_id=" << instrId;
1008     ExecSql(sql.str());
1009     } catch (Exception e) {
1010 iliev 1187 EndTransaction();
1011 iliev 1161 throw e;
1012     }
1013 iliev 1187 EndTransaction();
1014 iliev 1161 FireInstrumentCountChanged(ParentDir);
1015     FireInstrumentCountChanged(Dst);
1016     }
1017    
1018 iliev 1187 void InstrumentsDb::CopyInstrument(String Instr, String Dst) {
1019     dmsg(2,("InstrumentsDb: CopyInstrument(Instr=%s,Dst=%s)\n", Instr.c_str(), Dst.c_str()));
1020     String ParentDir = GetDirectoryPath(Instr);
1021     if(ParentDir.empty()) throw Exception("Unknown parent directory");
1022    
1023     BeginTransaction();
1024     try {
1025     int dirId = GetDirectoryId(GetDirectoryPath(Instr));
1026 iliev 1345 if (dirId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
1027 iliev 1187
1028     String instrName = GetFileName(Instr);
1029     int instrId = GetInstrumentId(dirId, instrName);
1030 iliev 1345 if (instrId == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
1031 iliev 1187
1032     int dstId = GetDirectoryId(Dst);
1033 iliev 1345 if (dstId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dst));
1034 iliev 1187 if (dirId == dstId) {
1035     EndTransaction();
1036     return;
1037     }
1038    
1039     if (GetInstrumentId(dstId, instrName) != -1) {
1040 iliev 1345 String s = toEscapedPath(instrName);
1041     throw Exception("Cannot copy. Instrument with that name already exists: " + s);
1042 iliev 1187 }
1043    
1044     if (GetDirectoryId(dstId, instrName) != -1) {
1045 iliev 1345 String s = toEscapedPath(instrName);
1046     throw Exception("Cannot copy. Directory with that name already exists: " + s);
1047 iliev 1187 }
1048    
1049     CopyInstrument(instrId, instrName, dstId, Dst);
1050     } catch (Exception e) {
1051     EndTransaction();
1052     throw e;
1053     }
1054     EndTransaction();
1055    
1056     }
1057    
1058     void InstrumentsDb::CopyInstrument(int InstrId, String InstrName, int DstDirId, String DstDir) {
1059     DbInstrument i = GetInstrumentInfo(InstrId);
1060     sqlite3_stmt *pStmt = NULL;
1061     std::stringstream sql;
1062     sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,instr_nr,format_family,";
1063     sql << "format_version,instr_size,description,is_drum,product,artists,keywords) ";
1064     sql << "VALUES (" << DstDirId << ",?,?," << i.InstrNr << ",?,?," << i.Size << ",?,";
1065     sql << i.IsDrum << ",?,?,?)";
1066    
1067     int res = sqlite3_prepare(GetDb(), sql.str().c_str(), -1, &pStmt, NULL);
1068     if (res != SQLITE_OK) {
1069     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1070     }
1071    
1072 iliev 1345 BindTextParam(pStmt, 1, toDbName(InstrName));
1073 iliev 1187 BindTextParam(pStmt, 2, i.InstrFile);
1074     BindTextParam(pStmt, 3, i.FormatFamily);
1075     BindTextParam(pStmt, 4, i.FormatVersion);
1076     BindTextParam(pStmt, 5, i.Description);
1077     BindTextParam(pStmt, 6, i.Product);
1078     BindTextParam(pStmt, 7, i.Artists);
1079     BindTextParam(pStmt, 8, i.Keywords);
1080    
1081     res = sqlite3_step(pStmt);
1082     if(res != SQLITE_DONE) {
1083     sqlite3_finalize(pStmt);
1084     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1085     }
1086    
1087     sqlite3_finalize(pStmt);
1088     FireInstrumentCountChanged(DstDir);
1089     }
1090    
1091 iliev 1161 void InstrumentsDb::SetInstrumentDescription(String Instr, String Desc) {
1092     dmsg(2,("InstrumentsDb: SetInstrumentDescription(Instr=%s,Desc=%s)\n", Instr.c_str(), Desc.c_str()));
1093    
1094 iliev 1187 BeginTransaction();
1095 iliev 1161 try {
1096     int id = GetInstrumentId(Instr);
1097 iliev 1345 if(id == -1) throw Exception("Unknown DB instrument: " + toEscapedPath(Instr));
1098 iliev 1161
1099     std::stringstream sql;
1100     sql << "UPDATE instruments SET description=?,modified=CURRENT_TIMESTAMP ";
1101     sql << "WHERE instr_id="<< id;
1102    
1103     ExecSql(sql.str(), Desc);
1104     } catch (Exception e) {
1105 iliev 1187 EndTransaction();
1106 iliev 1161 throw e;
1107     }
1108 iliev 1187 EndTransaction();
1109 iliev 1161 FireInstrumentInfoChanged(Instr);
1110     }
1111    
1112 iliev 1200 void InstrumentsDb::AddInstrumentsFromFile(String DbDir, String File, int Index, ScanProgress* pProgress) {
1113 iliev 1161 dmsg(2,("InstrumentsDb: AddInstrumentsFromFile(DbDir=%s,File=%s,Index=%d)\n", DbDir.c_str(), File.c_str(), Index));
1114    
1115     if(File.length() < 4) return;
1116    
1117     try {
1118     if(!strcasecmp(".gig", File.substr(File.length() - 4).c_str())) {
1119 iliev 1200 if (pProgress != NULL) {
1120     pProgress->SetStatus(0);
1121     pProgress->CurrentFile = File;
1122     }
1123    
1124     AddGigInstruments(DbDir, File, Index, pProgress);
1125    
1126     if (pProgress != NULL) {
1127     pProgress->SetScannedFileCount(pProgress->GetScannedFileCount() + 1);
1128     }
1129 iliev 1161 }
1130     } catch(Exception e) {
1131 iliev 1187 std::cerr << e.Message() << std::endl;
1132 iliev 1161 }
1133     }
1134    
1135 iliev 1200 void InstrumentsDb::AddGigInstruments(String DbDir, String File, int Index, ScanProgress* pProgress) {
1136 iliev 1161 dmsg(2,("InstrumentsDb: AddGigInstruments(DbDir=%s,File=%s,Index=%d)\n", DbDir.c_str(), File.c_str(), Index));
1137     int dirId = GetDirectoryId(DbDir);
1138 iliev 1345 if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));
1139 iliev 1161
1140     struct stat statBuf;
1141     int res = stat(File.c_str(), &statBuf);
1142     if (res) {
1143     std::stringstream ss;
1144     ss << "Fail to stat `" << File << "`: " << strerror(errno);
1145     throw Exception(ss.str());
1146     }
1147    
1148     if (!S_ISREG(statBuf.st_mode)) {
1149     std::stringstream ss;
1150     ss << "`" << File << "` is not a regular file";
1151     throw Exception(ss.str());
1152     }
1153    
1154     RIFF::File* riff = NULL;
1155     gig::File* gig = NULL;
1156     try {
1157     riff = new RIFF::File(File);
1158     gig::File* gig = new gig::File(riff);
1159 iliev 1200
1160 iliev 1161 std::stringstream sql;
1161     sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,";
1162     sql << "instr_nr,format_family,format_version,instr_size,";
1163     sql << "description,is_drum,product,artists,keywords) VALUES (";
1164     sql << dirId << ",?,?,?,'GIG',?," << statBuf.st_size << ",?,?,?,?,?)";
1165    
1166     sqlite3_stmt* pStmt = NULL;
1167    
1168     int res = sqlite3_prepare(GetDb(), sql.str().c_str(), -1, &pStmt, NULL);
1169     if (res != SQLITE_OK) {
1170     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1171     }
1172    
1173     BindTextParam(pStmt, 2, File);
1174     String ver = "";
1175     if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);
1176     BindTextParam(pStmt, 4, ver);
1177    
1178     if (Index == -1) {
1179     int instrIndex = 0;
1180 iliev 1200 if (pProgress != NULL) gig->GetInstrument(0, &(pProgress->GigFileProgress)); // TODO: this workaround should be fixed
1181 iliev 1161 gig::Instrument* pInstrument = gig->GetFirstInstrument();
1182     while (pInstrument) {
1183     BindTextParam(pStmt, 7, gig->pInfo->Product);
1184     BindTextParam(pStmt, 8, gig->pInfo->Artists);
1185     BindTextParam(pStmt, 9, gig->pInfo->Keywords);
1186     AddGigInstrument(pStmt, DbDir, dirId, File, pInstrument, instrIndex);
1187    
1188     instrIndex++;
1189     pInstrument = gig->GetNextInstrument();
1190     }
1191     } else {
1192 iliev 1200 gig::Instrument* pInstrument;
1193     if (pProgress == NULL) pInstrument = gig->GetInstrument(Index);
1194     else pInstrument = gig->GetInstrument(Index, &(pProgress->GigFileProgress));
1195 iliev 1161 if (pInstrument != NULL) {
1196     BindTextParam(pStmt, 7, gig->pInfo->Product);
1197     BindTextParam(pStmt, 8, gig->pInfo->Artists);
1198     BindTextParam(pStmt, 9, gig->pInfo->Keywords);
1199     AddGigInstrument(pStmt, DbDir, dirId, File, pInstrument, Index);
1200     }
1201     }
1202    
1203 iliev 1187 sqlite3_finalize(pStmt);
1204 iliev 1161 delete gig;
1205     delete riff;
1206     } catch (RIFF::Exception e) {
1207     if (gig != NULL) delete gig;
1208     if (riff != NULL) delete riff;
1209     std::stringstream ss;
1210     ss << "Failed to scan `" << File << "`: " << e.Message;
1211    
1212     throw Exception(ss.str());
1213     } catch (Exception e) {
1214     if (gig != NULL) delete gig;
1215     if (riff != NULL) delete riff;
1216     throw e;
1217     } catch (...) {
1218     if (gig != NULL) delete gig;
1219     if (riff != NULL) delete riff;
1220     throw Exception("Failed to scan `" + File + "`");
1221     }
1222     }
1223    
1224 iliev 1187 void InstrumentsDb::AddGigInstrument(sqlite3_stmt* pStmt, String DbDir, int DirId, String File, gig::Instrument* pInstrument, int Index) {
1225 iliev 1161 String name = pInstrument->pInfo->Name;
1226     if (name == "") return;
1227     name = GetUniqueInstrumentName(DirId, name);
1228    
1229     std::stringstream sql2;
1230     sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";
1231     sql2 << "instr_nr=" << Index;
1232     if (ExecSqlInt(sql2.str(), File) > 0) return;
1233    
1234     BindTextParam(pStmt, 1, name);
1235     BindIntParam(pStmt, 3, Index);
1236    
1237     BindTextParam(pStmt, 5, pInstrument->pInfo->Comments);
1238     BindIntParam(pStmt, 6, pInstrument->IsDrum);
1239    
1240     if (!pInstrument->pInfo->Product.empty()) {
1241     BindTextParam(pStmt, 7, pInstrument->pInfo->Product);
1242     }
1243     if (!pInstrument->pInfo->Artists.empty()) {
1244     BindTextParam(pStmt, 8, pInstrument->pInfo->Artists);
1245     }
1246    
1247     if (!pInstrument->pInfo->Keywords.empty()) {
1248     BindTextParam(pStmt, 9, pInstrument->pInfo->Keywords);
1249     }
1250    
1251     int res = sqlite3_step(pStmt);
1252     if(res != SQLITE_DONE) {
1253     sqlite3_finalize(pStmt);
1254     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1255     }
1256    
1257     res = sqlite3_reset(pStmt);
1258     FireInstrumentCountChanged(DbDir);
1259     }
1260    
1261 iliev 1345 void InstrumentsDb::DirectoryTreeWalk(String AbstractPath, DirectoryHandler* pHandler) {
1262     int DirId = GetDirectoryId(AbstractPath);
1263     if(DirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(AbstractPath));
1264     DirectoryTreeWalk(pHandler, AbstractPath, DirId, 0);
1265 iliev 1187 }
1266    
1267 iliev 1345 void InstrumentsDb::DirectoryTreeWalk(DirectoryHandler* pHandler, String AbstractPath, int DirId, int Level) {
1268 iliev 1187 if(Level == 1000) throw Exception("Possible infinite loop detected");
1269 iliev 1345 pHandler->ProcessDirectory(AbstractPath, DirId);
1270 iliev 1187
1271     String s;
1272     StringListPtr pDirs = GetDirectories(DirId);
1273     for(int i = 0; i < pDirs->size(); i++) {
1274 iliev 1345 if (AbstractPath.length() == 1 && AbstractPath.at(0) == '/') {
1275     s = "/" + pDirs->at(i);
1276     } else {
1277     s = AbstractPath + "/" + pDirs->at(i);
1278     }
1279 iliev 1187 DirectoryTreeWalk(pHandler, s, GetDirectoryId(DirId, pDirs->at(i)), Level + 1);
1280     }
1281     }
1282    
1283     StringListPtr InstrumentsDb::FindDirectories(String Dir, SearchQuery* pQuery, bool Recursive) {
1284     dmsg(2,("InstrumentsDb: FindDirectories(Dir=%s)\n", Dir.c_str()));
1285     DirectoryFinder directoryFinder(pQuery);
1286    
1287     BeginTransaction();
1288     try {
1289     int DirId = GetDirectoryId(Dir);
1290 iliev 1345 if(DirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
1291 iliev 1187
1292     if (Recursive) DirectoryTreeWalk(Dir, &directoryFinder);
1293     else directoryFinder.ProcessDirectory(Dir, DirId);
1294     } catch (Exception e) {
1295     EndTransaction();
1296     throw e;
1297     }
1298     EndTransaction();
1299    
1300     return directoryFinder.GetDirectories();
1301     }
1302    
1303     StringListPtr InstrumentsDb::FindInstruments(String Dir, SearchQuery* pQuery, bool Recursive) {
1304     dmsg(2,("InstrumentsDb: FindInstruments(Dir=%s)\n", Dir.c_str()));
1305     InstrumentFinder instrumentFinder(pQuery);
1306    
1307     BeginTransaction();
1308     try {
1309     int DirId = GetDirectoryId(Dir);
1310 iliev 1345 if(DirId == -1) throw Exception("Unknown DB directory: " + toEscapedPath(Dir));
1311 iliev 1187
1312     if (Recursive) DirectoryTreeWalk(Dir, &instrumentFinder);
1313     else instrumentFinder.ProcessDirectory(Dir, DirId);
1314     } catch (Exception e) {
1315     EndTransaction();
1316     throw e;
1317     }
1318     EndTransaction();
1319    
1320     return instrumentFinder.GetInstruments();
1321     }
1322    
1323     void InstrumentsDb::BeginTransaction() {
1324     dmsg(2,("InstrumentsDb: BeginTransaction(InTransaction=%d)\n", InTransaction));
1325     DbInstrumentsMutex.Lock();
1326     if (InTransaction) return;
1327    
1328     if(db == NULL) return;
1329     sqlite3_stmt *pStmt = NULL;
1330    
1331     InTransaction = true;
1332     int res = sqlite3_prepare(db, "BEGIN TRANSACTION", -1, &pStmt, NULL);
1333     if (res != SQLITE_OK) {
1334     std::cerr << ToString(sqlite3_errmsg(db)) << std::endl;
1335     return;
1336     }
1337    
1338     res = sqlite3_step(pStmt);
1339     if(res != SQLITE_DONE) {
1340     sqlite3_finalize(pStmt);
1341     std::cerr << ToString(sqlite3_errmsg(db)) << std::endl;
1342     return;
1343     }
1344    
1345     sqlite3_finalize(pStmt);
1346     }
1347    
1348     void InstrumentsDb::EndTransaction() {
1349     dmsg(2,("InstrumentsDb: EndTransaction(InTransaction=%d)\n", InTransaction));
1350     if (!InTransaction) {
1351     DbInstrumentsMutex.Unlock();
1352     return;
1353     }
1354     InTransaction = false;
1355    
1356     if(db == NULL) {
1357     DbInstrumentsMutex.Unlock();
1358     return;
1359     }
1360     sqlite3_stmt *pStmt = NULL;
1361    
1362     int res = sqlite3_prepare(db, "END TRANSACTION", -1, &pStmt, NULL);
1363     if (res != SQLITE_OK) {
1364     std::cerr << ToString(sqlite3_errmsg(db)) << std::endl;
1365     DbInstrumentsMutex.Unlock();
1366     return;
1367     }
1368    
1369     res = sqlite3_step(pStmt);
1370     if(res != SQLITE_DONE) {
1371     sqlite3_finalize(pStmt);
1372     std::cerr << ToString(sqlite3_errmsg(db)) << std::endl;
1373     DbInstrumentsMutex.Unlock();
1374     return;
1375     }
1376    
1377     sqlite3_finalize(pStmt);
1378     DbInstrumentsMutex.Unlock();
1379     }
1380    
1381 iliev 1161 void InstrumentsDb::ExecSql(String Sql) {
1382     dmsg(2,("InstrumentsDb: ExecSql(Sql=%s)\n", Sql.c_str()));
1383     sqlite3_stmt *pStmt = NULL;
1384    
1385     int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL);
1386     if (res != SQLITE_OK) {
1387     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1388     }
1389    
1390     res = sqlite3_step(pStmt);
1391     if(res != SQLITE_DONE) {
1392     sqlite3_finalize(pStmt);
1393     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1394     }
1395    
1396     sqlite3_finalize(pStmt);
1397     }
1398    
1399     void InstrumentsDb::ExecSql(String Sql, String Param) {
1400     dmsg(2,("InstrumentsDb: ExecSql(Sql=%s,Param=%s)\n", Sql.c_str(), Param.c_str()));
1401     sqlite3_stmt *pStmt = NULL;
1402    
1403     int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL);
1404     if (res != SQLITE_OK) {
1405     sqlite3_finalize(pStmt);
1406     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1407     }
1408    
1409     BindTextParam(pStmt, 1, Param);
1410    
1411     res = sqlite3_step(pStmt);
1412     if (res != SQLITE_DONE) {
1413     sqlite3_finalize(pStmt);
1414     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1415     }
1416    
1417     sqlite3_finalize(pStmt);
1418     }
1419    
1420     int InstrumentsDb::ExecSqlInt(String Sql) {
1421     dmsg(2,("InstrumentsDb: ExecSqlInt(Sql=%s)\n", Sql.c_str()));
1422     sqlite3_stmt *pStmt = NULL;
1423    
1424     int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL);
1425     if (res != SQLITE_OK) {
1426     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1427     }
1428    
1429     int i = -1;
1430     res = sqlite3_step(pStmt);
1431     if(res == SQLITE_ROW) {
1432     i = sqlite3_column_int(pStmt, 0);
1433     } else if (res != SQLITE_DONE) {
1434     sqlite3_finalize(pStmt);
1435     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1436     }
1437    
1438     sqlite3_finalize(pStmt);
1439    
1440     return i;
1441     }
1442    
1443     int InstrumentsDb::ExecSqlInt(String Sql, String Param) {
1444     dmsg(2,("InstrumentsDb: ExecSqlInt(Sql=%s,Param=%s)\n", Sql.c_str(), Param.c_str()));
1445     sqlite3_stmt *pStmt = NULL;
1446    
1447     int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL);
1448     if (res != SQLITE_OK) {
1449     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1450     }
1451    
1452     BindTextParam(pStmt, 1, Param);
1453    
1454     int i = -1;
1455     res = sqlite3_step(pStmt);
1456     if(res == SQLITE_ROW) {
1457     i = sqlite3_column_int(pStmt, 0);
1458     } else if (res != SQLITE_DONE) {
1459     sqlite3_finalize(pStmt);
1460     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1461     }
1462    
1463     sqlite3_finalize(pStmt);
1464     return i;
1465     }
1466    
1467     String InstrumentsDb::ExecSqlString(String Sql) {
1468     dmsg(2,("InstrumentsDb: ExecSqlString(Sql=%s)\n", Sql.c_str()));
1469     sqlite3_stmt *pStmt = NULL;
1470    
1471     int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL);
1472     if (res != SQLITE_OK) {
1473     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1474     }
1475    
1476     String s;
1477     res = sqlite3_step(pStmt);
1478     if(res == SQLITE_ROW) {
1479     s = ToString(sqlite3_column_text(pStmt, 0));
1480     } else if (res != SQLITE_DONE) {
1481     sqlite3_finalize(pStmt);
1482     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1483     }
1484    
1485     sqlite3_finalize(pStmt);
1486    
1487     return s;
1488     }
1489    
1490     IntListPtr InstrumentsDb::ExecSqlIntList(String Sql) {
1491     IntListPtr intList(new std::vector<int>);
1492    
1493     sqlite3_stmt *pStmt = NULL;
1494    
1495     int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL);
1496     if (res != SQLITE_OK) {
1497     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1498     }
1499    
1500     res = sqlite3_step(pStmt);
1501     while(res == SQLITE_ROW) {
1502     intList->push_back(sqlite3_column_int(pStmt, 0));
1503     res = sqlite3_step(pStmt);
1504     }
1505    
1506     if (res != SQLITE_DONE) {
1507     sqlite3_finalize(pStmt);
1508     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1509     }
1510    
1511     sqlite3_finalize(pStmt);
1512    
1513     return intList;
1514     }
1515    
1516     StringListPtr InstrumentsDb::ExecSqlStringList(String Sql) {
1517     StringListPtr stringList(new std::vector<String>);
1518    
1519     sqlite3_stmt *pStmt = NULL;
1520    
1521     int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL);
1522     if (res != SQLITE_OK) {
1523     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1524     }
1525    
1526     res = sqlite3_step(pStmt);
1527     while(res == SQLITE_ROW) {
1528     stringList->push_back(ToString(sqlite3_column_text(pStmt, 0)));
1529     res = sqlite3_step(pStmt);
1530     }
1531    
1532     if (res != SQLITE_DONE) {
1533     sqlite3_finalize(pStmt);
1534     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1535     }
1536    
1537     sqlite3_finalize(pStmt);
1538    
1539     return stringList;
1540     }
1541    
1542     void InstrumentsDb::BindTextParam(sqlite3_stmt* pStmt, int Index, String Text) {
1543     if (pStmt == NULL) return;
1544     int res = sqlite3_bind_text(pStmt, Index, Text.c_str(), -1, SQLITE_STATIC);
1545     if (res != SQLITE_OK) {
1546     sqlite3_finalize(pStmt);
1547     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1548     }
1549     }
1550    
1551     void InstrumentsDb::BindIntParam(sqlite3_stmt* pStmt, int Index, int Param) {
1552     if (pStmt == NULL) return;
1553     int res = sqlite3_bind_int(pStmt, Index, Param);
1554     if (res != SQLITE_OK) {
1555     sqlite3_finalize(pStmt);
1556     throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1557     }
1558     }
1559    
1560 iliev 1187 void InstrumentsDb::Regexp(sqlite3_context* pContext, int argc, sqlite3_value** ppValue) {
1561     if (argc != 2) return;
1562    
1563     String pattern = ToString(sqlite3_value_text(ppValue[0]));
1564     String str = ToString(sqlite3_value_text(ppValue[1]));
1565    
1566     if(!fnmatch(pattern.c_str(), str.c_str(), FNM_CASEFOLD)) {
1567     sqlite3_result_int(pContext, 1);
1568     }
1569     }
1570    
1571 iliev 1161 String InstrumentsDb::GetDirectoryPath(String File) {
1572     if (File.empty()) return String("");
1573     if (File.at(0) != '/') String("");
1574     if (File.length() == 1) return File;
1575     if (File.at(File.length() - 1) == '/') return File.substr(0, File.length() - 1);
1576     int i = File.rfind('/', File.length() - 1);
1577     if(i == std::string::npos) return String("");
1578     if(i == 0) return String("/");
1579     return File.substr(0, i);
1580     }
1581    
1582     String InstrumentsDb::GetFileName(String Path) {
1583     if (Path.length() < 2) return String("");
1584     if (Path.at(0) != '/') String("");
1585     if (Path.at(Path.length() - 1) == '/') return String("");
1586     int i = Path.rfind('/', Path.length() - 1);
1587     return Path.substr(i + 1);
1588     }
1589    
1590     void InstrumentsDb::CheckPathName(String Path) {
1591     if (Path.empty()) return;
1592    
1593     int i = 0, j = Path.find('/', i);
1594    
1595     while(j != std::string::npos) {
1596     if (j + 1 >= Path.length()) return;
1597     if (Path.at(j + 1) == '/') throw Exception("Invalid path name: " + Path);
1598    
1599     i = j + 1;
1600     j = Path.find('/', i);
1601     }
1602     }
1603    
1604     String InstrumentsDb::GetParentDirectory(String Dir) {
1605     if (Dir.length() < 2) return String("");
1606     if (Dir.at(0) != '/') String("");
1607     int i = Dir.rfind('/', Dir.length() - 2);
1608     if (i == 0) return "/";
1609     return Dir.substr(0, i);
1610     }
1611    
1612     void InstrumentsDb::CheckFileName(String File) {
1613     if (File.empty()) throw Exception("Invalid file name: " + File);
1614     }
1615    
1616     String InstrumentsDb::GetUniqueInstrumentName(int DirId, String Name) {
1617     dmsg(2,("InstrumentsDb: GetUniqueInstrumentName(DirId=%d,Name=%s)\n", DirId, Name.c_str()));
1618    
1619 iliev 1187 if (GetInstrumentId(DirId, Name) == -1 && GetDirectoryId(DirId, Name) == -1) return Name;
1620 iliev 1161 std::stringstream ss;
1621     for(int i = 2; i < 1001; i++) {
1622     ss.str("");
1623     ss << Name << '[' << i << ']';
1624 iliev 1187 if (GetInstrumentId(DirId, ss.str()) == -1 && GetInstrumentId(DirId, ss.str()) == -1) {
1625     return ss.str();
1626     }
1627 iliev 1161 }
1628    
1629     throw Exception("Unable to find an unique name: " + Name);
1630     }
1631 iliev 1200
1632 iliev 1345 String InstrumentsDb::toDbName(String AbstractName) {
1633     for (int i = 0; i < AbstractName.length(); i++) {
1634     if (AbstractName.at(i) == '\0') AbstractName.at(i) = '/';
1635     }
1636     return AbstractName;
1637     }
1638    
1639     String InstrumentsDb::toEscapedPath(String AbstractName) {
1640     for (int i = 0; i < AbstractName.length(); i++) {
1641     if (AbstractName.at(i) == '\0') AbstractName.replace(i++, 1, "\\/");
1642     else if (AbstractName.at(i) == '\\') AbstractName.replace(i++, 1, "\\\\");
1643     else if (AbstractName.at(i) == '\'') AbstractName.replace(i++, 1, "\\'");
1644     else if (AbstractName.at(i) == '"') AbstractName.replace(i++, 1, "\\\"");
1645     else if (AbstractName.at(i) == '\r') AbstractName.replace(i++, 1, "\\r");
1646     else if (AbstractName.at(i) == '\n') AbstractName.replace(i++, 1, "\\n");
1647     }
1648     return AbstractName;
1649     }
1650    
1651     String InstrumentsDb::toEscapedText(String text) {
1652     for (int i = 0; i < text.length(); i++) {
1653     if (text.at(i) == '\\') text.replace(i++, 1, "\\\\");
1654     else if (text.at(i) == '\'') text.replace(i++, 1, "\\'");
1655     else if (text.at(i) == '"') text.replace(i++, 1, "\\\"");
1656     else if (text.at(i) == '\r') text.replace(i++, 1, "\\r");
1657     else if (text.at(i) == '\n') text.replace(i++, 1, "\\n");
1658     }
1659     return text;
1660     }
1661    
1662     String InstrumentsDb::toEscapedName(String AbstractName) {
1663     for (int i = 0; i < AbstractName.length(); i++) {
1664     if (AbstractName.at(i) == '\0') AbstractName.at(i) = '/';
1665     else if (AbstractName.at(i) == '\\') AbstractName.replace(i++, 1, "\\\\");
1666     else if (AbstractName.at(i) == '\'') AbstractName.replace(i++, 1, "\\'");
1667     else if (AbstractName.at(i) == '"') AbstractName.replace(i++, 1, "\\\"");
1668     else if (AbstractName.at(i) == '\r') AbstractName.replace(i++, 1, "\\r");
1669     else if (AbstractName.at(i) == '\n') AbstractName.replace(i++, 1, "\\n");
1670     }
1671     return AbstractName;
1672     }
1673    
1674     String InstrumentsDb::toAbstractName(String DbName) {
1675     for (int i = 0; i < DbName.length(); i++) {
1676     if (DbName.at(i) == '/') DbName.at(i) = '\0';
1677     }
1678     return DbName;
1679     }
1680    
1681 iliev 1161 void InstrumentsDb::FireDirectoryCountChanged(String Dir) {
1682     for (int i = 0; i < llInstrumentsDbListeners.GetListenerCount(); i++) {
1683     llInstrumentsDbListeners.GetListener(i)->DirectoryCountChanged(Dir);
1684     }
1685     }
1686 iliev 1200
1687 iliev 1161 void InstrumentsDb::FireDirectoryInfoChanged(String Dir) {
1688     for (int i = 0; i < llInstrumentsDbListeners.GetListenerCount(); i++) {
1689     llInstrumentsDbListeners.GetListener(i)->DirectoryInfoChanged(Dir);
1690     }
1691     }
1692 iliev 1200
1693 iliev 1161 void InstrumentsDb::FireDirectoryNameChanged(String Dir, String NewName) {
1694     for (int i = 0; i < llInstrumentsDbListeners.GetListenerCount(); i++) {
1695     llInstrumentsDbListeners.GetListener(i)->DirectoryNameChanged(Dir, NewName);
1696     }
1697     }
1698 iliev 1200
1699 iliev 1161 void InstrumentsDb::FireInstrumentCountChanged(String Dir) {
1700     for (int i = 0; i < llInstrumentsDbListeners.GetListenerCount(); i++) {
1701     llInstrumentsDbListeners.GetListener(i)->InstrumentCountChanged(Dir);
1702     }
1703     }
1704 iliev 1200
1705 iliev 1161 void InstrumentsDb::FireInstrumentInfoChanged(String Instr) {
1706     for (int i = 0; i < llInstrumentsDbListeners.GetListenerCount(); i++) {
1707     llInstrumentsDbListeners.GetListener(i)->InstrumentInfoChanged(Instr);
1708     }
1709     }
1710 iliev 1200
1711 iliev 1161 void InstrumentsDb::FireInstrumentNameChanged(String Instr, String NewName) {
1712     for (int i = 0; i < llInstrumentsDbListeners.GetListenerCount(); i++) {
1713     llInstrumentsDbListeners.GetListener(i)->InstrumentNameChanged(Instr, NewName);
1714     }
1715     }
1716    
1717 iliev 1200 void InstrumentsDb::FireJobStatusChanged(int JobId) {
1718     for (int i = 0; i < llInstrumentsDbListeners.GetListenerCount(); i++) {
1719     llInstrumentsDbListeners.GetListener(i)->JobStatusChanged(JobId);
1720 iliev 1161 }
1721     }
1722    
1723     } // namespace LinuxSampler
1724    
1725     #endif // HAVE_SQLITE3

  ViewVC Help
Powered by ViewVC