winamp/Src/Plugins/Library/ml_local/mldbApi.cpp

400 lines
9 KiB
C++
Raw Permalink Normal View History

2024-09-24 12:54:57 +00:00
#include "mldbApi.h"
#include "main.h"
#include <strsafe.h>
itemRecordW *MLDBAPI::GetFile(const wchar_t *filename)
{
itemRecordW *result = 0;
if (filename)
{
openDb(); // just in case it's not opened yet (this function will return immediately if it's already open)
if (g_table)
{
EnterCriticalSection(&g_db_cs);
nde_scanner_t s = NDE_Table_CreateScanner(g_table);
if (s)
{
if (NDE_Scanner_LocateFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, filename))
{
nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_FILENAME);
if (f)
{
result = (itemRecordW *)_aligned_malloc(sizeof(itemRecordW), 16);
if (result)
{
result->filename = NDE_StringField_GetString(f);
ndestring_retain(result->filename);
ScannerRefToObjCacheNFNW(s, result, true);
}
}
}
NDE_Table_DestroyScanner(g_table, s);
}
LeaveCriticalSection(&g_db_cs);
}
}
return result;
}
itemRecordW *MLDBAPI::GetFileIf(const wchar_t *filename, const wchar_t *query)
{
itemRecordW *result = 0;
if (filename)
{
openDb(); // just in case it's not opened yet (this function will return immediately if it's already open)
if (g_table)
{
EnterCriticalSection(&g_db_cs);
nde_scanner_t s = NDE_Table_CreateScanner(g_table);
if (s)
{
NDE_Scanner_Query(s, query);
if (NDE_Scanner_LocateFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, filename))
{
nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_FILENAME);
if (f)
{
result = (itemRecordW *)_aligned_malloc(sizeof(itemRecordW), 16);
if (result)
{
result->filename = NDE_StringField_GetString(f);
ndestring_retain(result->filename);
ScannerRefToObjCacheNFNW(s, result, true);
}
}
}
NDE_Table_DestroyScanner(g_table, s);
}
LeaveCriticalSection(&g_db_cs);
}
}
return result;
}
itemRecordListW *MLDBAPI::GetAlbum(const wchar_t *albumname, const wchar_t *albumartist)
{
wchar_t query[4096] = {0}; // hope it's big enough
if (albumartist && albumname)
{
StringCchPrintfW(query, 4096, L"((albumartist isempty and artist=\"%s\") or albumartist=\"%s\") and album=\"%s\"", albumartist, albumartist, albumname);
return Query(query);
}
else if (albumname)
{
StringCchPrintfW(query, 4096, L"album=\"%s\"", albumname);
return Query(query);
}
return 0;
}
itemRecordListW *MLDBAPI::Query(const wchar_t *query)
{
itemRecordListW *result = 0;
if (query)
{
openDb(); // just in case it's not opened yet (this function will return immediately if it's already open)
if (g_table)
{
EnterCriticalSection(&g_db_cs);
nde_scanner_t s = NDE_Table_CreateScanner(g_table);
if (s)
{
NDE_Scanner_Query(s, query);
NDE_Scanner_First(s);
do
{
nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_FILENAME);
if (!f) break;
if (!result)
result = (itemRecordListW *)calloc(1, sizeof(itemRecordListW));
if (!result)
break;
allocRecordList(result, result->Size + 1);
if (!result->Alloc) break;
result->Items[result->Size].filename = NDE_StringField_GetString(f);
ndestring_retain(result->Items[result->Size].filename);
ScannerRefToObjCacheNFNW(s, result, true);
}
while (NDE_Scanner_Next(s));
NDE_Table_DestroyScanner(g_table, s);
}
LeaveCriticalSection(&g_db_cs);
}
}
return result;
}
itemRecordListW *MLDBAPI::QueryLimit(const wchar_t *query, unsigned int limit)
{
itemRecordListW *result = 0;
if (limit == 0)
return 0;
if (query)
{
openDb(); // just in case it's not opened yet (this function will return immediately if it's already open)
if (g_table)
{
EnterCriticalSection(&g_db_cs);
nde_scanner_t s = NDE_Table_CreateScanner(g_table);
if (s)
{
NDE_Scanner_Query(s, query);
NDE_Scanner_First(s);
do
{
nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_FILENAME);
if (!f) break;
if (!result)
{
result = (itemRecordListW *)calloc(1, sizeof(itemRecordListW));
if (!result)
break;
allocRecordList(result, limit);
if (!result->Alloc)
break;
}
result->Items[result->Size].filename = NDE_StringField_GetString(f);
ndestring_retain(result->Items[result->Size].filename);
ScannerRefToObjCacheNFNW(s, result, true);
}
while (result->Size < (int)limit && NDE_Scanner_Next(s));
NDE_Table_DestroyScanner(g_table, s);
}
LeaveCriticalSection(&g_db_cs);
}
}
return result;
}
void MLDBAPI::FreeRecord(itemRecordW *record)
{
freeRecord(record);
}
void MLDBAPI::FreeRecordList(itemRecordListW *recordList)
{
freeRecordList(recordList);
}
bool FindFileInDB(nde_scanner_t s, const wchar_t *filename);
void MLDBAPI::SetField(const wchar_t *filename, const char *field, const wchar_t *value)
{
openDb();
if (g_table)
{
EnterCriticalSection(&g_db_cs);
nde_scanner_t s = NDE_Table_CreateScanner(g_table);
if (s)
{
if (FindFileInDB(s, filename))
{
if (value && value[0])
{
NDE_Scanner_Edit(s);
nde_field_t f = NDE_Scanner_GetFieldByName(s, field);
if (!f)
f=NDE_Scanner_NewFieldByName(s, field);
if (f)
NDE_StringField_SetString(f, value);
}
else
{
nde_field_t f = NDE_Scanner_GetFieldByName(s, field);
if (f)
NDE_Scanner_DeleteField(s, f);
}
NDE_Scanner_Post(s);
g_table_dirty++;
}
NDE_Table_DestroyScanner(g_table, s);
}
LeaveCriticalSection(&g_db_cs);
}
}
void MLDBAPI::SetFieldInteger(const wchar_t *filename, const char *field, int value)
{
openDb();
if (g_table)
{
EnterCriticalSection(&g_db_cs);
nde_scanner_t s = NDE_Table_CreateScanner(g_table);
if (s)
{
if (FindFileInDB(s, filename))
{
NDE_Scanner_Edit(s);
nde_field_t f = NDE_Scanner_GetFieldByName(s, field);
if (!f)
f=NDE_Scanner_NewFieldByName(s, field);
if (f)
NDE_IntegerField_SetValue(f, value);
NDE_Scanner_Post(s);
g_table_dirty++;
}
NDE_Table_DestroyScanner(g_table, s);
}
LeaveCriticalSection(&g_db_cs);
}
}
void MLDBAPI::SetFieldInt128(const wchar_t *filename, const char *field, uint8_t value[16])
{
openDb();
if (g_table)
{
EnterCriticalSection(&g_db_cs);
nde_scanner_t s = NDE_Table_CreateScanner(g_table);
if (s)
{
if (FindFileInDB(s, filename))
{
if (value)
{
NDE_Scanner_Edit(s);
nde_field_t f = NDE_Scanner_GetFieldByName(s, field);
if (!f)
f=NDE_Scanner_NewFieldByName(s, field);
if (f)
NDE_Int128Field_SetValue(f, value);
}
else
{
nde_field_t f = NDE_Scanner_GetFieldByName(s, field);
if (f)
NDE_Scanner_DeleteField(s, f);
}
NDE_Scanner_Post(s);
g_table_dirty++;
}
NDE_Table_DestroyScanner(g_table, s);
}
LeaveCriticalSection(&g_db_cs);
}
}
void MLDBAPI::Sync()
{
openDb();
if (g_table)
{
EnterCriticalSection(&g_db_cs);
NDE_Table_Sync(g_table);
g_table_dirty=0;
LeaveCriticalSection(&g_db_cs);
}
}
int MLDBAPI::AddFile(const wchar_t *filename)
{
int guess = g_config->ReadInt(L"guessmode", 0);
int meta = g_config->ReadInt(L"usemetadata", 1);
return addFileToDb(filename, 0, meta, guess);
}
int MLDBAPI::RemoveFile(const wchar_t *filename)
{
return RemoveFileFromDB(filename);
}
void MLDBAPI::RetainString(wchar_t *str)
{
ndestring_retain(str);
}
void MLDBAPI::ReleaseString(wchar_t *str)
{
ndestring_release(str);
}
wchar_t *MLDBAPI::DuplicateString(const wchar_t *str)
{
return ndestring_wcsdup(str);
}
int MLDBAPI::GetMaxInteger(const char *field, int *max)
{
openDb();
if (!g_table)
return 1;
EnterCriticalSection(&g_db_cs);
nde_field_t f = NDE_Table_GetColumnByName(g_table, field);
if (!f)
{
LeaveCriticalSection(&g_db_cs);
return 1;
}
unsigned char field_id = NDE_ColumnField_GetFieldID(f);
nde_scanner_t s = NDE_Table_CreateScanner(g_table);
if (s)
{
int maximum_so_far=0;
NDE_Scanner_Query(s, L"");
NDE_Scanner_First(s);
do
{
nde_field_t f = NDE_Scanner_GetFieldByID(s, field_id);
if (f)
{
int this_value = NDE_IntegerField_GetValue(f);
if (this_value > maximum_so_far)
maximum_so_far = this_value;
}
} while (NDE_Scanner_Next(s) && !NDE_Scanner_EOF(s));
NDE_Table_DestroyScanner(g_table, s);
*max=maximum_so_far;
LeaveCriticalSection(&g_db_cs);
return 0;
}
else
{
LeaveCriticalSection(&g_db_cs);
return 1;
}
}
#define CBCLASS MLDBAPI
START_DISPATCH;
CB(API_MLDB_GETFILE, GetFile)
CB(API_MLDB_GETFILEIF, GetFileIf)
CB(API_MLDB_GETALBUM, GetAlbum)
CB(API_MLDB_QUERY, Query)
CB(API_MLDB_QUERYLIMIT, QueryLimit)
VCB(API_MLDB_FREERECORD, FreeRecord)
VCB(API_MLDB_FREERECORDLIST, FreeRecordList)
VCB(API_MLDB_SETFIELD, SetField)
VCB(API_MLDB_SETFIELDINT, SetFieldInteger)
VCB(API_MLDB_SETFIELDINT128, SetFieldInt128)
VCB(API_MLDB_SYNC, Sync)
CB(API_MLDB_ADDFILE, AddFile)
CB(API_MLDB_REMOVEFILE, RemoveFile)
VCB(API_MLDB_RETAINSTRING, RetainString)
VCB(API_MLDB_RELEASESTRING, ReleaseString)
CB(API_MLDB_DUPLICATESTRING, DuplicateString)
CB(API_MLDB_GETMAXINTEGER, GetMaxInteger)
END_DISPATCH;
#undef CBCLASS