File: SQL.h

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (209 lines) | stat: -rw-r--r-- 6,956 bytes parent folder | download | duplicates (2)
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#pragma once
#include "Core/Maybe.h"
#include "Core/Array.h"
#include "Core/Variant.h"
#include "Core/WeakSet.h"
#include "Row.h"
#include "Schema.h"
#include "Migration.h"
#include "QueryStr.h"
#include "Transaction.h"
#include "CachedQuery.h"
#include "Features.h"

namespace sql {

	class DBConnection;

	/**
	 * A prepared statement associated with a database connection.
	 *
	 * Abstract base class that is overridden by different database implementations.
	 */
	class Statement : public Object {
		STORM_ABSTRACT_CLASS;
	public:
		// Create.
		STORM_CTOR Statement(DBConnection *connection);

		// Disallow copy and move across thread boundaries.
		Statement(const Statement &o);
		virtual void STORM_FN deepCopy(CloneEnv *env);

		// Bind parameters.
		virtual void STORM_FN bind(Nat pos, Str *str) ABSTRACT;
		virtual void STORM_FN bind(Nat pos, Bool b) ABSTRACT;
		virtual void STORM_FN bind(Nat pos, Int i) ABSTRACT;
		virtual void STORM_FN bind(Nat pos, Long i) ABSTRACT;
		virtual void STORM_FN bind(Nat pos, Float f) ABSTRACT;
		virtual void STORM_FN bind(Nat pos, Double d) ABSTRACT;

		// Bind a null value.
		virtual void STORM_FN bindNull(Nat pos) ABSTRACT;

		/**
		 * Type describing the result of executing a statement. Acts like an iterator.
		 *
		 * The iterator is invalidated as soon as the parent statement object is modified in any
		 * way. At that time, the iterator acts as if the end of the iteration was reached.
		 *
		 * The database implementation may opt to stream data from the database until the iterator
		 * is destroyed. This implies that the database might be locked until this happens. It is
		 * possible to manually dispose of any resources in the database by calling 'finalize'.
		 */
		class Result {
			STORM_VALUE;
		public:
			Result(Statement *owner);
			Result(const Result &other);
			Result &operator =(const Result &other);
			~Result();

			// Get the next row.
			Maybe<Row> STORM_FN next();

			// Get the last inserted row ID.
			Int STORM_FN lastRowId() const;

			// Get the number of changes made when INSERT, UPDATE or DELETE was executed.
			Nat STORM_FN changes() const;

			// Finalize the result prematurely.
			void STORM_FN finalize();

			// To allow use in for-each loops:
			Result STORM_FN iter() { return *this; }

			// Deep copy: to issue an error.
			void STORM_FN deepCopy(CloneEnv *env);

		private:
			// Owning statement.
			Statement *owner;

			// Query sequence number.
			Nat sequence;
		};

		// Execute the prepared statement with the currently bound parameters. Returns an iterator
		// that can be used to retrieve the result. Any subsequent modification of the statement
		// (e.g. modifying bound parameters or calling 'execute' again) invalidates the returned
		// iterator.
		virtual Result STORM_FN execute() ABSTRACT;

		// Finalize (dispose of) the statement. It will not be usable again.
		// Finalize is called automatically by the destructor of derived classes,
		// but since finalization by the GC may not happen instantly, calling
		// finalize manually can make resource reclamation quicker.
		virtual void STORM_FN finalize() ABSTRACT;

	protected:
		// Called by derived classes to invalidate existing Result instances.
		void STORM_FN invalidateResult();

		// Called by the implementation whenever the current result can be disposed.
		virtual void STORM_FN disposeResult() ABSTRACT;

		// Called by iterators to get the next row.
		virtual Maybe<Row> STORM_FN nextRow() ABSTRACT;

		// Called by iterators to get the last row id.
		virtual Int STORM_FN lastRowId() ABSTRACT;

		// Called by iterators to get the number of changes.
		virtual Nat STORM_FN changes() ABSTRACT;

		// De-register from the DB connection to avoid multiple finalization messages.
		void STORM_FN deregister(DBConnection *c);

	private:
		// Number of Result objects that are currently alive. When it reaches zero, we can end the
		// current query even if not all rows were extracted.
		Nat resultAliveCount;

		// Query sequence number. Used to invalidate iterators for previous executions of the
		// statement.
		Nat resultSequence;
	};

	// Wrappers that allow binding maybe types conveniently.
	// Note: These can not be member functions since the string overload
	// would clash in C++.
	void STORM_FN bind(Statement *to, Nat pos, MAYBE(Str *) str);
	void STORM_FN bind(Statement *to, Nat pos, Maybe<Bool> b);
	void STORM_FN bind(Statement *to, Nat pos, Maybe<Int> i);
	void STORM_FN bind(Statement *to, Nat pos, Maybe<Long> l);
	void STORM_FN bind(Statement *to, Nat pos, Maybe<Float> f);
	void STORM_FN bind(Statement *to, Nat pos, Maybe<Double> d);


	/**
	 * A database connection.
	 *
	 * A connection to some database. This is the generic interface that the rest of the database
	 * system utilizes.
	 */
	class DBConnection : public Object {
		STORM_ABSTRACT_CLASS;
	public:
		// Create.
		STORM_CTOR DBConnection();

		// Disallow copying.
		DBConnection(const DBConnection &o);

		// Disallow moving across thread boundaries.
		virtual void STORM_FN deepCopy(CloneEnv *env);

		// Create a prepared statement. Throws an error if the statement is invalid.
		virtual Statement *STORM_FN prepare(Str *query) ABSTRACT;
		virtual Statement *STORM_FN prepare(QueryStr *query);

		// Create a prepared statement from a CachedQuery. This causes the connection to prepare the
		// query the first time it is seen, and use the cached version for all subsequent calls.
		Statement *STORM_FN prepare(CachedQuery *cached);

		// Closes the connection to the database. The base implementation finalizes all prepared
		// statements associated with this connection.
		virtual void STORM_FN close();

		// Returns all names of tables in SQLite connection in an Array of Str.
		virtual Array<Str*> *STORM_FN tables() ABSTRACT;

		// Returns a Schema for a particular table.
		virtual MAYBE(Schema *) STORM_FN schema(Str *table) ABSTRACT;

		// Migrate data according to the supplied Migration object.
		virtual void STORM_FN migrate(Migration *migration) ABSTRACT;

		// Get features of this database, that the database library or any other user might need to
		// consider.
		virtual features::DBFeatures STORM_FN features() const ABSTRACT;

	protected:
		// Get the visitor for converting query strings.
		virtual QueryStr::Visitor *STORM_FN visitor() const ABSTRACT;

		// Start a transaction.
		virtual void STORM_FN beginTransaction() ABSTRACT;

		// End a transaction.
		virtual void STORM_FN endTransaction(Transaction::End end) ABSTRACT;

	private:
		friend class Statement;

		// All prepared statements associated with this connection.
		WeakSetBase *statements;

		// Cached queries (based on object identity)
		// TODO: This is a good candidate for a weak hash table where the keys are weak.
		RefMap<CachedQuery *, Statement *> *cachedStatements;

		friend class Transaction;

		// Current topmost transaction, if any.
		Transaction::State *transaction;
	};

}