QDjango
Loading...
Searching...
No Matches
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
45template <class T>
47{
48public:
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
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
314 const_iterator begin() const;
315
316 const_iterator constEnd() const;
317 const_iterator end() const;
318
320
321private:
322 QDjangoQuerySetPrivate *d;
323};
324
327template <class T>
329{
330 d = new QDjangoQuerySetPrivate(T::staticMetaObject.className());
331}
332
337template <class T>
339{
340 other.d->counter.ref();
341 d = other.d;
342}
343
346template <class T>
348{
349 if (!d->counter.deref())
350 delete d;
351}
352
363template <class T>
364T *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
380template <class T>
385
390template <class T>
395
401template <class T>
406
412template <class T>
417
420template <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
441template <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
464template <class T>
466{
467 QDjangoQuerySet<T> other = all();
468 other.d->addFilter(!where);
469 return other;
470}
471
482template <class T>
484{
485 QDjangoQuerySet<T> other = all();
486 other.d->addFilter(where);
487 return other;
488}
489
501template <class T>
502T *QDjangoQuerySet<T>::get(const QDjangoWhere &where, T *target) const
503{
505 return qs.size() == 1 ? qs.at(0, target) : 0;
506}
507
520template <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
541template <class T>
543{
544 QDjangoQuerySet<T> other;
545 other.d->whereClause = !QDjangoWhere();
546 return other;
547}
548
556template <class T>
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
571template <class T>
573{
574 return d->sqlDelete();
575}
576
581template <class T>
583{
584 QDjangoQuerySet<T> other = all();
585 other.d->selectRelated = true;
586 return other;
587}
588
595template <class T>
597{
598 if (!d->sqlFetch())
599 return -1;
600 return d->properties.size();
601}
602
606template <class T>
607int QDjangoQuerySet<T>::update(const QVariantMap &fields)
608{
609 return d->sqlUpdate(fields);
610}
611
617template <class T>
618QList<QVariantMap> QDjangoQuerySet<T>::values(const QStringList &fields)
619{
620 return d->sqlValues(fields);
621}
622
629template <class T>
630QList<QVariantList> QDjangoQuerySet<T>::valuesList(const QStringList &fields)
631{
632 return d->sqlValuesList(fields);
633}
634
638template <class T>
640{
641 return d->resolvedWhere(QDjango::database());
642}
643
648template <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
Definition QDjangoQuerySet.h:79
const_iterator operator+(int i) const
Definition QDjangoQuerySet.h:226
const T * operator->() const
Definition QDjangoQuerySet.h:137
const_iterator(const const_iterator &other)
Definition QDjangoQuerySet.h:111
const_iterator operator--(int)
Definition QDjangoQuerySet.h:258
const_iterator()
Definition QDjangoQuerySet.h:102
std::bidirectional_iterator_tag iterator_category
Definition QDjangoQuerySet.h:86
const_iterator & operator-=(int i)
Definition QDjangoQuerySet.h:233
const_iterator operator-(int i) const
Definition QDjangoQuerySet.h:240
bool operator!=(const const_iterator &other) const
Definition QDjangoQuerySet.h:155
const T & operator*() const
Definition QDjangoQuerySet.h:131
bool operator<(const const_iterator &other) const
Definition QDjangoQuerySet.h:163
bool operator==(const const_iterator &other) const
Definition QDjangoQuerySet.h:145
const_iterator & operator--()
Definition QDjangoQuerySet.h:249
const_iterator operator++(int)
Definition QDjangoQuerySet.h:212
const_iterator & operator+=(int i)
Definition QDjangoQuerySet.h:219
bool operator>=(const const_iterator &other) const
Definition QDjangoQuerySet.h:190
bool operator>(const const_iterator &other) const
Definition QDjangoQuerySet.h:181
bool operator<=(const const_iterator &other) const
Definition QDjangoQuerySet.h:172
const_iterator & operator++()
Definition QDjangoQuerySet.h:203
difference_type operator-(const const_iterator &other) const
Definition QDjangoQuerySet.h:264
The QDjangoQuerySet class is a template class for performing database queries.
Definition QDjangoQuerySet.h:47
T * at(int index, T *target=0)
Definition QDjangoQuerySet.h:364
QDjangoQuerySet limit(int pos, int length=-1) const
Definition QDjangoQuerySet.h:521
QDjangoQuerySet selectRelated() const
Definition QDjangoQuerySet.h:582
int update(const QVariantMap &fields)
Definition QDjangoQuerySet.h:607
QDjangoQuerySet all() const
Definition QDjangoQuerySet.h:421
const_iterator constBegin() const
Definition QDjangoQuerySet.h:381
~QDjangoQuerySet()
Definition QDjangoQuerySet.h:347
QList< QVariantList > valuesList(const QStringList &fields=QStringList())
Definition QDjangoQuerySet.h:630
QDjangoQuerySet filter(const QDjangoWhere &where) const
Definition QDjangoQuerySet.h:483
int size()
Definition QDjangoQuerySet.h:596
QDjangoWhere where() const
Definition QDjangoQuerySet.h:639
T * get(const QDjangoWhere &where, T *target=0) const
Definition QDjangoQuerySet.h:502
QDjangoQuerySet< T > & operator=(const QDjangoQuerySet< T > &other)
Definition QDjangoQuerySet.h:649
int count() const
Definition QDjangoQuerySet.h:442
QDjangoQuerySet exclude(const QDjangoWhere &where) const
Definition QDjangoQuerySet.h:465
QList< QVariantMap > values(const QStringList &fields=QStringList())
Definition QDjangoQuerySet.h:618
QDjangoQuerySet none() const
Definition QDjangoQuerySet.h:542
const_iterator ConstIterator
Definition QDjangoQuerySet.h:287
QDjangoQuerySet()
Definition QDjangoQuerySet.h:328
bool remove()
Definition QDjangoQuerySet.h:572
const_iterator end() const
Definition QDjangoQuerySet.h:413
QDjangoQuerySet orderBy(const QStringList &keys) const
Definition QDjangoQuerySet.h:557
const_iterator begin() const
Definition QDjangoQuerySet.h:391
const_iterator constEnd() const
Definition QDjangoQuerySet.h:402
The QDjangoWhere class expresses an SQL constraint.
Definition QDjangoWhere.h:41
static QSqlDatabase database()
Returns the database used by QDjango.
Definition QDjango.cpp:166