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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
|
/* This file is part of the KDE project
Copyright (C) 2003-2004 Jaroslaw Staniek <js@iidea.pl>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KEXIDB_DRIVER_P_H
#define KEXIDB_DRIVER_P_H
#ifndef __KEXIDB__
# error "Do not include: this is KexiDB internal file"
#endif
#include <qstring.h>
#include <qvariant.h>
#include <qmap.h>
#include <qptrdict.h>
#include <qasciidict.h>
#include <qvaluevector.h>
#include <kgenericfactory.h>
#include "connection.h"
#include "admin.h"
class KService;
namespace KexiDB {
/*! Detailed definition of driver's default behaviour.
Note for driver developers:
Change these defaults in you Driver subclass
constructor, if needed.
*/
class KEXI_DB_EXPORT DriverBehaviour
{
public:
DriverBehaviour();
//! "UNSIGNED" by default
QString UNSIGNED_TYPE_KEYWORD;
//! "AUTO_INCREMENT" by default, used as add-in word to field definition
//! May be also used as full definition if SPECIAL_AUTO_INCREMENT_DEF is true.
QString AUTO_INCREMENT_FIELD_OPTION;
//! "AUTO_INCREMENT PRIMARY KEY" by default, used as add-in word to field definition
//! May be also used as full definition if SPECIAL_AUTO_INCREMENT_DEF is true.
QString AUTO_INCREMENT_PK_FIELD_OPTION;
//! "" by default, used as type string for autoinc. field definition
//! pgsql defines it as "SERIAL", sqlite defines it as "INTEGER"
QString AUTO_INCREMENT_TYPE;
/*! True if autoincrement field has special definition
e.g. like "INTEGER PRIMARY KEY" for SQLite.
Special definition string should be stored in AUTO_INCREMENT_FIELD_OPTION.
False by default. */
bool SPECIAL_AUTO_INCREMENT_DEF : 1;
/*! True if autoincrement requires field to be declared as primary key.
This is true for SQLite. False by default. */
bool AUTO_INCREMENT_REQUIRES_PK : 1;
/*! Name of a field (or built-in function) with autoincremented unique value,
typically returned by Connection::drv_lastInsertRowID().
Examples:
- PostgreSQL and SQLite engines use 'OID' field
- MySQL uses LAST_INSERT_ID() built-in function
*/
QString ROW_ID_FIELD_NAME;
/*! True if the value (fetched from field or function,
defined by ROW_ID_FIELD_NAME member) is EXACTLY the value of autoincremented field,
not an implicit (internal) row number. Default value is false.
Examples:
- PostgreSQL and SQLite engines have this flag set to false ('OID' field has
it's own implicit value)
- MySQL engine has this flag set to true (LAST_INSERT_ID() returns real value
of last autoincremented field).
Notes:
If it's false, we have a convenient way for identifying row even when there's
no primary key defined. So, as '_ROWID' column in MySQL is really
just a synonym for the primary key, this engine needs to have primary keys always
defined if we want to use interactive editing features like row updating and deleting.
*/
bool ROW_ID_FIELD_RETURNS_LAST_AUTOINCREMENTED_VALUE : 1;
/*! Name of any (e.g. first found) database for this connection that
typically always exists. This can be not set if we want to do some magic checking
what database name is availabe by reimplementing
Connection::anyAvailableDatabaseName().
Example: for PostgreSQL this is "template1".
\sa Connection::SetAvailableDatabaseName()
*/
QString ALWAYS_AVAILABLE_DATABASE_NAME;
/*! Quotation marks used for escaping identifier (see Driver::escapeIdentifier()).
Default value is '"'. Change it for your driver.
*/
QChar QUOTATION_MARKS_FOR_IDENTIFIER;
/*! True if using database is requied to perform real connection.
This is true for may engines, e.g. for PostgreSQL, where connections
string should contain a database name.
This flag is unused for file-based db drivers,
by default set to true and used for all other db drivers.
*/
bool USING_DATABASE_REQUIRED_TO_CONNECT : 1;
/*! True if before we know whether the fetched result of executed query
is empty or not, we need to fetch first record. Particularly, it's true for SQLite.
The flag is used in Cursor::open(). By default this flag is false. */
bool _1ST_ROW_READ_AHEAD_REQUIRED_TO_KNOW_IF_THE_RESULT_IS_EMPTY : 1;
/*! True if "SELECT 1 from (subquery)" is supported. False by default.
Used in Connection::resultExists() for optimization. It's set to true for SQLite driver. */
bool SELECT_1_SUBQUERY_SUPPORTED : 1;
/*! Keywords that need to be escaped for the driver. Set this before calling
Driver::initSQLKeywords. */
const char** SQL_KEYWORDS;
};
/*! Private driver's data members. Available for implementation. */
class DriverPrivate
{
public:
DriverPrivate();
virtual ~DriverPrivate();
QPtrDict<Connection> connections;
//(js)now QObject::name() is reused:
// /*! The name equal to the service name (X-Kexi-DriverName)
// stored in given service .desktop file. Set this in subclasses. */
// QString m_driverName;
/*! Name of MIME type of files handled by this driver
if it is a file-based database's driver
(equal X-Kexi-FileDBDriverMime service property) */
QString fileDBDriverMimeType;
/*! Info about the driver as a service. */
KService *service;
/*! Internal constant flag: Set this in subclass if driver is a file driver */
bool isFileDriver : 1;
/*! Internal constant flag: Set this in subclass if after successful
drv_createDatabased() database is in opened state (as after useDatabase()).
For most engines this is not true. */
bool isDBOpenedAfterCreate : 1;
/*! List of system objects names, eg. build-in system tables that
cannot be used by user, and in most cases user even shouldn't see these.
The list contents is driver dependent (by default is empty)
- fill this in subclass ctor. */
// QStringList m_systemObjectNames;
/*! List of system fields names, build-in system fields that cannot be used by user,
and in most cases user even shouldn't see these.
The list contents is driver dependent (by default is empty) - fill this in subclass ctor. */
// QStringList m_systemFieldNames;
/*! Features (like transactions, etc.) supported by this driver
(sum of selected Features enum items).
This member should be filled in driver implementation's constructor
(by default m_features==NoFeatures). */
int features;
//! real type names for this engine
QValueVector<QString> typeNames;
/*! Driver properties dictionary (indexed by name),
useful for presenting properties to the user.
Set available properties here in driver implementation. */
QMap<QCString,QVariant> properties;
/*! i18n'd captions for properties. You do not need
to set predefined properties' caption in driver implementation
-it's done automatically. */
QMap<QCString,QString> propertyCaptions;
/*! Provides a number of database administration tools for the driver. */
AdminTools *adminTools;
/*! Kexi SQL keywords that need to be escaped if used as an identifier (e.g.
for a table or column name). These keywords will be escaped by the
front-end, even if they are not recognised by the backend to provide
UI consistency and to allow DB migration without changing the queries.
\sa DriverPrivate::initKexiKeywords(), KexiDB::kexiSQLKeywords.
*/
static QAsciiDict<bool>* kexiSQLDict;
static const char *kexiSQLKeywords[];
/*! Driver-specific SQL keywords that need to be escaped if used as an
identifier (e.g. for a table or column name) that aren't also Kexi SQL
keywords. These don't neccesarily need to be escaped when displayed by
the front-end, because they won't confuse the parser. However, they do
need to be escaped before sending to the DB-backend which will have
it's own parser.
\sa DriverBehaviour::SQL_KEYWORDS.
*/
QAsciiDict<bool>* driverSQLDict;
/*! Initialise the dictionary of Kexi SQL keywords used for escaping. */
void initKexiKeywords();
/*! Initialise the dictionary of driver-specific keywords used for escaping.
\a hashSize is the number of buckets to use in the dictionary.
\sa Driver::initSQLKeywords(). */
void initDriverKeywords(const char* keywords[], int hashSize);
protected:
/*! Used by driver manager to initialize properties taken using internal
driver flags. */
void initInternalProperties();
private:
void initKeywords(const char* keywords[], QAsciiDict<bool>& dict);
friend class DriverManagerInternal;
};
// escaping types for Driver::escapeBLOBInternal()
#define BLOB_ESCAPING_TYPE_USE_X 0 //!< escaping like X'abcd0', used by sqlite
#define BLOB_ESCAPING_TYPE_USE_0x 1 //!< escaping like 0xabcd0, used by mysql
#define BLOB_ESCAPING_TYPE_USE_OCTAL 2 //!< escaping like 'abcd\\000', used by pgsql
class KEXI_DB_EXPORT AdminTools::Private
{
public:
Private();
~Private();
};
}
//! Driver's static version information (implementation),
//! with KLibFactory symbol declaration.
#define KEXIDB_DRIVER_INFO( class_name, internal_name ) \
DatabaseVersionInfo class_name::version() const { return KEXIDB_VERSION; } \
K_EXPORT_COMPONENT_FACTORY(kexidb_ ## internal_name ## driver, KGenericFactory<KexiDB::class_name>( "kexidb_" #internal_name ))
#endif
|