1
/* This file is part of the KDE project
2
Copyright (C) 2004 Martin Ellis <m.a.ellis@ncl.ac.uk>
3
Copyright (C) 2006-2016 Jarosław Staniek <staniek@kde.org>
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.
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.
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.
21
#include "KexiSqlMigrate.h"
22
#include <keximigratedata.h>
25
#include <KDbDriverManager>
26
#include <KDbConnectionProxy>
27
#include <KDbSqlResult>
28
#include <KDbSqlString>
29
#include <KDbQueryColumnInfo>
30
#include <KDbQuerySchema>
32
KexiSqlMigrate::KexiSqlMigrate(const QString &kdbDriverId, QObject *parent,
33
const QVariantList& args)
34
: KexiMigration::KexiMigrate(parent, args)
35
, m_kdbDriverId(kdbDriverId)
37
Q_ASSERT(!m_kdbDriverId.isEmpty());
40
KexiSqlMigrate::~KexiSqlMigrate()
44
KDbConnection* KexiSqlMigrate::drv_createConnection()
46
KDbDriverManager manager;
47
KDbDriver *driver = manager.driver(m_kdbDriverId);
49
m_result = manager.result();
52
KDbConnection *c = driver->createConnection(*data()->source);
53
m_result = c ? KDbResult() : driver->result();
57
bool KexiSqlMigrate::drv_readTableSchema(
58
const QString& originalName, KDbTableSchema *tableSchema)
60
//! @todo IDEA: ask for user input for captions
62
//Perform a query on the table to get some data
63
KDbEscapedString sql = KDbEscapedString("SELECT * FROM %1 LIMIT 0")
64
.arg(sourceConnection()->escapeIdentifier(tableSchema->name()));
65
QScopedPointer<KDbSqlResult> result(sourceConnection()->executeSQL(sql));
71
const int fieldsCount = result->fieldsCount();
72
for (int i = 0; i < fieldsCount; i++) {
73
KDbField *field = result->createField(originalName, i);
74
if (field->type() == KDbField::InvalidType) {
75
field->setType(userType(originalName + '.' + field->name()));
77
if (!tableSchema->addField(field)) {
87
bool KexiSqlMigrate::drv_tableNames(QStringList *tableNames)
89
QScopedPointer<KDbSqlResult> result(sourceConnection()->executeSQL(m_tableNamesSql));
90
if (!result || result->fieldsCount() < 1) {
94
QScopedPointer<KDbSqlRecord> record(result->fetchRecord());
96
if (result->lastResult().isError()) {
101
tableNames->append(record->stringValue(0));
106
tristate KexiSqlMigrate::drv_queryStringListFromSQL(
107
const KDbEscapedString& sqlStatement, int fieldIndex, QStringList *stringList, int numRecords)
109
QScopedPointer<KDbSqlResult> result(sourceConnection()->executeSQL(sqlStatement));
113
if (result->fieldsCount() < (fieldIndex+1)) {
114
qWarning() << sqlStatement << ": fieldIndex too large ("
115
<< fieldIndex << "), expected 0.." << result->fieldsCount() - 1;
118
for (int i = 0; numRecords == -1 || i < numRecords; i++) {
119
QScopedPointer<KDbSqlRecord> record(result->fetchRecord());
121
if (numRecords != -1 || result->lastResult().isError()) {
126
stringList->append(record->stringValue(fieldIndex));
131
bool KexiSqlMigrate::drv_copyTable(const QString& srcTable, KDbConnection *destConn,
132
KDbTableSchema* dstTable,
133
const RecordFilter *recordFilter)
135
QScopedPointer<KDbSqlResult> result(
136
sourceConnection()->executeSQL(KDbEscapedString("SELECT * FROM %1")
137
.arg(sourceConnection()->escapeIdentifier(srcTable))));
141
const KDbQueryColumnInfo::Vector fieldsExpanded(dstTable->query()->fieldsExpanded());
142
const int numFields = qMin(fieldsExpanded.count(), result->fieldsCount());
144
QScopedPointer<KDbSqlRecord> record(result->fetchRecord());
146
if (!result->lastResult().isError()) {
152
if (!(*recordFilter)(*record)) {
156
QList<QVariant> vals;
157
for(int i = 0; i < numFields; ++i) {
158
const KDbSqlString s(record->cstringValue(i));
159
vals.append(KDb::cstringToVariant(
160
s.string, fieldsExpanded.at(i)->field->type(), 0, s.length));
164
if (!(*recordFilter)(vals)) {
168
if (!destConn->insertRecord(dstTable, vals)) {
172
/*! @todo Check that wasn't an error, rather than end of result set */
176
bool KexiSqlMigrate::drv_getTableSize(const QString& table, quint64 *size)
179
QScopedPointer<KDbSqlResult> result(
180
sourceConnection()->executeSQL(KDbEscapedString("SELECT COUNT(*) FROM %1")
181
.arg(sourceConnection()->escapeIdentifier(table))));
185
QScopedPointer<KDbSqlRecord> record(result->fetchRecord());
186
if (!result || result->fieldsCount() == 0) {
190
quint64 value = record->toByteArray(0).toULongLong(&ok);
198
KDbSqlResult* KexiSqlMigrate::drv_readFromTable(const QString& tableName)
200
QScopedPointer<KDbSqlResult> result(sourceConnection()->executeSQL(KDbEscapedString("SELECT * FROM %1")
201
.arg(sourceConnection()->escapeIdentifier(tableName))));
202
if (!result || result->lastResult().isError()) {
203
m_result = sourceConnection()->result();
204
qWarning() << m_result;
207
return result.take();