783 lines
25 KiB
C++
783 lines
25 KiB
C++
/*
|
|
File: DataStore.cpp
|
|
Description: Implements the DataStore class which provides a centralized singleton repository
|
|
for managing system data in the Vehicle Service Management System.
|
|
Includes accessors for users, services, combo packages, service bookings,
|
|
job cards, inventory items, invoices, and payments.
|
|
Author: Trenser
|
|
Date: 19-May-2026
|
|
*/
|
|
|
|
#include "DataStore.h"
|
|
#include "Config.h"
|
|
#include "SerializedRecords.h"
|
|
#include "FileHelper.h"
|
|
#include "ServiceBooking.h"
|
|
#include "JobCard.h"
|
|
#include "Invoice.h"
|
|
|
|
/*
|
|
Function: DataStore
|
|
Description: Constructs the DataStore singleton and initializes
|
|
internal handles to their default values.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- None
|
|
*/
|
|
DataStore::DataStore() :
|
|
m_globalMutex(NULL) {}
|
|
|
|
/*
|
|
Function: ~DataStore
|
|
Description: Destroys the DataStore singleton and releases all
|
|
cached application objects owned by the datastore.
|
|
This includes users, notifications, services,
|
|
combo packages, inventory items, service bookings,
|
|
job cards, and invoices.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- None
|
|
*/
|
|
DataStore::~DataStore()
|
|
{
|
|
clearCache(m_userCache);
|
|
clearCache(m_notificationCache);
|
|
clearCache(m_serviceCache);
|
|
clearCache(m_comboPackageCache);
|
|
clearCache(m_inventoryItemCache);
|
|
clearCache(m_serviceBookingCache);
|
|
clearCache(m_jobCardCache);
|
|
clearCache(m_invoiceCache);
|
|
}
|
|
|
|
/*
|
|
Function: initialize
|
|
Description: Initializes the shared-memory datastore.
|
|
Creates or opens the global datastore mutex,
|
|
configures all mapping metadata, and creates
|
|
or opens the file mappings used to persist
|
|
application data. After successful completion,
|
|
all datastore files are mapped into memory and
|
|
ready for use by the application.
|
|
Parameter: None
|
|
Return type: bool
|
|
- true : Initialization completed successfully.
|
|
- false : Failed to create the mutex or open
|
|
one or more file mappings.
|
|
*/
|
|
bool DataStore::initialize()
|
|
{
|
|
m_globalMutex = CreateMutexA(NULL, FALSE, "VehicleServiceSystemMutex");
|
|
if (m_globalMutex == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
if (!lockDataStore())
|
|
{
|
|
CloseHandle(m_globalMutex);
|
|
m_globalMutex = NULL;
|
|
return false;
|
|
}
|
|
bool success = true;
|
|
do
|
|
{
|
|
util::ensureDirectoryExists(config::file::DIRECTORY);
|
|
m_users.fileName = config::file::USER_FILE;
|
|
m_users.recordSize = sizeof(SerializedUser);
|
|
m_notifications.fileName = config::file::NOTIFICATION_FILE;
|
|
m_notifications.recordSize = sizeof(SerializedNotification);
|
|
m_services.fileName = config::file::SERVICE_FILE;
|
|
m_services.recordSize = sizeof(SerializedService);
|
|
m_comboPackages.fileName = config::file::COMBOPACKAGE_FILE;
|
|
m_comboPackages.recordSize = sizeof(SerializedComboPackage);
|
|
m_inventoryItems.fileName = config::file::INVENTORYITEM_FILE;
|
|
m_inventoryItems.recordSize = sizeof(SerializedInventoryItem);
|
|
m_serviceBookings.fileName = config::file::SERVICEBOOKING_FILE;
|
|
m_serviceBookings.recordSize = sizeof(SerializedServiceBooking);
|
|
m_jobCards.fileName = config::file::JOBCARD_FILE;
|
|
m_jobCards.recordSize = sizeof(SerializedJobCard);
|
|
m_invoices.fileName = config::file::INVOICE_FILE;
|
|
m_invoices.recordSize = sizeof(SerializedInvoice);
|
|
m_serviceManagementObservers.fileName = config::file::SERVICEMANAGEMENTOBSERVERS;
|
|
m_serviceManagementObservers.recordSize = sizeof(SerializedObserver);
|
|
m_paymentManagementObservers.fileName = config::file::PAYMENTMANAGEMENTOBSERVERS;
|
|
m_paymentManagementObservers.recordSize = sizeof(SerializedObserver);
|
|
m_inventoryManagementObservers.fileName = config::file::INVENTORYMANAGEMENTOBSERVERS;
|
|
m_inventoryManagementObservers.recordSize = sizeof(SerializedObserver);
|
|
if (!SharedMemory::createOrOpenMapping(m_users))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
if (!SharedMemory::createOrOpenMapping(m_notifications))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
if (!SharedMemory::createOrOpenMapping(m_services))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
|
|
if (!SharedMemory::createOrOpenMapping(m_comboPackages))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
if (!SharedMemory::createOrOpenMapping(m_inventoryItems))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
if (!SharedMemory::createOrOpenMapping(m_serviceBookings))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
if (!SharedMemory::createOrOpenMapping(m_jobCards))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
if (!SharedMemory::createOrOpenMapping(m_invoices))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
if (!SharedMemory::createOrOpenMapping(m_serviceManagementObservers))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
if (!SharedMemory::createOrOpenMapping(m_paymentManagementObservers))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
if (!SharedMemory::createOrOpenMapping(m_inventoryManagementObservers))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
} while (false);
|
|
unlockDataStore();
|
|
if (!success)
|
|
{
|
|
shutdown();
|
|
}
|
|
return success;
|
|
}
|
|
|
|
/*
|
|
Function: shutdown
|
|
Description: Releases all shared-memory resources owned by the
|
|
datastore. Closes every file mapping, unmaps all
|
|
mapped views, and releases the datastore mutex.
|
|
After this call, the datastore must be initialized
|
|
again before use.
|
|
Parameter: None
|
|
Return type: void
|
|
*/
|
|
void DataStore::shutdown()
|
|
{
|
|
SharedMemory::closeMapping(m_users);
|
|
SharedMemory::closeMapping(m_notifications);
|
|
SharedMemory::closeMapping(m_services);
|
|
SharedMemory::closeMapping(m_comboPackages);
|
|
SharedMemory::closeMapping(m_inventoryItems);
|
|
SharedMemory::closeMapping(m_serviceBookings);
|
|
SharedMemory::closeMapping(m_jobCards);
|
|
SharedMemory::closeMapping(m_invoices);
|
|
SharedMemory::closeMapping(m_serviceManagementObservers);
|
|
SharedMemory::closeMapping(m_paymentManagementObservers);
|
|
SharedMemory::closeMapping(m_inventoryManagementObservers);
|
|
if (m_globalMutex != NULL)
|
|
{
|
|
CloseHandle(m_globalMutex);
|
|
m_globalMutex = NULL;
|
|
}
|
|
}
|
|
|
|
/*
|
|
Function: getInstance
|
|
Description: Provides a singleton instance of the DataStore class.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- Reference to the single DataStore instance.
|
|
*/
|
|
DataStore& DataStore::getInstance()
|
|
{
|
|
static DataStore dataStore;
|
|
return dataStore;
|
|
}
|
|
|
|
/*
|
|
Function: getUsers
|
|
Description: Retrieves all user records from the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- util::Map<std::string, TrackedRecord<User>>: Collection of user records
|
|
*/
|
|
util::Map<std::string, TrackedRecord<User>>& DataStore::getUsers()
|
|
{
|
|
auto users = loadRecords<User, SerializedUser>(m_users);
|
|
refreshCache(m_userCache, users);
|
|
return m_userCache;
|
|
}
|
|
|
|
/*
|
|
Function: getNotifications
|
|
Description: Retrieves all notification records from the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- util::Map<std::string, TrackedRecord<Notification>>: Collection of notification records
|
|
*/
|
|
util::Map<std::string, TrackedRecord<Notification>>& DataStore::getNotifications()
|
|
{
|
|
auto notifications = loadRecords<Notification, SerializedNotification>(m_notifications);
|
|
refreshCache(m_notificationCache, notifications);
|
|
return m_notificationCache;
|
|
}
|
|
|
|
/*
|
|
Function: getServices
|
|
Description: Retrieves all service records from the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- util::Map<std::string, TrackedRecord<Service>>: Collection of service records
|
|
*/
|
|
util::Map<std::string, TrackedRecord<Service>>& DataStore::getServices()
|
|
{
|
|
util::Map<std::string, TrackedRecord<Service>> services = loadRecords<Service, SerializedService>(m_services);
|
|
refreshCache(m_serviceCache, services);
|
|
util::Map<std::string, TrackedRecord<InventoryItem>>& inventoryItems = getInventoryItems();
|
|
size_t numberOfServices = m_serviceCache.getSize();
|
|
for (int iteratorOne =0; iteratorOne < numberOfServices; iteratorOne++)
|
|
{
|
|
Service* currentService = m_serviceCache.getValueAt(iteratorOne).data;
|
|
util::Map<std::string, InventoryItem*> inventoryItemMap;
|
|
util::Vector<std::string> currentServiceInventoryItem = currentService->getRequiredInventoryItemIDs();
|
|
for (int iteratorTwo = 0; iteratorTwo < currentServiceInventoryItem.getSize(); iteratorTwo++)
|
|
{
|
|
const std::string& currentInventoryItemId = currentServiceInventoryItem[iteratorTwo];
|
|
int currentInventoryItemIndex = inventoryItems.find(currentInventoryItemId);
|
|
if (currentInventoryItemIndex == -1)
|
|
{
|
|
throw std::runtime_error("Invalid inventory item ID");
|
|
}
|
|
InventoryItem* currentItem = inventoryItems.getValueAt(currentInventoryItemIndex).data;
|
|
inventoryItemMap[currentInventoryItemId] = currentItem;
|
|
}
|
|
currentService->setRequiredInventoryItems(inventoryItemMap);
|
|
}
|
|
return m_serviceCache;
|
|
}
|
|
|
|
/*
|
|
Function: getComboPackages
|
|
Description: Retrieves all combo package records from the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- util::Map<std::string, TrackedRecord<ComboPackage>>: Collection of combo package records
|
|
*/
|
|
util::Map<std::string, TrackedRecord<ComboPackage>>& DataStore::getComboPackages()
|
|
{
|
|
util::Map<std::string, TrackedRecord<ComboPackage>> comboPackages = loadRecords<ComboPackage, SerializedComboPackage>(m_comboPackages);
|
|
refreshCache(m_comboPackageCache, comboPackages);
|
|
util::Map<std::string, TrackedRecord<Service>>& services = getServices();
|
|
size_t numberOfComboPackages = m_comboPackageCache.getSize();
|
|
for (int iteratorOne = 0; iteratorOne < numberOfComboPackages; iteratorOne++)
|
|
{
|
|
ComboPackage* currentComboPackage = m_comboPackageCache.getValueAt(iteratorOne).data;
|
|
util::Vector<std::string> currentServiceIds = currentComboPackage->getServiceIDs();
|
|
util::Map<std::string, Service*> currentComboPackageServices;
|
|
for (int iteratorTwo = 0; iteratorTwo < currentServiceIds.getSize(); iteratorTwo++)
|
|
{
|
|
const std::string& currentServiceId = currentServiceIds[iteratorTwo];
|
|
int serviceIndex = services.find(currentServiceId);
|
|
if (serviceIndex == -1)
|
|
{
|
|
throw std::runtime_error("Invalid service ID");
|
|
}
|
|
Service* currentService = services.getValueAt(serviceIndex).data;
|
|
currentComboPackageServices[currentServiceId] = currentService;
|
|
}
|
|
currentComboPackage->setServices(currentComboPackageServices);
|
|
}
|
|
return m_comboPackageCache;
|
|
}
|
|
|
|
/*
|
|
Function: getInventoryItems
|
|
Description: Retrieves all inventory item records from the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- util::Map<std::string, TrackedRecord<InventoryItem>>: Collection of inventory item records
|
|
*/
|
|
util::Map<std::string, TrackedRecord<InventoryItem>>& DataStore::getInventoryItems()
|
|
{
|
|
auto inventoryItems = loadRecords<InventoryItem, SerializedInventoryItem>(m_inventoryItems);
|
|
refreshCache(m_inventoryItemCache, inventoryItems);
|
|
return m_inventoryItemCache;
|
|
}
|
|
|
|
/*
|
|
Function: getServiceBookings
|
|
Description: Retrieves all service booking records from the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- util::Map<std::string, TrackedRecord<ServiceBooking>>: Collection of service booking records
|
|
*/
|
|
util::Map<std::string, TrackedRecord<ServiceBooking>>& DataStore::getServiceBookings()
|
|
{
|
|
util::Map<std::string, TrackedRecord<ServiceBooking>> serviceBookings = loadRecords<ServiceBooking, SerializedServiceBooking>(m_serviceBookings);
|
|
refreshCache(m_serviceBookingCache, serviceBookings);
|
|
auto& users = getUsers();
|
|
auto& services = getServices();
|
|
size_t numberOfServiceBookings = m_serviceBookingCache.getSize();
|
|
for (int iteratorOne = 0; iteratorOne < numberOfServiceBookings; iteratorOne++)
|
|
{
|
|
ServiceBooking* serviceBooking = m_serviceBookingCache.getValueAt(iteratorOne).data;
|
|
auto& serviceIds = serviceBooking->getServiceIDs();
|
|
util::Map<std::string, Service*> servicesInBooking;
|
|
for (int iteratorTwo = 0; iteratorTwo < serviceIds.getSize(); iteratorTwo++)
|
|
{
|
|
const std::string& currentServiceId = serviceIds[iteratorTwo];
|
|
int serviceIndex = services.find(currentServiceId);
|
|
if (serviceIndex == -1)
|
|
{
|
|
throw std::runtime_error("Invalid service index.");
|
|
}
|
|
auto currentService = services.getValueAt(serviceIndex);
|
|
servicesInBooking[currentServiceId] = currentService.data;
|
|
}
|
|
serviceBooking->setServices(servicesInBooking);
|
|
if (!serviceBooking->getCustomerId().empty())
|
|
{
|
|
int userIndex = users.find(serviceBooking->getCustomerId());
|
|
if (userIndex == -1)
|
|
{
|
|
throw std::runtime_error("Invalid user index.");
|
|
}
|
|
auto customer = users.getValueAt(userIndex);
|
|
serviceBooking->setCustomer(customer.data);
|
|
}
|
|
if (!serviceBooking->getAssignedTechnicianId().empty())
|
|
{
|
|
int technicianIndex = users.find(serviceBooking->getAssignedTechnicianId());
|
|
if (technicianIndex == -1)
|
|
{
|
|
throw std::runtime_error("Invalid technician index.");
|
|
}
|
|
auto technician = users.getValueAt(technicianIndex);
|
|
serviceBooking->setAssignedTechnician(technician.data);
|
|
}
|
|
}
|
|
return m_serviceBookingCache;
|
|
}
|
|
|
|
/*
|
|
Function: getJobCards
|
|
Description: Retrieves all job card records from the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- util::Map<std::string, TrackedRecord<JobCard>>: Collection of job card records
|
|
*/
|
|
util::Map<std::string, TrackedRecord<JobCard>>& DataStore::getJobCards()
|
|
{
|
|
util::Map<std::string, TrackedRecord<JobCard>> jobCards = loadRecords<JobCard, SerializedJobCard>(m_jobCards);
|
|
refreshCache(m_jobCardCache, jobCards);
|
|
auto& serviceBookings = getServiceBookings();
|
|
auto& services = getServices();
|
|
auto& users = getUsers();
|
|
int numberOfJobCards = m_jobCardCache.getSize();
|
|
for (int iterator = 0; iterator < numberOfJobCards; iterator++)
|
|
{
|
|
JobCard* jobCard = m_jobCardCache.getValueAt(iterator).data;
|
|
if (!jobCard)
|
|
{
|
|
continue;
|
|
}
|
|
const std::string& bookingId = jobCard->getBookingId();
|
|
int bookingIndex = serviceBookings.find(bookingId);
|
|
if (bookingIndex == -1)
|
|
{
|
|
throw std::runtime_error("Invalid booking ID: " + bookingId);
|
|
}
|
|
auto trackedBooking = serviceBookings.getValueAt(bookingIndex);
|
|
jobCard->setBooking(trackedBooking.data);
|
|
const std::string& serviceId = jobCard->getServiceId();
|
|
int serviceIndex = services.find(serviceId);
|
|
if (serviceIndex == -1)
|
|
{
|
|
throw std::runtime_error("Invalid service ID: " + serviceId);
|
|
}
|
|
auto trackedService = services.getValueAt(serviceIndex);
|
|
jobCard->setService(trackedService.data);
|
|
const std::string& technicianId = jobCard->getTechnicianId();
|
|
if (!technicianId.empty())
|
|
{
|
|
int technicianIndex = users.find(technicianId);
|
|
if (technicianIndex == -1)
|
|
{
|
|
throw std::runtime_error("Invalid technician ID: " + technicianId);
|
|
}
|
|
auto trackedTechnician = users.getValueAt(technicianIndex);
|
|
jobCard->setTechnician(trackedTechnician.data);
|
|
}
|
|
}
|
|
return m_jobCardCache;
|
|
}
|
|
|
|
|
|
/*
|
|
Function: getInvoices
|
|
Description: Retrieves all invoice records from the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- util::Map<std::string, TrackedRecord<Invoice>>: Collection of invoice records
|
|
*/
|
|
util::Map<std::string, TrackedRecord<Invoice>>& DataStore::getInvoices()
|
|
{
|
|
auto& serviceBookings = getServiceBookings();
|
|
auto& inventoryItems = getInventoryItems();
|
|
util::Map<std::string, TrackedRecord<Invoice>> invoices = loadRecords<Invoice, SerializedInvoice>(m_invoices);
|
|
refreshCache(m_invoiceCache, invoices);
|
|
for (int iterator = 0; iterator < m_invoiceCache.getSize(); iterator++)
|
|
{
|
|
auto& trackedInvoice = m_invoiceCache.getValueAt(iterator);
|
|
Invoice* invoice = trackedInvoice.data;
|
|
if (!invoice)
|
|
{
|
|
continue;
|
|
}
|
|
const std::string& currentBookingId = invoice->getBookingId();
|
|
int currentBookingIndex = serviceBookings.find(currentBookingId);
|
|
if (currentBookingIndex == -1)
|
|
{
|
|
throw std::runtime_error("Invalid Service Booking Index.");
|
|
}
|
|
ServiceBooking* currentBooking = serviceBookings.getValueAt(currentBookingIndex).data;
|
|
auto& currentInventoryItemIds = invoice->getPartIDs();
|
|
util::Map<std::string, InventoryItem*> currentInventoryItems;
|
|
for (int iterator = 0; iterator < currentInventoryItemIds.getSize(); iterator++)
|
|
{
|
|
const std::string& currentItemId = currentInventoryItemIds[iterator];
|
|
int currentItemIndex = inventoryItems.find(currentItemId);
|
|
if (currentItemIndex == -1)
|
|
{
|
|
throw std::runtime_error("Invalid Inventory item id.");
|
|
}
|
|
InventoryItem* currentItem = inventoryItems.getValueAt(currentItemIndex).data;
|
|
if (!currentItem)
|
|
{
|
|
continue;
|
|
}
|
|
currentInventoryItems[currentItemId] = currentItem;
|
|
}
|
|
invoice->setBooking(currentBooking);
|
|
invoice->setParts(currentInventoryItems);
|
|
}
|
|
return m_invoiceCache;
|
|
}
|
|
|
|
/*
|
|
Function: getObservers
|
|
Description: Retrieves observer records from the specified observer mapping
|
|
and resolves them to User objects.
|
|
Parameters:
|
|
- mapping: Observer mapping to read from
|
|
Returns:
|
|
- util::Map<std::string, User*>: Collection of observer records
|
|
Throws:
|
|
- std::runtime_error if an observer references an invalid user ID
|
|
*/
|
|
util::Map<std::string, User*> DataStore::getObservers(MappingInfo& mapping)
|
|
{
|
|
auto& users = getUsers();
|
|
util::Map<std::string, User*> observers;
|
|
SharedMemory::ensureLatestMapping(mapping);
|
|
size_t recordCount = SharedMemory::getRecordCount(mapping);
|
|
for (size_t index = 0; index < recordCount; index++)
|
|
{
|
|
const SerializedObserver* observer = static_cast<SerializedObserver*>(SharedMemory::getRecordAddress(mapping, index));
|
|
int userIndex = users.find(observer->id);
|
|
if (userIndex == -1)
|
|
{
|
|
throw std::runtime_error("Invalid observer user ID");
|
|
}
|
|
User* user = users.getValueAt(userIndex).data;
|
|
observers.insert(user->getId(), user);
|
|
}
|
|
return observers;
|
|
}
|
|
|
|
/*
|
|
Function: getServiceManagementObservers
|
|
Description: Retrieves all service management observer records from the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- util::Map<std::string, User*>: Collection of observer records
|
|
*/
|
|
util::Map<std::string, User*> DataStore::getServiceManagementObservers()
|
|
{
|
|
return getObservers(m_serviceManagementObservers);
|
|
}
|
|
|
|
/*
|
|
Function: getPaymentManagementObservers
|
|
Description: Retrieves all payment management observer records from the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- util::Map<std::string, User*>: Collection of observer records
|
|
*/
|
|
util::Map<std::string, User*> DataStore::getPaymentManagementObservers()
|
|
{
|
|
return getObservers(m_paymentManagementObservers);
|
|
}
|
|
|
|
/*
|
|
Function: getInventoryManagementObservers
|
|
Description: Retrieves all inventory management observer records from the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- util::Map<std::string, User*>: Collection of observer records
|
|
*/
|
|
util::Map<std::string, User*> DataStore::getInventoryManagementObservers()
|
|
{
|
|
return getObservers(m_inventoryManagementObservers);
|
|
}
|
|
|
|
/*
|
|
Function: saveUsers
|
|
Description: Persists all user records to the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::saveUsers()
|
|
{
|
|
saveRecords<User, SerializedUser>(m_users, m_userCache);
|
|
}
|
|
|
|
/*
|
|
Function: saveNotifications
|
|
Description: Persists all notification records to the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::saveNotifications()
|
|
{
|
|
saveRecords<Notification, SerializedNotification>(m_notifications, m_notificationCache);
|
|
}
|
|
|
|
/*
|
|
Function: saveServices
|
|
Description: Persists all service records to the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::saveServices()
|
|
{
|
|
saveRecords<Service, SerializedService>(m_services, m_serviceCache);
|
|
}
|
|
|
|
/*
|
|
Function: saveComboPackages
|
|
Description: Persists all combo package records to the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::saveComboPackages()
|
|
{
|
|
saveRecords<ComboPackage, SerializedComboPackage>(m_comboPackages, m_comboPackageCache);
|
|
}
|
|
|
|
/*
|
|
Function: saveInventoryItems
|
|
Description: Persists all inventory item records to the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::saveInventoryItems()
|
|
{
|
|
saveRecords<InventoryItem, SerializedInventoryItem>(m_inventoryItems, m_inventoryItemCache);
|
|
}
|
|
|
|
/*
|
|
Function: saveServiceBookings
|
|
Description: Persists all service booking records to the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::saveServiceBookings()
|
|
{
|
|
saveRecords<ServiceBooking, SerializedServiceBooking>(m_serviceBookings, m_serviceBookingCache);
|
|
}
|
|
|
|
/*
|
|
Function: saveJobCards
|
|
Description: Persists all job card records to the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::saveJobCards()
|
|
{
|
|
saveRecords<JobCard, SerializedJobCard>(m_jobCards, m_jobCardCache);
|
|
}
|
|
|
|
/*
|
|
Function: saveInvoices
|
|
Description: Persists all invoice records to the datastore.
|
|
Parameters:
|
|
- None
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::saveInvoices()
|
|
{
|
|
saveRecords<Invoice, SerializedInvoice>(m_invoices, m_invoiceCache);
|
|
}
|
|
|
|
/*
|
|
Function: saveObservers
|
|
Description: Persists observer records to the specified observer mapping.
|
|
Parameters:
|
|
- mapping: MappingInfo&, observer mapping to save to
|
|
- observers: util::Map<std::string, User*>&, collection of observer records
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::saveObservers(MappingInfo& mapping, util::Map<std::string, User*>& observers)
|
|
{
|
|
size_t observerCount = static_cast<size_t>(observers.getSize());
|
|
size_t capacity = config::file::INITIAL_CAPACITY;
|
|
while (capacity < observerCount)
|
|
{
|
|
capacity *= config::file::GROWTH_FACTOR;
|
|
}
|
|
if (!SharedMemory::resizeMapping(mapping, capacity))
|
|
{
|
|
throw std::runtime_error("Failed to resize observer mapping");
|
|
}
|
|
SharedMemory::setRecordCount(mapping, observerCount);
|
|
for (size_t index = 0; index < observerCount; index++)
|
|
{
|
|
SerializedObserver serializedObserver;
|
|
User* user = observers.getValueAt(static_cast<int>(index));
|
|
strcpy_s(serializedObserver.id, sizeof(serializedObserver.id), user->getId().c_str());
|
|
SerializedObserver* destination = static_cast<SerializedObserver*>(SharedMemory::getRecordAddress(mapping, index));
|
|
*destination = serializedObserver;
|
|
}
|
|
}
|
|
|
|
/*
|
|
Function: saveServiceManagementObservers
|
|
Description: Persists all service management observer records to the datastore.
|
|
Parameters:
|
|
- observers: util::Map<std::string, User*>&, collection of observer records
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::saveServiceManagementObservers(util::Map<std::string, User*>& observers)
|
|
{
|
|
saveObservers(m_serviceManagementObservers, observers);
|
|
}
|
|
|
|
/*
|
|
Function: savePaymentManagementObservers
|
|
Description: Persists all payment management observer records to the datastore.
|
|
Parameters:
|
|
- observers: util::Map<std::string, User*>&, collection of observer records
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::savePaymentManagementObservers(util::Map<std::string, User*>& observers)
|
|
{
|
|
saveObservers(m_paymentManagementObservers, observers);
|
|
}
|
|
|
|
/*
|
|
Function: saveInventoryManagementObservers
|
|
Description: Persists all inventory management observer records to the datastore.
|
|
Parameters:
|
|
- observers: util::Map<std::string, User*>&, collection of observer records
|
|
Returns:
|
|
- None
|
|
*/
|
|
void DataStore::saveInventoryManagementObservers(util::Map<std::string, User*>& observers)
|
|
{
|
|
saveObservers(m_inventoryManagementObservers, observers);
|
|
}
|
|
|
|
/*
|
|
Function: lockDataStore
|
|
Description: Acquires the datastore mutex, providing
|
|
exclusive access to the shared-memory
|
|
datastore. This function blocks until
|
|
the mutex becomes available or an error
|
|
occurs.
|
|
Parameter: None
|
|
Return type:
|
|
bool
|
|
- true : Mutex successfully acquired.
|
|
- false : Failed to acquire the mutex.
|
|
*/
|
|
bool DataStore::lockDataStore()
|
|
{
|
|
if (m_globalMutex == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
DWORD result = WaitForSingleObject(m_globalMutex, INFINITE);
|
|
return result == WAIT_OBJECT_0;
|
|
}
|
|
|
|
/*
|
|
Function: unlockDataStore
|
|
Description: Releases the datastore mutex after a
|
|
successful call to lockDataStore(),
|
|
allowing other processes to access the
|
|
shared-memory datastore.
|
|
Parameter: None
|
|
Return type:
|
|
bool
|
|
- true : Mutex successfully released.
|
|
- false : Failed to release the mutex.
|
|
*/
|
|
bool DataStore::unlockDataStore()
|
|
{
|
|
if (m_globalMutex == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
return ReleaseMutex(m_globalMutex) != 0;
|
|
} |