Compare commits

...

2 Commits

Author SHA1 Message Date
joelthomastrenser dc5da0a7b7 changes 2026-06-11 16:39:47 +05:30
joelthomastrenser 7454c5a75f changes 2026-06-11 15:49:20 +05:30
6 changed files with 566 additions and 81 deletions
@@ -9,6 +9,139 @@ Date: 19-May-2026
*/
#include "DataStore.h"
#include "Config.h"
#include "SerializedRecords.h"
#include "FileHelper.h"
DataStore::DataStore() :
m_globalMutex(NULL) {}
/*
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;
}
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))
{
return false;
}
if (!SharedMemory::createOrOpenMapping(m_notifications))
{
return false;
}
if (!SharedMemory::createOrOpenMapping(m_services))
{
return false;
}
if (!SharedMemory::createOrOpenMapping(m_comboPackages))
{
return false;
}
if (!SharedMemory::createOrOpenMapping(m_inventoryItems))
{
return false;
}
if (!SharedMemory::createOrOpenMapping(m_serviceBookings))
{
return false;
}
if (!SharedMemory::createOrOpenMapping(m_jobCards))
{
return false;
}
if (!SharedMemory::createOrOpenMapping(m_invoices))
{
return false;
}
if (!SharedMemory::createOrOpenMapping(m_payments))
{
return false;
}
if (!SharedMemory::createOrOpenMapping(m_serviceManagementObservers))
{
return false;
}
if (!SharedMemory::createOrOpenMapping(m_paymentManagementObservers))
{
return false;
}
if (!SharedMemory::createOrOpenMapping(m_inventoryManagementObservers))
{
return false;
}
return true;
}
/*
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_payments);
SharedMemory::closeMapping(m_serviceManagementObservers);
SharedMemory::closeMapping(m_paymentManagementObservers);
SharedMemory::closeMapping(m_inventoryManagementObservers);
if (m_globalMutex != NULL)
{
CloseHandle(m_globalMutex);
m_globalMutex = NULL;
}
}
/*
Function: getInstance
@@ -26,104 +159,370 @@ DataStore& DataStore::getInstance()
/*
Function: getUsers
Description: Retrieves the internal map of users.
Description: Retrieves all user records from the datastore.
Parameters:
- None
Returns:
- Reference to util::Map<std::string, User*> containing all users.
- util::Map<std::string, TrackedRecord<User>>: Collection of user records
*/
util::Map<std::string, User*>& DataStore::getUsers()
util::Map<std::string, TrackedRecord<User>> DataStore::getUsers()
{
return m_users;
return util::Map<std::string, TrackedRecord<User>>();
}
/*
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()
{
return util::Map<std::string, TrackedRecord<Notification>>();
}
/*
Function: getServices
Description: Retrieves the internal map of services.
Description: Retrieves all service records from the datastore.
Parameters:
- None
Returns:
- Reference to util::Map<std::string, Service*> containing all services.
- util::Map<std::string, TrackedRecord<Service>>: Collection of service records
*/
util::Map<std::string, Service*>& DataStore::getServices()
util::Map<std::string, TrackedRecord<Service>> DataStore::getServices()
{
return m_services;
return util::Map<std::string, TrackedRecord<Service>>();
}
/*
Function: getComboPackages
Description: Retrieves the internal map of combo packages.
Description: Retrieves all combo package records from the datastore.
Parameters:
- None
Returns:
- Reference to util::Map<std::string, ComboPackage*> containing all combo packages.
- util::Map<std::string, TrackedRecord<ComboPackage>>: Collection of combo package records
*/
util::Map<std::string, ComboPackage*>& DataStore::getComboPackages()
util::Map<std::string, TrackedRecord<ComboPackage>> DataStore::getComboPackages()
{
return m_comboPackages;
}
/*
Function: getServiceBookings
Description: Retrieves the internal map of service bookings.
Parameters:
- None
Returns:
- Reference to util::Map<std::string, ServiceBooking*> containing all service bookings.
*/
util::Map<std::string, ServiceBooking*>& DataStore::getServiceBookings()
{
return m_serviceBookings;
}
/*
Function: getJobCards
Description: Retrieves the internal map of job cards.
Parameters:
- None
Returns:
- Reference to util::Map<std::string, JobCard*> containing all job cards.
*/
util::Map<std::string, JobCard*>& DataStore::getJobCards()
{
return m_jobCards;
return util::Map<std::string, TrackedRecord<ComboPackage>>();
}
/*
Function: getInventoryItems
Description: Retrieves the internal map of inventory items.
Description: Retrieves all inventory item records from the datastore.
Parameters:
- None
Returns:
- Reference to util::Map<std::string, InventoryItem*> containing all inventory items.
- util::Map<std::string, TrackedRecord<InventoryItem>>: Collection of inventory item records
*/
util::Map<std::string, InventoryItem*>& DataStore::getInventoryItems()
util::Map<std::string, TrackedRecord<InventoryItem>> DataStore::getInventoryItems()
{
return m_inventoryItems;
return util::Map<std::string, TrackedRecord<InventoryItem>>();
}
/*
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()
{
return util::Map<std::string, TrackedRecord<ServiceBooking>>();
}
/*
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()
{
return util::Map<std::string, TrackedRecord<JobCard>>();
}
/*
Function: getInvoices
Description: Retrieves the internal map of invoices.
Description: Retrieves all invoice records from the datastore.
Parameters:
- None
Returns:
- Reference to util::Map<std::string, Invoice*> containing all invoices.
- util::Map<std::string, TrackedRecord<Invoice>>: Collection of invoice records
*/
util::Map<std::string, Invoice*>& DataStore::getInvoices()
util::Map<std::string, TrackedRecord<Invoice>> DataStore::getInvoices()
{
return m_invoices;
return util::Map<std::string, TrackedRecord<Invoice>>();
}
/*
Function: getPayments
Description: Retrieves the internal map of payments.
Description: Retrieves all payment records from the datastore.
Parameters:
- None
Returns:
- Reference to util::Map<std::string, Payment*> containing all payments.
- util::Map<std::string, TrackedRecord<Payment>>: Collection of payment records
*/
util::Map<std::string, Payment*>& DataStore::getPayments()
util::Map<std::string, TrackedRecord<Payment>> DataStore::getPayments()
{
return m_payments;
return util::Map<std::string, TrackedRecord<Payment>>();
}
/*
Function: getServiceManagementObservers
Description: Retrieves all service management observer records from the datastore.
Parameters:
- None
Returns:
- util::Map<std::string, TrackedRecord<std::string>>: Collection of observer records
*/
util::Map<std::string, TrackedRecord<std::string>> DataStore::getServiceManagementObservers()
{
return util::Map<std::string, TrackedRecord<std::string>>();
}
/*
Function: getPaymentManagementObservers
Description: Retrieves all payment management observer records from the datastore.
Parameters:
- None
Returns:
- util::Map<std::string, TrackedRecord<std::string>>: Collection of observer records
*/
util::Map<std::string, TrackedRecord<std::string>> DataStore::getPaymentManagementObservers()
{
return util::Map<std::string, TrackedRecord<std::string>>();
}
/*
Function: getInventoryManagementObservers
Description: Retrieves all inventory management observer records from the datastore.
Parameters:
- None
Returns:
- util::Map<std::string, TrackedRecord<std::string>>: Collection of observer records
*/
util::Map<std::string, TrackedRecord<std::string>> DataStore::getInventoryManagementObservers()
{
return util::Map<std::string, TrackedRecord<std::string>>();
}
/*
Function: saveUsers
Description: Persists all user records to the datastore.
Parameters:
- users: util::Map<std::string, TrackedRecord<User>>&, collection of user records
Returns:
- None
*/
void DataStore::saveUsers(util::Map<std::string, TrackedRecord<User>>& users)
{
}
/*
Function: saveNotifications
Description: Persists all notification records to the datastore.
Parameters:
- notifications: util::Map<std::string, TrackedRecord<Notification>>&, collection of notification records
Returns:
- None
*/
void DataStore::saveNotifications(util::Map<std::string, TrackedRecord<Notification>>& notifications)
{
}
/*
Function: saveServices
Description: Persists all service records to the datastore.
Parameters:
- services: util::Map<std::string, TrackedRecord<Service>>&, collection of service records
Returns:
- None
*/
void DataStore::saveServices(util::Map<std::string, TrackedRecord<Service>>& services)
{
}
/*
Function: saveComboPackages
Description: Persists all combo package records to the datastore.
Parameters:
- comboPackages: util::Map<std::string, TrackedRecord<ComboPackage>>&, collection of combo package records
Returns:
- None
*/
void DataStore::saveComboPackages(util::Map<std::string, TrackedRecord<ComboPackage>>& comboPackages)
{
}
/*
Function: saveInventoryItems
Description: Persists all inventory item records to the datastore.
Parameters:
- inventoryItems: util::Map<std::string, TrackedRecord<InventoryItem>>&, collection of inventory item records
Returns:
- None
*/
void DataStore::saveInventoryItems(util::Map<std::string, TrackedRecord<InventoryItem>>& inventoryItems)
{
}
/*
Function: saveServiceBookings
Description: Persists all service booking records to the datastore.
Parameters:
- bookings: util::Map<std::string, TrackedRecord<ServiceBooking>>&, collection of service booking records
Returns:
- None
*/
void DataStore::saveServiceBookings(util::Map<std::string, TrackedRecord<ServiceBooking>>& bookings)
{
}
/*
Function: saveJobCards
Description: Persists all job card records to the datastore.
Parameters:
- jobCards: util::Map<std::string, TrackedRecord<JobCard>>&, collection of job card records
Returns:
- None
*/
void DataStore::saveJobCards(util::Map<std::string, TrackedRecord<JobCard>>& jobCards)
{
}
/*
Function: saveInvoices
Description: Persists all invoice records to the datastore.
Parameters:
- invoices: util::Map<std::string, TrackedRecord<Invoice>>&, collection of invoice records
Returns:
- None
*/
void DataStore::saveInvoices(util::Map<std::string, TrackedRecord<Invoice>>& invoices)
{
}
/*
Function: savePayments
Description: Persists all payment records to the datastore.
Parameters:
- payments: util::Map<std::string, TrackedRecord<Payment>>&, collection of payment records
Returns:
- None
*/
void DataStore::savePayments(util::Map<std::string, TrackedRecord<Payment>>& payments)
{
}
/*
Function: saveServiceManagementObservers
Description: Persists all service management observer records to the datastore.
Parameters:
- observers: util::Map<std::string, TrackedRecord<std::string>>&, collection of observer records
Returns:
- None
*/
void DataStore::saveServiceManagementObservers(util::Map<std::string, TrackedRecord<std::string>>& observers)
{
}
/*
Function: savePaymentManagementObservers
Description: Persists all payment management observer records to the datastore.
Parameters:
- observers: util::Map<std::string, TrackedRecord<std::string>>&, collection of observer records
Returns:
- None
*/
void DataStore::savePaymentManagementObservers(util::Map<std::string, TrackedRecord<std::string>>& observers)
{
}
/*
Function: saveInventoryManagementObservers
Description: Persists all inventory management observer records to the datastore.
Parameters:
- observers: util::Map<std::string, TrackedRecord<std::string>>&, collection of observer records
Returns:
- None
*/
void DataStore::saveInventoryManagementObservers(util::Map<std::string, TrackedRecord<std::string>>& observers)
{
}
/*
Function: lockDataStore
Description: Acquires exclusive access to the datastore.
Parameters:
- None
Returns:
- bool: True if the datastore was successfully locked, otherwise false
*/
bool DataStore::lockDataStore()
{
return false;
}
/*
Function: unlockDataStore
Description: Releases exclusive access to the datastore.
Parameters:
- None
Returns:
- bool: True if the datastore was successfully unlocked, otherwise false
*/
bool DataStore::unlockDataStore()
{
return false;
}
/*
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;
}
@@ -40,6 +40,9 @@ private:
MappingInfo m_jobCards;
MappingInfo m_invoices;
MappingInfo m_payments;
MappingInfo m_serviceManagementObservers;
MappingInfo m_paymentManagementObservers;
MappingInfo m_inventoryManagementObservers;
public:
static DataStore& getInstance();
bool initialize();
@@ -53,6 +56,9 @@ public:
util::Map<std::string, TrackedRecord<JobCard>> getJobCards();
util::Map<std::string, TrackedRecord<Invoice>> getInvoices();
util::Map<std::string, TrackedRecord<Payment>> getPayments();
util::Map<std::string, TrackedRecord<std::string>> getServiceManagementObservers();
util::Map<std::string, TrackedRecord<std::string>> getPaymentManagementObservers();
util::Map<std::string, TrackedRecord<std::string>> getInventoryManagementObservers();
void saveUsers(util::Map<std::string, TrackedRecord<User>>& users);
void saveNotifications(util::Map<std::string, TrackedRecord<Notification>>& notifications);
void saveServices(util::Map<std::string, TrackedRecord<Service>>& services);
@@ -62,6 +68,9 @@ public:
void saveJobCards(util::Map<std::string, TrackedRecord<JobCard>>& jobCards);
void saveInvoices(util::Map<std::string, TrackedRecord<Invoice>>& invoices);
void savePayments(util::Map<std::string, TrackedRecord<Payment>>& payments);
void saveServiceManagementObservers(util::Map<std::string, TrackedRecord<std::string>>& observers);
void savePaymentManagementObservers(util::Map<std::string, TrackedRecord<std::string>>& observers);
void saveInventoryManagementObservers(util::Map<std::string, TrackedRecord<std::string>>& observers);
bool lockDataStore();
bool unlockDataStore();
private:
@@ -70,3 +79,93 @@ private:
template<typename TObject, typename TSerialized>
void saveRecords(MappingInfo& mapping, util::Map<std::string, TrackedRecord<TObject>>& records);
};
/*
Function: loadRecords
Description: Loads all serialized records from the specified
shared-memory mapping, deserializes them into
application objects, and returns them as a map
of tracked records. Each loaded record is marked
as CLEAN and assigned its corresponding slot index
within the mapping so that future modifications
can be written back efficiently.
Parameter:
- mapping: Reference to the mapping containing the
serialized records.
Return type:
util::Map<std::string, TrackedRecord<TObject>>
A map containing all loaded records keyed by
their unique identifier.
*/
template<typename TObject, typename TSerialized>
util::Map<std::string, TrackedRecord<TObject>> DataStore::loadRecords(MappingInfo& mapping)
{
util::Map<std::string, TrackedRecord<TObject>> records;
SharedMemory::ensureLatestMapping(mapping);
size_t recordCount = SharedMemory::getRecordCount(mapping);
for (size_t index = 0; index < recordCount; ++index)
{
TSerialized* serialized = static_cast<TSerialized*>(SharedMemory::getRecordAddress(mapping,index));
TObject* object = TObject::deserialize(*serialized);
TrackedRecord<TObject> trackedRecord;
trackedRecord.data = object;
trackedRecord.state = RecordState::CLEAN;
trackedRecord.slotIndex = index;
records.insert(object->getId(), trackedRecord);
}
return records;
}
/*
Function: saveRecords
Description: Persists all modified and newly added records
contained in the provided map to the specified
shared-memory mapping. Modified records overwrite
their existing slots, while new records are
appended to the end of the mapping. Records marked
as CLEAN are ignored. After persistence, all
temporary objects owned by the tracked records are
destroyed to release memory.
Parameter:
- mapping: Reference to the mapping where records are
stored.
- records: Map containing the records to be persisted.
Return type: void
*/
template<typename TObject, typename TSerialized> void DataStore::saveRecords(MappingInfo& mapping, util::Map<std::string, TrackedRecord<TObject>>& records)
{
SharedMemory::ensureLatestMapping(mapping);
for (int index = 0; index < records.getSize(); ++index)
{
TrackedRecord<TObject>& record = records.getValueAt(index);
if (record.state == RecordState::CLEAN)
{
continue;
}
TSerialized serialized = record.data->serialize();
if (record.state == RecordState::MODIFIED)
{
TSerialized* destination = static_cast<TSerialized*>(SharedMemory::getRecordAddress(mapping, record.slotIndex));
if (destination)
{
*destination = serialized;
}
}
else if (record.state == RecordState::NEW_RECORD)
{
if (!SharedMemory::ensureCapacityForInsert(mapping))
{
continue;
}
size_t recordCount = SharedMemory::getRecordCount(mapping);
TSerialized* destination = static_cast<TSerialized*>(SharedMemory::getRecordAddress(mapping, recordCount));
*destination = serialized;
SharedMemory::setRecordCount(mapping, recordCount + 1);
}
}
for (int index = 0; index < records.getSize(); ++index)
{
delete records.getValueAt(index).data;
records.getValueAt(index).data = nullptr;
}
}
@@ -4,6 +4,5 @@ enum class RecordState : int
{
CLEAN,
NEW_RECORD,
MODIFIED,
DELETED
MODIFIED
};
@@ -90,3 +90,8 @@ struct SerializedInvoice
util::PaymentMode paymentMethod;
util::PaymentStatus status;
};
struct SerializedObserver
{
char id[64];
};
@@ -167,24 +167,6 @@ void* SharedMemory::getRecordAddress(MappingInfo& mapping, size_t index)
return reinterpret_cast<char*>(mapping.mappedView) + sizeof(FileHeader) + index * mapping.recordSize;
}
/*
Function: getRecordAddress
Description: Returns the address of a record at the specified index within the mapped memory region.
Parameters:
- mapping: MappingInfo&, mapping information and handles
- index: size_t, record index
Returns:
- void*: Pointer to the record, or nullptr if the mapping is not valid
*/
void* SharedMemory::getRecordAddress(MappingInfo& mapping, size_t index)
{
if (mapping.mappedView == nullptr)
{
return nullptr;
}
return reinterpret_cast<char*>(mapping.mappedView) + sizeof(FileHeader) + index * mapping.recordSize;
}
/*
Function: getRecordCount
Description: Returns the number of records currently stored in the mapping.
@@ -29,16 +29,17 @@ namespace config
namespace file
{
const size_t INITIAL_CAPACITY = 100;
constexpr const char* INVENTORYITEM_FILE = "files/InventoryItem.csv";
constexpr const char* USER_FILE = "files/User.csv";
constexpr const char* NOTIFICATION_FILE = "files/Notification.csv";
constexpr const char* SERVICE_FILE = "files/Service.csv";
constexpr const char* COMBOPACKAGE_FILE = "files/ComboPackage.csv";
constexpr const char* SERVICEBOOKING_FILE = "files/ServiceBooking.csv";
constexpr const char* JOBCARD_FILE = "files/JobCard.csv";
constexpr const char* INVOICE_FILE = "files/Invoice.csv";
constexpr const char* SERVICEMANAGEMENTOBSERVERS = "files/ServiceManagementObservers.csv";
constexpr const char* PAYMENTMANAGEMENTOBSERVERS = "files/PaymentManagementObservers.csv";
constexpr const char* INVENTORYMANAGEMENTOBSERVERS = "files/InventoryManagementObservers.csv";
constexpr const char* DIRECTORY = "files/";
constexpr const char* INVENTORYITEM_FILE = "files/InventoryItem.dat";
constexpr const char* USER_FILE = "files/User.dat";
constexpr const char* NOTIFICATION_FILE = "files/Notification.dat";
constexpr const char* SERVICE_FILE = "files/Service.dat";
constexpr const char* COMBOPACKAGE_FILE = "files/ComboPackage.dat";
constexpr const char* SERVICEBOOKING_FILE = "files/ServiceBooking.dat";
constexpr const char* JOBCARD_FILE = "files/JobCard.dat";
constexpr const char* INVOICE_FILE = "files/Invoice.dat";
constexpr const char* SERVICEMANAGEMENTOBSERVERS = "files/ServiceManagementObservers.dat";
constexpr const char* PAYMENTMANAGEMENTOBSERVERS = "files/PaymentManagementObservers.dat";
constexpr const char* INVENTORYMANAGEMENTOBSERVERS = "files/InventoryManagementObservers.dat";
}
}