Merge lp:~kevin-wright-1/u1db-qt/document-april-6-i into lp:u1db-qt

Proposed by Kevin Wright
Status: Superseded
Proposed branch: lp:~kevin-wright-1/u1db-qt/document-april-6-i
Merge into: lp:u1db-qt
Diff against target: 470 lines (+254/-18)
8 files modified
database.cpp (+6/-0)
database.h (+3/-0)
document.cpp (+38/-2)
document.h (+5/-0)
index.cpp (+157/-1)
index.h (+9/-0)
query.cpp (+35/-14)
query.h (+1/-1)
To merge this branch: bzr merge lp:~kevin-wright-1/u1db-qt/document-april-6-i
Reviewer Review Type Date Requested Status
Cris Dywan Needs Information
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+157505@code.launchpad.net

This proposal has been superseded by a proposal from 2013-04-08.

Commit message

"Added a 'revise' property to Document and accompanying functionality that provides the abilty to modify existing documents in the database (if the docId already exists).

Description of the change

"Added a 'revise' property to Document and accompanying functionality that provides the ability to modify existing documents in the database (if the docId already exists).

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

I'm unsure of the 'revise' functionality, it looks to do mostly what I *intended* 'create' for, *maybe* hinting at a bug in existing code. I'll prefer to discuss this in detail before making a decision.

review: Needs Information

Unmerged revisions

64. By Kevin Wright

Added a 'revise' property to Document and accompanying functionality that provides the abilty to modify existing documents in the database (if the docId already exists).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'database.cpp'
2--- database.cpp 2013-04-03 15:36:45 +0000
3+++ database.cpp 2013-04-06 04:32:22 +0000
4@@ -317,6 +317,7 @@
5 query.bindValue(":docRev", newRev);
6 // Parse Variant from QML as JsonDocument, fallback to string
7 QString json(QJsonDocument::fromVariant(newDoc).toJson());
8+
9 query.bindValue(":docJson", json.isEmpty() ? newDoc : json);
10 if (!query.exec())
11 return setError(QString("Failed to put/ update document %1: %2\n%3").arg(docId).arg(query.lastError().text()).arg(query.lastQuery())) ? -1 : -1;
12@@ -348,6 +349,11 @@
13 beginInsertRows(QModelIndex(), rowCount(), 0);
14 endInsertRows();
15 */
16+
17+ QList<QString> documents = listDocs();
18+
19+ documentCount = documents.count();
20+
21 Q_EMIT docChanged(docId, newDoc);
22
23 return newRev;
24
25=== modified file 'database.h'
26--- database.h 2013-03-20 17:10:45 +0000
27+++ database.h 2013-04-06 04:32:22 +0000
28@@ -37,6 +37,8 @@
29 Database(QObject* parent = 0);
30 ~Database() { }
31
32+ int documentCount = 0;
33+
34 // QAbstractListModel
35 QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
36 QHash<int, QByteArray>roleNames() const;
37@@ -57,6 +59,7 @@
38 void errorChanged(const QString& error);
39 void docChanged(const QString& docId, QVariant content);
40 void docLoaded(const QString& docId, QVariant content) const;
41+ void documentsAvailable();
42 private:
43 Q_DISABLE_COPY(Database)
44 QString m_path;
45
46=== modified file 'document.cpp'
47--- document.cpp 2013-04-03 15:36:45 +0000
48+++ document.cpp 2013-04-06 04:32:22 +0000
49@@ -145,7 +145,36 @@
50 Q_EMIT createChanged(create);
51
52 if (m_create && m_database && m_defaults.isValid() && !m_database->getDocUnchecked(m_docId).isValid())
53- m_database->putDoc(m_defaults, m_docId);
54+ {
55+ m_database->putDoc(m_defaults, m_docId);
56+ }
57+
58+}
59+
60+bool
61+Document::getRevise()
62+{
63+ return m_revise;
64+}
65+
66+/*!
67+ If revise is true, docId is not empty and no document with the same docId
68+ exists, defaults will be used to store the document.
69+ */
70+void
71+Document::setRevise(bool revise)
72+{
73+ if (m_revise == revise)
74+ return;
75+
76+ m_revise = revise;
77+ Q_EMIT reviseChanged(revise);
78+
79+ if (m_revise && m_database && m_defaults.isValid() && m_database->getDocUnchecked(m_docId).isValid())
80+ {
81+ m_database->putDoc(m_defaults, m_docId);
82+ }
83+
84 }
85
86 QVariant
87@@ -167,10 +196,17 @@
88 return;
89
90 m_defaults = defaults;
91+
92 Q_EMIT defaultsChanged(defaults);
93
94 if (m_create && m_database && m_defaults.isValid() && !m_database->getDocUnchecked(m_docId).isValid())
95- m_database->putDoc(m_defaults, m_docId);
96+ {
97+ m_database->putDoc(m_defaults, m_docId);
98+ }
99+ else if (m_revise && m_database && m_defaults.isValid() && m_database->getDocUnchecked(m_docId).isValid())
100+ {
101+ m_database->putDoc(m_defaults, m_docId);
102+ }
103 }
104
105 /*!
106
107=== modified file 'document.h'
108--- document.h 2013-04-03 15:36:45 +0000
109+++ document.h 2013-04-06 04:32:22 +0000
110@@ -37,6 +37,7 @@
111 #endif
112 Q_PROPERTY(QString docId READ getDocId WRITE setDocId NOTIFY docIdChanged)
113 Q_PROPERTY(bool create READ getCreate WRITE setCreate NOTIFY createChanged)
114+ Q_PROPERTY(bool revise READ getRevise WRITE setRevise NOTIFY reviseChanged)
115 Q_PROPERTY(QVariant defaults READ getDefaults WRITE setDefaults NOTIFY defaultsChanged)
116 Q_PROPERTY(QVariant contents READ getContents WRITE setContents NOTIFY contentsChanged)
117 public:
118@@ -48,7 +49,9 @@
119 QString getDocId();
120 void setDocId(const QString& docId);
121 bool getCreate();
122+ bool getRevise();
123 void setCreate(bool create);
124+ void setRevise(bool revise);
125 QVariant getDefaults();
126 void setDefaults(QVariant defaults);
127 QVariant getContents();
128@@ -57,6 +60,7 @@
129 void databaseChanged(Database* database);
130 void docIdChanged(const QString& docId);
131 void createChanged(bool create);
132+ void reviseChanged(bool revise);
133 void defaultsChanged(QVariant defaults);
134 void contentsChanged(QVariant contents);
135 private:
136@@ -64,6 +68,7 @@
137 Database* m_database;
138 QString m_docId;
139 bool m_create;
140+ bool m_revise;
141 QVariant m_defaults;
142 QVariant m_contents;
143
144
145=== modified file 'index.cpp'
146--- index.cpp 2013-04-03 15:36:45 +0000
147+++ index.cpp 2013-04-06 04:32:22 +0000
148@@ -32,7 +32,6 @@
149
150 /*!
151 \class Index
152- \inmodule U1db
153
154 \brief The Index class defines an index to be stored in the database and
155 queried using Query. Changes in documents affected by the index also update
156@@ -89,6 +88,7 @@
157 QObject::connect(m_database, &Database::docChanged, this, &Index::onDocChanged);
158 Q_EMIT dataInvalidated();
159 }
160+
161 }
162
163 QString
164@@ -126,10 +126,14 @@
165 /*!
166 Sets the expression used. Both an expression and a name must be specified
167 for an index to be created.
168+
169+ Also starts the process of creating the Index result list, which can then be queried or populate the Query model as is.
170+
171 */
172 void
173 Index::setExpression(QStringList expression)
174 {
175+
176 if (m_expression == expression)
177 return;
178
179@@ -140,7 +144,159 @@
180 }
181
182 m_expression = expression;
183+
184 Q_EMIT expressionChanged(expression);
185+ Q_EMIT dataIndexed();
186+}
187+
188+/*!
189+ * \brief Index::generateIndexResults
190+ *
191+ * Iterates through the documents stored in the database and creates the list of results based on the Index expressions.
192+ */
193+
194+void Index::generateIndexResults()
195+{
196+
197+ Database *db(getDatabase());
198+
199+ if(db){
200+
201+ QList<QString> documents = db->listDocs();
202+
203+ Q_FOREACH (QString docId, documents){
204+
205+ QVariant document = db->getDocUnchecked(docId);
206+
207+ QStringList fieldsList;
208+
209+ appendResultsFromMap(fieldsList, document.toMap(),"");
210+
211+ }
212+
213+ }
214+
215+}
216+
217+void Index::clearResults()
218+{
219+ m_results.clear();
220+}
221+
222+
223+/*!
224+ * \brief Index::getAllResults
225+ * \return
226+ */
227+
228+QList<QVariantMap> Index::getAllResults(){
229+ return m_results;
230+}
231+
232+/*!
233+ * \brief Index::getResult
234+ * \param index
235+ * \return
236+ */
237+QVariantMap Index::getResult(int index){
238+ return m_results[index];
239+}
240+
241+/*!
242+ * \brief Index::appendResultsFromMap
243+ * \param fieldsList
244+ * \param current_section
245+ * \param current_field
246+ * \return
247+ *
248+ *This method is desinged to recursively iterate through a document, or section of a document, which represents a QVariantMap. As it iterates through the entire document, the method keeps track of the current index expression, and populates a local QVariantMap should the current expression be found in the Index's list of expressions.
249+ *
250+ *If that QVariantMap contains more than one entry it is added to the global results, which can then be utilized by a Query. This needs to be modified to ensure all expressions are found, whereas at the moment if more than one expressions are defined and any of them are found then the map is added to the results list.
251+ *
252+ */
253+QStringList Index::appendResultsFromMap(QStringList fieldsList, QVariantMap current_section, QString current_field)
254+{
255+
256+ QMapIterator<QString, QVariant> i(current_section);
257+
258+ QString original_field = current_field;
259+
260+ QVariantMap results_map;
261+
262+ while (i.hasNext()) {
263+
264+ i.next();
265+
266+ if(fieldsList.count()>0){
267+ current_field = original_field + "." + i.key();
268+ }
269+ else{
270+ current_field = i.key();
271+ }
272+
273+ fieldsList.append(current_field);
274+
275+ QVariant value = i.value();
276+
277+ if(value.userType()==8) // QVariantMap
278+ {
279+ fieldsList = appendResultsFromMap(fieldsList, value.toMap(),current_field);
280+ }
281+ else if(value.userType()==9) // QVariantList
282+ {
283+ fieldsList = getFieldsFromList(fieldsList, value.toList(),current_field);
284+ }
285+ else
286+ {
287+ if(m_expression.contains(current_field)==true){
288+ results_map.insert(i.key(),value);
289+ }
290+
291+ }
292+ }
293+
294+ if(results_map.count()>0){
295+ m_results.append(results_map);
296+ }
297+
298+ return fieldsList;
299+}
300+/*!
301+ * \brief Index::getFieldsFromList
302+ * \param fieldsList
303+ * \param current_section
304+ * \param current_field
305+ * \return
306+ *
307+ *This recursive method is used in conjuntion with Index::appendResultsFromMap, to aid in iterating through a document when an embedded list is found.
308+ *
309+ */
310+
311+
312+QStringList Index::getFieldsFromList(QStringList fieldsList, QVariantList current_section, QString current_field)
313+{
314+
315+ QListIterator<QVariant> i(current_section);
316+
317+ while (i.hasNext()) {
318+
319+ QVariant value = i.next();
320+
321+ if(value.userType()==8) // QVariantMap
322+ {
323+ fieldsList = appendResultsFromMap(fieldsList, value.toMap(),current_field);
324+ }
325+ else if(value.userType()==9) // QVariantList
326+ {
327+ fieldsList = getFieldsFromList(fieldsList, value.toList(),current_field);
328+ }
329+ else
330+ {
331+
332+ }
333+ }
334+
335+ return fieldsList;
336 }
337
338 QT_END_NAMESPACE_U1DB
339
340=== modified file 'index.h'
341--- index.h 2013-04-03 15:36:45 +0000
342+++ index.h 2013-04-06 04:32:22 +0000
343@@ -47,17 +47,26 @@
344 void setName(const QString& name);
345 QStringList getExpression();
346 void setExpression(QStringList expression);
347+ void generateIndexResults();
348+ QStringList appendResultsFromMap(QStringList fieldsList, QVariantMap current_section, QString current_field);
349+ QStringList getFieldsFromList(QStringList fieldsList, QVariantList current_section, QString current_field);
350+ void clearResults();
351+ QVariantMap getResult(int index);
352+ QList<QVariantMap> getAllResults();
353+
354 Q_SIGNALS:
355 void databaseChanged(Database* database);
356 void nameChanged(const QString& name);
357 void expressionChanged(QVariant expression);
358 // Either of the above has changed:
359 void dataInvalidated();
360+ void dataIndexed();
361 private:
362 Q_DISABLE_COPY(Index)
363 Database* m_database;
364 QString m_name;
365 QStringList m_expression;
366+ QList<QVariantMap> m_results;
367
368 void onPathChanged(const QString& path);
369 void onDocChanged(const QString& docId, QVariant content);
370
371=== modified file 'query.cpp'
372--- query.cpp 2013-04-03 15:36:45 +0000
373+++ query.cpp 2013-04-06 04:32:22 +0000
374@@ -47,27 +47,28 @@
375 }
376
377 /*!
378- Used to implement QAbstractListModel
379- Implements the variables exposed to the Delegate in a model
380- QVariant contents
381- QString docId
382- int index (built-in)
383+ * \brief Query::data
384+ * \param index
385+ * \param role
386+ * \return
387+ *Used to implement QAbstractListModel
388+ *Implements the variables exposed to the Delegate in a model
389 */
390 QVariant
391 Query::data(const QModelIndex & index, int role) const
392 {
393- QString docId(m_hash.value(index.row()));
394+ QVariantMap result(m_hash.value(index.row()));
395+
396 if (role == 0) // contents
397 {
398 Database* db(m_index->getDatabase());
399 if (db)
400 {
401- qDebug() << "Query::getData" << docId;
402- return db->getDocUnchecked(docId);
403+ return result;
404 }
405 }
406 if (role == 1) // docId
407- return docId;
408+ //return docId;
409 return QVariant();
410 }
411
412@@ -105,10 +106,25 @@
413 Query::onDataInvalidated()
414 {
415 m_hash.clear();
416- Database* db(m_index->getDatabase());
417- if (db)
418- ;
419- // TODO
420+
421+ Database *db = m_index->getDatabase();
422+ if(db){
423+ if(db->documentCount>0){
424+ QObject::connect(db, &Database::documentsAvailable, this, &Query::onDataInvalidated);
425+ }
426+ }
427+
428+ m_index->clearResults();
429+
430+ m_index->generateIndexResults();
431+
432+ QListIterator<QVariantMap> i(m_index->getAllResults());
433+
434+ while (i.hasNext()) {
435+ QVariantMap result = i.next();
436+ m_hash.insert(m_hash.count(),result);
437+ }
438+
439 }
440
441 /*!
442@@ -124,10 +140,15 @@
443 if (m_index)
444 QObject::disconnect(m_index, 0, this, 0);
445 m_index = index;
446- if (m_index)
447+ if (m_index){
448 QObject::connect(m_index, &Index::dataInvalidated, this, &Query::onDataInvalidated);
449+ QObject::connect(m_index, &Index::dataIndexed, this, &Query::onDataInvalidated);
450+ }
451 Q_EMIT indexChanged(index);
452+
453+
454 onDataInvalidated();
455+
456 }
457
458 QVariant
459
460=== modified file 'query.h'
461--- query.h 2013-04-03 15:36:45 +0000
462+++ query.h 2013-04-06 04:32:22 +0000
463@@ -58,7 +58,7 @@
464 private:
465 Q_DISABLE_COPY(Query)
466 Index* m_index;
467- QHash<int, QString> m_hash;
468+ QHash<int, QVariantMap> m_hash;
469 QVariant m_query;
470 QVariant m_range;
471

Subscribers

People subscribed via source and target branches

to all changes: