I'm trying to construct a simple database for use by 2 persons only (myself and other guy), right now, we're using excel table with 4 fields "requisition, origin date, request date and authorized date", but I want to take it to the next level :D. So, I'm building this small database app to emulate that, the file will be shared and I'm not worried about not being able to load the file if it's in use by him ( or viceversa). This database consists of 2 classes "Element" and "Records", element carries each row data, and records handles vectors of elements, it's the connection with the outer world for elements.
I need help on this to know, if this is much code, or a little bit of code, or how can it be improved?, I'm not worried about speed or disk space or access time, this database will contain at much 5,000 records.
Later on, this code will be used on winapi.
This is the code, I'm using visual studio:
Element.h
#pragma once
#include <cstdint>
#include <ctime>
class Element
{
public:
Element(uint32_t requi, time_t originDate,
time_t requestDate, time_t authorizedDate, uint64_t amount, bool hasTax, bool authorized = false);
void SetId(uint32_t id)
{
this->id = id;
}
uint32_t GetId() const
{
return id;
}
bool operator<(const Element& rhs) const
{
return requi < rhs.requi;
}
uint32_t GetRequi() const
{
return requi;
}
time_t GetOriginDate() const
{
return originDate;
}
time_t GetRequestDate() const
{
return requestDate;
}
time_t GetAuthorizedDate() const
{
return authorizedDate;
}
uint64_t GetAmount() const
{
return amount;
}
bool IsTaxed() const
{
return hasTax;
}
bool IsAuthorized() const
{
return authorized;
}
bool operator<(const Element& rhs)
{
return requi < rhs.requi;
}
bool operator>(const Element& rhs)
{
return requi > rhs.requi;
}
bool operator==(const Element& rhs)
{
return requi == rhs.requi;
}
void Authorize();
void Print();
private:
uint32_t id;
uint32_t requi;
time_t originDate;
time_t requestDate;
time_t authorizedDate;
uint64_t amount;
bool hasTax;
bool reviewed = true;
bool authorized = false;
};
Element.cpp
#include "Element.h"
#include <iostream>
Element::Element(uint32_t requi, time_t originDate,
time_t requestDate, time_t authorizedDate, uint64_t amount, bool hasTax, bool authorized)
:
requi(requi),
originDate(originDate),
requestDate(requestDate),
authorizedDate(authorizedDate),
amount(amount),
hasTax(hasTax),
authorized(authorized)
{
}
void Element::Authorize()
{
std::time(&authorizedDate);
authorized = true;
}
void Element::Print() // not used at the moment
{
std::cout << "Id: " << id << ", Requi: " << requi << ", Monto: $ "
<< amount << std::endl;
}
Records.h
#pragma once
#include <string>
#include <vector>
#include "Element.h"
class Records
{
public:
friend std::ostream& operator<<(std::ostream& out, const Element& rhs)
{
out << "Id: " << rhs.GetId() << ", Requi: " << rhs.GetRequi() << ", Monto: $ "
<< int(rhs.GetAmount() / 100) << "." << int(rhs.GetAmount() % 100)
<< (rhs.IsTaxed() ? " mas IVA":" neto (no aplica IVA)");
return out;
}
void Insert(Element& element);
void SaveToFile();
void LoadFromFile();
void ListRequi();
private:
std::vector<Element> elements;
unsigned int nRecords = 0;
};
Records.cpp
#include "Records.h"
#include <cassert>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <iostream>
void Records::Insert(Element & element)
{
//autoincrement record count and use it as indes (id)
element.SetId(++nRecords);
elements.emplace_back(element);
}
void Records::SaveToFile()
{
std::ofstream file("datos.txt", std::ios::binary);
assert(file);
if (file)
{
nRecords = (unsigned int)elements.size();
file.write(reinterpret_cast<char*>(&nRecords), sizeof(nRecords) );
if (nRecords > 0)
{
for (auto& e : elements)
{
uint32_t tmpId = e.GetId();
uint32_t tmpRequi = e.GetRequi();
time_t tmpOrigin = e.GetOriginDate();
time_t tmpRequest = e.GetRequestDate();
time_t tmpAuth = e.GetAuthorizedDate();
uint64_t tmpAmount = e.GetAmount();
bool tmpTaxed = e.IsTaxed();
bool tmoAuthorized = e.IsAuthorized();
file.write(reinterpret_cast<char*>(&tmpId), sizeof(tmpId));
file.write(reinterpret_cast<char*>(&tmpRequi), sizeof(tmpRequi));
file.write(reinterpret_cast<char*>(&tmpOrigin), sizeof(tmpOrigin));
file.write(reinterpret_cast<char*>(&tmpRequest), sizeof(tmpRequest));
file.write(reinterpret_cast<char*>(&tmpAuth), sizeof(tmpAuth));
file.write(reinterpret_cast<char*>(&tmpAmount), sizeof(tmpAmount));
file.write(reinterpret_cast<char*>(&tmpTaxed), sizeof(tmpTaxed));
file.write(reinterpret_cast<char*>(&tmoAuthorized), sizeof(tmoAuthorized));
}
}
}
}
void Records::LoadFromFile()
{
std::ifstream file("datos.txt", std::ios::binary);
assert(file);
if (file)
{
unsigned int nTmpRecords = 0;
nRecords = 0;
file.read(reinterpret_cast<char*>(&nTmpRecords), sizeof(nTmpRecords));
if (nTmpRecords > 0)
{
elements.clear();
for (unsigned int i = 0; i < nTmpRecords && file.good(); ++i)
{
uint32_t tmpId = 0;
uint32_t tmpRequi = 0;
time_t tmpOrigin = 0;
time_t tmpRequest = 0;
time_t tmpAuth = 0;
uint64_t tmpAmount = 0;
bool tmpTaxed;
bool tmpAuthorized;
file.read(reinterpret_cast<char*>(&tmpId), sizeof(tmpId));
file.read(reinterpret_cast<char*>(&tmpRequi), sizeof(tmpRequi));
file.read(reinterpret_cast<char*>(&tmpOrigin), sizeof(tmpOrigin));
file.read(reinterpret_cast<char*>(&tmpRequest), sizeof(tmpRequest));
file.read(reinterpret_cast<char*>(&tmpAuth), sizeof(tmpAuth));
file.read(reinterpret_cast<char*>(&tmpAmount), sizeof(tmpAmount));
file.read(reinterpret_cast<char*>(&tmpTaxed), sizeof(tmpTaxed));
file.read(reinterpret_cast<char*>(&tmpAuthorized), sizeof(tmpAuthorized));
Element tmpElement(tmpRequi, tmpOrigin, tmpRequest, tmpAuth,
tmpAmount, tmpTaxed, tmpAuthorized);
tmpElement.SetId(tmpId);
elements.emplace_back(tmpElement);
}
}
}
}
void Records::ListRequi()
{
if (elements.size() > 0)
{
std::sort(elements.begin(), elements.end());
//test code
//auto result = std::find_if(elements.begin(), elements.end(),
// [](const Element& e)
// {
// return e.GetId() == 2;
// });
//if (result != elements.end())
//{
// std::cout << result->GetRequi() << std::endl;
//}
std::copy(elements.begin(), elements.end(), std::ostream_iterator<Element>(std::cout, "\n") );
}
}
This is just to test the database app, it will save to a file named "datos.txt".
main.cpp
#include <iostream>
#include "Records.h"
#include <algorithm>
#include <ctime>
int main()
{
//test code to insert elements to records and save to file
{
time_t tRequest = 0;
time_t tElaboration = 0;
// get today's date and time
std::time(&tRequest);
std::time(&tElaboration);
Records reg;
reg.Insert(Element(22132, tElaboration, tRequest, 0, 1586450, true));
reg.Insert(Element(22340, tElaboration, tRequest, 0, 123490, false));
reg.Insert(Element(45398, tElaboration, tRequest, 0, 58674, true));
reg.Insert(Element(21518, tElaboration, tRequest, 0, 879965, true));
reg.SaveToFile();
std::cout << "The following records has been saved: \n";
reg.ListRequi();
}
std::cout << "======================================\n";
//test code to load elements to memory from file
{
Records reg;
reg.LoadFromFile();
std::cout << "\nThe following records has been loaded \n";
reg.ListRequi();
}
std::cin.get();
return 0;
}