meos-2024/code/RunnerDB.h
2017-08-30 08:57:46 +02:00

250 lines
6.5 KiB
C++

#pragma once
#include <vector>
#include <map>
#include "inthashmap.h"
#include "oclub.h"
#include <hash_set>
/************************************************************************
MeOS - Orienteering Software
Copyright (C) 2009-2017 Melin Software HB
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Melin Software HB - software@melin.nu - www.melin.nu
Eksoppsvägen 16, SE-75646 UPPSALA, Sweden
************************************************************************/
const int baseNameLength=32;
//Has 0-clearing constructor. Must not contain any
//dynamic data etc.
struct RunnerDBEntryV1 {
RunnerDBEntryV1();
char name[baseNameLength];
int cardNo;
int clubNo;
char national[3];
char sex;
short int birthYear;
short int reserved;
};
struct RunnerDBEntry {
// Init from old struct
void init(const RunnerDBEntryV1 &dbe);
RunnerDBEntry();
/** Binary compatible with V1*/
char name[baseNameLength];
int cardNo;
int clubNo;
char national[3];
char sex;
short int birthYear;
short int reserved;
/** End of V1*/
__int64 extId;
void getName(string &name) const;
void setName(const char *name);
string getGivenName() const;
string getFamilyName() const;
string getNationality() const;
int getBirthYear() const {return birthYear;}
string getSex() const;
__int64 getExtId() const;
void setExtId(__int64 id);
bool isRemoved() const {return (reserved & 1) == 1;}
void remove() {reserved |= 1;}
};
typedef vector<RunnerDBEntry> RunnerDBVector;
class oDBRunnerEntry;
class oClass;
class oDBClubEntry;
class RunnerDB {
private:
oEvent *oe;
Table *runnerTable;
Table *clubTable;
bool check(const RunnerDBEntry &rde) const;
intkeymap<oClass *, __int64> runnerInEvent;
/** Init name hash lazy */
void setupNameHash() const;
void setupIdHash() const;
void setupCNHash() const;
vector<RunnerDBEntry> rdb;
vector<oDBClubEntry> cdb;
vector<oDBRunnerEntry> oRDB;
// Runner card hash
inthashmap rhash;
// Runner id hash
mutable intkeymap<int, __int64> idhash;
// Club id hash
inthashmap chash;
// Last known free index
int freeCIx;
// Name hash
mutable multimap<string, int> nhash;
// Club name hash
mutable multimap<string, int> cnhash;
static void canonizeSplitName(const string &name, vector<string> &split);
bool loadedFromServer;
/** Date when database was updated. The format is YYYYMMDD */
int dataDate;
/** Time when database was updated. The format is HH:MM:SS */
int dataTime;
void fillClubs(vector< pair<string, size_t> > &out) const;
public:
void generateRunnerTableData(Table &table, oDBRunnerEntry *addEntry);
void generateClubTableData(Table &table, oClub *addEntry);
void refreshRunnerTableData(Table &table);
void refreshClubTableData(Table &table);
void refreshTables();
Table *getRunnerTB();
Table *getClubTB();
void hasEnteredCompetition(__int64 extId);
void releaseTables();
/** Get the date, YYYY-MM-DD HH:MM:SS when database was updated */
string getDataDate() const;
/** Set the date YYYY-MM-DD HH:MM:SS when database was updated */
void setDataDate(const string &date);
/** Returns true if the database was loaded from server */
bool isFromServer() const {return loadedFromServer;}
/** Prepare for loading runner from server*/
void prepareLoadFromServer(int nrunner, int nclub);
const vector<RunnerDBEntry>& getRunnerDB() const;
const vector<oDBClubEntry>& getClubDB() const;
void clearRunners();
void clearClubs();
/** Add a club. Create a new Id if necessary*/
int addClub(oClub &c, bool createNewId);
RunnerDBEntry *addRunner(const char *name, __int64 extId,
int club, int card);
oDBRunnerEntry *addRunner();
oClub *addClub();
RunnerDBEntry *getRunnerByIndex(size_t index) const;
RunnerDBEntry *getRunnerById(__int64 extId) const;
RunnerDBEntry *getRunnerByCard(int card) const;
RunnerDBEntry *getRunnerByName(const string &name, int clubId,
int expectedBirthYear) const;
bool getClub(int clubId, string &club) const;
oClub *getClub(int clubId) const;
oClub *getClub(const string &name) const;
void saveClubs(const char *file);
void saveRunners(const char *file);
void loadRunners(const char *file);
void loadClubs(const char *file);
void updateAdd(const oRunner &r, map<int, int> &clubIdMap);
void importClub(oClub &club, bool matchName);
void compactifyClubs();
void getAllNames(vector<string> &givenName, vector<string> &familyName);
RunnerDB(oEvent *);
~RunnerDB(void);
friend class oDBRunnerEntry;
friend class oDBClubEntry;
};
class oDBRunnerEntry : public oBase {
private:
RunnerDB *db;
int index;
protected:
/** Get internal data buffers for DI */
oDataContainer &getDataBuffers(pvoid &data, pvoid &olddata, pvectorstr &strData) const;
int getDISize() const {return 0;}
void changedObject() {}
public:
int getIndex() const {return index;}
void init(RunnerDB *db_, int index_) {db=db_, index=index_; Id = index;}
const RunnerDBEntry &getRunner() const;
void addTableRow(Table &table) const;
bool inputData(int id, const string &input,
int inputId, string &output, bool noUpdate);
void fillInput(int id, vector< pair<string, size_t> > &out, size_t &selected);
oDBRunnerEntry(oEvent *oe);
virtual ~oDBRunnerEntry();
void remove();
bool canRemove() const;
string getInfo() const {return "Database Runner";}
};
class oDBClubEntry : public oClub {
private:
int index;
RunnerDB *db;
public:
oDBClubEntry(oEvent *oe, int id, int index, RunnerDB *db);
oDBClubEntry(const oClub &c, int index, RunnerDB *db);
int getTableId() const;
virtual ~oDBClubEntry();
void remove();
bool canRemove() const;
};