20 |
|
|
21 |
#include "InstrumentsDb.h" |
#include "InstrumentsDb.h" |
22 |
|
|
23 |
#if HAVE_SQLITE3 |
#include "../common/global_private.h" |
24 |
|
|
25 |
#include <iostream> |
#include <iostream> |
26 |
#include <sstream> |
#include <sstream> |
58 |
|
|
59 |
GetInstrumentsDb()->ExecSql(sql); |
GetInstrumentsDb()->ExecSql(sql); |
60 |
|
|
61 |
sql = "INSERT INTO instr_dirs (dir_id, parent_dir_id, dir_name) VALUES (0, 0, '/');"; |
sql = "INSERT INTO instr_dirs (dir_id, parent_dir_id, dir_name) VALUES (0, -2, '/');"; |
62 |
GetInstrumentsDb()->ExecSql(sql); |
GetInstrumentsDb()->ExecSql(sql); |
63 |
|
|
64 |
sql = |
sql = |
127 |
sqlite3* InstrumentsDb::GetDb() { |
sqlite3* InstrumentsDb::GetDb() { |
128 |
if ( db != NULL) return db; |
if ( db != NULL) return db; |
129 |
|
|
130 |
if (DbFile.empty()) DbFile = "/var/lib/linuxsampler/instruments.db"; |
if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION; |
131 |
int rc = sqlite3_open(DbFile.c_str(), &db); |
int rc = sqlite3_open(DbFile.c_str(), &db); |
132 |
if (rc) { |
if (rc) { |
133 |
sqlite3_close(db); |
sqlite3_close(db); |
136 |
} |
} |
137 |
rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, NULL, Regexp, NULL, NULL); |
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."); } |
if (rc) { throw Exception("Failed to add user function for handling regular expressions."); } |
139 |
|
|
140 |
|
// TODO: remove this in the next version |
141 |
|
try { |
142 |
|
int i = ExecSqlInt("SELECT parent_dir_id FROM instr_dirs WHERE dir_id=0"); |
143 |
|
// The parent ID of the root directory should be -2 now. |
144 |
|
if(i != -2) ExecSql("UPDATE instr_dirs SET parent_dir_id=-2 WHERE dir_id=0"); |
145 |
|
} catch(Exception e) { } |
146 |
|
//////////////////////////////////////// |
147 |
|
|
148 |
return db; |
return db; |
149 |
} |
} |
157 |
|
|
158 |
int count = ExecSqlInt(sql.str()); |
int count = ExecSqlInt(sql.str()); |
159 |
|
|
|
// While the root dir has ID 0 and parent ID 0, the directory |
|
|
// count for the root dir will be incorrect, so we should fix it. |
|
|
if (count != -1 && DirId == 0) count--; |
|
160 |
return count; |
return count; |
161 |
} |
} |
162 |
|
|
501 |
} |
} |
502 |
|
|
503 |
EndTransaction(); |
EndTransaction(); |
504 |
FireDirectoryNameChanged(Dir, Name); |
FireDirectoryNameChanged(Dir, toAbstractName(Name)); |
505 |
} |
} |
506 |
|
|
507 |
void InstrumentsDb::MoveDirectory(String Dir, String Dst) { |
void InstrumentsDb::MoveDirectory(String Dir, String Dst) { |
813 |
sql << "SELECT instr_name FROM instruments WHERE dir_id=" << dirId; |
sql << "SELECT instr_name FROM instruments WHERE dir_id=" << dirId; |
814 |
|
|
815 |
pInstrs = ExecSqlStringList(sql.str()); |
pInstrs = ExecSqlStringList(sql.str()); |
816 |
|
// Converting to abstract names |
817 |
|
for (int i = 0; i < pInstrs->size(); i++) { |
818 |
|
for (int j = 0; j < pInstrs->at(i).length(); j++) { |
819 |
|
if (pInstrs->at(i).at(j) == '/') pInstrs->at(i).at(j) = '\0'; |
820 |
|
} |
821 |
|
} |
822 |
} |
} |
823 |
EndTransaction(); |
EndTransaction(); |
824 |
return pInstrs; |
return pInstrs; |
979 |
throw e; |
throw e; |
980 |
} |
} |
981 |
EndTransaction(); |
EndTransaction(); |
982 |
FireInstrumentNameChanged(Instr, Name); |
FireInstrumentNameChanged(Instr, toAbstractName(Name)); |
983 |
} |
} |
984 |
|
|
985 |
void InstrumentsDb::MoveInstrument(String Instr, String Dst) { |
void InstrumentsDb::MoveInstrument(String Instr, String Dst) { |
1047 |
return; |
return; |
1048 |
} |
} |
1049 |
|
|
|
if (GetInstrumentId(dstId, instrName) != -1) { |
|
|
String s = toEscapedPath(instrName); |
|
|
throw Exception("Cannot copy. Instrument with that name already exists: " + s); |
|
|
} |
|
|
|
|
|
if (GetDirectoryId(dstId, instrName) != -1) { |
|
|
String s = toEscapedPath(instrName); |
|
|
throw Exception("Cannot copy. Directory with that name already exists: " + s); |
|
|
} |
|
|
|
|
1050 |
CopyInstrument(instrId, instrName, dstId, Dst); |
CopyInstrument(instrId, instrName, dstId, Dst); |
1051 |
} catch (Exception e) { |
} catch (Exception e) { |
1052 |
EndTransaction(); |
EndTransaction(); |
1057 |
} |
} |
1058 |
|
|
1059 |
void InstrumentsDb::CopyInstrument(int InstrId, String InstrName, int DstDirId, String DstDir) { |
void InstrumentsDb::CopyInstrument(int InstrId, String InstrName, int DstDirId, String DstDir) { |
1060 |
|
if (GetInstrumentId(DstDirId, InstrName) != -1) { |
1061 |
|
String s = toEscapedPath(InstrName); |
1062 |
|
throw Exception("Cannot copy. Instrument with that name already exists: " + s); |
1063 |
|
} |
1064 |
|
|
1065 |
|
if (GetDirectoryId(DstDirId, InstrName) != -1) { |
1066 |
|
String s = toEscapedPath(InstrName); |
1067 |
|
throw Exception("Cannot copy. Directory with that name already exists: " + s); |
1068 |
|
} |
1069 |
|
|
1070 |
DbInstrument i = GetInstrumentInfo(InstrId); |
DbInstrument i = GetInstrumentInfo(InstrId); |
1071 |
sqlite3_stmt *pStmt = NULL; |
sqlite3_stmt *pStmt = NULL; |
1072 |
std::stringstream sql; |
std::stringstream sql; |
1080 |
throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); |
throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); |
1081 |
} |
} |
1082 |
|
|
1083 |
BindTextParam(pStmt, 1, toDbName(InstrName)); |
String s = toDbName(InstrName); |
1084 |
|
BindTextParam(pStmt, 1, s); |
1085 |
BindTextParam(pStmt, 2, i.InstrFile); |
BindTextParam(pStmt, 2, i.InstrFile); |
1086 |
BindTextParam(pStmt, 3, i.FormatFamily); |
BindTextParam(pStmt, 3, i.FormatFamily); |
1087 |
BindTextParam(pStmt, 4, i.FormatVersion); |
BindTextParam(pStmt, 4, i.FormatVersion); |
1168 |
try { |
try { |
1169 |
riff = new RIFF::File(File); |
riff = new RIFF::File(File); |
1170 |
gig::File* gig = new gig::File(riff); |
gig::File* gig = new gig::File(riff); |
1171 |
|
gig->SetAutoLoad(false); // avoid time consuming samples scanning |
1172 |
|
|
1173 |
std::stringstream sql; |
std::stringstream sql; |
1174 |
sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,"; |
sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,"; |
1183 |
throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); |
throw Exception("DB error: " + ToString(sqlite3_errmsg(db))); |
1184 |
} |
} |
1185 |
|
|
1186 |
BindTextParam(pStmt, 2, File); |
String s = toEscapedFsPath(File); |
1187 |
|
BindTextParam(pStmt, 2, s); |
1188 |
String ver = ""; |
String ver = ""; |
1189 |
if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major); |
if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major); |
1190 |
BindTextParam(pStmt, 4, ver); |
BindTextParam(pStmt, 4, ver); |
1243 |
std::stringstream sql2; |
std::stringstream sql2; |
1244 |
sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND "; |
sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND "; |
1245 |
sql2 << "instr_nr=" << Index; |
sql2 << "instr_nr=" << Index; |
1246 |
if (ExecSqlInt(sql2.str(), File) > 0) return; |
String s = toEscapedFsPath(File); |
1247 |
|
if (ExecSqlInt(sql2.str(), s) > 0) return; |
1248 |
|
|
1249 |
BindTextParam(pStmt, 1, name); |
BindTextParam(pStmt, 1, name); |
1250 |
BindIntParam(pStmt, 3, Index); |
BindIntParam(pStmt, 3, Index); |
1624 |
return Dir.substr(0, i); |
return Dir.substr(0, i); |
1625 |
} |
} |
1626 |
|
|
1627 |
|
void InstrumentsDb::Format() { |
1628 |
|
DbInstrumentsMutex.Lock(); |
1629 |
|
if (db != NULL) { |
1630 |
|
sqlite3_close(db); |
1631 |
|
db = NULL; |
1632 |
|
} |
1633 |
|
|
1634 |
|
if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION; |
1635 |
|
String bkp = DbFile + ".bkp"; |
1636 |
|
remove(bkp.c_str()); |
1637 |
|
if (rename(DbFile.c_str(), bkp.c_str()) && errno != ENOENT) { |
1638 |
|
DbInstrumentsMutex.Unlock(); |
1639 |
|
throw Exception(String("Failed to backup database: ") + strerror(errno)); |
1640 |
|
} |
1641 |
|
|
1642 |
|
String f = DbFile; |
1643 |
|
DbFile = ""; |
1644 |
|
try { CreateInstrumentsDb(f); } |
1645 |
|
catch(Exception e) { |
1646 |
|
DbInstrumentsMutex.Unlock(); |
1647 |
|
throw e; |
1648 |
|
} |
1649 |
|
DbInstrumentsMutex.Unlock(); |
1650 |
|
|
1651 |
|
FireDirectoryCountChanged("/"); |
1652 |
|
FireInstrumentCountChanged("/"); |
1653 |
|
} |
1654 |
|
|
1655 |
void InstrumentsDb::CheckFileName(String File) { |
void InstrumentsDb::CheckFileName(String File) { |
1656 |
if (File.empty()) throw Exception("Invalid file name: " + File); |
if (File.empty()) throw Exception("Invalid file name: " + File); |
1657 |
} |
} |
1681 |
|
|
1682 |
String InstrumentsDb::toEscapedPath(String AbstractName) { |
String InstrumentsDb::toEscapedPath(String AbstractName) { |
1683 |
for (int i = 0; i < AbstractName.length(); i++) { |
for (int i = 0; i < AbstractName.length(); i++) { |
1684 |
if (AbstractName.at(i) == '\0') AbstractName.replace(i++, 1, "\\/"); |
if (AbstractName.at(i) == '\0') AbstractName.replace(i++, 1, "\\x2f"); |
1685 |
else if (AbstractName.at(i) == '\\') AbstractName.replace(i++, 1, "\\\\"); |
else if (AbstractName.at(i) == '\\') AbstractName.replace(i++, 1, "\\\\"); |
1686 |
else if (AbstractName.at(i) == '\'') AbstractName.replace(i++, 1, "\\'"); |
else if (AbstractName.at(i) == '\'') AbstractName.replace(i++, 1, "\\'"); |
1687 |
else if (AbstractName.at(i) == '"') AbstractName.replace(i++, 1, "\\\""); |
else if (AbstractName.at(i) == '"') AbstractName.replace(i++, 1, "\\\""); |
1702 |
return text; |
return text; |
1703 |
} |
} |
1704 |
|
|
1705 |
String InstrumentsDb::toEscapedName(String AbstractName) { |
String InstrumentsDb::toEscapedFsPath(String FsPath) { |
1706 |
for (int i = 0; i < AbstractName.length(); i++) { |
return toEscapedText(FsPath); |
|
if (AbstractName.at(i) == '\0') AbstractName.at(i) = '/'; |
|
|
else if (AbstractName.at(i) == '\\') AbstractName.replace(i++, 1, "\\\\"); |
|
|
else if (AbstractName.at(i) == '\'') AbstractName.replace(i++, 1, "\\'"); |
|
|
else if (AbstractName.at(i) == '"') AbstractName.replace(i++, 1, "\\\""); |
|
|
else if (AbstractName.at(i) == '\r') AbstractName.replace(i++, 1, "\\r"); |
|
|
else if (AbstractName.at(i) == '\n') AbstractName.replace(i++, 1, "\\n"); |
|
|
} |
|
|
return AbstractName; |
|
1707 |
} |
} |
1708 |
|
|
1709 |
String InstrumentsDb::toAbstractName(String DbName) { |
String InstrumentsDb::toAbstractName(String DbName) { |
1756 |
} |
} |
1757 |
|
|
1758 |
} // namespace LinuxSampler |
} // namespace LinuxSampler |
|
|
|
|
#endif // HAVE_SQLITE3 |
|