KDb

PostgresqlDriver.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2003 Adam Pigg <[email protected]>
3  Copyright (C) 2010-2015 JarosÅ‚aw Staniek <[email protected]>
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this program; see the file COPYING. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19 */
20 
21 #include "PostgresqlDriver.h"
22 
23 #include "KDbConnection.h"
24 #include "KDbDriverManager.h"
25 #include "KDbDriverBehavior.h"
26 #include "KDbExpression.h"
27 #include "KDb.h"
28 
29 #include "PostgresqlConnection.h"
30 
31 #include <KPluginFactory>
32 
33 #include <libpq-fe.h>
34 
35 K_PLUGIN_CLASS_WITH_JSON(PostgresqlDriver, "kdb_postgresqldriver.json")
36 
37 PostgresqlDriver::PostgresqlDriver(QObject *parent, const QVariantList &args)
38  : KDbDriver(parent, args)
39 {
40  KDbDriverBehavior *beh = behavior();
41  beh->features = SingleTransactions | CursorForward | CursorBackward;
42 //! @todo enable this when KDb supports multiple: beh->features = MultipleTransactions | CursorForward | CursorBackward;
43 
45  beh->ROW_ID_FIELD_NAME = QLatin1String("oid");
46  beh->SPECIAL_AUTO_INCREMENT_DEF = false;
47  beh->AUTO_INCREMENT_TYPE = QLatin1String("SERIAL");
49  beh->AUTO_INCREMENT_PK_FIELD_OPTION = QLatin1String("PRIMARY KEY");
53  beh->LIKE_OPERATOR = QLatin1String("ILIKE");
54  // Use SQL compliant TRUE or FALSE as described
55  // at https://www.postgresql.org/docs/8.0/interactive/datatype-boolean.html
56  // 1 or 0 does not work.
57  beh->BOOLEAN_TRUE_LITERAL = QLatin1String("TRUE");
58  beh->BOOLEAN_FALSE_LITERAL = QLatin1String("FALSE");
61  "SELECT table_name FROM information_schema.tables WHERE "
62  "table_type='BASE TABLE' AND table_schema NOT IN ('pg_catalog', 'information_schema')");
63 
64  initDriverSpecificKeywords(m_keywords);
65  initPgsqlToKDbMap();
66 
67  //predefined properties
68  //https://www.postgresql.org/docs/9.5/static/libpq-misc.html#LIBPQ-PQLIBVERSION
69 //! @todo use QLibrary to resolve PQlibVersion
70  beh->properties.insert("client_library_version", PQlibVersion());
71  //! @todo pgsql default_server_encoding: should be a property of connection
72  //beh->properties["default_server_encoding"] = QString();
73 
74  beh->typeNames[KDbField::Byte] = QLatin1String("SMALLINT");
76  beh->typeNames[KDbField::Integer] = QLatin1String("INTEGER");
78  beh->typeNames[KDbField::Boolean] = QLatin1String("BOOLEAN");
79  beh->typeNames[KDbField::Date] = QLatin1String("DATE");
80  beh->typeNames[KDbField::DateTime] = QLatin1String("TIMESTAMP");
81  beh->typeNames[KDbField::Time] = QLatin1String("TIME");
82  beh->typeNames[KDbField::Float] = QLatin1String("REAL");
83  beh->typeNames[KDbField::Double] = QLatin1String("DOUBLE PRECISION");
84  beh->typeNames[KDbField::Text] = QLatin1String("CHARACTER VARYING");
86  beh->typeNames[KDbField::BLOB] = QLatin1String("BYTEA");
87 }
88 
89 PostgresqlDriver::~PostgresqlDriver()
90 {
91 }
92 
94 {
95  if (type == KDbField::Null) {
96  return QLatin1String("NULL");
97  }
98  if (type == KDbField::Float || type == KDbField::Double) {
99  if (field.precision() > 0) {
100  return QLatin1String("NUMERIC");
101  }
102  }
103  return KDbDriver::sqlTypeName(type, field);
104 }
105 
107  const KDbConnectionOptions &options)
108 {
109  return new PostgresqlConnection(this, connData, options);
110 }
111 
113 {
114  Q_UNUSED(name);
115  return false;
116 }
117 
119 {
120  Q_UNUSED(name);
121  return false;
122 }
123 
125 {
126  return 0 == name.compare(QLatin1String("template1"), Qt::CaseInsensitive)
127  || 0 == name.compare(QLatin1String("template0"), Qt::CaseInsensitive)
128  || 0 == name.compare(QLatin1String("postgres"), Qt::CaseInsensitive);
129 }
130 
132 {
133  //Cannot use libpq escape functions as they require a db connection
134  //to escape using the char encoding of the database
135  //see https://www.postgresql.org/docs/8.1/static/libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING
136  return KDbEscapedString("E'")
137  + KDbEscapedString(str).replace("\\", "\\\\").replace("'", "\\\'")
138  + "'";
139 }
140 
142 {
143  //Cannot use libpq escape functions as they require a db connection
144  //to escape using the char encoding of the database
145  //see https://www.postgresql.org/docs/8.1/static/libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING
146  return KDbEscapedString("'")
147  + QByteArray(str).replace("\\", "\\\\").replace("'", "\\\'")
148  + "'";
149 }
150 
152 {
153  return QString(str).replace(QLatin1Char('"'), QLatin1String("\"\""));
154 }
155 
157 {
158  return QByteArray(str).replace('"', "\"\"");
159 }
160 
162 {
164 }
165 
168  KDb::ExpressionCallStack* callStack) const
169 {
170  Q_ASSERT(args.argCount() == 1);
171  return KDbEscapedString("UPPER(ENCODE(%1, 'hex'))").arg(args.arg(0).toString(this, params, callStack));
172 }
173 
176  KDb::ExpressionCallStack* callStack) const
177 {
178  return KDbFunctionExpression::toString(QLatin1String("COALESCE"), this, args, params, callStack);
179 }
180 
183  KDb::ExpressionCallStack* callStack) const
184 {
185  Q_ASSERT(args.argCount() == 1);
186  if (args.arg(0).type() == KDbField::BLOB) {
187  return KDbFunctionExpression::toString(QLatin1String("OCTET_LENGTH"), this, args, params, callStack);
188  }
189  return KDbDriver::lengthFunctionToString(args, params, callStack); // default
190 }
191 
193  const KDbNArgExpression &args,
195  KDb::ExpressionCallStack* callStack) const
196 {
198  name, this, args, params, callStack);
199 }
200 
202  const KDbNArgExpression &args,
204  KDb::ExpressionCallStack* callStack) const
205 {
206  Q_ASSERT(args.argCount() == 1);
207  return KDbEscapedString("ASCII(%1)").arg(args.arg(0).toString(this, params, callStack));
208 }
209 
210 #include "PostgresqlDriver.moc"
KDbEscapedString hexFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const override
Generates native (driver-specific) HEX() function call.
KDbEscapedString GET_TABLE_NAMES_SQL
SQL statement used to obtain list of physical table names.
@ ByteaHex
"bytea hex" escaping, e.g.
virtual QString sqlTypeName(KDbField::Type type, const KDbField &field) const
Definition: KDbDriver.cpp:130
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
QString UNSIGNED_TYPE_KEYWORD
"UNSIGNED" by default
QString drv_escapeIdentifier(const QString &str) const override
KDbExpression arg(int i) const
CaseInsensitive
An iterator for a list of values of query schema parameters Allows to iterate over parameters and ret...
@ Text
Definition: KDbField.h:98
KDbEscapedString escapeBLOB(const QByteArray &array) const override
Escape BLOB value array.
bool USE_TEMPORARY_DATABASE_FOR_CONNECTION_IF_NEEDED
Specialized string for escaping.
QString AUTO_INCREMENT_TYPE
"" by default, used as type string for autoinc.
QString ALWAYS_AVAILABLE_DATABASE_NAME
Database driver's abstraction.
Definition: KDbDriver.h:49
QVector< QString > typeNames
real type names for this engine
QString AUTO_INCREMENT_FIELD_OPTION
"AUTO_INCREMENT" by default, used as add-in word to field definition May be also used as full definit...
bool isSystemDatabaseName(const QString &name) const override
KDbEscapedString lengthFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const override
Generates native (driver-specific) LENGTH() function call.
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 ...
QString sqlTypeName(KDbField::Type type, const KDbField &field) const override
Overrides the default implementation to allow for NUMERIC type natively.
@ Integer
Definition: KDbField.h:90
KDbEscapedString toString(const KDbDriver *driver, KDbQuerySchemaParameterValueListIterator *params=nullptr, KDb::ExpressionCallStack *callStack=nullptr) const
KDbUtils::PropertySet properties
int precision() const
Definition: KDbField.cpp:286
static KDbEscapedString greatestOrLeastFunctionUsingCaseToString(const QString &name, const KDbDriver *driver, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack)
KDbConnection * drv_createConnection(const KDbConnectionData &connData, const KDbConnectionOptions &options) override
@ BigInteger
Definition: KDbField.h:91
@ Double
Definition: KDbField.h:97
@ LongText
Definition: KDbField.h:99
QByteArray & replace(int pos, int len, const char *after)
QString & replace(int position, int n, QChar after)
@ Byte
Definition: KDbField.h:87
KDbEscapedString unicodeFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const override
Generates native (driver-specific) UNICODE() function call.
The KDbNArgExpression class represents a base class N-argument expression.
KDB_EXPORT QString escapeBLOB(const QByteArray &array, BLOBEscapingType type)
KDbEscapedString greatestOrLeastFunctionToString(const QString &name, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const override
Generates native (driver-specific) GREATEST() and LEAST() function calls.
KDbEscapedString escapeString(const QString &str) const override
Escape a string for use as a value.
Detailed definition of driver's default behavior.
@ Boolean
Definition: KDbField.h:92
static KDbEscapedString toString(const QString &name, const KDbDriver *driver, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack)
Database specific connection data, e.g. host, port.
virtual KDbEscapedString lengthFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) LENGTH() function call.
Definition: KDbDriver.cpp:335
Generic options for a single connection. The options are accessible using key/value pairs....
char CLOSING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER
bool isSystemObjectName(const QString &name) const override
Meta-data for a field.
Definition: KDbField.h:71
KDbEscapedString ifnullFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const override
Generates native (driver-specific) IFNULL() function call.
@ Float
Definition: KDbField.h:96
Provides database connection, allowing queries and data modification.
Definition: KDbConnection.h:51
#define K_PLUGIN_CLASS_WITH_JSON(classname, jsonFile)
KDbField::Type type() const
PostgreSQL database driver.
bool drv_isSystemFieldName(const QString &name) const override
@ ShortInteger
Definition: KDbField.h:89
char OPENING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Nov 29 2023 04:11:26 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.