3
* TOra - An Oracle Toolkit for DBA's and developers
4
* Copyright (C) 2003-2005 Quest Software, Inc
5
* Portions Copyright (C) 2005 Other Contributors
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; only version 2 of
10
* the License is valid for this program.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
* As a special exception, you have permission to link this program
22
* with the Oracle Client libraries and distribute executables, as long
23
* as you follow the requirements of the GNU GPL in regard to all of the
24
* software in the executable aside from Oracle client libraries.
26
* Specifically you are not permitted to link this program with the
27
* Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech.
28
* And you are not permitted to distribute binaries compiled against
29
* these libraries without written consent from Quest Software, Inc.
30
* Observe that this does not disallow linking to the Qt Free Edition.
32
* You may link this product with any GPL'd Qt library such as Qt/Free
34
* All trademarks belong to their respective owners.
41
#include "toconnection.h"
42
#include "tohighlightedtext.h"
50
#include <qapplication.h>
52
#include <qprogressdialog.h>
53
#include <qtextstream.h>
56
// A little magic to get lrefresh to work and get a check on qApp
58
#undef QT_TRANSLATE_NOOP
59
#define QT_TRANSLATE_NOOP(x,y) QTRANS(x,y)
61
#define TO_DEBUGOUT(x) fprintf(stderr,(const char *)x);
63
// Connection provider implementation
65
std::map<QCString, toConnectionProvider *> *toConnectionProvider::Providers;
66
std::map<QCString, toConnectionProvider *> *toConnectionProvider::Types;
68
static int NumberFormat;
69
static int NumberDecimals;
71
void toConnectionProvider::checkAlloc(void)
74
Providers = new std::map<QCString, toConnectionProvider *>;
77
void toConnectionProvider::addProvider(const QCString &provider)
81
(*Providers)[Provider] = this;
84
toConnectionProvider::toConnectionProvider(const QCString &provider, bool add
90
addProvider(provider);
92
Types = new std::map<QCString, toConnectionProvider *>;
93
(*Types)[provider] = this;
96
std::list<QString> toConnectionProvider::providedOptions(const QCString &)
98
std::list<QString> ret;
102
void toConnectionProvider::removeProvider(const QCString &provider)
104
std::map<QCString, toConnectionProvider *>::iterator i = Providers->find(provider);
105
if (i != Providers->end())
109
toConnectionProvider::~toConnectionProvider()
113
if (!Provider.isEmpty())
114
removeProvider(Provider);
115
std::map<QCString, toConnectionProvider *>::iterator i = Types->find(Provider);
116
if (i != Types->end())
123
std::list<QString> toConnectionProvider::providedHosts(const QCString &)
125
std::list<QString> ret;
129
std::list<QCString> toConnectionProvider::providers()
131
std::list<QCString> ret;
134
for (std::map<QCString, toConnectionProvider *>::iterator i = Providers->begin();i != Providers->end();i++)
135
ret.insert(ret.end(), (*i).first);
139
void toConnectionProvider::initializeAll(void)
142
for (std::map<QCString, toConnectionProvider *>::iterator i = Types->begin();
143
i != Types->end();i++)
144
(*i).second->initialize();
147
toConnectionProvider &toConnectionProvider::fetchProvider(const QCString &provider)
150
std::map<QCString, toConnectionProvider *>::iterator i = Providers->find(provider);
151
if (i == Providers->end())
152
throw QT_TRANSLATE_NOOP("toConnectionProvider", "Tried to fetch unknown provider %1").arg(provider);
153
return *((*i).second);
156
std::list<QString> toConnectionProvider::options(const QCString &provider)
158
return fetchProvider(provider).providedOptions(provider);
161
QWidget *toConnectionProvider::configurationTab(const QCString &provider, QWidget *parent)
163
return fetchProvider(provider).providerConfigurationTab(provider, parent);
166
toConnection::connectionImpl *toConnectionProvider::connection(const QCString &provider,
169
return fetchProvider(provider).provideConnection(provider, conn);
172
std::list<QString> toConnectionProvider::hosts(const QCString &provider)
174
return fetchProvider(provider).providedHosts(provider);
177
std::list<QString> toConnectionProvider::databases(const QCString &provider, const QString &host,
178
const QString &user, const QString &pwd)
180
return fetchProvider(provider).providedDatabases(provider, host, user, pwd);
183
const QString &toConnectionProvider::config(const QCString &tag, const QCString &def)
185
QCString str = Provider;
188
return toTool::globalConfig(str, def);
191
void toConnectionProvider::setConfig(const QCString &tag, const QCString &def)
193
QCString str = Provider;
196
toTool::globalSetConfig(str, def);
199
QWidget *toConnectionProvider::providerConfigurationTab(const QCString &, QWidget *)
204
// Query value implementation
206
toQValue::toQValue(int i)
212
toQValue::toQValue(double i)
218
toQValue::toQValue(const toQValue ©)
224
Value.Int = copy.Value.Int;
227
Value.Double = copy.Value.Double;
230
Value.String = new QString(*copy.Value.String);
233
Value.Array = new QByteArray(*copy.Value.Array);
240
const toQValue &toQValue::operator = (const toQValue ©)
242
if (Type == stringType)
244
else if (Type == binaryType)
251
Value.Int = copy.Value.Int;
254
Value.Double = copy.Value.Double;
257
Value.String = new QString(*copy.Value.String);
260
Value.Array = new QByteArray(*copy.Value.Array);
268
bool toQValue::operator == (const toQValue &val) const
270
if (isNull() && val.isNull())
272
if (val.Type != Type)
277
return (val.Value.Int == Value.Int);
279
return (val.Value.Double == Value.Double);
281
return (*val.Value.String) == (*Value.String);
283
return (*val.Value.Array) == (*Value.Array);
287
return false; // Should never get here
290
toQValue::toQValue(const QString &str)
293
Value.String = new QString(str);
296
toQValue::toQValue(void)
301
toQValue::~toQValue()
303
if (Type == stringType)
305
else if (Type == binaryType)
309
bool toQValue::isInt(void) const
311
return Type == intType;
314
bool toQValue::isDouble(void) const
316
return Type == doubleType;
319
bool toQValue::isString(void) const
321
return Type == stringType;
324
bool toQValue::isBinary(void) const
326
return Type == binaryType;
329
bool toQValue::isNull(void) const
331
if (Type == nullType)
333
if (Type == stringType && Value.String->isNull())
338
const QByteArray &toQValue::toByteArray() const
340
if (Type != binaryType)
341
throw qApp->translate("toQValue", "Tried to convert non binary value to binary");
345
static char HexString[] = "0123456789ABCDEF";
347
QCString toQValue::utf8(void) const
359
ret.setNum(Value.Int);
365
if (Value.Double != int(Value.Double))
367
ret.setNum(Value.Double);
371
switch (NumberFormat)
374
ret.setNum(Value.Double);
377
sprintf(buf, "%E", Value.Double);
381
sprintf(buf, "%0.*f", NumberDecimals, Value.Double);
388
return Value.String->utf8();
391
QCString ret(Value.Array->size()*2 + 1);
392
for (unsigned int i = 0;i < Value.Array->size();i++)
394
unsigned char c = (unsigned char)Value.Array->at(i);
395
ret.at(i*2) = HexString[(c / 16) % 16];
396
ret.at(i*2 + 1) = HexString[c % 16];
398
ret.at(Value.Array->size()*2) = 0;
402
throw qApp->translate("toQValue", "Unknown type of query value");
405
int toQValue::toInt(void) const
414
return int(Value.Double);
416
return Value.String->toInt();
418
throw qApp->translate("toQValue", "Can't transform binary value to int");
420
throw qApp->translate("toQValue", "Unknown type of query value");
423
double toQValue::toDouble(void) const
430
return double(Value.Int);
434
return Value.String->toDouble();
436
throw qApp->translate("toQValue", "Can't transform binary value to double");
438
throw qApp->translate("toQValue", "Unknown type of query value");
441
void toQValue::setNumberFormat(int format, int decimals)
443
NumberFormat = format;
444
NumberDecimals = decimals;
447
QString toQValue::formatNumber(double number)
449
if (number == int(number))
450
return QString::number(number);
451
switch (NumberFormat)
456
sprintf(buf, "%E", number);
462
sprintf(buf, "%0.*f", NumberDecimals, number);
466
return QString::number(number);
470
int toQValue::numberFormat(void)
475
int toQValue::numberDecimals(void)
477
return NumberDecimals;
480
toQValue toQValue::createBinary(const QByteArray &arr)
483
ret.Type = binaryType;
484
ret.Value.Array = new QByteArray(arr);
488
toQValue toQValue::createFromHex(const QCString &hex)
490
QByteArray arr((hex.length() + 1) / 2);
491
for (unsigned int i = 0;i < hex.length();i += 2)
511
return createBinary(arr);
514
toQValue toQValue::createFromHex(const QString &hex)
516
QByteArray arr((hex.length() + 1) / 2);
517
for (unsigned int i = 0;i < hex.length();i += 2)
537
return createBinary(arr);
540
toQValue::operator QString() const
545
return QString::null;
547
return formatNumber(Value.Double);
549
return QString::number(Value.Int);
551
return *Value.String;
555
for (unsigned int i = 0;i < Value.Array->size();i++)
557
unsigned char c = (unsigned char)Value.Array->at(i);
558
ret += HexString[(c / 16) % 16];
559
ret += HexString[c % 16];
564
throw qApp->translate("toQValue", "Unknown type of query value");
567
// toQuery implementation
569
toQuery::toQuery(toConnection &conn, const toSQL &sql,
570
const QString &arg1, const QString &arg2,
571
const QString &arg3, const QString &arg4,
572
const QString &arg5, const QString &arg6,
573
const QString &arg7, const QString &arg8,
575
: Connection(conn), ConnectionSub(conn.mainConnection()), SQL(sql(Connection))
581
else if (!arg8.isNull())
583
else if (!arg7.isNull())
585
else if (!arg6.isNull())
587
else if (!arg5.isNull())
589
else if (!arg4.isNull())
591
else if (!arg3.isNull())
593
else if (!arg2.isNull())
595
else if (!arg1.isNull())
601
Params.insert(Params.end(), arg1);
603
Params.insert(Params.end(), arg2);
605
Params.insert(Params.end(), arg3);
607
Params.insert(Params.end(), arg4);
609
Params.insert(Params.end(), arg5);
611
Params.insert(Params.end(), arg6);
613
Params.insert(Params.end(), arg7);
615
Params.insert(Params.end(), arg8);
617
Params.insert(Params.end(), arg9);
623
Query = conn.Connection->createQuery(this, ConnectionSub);
630
Connection.freeConnection(ConnectionSub);
633
ConnectionSub->setQuery(this);
636
toQuery::toQuery(toConnection &conn, const QString &sql,
637
const QString &arg1, const QString &arg2,
638
const QString &arg3, const QString &arg4,
639
const QString &arg5, const QString &arg6,
640
const QString &arg7, const QString &arg8,
642
: Connection(conn), ConnectionSub(conn.mainConnection()), SQL(sql.utf8())
648
else if (!arg8.isNull())
650
else if (!arg7.isNull())
652
else if (!arg6.isNull())
654
else if (!arg5.isNull())
656
else if (!arg4.isNull())
658
else if (!arg3.isNull())
660
else if (!arg2.isNull())
662
else if (!arg1.isNull())
668
Params.insert(Params.end(), arg1);
670
Params.insert(Params.end(), arg2);
672
Params.insert(Params.end(), arg3);
674
Params.insert(Params.end(), arg4);
676
Params.insert(Params.end(), arg5);
678
Params.insert(Params.end(), arg6);
680
Params.insert(Params.end(), arg7);
682
Params.insert(Params.end(), arg8);
684
Params.insert(Params.end(), arg9);
690
Query = conn.Connection->createQuery(this, ConnectionSub);
697
Connection.freeConnection(ConnectionSub);
700
ConnectionSub->setQuery(this);
703
toQuery::toQuery(toConnection &conn, const toSQL &sql, const toQList ¶ms)
704
: Connection(conn), ConnectionSub(conn.mainConnection()), Params(params), SQL(sql(conn))
711
Query = conn.Connection->createQuery(this, ConnectionSub);
718
Connection.freeConnection(ConnectionSub);
721
ConnectionSub->setQuery(this);
724
toQuery::toQuery(toConnection &conn, const QString &sql, const toQList ¶ms)
725
: Connection(conn), ConnectionSub(conn.mainConnection()), Params(params), SQL(sql.utf8())
732
Query = conn.Connection->createQuery(this, ConnectionSub);
739
Connection.freeConnection(ConnectionSub);
742
ConnectionSub->setQuery(this);
745
toQuery::toQuery(toConnection &conn, queryMode mode, const toSQL &sql, const toQList ¶ms)
756
ConnectionSub = conn.mainConnection();
759
ConnectionSub = conn.backgroundConnection();
762
ConnectionSub = conn.longConnection();
770
Query = conn.Connection->createQuery(this, ConnectionSub);
777
Connection.freeConnection(ConnectionSub);
780
ConnectionSub->setQuery(this);
783
toQuery::toQuery(toConnection &conn, queryMode mode, const QString &sql, const toQList ¶ms)
794
ConnectionSub = conn.mainConnection();
797
ConnectionSub = conn.backgroundConnection();
800
ConnectionSub = conn.longConnection();
808
Query = conn.Connection->createQuery(this, ConnectionSub);
815
Connection.freeConnection(ConnectionSub);
818
ConnectionSub->setQuery(this);
821
toQuery::toQuery(toConnection &conn, queryMode mode)
830
ConnectionSub = conn.mainConnection();
833
ConnectionSub = conn.backgroundConnection();
836
ConnectionSub = conn.longConnection();
844
Query = conn.Connection->createQuery(this, ConnectionSub);
852
ConnectionSub->setQuery(this);
855
void toQuery::execute(const toSQL &sql, const toQList ¶ms)
858
SQL = sql(Connection);
863
void toQuery::execute(const QString &sql, const toQList ¶ms)
877
if (ConnectionSub->query() == this)
878
ConnectionSub->setQuery(NULL);
879
Connection.freeConnection(ConnectionSub);
885
bool toQuery::eof(void)
891
Connection.Lock.lock();
895
std::list<toConnectionSub *> &cons = Connection.connections();
896
for (std::list<toConnectionSub *>::iterator i = cons.begin();i != cons.end();i++)
898
if (*i == ConnectionSub)
904
Connection.Lock.unlock();
908
Query = connection().Connection->createQuery(this, ConnectionSub);
910
Connection.Lock.lock();
915
Connection.Lock.unlock();
924
toQList toQuery::readQuery(toConnection &conn, const toSQL &sql, toQList ¶ms)
927
toQuery query(conn, sql, params);
930
ret.insert(ret.end(), query.readValue());
934
toQList toQuery::readQuery(toConnection &conn, const QString &sql, toQList ¶ms)
937
toQuery query(conn, sql, params);
940
ret.insert(ret.end(), query.readValue());
944
toQList toQuery::readQuery(toConnection &conn, const toSQL &sql,
945
const QString &arg1, const QString &arg2,
946
const QString &arg3, const QString &arg4,
947
const QString &arg5, const QString &arg6,
948
const QString &arg7, const QString &arg8,
952
toQuery query(conn, sql, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
955
ret.insert(ret.end(), query.readValue());
959
toQList toQuery::readQuery(toConnection &conn, const QString &sql,
960
const QString &arg1, const QString &arg2,
961
const QString &arg3, const QString &arg4,
962
const QString &arg5, const QString &arg6,
963
const QString &arg7, const QString &arg8,
967
toQuery query(conn, sql, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
970
ret.insert(ret.end(), query.readValue());
974
toQList toQuery::readQueryNull(toConnection &conn, const toSQL &sql, toQList ¶ms)
977
toQuery query(conn, sql, params);
980
ret.insert(ret.end(), query.readValueNull());
984
toQList toQuery::readQueryNull(toConnection &conn, const QString &sql, toQList ¶ms)
987
toQuery query(conn, sql, params);
990
ret.insert(ret.end(), query.readValueNull());
994
toQList toQuery::readQueryNull(toConnection &conn, const toSQL &sql,
995
const QString &arg1, const QString &arg2,
996
const QString &arg3, const QString &arg4,
997
const QString &arg5, const QString &arg6,
998
const QString &arg7, const QString &arg8,
1002
toQuery query(conn, sql, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
1004
while (!query.eof())
1005
ret.insert(ret.end(), query.readValueNull());
1009
toQList toQuery::readQueryNull(toConnection &conn, const QString &sql,
1010
const QString &arg1, const QString &arg2,
1011
const QString &arg3, const QString &arg4,
1012
const QString &arg5, const QString &arg6,
1013
const QString &arg7, const QString &arg8,
1014
const QString &arg9)
1017
toQuery query(conn, sql, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
1019
while (!query.eof())
1020
ret.insert(ret.end(), query.readValueNull());
1024
toQValue toQuery::readValue(void)
1027
if (Connection.Abort)
1028
throw qApp->translate("toQuery", "Query aborted");
1031
return toNull(Query->readValue());
1034
toQValue toQuery::readValueNull(void)
1037
if (Connection.Abort)
1038
throw qApp->translate("toQuery", "Query aborted");
1041
return Query->readValue();
1044
void toQuery::cancel(void)
1049
// toConnection implementation
1051
void toConnection::addConnection(void)
1054
toConnectionSub *sub = Connection->createConnection();
1055
toLocker lock (Lock)
1057
Connections.insert(Connections.end(), sub);
1059
for (std::list<QString>::iterator i = InitStrings.begin();i != InitStrings.end();i++)
1063
Connection->execute(sub, (*i).utf8(), params);
1069
toConnection::toConnection(const QCString &provider,
1070
const QString &user, const QString &password,
1071
const QString &host, const QString &database,
1073
<QString> &options, bool cache)
1074
: Provider(provider), User(user), Password(password), Host(host), Database(database), Options(options)
1076
BackgroundConnection = NULL;
1077
BackgroundCount = 0;
1078
Connection = toConnectionProvider::connection(Provider, this);
1080
Version = Connection->version(mainConnection());
1081
NeedCommit = Abort = false;
1082
ReadingCache = false;
1085
if (toTool::globalConfig(CONF_OBJECT_CACHE, DEFAULT_OBJECT_CACHE).toInt() == 1)
1095
toConnection::toConnection(const toConnection &conn)
1096
: Provider(conn.Provider),
1098
Password(conn.Password),
1100
Database(conn.Database),
1101
Options(conn.Options)
1103
BackgroundConnection = NULL;
1104
BackgroundCount = 0;
1105
Connection = toConnectionProvider::connection(Provider, this);
1107
Version = Connection->version(mainConnection());
1110
ReadingCache = false;
1111
NeedCommit = Abort = false;
1114
std::list<QString> toConnection::running(void)
1117
toLocker lock (Lock)
1119
std::list<QString> ret;
1120
toConnectionSub *sub = (*(Connections.begin()));
1121
if (sub && sub->query())
1122
ret.insert(ret.end(), sub->query()->sql());
1123
if (BackgroundConnection && BackgroundConnection->query())
1124
ret.insert(ret.end(), BackgroundConnection->query()->sql());
1125
for (std::list<toConnectionSub *>::const_iterator i = Running.begin();i != Running.end();i++)
1128
if (sub && sub->query())
1129
ret.insert(ret.end(), sub->query()->sql());
1134
void toConnection::cancelAll(void)
1137
toLocker lock (Lock)
1139
for (std::list<toConnectionSub *>::iterator i = Running.begin();i != Running.end();i++)
1143
toConnection::~toConnection()
1148
toLocker lock (Lock)
1150
for_each(Widgets.begin(), Widgets.end(), DeleteObject());
1152
for (std::list<toConnectionSub *>::iterator i = Running.begin();i != Running.end();i++)
1164
ReadingValues.down();
1165
ReadingValues.down();
1167
for (std::list<toConnectionSub *>::iterator i = Connections.begin();i != Connections.end();i++)
1171
Connection->closeConnection(*i);
1179
toConnectionSub *toConnection::mainConnection()
1181
if (Connection->handleMultipleQueries())
1183
toLocker lock (Lock)
1185
return (*(Connections.begin()));
1189
return longConnection();
1193
toConnectionSub *toConnection::backgroundConnection()
1195
if (!Connection->handleMultipleQueries())
1196
return longConnection();
1197
if (toTool::globalConfig(CONF_BKGND_CONNECT, "").isEmpty())
1198
return mainConnection();
1200
if (!BackgroundConnection)
1203
toConnectionSub *tmp = longConnection();
1206
BackgroundConnection = tmp;
1207
BackgroundCount = 0;
1211
return BackgroundConnection;
1214
toConnectionSub *toConnection::longConnection()
1217
bool multiple = Connection->handleMultipleQueries();
1218
if ((multiple && Connections.size() == 1) ||
1219
(!multiple && Connections.empty()))
1226
toLocker lock (Lock)
1228
std::list<toConnectionSub *>::iterator i = Connections.begin();
1231
toConnectionSub *ret = (*i);
1232
Connections.erase(i);
1233
Running.insert(Running.end(), ret);
1237
void toConnection::freeConnection(toConnectionSub *sub)
1239
toLocker lock (Lock)
1241
if (sub == BackgroundConnection)
1244
if (BackgroundCount > 0)
1246
BackgroundConnection = NULL;
1249
for (std::list<toConnectionSub *>::iterator i = Running.begin();i != Running.end();i++)
1259
for (std::list<toConnectionSub *>::iterator i = Connections.begin();i != Connections.end();i++)
1265
Connections.insert(Connections.end(), sub);
1268
void toConnection::commit(void)
1271
toLocker lock (Lock)
1273
for (std::list<toConnectionSub *>::iterator i = Connections.begin();i != Connections.end();i++)
1274
Connection->commit(*i);
1275
while (Connections.size() > 2)
1277
std::list<toConnectionSub *>::iterator i = Connections.begin();
1280
Connections.erase(i);
1282
setNeedCommit(false);
1285
void toConnection::rollback(void)
1288
toLocker lock (Lock)
1290
for (std::list<toConnectionSub *>::iterator i = Connections.begin();i != Connections.end();i++)
1292
Connection->rollback(*i);
1294
while (Connections.size() > 2)
1296
std::list<toConnectionSub *>::iterator i = Connections.begin();
1299
Connections.erase(i);
1301
setNeedCommit(false);
1304
void toConnection::delWidget(QObject *widget)
1306
for (std::list<QObject *>::iterator i = Widgets.begin();i != Widgets.end();i++)
1316
bool toConnection::closeWidgets(void)
1318
for (std::list<QObject *>::iterator i = Widgets.begin();i != Widgets.end();i = Widgets.begin())
1320
if ((*i)->inherits("QWidget"))
1322
QWidget * widget = static_cast<QWidget *>(*i);
1323
if (!widget->close(true))
1328
std::list<QObject *>::iterator nextI = Widgets.begin();
1330
throw qApp->translate("toConnection", "All tool widgets need to have autodelete flag set");
1335
QString toConnection::description(bool version) const
1338
ret += QString::fromLatin1("@");
1340
if (!Host.isEmpty() && Host != "SQL*Net")
1342
ret += QString::fromLatin1(".");
1348
if (!Version.isEmpty())
1350
ret += QString::fromLatin1(" [");
1351
ret += QString::fromLatin1(Version);
1352
ret += QString::fromLatin1("]");
1358
void toConnection::addInit(const QString &sql)
1361
InitStrings.insert(InitStrings.end(), sql);
1364
void toConnection::delInit(const QString &sql)
1366
std::list<QString>::iterator i = InitStrings.begin();
1367
while (i != InitStrings.end())
1370
i = InitStrings.erase(i);
1376
const std::list<QString> toConnection::initStrings() const
1381
void toConnection::parse(const QString &sql)
1384
Connection->parse(mainConnection(), sql.utf8());
1387
void toConnection::parse(const toSQL &sql)
1390
Connection->parse(mainConnection(), toSQL::sql(sql, *this));
1393
void toConnection::execute(const toSQL &sql, toQList ¶ms)
1396
Connection->execute(mainConnection(), toSQL::sql(sql, *this), params);
1399
void toConnection::execute(const QString &sql, toQList ¶ms)
1402
Connection->execute(mainConnection(), sql.utf8(), params);
1405
void toConnection::execute(const toSQL &sql,
1406
const QString &arg1, const QString &arg2,
1407
const QString &arg3, const QString &arg4,
1408
const QString &arg5, const QString &arg6,
1409
const QString &arg7, const QString &arg8,
1410
const QString &arg9)
1415
else if (!arg8.isNull())
1417
else if (!arg7.isNull())
1419
else if (!arg6.isNull())
1421
else if (!arg5.isNull())
1423
else if (!arg4.isNull())
1425
else if (!arg3.isNull())
1427
else if (!arg2.isNull())
1429
else if (!arg1.isNull())
1436
args.insert(args.end(), arg1);
1438
args.insert(args.end(), arg2);
1440
args.insert(args.end(), arg3);
1442
args.insert(args.end(), arg4);
1444
args.insert(args.end(), arg5);
1446
args.insert(args.end(), arg6);
1448
args.insert(args.end(), arg7);
1450
args.insert(args.end(), arg8);
1452
args.insert(args.end(), arg9);
1455
Connection->execute(mainConnection(), toSQL::sql(sql, *this), args);
1458
void toConnection::execute(const QString &sql,
1459
const QString &arg1, const QString &arg2,
1460
const QString &arg3, const QString &arg4,
1461
const QString &arg5, const QString &arg6,
1462
const QString &arg7, const QString &arg8,
1463
const QString &arg9)
1468
else if (!arg8.isNull())
1470
else if (!arg7.isNull())
1472
else if (!arg6.isNull())
1474
else if (!arg5.isNull())
1476
else if (!arg4.isNull())
1478
else if (!arg3.isNull())
1480
else if (!arg2.isNull())
1482
else if (!arg1.isNull())
1489
args.insert(args.end(), arg1);
1491
args.insert(args.end(), arg2);
1493
args.insert(args.end(), arg3);
1495
args.insert(args.end(), arg4);
1497
args.insert(args.end(), arg5);
1499
args.insert(args.end(), arg6);
1501
args.insert(args.end(), arg7);
1503
args.insert(args.end(), arg8);
1505
args.insert(args.end(), arg9);
1508
Connection->execute(mainConnection(), sql.utf8(), args);
1511
void toConnection::allExecute(const toSQL &sql, toQList ¶ms)
1514
toLocker lock (Lock)
1516
for (std::list<toConnectionSub *>::iterator i = Connections.begin();i != Connections.end();i++)
1520
Connection->execute(*i, toSQL::sql(sql, *this), params);
1526
void toConnection::allExecute(const QString &sql, toQList ¶ms)
1529
toLocker lock (Lock)
1531
for (std::list<toConnectionSub *>::iterator i = Connections.begin();i != Connections.end();i++)
1535
Connection->execute(*i, sql.utf8(), params);
1541
void toConnection::allExecute(const toSQL &sql,
1542
const QString &arg1, const QString &arg2,
1543
const QString &arg3, const QString &arg4,
1544
const QString &arg5, const QString &arg6,
1545
const QString &arg7, const QString &arg8,
1546
const QString &arg9)
1551
else if (!arg8.isNull())
1553
else if (!arg7.isNull())
1555
else if (!arg6.isNull())
1557
else if (!arg5.isNull())
1559
else if (!arg4.isNull())
1561
else if (!arg3.isNull())
1563
else if (!arg2.isNull())
1565
else if (!arg1.isNull())
1572
args.insert(args.end(), arg1);
1574
args.insert(args.end(), arg2);
1576
args.insert(args.end(), arg3);
1578
args.insert(args.end(), arg4);
1580
args.insert(args.end(), arg5);
1582
args.insert(args.end(), arg6);
1584
args.insert(args.end(), arg7);
1586
args.insert(args.end(), arg8);
1588
args.insert(args.end(), arg9);
1591
toLocker lock (Lock)
1593
for (std::list<toConnectionSub *>::iterator i = Connections.begin();i != Connections.end();i++)
1597
Connection->execute(*i, toSQL::sql(sql, *this), args);
1603
void toConnection::allExecute(const QString &sql,
1604
const QString &arg1, const QString &arg2,
1605
const QString &arg3, const QString &arg4,
1606
const QString &arg5, const QString &arg6,
1607
const QString &arg7, const QString &arg8,
1608
const QString &arg9)
1613
else if (!arg8.isNull())
1615
else if (!arg7.isNull())
1617
else if (!arg6.isNull())
1619
else if (!arg5.isNull())
1621
else if (!arg4.isNull())
1623
else if (!arg3.isNull())
1625
else if (!arg2.isNull())
1627
else if (!arg1.isNull())
1634
args.insert(args.end(), arg1);
1636
args.insert(args.end(), arg2);
1638
args.insert(args.end(), arg3);
1640
args.insert(args.end(), arg4);
1642
args.insert(args.end(), arg5);
1644
args.insert(args.end(), arg6);
1646
args.insert(args.end(), arg7);
1648
args.insert(args.end(), arg8);
1650
args.insert(args.end(), arg9);
1653
toLocker lock (Lock)
1655
for (std::list<toConnectionSub *>::iterator i = Connections.begin();i != Connections.end();i++)
1659
Connection->execute(*i, sql.utf8(), args);
1665
const QCString &toConnection::provider(void) const
1670
QString toConnection::cacheDir()
1672
QString home = QDir::homeDirPath();
1673
QString dirname = toTool::globalConfig(CONF_CACHE_DIR, "");
1675
if (dirname.isEmpty())
1679
dirname = QString(getenv("TEMP"));
1683
dirname = QString(home);
1686
dirname += "/.toad_cache";
1689
dirname += "/.tora_cache";
1696
QString toConnection::cacheFile()
1698
QString dbname (description(false).stripWhiteSpace());
1700
return (cacheDir() + "/" + dbname).simplifyWhiteSpace();
1703
bool toConnection::loadDiskCache()
1705
if (toTool::globalConfig(CONF_CACHE_DISK, DEFAULT_CACHE_DISK).isEmpty())
1708
toConnection::objectName *cur = 0;
1712
QString filename = cacheFile();
1714
QFile file(filename);
1716
if (!QFile::exists(filename))
1721
if (fi.lastModified().addDays(toTool::globalConfig(CONF_CACHE_TIMEOUT, DEFAULT_CACHE_TIMEOUT).toInt()) < today)
1724
/** read in all data
1727
if (!file.open(IO_ReadOnly))
1730
QString data = file.readAll();
1732
/** build cache lists
1735
QStringList records = QStringList::split("\x1D", data, true);
1736
for ( QStringList::Iterator i = records.begin(); i != records.end(); i++)
1739
QStringList record = QStringList::split("\x1E", (*i), true);
1740
QStringList::Iterator rec = record.begin();
1741
cur = new objectName;
1742
(*cur).Owner = (*rec);
1744
(*cur).Name = (*rec);
1746
(*cur).Type = (*rec);
1748
(*cur).Comment = (*rec);
1750
QStringList slist = QStringList::split("\x1F", (*rec), false);
1751
for (QStringList::Iterator s = slist.begin(); s != slist.end(); s++)
1753
SynonymMap[(*s)] = (*cur);
1754
(*cur).Synonyms.insert((*cur).Synonyms.end(), (*s));
1757
ObjectNames.insert(ObjectNames.end(), (*cur));
1764
void toConnection::writeDiskCache()
1767
long objCounter = 0;
1768
long synCounter = 0;
1770
if (toTool::globalConfig(CONF_CACHE_DISK, DEFAULT_CACHE_DISK).isEmpty())
1774
QString filename(cacheFile());
1776
/** check pathnames and create
1779
QString dirname(cacheDir());
1781
dir.setPath(dirname);
1783
if (!dir.exists(dirname))
1787
/** build record to write out
1791
QStringList records;
1792
QStringList recordSynonym;
1793
for (std::list<objectName>::iterator i = ObjectNames.begin();i != ObjectNames.end();i++)
1796
record.append((*i).Owner);
1797
record.append((*i).Name);
1798
record.append((*i).Type);
1799
record.append((*i).Comment);
1800
for (std::list<QString>::iterator s = (*i).Synonyms.begin();s != (*i).Synonyms.end();s++)
1802
recordSynonym.append((*s));
1805
record.append(recordSynonym.join("\x1F"));
1806
recordSynonym.clear();
1808
records.append(record.join("\x1E"));
1812
QFile file(filename);
1813
file.open( IO_ReadWrite | IO_Truncate );
1814
QTextStream t (&file);
1815
t << records.join("\x1D");
1820
void toConnection::cacheObjects::run()
1822
bool diskloaded = false;
1825
diskloaded = Connection.loadDiskCache();
1828
Connection.ObjectNames = Connection.Connection->objectNames();
1830
Connection.ObjectNames.sort();
1831
Connection.ReadingValues.up();
1834
Connection.SynonymMap = Connection.Connection->synonymMap(Connection.ObjectNames);
1835
Connection.writeDiskCache();
1840
if (Connection.ReadingValues.getValue() == 0)
1841
Connection.ReadingValues.up();
1843
Connection.ReadingValues.up();
1847
void toConnection::readObjects(void)
1849
if (toTool::globalConfig(CONF_OBJECT_CACHE, DEFAULT_OBJECT_CACHE).toInt() == 3)
1851
ReadingCache = false;
1857
ReadingCache = true;
1860
(new toThread(new cacheObjects(*this)))->start();
1864
ReadingCache = false;
1869
void toConnection::rereadCache(void)
1872
if (toTool::globalConfig(CONF_OBJECT_CACHE, DEFAULT_OBJECT_CACHE).toInt() == 3)
1874
ColumnCache.clear();
1878
if (ReadingValues.getValue() < 2 && ReadingCache)
1880
toStatusMessage(qApp->translate("toConnection",
1881
"Not done caching objects, can not clear unread cache"));
1886
ReadingCache = false;
1887
while (ReadingValues.getValue() > 0)
1888
ReadingValues.down();
1890
ObjectNames.clear();
1891
ColumnCache.clear();
1894
/** delete cache file to force reload
1897
QString filename(cacheFile());
1899
if (QFile::exists(filename))
1906
QString toConnection::quote(const QString &name)
1908
return Connection->quote(name);
1911
QString toConnection::unQuote(const QString &name)
1913
return Connection->unQuote(name);
1916
bool toConnection::cacheAvailable(bool synonyms, bool block, bool need)
1918
if (toTool::globalConfig(CONF_OBJECT_CACHE, DEFAULT_OBJECT_CACHE).toInt() == 3)
1925
if (toTool::globalConfig(CONF_OBJECT_CACHE, DEFAULT_OBJECT_CACHE).toInt() == 2 && !block)
1928
toMainWidget()->checkCaching();
1930
if (ReadingValues.getValue() == 0 || (ReadingValues.getValue() == 1 && synonyms == true))
1935
if (toThread::mainThread())
1937
QProgressDialog waiting(qApp->translate("toConnection",
1938
"Waiting for object caching to be completed.\n"
1939
"Canceling this dialog will probably leave some list of\n"
1940
"database objects empty."),
1941
qApp->translate("toConnection", "Cancel"),
1946
waiting.setCaption(qApp->translate("toConnection", "Waiting for object cache"));
1949
int waitVal = (synonyms ? 2 : 1);
1952
qApp->processEvents();
1953
toThread::msleep(100);
1954
waiting.setProgress((++num) % 10);
1955
if (waiting.wasCancelled())
1958
while (ReadingValues.getValue() < waitVal);
1961
ReadingValues.down();
1964
ReadingValues.down();
1975
std::list<toConnection::objectName> &toConnection::objects(bool block)
1977
if (!cacheAvailable(false, block))
1979
toStatusMessage(qApp->translate("toConnection", "Not done caching objects"), false, false);
1980
static std::list<objectName> ret;
1987
void toConnection::addIfNotExists(toConnection::objectName &obj)
1989
if (!cacheAvailable(true, false))
1991
toStatusMessage(qApp->translate("toConnection", "Not done caching objects"), false, false);
1994
std::list<toConnection::objectName>::iterator i = ObjectNames.begin();
1995
while (i != ObjectNames.end() && (*i) < obj)
1997
if (i != ObjectNames.end() && *i == obj) // Already exists, don't add
1999
ObjectNames.insert(i, obj);
2002
std::map<QString, toConnection::objectName> &toConnection::synonyms(bool block)
2004
if (!cacheAvailable(true, block))
2006
toStatusMessage(qApp->translate("toConnection", "Not done caching objects"), false, false);
2007
static std::map<QString, objectName> ret;
2014
const toConnection::objectName &toConnection::realName(const QString &object,
2018
if (!cacheAvailable(true, block))
2019
throw qApp->translate("toConnection", "Not done caching objects");
2024
QString q = QString::fromLatin1("\"");
2025
QString c = QString::fromLatin1(".");
2028
for (unsigned int pos = 0;pos < object.length();pos++)
2030
if (object.at(pos) == q)
2036
if (!quote && object.at(pos) == c)
2039
name = QString::null;
2042
name += object.at(pos);
2046
QString uo = owner.upper();
2047
QString un = name.upper();
2049
synonym = QString::null;
2050
for (std::list<objectName>::iterator i = ObjectNames.begin();i != ObjectNames.end();i++)
2052
if (owner.isEmpty())
2054
if (((*i).Name == un || (*i).Name == name) &&
2055
((*i).Owner == user().upper() || (*i).Owner == database()))
2058
else if (((*i).Name == un || (*i).Name == name) &&
2059
((*i).Owner == uo || (*i).Owner == owner))
2062
if (owner.isEmpty())
2064
std::map<QString, objectName>::iterator i = SynonymMap.find(name);
2065
if (i == SynonymMap.end() && un != name)
2067
i = SynonymMap.find(un);
2072
if (i != SynonymMap.end())
2077
throw qApp->translate("toConnection", "Object %1 not available for %2").arg(object).arg(user());
2080
const toConnection::objectName &toConnection::realName(const QString &object, bool block)
2083
return realName(object, dummy, block);
2086
toQDescList &toConnection::columns(const objectName &object, bool nocache)
2088
std::map<objectName, toQDescList>::iterator i = ColumnCache.find(object);
2089
if (i == ColumnCache.end() || nocache)
2091
ColumnCache[object] = Connection->columnDesc(object);
2094
return ColumnCache[object];
2097
bool toConnection::objectName::operator < (const objectName &nam) const
2099
if (Owner < nam.Owner || (Owner.isNull() && !nam.Owner.isNull()))
2101
if (Owner > nam.Owner || (!Owner.isNull() && nam.Owner.isNull()))
2103
if (Name < nam.Name || (Name.isNull() && !nam.Name.isNull()))
2105
if (Name > nam.Name || (!Name.isNull() && nam.Name.isNull()))
2107
if (Type < nam.Type)
2112
bool toConnection::objectName::operator == (const objectName &nam) const
2114
return Owner == nam.Owner && Name == nam.Name && Type == nam.Type;
2117
toSyntaxAnalyzer &toConnection::connectionImpl::analyzer()
2119
return toSyntaxAnalyzer::defaultAnalyzer();
2122
toSyntaxAnalyzer &toConnection::analyzer()
2124
return Connection->analyzer();
2127
std::list<toConnection::objectName> toConnection::connectionImpl::objectNames(void)
2129
std::list<toConnection::objectName> ret;
2133
std::map<QString, toConnection::objectName> toConnection::connectionImpl::synonymMap(std::list<toConnection::objectName> &)
2135
std::map<QString, toConnection::objectName> ret;
2139
toQDescList toConnection::connectionImpl::columnDesc(const objectName &)
2145
void toConnection::connectionImpl::parse(toConnectionSub *, const QCString &)
2147
throw qApp->translate("toConnection", "Parse only not implemented for this type of connection");