File: SQLiteConnection.h

package info (click to toggle)
vcmi 1.6.5%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid, trixie
  • size: 32,060 kB
  • sloc: cpp: 238,971; python: 265; sh: 224; xml: 157; ansic: 78; objc: 61; makefile: 49
file content (125 lines) | stat: -rw-r--r-- 3,403 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
 * SQLiteConnection.h, part of VCMI engine
 *
 * Authors: listed in file AUTHORS in main folder
 *
 * License: GNU General Public License v2.0 or later
 * Full text of license available in license.txt file, in main folder
 *
 */
#pragma once

using sqlite3 = struct sqlite3;
using sqlite3_stmt = struct sqlite3_stmt;

class SQLiteInstance;
class SQLiteStatement;

using SQLiteInstancePtr = std::unique_ptr<SQLiteInstance>;
using SQLiteStatementPtr = std::unique_ptr<SQLiteStatement>;

class SQLiteStatement : boost::noncopyable
{
public:
	friend class SQLiteInstance;

	bool execute();
	void reset();
	void clear();

	~SQLiteStatement();

	template<typename... Args>
	void executeOnce(const Args &... args)
	{
		setBinds(args...);
		execute();
		reset();
	}

	template<typename... Args>
	void setBinds(const Args &... args)
	{
		setBindSingle(1, args...); // The leftmost SQL parameter has an index of 1
	}

	template<typename... Args>
	void getColumns(Args &... args)
	{
		getColumnSingle(0, args...); // The leftmost column of the result set has the index 0
	}

private:
	void setBindSingle(size_t index, const double & value);
	void setBindSingle(size_t index, const bool & value);
	void setBindSingle(size_t index, const uint8_t & value);
	void setBindSingle(size_t index, const uint16_t & value);
	void setBindSingle(size_t index, const uint32_t & value);
	void setBindSingle(size_t index, const int32_t & value);
	void setBindSingle(size_t index, const int64_t & value);
	void setBindSingle(size_t index, const std::string & value);
	void setBindSingle(size_t index, const char * value);

	void getColumnSingle(size_t index, double & value);
	void getColumnSingle(size_t index, bool & value);
	void getColumnSingle(size_t index, uint8_t & value);
	void getColumnSingle(size_t index, uint16_t & value);
	void getColumnSingle(size_t index, uint32_t & value);
	void getColumnSingle(size_t index, int32_t & value);
	void getColumnSingle(size_t index, int64_t & value);
	void getColumnSingle(size_t index, std::string & value);

	template < typename T, typename std::enable_if_t < std::is_enum_v<T>, int  > = 0 >
	void getColumnSingle(size_t index, T & value)
	{
		using Integer = std::underlying_type_t<T>;
		Integer result;
		getColumnSingle(index, result);

		value = static_cast<T>(result);
	}

	template<typename Rep, typename Period>
	void getColumnSingle(size_t index, std::chrono::duration<Rep, Period> & value)
	{
		int64_t durationValue = 0;
		getColumnSingle(index, durationValue);
		value = std::chrono::duration<Rep, Period>(durationValue);
	}

	SQLiteStatement(SQLiteInstance & instance, sqlite3_stmt * statement);

	template<typename T, typename... Args>
	void setBindSingle(size_t index, T const & arg, const Args &... args)
	{
		setBindSingle(index, arg);
		setBindSingle(index + 1, args...);
	}

	template<typename T, typename... Args>
	void getColumnSingle(size_t index, T & arg, Args &... args)
	{
		getColumnSingle(index, arg);
		getColumnSingle(index + 1, args...);
	}

	SQLiteInstance & m_instance;
	sqlite3_stmt * m_statement;
};

class SQLiteInstance : boost::noncopyable
{
public:
	friend class SQLiteStatement;

	static SQLiteInstancePtr open(const boost::filesystem::path & db_path, bool allow_write);

	~SQLiteInstance();

	SQLiteStatementPtr prepare(const std::string & statement);

private:
	explicit SQLiteInstance(sqlite3 * connection);

	sqlite3 * m_connection;
};