mldbApi.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. #include "mldbApi.h"
  2. #include "main.h"
  3. #include <strsafe.h>
  4. itemRecordW *MLDBAPI::GetFile(const wchar_t *filename)
  5. {
  6. itemRecordW *result = 0;
  7. if (filename)
  8. {
  9. openDb(); // just in case it's not opened yet (this function will return immediately if it's already open)
  10. if (g_table)
  11. {
  12. EnterCriticalSection(&g_db_cs);
  13. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  14. if (s)
  15. {
  16. if (NDE_Scanner_LocateFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, filename))
  17. {
  18. nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_FILENAME);
  19. if (f)
  20. {
  21. result = (itemRecordW *)_aligned_malloc(sizeof(itemRecordW), 16);
  22. if (result)
  23. {
  24. result->filename = NDE_StringField_GetString(f);
  25. ndestring_retain(result->filename);
  26. ScannerRefToObjCacheNFNW(s, result, true);
  27. }
  28. }
  29. }
  30. NDE_Table_DestroyScanner(g_table, s);
  31. }
  32. LeaveCriticalSection(&g_db_cs);
  33. }
  34. }
  35. return result;
  36. }
  37. itemRecordW *MLDBAPI::GetFileIf(const wchar_t *filename, const wchar_t *query)
  38. {
  39. itemRecordW *result = 0;
  40. if (filename)
  41. {
  42. openDb(); // just in case it's not opened yet (this function will return immediately if it's already open)
  43. if (g_table)
  44. {
  45. EnterCriticalSection(&g_db_cs);
  46. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  47. if (s)
  48. {
  49. NDE_Scanner_Query(s, query);
  50. if (NDE_Scanner_LocateFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, filename))
  51. {
  52. nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_FILENAME);
  53. if (f)
  54. {
  55. result = (itemRecordW *)_aligned_malloc(sizeof(itemRecordW), 16);
  56. if (result)
  57. {
  58. result->filename = NDE_StringField_GetString(f);
  59. ndestring_retain(result->filename);
  60. ScannerRefToObjCacheNFNW(s, result, true);
  61. }
  62. }
  63. }
  64. NDE_Table_DestroyScanner(g_table, s);
  65. }
  66. LeaveCriticalSection(&g_db_cs);
  67. }
  68. }
  69. return result;
  70. }
  71. itemRecordListW *MLDBAPI::GetAlbum(const wchar_t *albumname, const wchar_t *albumartist)
  72. {
  73. wchar_t query[4096] = {0}; // hope it's big enough
  74. if (albumartist && albumname)
  75. {
  76. StringCchPrintfW(query, 4096, L"((albumartist isempty and artist=\"%s\") or albumartist=\"%s\") and album=\"%s\"", albumartist, albumartist, albumname);
  77. return Query(query);
  78. }
  79. else if (albumname)
  80. {
  81. StringCchPrintfW(query, 4096, L"album=\"%s\"", albumname);
  82. return Query(query);
  83. }
  84. return 0;
  85. }
  86. itemRecordListW *MLDBAPI::Query(const wchar_t *query)
  87. {
  88. itemRecordListW *result = 0;
  89. if (query)
  90. {
  91. openDb(); // just in case it's not opened yet (this function will return immediately if it's already open)
  92. if (g_table)
  93. {
  94. EnterCriticalSection(&g_db_cs);
  95. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  96. if (s)
  97. {
  98. NDE_Scanner_Query(s, query);
  99. NDE_Scanner_First(s);
  100. do
  101. {
  102. nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_FILENAME);
  103. if (!f) break;
  104. if (!result)
  105. result = (itemRecordListW *)calloc(1, sizeof(itemRecordListW));
  106. if (!result)
  107. break;
  108. allocRecordList(result, result->Size + 1);
  109. if (!result->Alloc) break;
  110. result->Items[result->Size].filename = NDE_StringField_GetString(f);
  111. ndestring_retain(result->Items[result->Size].filename);
  112. ScannerRefToObjCacheNFNW(s, result, true);
  113. }
  114. while (NDE_Scanner_Next(s));
  115. NDE_Table_DestroyScanner(g_table, s);
  116. }
  117. LeaveCriticalSection(&g_db_cs);
  118. }
  119. }
  120. return result;
  121. }
  122. itemRecordListW *MLDBAPI::QueryLimit(const wchar_t *query, unsigned int limit)
  123. {
  124. itemRecordListW *result = 0;
  125. if (limit == 0)
  126. return 0;
  127. if (query)
  128. {
  129. openDb(); // just in case it's not opened yet (this function will return immediately if it's already open)
  130. if (g_table)
  131. {
  132. EnterCriticalSection(&g_db_cs);
  133. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  134. if (s)
  135. {
  136. NDE_Scanner_Query(s, query);
  137. NDE_Scanner_First(s);
  138. do
  139. {
  140. nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_FILENAME);
  141. if (!f) break;
  142. if (!result)
  143. {
  144. result = (itemRecordListW *)calloc(1, sizeof(itemRecordListW));
  145. if (!result)
  146. break;
  147. allocRecordList(result, limit);
  148. if (!result->Alloc)
  149. break;
  150. }
  151. result->Items[result->Size].filename = NDE_StringField_GetString(f);
  152. ndestring_retain(result->Items[result->Size].filename);
  153. ScannerRefToObjCacheNFNW(s, result, true);
  154. }
  155. while (result->Size < (int)limit && NDE_Scanner_Next(s));
  156. NDE_Table_DestroyScanner(g_table, s);
  157. }
  158. LeaveCriticalSection(&g_db_cs);
  159. }
  160. }
  161. return result;
  162. }
  163. void MLDBAPI::FreeRecord(itemRecordW *record)
  164. {
  165. freeRecord(record);
  166. }
  167. void MLDBAPI::FreeRecordList(itemRecordListW *recordList)
  168. {
  169. freeRecordList(recordList);
  170. }
  171. bool FindFileInDB(nde_scanner_t s, const wchar_t *filename);
  172. void MLDBAPI::SetField(const wchar_t *filename, const char *field, const wchar_t *value)
  173. {
  174. openDb();
  175. if (g_table)
  176. {
  177. EnterCriticalSection(&g_db_cs);
  178. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  179. if (s)
  180. {
  181. if (FindFileInDB(s, filename))
  182. {
  183. if (value && value[0])
  184. {
  185. NDE_Scanner_Edit(s);
  186. nde_field_t f = NDE_Scanner_GetFieldByName(s, field);
  187. if (!f)
  188. f=NDE_Scanner_NewFieldByName(s, field);
  189. if (f)
  190. NDE_StringField_SetString(f, value);
  191. }
  192. else
  193. {
  194. nde_field_t f = NDE_Scanner_GetFieldByName(s, field);
  195. if (f)
  196. NDE_Scanner_DeleteField(s, f);
  197. }
  198. NDE_Scanner_Post(s);
  199. g_table_dirty++;
  200. }
  201. NDE_Table_DestroyScanner(g_table, s);
  202. }
  203. LeaveCriticalSection(&g_db_cs);
  204. }
  205. }
  206. void MLDBAPI::SetFieldInteger(const wchar_t *filename, const char *field, int value)
  207. {
  208. openDb();
  209. if (g_table)
  210. {
  211. EnterCriticalSection(&g_db_cs);
  212. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  213. if (s)
  214. {
  215. if (FindFileInDB(s, filename))
  216. {
  217. NDE_Scanner_Edit(s);
  218. nde_field_t f = NDE_Scanner_GetFieldByName(s, field);
  219. if (!f)
  220. f=NDE_Scanner_NewFieldByName(s, field);
  221. if (f)
  222. NDE_IntegerField_SetValue(f, value);
  223. NDE_Scanner_Post(s);
  224. g_table_dirty++;
  225. }
  226. NDE_Table_DestroyScanner(g_table, s);
  227. }
  228. LeaveCriticalSection(&g_db_cs);
  229. }
  230. }
  231. void MLDBAPI::SetFieldInt128(const wchar_t *filename, const char *field, uint8_t value[16])
  232. {
  233. openDb();
  234. if (g_table)
  235. {
  236. EnterCriticalSection(&g_db_cs);
  237. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  238. if (s)
  239. {
  240. if (FindFileInDB(s, filename))
  241. {
  242. if (value)
  243. {
  244. NDE_Scanner_Edit(s);
  245. nde_field_t f = NDE_Scanner_GetFieldByName(s, field);
  246. if (!f)
  247. f=NDE_Scanner_NewFieldByName(s, field);
  248. if (f)
  249. NDE_Int128Field_SetValue(f, value);
  250. }
  251. else
  252. {
  253. nde_field_t f = NDE_Scanner_GetFieldByName(s, field);
  254. if (f)
  255. NDE_Scanner_DeleteField(s, f);
  256. }
  257. NDE_Scanner_Post(s);
  258. g_table_dirty++;
  259. }
  260. NDE_Table_DestroyScanner(g_table, s);
  261. }
  262. LeaveCriticalSection(&g_db_cs);
  263. }
  264. }
  265. void MLDBAPI::Sync()
  266. {
  267. openDb();
  268. if (g_table)
  269. {
  270. EnterCriticalSection(&g_db_cs);
  271. NDE_Table_Sync(g_table);
  272. g_table_dirty=0;
  273. LeaveCriticalSection(&g_db_cs);
  274. }
  275. }
  276. int MLDBAPI::AddFile(const wchar_t *filename)
  277. {
  278. int guess = g_config->ReadInt(L"guessmode", 0);
  279. int meta = g_config->ReadInt(L"usemetadata", 1);
  280. return addFileToDb(filename, 0, meta, guess);
  281. }
  282. int MLDBAPI::RemoveFile(const wchar_t *filename)
  283. {
  284. return RemoveFileFromDB(filename);
  285. }
  286. void MLDBAPI::RetainString(wchar_t *str)
  287. {
  288. ndestring_retain(str);
  289. }
  290. void MLDBAPI::ReleaseString(wchar_t *str)
  291. {
  292. ndestring_release(str);
  293. }
  294. wchar_t *MLDBAPI::DuplicateString(const wchar_t *str)
  295. {
  296. return ndestring_wcsdup(str);
  297. }
  298. int MLDBAPI::GetMaxInteger(const char *field, int *max)
  299. {
  300. openDb();
  301. if (!g_table)
  302. return 1;
  303. EnterCriticalSection(&g_db_cs);
  304. nde_field_t f = NDE_Table_GetColumnByName(g_table, field);
  305. if (!f)
  306. {
  307. LeaveCriticalSection(&g_db_cs);
  308. return 1;
  309. }
  310. unsigned char field_id = NDE_ColumnField_GetFieldID(f);
  311. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  312. if (s)
  313. {
  314. int maximum_so_far=0;
  315. NDE_Scanner_Query(s, L"");
  316. NDE_Scanner_First(s);
  317. do
  318. {
  319. nde_field_t f = NDE_Scanner_GetFieldByID(s, field_id);
  320. if (f)
  321. {
  322. int this_value = NDE_IntegerField_GetValue(f);
  323. if (this_value > maximum_so_far)
  324. maximum_so_far = this_value;
  325. }
  326. } while (NDE_Scanner_Next(s) && !NDE_Scanner_EOF(s));
  327. NDE_Table_DestroyScanner(g_table, s);
  328. *max=maximum_so_far;
  329. LeaveCriticalSection(&g_db_cs);
  330. return 0;
  331. }
  332. else
  333. {
  334. LeaveCriticalSection(&g_db_cs);
  335. return 1;
  336. }
  337. }
  338. #define CBCLASS MLDBAPI
  339. START_DISPATCH;
  340. CB(API_MLDB_GETFILE, GetFile)
  341. CB(API_MLDB_GETFILEIF, GetFileIf)
  342. CB(API_MLDB_GETALBUM, GetAlbum)
  343. CB(API_MLDB_QUERY, Query)
  344. CB(API_MLDB_QUERYLIMIT, QueryLimit)
  345. VCB(API_MLDB_FREERECORD, FreeRecord)
  346. VCB(API_MLDB_FREERECORDLIST, FreeRecordList)
  347. VCB(API_MLDB_SETFIELD, SetField)
  348. VCB(API_MLDB_SETFIELDINT, SetFieldInteger)
  349. VCB(API_MLDB_SETFIELDINT128, SetFieldInt128)
  350. VCB(API_MLDB_SYNC, Sync)
  351. CB(API_MLDB_ADDFILE, AddFile)
  352. CB(API_MLDB_REMOVEFILE, RemoveFile)
  353. VCB(API_MLDB_RETAINSTRING, RetainString)
  354. VCB(API_MLDB_RELEASESTRING, ReleaseString)
  355. CB(API_MLDB_DUPLICATESTRING, DuplicateString)
  356. CB(API_MLDB_GETMAXINTEGER, GetMaxInteger)
  357. END_DISPATCH;
  358. #undef CBCLASS