1#ifndef ENGINE_SERVER_DATABASES_CONNECTION_H
2#define ENGINE_SERVER_DATABASES_CONNECTION_H
3
4#include "connection_pool.h"
5
6#include <engine/shared/protocol.h>
7
8#include <memory>
9
10enum
11{
12 // MAX_NAME_LENGTH includes the size with \0, which is not necessary in SQL
13 MAX_NAME_LENGTH_SQL = MAX_NAME_LENGTH - 1,
14};
15
16class IConsole;
17
18// can hold one PreparedStatement with Results
19class IDbConnection
20{
21public:
22 IDbConnection(const char *pPrefix);
23 virtual ~IDbConnection() = default;
24 IDbConnection &operator=(const IDbConnection &) = delete;
25 virtual void Print(IConsole *pConsole, const char *pMode) = 0;
26
27 // returns the database prefix
28 const char *GetPrefix() const { return m_aPrefix; }
29 virtual const char *BinaryCollate() const = 0;
30 // can be inserted into queries to convert a timestamp variable to the unix timestamp
31 virtual void ToUnixTimestamp(const char *pTimestamp, char *aBuf, unsigned int BufferSize) = 0;
32 // since MySQL automatically converts timestamps to utc, meanwhile sqlite code has to
33 // explicitly convert before inserting timestamps, NOTE: CURRENT_TIMESTAMP in SQLite is UTC by
34 // default and doesn't have to be converted
35 virtual const char *InsertTimestampAsUtc() const = 0;
36 // can be used in the context of `LIKE Map`, adds `? COLLATE`
37 virtual const char *CollateNocase() const = 0;
38 // syntax to insert a row into table or ignore if it already exists
39 virtual const char *InsertIgnore() const = 0;
40 // ORDER BY RANDOM()/RAND()
41 virtual const char *Random() const = 0;
42 // Get Median Map Time from l.Map
43 virtual const char *MedianMapTime(char *pBuffer, int BufferSize) const = 0;
44 virtual const char *False() const = 0;
45 virtual const char *True() const = 0;
46
47 // tries to allocate the connection from the pool established
48 //
49 // returns true on success
50 virtual bool Connect(char *pError, int ErrorSize) = 0;
51 // has to be called to return the connection back to the pool
52 virtual void Disconnect() = 0;
53
54 // ? for Placeholders, connection has to be established, can overwrite previous prepared statements
55 //
56 // returns true on success
57 virtual bool PrepareStatement(const char *pStmt, char *pError, int ErrorSize) = 0;
58
59 // PrepareStatement has to be called beforehand,
60 virtual void BindString(int Idx, const char *pString) = 0;
61 virtual void BindBlob(int Idx, unsigned char *pBlob, int Size) = 0;
62 virtual void BindInt(int Idx, int Value) = 0;
63 virtual void BindInt64(int Idx, int64_t Value) = 0;
64 virtual void BindFloat(int Idx, float Value) = 0;
65 virtual void BindNull(int Idx) = 0;
66
67 // Print expanded sql statement
68 virtual void Print() = 0;
69
70 // executes the query and returns if a result row exists and selects it
71 // when called multiple times the next row is selected
72 //
73 // returns true on success
74 virtual bool Step(bool *pEnd, char *pError, int ErrorSize) = 0;
75 // executes the query and returns the number of rows affected by the update/insert/delete
76 //
77 // returns true on success
78 virtual bool ExecuteUpdate(int *pNumUpdated, char *pError, int ErrorSize) = 0;
79
80 virtual bool IsNull(int Col) = 0;
81 virtual float GetFloat(int Col) = 0;
82 virtual int GetInt(int Col) = 0;
83 virtual int64_t GetInt64(int Col) = 0;
84 // ensures that the string is null terminated
85 virtual void GetString(int Col, char *pBuffer, int BufferSize) = 0;
86 // returns number of bytes read into the buffer
87 virtual int GetBlob(int Col, unsigned char *pBuffer, int BufferSize) = 0;
88
89 // SQL statements, that can't be abstracted, has side effects to the result
90 virtual bool AddPoints(const char *pPlayer, int Points, char *pError, int ErrorSize) = 0;
91
92private:
93 char m_aPrefix[64];
94
95protected:
96 void FormatCreateRace(char *aBuf, unsigned int BufferSize, bool Backup) const;
97 void FormatCreateTeamrace(char *aBuf, unsigned int BufferSize, const char *pIdType, bool Backup) const;
98 void FormatCreateMaps(char *aBuf, unsigned int BufferSize) const;
99 void FormatCreateSaves(char *aBuf, unsigned int BufferSize, bool Backup) const;
100 void FormatCreatePoints(char *aBuf, unsigned int BufferSize) const;
101};
102
103bool MysqlAvailable();
104int MysqlInit();
105void MysqlUninit();
106
107std::unique_ptr<IDbConnection> CreateSqliteConnection(const char *pFilename, bool Setup);
108// Returns nullptr if MySQL support is not compiled in.
109std::unique_ptr<IDbConnection> CreateMysqlConnection(CMysqlConfig Config);
110
111#endif // ENGINE_SERVER_DATABASES_CONNECTION_H
112