QDjango
QDjangoQuerySet.h
1 /*
2  * Copyright (C) 2010-2015 Jeremy LainĂ©
3  * Copyright (C) 2011 Mathias Hasselmann
4  * Contact: https://github.com/jlaine/qdjango
5  *
6  * This file is part of the QDjango Library.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  */
18 
19 #ifndef QDJANGO_QUERYSET_H
20 #define QDJANGO_QUERYSET_H
21 
22 #include "QDjango.h"
23 #include "QDjangoWhere.h"
24 #include "QDjangoQuerySet_p.h"
25 
45 template <class T>
47 {
48 public:
50  typedef int size_type;
51  typedef T value_type;
52  typedef value_type *pointer;
53  typedef const value_type *const_pointer;
54  typedef value_type &reference;
55  typedef const value_type &const_reference;
56  typedef qptrdiff difference_type;
79  {
80  friend class QDjangoQuerySet;
81 
82  public:
86  typedef std::bidirectional_iterator_tag iterator_category;
87 
89  typedef qptrdiff difference_type;
90  typedef T value_type;
91  typedef T *pointer;
92  typedef T &reference;
103  : m_querySet(0)
104  , m_fetched(-1)
105  , m_offset(0)
106  {
107  }
108 
112  : m_querySet(other.m_querySet)
113  , m_fetched(-1)
114  , m_offset(other.m_offset)
115  {
116  }
117 
118  private:
119  const_iterator(const QDjangoQuerySet<T> *querySet, int offset = 0)
120  : m_querySet(querySet)
121  , m_fetched(-1)
122  , m_offset(offset)
123  {
124  }
125 
126  public:
131  const T &operator*() const { return *t(); }
132 
137  const T *operator->() const { return t(); }
138 
139 
145  bool operator==(const const_iterator &other) const
146  {
147  return m_querySet == other.m_querySet && m_offset == other.m_offset;
148  }
149 
155  bool operator!=(const const_iterator &other) const
156  {
157  return m_querySet != other.m_querySet || m_offset != other.m_offset;
158  }
159 
163  bool operator<(const const_iterator& other) const
164  {
165  return (m_querySet == other.m_querySet && m_offset < other.m_offset)
166  || m_querySet < other.m_querySet;
167  }
168 
172  bool operator<=(const const_iterator& other) const
173  {
174  return (m_querySet == other.m_querySet && m_offset <= other.m_offset)
175  || m_querySet < other.m_querySet;
176  }
177 
181  bool operator>(const const_iterator& other) const
182  {
183  return (m_querySet == other.m_querySet && m_offset > other.m_offset)
184  || m_querySet > other.m_querySet;
185  }
186 
190  bool operator>=(const const_iterator& other) const
191  {
192  return (m_querySet == other.m_querySet && m_offset >= other.m_offset)
193  || m_querySet > other.m_querySet;
194  }
195 
203  const_iterator &operator++() { ++m_offset; return *this; }
204 
212  const_iterator operator++(int) { const_iterator n(*this); ++m_offset; return n; }
213 
219  const_iterator &operator+=(int i) { m_offset += i; return *this; }
220 
226  const_iterator operator+(int i) const { return const_iterator(m_querySet, m_offset + i); }
227 
233  const_iterator &operator-=(int i) { m_offset -= i; return *this; }
234 
240  const_iterator operator-(int i) const { return const_iterator(m_querySet, m_offset - i); }
241 
249  const_iterator &operator--() { --m_offset; return *this; }
250 
258  const_iterator operator--(int) { const_iterator n(*this); --m_offset; return n; }
259 
260 
264  difference_type operator-(const const_iterator &other) const { return m_offset - other.m_offset; }
265 
266  private:
267  const T *t() const
268  {
269  if (m_fetched != m_offset && m_querySet) {
270  if (const_cast<QDjangoQuerySet<T> *>(m_querySet)->at(m_offset, &m_object)) {
271  m_fetched = m_offset;
272  }
273  }
274 
275  return m_fetched == m_offset ? &m_object : 0;
276  }
277 
278  private:
279  const QDjangoQuerySet<T> *m_querySet;
280  mutable int m_fetched;
281  mutable T m_object;
282 
283  int m_offset;
284  };
285 
288 
289  QDjangoQuerySet();
290  QDjangoQuerySet(const QDjangoQuerySet<T> &other);
292 
293  QDjangoQuerySet all() const;
296  QDjangoQuerySet limit(int pos, int length = -1) const;
297  QDjangoQuerySet none() const;
298  QDjangoQuerySet orderBy(const QStringList &keys) const;
300 
301  int count() const;
302  QDjangoWhere where() const;
303 
304  bool remove();
305  int size();
306  int update(const QVariantMap &fields);
307  QList<QVariantMap> values(const QStringList &fields = QStringList());
308  QList<QVariantList> valuesList(const QStringList &fields = QStringList());
309 
310  T *get(const QDjangoWhere &where, T *target = 0) const;
311  T *at(int index, T *target = 0);
312 
313  const_iterator constBegin() const;
314  const_iterator begin() const;
315 
316  const_iterator constEnd() const;
317  const_iterator end() const;
318 
320 
321 private:
322  QDjangoQuerySetPrivate *d;
323 };
324 
327 template <class T>
329 {
330  d = new QDjangoQuerySetPrivate(T::staticMetaObject.className());
331 }
332 
337 template <class T>
339 {
340  other.d->counter.ref();
341  d = other.d;
342 }
343 
346 template <class T>
348 {
349  if (!d->counter.deref())
350  delete d;
351 }
352 
363 template <class T>
364 T *QDjangoQuerySet<T>::at(int index, T *target)
365 {
366  T *entry = target ? target : new T;
367  if (!d->sqlLoad(entry, index))
368  {
369  if (!target)
370  delete entry;
371  return 0;
372  }
373  return entry;
374 }
375 
380 template <class T>
382 {
383  return const_iterator(this);
384 }
385 
390 template <class T>
392 {
393  return const_iterator(this);
394 }
395 
401 template <class T>
403 {
405 }
406 
412 template <class T>
414 {
416 }
417 
420 template <class T>
422 {
423  QDjangoQuerySet<T> other;
424  other.d->lowMark = d->lowMark;
425  other.d->highMark = d->highMark;
426  other.d->orderBy = d->orderBy;
427  other.d->selectRelated = d->selectRelated;
428  other.d->whereClause = d->whereClause;
429  return other;
430 }
431 
441 template <class T>
443 {
444  if (d->hasResults)
445  return d->properties.size();
446 
447  // execute COUNT query
448  QDjangoQuery query(d->countQuery());
449  if (!query.exec() || !query.next())
450  return -1;
451  return query.value(0).toInt();
452 }
453 
464 template <class T>
466 {
467  QDjangoQuerySet<T> other = all();
468  other.d->addFilter(!where);
469  return other;
470 }
471 
482 template <class T>
484 {
485  QDjangoQuerySet<T> other = all();
486  other.d->addFilter(where);
487  return other;
488 }
489 
501 template <class T>
502 T *QDjangoQuerySet<T>::get(const QDjangoWhere &where, T *target) const
503 {
504  QDjangoQuerySet<T> qs = filter(where);
505  return qs.size() == 1 ? qs.at(0, target) : 0;
506 }
507 
520 template <class T>
522 {
523  Q_ASSERT(pos >= 0);
524  Q_ASSERT(length >= -1);
525 
526  QDjangoQuerySet<T> other = all();
527  other.d->lowMark += pos;
528  if (length > 0)
529  {
530  // calculate new high mark
531  other.d->highMark = other.d->lowMark + length;
532  // never exceed the current high mark
533  if (d->highMark > 0 && other.d->highMark > d->highMark)
534  other.d->highMark = d->highMark;
535  }
536  return other;
537 }
538 
541 template <class T>
543 {
544  QDjangoQuerySet<T> other;
545  other.d->whereClause = !QDjangoWhere();
546  return other;
547 }
548 
556 template <class T>
557 QDjangoQuerySet<T> QDjangoQuerySet<T>::orderBy(const QStringList &keys) const
558 {
559  // it is not possible to change ordering once a limit has been set
560  Q_ASSERT(!d->lowMark && !d->highMark);
561 
562  QDjangoQuerySet<T> other = all();
563  other.d->orderBy << keys;
564  return other;
565 }
566 
571 template <class T>
573 {
574  return d->sqlDelete();
575 }
576 
581 template <class T>
583 {
584  QDjangoQuerySet<T> other = all();
585  other.d->selectRelated = true;
586  return other;
587 }
588 
595 template <class T>
597 {
598  if (!d->sqlFetch())
599  return -1;
600  return d->properties.size();
601 }
602 
606 template <class T>
607 int QDjangoQuerySet<T>::update(const QVariantMap &fields)
608 {
609  return d->sqlUpdate(fields);
610 }
611 
617 template <class T>
618 QList<QVariantMap> QDjangoQuerySet<T>::values(const QStringList &fields)
619 {
620  return d->sqlValues(fields);
621 }
622 
629 template <class T>
630 QList<QVariantList> QDjangoQuerySet<T>::valuesList(const QStringList &fields)
631 {
632  return d->sqlValuesList(fields);
633 }
634 
638 template <class T>
640 {
641  return d->resolvedWhere(QDjango::database());
642 }
643 
648 template <class T>
650 {
651  other.d->counter.ref();
652  if (!d->counter.deref())
653  delete d;
654  d = other.d;
655  return *this;
656 }
657 
658 #endif
~QDjangoQuerySet()
Definition: QDjangoQuerySet.h:347
The QDjangoWhere class expresses an SQL constraint.
Definition: QDjangoWhere.h:40
int update(const QVariantMap &fields)
Definition: QDjangoQuerySet.h:607
const_iterator operator--(int)
Definition: QDjangoQuerySet.h:258
difference_type operator-(const const_iterator &other) const
Definition: QDjangoQuerySet.h:264
static QSqlDatabase database()
Returns the database used by QDjango.
Definition: QDjango.cpp:166
bool remove()
Definition: QDjangoQuerySet.h:572
QDjangoQuerySet selectRelated() const
Definition: QDjangoQuerySet.h:582
QDjangoWhere where() const
Definition: QDjangoQuerySet.h:639
bool operator==(const const_iterator &other) const
Definition: QDjangoQuerySet.h:145
int count() const
Definition: QDjangoQuerySet.h:442
const_iterator()
Definition: QDjangoQuerySet.h:102
const_iterator operator++(int)
Definition: QDjangoQuerySet.h:212
bool operator<=(const const_iterator &other) const
Definition: QDjangoQuerySet.h:172
Definition: QDjangoQuerySet.h:78
QDjangoQuerySet limit(int pos, int length=-1) const
Definition: QDjangoQuerySet.h:521
const_iterator & operator-=(int i)
Definition: QDjangoQuerySet.h:233
QDjangoQuerySet filter(const QDjangoWhere &where) const
Definition: QDjangoQuerySet.h:483
const_iterator constBegin() const
Definition: QDjangoQuerySet.h:381
QDjangoQuerySet exclude(const QDjangoWhere &where) const
Definition: QDjangoQuerySet.h:465
QDjangoQuerySet()
Definition: QDjangoQuerySet.h:328
const_iterator & operator+=(int i)
Definition: QDjangoQuerySet.h:219
QDjangoQuerySet< T > & operator=(const QDjangoQuerySet< T > &other)
Definition: QDjangoQuerySet.h:649
const_iterator ConstIterator
Definition: QDjangoQuerySet.h:287
const_iterator & operator++()
Definition: QDjangoQuerySet.h:203
const_iterator & operator--()
Definition: QDjangoQuerySet.h:249
const_iterator constEnd() const
Definition: QDjangoQuerySet.h:402
const_iterator(const const_iterator &other)
Definition: QDjangoQuerySet.h:111
The QDjangoQuerySet class is a template class for performing database queries.
Definition: QDjangoQuerySet.h:46
QDjangoQuerySet none() const
Definition: QDjangoQuerySet.h:542
T * at(int index, T *target=0)
Definition: QDjangoQuerySet.h:364
QList< QVariantList > valuesList(const QStringList &fields=QStringList())
Definition: QDjangoQuerySet.h:630
bool operator!=(const const_iterator &other) const
Definition: QDjangoQuerySet.h:155
const_iterator end() const
Definition: QDjangoQuerySet.h:413
const_iterator operator+(int i) const
Definition: QDjangoQuerySet.h:226
QDjangoQuerySet orderBy(const QStringList &keys) const
Definition: QDjangoQuerySet.h:557
T * get(const QDjangoWhere &where, T *target=0) const
Definition: QDjangoQuerySet.h:502
const_iterator operator-(int i) const
Definition: QDjangoQuerySet.h:240
int size()
Definition: QDjangoQuerySet.h:596
QDjangoQuerySet all() const
Definition: QDjangoQuerySet.h:421
const T & operator*() const
Definition: QDjangoQuerySet.h:131
bool operator<(const const_iterator &other) const
Definition: QDjangoQuerySet.h:163
std::bidirectional_iterator_tag iterator_category
Definition: QDjangoQuerySet.h:86
const T * operator->() const
Definition: QDjangoQuerySet.h:137
const_iterator begin() const
Definition: QDjangoQuerySet.h:391
QList< QVariantMap > values(const QStringList &fields=QStringList())
Definition: QDjangoQuerySet.h:618
bool operator>=(const const_iterator &other) const
Definition: QDjangoQuerySet.h:190
bool operator>(const const_iterator &other) const
Definition: QDjangoQuerySet.h:181