KDb

SqliteDriver.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003-2015 Jarosław Staniek <staniek@kde.org>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "SqliteDriver.h"
21#include "SqliteConnection.h"
22#include "SqliteConnection_p.h"
23#include "SqliteAdmin.h"
24
25#include "KDbConnection.h"
26#include "KDbDriverManager.h"
27#include "KDbDriverBehavior.h"
28#include "KDbExpression.h"
29#include "KDb.h"
30
31#include <KPluginFactory>
32
33#include <sqlite3.h>
34
35K_PLUGIN_CLASS_WITH_JSON(SqliteDriver, "kdb_sqlitedriver.json")
36
37//! driver specific private data
38//! @internal
39class SqliteDriverPrivate
40{
41public:
42 SqliteDriverPrivate()
43 : collate(QLatin1String(" COLLATE ''"))
44 {
45 }
46 KDbEscapedString collate;
47 Q_DISABLE_COPY(SqliteDriverPrivate)
48};
49
50SqliteDriver::SqliteDriver(QObject *parent, const QVariantList &args)
51 : KDbDriver(parent, args)
52 , dp(new SqliteDriverPrivate)
53{
54 KDbDriverBehavior *beh = behavior();
55 beh->features = SingleTransactions | CursorForward | CompactingDatabaseSupported;
56
57 //special method for autoincrement definition
59 beh->AUTO_INCREMENT_FIELD_OPTION = QString(); //not available
60 beh->AUTO_INCREMENT_TYPE = QLatin1String("INTEGER");
63 beh->ROW_ID_FIELD_NAME = QLatin1String("OID");
64 beh->IS_DB_OPEN_AFTER_CREATE = true;
73 = KDbEscapedString("SELECT name FROM sqlite_master WHERE type='table'");
74
75 initDriverSpecificKeywords(keywords);
76
77 // internal properties
78 beh->properties.insert("client_library_version", QLatin1String(sqlite3_libversion()));
79 beh->properties.insert("default_server_encoding", QLatin1String("UTF8")); //OK?
80
82 beh->typeNames[KDbField::ShortInteger] = QLatin1String("ShortInteger");
83 beh->typeNames[KDbField::Integer] = QLatin1String("Integer");
84 beh->typeNames[KDbField::BigInteger] = QLatin1String("BigInteger");
85 beh->typeNames[KDbField::Boolean] = QLatin1String("Boolean");
86 beh->typeNames[KDbField::Date] = QLatin1String("Date"); // In fact date/time types could be declared as datetext etc.
87 beh->typeNames[KDbField::DateTime] = QLatin1String("DateTime"); // to force text affinity..., see https://sqlite.org/datatype3.html
88 beh->typeNames[KDbField::Time] = QLatin1String("Time");
94}
95
96SqliteDriver::~SqliteDriver()
97{
98 delete dp;
99}
100
101
104 const KDbConnectionOptions &options)
105{
106 return new SqliteConnection(this, connData, options);
107}
108
110{
111 return name.startsWith(QLatin1String("sqlite_"), Qt::CaseInsensitive);
112}
113
115{
116 Q_UNUSED(name);
117 return false;
118}
119
121{
122 return 0 == name.compare(QLatin1String("_rowid_"), Qt::CaseInsensitive)
123 || 0 == name.compare(QLatin1String("rowid"), Qt::CaseInsensitive)
124 || 0 == name.compare(QLatin1String("oid"), Qt::CaseInsensitive);
125}
126
128{
129 return KDbEscapedString("'") + KDbEscapedString(str).replace('\'', "''") + '\'';
130}
131
133{
134 return KDbEscapedString("'") + KDbEscapedString(str).replace('\'', "''") + '\'';
135}
136
141
143{
144 return QString(str).replace(QLatin1Char('"'), QLatin1String("\"\""));
145}
146
148{
149 return QByteArray(str).replace('"', "\"\"");
150}
151
156
158{
159 return dp->collate;
160}
161
163 const KDbNArgExpression &args,
165 KDb::ExpressionCallStack* callStack) const
166{
167 Q_ASSERT(args.argCount() >= 2);
168 static QString greatestString(QLatin1String("GREATEST"));
169 static QString maxString(QLatin1String("MAX"));
170 static QString minString(QLatin1String("MIN"));
171 const QString realName(
172 name == greatestString ? maxString : minString);
173 if (args.argCount() >= 2 && KDbField::isTextType(args.arg(0).type())) {
175 s.reserve(256);
176 for(int i=0; i < args.argCount(); ++i) {
177 if (!s.isEmpty()) {
178 s += ", ";
179 }
180 s += QLatin1Char('(') + args.arg(i).toString(this, params, callStack) + QLatin1String(") ") + collationSql();
181 }
182 return realName + QLatin1Char('(') + s + QLatin1Char(')');
183 }
184 return KDbFunctionExpression::toString(realName, this, args, params, callStack);
185}
186
189 KDb::ExpressionCallStack* callStack) const
190{
191 if (args.isNull() || args.argCount() < 1 ) {
192 static KDbEscapedString randomStatic("((RANDOM()+9223372036854775807)/18446744073709551615)");
193 return randomStatic;
194 }
195 Q_ASSERT(args.argCount() == 2);
196 const KDbEscapedString x(args.arg(0).toString(this, params, callStack));
197 const KDbEscapedString y(args.arg(1).toString(this, params, callStack));
198 static KDbEscapedString floorRandomStatic("+CAST(((");
199 static KDbEscapedString floorRandomStatic2("))*(RANDOM()+9223372036854775807)/18446744073709551615 AS INT))");
200 //! (X + CAST((Y - X) * (RANDOM()+9223372036854775807)/18446744073709551615 AS INT)).
201 return KDbEscapedString("((") + x + QLatin1Char(')') + floorRandomStatic + y + QLatin1Char(')')
202 + QLatin1String("-(") + x + floorRandomStatic2;
203}
204
206 const KDbNArgExpression &args,
208 KDb::ExpressionCallStack* callStack) const
209{
210 Q_ASSERT(args.argCount() == 1);
211 static QLatin1String ceilingString("CEILING");
212 KDbEscapedString x(args.arg(0).toString(this, params, callStack));
213 if (name == ceilingString) {
214 return KDbEscapedString("(CASE WHEN ")
215 + x + QLatin1String("=CAST(") + x + QLatin1String(" AS INT) THEN CAST(")
216 + x + QLatin1String(" AS INT) WHEN ")
217 + x + QLatin1String(">=0 THEN CAST(")
218 + x + QLatin1String(" AS INT)+1 ELSE CAST(")
219 + x + QLatin1String(" AS INT) END)");
220 }
221 // floor():
222 return KDbEscapedString("(CASE WHEN ") + x + QLatin1String(">=0 OR ")
223 + x + QLatin1String("=CAST(") + x + QLatin1String(" AS INT) THEN CAST(")
224 + x + QLatin1String(" AS INT) ELSE CAST(")
225 + x + QLatin1String(" AS INT)-1 END)");
226}
227
228#include "SqliteDriver.moc"
An interface containing a set of tools for database administration.
Definition KDbAdmin.h:31
Database specific connection data, e.g. host, port.
Generic options for a single connection. The options are accessible using key/value pairs....
Provides database connection, allowing queries and data modification.
Detailed definition of driver's default behavior.
QString AUTO_INCREMENT_FIELD_OPTION
"AUTO_INCREMENT" by default, used as add-in word to field definition May be also used as full definit...
KDbEscapedString GET_TABLE_NAMES_SQL
SQL statement used to obtain list of physical table names.
char OPENING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER
QString AUTO_INCREMENT_PK_FIELD_OPTION
"AUTO_INCREMENT PRIMARY KEY" by default, used as add-in word to field definition May be also used as ...
KDbUtils::PropertySet properties
QVector< QString > typeNames
real type names for this engine
QString AUTO_INCREMENT_TYPE
"" by default, used as type string for autoinc.
char CLOSING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER
bool CONNECTION_REQUIRED_TO_CHECK_DB_EXISTENCE
bool _1ST_ROW_READ_AHEAD_REQUIRED_TO_KNOW_IF_THE_RESULT_IS_EMPTY
Database driver's abstraction.
Definition KDbDriver.h:50
Specialized string for escaping.
bool isNull() const
KDbEscapedString toString(const KDbDriver *driver, KDbQuerySchemaParameterValueListIterator *params=nullptr, KDb::ExpressionCallStack *callStack=nullptr) const
KDbField::Type type() const
bool isTextType() const
Definition KDbField.h:353
@ Integer
Definition KDbField.h:90
@ Boolean
Definition KDbField.h:92
@ ShortInteger
Definition KDbField.h:89
@ BigInteger
Definition KDbField.h:91
@ LongText
Definition KDbField.h:99
static KDbEscapedString toString(const QString &name, const KDbDriver *driver, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack)
The KDbNArgExpression class represents a base class N-argument expression.
KDbExpression arg(int i) const
An iterator for a list of values of query schema parameters Allows to iterate over parameters and ret...
void insert(const QByteArray &name, const QVariant &value, const QString &caption=QString())
Inserts property with a given name, value and caption.
Definition KDbUtils.cpp:660
#define K_PLUGIN_CLASS_WITH_JSON(classname, jsonFile)
An interface containing a set of tools for SQLite database administration.
Definition SqliteAdmin.h:28
SQLite-specific connection Following connection options are supported (see KDbConnectionOptions):
SQLite database driver.
QString drv_escapeIdentifier(const QString &str) const override
KDbConnection * drv_createConnection(const KDbConnectionData &connData, const KDbConnectionOptions &options) override
KDbEscapedString collationSql() const override
bool isSystemObjectName(const QString &n) const override
KDbEscapedString greatestOrLeastFunctionToString(const QString &name, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const override
Generates native (driver-specific) GREATEST() and LEAST() function calls.
KDbAdminTools * drv_createAdminTools() const override
bool isSystemDatabaseName(const QString &) const override
bool drv_isSystemFieldName(const QString &n) const override
KDbEscapedString randomFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const override
Generates native (driver-specific) RANDOM() and RANDOM(X,Y) function calls.
KDbEscapedString escapeBLOB(const QByteArray &array) const override
Escape BLOB value array.
KDbEscapedString ceilingOrFloorFunctionToString(const QString &name, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const override
Generates native (driver-specific) CEILING() and FLOOR() function calls.
KDbEscapedString escapeString(const QString &str) const override
Escape a string for use as a value.
@ XHex
Escaping like X'1FAD', used by sqlite (hex numbers)
KDB_EXPORT QString escapeBLOB(const QByteArray &array, BLOBEscapingType type)
QByteArray & replace(QByteArrayView before, QByteArrayView after)
int compare(QLatin1StringView s1, const QString &s2, Qt::CaseSensitivity cs)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
CaseInsensitive
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 22 2024 12:11:01 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.