KDb

KDbFieldList.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003-2012 Jarosław Staniek <staniek@kde.org>
3
4 This library 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 library 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 library; see the file COPYING.LIB. 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 "KDbFieldList.h"
21#include "KDbConnection.h"
22#include "kdb_debug.h"
23
24class Q_DECL_HIDDEN KDbFieldList::Private
25{
26public:
27 Private()
28 {
29 }
30 ~Private()
31 {
32 delete autoincFields;
33 }
34
35 //! Clear cached autoinc fields list
36 void clearAutoincFields()
37 {
38 delete autoincFields;
39 autoincFields = nullptr;
40 }
41
42 bool renameFieldInternal(KDbField *field, const QString& newNameLower)
43 {
44 if (fieldsByName.value(newNameLower)) {
45 kdbWarning() << "Field" << newNameLower << "already exists";
46 return false;
47 }
48 fieldsByName.remove(field->name().toLower());
49 field->setName(newNameLower);
50 fieldsByName.insert(newNameLower, field);
51 return true;
52 }
53
54 KDbField::List fields;
55
56 //!< Fields collected by name. Not used by KDbQuerySchema.
57 QHash<QString, KDbField*> fieldsByName;
58
59 KDbField::List *autoincFields = nullptr;
60
61 //! cached
62 KDbEscapedString sqlFields;
63};
64
65//-------------------------------------------------------
66
68 : d(new Private)
69{
70 d->fields.setAutoDelete(owner);
71}
72
73//! @todo IMPORTANT: (API) improve deepCopyFields
74KDbFieldList::KDbFieldList(const KDbFieldList& fl, bool deepCopyFields)
75 : KDbFieldList(fl.d->fields.autoDelete())
76{
77 if (deepCopyFields) {
78 //deep copy for the fields
79 for (KDbField *origField : *fl.fields()) {
80 KDbField *f = origField->copy();
81 if (origField->parent() == &fl) {
82 f->setParent(this);
83 }
84 const bool addFieldOk = addField(f);
85 Q_ASSERT(addFieldOk);
86 }
87 }
88}
91{
92 delete d;
93}
94
96{
97 return &d->fields;
98}
99
101{
102 return &d->fields;
103}
104
106{
107 return d->fields.count();
108}
109
111{
112 return d->fields.isEmpty();
113}
114
116{
117 d->fieldsByName.clear();
118 d->clearAutoincFields();
119 d->fields.clear();
120 d->sqlFields.clear();
121}
122
123bool KDbFieldList::insertField(int index, KDbField *field)
124{
125 if (!field) {
126 return false;
127 }
128 if (index > d->fields.count()) {
129 kdbWarning() << "index (" << index << ") out of range";
130 return false;
131 }
132 d->fields.insert(index, field);
133 if (!field->name().isEmpty()) {
134 d->fieldsByName.insert(field->name().toLower(), field);
135 }
136 d->sqlFields.clear();
137 d->clearAutoincFields();
138 return true;
139}
140
141bool KDbFieldList::renameField(const QString& oldName, const QString& newName)
142{
143 KDbField *field = d->fieldsByName.value(oldName.toLower());
144 if (!field) {
145 kdbWarning() << "Fiels" << oldName << "not found";
146 return false;
147 }
148 return d->renameFieldInternal(field, newName.toLower());
149}
150
151bool KDbFieldList::renameField(KDbField *field, const QString& newName)
152{
153 if (!field || field != d->fieldsByName.value(field->name().toLower())) {
154 kdbWarning() << "No field found"
155 << QString::fromLatin1("\"%1\"").arg(field ? field->name() : QString());
156 return false;
157 }
158 return d->renameFieldInternal(field, newName.toLower());
159}
160
162{
163 return insertField(d->fields.count(), field);
164}
165
167{
168 if (!field) {
169 return false;
170 }
171 if (d->fieldsByName.remove(field->name().toLower()) < 1) {
172 return false;
173 }
174 d->fields.removeAt(d->fields.indexOf(field));
175 d->sqlFields.clear();
176 d->clearAutoincFields();
177 return true;
178}
179
180bool KDbFieldList::moveField(KDbField *field, int newIndex)
181{
182 if (!field || !d->fields.removeOne(field)) {
183 return false;
184 }
185 if (newIndex > d->fields.count()) {
186 newIndex = d->fields.count();
187 }
188 d->fields.insert(newIndex, field);
189 d->sqlFields.clear();
190 d->clearAutoincFields();
191 return true;
192}
193
195{
196 return d->fields.value(id);
197}
198
199const KDbField* KDbFieldList::field(int id) const
200{
201 return d->fields.value(id);
202}
203
205{
206 return d->fieldsByName.value(name.toLower());
207}
208
209const KDbField* KDbFieldList::field(const QString& name) const
210{
211 return d->fieldsByName.value(name.toLower());
212}
213
214bool KDbFieldList::hasField(const KDbField& field) const
215{
216 return d->fields.contains(const_cast<KDbField*>(&field));
217}
218
219int KDbFieldList::indexOf(const KDbField& field) const
220{
221 return d->fields.indexOf(const_cast<KDbField*>(&field));
222}
223
224KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbFieldList& list)
225{
226 if (list.fields()->isEmpty())
227 dbg.nospace() << "<NO FIELDS>";
228 bool start = true;
229 foreach(const KDbField *field, *list.fields()) {
230 if (!start)
231 dbg.nospace() << '\n';
232 else
233 start = false;
234 dbg.nospace() << " - " << *field;
235 }
236 return dbg.space();
237}
238
239#define _ADD_FIELD(fname) \
240 { \
241 if (fname.isEmpty()) return fl; \
242 KDbField *f = d->fieldsByName.value(fname.toLower()); \
243 if (!f || !fl->addField(f)) { kdbWarning() << subListWarning1(fname); delete fl; return nullptr; } \
244 }
245
246static QString subListWarning1(const QString& fname)
247{
248 return QString::fromLatin1("could not find field \"%1\"").arg(fname);
249}
250
252 const QString& n3, const QString& n4,
253 const QString& n5, const QString& n6,
254 const QString& n7, const QString& n8,
255 const QString& n9, const QString& n10,
256 const QString& n11, const QString& n12,
257 const QString& n13, const QString& n14,
258 const QString& n15, const QString& n16,
259 const QString& n17, const QString& n18)
260{
261 if (n1.isEmpty())
262 return nullptr;
263 KDbFieldList *fl = new KDbFieldList(false);
264 _ADD_FIELD(n1);
265 _ADD_FIELD(n2);
266 _ADD_FIELD(n3);
267 _ADD_FIELD(n4);
268 _ADD_FIELD(n5);
269 _ADD_FIELD(n6);
270 _ADD_FIELD(n7);
271 _ADD_FIELD(n8);
272 _ADD_FIELD(n9);
273 _ADD_FIELD(n10);
274 _ADD_FIELD(n11);
275 _ADD_FIELD(n12);
276 _ADD_FIELD(n13);
277 _ADD_FIELD(n14);
278 _ADD_FIELD(n15);
279 _ADD_FIELD(n16);
280 _ADD_FIELD(n17);
281 _ADD_FIELD(n18);
282 return fl;
283}
284
286{
287 KDbFieldList *fl = new KDbFieldList(false);
288 for (QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it) {
289 _ADD_FIELD((*it));
290 }
291 return fl;
292}
293
294#undef _ADD_FIELD
295
296#define _ADD_FIELD(fname) \
297 { \
298 if (fname.isEmpty()) return fl; \
299 KDbField *f = d->fieldsByName.value(QLatin1String(fname.toLower())); \
300 if (!f || !fl->addField(f)) { kdbWarning() << subListWarning1(QLatin1String(fname)); delete fl; return nullptr; } \
301 }
302
304{
305 KDbFieldList *fl = new KDbFieldList(false);
306 for (QList<QByteArray>::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it) {
307 _ADD_FIELD((*it));
308 }
309 return fl;
310}
311
312#undef _ADD_FIELD
313
315{
317 foreach(int index, list) {
318 KDbField *f = field(index);
319 if (!f) {
320 kdbWarning() << QString::fromLatin1("could not find field at position %1").arg(index);
321 return nullptr;
322 }
323 if (!fl->addField(f)) {
324 kdbWarning() << QString::fromLatin1("could not add field at position %1").arg(index);
325 return nullptr;
326 }
327 }
328 return fl.take();
329}
330
332{
333 QStringList r;
334 for (KDbField *f : qAsConst(d->fields)) {
335 r += f->name().toLower();
336 }
337 return r;
338}
339
341{
342 return d->fields.constBegin();
343}
344
349
351{
352 return d->fields.autoDelete();
353}
354
355//static
357 const QString& separator, const QString& tableOrAlias,
358 KDb::IdentifierEscapingType escapingType)
359{
360 KDbEscapedString result;
361 result.reserve(256);
362 bool start = true;
363 QString tableOrAliasAndDot;
364 if (!tableOrAlias.isEmpty()) {
365 tableOrAliasAndDot
366 = ((conn && escapingType == KDb::DriverEscaping)
367 ? conn->escapeIdentifier(tableOrAlias)
368 : KDb::escapeIdentifier(tableOrAlias))
369 + QLatin1Char('.');
370 }
371 foreach(KDbField *f, list) {
372 if (!start)
373 result.append(separator);
374 else
375 start = false;
376 result = (result + tableOrAliasAndDot +
377 ((conn && escapingType == KDb::DriverEscaping)
378 ? conn->escapeIdentifier(f->name())
380 );
381 }
382 return result;
383}
384
386 const QString& separator, const QString& tableOrAlias,
387 KDb::IdentifierEscapingType escapingType) const
388{
389 if (!d->sqlFields.isEmpty())
390 return d->sqlFields;
391
392 d->sqlFields = KDbFieldList::sqlFieldsList(d->fields, conn, separator, tableOrAlias, escapingType);
393 return d->sqlFields;
394}
395
397{
398 if (d->autoincFields)
399 return d->autoincFields;
400
401 d->autoincFields = new KDbField::List(false);
402 for (KDbField *f : d->fields) {
403 if (f->isAutoIncrement()) {
404 d->autoincFields->append(f);
405 }
406 }
407 return d->autoincFields;
408}
Provides database connection, allowing queries and data modification.
virtual QString escapeIdentifier(const QString &id) const
Identifier escaping function in the associated KDbDriver.
Specialized string for escaping.
KDbField::List * autoIncrementFields() const
bool addField(KDbField *field)
bool hasField(const KDbField &field) const
virtual bool removeField(KDbField *field)
virtual KDbField * field(int id)
virtual void clear()
virtual ~KDbFieldList()
int indexOf(const KDbField &field) const
bool isOwner() const
KDbFieldList * subList(const QString &n1, const QString &n2=QString(), const QString &n3=QString(), const QString &n4=QString(), const QString &n5=QString(), const QString &n6=QString(), const QString &n7=QString(), const QString &n8=QString(), const QString &n9=QString(), const QString &n10=QString(), const QString &n11=QString(), const QString &n12=QString(), const QString &n13=QString(), const QString &n14=QString(), const QString &n15=QString(), const QString &n16=QString(), const QString &n17=QString(), const QString &n18=QString())
KDbField::ListIterator fieldsIterator() const
int fieldCount() const
QStringList names() const
KDbField::ListIterator fieldsIteratorConstEnd() const
virtual bool insertField(int index, KDbField *field)
virtual bool moveField(KDbField *field, int newIndex)
bool renameField(const QString &oldName, const QString &newName)
bool isEmpty() const
KDbEscapedString sqlFieldsList(KDbConnection *conn, const QString &separator=QLatin1String(","), const QString &tableOrAlias=QString(), KDb::IdentifierEscapingType escapingType=KDb::DriverEscaping) const
KDbField::List * fields()
KDbFieldList(bool owner=false)
Meta-data for a field.
Definition KDbField.h:72
KDbUtils::AutodeletedList< KDbField * > List
list of fields
Definition KDbField.h:77
QString name() const
Definition KDbField.cpp:256
bool isAutoIncrement() const
Definition KDbField.h:282
QList< KDbField * >::ConstIterator ListIterator
iterator for list of fields
Definition KDbField.h:79
virtual KDbField * copy()
Definition KDbField.cpp:374
void setParent(KDbFieldList *parent)
Sets parent for this field.
Definition KDbField.cpp:251
void setName(const QString &name)
Definition KDbField.cpp:615
Q_SCRIPTABLE Q_NOREPLY void start()
KDB_EXPORT QString escapeIdentifier(const QString &string)
Definition KDb.cpp:1334
IdentifierEscapingType
Escaping type for identifiers.
Definition KDbGlobal.h:144
@ DriverEscaping
Identifiers are escaped by driver.
Definition KDbGlobal.h:145
QDebug & nospace()
QDebug & space()
void clear()
iterator insert(const Key &key, const T &value)
bool remove(const Key &key)
T value(const Key &key) const const
void append(QList< T > &&value)
const_iterator constBegin() const const
const_iterator constEnd() const const
bool contains(const AT &value) const const
qsizetype count() const const
qsizetype indexOf(const AT &value, qsizetype from) const const
bool isEmpty() const const
bool removeOne(const AT &t)
T value(qsizetype i) const const
QString arg(Args &&... args) const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
QString toLower() const const
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.