Files
vba10/Database/ROMDatabase.cpp

307 lines
7.5 KiB
C++
Raw Normal View History

2015-06-18 17:33:07 +00:00
#include "ROMDatabase.h"
#include "ppltasks_extra.h"
2015-06-18 17:33:07 +00:00
#include <collection.h>
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Storage;
using namespace Windows::Storage::Streams;
2015-06-23 14:46:09 +00:00
using namespace Windows::Storage::AccessCache;
using namespace Windows::UI::Xaml;
2015-06-18 17:33:07 +00:00
using namespace Concurrency;
using namespace Concurrency::extras;
using namespace std;
2015-07-15 05:02:33 +00:00
using namespace VBA10;
2015-06-18 17:33:07 +00:00
#define ROMDB_FILE_NAME "romdb.db"
//ROMDatabase^ ROMDatabase::singleton;
2015-07-15 05:02:33 +00:00
ROMDatabase::ROMDatabase()
{
}
task<void> ROMDatabase::Initialize(void)
2015-06-18 17:33:07 +00:00
{
2015-07-15 05:02:33 +00:00
return create_task(Windows::Storage::ApplicationData::Current->LocalFolder->CreateFileAsync(ROMDB_FILE_NAME, CreationCollisionOption::OpenIfExists))
.then([this](StorageFile^ file)
2015-06-18 17:33:07 +00:00
{
2015-07-15 05:02:33 +00:00
db = ref new SQLiteWinRT::Database(file);
2015-06-18 17:33:07 +00:00
2015-07-15 05:02:33 +00:00
//open database
return db->OpenAsync(SQLiteWinRT::SqliteOpenMode::OpenReadWrite);
}).then([this]
2015-06-18 17:33:07 +00:00
{
2015-07-15 05:02:33 +00:00
//create table if not exist
return db->ExecuteStatementAsync("CREATE TABLE IF NOT EXISTS ROMTABLE ( "\
"LOCATIONTYPE INT NOT NULL,"\
"DISPLAYNAME TEXT NOT NULL,"\
2015-07-29 21:14:08 +00:00
"FILENAME TEXT NOT NULL,"\
"FOLDERPATH TEXT NOT NULL,"\
"TOKEN TEXT NOT NULL,"\
2015-07-15 05:02:33 +00:00
"LASTPLAYED INT NOT NULL,"\
"LASTSAVEINDEX INT NOT NULL, "\
"AUTOSAVEINDEX INT NOT NULL, "\
"SNAPSHOTURI TEXT NOT NULL );");
}).then([this]
{
return db->PrepareStatementAsync("SELECT * FROM ROMTABLE ORDER BY DISPLAYNAME ASC;");
}).then([this](SQLiteWinRT::Statement^ stmt)
{
statement = stmt;
return RetrieveQuerry();
}).then([this] (Vector<ROMDBEntry^>^ ret)
{
_allROMDBEntries = ret;
//load rom entry
return LoadSnapshotImage();
2015-07-29 19:41:41 +00:00
}).then([this](task<void> t)
2015-07-15 05:02:33 +00:00
{
2015-07-29 19:41:41 +00:00
//check to see if any entry failed to load (due to deleted folder)
for (int i = 0; i < _allROMDBEntries->Size; i++)
{
auto entry = _allROMDBEntries->GetAt(i);
if (!entry->Folder)
{
_allROMDBEntries->RemoveAt(i);
i--;
}
}
2015-07-15 05:02:33 +00:00
return t.get();
});
//auto items = ref new Vector<String^>();
//__await db->OpenAsync(SQLiteWinRT::SqliteOpenMode::OpenRead);
//auto stmt = __await db->PrepareStatementAsync("SELECT rowid, CityName FROM Cities;");
//while (__await stmt->StepAsync())
// items->Append(stmt->GetIntAt(0) + ": " + stmt->GetTextAt(1));
}
task<void> ROMDatabase::AddAsync(ROMDBEntry^ entry)
{
return create_task([this, entry]
2015-06-18 17:33:07 +00:00
{
2015-07-15 05:02:33 +00:00
//prepare statement to add to rom table
2015-07-29 21:14:08 +00:00
Platform::String^ cmd = "INSERT INTO ROMTABLE (LOCATIONTYPE, DISPLAYNAME, FILENAME, FOLDERPATH, TOKEN, LASTPLAYED, LASTSAVEINDEX, AUTOSAVEINDEX, SNAPSHOTURI) VALUES (";
2015-07-15 05:02:33 +00:00
cmd += entry->LocationType + ",";
cmd += "'" + entry->DisplayName + "',";
cmd += "'" + entry->FileName + "',";
2015-07-29 21:14:08 +00:00
cmd += "'" + entry->FolderPath + "',";
cmd += "'" + entry->Token + "',";
2015-07-15 05:02:33 +00:00
cmd += entry->LastPlayed.UniversalTime + ",";
cmd += entry->LastSaveIndex + ",";
cmd += entry->AutoSaveIndex + ",";
cmd += "'" + entry->SnapshotUri + "')";
2015-06-18 17:33:07 +00:00
#if _DEBUG
2015-07-15 05:02:33 +00:00
Platform::String ^message = cmd;
wstring wstr(message->Begin(), message->End());
OutputDebugStringW(wstr.c_str());
2015-06-18 17:33:07 +00:00
#endif
2015-07-15 05:02:33 +00:00
return db->ExecuteStatementAsync(cmd);
});
}
2015-06-18 17:33:07 +00:00
2015-07-15 05:02:33 +00:00
//call this after prepare statement async
task<Vector<ROMDBEntry^>^> ROMDatabase::RetrieveQuerry()
{
auto items = ref new Vector<ROMDBEntry^>();
2015-06-18 17:33:07 +00:00
2015-07-15 05:02:33 +00:00
//now carry out the tasks, start with one StepAsync to see table has any data
return create_task([this]
{
2015-07-15 05:02:33 +00:00
return statement->StepAsync();
}).then([this, items](bool ret)
{
if (ret)
{
2015-07-15 05:02:33 +00:00
return create_iterative_task([this, items]
{
2015-07-15 05:02:33 +00:00
return create_task([this, items]
2015-06-23 14:46:09 +00:00
{
2015-07-15 05:02:33 +00:00
ROMDBEntry^ entry = ref new ROMDBEntry(
statement->GetIntAt(0), statement->GetTextAt(1), statement->GetTextAt(2), statement->GetTextAt(3),
2015-07-29 21:14:08 +00:00
statement->GetTextAt(4), DateTime{ statement->GetInt64At(5) }, statement->GetIntAt(6), statement->GetIntAt(7), statement->GetTextAt(8)
2015-07-15 05:02:33 +00:00
);
items->Append(entry);
return statement->StepAsync();
});
});;
}
else
return create_task([] {});
}).then([items](task<void> t)
{
return items; //t.get();
});
}
task<void> ROMDatabase::LoadSnapshotImage()
{
vector<task<void>> tasks;
for (int i= 0; i < _allROMDBEntries->Size; i++)
{
auto entry = _allROMDBEntries->GetAt(i);
2015-07-15 05:02:33 +00:00
tasks.emplace_back(create_task([entry]
{
if (entry->LocationType == 0) //app storage
{
2015-06-23 14:46:09 +00:00
2015-07-15 05:02:33 +00:00
return create_task([entry]()->StorageFolder^
2015-06-23 14:46:09 +00:00
{
2015-07-15 05:02:33 +00:00
return ApplicationData::Current->LocalFolder;
});
}
else // external storage
{
2015-07-15 05:02:33 +00:00
//find the folder in futureaccesslist
2015-06-23 14:46:09 +00:00
2015-07-29 21:14:08 +00:00
return create_task([entry]
2015-07-15 05:02:33 +00:00
{
2015-07-29 21:14:08 +00:00
return StorageApplicationPermissions::FutureAccessList->GetFolderAsync(entry->Token);
2015-07-15 05:02:33 +00:00
});
}
}).then([entry](StorageFolder^ folder)
{
2015-07-29 21:14:08 +00:00
if (folder)
2015-07-29 19:41:41 +00:00
{
2015-07-29 21:14:08 +00:00
//update folder path (incase user change folder name)
entry->FolderPath = folder->Path;
entry->Folder = folder;
2015-07-29 23:57:19 +00:00
2015-07-29 19:41:41 +00:00
}
2015-07-15 05:02:33 +00:00
//get the snapshot file
return folder->GetFileAsync(entry->SnapshotUri);
}).then([entry](StorageFile ^file)
{
//open file
return file->OpenAsync(FileAccessMode::Read);
}).then([entry](IRandomAccessStream^ stream)
{
//load bitmap image for snapshot
entry->Snapshot = ref new BitmapImage();
return entry->Snapshot->SetSourceAsync(stream);
}).then([tasks](task<void> t)
{
try
{
t.get();
}
catch (Exception^ e)
{
// We'll handle the specific errors below.
}
2015-07-15 05:02:33 +00:00
}));
}
// When all tasks finish, create a continuation task that observes any exceptions that occurred.
return when_all(begin(tasks), end(tasks)).then([tasks](task<void> t)
{
try
{
t.get();
}
catch (COMException^ e)
{
// We'll handle the specific errors below.
}
2015-07-15 05:02:33 +00:00
});
}
2015-07-15 05:02:33 +00:00
task<void> ROMDatabase::UpdateAsync(ROMDBEntry^ entry)
{
return create_task([this, entry]
{
2015-07-15 05:02:33 +00:00
//prepare statement to update entry
Platform::String^ cmd = "UPDATE ROMTABLE SET DISPLAYNAME = ";
cmd += "'" + entry->DisplayName + "',";
2015-07-29 21:14:08 +00:00
cmd += " FOLDERPATH = '" + entry->FolderPath + "',";
2015-07-15 05:02:33 +00:00
cmd += " LASTPLAYED = " + entry->LastPlayed.UniversalTime + ",";
cmd += " LASTSAVEINDEX = " + entry->LastSaveIndex + ",";
cmd += " AUTOSAVEINDEX = " + entry->AutoSaveIndex ;
2015-07-29 21:14:08 +00:00
cmd += " WHERE FILENAME = '" + entry->FileName + "' AND TOKEN = '" + entry->Token + "';";
#if _DEBUG
2015-07-15 05:02:33 +00:00
Platform::String ^message = cmd;
wstring wstr(message->Begin(), message->End());
OutputDebugStringW(wstr.c_str());
#endif
2015-07-15 05:02:33 +00:00
return db->ExecuteStatementAsync(cmd);
});
}
ROMDBEntry^ ROMDatabase::GetEntryFromName(Platform::String^ name)
{
for (int i = 0; i < _allROMDBEntries->Size; i++)
{
ROMDBEntry^ entry = _allROMDBEntries->GetAt(i);
if (entry->DisplayName == name)
return entry;
}
2015-07-15 05:02:33 +00:00
//if come to here, it means we don't find the entry with the correct name
return nullptr;
}
task<void> ROMDatabase::RemoveAsync(ROMDBEntry ^ entry)
{
return create_task([this, entry]
{
//prepare statement to update entry
Platform::String^ cmd = "DELETE FROM ROMTABLE ";
cmd += " WHERE FILENAME = '" + entry->FileName + "' AND TOKEN = '" + entry->Token + "';";
#if _DEBUG
Platform::String ^message = cmd;
wstring wstr(message->Begin(), message->End());
OutputDebugStringW(wstr.c_str());
#endif
return db->ExecuteStatementAsync(cmd);
});
}