KDb

KDbFieldList.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2003-2012 JarosÅ‚aw Staniek <[email protected]>
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 
24 class Q_DECL_HIDDEN KDbFieldList::Private
25 {
26 public:
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
74 KDbFieldList::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 }
89 
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 
123 bool 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 
141 bool 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 
151 bool 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 
180 bool 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 
199 const 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 
209 const KDbField* KDbFieldList::field(const QString& name) const
210 {
211  return d->fieldsByName.value(name.toLower());
212 }
213 
214 bool KDbFieldList::hasField(const KDbField& field) const
215 {
216  return d->fields.contains(const_cast<KDbField*>(&field));
217 }
218 
219 int KDbFieldList::indexOf(const KDbField& field) const
220 {
221  return d->fields.indexOf(const_cast<KDbField*>(&field));
222 }
223 
224 KDB_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 
246 static 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 
346 {
347  return d->fields.constEnd();
348 }
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())
379  : KDb::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 }
KDbField::List * autoIncrementFields() const
KDB_EXPORT QString escapeIdentifier(const QString &string)
Definition: KDb.cpp:1334
KCALENDARCORE_EXPORT QDataStream & operator<<(QDataStream &out, const KCalendarCore::Alarm::Ptr &)
KDbField::ListIterator fieldsIterator() const
virtual KDbField * field(int id)
QDebug & nospace()
Specialized string for escaping.
virtual QString escapeIdentifier(const QString &id) const
Identifier escaping function in the associated KDbDriver.
QDebug & space()
QList::const_iterator constBegin() const const
@ DriverEscaping
Identifiers are escaped by driver.
Definition: KDbGlobal.h:145
virtual KDbField * copy()
Definition: KDbField.cpp:374
virtual bool insertField(int index, KDbField *field)
bool hasField(const KDbField &field) const
int indexOf(const KDbField &field) const
Q_SCRIPTABLE Q_NOREPLY void start()
QStringList names() const
KDbFieldList(bool owner=false)
bool isEmpty() const const
KDbEscapedString sqlFieldsList(KDbConnection *conn, const QString &separator=QLatin1String(","), const QString &tableOrAlias=QString(), KDb::IdentifierEscapingType escapingType=KDb::DriverEscaping) const
bool addField(KDbField *field)
bool isEmpty() const 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())
virtual bool removeField(KDbField *field)
QList< KDbField * >::ConstIterator ListIterator
iterator for list of fields
Definition: KDbField.h:79
KDbField::List * fields()
void setName(const QString &name)
Definition: KDbField.cpp:615
QString & remove(int position, int n)
typedef ConstIterator
QString toLower() const const
bool isAutoIncrement() const
Definition: KDbField.h:282
QList::const_iterator constEnd() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromLatin1(const char *str, int size)
void setParent(KDbFieldList *parent)
Sets parent for this field.
Definition: KDbField.cpp:251
bool isEmpty() const
virtual bool moveField(KDbField *field, int newIndex)
bool isOwner() const
Meta-data for a field.
Definition: KDbField.h:71
int fieldCount() const
bool renameField(const QString &oldName, const QString &newName)
Provides database connection, allowing queries and data modification.
Definition: KDbConnection.h:51
QString name() const
Definition: KDbField.cpp:256
IdentifierEscapingType
Escaping type for identifiers.
Definition: KDbGlobal.h:144
KDbField::ListIterator fieldsIteratorConstEnd() const
virtual void clear()
KDbUtils::AutodeletedList< KDbField * > List
list of fields
Definition: KDbField.h:77
virtual ~KDbFieldList()
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Sep 27 2023 04:08:32 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.