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 "AssemblyObject.h"
23
24 #include <U2Core/AssemblyImporter.h>
25 #include <U2Core/DocumentModel.h>
26 #include <U2Core/GHints.h>
27 #include <U2Core/U2AssemblyDbi.h>
28 #include <U2Core/U2AttributeDbi.h>
29 #include <U2Core/U2AttributeUtils.h>
30 #include <U2Core/U2CoreAttributes.h>
31 #include <U2Core/U2DbiUtils.h>
32 #include <U2Core/U2ObjectDbi.h>
33 #include <U2Core/U2OpStatus.h>
34 #include <U2Core/U2OpStatusUtils.h>
35 #include <U2Core/U2SafePoints.h>
36
37 namespace U2 {
38
AssemblyObject(const QString & objectName,const U2EntityRef & ref,const QVariantMap & hints)39 AssemblyObject::AssemblyObject(const QString &objectName, const U2EntityRef &ref, const QVariantMap &hints)
40 : GObject(GObjectTypes::ASSEMBLY, objectName, hints) {
41 this->entityRef = ref;
42 }
43
clone(const U2DbiRef & dstDbiRef,U2OpStatus & os,const QVariantMap & hints) const44 GObject *AssemblyObject::clone(const U2DbiRef &dstDbiRef, U2OpStatus &os, const QVariantMap &hints) const {
45 GHintsDefaultImpl gHints(getGHintsMap());
46 gHints.setAll(hints);
47
48 U2EntityRef dstEntityRef = AssemblyObject::dbi2dbiClone(this, dstDbiRef, os, gHints.getMap());
49 CHECK_OP(os, nullptr);
50 AssemblyObject *dstObj = new AssemblyObject(this->getGObjectName(), dstEntityRef, gHints.getMap());
51
52 return dstObj;
53 }
54
55 class CloneInfo : public U2AssemblyReadsImportInfo {
56 public:
CloneInfo(qint64 readsCount,U2OpStatus & os)57 CloneInfo(qint64 readsCount, U2OpStatus &os)
58 : U2AssemblyReadsImportInfo(nullptr), os(os), readsCount(readsCount), addedCount(0), currentChunkSize(0) {
59 chunkSize = readsCount / 100;
60 }
61
onReadImported()62 void onReadImported() {
63 addedCount++;
64 currentChunkSize++;
65 if (currentChunkSize >= chunkSize) {
66 os.setProgress(100 * addedCount / readsCount);
67 currentChunkSize = 0;
68 }
69 }
70
71 private:
72 U2OpStatus &os;
73 qint64 readsCount;
74 qint64 addedCount;
75 qint64 currentChunkSize;
76 qint64 chunkSize;
77 };
78
copyReadsUnrelatedAttributes(const U2DataId & srcObjId,const U2DataId & dstObjId,U2AttributeDbi * srcAttributeDbi,U2AttributeDbi * dstAttributeDbi,U2OpStatus & os)79 void copyReadsUnrelatedAttributes(const U2DataId &srcObjId, const U2DataId &dstObjId, U2AttributeDbi *srcAttributeDbi, U2AttributeDbi *dstAttributeDbi, U2OpStatus &os) {
80 CHECK_EXT(nullptr != srcAttributeDbi, os.setError("NULL source attribute dbi"), );
81 CHECK_EXT(nullptr != dstAttributeDbi, os.setError("NULL destination attribute dbi"), );
82
83 U2Dbi *dstDbi = dstAttributeDbi->getRootDbi();
84 U2Dbi *srcDbi = srcAttributeDbi->getRootDbi();
85 CHECK_EXT(nullptr != srcDbi, os.setError("NULL source root dbi"), );
86 CHECK_EXT(nullptr != dstDbi, os.setError("NULL destination root dbi"), );
87
88 if (!dstDbi->getFeatures().contains(U2DbiFeature_WriteAttributes)) {
89 os.setError("Destination dbi does not support writing");
90 return;
91 }
92
93 const QStringList attributesNotToCopy = U2BaseAttributeName::getReadsRelatedAttributes();
94
95 QList<U2DataId> attrIds = srcAttributeDbi->getObjectAttributes(srcObjId, "", os);
96 CHECK_OP(os, );
97
98 foreach (const U2DataId &attrId, attrIds) {
99 U2DataType attrType = srcDbi->getEntityTypeById(attrId);
100 if (U2Type::AttributeInteger == attrType) {
101 U2IntegerAttribute attr = srcAttributeDbi->getIntegerAttribute(attrId, os);
102 CHECK_OP(os, );
103 if (attributesNotToCopy.contains(attr.name)) {
104 continue;
105 }
106 attr.objectId = dstObjId;
107 dstAttributeDbi->createIntegerAttribute(attr, os);
108 } else if (U2Type::AttributeReal == attrType) {
109 U2RealAttribute attr = srcAttributeDbi->getRealAttribute(attrId, os);
110 CHECK_OP(os, );
111 if (attributesNotToCopy.contains(attr.name)) {
112 continue;
113 }
114 attr.objectId = dstObjId;
115 dstAttributeDbi->createRealAttribute(attr, os);
116 } else if (U2Type::AttributeString == attrType) {
117 U2StringAttribute attr = srcAttributeDbi->getStringAttribute(attrId, os);
118 CHECK_OP(os, );
119 if (attributesNotToCopy.contains(attr.name)) {
120 continue;
121 }
122 attr.objectId = dstObjId;
123 dstAttributeDbi->createStringAttribute(attr, os);
124 } else if (U2Type::AttributeByteArray == attrType) {
125 U2ByteArrayAttribute attr = srcAttributeDbi->getByteArrayAttribute(attrId, os);
126 CHECK_OP(os, );
127 if (attributesNotToCopy.contains(attr.name)) {
128 continue;
129 }
130 attr.objectId = dstObjId;
131 dstAttributeDbi->createByteArrayAttribute(attr, os);
132 }
133 CHECK_OP(os, );
134 }
135 }
136
dbi2dbiExtractRegion(const AssemblyObject * const srcObj,const U2DbiRef & dstDbiRef,U2OpStatus & os,const U2Region & desiredRegion,const QVariantMap & hints)137 U2EntityRef AssemblyObject::dbi2dbiExtractRegion(const AssemblyObject *const srcObj, const U2DbiRef &dstDbiRef, U2OpStatus &os, const U2Region &desiredRegion, const QVariantMap &hints) {
138 U2DbiRef srcDbiRef = srcObj->getEntityRef().dbiRef;
139 U2DataId srcObjId = srcObj->getEntityRef().entityId;
140 const QString dstFolder = hints.value(DocumentFormat::DBI_FOLDER_HINT, U2ObjectDbi::ROOT_FOLDER).toString();
141
142 DbiConnection dstCon(dstDbiRef, true, os);
143 CHECK_OP(os, U2EntityRef());
144 DbiConnection srcCon(srcDbiRef, os);
145 CHECK_OP(os, U2EntityRef());
146
147 U2ObjectDbi *dstObjectDbi = dstCon.dbi->getObjectDbi();
148 U2ObjectDbi *srcObjectDbi = srcCon.dbi->getObjectDbi();
149 SAFE_POINT_EXT(nullptr != dstObjectDbi, os.setError("NULL destination object dbi"), U2EntityRef());
150 SAFE_POINT_EXT(nullptr != srcObjectDbi, os.setError("NULL source object dbi"), U2EntityRef());
151
152 U2AssemblyDbi *dstAssemblyDbi = dstCon.dbi->getAssemblyDbi();
153 U2AssemblyDbi *srcAssemblyDbi = srcCon.dbi->getAssemblyDbi();
154 SAFE_POINT_EXT(nullptr != dstAssemblyDbi, os.setError("NULL destination assembly dbi"), U2EntityRef());
155 SAFE_POINT_EXT(nullptr != srcAssemblyDbi, os.setError("NULL source assembly dbi"), U2EntityRef());
156
157 // prepare reads
158 CHECK_OP(os, U2EntityRef());
159 qint64 readsCount = srcAssemblyDbi->countReads(srcObjId, desiredRegion, os);
160 CHECK_OP(os, U2EntityRef());
161 U2DbiIterator<U2AssemblyRead> *iter = srcAssemblyDbi->getReads(srcObjId, desiredRegion, os, true);
162 QScopedPointer<U2DbiIterator<U2AssemblyRead>> iterPtr(iter);
163 CHECK_OP(os, U2EntityRef());
164 Q_UNUSED(iterPtr);
165
166 // copy object
167 U2Assembly assembly;
168 assembly.visualName = srcObj->getGObjectName();
169 CloneInfo info(readsCount, os);
170
171 AssemblyImporter importer(os);
172 importer.createAssembly(dstDbiRef, dstFolder, iter, info, assembly);
173 CHECK_OP(os, U2EntityRef());
174
175 // copy attributes
176 U2AttributeDbi *srcAttributeDbi = srcCon.dbi->getAttributeDbi();
177 U2AttributeDbi *dstAttributeDbi = dstCon.dbi->getAttributeDbi();
178 if (desiredRegion == U2_REGION_MAX) {
179 U2AttributeUtils::copyObjectAttributes(srcObjId, assembly.id, srcAttributeDbi, dstAttributeDbi, os);
180 } else {
181 copyReadsUnrelatedAttributes(srcObjId, assembly.id, srcAttributeDbi, dstAttributeDbi, os);
182 }
183 CHECK_OP(os, U2EntityRef());
184
185 U2EntityRef dstEntityRef(dstDbiRef, assembly.id);
186
187 return dstEntityRef;
188 }
189
dbi2dbiClone(const AssemblyObject * const srcObj,const U2DbiRef & dstDbiRef,U2OpStatus & os,const QVariantMap & hints)190 U2EntityRef AssemblyObject::dbi2dbiClone(const AssemblyObject *const srcObj, const U2DbiRef &dstDbiRef, U2OpStatus &os, const QVariantMap &hints) {
191 return dbi2dbiExtractRegion(srcObj, dstDbiRef, os, U2_REGION_MAX, hints);
192 }
193
194 } // namespace U2
195