~ubuntu-branches/debian/sid/kexi/sid

« back to all changes in this revision

Viewing changes to src/migration/KexiSqlMigrate.cpp

  • Committer: Package Import Robot
  • Author(s): Pino Toscano
  • Date: 2017-06-24 20:10:10 UTC
  • Revision ID: package-import@ubuntu.com-20170624201010-5lrzd5r2vwthwifp
Tags: upstream-3.0.1.1
Import upstream version 3.0.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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>
 
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 "KexiSqlMigrate.h"
 
22
#include <keximigratedata.h>
 
23
#include <kexi.h>
 
24
 
 
25
#include <KDbDriverManager>
 
26
#include <KDbConnectionProxy>
 
27
#include <KDbSqlResult>
 
28
#include <KDbSqlString>
 
29
#include <KDbQueryColumnInfo>
 
30
#include <KDbQuerySchema>
 
31
 
 
32
KexiSqlMigrate::KexiSqlMigrate(const QString &kdbDriverId, QObject *parent,
 
33
                               const QVariantList& args)
 
34
        : KexiMigration::KexiMigrate(parent, args)
 
35
        , m_kdbDriverId(kdbDriverId)
 
36
{
 
37
    Q_ASSERT(!m_kdbDriverId.isEmpty());
 
38
}
 
39
 
 
40
KexiSqlMigrate::~KexiSqlMigrate()
 
41
{
 
42
}
 
43
 
 
44
KDbConnection* KexiSqlMigrate::drv_createConnection()
 
45
{
 
46
    KDbDriverManager manager;
 
47
    KDbDriver *driver = manager.driver(m_kdbDriverId);
 
48
    if (!driver) {
 
49
        m_result = manager.result();
 
50
        return nullptr;
 
51
    }
 
52
    KDbConnection *c = driver->createConnection(*data()->source);
 
53
    m_result = c ? KDbResult() : driver->result();
 
54
    return c;
 
55
}
 
56
 
 
57
bool KexiSqlMigrate::drv_readTableSchema(
 
58
    const QString& originalName, KDbTableSchema *tableSchema)
 
59
{
 
60
//! @todo IDEA: ask for user input for captions
 
61
 
 
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));
 
66
    if (!result) {
 
67
        return false;
 
68
    }
 
69
 
 
70
    bool ok = true;
 
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()));
 
76
        }
 
77
        if (!tableSchema->addField(field)) {
 
78
            delete field;
 
79
            tableSchema->clear();
 
80
            ok = false;
 
81
            break;
 
82
        }
 
83
    }
 
84
    return ok;
 
85
}
 
86
 
 
87
bool KexiSqlMigrate::drv_tableNames(QStringList *tableNames)
 
88
{
 
89
    QScopedPointer<KDbSqlResult> result(sourceConnection()->executeSQL(m_tableNamesSql));
 
90
    if (!result || result->fieldsCount() < 1) {
 
91
        return false;
 
92
    }
 
93
    Q_FOREVER {
 
94
        QScopedPointer<KDbSqlRecord> record(result->fetchRecord());
 
95
        if (!record) {
 
96
            if (result->lastResult().isError()) {
 
97
                return false;
 
98
            }
 
99
            break;
 
100
        }
 
101
        tableNames->append(record->stringValue(0));
 
102
    }
 
103
    return true;
 
104
}
 
105
 
 
106
tristate KexiSqlMigrate::drv_queryStringListFromSQL(
 
107
    const KDbEscapedString& sqlStatement, int fieldIndex, QStringList *stringList, int numRecords)
 
108
{
 
109
    QScopedPointer<KDbSqlResult> result(sourceConnection()->executeSQL(sqlStatement));
 
110
    if (!result) {
 
111
        return true;
 
112
    }
 
113
    if (result->fieldsCount() < (fieldIndex+1)) {
 
114
        qWarning() << sqlStatement << ": fieldIndex too large ("
 
115
                   << fieldIndex << "), expected 0.." << result->fieldsCount() - 1;
 
116
        return false;
 
117
    }
 
118
    for (int i = 0; numRecords == -1 || i < numRecords; i++) {
 
119
        QScopedPointer<KDbSqlRecord> record(result->fetchRecord());
 
120
        if (!record) {
 
121
            if (numRecords != -1 || result->lastResult().isError()) {
 
122
                return false;
 
123
            }
 
124
            return true;
 
125
        }
 
126
        stringList->append(record->stringValue(fieldIndex));
 
127
    }
 
128
    return true;
 
129
}
 
130
 
 
131
bool KexiSqlMigrate::drv_copyTable(const QString& srcTable, KDbConnection *destConn,
 
132
                                 KDbTableSchema* dstTable,
 
133
                                 const RecordFilter *recordFilter)
 
134
{
 
135
    QScopedPointer<KDbSqlResult> result(
 
136
        sourceConnection()->executeSQL(KDbEscapedString("SELECT * FROM %1")
 
137
            .arg(sourceConnection()->escapeIdentifier(srcTable))));
 
138
    if (!result) {
 
139
        return false;
 
140
    }
 
141
    const KDbQueryColumnInfo::Vector fieldsExpanded(dstTable->query()->fieldsExpanded());
 
142
    const int numFields = qMin(fieldsExpanded.count(), result->fieldsCount());
 
143
    Q_FOREVER {
 
144
        QScopedPointer<KDbSqlRecord> record(result->fetchRecord());
 
145
        if (!record) {
 
146
            if (!result->lastResult().isError()) {
 
147
                break;
 
148
            }
 
149
            return false;
 
150
        }
 
151
        if (recordFilter) {
 
152
            if (!(*recordFilter)(*record)) {
 
153
                continue;
 
154
            }
 
155
        }
 
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));
 
161
        }
 
162
        updateProgress();
 
163
        if (recordFilter) {
 
164
            if (!(*recordFilter)(vals)) {
 
165
                continue;
 
166
            }
 
167
        }
 
168
        if (!destConn->insertRecord(dstTable, vals)) {
 
169
            return false;
 
170
        }
 
171
    }
 
172
    /*! @todo Check that wasn't an error, rather than end of result set */
 
173
    return true;
 
174
}
 
175
 
 
176
bool KexiSqlMigrate::drv_getTableSize(const QString& table, quint64 *size)
 
177
{
 
178
    Q_ASSERT(size);
 
179
    QScopedPointer<KDbSqlResult> result(
 
180
        sourceConnection()->executeSQL(KDbEscapedString("SELECT COUNT(*) FROM %1")
 
181
                                       .arg(sourceConnection()->escapeIdentifier(table))));
 
182
    if (!result) {
 
183
        return false;
 
184
    }
 
185
    QScopedPointer<KDbSqlRecord> record(result->fetchRecord());
 
186
    if (!result || result->fieldsCount() == 0) {
 
187
        return false;
 
188
    }
 
189
    bool ok;
 
190
    quint64 value = record->toByteArray(0).toULongLong(&ok);
 
191
    if (!ok) {
 
192
        value = -1;
 
193
    }
 
194
    *size = value;
 
195
    return ok;
 
196
}
 
197
 
 
198
KDbSqlResult* KexiSqlMigrate::drv_readFromTable(const QString& tableName)
 
199
{
 
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;
 
205
        return nullptr;
 
206
    }
 
207
    return result.take();
 
208
}