1 /**
2 * UGENE - Integrated Bioinformatics Tools.
3 * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4 * http://ugene.net
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22 #include "SQLiteObjectDbiUnitTests.h"
23
24 #include <U2Core/DNAAlphabet.h>
25 #include <U2Core/U2AttributeDbi.h>
26 #include <U2Core/U2MsaDbi.h>
27 #include <U2Core/U2OpStatusUtils.h>
28 #include <U2Core/U2SequenceDbi.h>
29 #include <U2Core/U2SequenceUtils.h>
30
31 #include <U2Formats/SQLiteDbi.h>
32 #include <U2Formats/SQLiteObjectDbi.h>
33 #include <U2Formats/SQLiteSequenceDbi.h>
34
35 #include "core/util/MsaDbiUtilsUnitTests.h"
36
37 namespace U2 {
38
39 TestDbiProvider SQLiteObjectDbiTestData::dbiProvider = TestDbiProvider();
40 const QString &SQLiteObjectDbiTestData::SQLITE_OBJ_DB_URL("sqlite-obj-dbi.ugenedb");
41 U2AttributeDbi *SQLiteObjectDbiTestData::attributeDbi = nullptr;
42 U2MsaDbi *SQLiteObjectDbiTestData::msaDbi = nullptr;
43 U2SequenceDbi *SQLiteObjectDbiTestData::sequenceDbi = nullptr;
44 SQLiteDbi *SQLiteObjectDbiTestData::sqliteDbi = nullptr;
45 SQLiteObjectDbi *SQLiteObjectDbiTestData::sqliteObjectDbi = nullptr;
46
init()47 void SQLiteObjectDbiTestData::init() {
48 SAFE_POINT(nullptr == sqliteDbi, "sqliteDbi has already been initialized!", );
49
50 // Get URL
51 bool ok = dbiProvider.init(SQLITE_OBJ_DB_URL, false);
52 SAFE_POINT(ok, "Dbi provider failed to initialize in MsaTestData::init()!", );
53
54 U2Dbi *dbi = dbiProvider.getDbi();
55 QString url = dbi->getDbiRef().dbiId;
56 dbiProvider.close();
57
58 // Init DBI
59 sqliteDbi = new SQLiteDbi();
60 QHash<QString, QString> initProperties;
61 initProperties[U2DbiOptions::U2_DBI_OPTION_URL] = url;
62 U2OpStatusImpl os;
63 sqliteDbi->init(initProperties, QVariantMap(), os);
64 SAFE_POINT_OP(os, );
65
66 sqliteObjectDbi = sqliteDbi->getSQLiteObjectDbi();
67 SAFE_POINT(nullptr != sqliteObjectDbi, "Failed to get sqliteObjectDbi!", );
68
69 attributeDbi = sqliteDbi->getAttributeDbi();
70 SAFE_POINT(nullptr != attributeDbi, "Failed to get attributeDbi!", );
71
72 msaDbi = sqliteDbi->getMsaDbi();
73 SAFE_POINT(nullptr != msaDbi, "Failed to get msaDbi!", );
74
75 sequenceDbi = sqliteDbi->getSequenceDbi();
76 SAFE_POINT(nullptr != sequenceDbi, "Failed to get sequenceDbi!", );
77 }
78
shutdown()79 void SQLiteObjectDbiTestData::shutdown() {
80 if (nullptr != sqliteDbi) {
81 delete sqliteDbi;
82
83 sqliteDbi = nullptr;
84 sqliteObjectDbi = nullptr;
85 attributeDbi = nullptr;
86 msaDbi = nullptr;
87 sequenceDbi = nullptr;
88 }
89 }
90
getSQLiteDbi()91 SQLiteDbi *SQLiteObjectDbiTestData::getSQLiteDbi() {
92 if (nullptr == sqliteDbi) {
93 init();
94 }
95 return sqliteDbi;
96 }
97
getSQLiteObjectDbi()98 SQLiteObjectDbi *SQLiteObjectDbiTestData::getSQLiteObjectDbi() {
99 if (nullptr == sqliteObjectDbi) {
100 init();
101 }
102 return sqliteObjectDbi;
103 }
104
getAttributeDbi()105 U2AttributeDbi *SQLiteObjectDbiTestData::getAttributeDbi() {
106 if (nullptr == attributeDbi) {
107 init();
108 }
109 return attributeDbi;
110 }
111
getMsaDbi()112 U2MsaDbi *SQLiteObjectDbiTestData::getMsaDbi() {
113 if (nullptr == msaDbi) {
114 init();
115 }
116 return msaDbi;
117 }
118
getSequenceDbi()119 U2SequenceDbi *SQLiteObjectDbiTestData::getSequenceDbi() {
120 if (nullptr == sequenceDbi) {
121 init();
122 }
123 return sequenceDbi;
124 }
125
createTestMsa(bool enableModTracking,U2OpStatus & os)126 U2DataId SQLiteObjectDbiTestData::createTestMsa(bool enableModTracking, U2OpStatus &os) {
127 // Create an alignment
128 U2AlphabetId alphabet = BaseDNAAlphabetIds::NUCL_DNA_DEFAULT();
129 U2DataId msaId = sqliteDbi->getMsaDbi()->createMsaObject("", "Test alignment", alphabet, os);
130 CHECK_OP(os, U2DataId());
131
132 if (enableModTracking) {
133 sqliteDbi->getObjectDbi()->setTrackModType(msaId, TrackOnUpdate, os);
134 CHECK_OP(os, U2DataId());
135 }
136
137 return msaId;
138 }
139
addTestRow(const U2DataId & msaId,U2OpStatus & os)140 void SQLiteObjectDbiTestData::addTestRow(const U2DataId &msaId, U2OpStatus &os) {
141 U2Sequence seq;
142 seq.alphabet = BaseDNAAlphabetIds::NUCL_DNA_DEFAULT();
143 seq.circular = false;
144 seq.trackModType = NoTrack;
145 seq.visualName = "Test sequence";
146 sqliteDbi->getSQLiteSequenceDbi()->createSequenceObject(seq, "", os, U2DbiObjectRank_TopLevel);
147 SAFE_POINT_OP(os, );
148
149 U2MsaRow row;
150 row.sequenceId = seq.id;
151 row.gstart = 0;
152 row.gend = 0;
153 row.length = 0;
154
155 sqliteDbi->getMsaDbi()->addRow(msaId, -1, row, os);
156 SAFE_POINT_OP(os, );
157 }
158
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,removeMsaObject)159 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, removeMsaObject) {
160 U2OpStatusImpl os;
161 U2MsaDbi *msaDbi = SQLiteObjectDbiTestData::getMsaDbi();
162
163 // FIRST ALIGNMENT
164 // Create an alignment
165 U2DataId msaId = msaDbi->createMsaObject("", "Test name", BaseDNAAlphabetIds::NUCL_DNA_DEFAULT(), os);
166 CHECK_NO_ERROR(os);
167
168 // Add alignment info
169 U2StringAttribute attr(msaId, "MSA1 info key", "MSA1 info value");
170 U2AttributeDbi *attrDbi = SQLiteObjectDbiTestData::getAttributeDbi();
171 attrDbi->createStringAttribute(attr, os);
172 CHECK_NO_ERROR(os);
173
174 // Create sequences
175 U2SequenceDbi *sequenceDbi = SQLiteObjectDbiTestData::getSequenceDbi();
176 U2Sequence seq1;
177 U2Sequence seq2;
178 sequenceDbi->createSequenceObject(seq1, "", os);
179 CHECK_NO_ERROR(os);
180 sequenceDbi->createSequenceObject(seq2, "", os);
181 CHECK_NO_ERROR(os);
182
183 // Add rows
184 U2MsaRow row1;
185 row1.rowId = 0;
186 row1.sequenceId = seq1.id;
187 row1.gstart = 0;
188 row1.gend = 5;
189
190 U2MsaGap row1gap1(0, 2);
191 U2MsaGap row1gap2(3, 1);
192 QList<U2MsaGap> row1gaps;
193 row1gaps << row1gap1 << row1gap2;
194
195 row1.gaps = row1gaps;
196
197 U2MsaRow row2;
198 row2.rowId = 1;
199 row2.sequenceId = seq2.id;
200 row2.gstart = 2;
201 row2.gend = 4;
202
203 U2MsaGap row2gap(1, 2);
204 QList<U2MsaGap> row2gaps;
205 row2gaps << row2gap;
206
207 row2.gaps = row2gaps;
208
209 QList<U2MsaRow> rows;
210 rows << row1 << row2;
211
212 msaDbi->addRows(msaId, rows, -1, os);
213 CHECK_NO_ERROR(os);
214
215 // SECOND ALIGNMENT
216 // Create an alignment
217 U2DataId msaId2 = msaDbi->createMsaObject("", "Test name 2", BaseDNAAlphabetIds::AMINO_DEFAULT(), os);
218 CHECK_NO_ERROR(os);
219
220 // Add alignment info
221 U2StringAttribute attr2(msaId2, "MSA2 info key", "MSA2 info value");
222 attrDbi->createStringAttribute(attr2, os);
223 CHECK_NO_ERROR(os);
224
225 // Create sequences
226 U2Sequence al2Seq;
227 sequenceDbi->createSequenceObject(al2Seq, "", os);
228 CHECK_NO_ERROR(os);
229
230 // Add rows
231 U2MsaRow al2Row;
232 al2Row.rowId = 0;
233 al2Row.sequenceId = al2Seq.id;
234 al2Row.gstart = 0;
235 al2Row.gend = 15;
236
237 U2MsaGap al2RowGap(1, 12);
238 QList<U2MsaGap> al2RowGaps;
239 al2RowGaps << al2RowGap;
240
241 al2Row.gaps = al2RowGaps;
242
243 QList<U2MsaRow> al2Rows;
244 al2Rows << al2Row;
245
246 msaDbi->addRows(msaId2, al2Rows, -1, os);
247 CHECK_NO_ERROR(os);
248
249 // REMOVE THE FIRST ALIGNMENT OBJECT
250 SQLiteObjectDbi *sqliteObjectDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
251 sqliteObjectDbi->removeObject(msaId, os);
252
253 // VERIFY THAT THERE IS ONLY THE SECOND ALIGNMENT'S RECORDS LEFT IN TABLES
254 SQLiteDbi *sqliteDbi = SQLiteObjectDbiTestData::getSQLiteDbi();
255
256 // "Attribute"
257 SQLiteReadQuery qAttr("SELECT COUNT(*) FROM Attribute WHERE name = ?1", sqliteDbi->getDbRef(), os);
258 qAttr.bindString(1, "MSA1 info key");
259 qint64 msa1AttrNum = qAttr.selectInt64();
260 CHECK_EQUAL(0, msa1AttrNum, "MSA1 attributes number");
261
262 qAttr.reset(true);
263 qAttr.bindString(1, "MSA2 info key");
264 qint64 msa2AttrNum = qAttr.selectInt64();
265 CHECK_EQUAL(1, msa2AttrNum, "MSA2 attributes number");
266
267 // "StringAttribute"
268 SQLiteReadQuery qStringAttr("SELECT COUNT(*) FROM StringAttribute WHERE value = ?1", sqliteDbi->getDbRef(), os);
269 qStringAttr.bindString(1, "MSA1 info value");
270 qint64 msa1StrAttrNum = qStringAttr.selectInt64();
271 CHECK_EQUAL(0, msa1StrAttrNum, "MSA1 string attributes number");
272
273 qStringAttr.reset(true);
274 qStringAttr.bindString(1, "MSA2 info value");
275 qint64 msa2StrAttrNum = qStringAttr.selectInt64();
276 CHECK_EQUAL(1, msa2StrAttrNum, "MSA2 string attributes number");
277
278 // "MsaRow"
279 SQLiteReadQuery qMsaRow("SELECT COUNT(*) FROM MsaRow WHERE msa = ?1", sqliteDbi->getDbRef(), os);
280 qMsaRow.bindDataId(1, msaId);
281 qint64 msa1Rows = qMsaRow.selectInt64();
282 CHECK_EQUAL(0, msa1Rows, "number of rows in MSA1");
283
284 qMsaRow.reset(true);
285 qMsaRow.bindDataId(1, msaId2);
286 qint64 msa2Rows = qMsaRow.selectInt64();
287 CHECK_EQUAL(1, msa2Rows, "number of rows in MSA2");
288
289 // "MsaRowGap"
290 SQLiteReadQuery qMsaRowGap("SELECT COUNT(*) FROM MsaRowGap WHERE msa = ?1", sqliteDbi->getDbRef(), os);
291 qMsaRowGap.bindDataId(1, msaId);
292 qint64 msa1Gaps = qMsaRowGap.selectInt64();
293 CHECK_EQUAL(0, msa1Gaps, "number of gaps in MSA1 rows");
294
295 qMsaRowGap.reset(true);
296 qMsaRowGap.bindDataId(1, msaId2);
297 qint64 msa2Gaps = qMsaRowGap.selectInt64();
298 CHECK_EQUAL(1, msa2Gaps, "number of gaps in MSA2 rows");
299
300 // "Sequence"
301 SQLiteReadQuery qSeq("SELECT COUNT(*) FROM Sequence WHERE object = ?1", sqliteDbi->getDbRef(), os);
302 qSeq.bindDataId(1, seq1.id);
303 qint64 msa1seq1 = qSeq.selectInt64();
304 CHECK_EQUAL(0, msa1seq1, "seq1 of msa1");
305
306 qSeq.reset(true);
307 qSeq.bindDataId(1, seq2.id);
308 qint64 msa1seq2 = qSeq.selectInt64();
309 CHECK_EQUAL(0, msa1seq2, "seq2 of msa1");
310
311 qSeq.reset(true);
312 qSeq.bindDataId(1, al2Seq.id);
313 qint64 msa2seq = qSeq.selectInt64();
314 CHECK_EQUAL(1, msa2seq, "seq of msa2");
315
316 // "Msa"
317 SQLiteReadQuery qMsa("SELECT COUNT(*) FROM Msa WHERE object = ?1", sqliteDbi->getDbRef(), os);
318 qMsa.bindDataId(1, msaId);
319 qint64 msa1records = qMsa.selectInt64();
320 CHECK_EQUAL(0, msa1records, "number of MSA1 records");
321
322 qMsa.reset(true);
323 qMsa.bindDataId(1, msaId2);
324 qint64 msa2records = qMsa.selectInt64();
325 CHECK_EQUAL(1, msa2records, "number of MSA2 records");
326
327 // "Object"
328 SQLiteReadQuery qObj("SELECT COUNT(*) FROM Object WHERE id = ?1", sqliteDbi->getDbRef(), os);
329 qObj.bindDataId(1, msaId);
330 qint64 msa1objects = qObj.selectInt64();
331 CHECK_EQUAL(0, msa1objects, "number of MSA1 objects");
332
333 qObj.reset(true);
334 qObj.bindDataId(1, msaId2);
335 qint64 msa2objects = qObj.selectInt64();
336 CHECK_EQUAL(1, msa2objects, "number of MSA2 objects");
337
338 // Remove the second alignment
339 sqliteObjectDbi->removeObject(msaId2, os);
340 }
341
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,setTrackModType)342 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, setTrackModType) {
343 U2OpStatusImpl os;
344 U2MsaDbi *msaDbi = SQLiteObjectDbiTestData::getMsaDbi();
345 SQLiteObjectDbi *objectDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
346
347 // Create alignment 1
348 U2DataId msaId1 = msaDbi->createMsaObject("", "Test name 1", BaseDNAAlphabetIds::NUCL_DNA_DEFAULT(), os);
349 CHECK_NO_ERROR(os);
350 Utils::addRow(msaDbi->getRootDbi(), msaId1, "1", "ACGTACGT", QList<U2MsaGap>(), os);
351 CHECK_NO_ERROR(os);
352 QList<U2MsaRow> rows1 = msaDbi->getRows(msaId1, os);
353 CHECK_NO_ERROR(os);
354
355 // Create alignment 2
356 U2DataId msaId2 = msaDbi->createMsaObject("", "Test name 2", BaseDNAAlphabetIds::NUCL_DNA_DEFAULT(), os);
357 CHECK_NO_ERROR(os);
358 Utils::addRow(msaDbi->getRootDbi(), msaId2, "2", "CCCCCCC", QList<U2MsaGap>(), os);
359 CHECK_NO_ERROR(os);
360 QList<U2MsaRow> rows2 = msaDbi->getRows(msaId2, os);
361 CHECK_NO_ERROR(os);
362
363 // Change mod track 1
364 objectDbi->setTrackModType(msaId1, TrackOnUpdate, os);
365 CHECK_NO_ERROR(os);
366
367 U2TrackModType newType1_1 = objectDbi->getTrackModType(rows1[0].sequenceId, os);
368 CHECK_EQUAL(TrackOnUpdate, newType1_1, "new mod track type 1_1");
369
370 U2TrackModType newType1_2 = objectDbi->getTrackModType(rows2[0].sequenceId, os);
371 CHECK_EQUAL(NoTrack, newType1_2, "new mod track type 1_2");
372
373 // Change mod track 2
374 objectDbi->setTrackModType(msaId1, NoTrack, os);
375 CHECK_NO_ERROR(os);
376 objectDbi->setTrackModType(msaId2, TrackOnUpdate, os);
377 CHECK_NO_ERROR(os);
378
379 U2TrackModType newType2_1 = objectDbi->getTrackModType(rows1[0].sequenceId, os);
380 CHECK_EQUAL(NoTrack, newType2_1, "new mod track type 2_1");
381
382 U2TrackModType newType2_2 = objectDbi->getTrackModType(rows2[0].sequenceId, os);
383 CHECK_EQUAL(TrackOnUpdate, newType2_2, "new mod track type 2_2");
384 }
385
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,canUndoRedo_noTrack)386 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, canUndoRedo_noTrack) {
387 U2OpStatusImpl os;
388 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
389
390 // Create test msa
391 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(false, os);
392 CHECK_NO_ERROR(os);
393
394 // Do action
395 SQLiteObjectDbiTestData::addTestRow(msaId, os);
396 CHECK_NO_ERROR(os);
397
398 // Verify canUndo/canRedo
399 bool undoState = objDbi->canUndo(msaId, os);
400 CHECK_NO_ERROR(os);
401 bool redoState = objDbi->canRedo(msaId, os);
402 CHECK_NO_ERROR(os);
403 CHECK_FALSE(undoState, "undo state");
404 CHECK_FALSE(redoState, "redo state");
405 }
406
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,canUndoRedo_noAction)407 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, canUndoRedo_noAction) {
408 U2OpStatusImpl os;
409 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
410
411 // Create test msa
412 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
413 CHECK_NO_ERROR(os);
414
415 // Verify canUndo/canRedo
416 bool undoState = objDbi->canUndo(msaId, os);
417 CHECK_NO_ERROR(os);
418 bool redoState = objDbi->canRedo(msaId, os);
419 CHECK_NO_ERROR(os);
420 CHECK_FALSE(undoState, "undo state");
421 CHECK_FALSE(redoState, "redo state");
422 }
423
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,canUndoRedo_lastState)424 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, canUndoRedo_lastState) {
425 U2OpStatusImpl os;
426 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
427
428 // Create test msa
429 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
430 CHECK_NO_ERROR(os);
431
432 // Do action
433 SQLiteObjectDbiTestData::addTestRow(msaId, os);
434 CHECK_NO_ERROR(os);
435
436 // Verify canUndo/canRedo
437 bool undoState = objDbi->canUndo(msaId, os);
438 CHECK_NO_ERROR(os);
439 bool redoState = objDbi->canRedo(msaId, os);
440 CHECK_NO_ERROR(os);
441 CHECK_TRUE(undoState, "undo state");
442 CHECK_FALSE(redoState, "redo state");
443 }
444
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,canUndoRedo_firstState)445 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, canUndoRedo_firstState) {
446 U2OpStatusImpl os;
447 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
448
449 // Create test msa
450 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
451 CHECK_NO_ERROR(os);
452
453 // Do action, undo
454 SQLiteObjectDbiTestData::addTestRow(msaId, os);
455 CHECK_NO_ERROR(os);
456 objDbi->undo(msaId, os);
457 CHECK_NO_ERROR(os);
458
459 // Verify canUndo/canRedo
460 bool undoState = objDbi->canUndo(msaId, os);
461 CHECK_NO_ERROR(os);
462 bool redoState = objDbi->canRedo(msaId, os);
463 CHECK_NO_ERROR(os);
464 CHECK_FALSE(undoState, "undo state");
465 CHECK_TRUE(redoState, "redo state");
466 }
467
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,canUndoRedo_midState)468 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, canUndoRedo_midState) {
469 U2OpStatusImpl os;
470 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
471
472 // Create test msa
473 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
474 CHECK_NO_ERROR(os);
475
476 // Do action twice, undo
477 SQLiteObjectDbiTestData::addTestRow(msaId, os);
478 CHECK_NO_ERROR(os);
479 SQLiteObjectDbiTestData::addTestRow(msaId, os);
480 CHECK_NO_ERROR(os);
481
482 objDbi->undo(msaId, os);
483 CHECK_NO_ERROR(os);
484
485 // Verify canUndo/canRedo
486 bool undoState = objDbi->canUndo(msaId, os);
487 CHECK_NO_ERROR(os);
488 bool redoState = objDbi->canRedo(msaId, os);
489 CHECK_NO_ERROR(os);
490 CHECK_TRUE(undoState, "undo state");
491 CHECK_TRUE(redoState, "redo state");
492 }
493
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,canUndoRedo_oneUserStep)494 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, canUndoRedo_oneUserStep) {
495 U2OpStatusImpl os;
496 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
497
498 // Create test msa
499 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
500 CHECK_NO_ERROR(os);
501
502 // Do action twice inside one UserStep
503 {
504 U2UseCommonUserModStep userStep(objDbi->getRootDbi(), msaId, os);
505 CHECK_NO_ERROR(os);
506 Q_UNUSED(userStep);
507
508 SQLiteObjectDbiTestData::addTestRow(msaId, os);
509 CHECK_NO_ERROR(os);
510 SQLiteObjectDbiTestData::addTestRow(msaId, os);
511 CHECK_NO_ERROR(os);
512 }
513
514 // Verify canUndo/canRedo
515 bool undoState = objDbi->canUndo(msaId, os);
516 CHECK_NO_ERROR(os);
517 bool redoState = objDbi->canRedo(msaId, os);
518 CHECK_NO_ERROR(os);
519 CHECK_TRUE(undoState, "undo state before undo");
520 CHECK_FALSE(redoState, "redo state before undo");
521
522 // Undo UserStep
523 objDbi->undo(msaId, os);
524 CHECK_NO_ERROR(os);
525
526 // Verify canUndo/canRedo
527 undoState = objDbi->canUndo(msaId, os);
528 CHECK_NO_ERROR(os);
529 redoState = objDbi->canRedo(msaId, os);
530 CHECK_NO_ERROR(os);
531 CHECK_FALSE(undoState, "undo state after undo");
532 CHECK_TRUE(redoState, "redo state after undo");
533 }
534
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,commonUndoRedo_user3Multi)535 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, commonUndoRedo_user3Multi) {
536 U2OpStatusImpl os;
537 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
538 SQLiteDbi *sqliteDbi = SQLiteObjectDbiTestData::getSQLiteDbi();
539
540 // Create test msa
541 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
542 CHECK_NO_ERROR(os);
543
544 // Get msa version
545 qint64 msaVersion = objDbi->getObjectVersion(msaId, os);
546 CHECK_NO_ERROR(os);
547
548 // Do 3 actions
549 {
550 U2UseCommonUserModStep userStep(objDbi->getRootDbi(), msaId, os);
551 CHECK_NO_ERROR(os);
552 Q_UNUSED(userStep);
553
554 SQLiteObjectDbiTestData::addTestRow(msaId, os);
555 CHECK_NO_ERROR(os);
556
557 SQLiteObjectDbiTestData::addTestRow(msaId, os);
558 CHECK_NO_ERROR(os);
559
560 SQLiteObjectDbiTestData::addTestRow(msaId, os);
561 CHECK_NO_ERROR(os);
562 }
563
564 // Verify version in the userModStep
565 SQLiteReadQuery qVersion("SELECT version FROM UserModStep WHERE object = ?1", sqliteDbi->getDbRef(), os);
566 qVersion.bindDataId(1, msaId);
567 if (qVersion.step()) {
568 qint64 userStepVersion = qVersion.getInt64(0);
569 CHECK_EQUAL(msaVersion, userStepVersion, "version in user step");
570 } else {
571 CHECK_TRUE(false, "Failed to get userModStep version!");
572 }
573 CHECK_NO_ERROR(os);
574
575 // Verify msa version
576 qint64 msaVersionAftAct = objDbi->getObjectVersion(msaId, os);
577 CHECK_NO_ERROR(os);
578 CHECK_EQUAL(msaVersion + 3, msaVersionAftAct, "msa version after 3 actions");
579
580 // Verify canUndo/canRedo
581 bool undoState = objDbi->canUndo(msaId, os);
582 CHECK_NO_ERROR(os);
583 bool redoState = objDbi->canRedo(msaId, os);
584 CHECK_NO_ERROR(os);
585 CHECK_TRUE(undoState, "undo state before undo");
586 CHECK_FALSE(redoState, "redo state before undo");
587
588 // Undo
589 objDbi->undo(msaId, os);
590 CHECK_NO_ERROR(os);
591
592 // Verify msa version
593 qint64 msaVersionAftUndo = objDbi->getObjectVersion(msaId, os);
594 CHECK_NO_ERROR(os);
595 CHECK_EQUAL(msaVersion, msaVersionAftUndo, "msa version after undo");
596
597 // Verify canUndo/canRedo
598 undoState = objDbi->canUndo(msaId, os);
599 CHECK_NO_ERROR(os);
600 redoState = objDbi->canRedo(msaId, os);
601 CHECK_NO_ERROR(os);
602 CHECK_FALSE(undoState, "undo state after undo");
603 CHECK_TRUE(redoState, "redo state after undo");
604
605 // Redo
606 objDbi->redo(msaId, os);
607 CHECK_NO_ERROR(os);
608
609 // Verify msa version
610 qint64 msaVersionAftRedo = objDbi->getObjectVersion(msaId, os);
611 CHECK_NO_ERROR(os);
612 CHECK_EQUAL(msaVersion + 3, msaVersionAftRedo, "msa version after redo");
613
614 // Verify canUndo/canRedo
615 undoState = objDbi->canUndo(msaId, os);
616 CHECK_NO_ERROR(os);
617 redoState = objDbi->canRedo(msaId, os);
618 CHECK_NO_ERROR(os);
619 CHECK_TRUE(undoState, "undo state after redo");
620 CHECK_FALSE(redoState, "redo state after redo");
621 }
622
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,commonUndoRedo_actionAfterUndo)623 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, commonUndoRedo_actionAfterUndo) {
624 U2OpStatusImpl os;
625 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
626 SQLiteDbi *sqliteDbi = SQLiteObjectDbiTestData::getSQLiteDbi();
627
628 // Create test msa
629 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
630 CHECK_NO_ERROR(os);
631
632 // Get msa version
633 qint64 msaVersion = objDbi->getObjectVersion(msaId, os);
634 CHECK_NO_ERROR(os);
635
636 // Do 2 actions
637 {
638 U2UseCommonUserModStep userStep(objDbi->getRootDbi(), msaId, os);
639 CHECK_NO_ERROR(os);
640 Q_UNUSED(userStep);
641
642 SQLiteObjectDbiTestData::addTestRow(msaId, os);
643 CHECK_NO_ERROR(os);
644
645 SQLiteObjectDbiTestData::addTestRow(msaId, os);
646 CHECK_NO_ERROR(os);
647 }
648
649 // Undo
650 objDbi->undo(msaId, os);
651 CHECK_NO_ERROR(os);
652
653 // Do action
654 SQLiteObjectDbiTestData::addTestRow(msaId, os);
655
656 // Check there is no obsolete steps
657 SQLiteReadQuery qUser("SELECT COUNT(*) FROM UserModStep WHERE object = ?1", sqliteDbi->getDbRef(), os);
658 qUser.bindDataId(1, msaId);
659 if (qUser.step()) {
660 CHECK_EQUAL(1, qUser.getInt64(0), "number of user steps");
661 } else {
662 CHECK_TRUE(false, "Unexpected error!");
663 }
664 CHECK_NO_ERROR(os);
665
666 SQLiteReadQuery qSingle("SELECT COUNT(*) FROM SingleModStep WHERE object = ?1", sqliteDbi->getDbRef(), os);
667 qSingle.bindDataId(1, msaId);
668 if (qSingle.step()) {
669 CHECK_EQUAL(1, qSingle.getInt64(0), "number of single steps");
670 } else {
671 CHECK_TRUE(false, "Unexpected error!");
672 }
673 CHECK_NO_ERROR(os);
674
675 // Undo
676 objDbi->undo(msaId, os);
677 CHECK_NO_ERROR(os);
678
679 // Verify msa version
680 qint64 msaVersionAfterActUndo = objDbi->getObjectVersion(msaId, os);
681 CHECK_NO_ERROR(os);
682 CHECK_EQUAL(msaVersion, msaVersionAfterActUndo, "msa version after undo, action and undo");
683
684 // Verify canUndo/canRedo
685 bool undoState = objDbi->canUndo(msaId, os);
686 CHECK_NO_ERROR(os);
687 bool redoState = objDbi->canRedo(msaId, os);
688 CHECK_NO_ERROR(os);
689 CHECK_FALSE(undoState, "undo state after undo, action and undo");
690 CHECK_TRUE(redoState, "redo state after undo, action and undo");
691
692 // Redo
693 objDbi->redo(msaId, os);
694 CHECK_NO_ERROR(os);
695
696 // Verify msa version
697 qint64 msaVersionAfterActRedo = objDbi->getObjectVersion(msaId, os);
698 CHECK_NO_ERROR(os);
699 CHECK_EQUAL(msaVersion + 1, msaVersionAfterActRedo, "msa version after undo, action and undo/redo");
700
701 // Verify canUndo/canRedo
702 undoState = objDbi->canUndo(msaId, os);
703 CHECK_NO_ERROR(os);
704 redoState = objDbi->canRedo(msaId, os);
705 CHECK_NO_ERROR(os);
706 CHECK_TRUE(undoState, "undo state after undo, action and undo/redo");
707 CHECK_FALSE(redoState, "redo state after undo, action and undo/redo");
708 }
709
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,commonUndoRedo_actionUndoActionUndo1)710 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, commonUndoRedo_actionUndoActionUndo1) {
711 U2OpStatusImpl os;
712 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
713 SQLiteDbi *sqliteDbi = SQLiteObjectDbiTestData::getSQLiteDbi();
714
715 // Create test msa
716 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
717 CHECK_NO_ERROR(os);
718
719 // Get msa version
720 qint64 msaVersion = objDbi->getObjectVersion(msaId, os);
721 CHECK_NO_ERROR(os);
722
723 // Do an action
724 {
725 U2UseCommonUserModStep userStep(objDbi->getRootDbi(), msaId, os);
726 CHECK_NO_ERROR(os);
727 Q_UNUSED(userStep);
728
729 SQLiteObjectDbiTestData::addTestRow(msaId, os);
730 CHECK_NO_ERROR(os);
731 }
732
733 // Undo
734 objDbi->undo(msaId, os);
735 CHECK_NO_ERROR(os);
736
737 // Do an action
738 {
739 U2UseCommonUserModStep userStep(objDbi->getRootDbi(), msaId, os);
740 CHECK_NO_ERROR(os);
741 Q_UNUSED(userStep);
742
743 SQLiteObjectDbiTestData::addTestRow(msaId, os);
744 CHECK_NO_ERROR(os);
745 }
746
747 // Check there is no obsolete steps
748 SQLiteReadQuery qUser("SELECT COUNT(*) FROM UserModStep WHERE object = ?1", sqliteDbi->getDbRef(), os);
749 qUser.bindDataId(1, msaId);
750 if (qUser.step()) {
751 CHECK_EQUAL(1, qUser.getInt64(0), "number of user steps");
752 } else {
753 CHECK_TRUE(false, "Unexpected error!");
754 }
755 CHECK_NO_ERROR(os);
756
757 SQLiteReadQuery qSingle("SELECT COUNT(*) FROM SingleModStep WHERE object = ?1", sqliteDbi->getDbRef(), os);
758 qSingle.bindDataId(1, msaId);
759 if (qSingle.step()) {
760 CHECK_EQUAL(1, qSingle.getInt64(0), "number of single steps");
761 } else {
762 CHECK_TRUE(false, "Unexpected error!");
763 }
764 CHECK_NO_ERROR(os);
765
766 // Undo
767 objDbi->undo(msaId, os);
768 CHECK_NO_ERROR(os);
769
770 // Verify msa version
771 qint64 msaVersionAfter = objDbi->getObjectVersion(msaId, os);
772 CHECK_NO_ERROR(os);
773 CHECK_EQUAL(msaVersion, msaVersionAfter, "msa version after action, undo, action, undo");
774
775 // Verify canUndo/canRedo
776 bool undoState = objDbi->canUndo(msaId, os);
777 CHECK_NO_ERROR(os);
778 bool redoState = objDbi->canRedo(msaId, os);
779 CHECK_NO_ERROR(os);
780 CHECK_FALSE(undoState, "undo state after undo, action and undo/redo");
781 CHECK_TRUE(redoState, "redo state after undo, action and undo/redo");
782 }
783
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,commonUndoRedo_actionUndoActionUndo2)784 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, commonUndoRedo_actionUndoActionUndo2) {
785 U2OpStatusImpl os;
786 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
787 SQLiteDbi *sqliteDbi = SQLiteObjectDbiTestData::getSQLiteDbi();
788
789 // Create test msa
790 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
791 CHECK_NO_ERROR(os);
792
793 // Get msa version
794 qint64 msaVersion = objDbi->getObjectVersion(msaId, os);
795 CHECK_NO_ERROR(os);
796
797 // Do an action
798 SQLiteObjectDbiTestData::addTestRow(msaId, os);
799
800 // Undo
801 objDbi->undo(msaId, os);
802 CHECK_NO_ERROR(os);
803
804 // Do an action
805 SQLiteObjectDbiTestData::addTestRow(msaId, os);
806
807 // Check there is no obsolete steps
808 SQLiteReadQuery qUser("SELECT COUNT(*) FROM UserModStep WHERE object = ?1", sqliteDbi->getDbRef(), os);
809 qUser.bindDataId(1, msaId);
810 if (qUser.step()) {
811 CHECK_EQUAL(1, qUser.getInt64(0), "number of user steps");
812 } else {
813 CHECK_TRUE(false, "Unexpected error!");
814 }
815 CHECK_NO_ERROR(os);
816
817 SQLiteReadQuery qSingle("SELECT COUNT(*) FROM SingleModStep WHERE object = ?1", sqliteDbi->getDbRef(), os);
818 qSingle.bindDataId(1, msaId);
819 if (qSingle.step()) {
820 CHECK_EQUAL(1, qSingle.getInt64(0), "number of single steps");
821 } else {
822 CHECK_TRUE(false, "Unexpected error!");
823 }
824 CHECK_NO_ERROR(os);
825
826 // Undo
827 objDbi->undo(msaId, os);
828 CHECK_NO_ERROR(os);
829
830 // Verify msa version
831 qint64 msaVersionAfter = objDbi->getObjectVersion(msaId, os);
832 CHECK_NO_ERROR(os);
833 CHECK_EQUAL(msaVersion, msaVersionAfter, "msa version after action, undo, action, undo");
834
835 // Verify canUndo/canRedo
836 bool undoState = objDbi->canUndo(msaId, os);
837 CHECK_NO_ERROR(os);
838 bool redoState = objDbi->canRedo(msaId, os);
839 CHECK_NO_ERROR(os);
840 CHECK_FALSE(undoState, "undo state after undo, action and undo/redo");
841 CHECK_TRUE(redoState, "redo state after undo, action and undo/redo");
842 }
843
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,commonUndoRedo_actionUndoActionUndo3)844 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, commonUndoRedo_actionUndoActionUndo3) {
845 U2OpStatusImpl os;
846 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
847 SQLiteDbi *sqliteDbi = SQLiteObjectDbiTestData::getSQLiteDbi();
848
849 // Create test msa
850 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
851 CHECK_NO_ERROR(os);
852
853 // Get msa version
854 qint64 msaVersion = objDbi->getObjectVersion(msaId, os);
855 CHECK_NO_ERROR(os);
856
857 // Do an action
858 SQLiteObjectDbiTestData::addTestRow(msaId, os);
859
860 // Undo
861 objDbi->undo(msaId, os);
862 CHECK_NO_ERROR(os);
863
864 // Do an action
865 {
866 U2UseCommonUserModStep userStep(objDbi->getRootDbi(), msaId, os);
867 CHECK_NO_ERROR(os);
868 Q_UNUSED(userStep);
869
870 SQLiteObjectDbiTestData::addTestRow(msaId, os);
871 CHECK_NO_ERROR(os);
872 }
873
874 // Check there is no obsolete steps
875 SQLiteReadQuery qUser("SELECT COUNT(*) FROM UserModStep WHERE object = ?1", sqliteDbi->getDbRef(), os);
876 qUser.bindDataId(1, msaId);
877 if (qUser.step()) {
878 CHECK_EQUAL(1, qUser.getInt64(0), "number of user steps");
879 } else {
880 CHECK_TRUE(false, "Unexpected error!");
881 }
882 CHECK_NO_ERROR(os);
883
884 SQLiteReadQuery qSingle("SELECT COUNT(*) FROM SingleModStep WHERE object = ?1", sqliteDbi->getDbRef(), os);
885 qSingle.bindDataId(1, msaId);
886 if (qSingle.step()) {
887 CHECK_EQUAL(1, qSingle.getInt64(0), "number of single steps");
888 } else {
889 CHECK_TRUE(false, "Unexpected error!");
890 }
891 CHECK_NO_ERROR(os);
892
893 // Undo
894 objDbi->undo(msaId, os);
895 CHECK_NO_ERROR(os);
896
897 // Verify msa version
898 qint64 msaVersionAfter = objDbi->getObjectVersion(msaId, os);
899 CHECK_NO_ERROR(os);
900 CHECK_EQUAL(msaVersion, msaVersionAfter, "msa version after action, undo, action, undo");
901
902 // Verify canUndo/canRedo
903 bool undoState = objDbi->canUndo(msaId, os);
904 CHECK_NO_ERROR(os);
905 bool redoState = objDbi->canRedo(msaId, os);
906 CHECK_NO_ERROR(os);
907 CHECK_FALSE(undoState, "undo state after undo, action and undo/redo");
908 CHECK_TRUE(redoState, "redo state after undo, action and undo/redo");
909 }
910
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,commonUndoRedo_actionUndoActionUndo4)911 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, commonUndoRedo_actionUndoActionUndo4) {
912 U2OpStatusImpl os;
913 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
914 SQLiteDbi *sqliteDbi = SQLiteObjectDbiTestData::getSQLiteDbi();
915
916 // Create test msa
917 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
918 CHECK_NO_ERROR(os);
919
920 // Get msa version
921 qint64 msaVersion = objDbi->getObjectVersion(msaId, os);
922 CHECK_NO_ERROR(os);
923
924 // Do an action
925 {
926 U2UseCommonUserModStep userStep(objDbi->getRootDbi(), msaId, os);
927 CHECK_NO_ERROR(os);
928 Q_UNUSED(userStep);
929
930 SQLiteObjectDbiTestData::addTestRow(msaId, os);
931 CHECK_NO_ERROR(os);
932 }
933
934 // Undo
935 objDbi->undo(msaId, os);
936 CHECK_NO_ERROR(os);
937
938 // Do an action
939 SQLiteObjectDbiTestData::addTestRow(msaId, os);
940
941 // Check there is no obsolete steps
942 SQLiteReadQuery qUser("SELECT COUNT(*) FROM UserModStep WHERE object = ?1", sqliteDbi->getDbRef(), os);
943 qUser.bindDataId(1, msaId);
944 if (qUser.step()) {
945 CHECK_EQUAL(1, qUser.getInt64(0), "number of user steps");
946 } else {
947 CHECK_TRUE(false, "Unexpected error!");
948 }
949 CHECK_NO_ERROR(os);
950
951 SQLiteReadQuery qSingle("SELECT COUNT(*) FROM SingleModStep WHERE object = ?1", sqliteDbi->getDbRef(), os);
952 qSingle.bindDataId(1, msaId);
953 if (qSingle.step()) {
954 CHECK_EQUAL(1, qSingle.getInt64(0), "number of single steps");
955 } else {
956 CHECK_TRUE(false, "Unexpected error!");
957 }
958 CHECK_NO_ERROR(os);
959
960 // Undo
961 objDbi->undo(msaId, os);
962 CHECK_NO_ERROR(os);
963
964 // Verify msa version
965 qint64 msaVersionAfter = objDbi->getObjectVersion(msaId, os);
966 CHECK_NO_ERROR(os);
967 CHECK_EQUAL(msaVersion, msaVersionAfter, "msa version after action, undo, action, undo");
968
969 // Verify canUndo/canRedo
970 bool undoState = objDbi->canUndo(msaId, os);
971 CHECK_NO_ERROR(os);
972 bool redoState = objDbi->canRedo(msaId, os);
973 CHECK_NO_ERROR(os);
974 CHECK_FALSE(undoState, "undo state after undo, action and undo/redo");
975 CHECK_TRUE(redoState, "redo state after undo, action and undo/redo");
976 }
977
IMPLEMENT_TEST(SQLiteObjectDbiUnitTests,commonUndoRedo_user3Single6)978 IMPLEMENT_TEST(SQLiteObjectDbiUnitTests, commonUndoRedo_user3Single6) {
979 U2OpStatusImpl os;
980 U2ObjectDbi *objDbi = SQLiteObjectDbiTestData::getSQLiteObjectDbi();
981 SQLiteDbi *sqliteDbi = SQLiteObjectDbiTestData::getSQLiteDbi();
982
983 // Create test msa
984 U2DataId msaId = SQLiteObjectDbiTestData::createTestMsa(true, os);
985 CHECK_NO_ERROR(os);
986
987 // Get msa version
988 qint64 msaVersion = objDbi->getObjectVersion(msaId, os);
989 CHECK_NO_ERROR(os);
990
991 // User step 1
992 {
993 U2UseCommonUserModStep userStep(objDbi->getRootDbi(), msaId, os);
994 CHECK_NO_ERROR(os);
995 Q_UNUSED(userStep);
996
997 SQLiteObjectDbiTestData::addTestRow(msaId, os); // multi/single step 1
998 CHECK_NO_ERROR(os);
999
1000 SQLiteObjectDbiTestData::addTestRow(msaId, os); // multi/single step 2
1001 CHECK_NO_ERROR(os);
1002 }
1003
1004 // User step 2
1005 SQLiteObjectDbiTestData::addTestRow(msaId, os); // multi/single step 3
1006
1007 // Verify version
1008 qint64 msaVersionAfterUser1 = msaVersion + 2; // verified in another test
1009 qint64 msaVersionAfterUser2 = objDbi->getObjectVersion(msaId, os);
1010 CHECK_NO_ERROR(os);
1011 CHECK_EQUAL(msaVersionAfterUser1 + 1, msaVersionAfterUser2, "msa version after user step 2");
1012
1013 // Verify canUndo/canRedo
1014 bool undoState = objDbi->canUndo(msaId, os);
1015 CHECK_NO_ERROR(os);
1016 bool redoState = objDbi->canRedo(msaId, os);
1017 CHECK_NO_ERROR(os);
1018 CHECK_TRUE(undoState, "undo state after user step 2");
1019 CHECK_FALSE(redoState, "redo state after user step 2");
1020
1021 // User step 3
1022 U2Sequence seq;
1023 seq.alphabet = BaseDNAAlphabetIds::NUCL_DNA_DEFAULT();
1024 seq.circular = false;
1025 seq.trackModType = NoTrack;
1026 seq.visualName = "Test sequence";
1027 sqliteDbi->getSQLiteSequenceDbi()->createSequenceObject(seq, "", os, U2DbiObjectRank_TopLevel);
1028 CHECK_NO_ERROR(os);
1029
1030 U2MsaRow row;
1031 row.sequenceId = seq.id;
1032 row.gstart = 0;
1033 row.gend = 0;
1034 row.length = 0;
1035
1036 {
1037 U2UseCommonUserModStep userStep(objDbi->getRootDbi(), msaId, os);
1038 CHECK_NO_ERROR(os);
1039 Q_UNUSED(userStep);
1040
1041 sqliteDbi->getMsaDbi()->addRow(msaId, -1, row, os); // multi/single step 4
1042 CHECK_NO_ERROR(os);
1043
1044 sqliteDbi->getMsaDbi()->updateRowContent(msaId, row.rowId, "ACGT", QList<U2MsaGap>(), os); // multi step 5, single steps 5-6
1045 CHECK_NO_ERROR(os);
1046 }
1047
1048 // Verify version
1049 qint64 msaVersionAfterUser3 = objDbi->getObjectVersion(msaId, os);
1050 CHECK_NO_ERROR(os);
1051 CHECK_EQUAL(msaVersionAfterUser2 + 2, msaVersionAfterUser3, "msa version after user step 3");
1052
1053 // Verify canUndo/canRedo
1054 undoState = objDbi->canUndo(msaId, os);
1055 CHECK_NO_ERROR(os);
1056 redoState = objDbi->canRedo(msaId, os);
1057 CHECK_NO_ERROR(os);
1058 CHECK_TRUE(undoState, "undo state after user step 3");
1059 CHECK_FALSE(redoState, "redo state after user step 3");
1060
1061 // Undo 1 (to user step 2)
1062 objDbi->undo(msaId, os);
1063 CHECK_NO_ERROR(os);
1064
1065 // Verify version
1066 qint64 msaVersionAfterUndo1 = objDbi->getObjectVersion(msaId, os);
1067 CHECK_NO_ERROR(os);
1068 CHECK_EQUAL(msaVersionAfterUser2, msaVersionAfterUndo1, "msa version after undo 1");
1069
1070 // Verify canUndo/canRedo
1071 undoState = objDbi->canUndo(msaId, os);
1072 CHECK_NO_ERROR(os);
1073 redoState = objDbi->canRedo(msaId, os);
1074 CHECK_NO_ERROR(os);
1075 CHECK_TRUE(undoState, "undo state after undo 1");
1076 CHECK_TRUE(redoState, "redo state after undo 1");
1077
1078 // Undo 2 (to user step 1)
1079 objDbi->undo(msaId, os);
1080 CHECK_NO_ERROR(os);
1081
1082 // Verify version
1083 qint64 msaVersionAfterUndo2 = objDbi->getObjectVersion(msaId, os);
1084 CHECK_NO_ERROR(os);
1085 CHECK_EQUAL(msaVersionAfterUser1, msaVersionAfterUndo2, "msa version after undo 2");
1086
1087 // Verify canUndo/canRedo
1088 undoState = objDbi->canUndo(msaId, os);
1089 CHECK_NO_ERROR(os);
1090 redoState = objDbi->canRedo(msaId, os);
1091 CHECK_NO_ERROR(os);
1092 CHECK_TRUE(undoState, "undo state after undo 2");
1093 CHECK_TRUE(redoState, "redo state after undo 2");
1094
1095 // Undo 3 (to original)
1096 objDbi->undo(msaId, os);
1097 CHECK_NO_ERROR(os);
1098
1099 // Verify version
1100 qint64 msaVersionAfterUndo3 = objDbi->getObjectVersion(msaId, os);
1101 CHECK_NO_ERROR(os);
1102 CHECK_EQUAL(msaVersion, msaVersionAfterUndo3, "msa version after undo 3");
1103
1104 // Verify canUndo/canRedo
1105 undoState = objDbi->canUndo(msaId, os);
1106 CHECK_NO_ERROR(os);
1107 redoState = objDbi->canRedo(msaId, os);
1108 CHECK_NO_ERROR(os);
1109 CHECK_FALSE(undoState, "undo state after undo 3");
1110 CHECK_TRUE(redoState, "redo state after undo 3");
1111
1112 // Redo 1 (to user step 1)
1113 objDbi->redo(msaId, os);
1114 CHECK_NO_ERROR(os);
1115
1116 // Verify version
1117 qint64 msaVersionAfterRedo1 = objDbi->getObjectVersion(msaId, os);
1118 CHECK_NO_ERROR(os);
1119 CHECK_EQUAL(msaVersionAfterUser1, msaVersionAfterRedo1, "msa version after redo 1");
1120
1121 // Verify canUndo/canRedo
1122 undoState = objDbi->canUndo(msaId, os);
1123 CHECK_NO_ERROR(os);
1124 redoState = objDbi->canRedo(msaId, os);
1125 CHECK_NO_ERROR(os);
1126 CHECK_TRUE(undoState, "undo state after redo 1");
1127 CHECK_TRUE(redoState, "redo state after redo 1");
1128
1129 // Redo 2 (to user step 2)
1130 objDbi->redo(msaId, os);
1131 CHECK_NO_ERROR(os);
1132
1133 // Verify version
1134 qint64 msaVersionAfterRedo2 = objDbi->getObjectVersion(msaId, os);
1135 CHECK_NO_ERROR(os);
1136 CHECK_EQUAL(msaVersionAfterUser2, msaVersionAfterRedo2, "msa version after redo 2");
1137
1138 // Verify canUndo/canRedo
1139 undoState = objDbi->canUndo(msaId, os);
1140 CHECK_NO_ERROR(os);
1141 redoState = objDbi->canRedo(msaId, os);
1142 CHECK_NO_ERROR(os);
1143 CHECK_TRUE(undoState, "undo state after redo 2");
1144 CHECK_TRUE(redoState, "redo state after redo 2");
1145
1146 // Redo 3 (to user step 3)
1147 objDbi->redo(msaId, os);
1148 CHECK_NO_ERROR(os);
1149
1150 // Verify version
1151 qint64 msaVersionAfterRedo3 = objDbi->getObjectVersion(msaId, os);
1152 CHECK_NO_ERROR(os);
1153 CHECK_EQUAL(msaVersionAfterUser3, msaVersionAfterRedo3, "msa version after redo 3");
1154
1155 // Verify canUndo/canRedo
1156 undoState = objDbi->canUndo(msaId, os);
1157 CHECK_NO_ERROR(os);
1158 redoState = objDbi->canRedo(msaId, os);
1159 CHECK_NO_ERROR(os);
1160 CHECK_TRUE(undoState, "undo state after redo 3");
1161 CHECK_FALSE(redoState, "redo state after redo 3");
1162 }
1163
1164 } // namespace U2
1165