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

Contents of /linuxsampler/trunk/src/db/InstrumentsDb.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1163 - (show annotations) (download) (as text)
Mon Apr 16 21:56:18 2007 UTC (17 years ago) by iliev
File MIME type: text/x-c++hdr
File size: 27744 byte(s)
* added check for the presence of sqlite3 program

1 /***************************************************************************
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 "../common/global.h"
22
23 #if HAVE_SQLITE3
24
25 #ifndef __LS_INSTRUMENTSDB_H__
26 #define __LS_INSTRUMENTSDB_H__
27
28 #include <sqlite3.h>
29 #include <vector>
30 #include <sys/stat.h>
31 #include <gig.h>
32 #include "../common/Mutex.h"
33 #include "../EventListeners.h"
34
35 namespace LinuxSampler {
36
37 class DbInstrument {
38 public:
39 String InstrFile;
40 int InstrNr;
41 String FormatFamily;
42 String FormatVersion;
43 long long int Size;
44 String Created;
45 String Modified;
46 String Description;
47 bool IsDrum;
48 String Product;
49 String Artists;
50 String Keywords;
51
52 DbInstrument() { }
53 DbInstrument(const DbInstrument& Instr) { Copy(Instr); }
54 void operator=(const DbInstrument& Instr) { Copy(Instr); }
55 void Copy(const DbInstrument&);
56 };
57
58 class DbDirectory {
59 public:
60 String Created;
61 String Modified;
62 String Description;
63
64 DbDirectory() { }
65 DbDirectory(const DbDirectory& Dir) { Copy(Dir); }
66 void operator=(const DbDirectory& Dir) { Copy(Dir); }
67 void Copy(const DbDirectory&);
68 };
69
70 typedef std::auto_ptr<std::vector<int> > IntListPtr;
71 typedef std::auto_ptr<std::vector<String> > StringListPtr;
72
73 /**
74 * @brief Provides access to the instruments database.
75 */
76 class InstrumentsDb {
77 public:
78
79 /**
80 * This class is used as a listener, which is notified when
81 * changes to the instruments database are made.
82 */
83 class Listener {
84 public:
85 /**
86 * Invoked when the number of instrument directories
87 * in a specific directory has changed.
88 * @param Dir The absolute pathname of the directory in
89 * which the number of directories is changed.
90 */
91 virtual void DirectoryCountChanged(String Dir) = 0;
92
93 /**
94 * Invoked when the settings of an instrument directory
95 * are changed.
96 * @param Dir The absolute pathname of the directory
97 * whose settings are changed.
98 */
99 virtual void DirectoryInfoChanged(String Dir) = 0;
100
101 /**
102 * Invoked when an instrument directory is renamed.
103 * @param Dir The old absolute pathname of the directory.
104 * @param NewName The new name of the directory.
105 */
106 virtual void DirectoryNameChanged(String Dir, String NewName) = 0;
107
108 /**
109 * Invoked when the number of instruments
110 * in a specific directory has changed.
111 * @param Dir The absolute pathname of the directory in
112 * which the number of instruments is changed.
113 */
114 virtual void InstrumentCountChanged(String Dir) = 0;
115
116 /**
117 * Invoked when the settings of an instrument are changed.
118 * @param Instr The absolute pathname of the instrument
119 * whose settings are changed.
120 */
121 virtual void InstrumentInfoChanged(String Instr) = 0;
122
123 /**
124 * Invoked when an instrument is renamed.
125 * @param Instr The old absolute pathname of the instrument.
126 * @param NewName The new name of the directory.
127 */
128 virtual void InstrumentNameChanged(String Instr, String NewName) = 0;
129 };
130
131 /**
132 * Registers the specified listener to be notified
133 * when changes to the instruments database are made.
134 */
135 void AddInstrumentsDbListener(InstrumentsDb::Listener* l);
136
137 /**
138 * Removes the specified listener.
139 */
140 void RemoveInstrumentsDbListener(InstrumentsDb::Listener* l);
141
142 /**
143 * This method is used to access the instruments database.
144 */
145 static InstrumentsDb* GetInstrumentsDb();
146
147 /**
148 * Sets the absolute path name of the instruments database file to use.
149 * The instruments database file location should be set before
150 * any attempt to access the database and once set could not be changed.
151 * @throws Exception - if an empty string is provided or if
152 * the method is called more than once.
153 */
154 void SetDbFile(String File);
155
156 /**
157 * Gets the number of directories in the specified directory.
158 * @param Dir The absolute path name of the directory.
159 * @throws Exception - if database error occurs, or
160 * the specified path name is invalid.
161 * @returns The number of directories in the specified directory.
162 */
163 int GetDirectoryCount(String Dir);
164
165 /**
166 * Gets the list of directories in the specified directory.
167 * @param Dir The absolute path name of the directory.
168 * @throws Exception - if database error occurs, or
169 * the specified path name is invalid.
170 */
171 StringListPtr GetDirectories(String Dir);
172
173 /**
174 * Adds the specified directory to the database.
175 * @param Dir The absolute path name of the directory to add.
176 * @throws Exception - if database error occurs, or the
177 * specified path is invalid.
178 */
179 void AddDirectory(String Dir);
180
181 /**
182 * Removes the specified directory from the database.
183 * @param Dir The absolute path name of the directory to remove.
184 * @throws Exception - If the specified path is invalid, or
185 * Force is false and the specified directory is
186 * not empty, or if database error occurs.
187 */
188 void RemoveDirectory(String Dir, bool Force = false);
189
190 /**
191 * Determines whether the specified directory exists in the database.
192 * @throws Exception - If database error occurs.
193 */
194 bool DirectoryExist(String Dir);
195
196 /**
197 * Gets information about the specified directory.
198 * @param Dir The absolute path name of the directory.
199 * @throws Exception - if database error occurs, or if
200 * the specified directory is not found.
201 */
202 DbDirectory GetDirectoryInfo(String Dir);
203
204 /**
205 * Renames the specified directory.
206 * @param Dir The absolute path name of the directory to rename.
207 * @param Name The new name for the directory.
208 * @throws Exception - In case the given directory does not exists,
209 * or the specified name is not a valid name,
210 * or if a directory with name equal to the new name already
211 * exists, or if database error occurs.
212 */
213 void RenameDirectory(String Dir, String Name);
214
215 /**
216 * Moves the specified directory into the specified location.
217 * @param Dir The absolute path name of the directory to move.
218 * @param Dst The location where the directory will be moved to.
219 * @throws Exception - In case a given directory does not exists,
220 * or if a directory with name equal to the directory name already
221 * exists in the specified destination directory, or if database error
222 * occurs. Error is also thrown when trying to move a directory to a
223 * subdirectory of itself.
224 */
225 void MoveDirectory(String Dir, String Dst);
226
227 /**
228 * Changes the description of the specified directory.
229 * @throws Exception - if database error occurs, or if
230 * the specified directory is not found.
231 */
232 void SetDirectoryDescription(String Dir, String Desc);
233
234 /**
235 * Adds the instruments in the specified file or
236 * directory to the specified instruments database directory.
237 * @param DbDir The absolute path name of a directory in the
238 * instruments database in which only the new instruments
239 * (that are not already in the database) will be added.
240 * @param FilePath The absolute path name of a file or
241 * directory in the file system. In case a directory is
242 * supplied, all supported instruments in the specified directory
243 * will be added to the instruments database, including the
244 * instruments in the subdirectories. The respective subdirectory
245 * structure will be recreated in the supplied database directory.
246 * @param Index The index of the instrument (in the given
247 * instrument file) to add. If -1 is specified, all instruments in
248 * the supplied instrument file will be added. Error is thrown if
249 * a directory is supplied and Index is not equal to -1.
250 * @throws Exception if the operation failed.
251 */
252 void AddInstruments(String DbDir, String FilePath, int Index = -1);
253
254 /**
255 * Adds all supported instruments in the specified directory
256 * to the specified instruments database directory. The
257 * instruments in the subdirectories will not be processed
258 * @param DbDir The absolute path name of a directory in the
259 * instruments database in which only the new instruments
260 * (that are not already in the database) will be added.
261 * @param FsDir The absolute path name of a directory in the file
262 * system.
263 * @throws Exception if the operation failed.
264 */
265 void AddInstrumentsNonrecursive(String DbDir, String FsDir);
266
267 /**
268 * Adds all supported instruments in the specified file system
269 * direcotry to the specified instruments database directory,
270 * including the instruments in the subdirectories of the
271 * supplied directory.
272 * @param DbDir The absolute path name of a directory in the
273 * instruments database in which only the new instruments
274 * (that are not already in the database) will be added.
275 * @param FsDir The absolute path name of an existing
276 * directory in the file system.
277 * @param Flat If true, the respective subdirectory structure will
278 * not be recreated in the instruments database and all instruments
279 * will be added directly in the specified database directory.
280 * @throws Exception if the operation failed.
281 */
282 void AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat = false);
283
284 /**
285 * Gets the number of instruments in the specified directory.
286 * @param Dir The absolute path name of the directory.
287 * @throws Exception - if database error occurs, or
288 * the specified path name is invalid.
289 * @returns The number of instruments in the specified directory.
290 */
291 int GetInstrumentCount(String Dir);
292
293 /**
294 * Gets the list of instruments in the specified directory.
295 * @param Dir The absolute path name of the directory.
296 * @throws Exception - if database error occurs, or
297 * the specified path name is invalid.
298 */
299 StringListPtr GetInstruments(String Dir);
300
301 /**
302 * Removes the specified instrument from the database.
303 * @param Instr The absolute path name of the instrument to remove.
304 * @throws Exception - If the specified instrument does not exist,
305 * or database error occurs.
306 */
307 void RemoveInstrument(String Instr);
308
309 /**
310 * Gets information about the specified instrument.
311 * @param Instr The absolute path name of the instrument.
312 * @throws Exception - if database error occurs, or if
313 * the specified instrument is not found.
314 */
315 DbInstrument GetInstrumentInfo(String Instr);
316
317 /**
318 * Renames the specified instrument.
319 * @param Instr The absolute path name of the instrument to rename.
320 * @param Name The new name for the instrument.
321 * @throws Exception - In case the given instrument does not exists,
322 * or the specified name is not a valid name, or if an instrument
323 * with name equal to the new name already exists, or
324 * if database error occurs.
325 */
326 void RenameInstrument(String Instr, String Name);
327
328 /**
329 * Moves the specified instrument into the specified directory.
330 * @param Instr The absolute path name of the instrument to move.
331 * @param Dst The directory where the instrument will be moved to.
332 * @throws Exception - In case the given directory or instrument
333 * does not exist, or if an instrument with name equal to the name
334 * of the specified instrument already exists in the specified
335 * destination directory, or if database error occurs.
336 */
337 void MoveInstrument(String Instr, String Dst);
338
339 /**
340 * Changes the description of the specified instrument.
341 * @throws Exception - if database error occurs, or if
342 * the specified instrument is not found.
343 */
344 void SetInstrumentDescription(String Instr, String Desc);
345
346 /**
347 * Closes the database connection if opened and deletes
348 * the InstrumentsDb instance.
349 */
350 static void Destroy();
351
352
353 private:
354 sqlite3* db;
355 String DbFile;
356 static InstrumentsDb* pInstrumentsDb;
357 Mutex DbInstrumentsMutex;
358 ListenerList<InstrumentsDb::Listener*> llInstrumentsDbListeners;
359
360 InstrumentsDb();
361 ~InstrumentsDb();
362
363 /**
364 * Gets the instruments database. If the database is not
365 * opened, a connection to the database is established first.
366 * @returns The instruments database.
367 * @throws Exception if fail to open the database.
368 */
369 sqlite3* GetDb();
370
371 /**
372 * Gets the number of directories in the directory
373 * with ID DirId.
374 * @returns The number of directories in the specified directory
375 * or -1 if the directory doesn't exist.
376 */
377 int GetDirectoryCount(int DirId);
378
379 /**
380 * Gets a list containing the IDs of all directories in
381 * the specified instrument directory.
382 * @returns The IDs of all directories in the specified directory.
383 * @throws Exception - if database error occurs.
384 */
385 IntListPtr GetDirectoryIDs(int DirId);
386
387 /**
388 * Gets the directory ID.
389 * @param Dir The absolute path name of the directory.
390 * @returns The directory ID or -1 if the directory is not found.
391 * @throws Exception - if database error occurs.
392 */
393 int GetDirectoryId(String Dir);
394
395 /**
396 * Gets the directory ID.
397 * @param ParentDirId The ID of the parent directory.
398 * @param DirName The directory name.
399 * @throws Exception - if database error occurs.
400 * @returns The ID of the specified directory
401 * or -1 if the directory doesn't exist.
402 */
403 int GetDirectoryId(int ParentDirId, String DirName);
404
405 /**
406 * Removes the specified directory from the database.
407 * @param DirId The ID of the directory to remove.
408 * @throws Exception - If the specified directory is not empty.
409 */
410 void RemoveDirectory(int DirId);
411
412 /**
413 * Removes all directories in the specified directory.
414 * Do NOT call this method before ensuring that all
415 * directories in the specified directory are empty.
416 * @param DirId The ID of the directory.
417 * @throws Exception - if at least one of the directories in the
418 * specified directory is not empty or if database error occurs.
419 * @see IsDirectoryEmpty
420 */
421 void RemoveAllDirectories(int DirId);
422
423 /**
424 * Determines whether the specified directory is empty.
425 * If the directory doesn't exist the return value is false.
426 * @throws Exception - if database error occurs.
427 */
428 bool IsDirectoryEmpty(int DirId);
429
430 /**
431 * Removes the content of the specified directory from the database.
432 * @param DirId The ID of the directory.
433 * @param Level Used to prevent stack overflow, which may occur
434 * due to large or infinite recursive loop.
435 * @throws Exception - If database error occurs.
436 */
437 void RemoveDirectoryContent(int DirId, int Level = 0);
438
439 /**
440 * Gets the ID of the specified database instrument.
441 * @param Instr The absolute path name of the instrument.
442 * @returns The instrument ID or -1 if the instrument is not found.
443 * @throws Exception - if database error occurs.
444 */
445 int GetInstrumentId(String Instr);
446
447 /**
448 * Gets the ID of the specified database instrument.
449 * @param DirId The ID of the directory containing the instrument.
450 * @param InstrName The name of the instrument.
451 * @returns The instrument ID or -1 if the instrument is not found.
452 * @throws Exception - if database error occurs.
453 */
454 int GetInstrumentId(int DirId, String InstrName);
455
456 /**
457 * Removes the specified instrument from the database.
458 * @param InstrId The ID of the instrument to remove.
459 * @throws Exception - If the specified instrument does not exist.
460 */
461 void RemoveInstrument(int InstrId);
462
463 /**
464 * Removes all instruments in the specified directory.
465 * @param DirId The ID of the directory.
466 * @throws Exception - if database error occurs.
467 */
468 void RemoveAllInstruments(int DirId);
469
470 /**
471 * Gets the number of instruments in the directory
472 * with ID DirId.
473 * @returns The number of instruments in the specified directory
474 * or -1 if the directory doesn't exist.
475 */
476 int GetInstrumentCount(int DirId);
477
478 /**
479 * Gets a list containing the IDs of all instruments in
480 * the specified instrument directory.
481 * @returns The IDs of all instruments in the specified directory.
482 * @throws Exception - if database error occurs.
483 */
484 IntListPtr GetInstrumentIDs(int DirId);
485
486 /**
487 * Adds the instruments in the specified file
488 * to the specified instruments database directory.
489 * @param DbDir The absolute path name of a directory in the
490 * instruments database in which only the new instruments
491 * (that are not already in the database) will be added.
492 * @param File The absolute path name of a file in the file system.
493 * @param Index The index of the instrument (in the given
494 * instrument file) to add. If -1 is specified, all instruments in
495 * the supplied instrument file will be added.
496 * @throws Exception if the operation failed.
497 */
498 void AddInstrumentsFromFile(String DbDir, String File, int Index = -1);
499
500 /**
501 * Adds the specified GIG instrument(s) to the specified location
502 * in the instruments database.
503 * @param DbDir The instruments database directory
504 * in which the instrument will be added.
505 * @param File The absolute path name of the instrument file.
506 * @param Index The index of the instrument (in the given
507 * instrument file) to add. If -1 is specified, all instruments in
508 * the supplied instrument file will be added.
509 * @throws Exception if the operation failed.
510 */
511 void AddGigInstruments(String DbDir, String File, int Index = -1);
512
513 /**
514 * Adds the specified GIG instrument.
515 * @throws Exception if the operation failed.
516 */
517 void AddGigInstrument(sqlite3_stmt* pStmt, String DbDir, int DirId, String File, ::gig::Instrument* pInstrument, int Index);
518
519 /**
520 * Used to execute SQL commands which return empty result set.
521 */
522 void ExecSql(String Sql);
523
524 /**
525 * Used to execute SQL commands which return empty result set.
526 */
527 void ExecSql(String Sql, String Param);
528
529 /**
530 * Used to execute SQL commands which returns integer.
531 */
532 int ExecSqlInt(String Sql);
533
534 /**
535 * Used to execute SQL commands which returns integer.
536 */
537 int ExecSqlInt(String Sql, String Param);
538
539 /**
540 * Used to execute SQL commands which returns integer.
541 */
542 String ExecSqlString(String Sql);
543
544 /**
545 * Used to execute SQL commands which returns integer list.
546 */
547 IntListPtr ExecSqlIntList(String Sql);
548
549 /**
550 * Used to execute SQL commands which returns string list.
551 */
552 StringListPtr ExecSqlStringList(String Sql);
553
554 /**
555 * Binds the specified text parameter.
556 */
557 void BindTextParam(sqlite3_stmt* pStmt, int Index, String Text);
558
559 /**
560 * Binds the specified integer parameter.
561 */
562 void BindIntParam(sqlite3_stmt* pStmt, int Index, int Param);
563
564 /**
565 * Checks whether an instrument with the specified name already
566 * exists in the specified directory and if so a new unique name
567 * is returnded. The new name is generated by adding the suffix
568 * [<nr>] to the end of the name , where <nr> is a number between
569 * 2 and 1000.
570 * throws Exception if cannot find an unique name. This is done
571 * because it is highly unlikely that this can happen, so it is
572 * supposed that this is due to a bug or an infinite loop.
573 */
574 String GetUniqueInstrumentName(int DirId, String Name);
575
576 void FireDirectoryCountChanged(String Dir);
577 void FireDirectoryInfoChanged(String Dir);
578 void FireDirectoryNameChanged(String Dir, String NewName);
579 void FireInstrumentCountChanged(String Dir);
580 void FireInstrumentInfoChanged(String Instr);
581 void FireInstrumentNameChanged(String Instr, String NewName);
582
583 /**
584 * Strips the non-directory suffix from the file name. If the string
585 * ends with `/' only the last character is removed. If the string
586 * doesn't starts with `/' charater, an empty string is returned.
587 */
588 static String GetDirectoryPath(String File);
589
590 /**
591 * Returns the file name extracted from the specified absolute path
592 * name. If the string doesn't starts with `/' or ends with `/',
593 * an empty string is returned.
594 */
595 static String GetFileName(String Path);
596
597 /**
598 * Strips the last directory from the specified path name. If the
599 * string doesn't starts with `/' an empty string is returned.
600 */
601 static String GetParentDirectory(String Dir);
602
603 /**
604 * Checks whether the specified path is valid.
605 * @throws Exception - if the specified path is invalid.
606 */
607 static void CheckPathName(String Path);
608
609 /**
610 * Checks whether the specified file name is valid.
611 * @throws Exception - if the specified file name is invalid.
612 */
613 static void CheckFileName(String File);
614 };
615
616 /**
617 * This class is used for recursive
618 */
619 class DirectoryScanner {
620 public:
621 /**
622 * Recursively scans all subdirectories of the specified
623 * directory and adds the supported instruments to the database.
624 * @throws Exception - if the specified directories are invalid.
625 */
626 static void Scan(String DbDir, String FsDir, bool Flat);
627
628 private:
629 static String DbDir;
630 static String FsDir;
631 static bool Flat;
632 static int FtwCallback(const char* fpath, const struct stat* sb, int typeflag);
633 };
634
635 } // namespace LinuxSampler
636
637 #endif // __LS_INSTRUMENTSDB_H__
638
639 #endif // HAVE_SQLITE3

  ViewVC Help
Powered by ViewVC