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 #ifndef _U2_DBI_H_
23 #define _U2_DBI_H_
24 
25 #include <QHash>
26 #include <QSet>
27 
28 #include <U2Core/GUrl.h>
29 #include <U2Core/U2Assembly.h>
30 #include <U2Core/U2Feature.h>
31 #include <U2Core/U2FormatCheckResult.h>
32 #include <U2Core/U2Mod.h>
33 #include <U2Core/U2Msa.h>
34 
35 class QMutex;
36 
37 namespace U2 {
38 
39 // For the classes below, see description in class definition
40 class U2AssemblyDbi;
41 class U2AttributeDbi;
42 class U2CrossDatabaseReferenceDbi;
43 class U2Dbi;
44 class U2FeatureDbi;
45 class U2ModDbi;
46 class U2MsaDbi;
47 class U2ObjectDbi;
48 class U2ObjectRelationsDbi;
49 class U2OpStatus;
50 class U2SequenceDbi;
51 class U2VariantDbi;
52 class UdrDbi;
53 class Version;
54 
55 class U2CORE_EXPORT U2DbiOptions {
56 public:
57     /** Application version number that is supposed to be minimum version required to make use of the database */
58     static const QString APP_MIN_COMPATIBLE_VERSION;
59 
60     /** A constant to retrieve all available data. */
61     static const int U2_DBI_NO_LIMIT;
62 
63     /** Init time DBI parameter name to specify URL of the database */
64     static const QString U2_DBI_OPTION_URL;
65 
66     /** Init time DBI parameter name to specify that database must be created if not exists */
67     static const QString U2_DBI_OPTION_CREATE;
68 
69     /** Init time DBI parameter name to specify user password for the database. */
70     static const QString U2_DBI_OPTION_PASSWORD;
71 
72     /** Init time DBI parameter value. Indicates boolean 'Yes' or 'true'. */
73     static const QString U2_DBI_VALUE_ON;
74 
75     /** SQLite only: "exclusive" (default) or "normal" mode. */
76     static const QString U2_DBI_LOCKING_MODE;
77 };
78 
79 /**
80     Operational state of the database.
81     */
82 enum U2DbiState {
83     U2DbiState_Void = 1,
84     U2DbiState_Starting = 2,
85     U2DbiState_Ready = 3,
86     U2DbiState_Stopping = 4
87 };
88 
89 /**
90     DBI feature flags
91     */
92 enum U2DbiFeature {
93 
94     /** DBI supports sequence reading methods */
95     U2DbiFeature_ReadSequence = 1,
96     /** DBI supports MSA reading methods */
97     U2DbiFeature_ReadMsa = 2,
98     /** DBI supports Assembly reading methods */
99     U2DbiFeature_ReadAssembly = 3,
100     /** DBI supports sequence annotations reading methods */
101     U2DbiFeature_ReadFeatures = 4,
102     /** DBI supports read methods for attributes */
103     U2DbiFeature_ReadAttributes = 5,
104     /** DBI supports read methods for remote objects  */
105     U2DbiFeature_ReadCrossDatabaseReferences = 6,
106     /** DBI supports readings Variants and VariantTracks */
107     U2DbiFeature_ReadVariant = 7,
108     /** DBI supports readings of custom properties */
109     U2DbiFeature_ReadProperties = 8,
110     /** DBI supports reading of objects modification tracks */
111     U2DbiFeature_ReadModifications = 9,
112     /** DBI supports UDR reading methods */
113     U2DbiFeature_ReadUdr = 10,
114     /** DBI supports reading of object relations */
115     U2DbiFeature_ReadRelations = 11,
116 
117     /** DBI supports changing/storing sequences */
118     U2DbiFeature_WriteSequence = 101,
119     /** DBI supports changing/storing multiple sequence alignments */
120     U2DbiFeature_WriteMsa = 102,
121     /** DBI supports changing/storing assemblies */
122     U2DbiFeature_WriteAssembly = 103
123     /** DBI supports changing/storing sequence annotations */,
124     U2DbiFeature_WriteFeatures = 104,
125     /** DBI supports changing/storing attributes */
126     U2DbiFeature_WriteAttributes = 105,
127     /** DBI supports cross database references */
128     U2DbiFeature_WriteCrossDatabaseReferences = 106,
129     /** DBI supports changing/storing Variants and VariantTracks */
130     U2DbiFeature_WriteVariant = 107,
131     /** DBI supports changing/storing custom properties */
132     U2DbiFeature_WriteProperties = 108,
133     /** DBI supports changing/storing of objects modification tracks */
134     U2DbiFeature_WriteModifications = 109,
135     /** DBI supports changing/storing UDR */
136     U2DbiFeature_WriteUdr = 110,
137     /** DBI supports writing of object relations */
138     U2DbiFeature_WriteRelations = 111,
139 
140     /** DBI supports removal of objects */
141     U2DbiFeature_RemoveObjects = 200,
142     /** DBI supports set folder modification operations */
143     U2DbiFeature_ChangeFolders = 201,
144 
145     /** DBI provides optimized algorithm for assembly reads packing */
146     U2DbiFeature_AssemblyReadsPacking = 300,
147     /** DBI provides optimized algorithm for coverage calculation */
148     U2DbiFeature_AssemblyCoverageStat = 301,
149 
150     /** DBI provides optimized algorithm for sorting attributes */
151     U2DbiFeature_AttributeSorting = 400,
152 
153     /** DBI supports undo/redo of changing operations */
154     U2DbiFeature_UndoRedo = 500,
155 
156     U2DbiFeature_GlobalReadOnly = 600
157 };
158 
159 /** Indicates object life-cycle and storage location */
160 enum U2DbiObjectRank {
161     /** Object  is stored in this database and is top-level (included into some folder) */
162     U2DbiObjectRank_TopLevel = 1,
163     /** Object  is stored in this database and is not top-level, it is a child of another object */
164     U2DbiObjectRank_Child = 2,
165     /** Object  is stored in another database, see CrossDbiReference table for details */
166     U2DbiObjectRank_Remote = 3
167 };
168 
169 /**
170     DBI factory provides functions to create new DBI instances
171     and check file content to ensure that file is a valid database file
172     */
173 class U2CORE_EXPORT U2DbiFactory {
174 public:
175     U2DbiFactory();
176     virtual ~U2DbiFactory();
177 
178     /** Creates new DBI instance */
179     virtual U2Dbi *createDbi() = 0;
180 
181     /** Returns DBI type ID */
182     virtual U2DbiFactoryId getId() const = 0;
183 
184     /**
185         Checks that data pointed by properties is a valid DBI resource
186         rawData param is used for compatibility with UGENE 1.x format detection
187         and can be used by factory directly to check database header
188         */
189     virtual FormatCheckResult isValidDbi(const QHash<QString, QString> &properties, const QByteArray &rawData, U2OpStatus &os) const = 0;
190 
191     virtual GUrl id2Url(const U2DbiId &id) const = 0;
192 
193     virtual bool isDbiExists(const U2DbiId &id) const = 0;
194 };
195 
196 /**
197     Database access interface.
198     Database examples: fasta file, genbank file, BAM file, SQLite file
199     */
200 class U2CORE_EXPORT U2Dbi {
201 public:
202     virtual ~U2Dbi();
203     //////////////////////////////////////////////////////////////////////////
204     // base methods that any DBI must support
205 
206     /**
207         Boots the database up to functional state.
208         Some property names are reserved:
209         'url' - url of the DBI
210         'create'  - '1' or '0'- if DBI does not exist, asks to create instance if possible
211         'user', 'password' - user and password to access to the DBI
212         The 'persistentData' parameter provides database state saved from previous session in a project or workspace, if any.
213 
214         @see shutdown()
215         */
216     virtual void init(const QHash<QString, QString> &properties, const QVariantMap &persistentData, U2OpStatus &os) = 0;
217 
218     /** Stops the database and frees up used resources.
219     Returns persistent database state for external storage in a project or workspace, if any.
220     For example, plain-file-based DBI can store certain settings or preferences between sessions,
221     which may not fit into particular file format.
222 
223     Note: this method will call flush()
224     @see init()
225     */
226     virtual QVariantMap shutdown(U2OpStatus &os) = 0;
227 
228     /**
229         Ensures that dbi state is synchronized with storage
230         Return 'true' of operation is successful
231         */
232     virtual bool flush(U2OpStatus &os) = 0;
233 
234     /**  Unique database id. Usually is an URL of the database */
235     virtual U2DbiId getDbiId() const = 0;
236 
237     /** Return factory instance for this DBI */
238     virtual U2DbiFactoryId getFactoryId() const = 0;
239 
240     virtual U2DbiRef getDbiRef() const;
241 
242     /** Returning result specifies whether the database internal structure is ready for work,
243         namely, the database schema is created correctly.
244         */
245     virtual bool isInitialized(U2OpStatus &);
246 
247     /** Performs initialization of the database schema. The database is supposed to be available
248         for use after this function returns if @os has no error.
249         */
250     virtual void populateDefaultSchema(U2OpStatus &os);
251 
252     /** Returns all features supported by this DBI instance */
253     virtual const QSet<U2DbiFeature> &getFeatures() const = 0;
254 
255     /** Returns properties used to initialize the database */
256     virtual QHash<QString, QString> getInitProperties() const = 0;
257 
258     /** Returns database meta-info. Any set of properties to be shown to user */
259     virtual QHash<QString, QString> getDbiMetaInfo(U2OpStatus &) = 0;
260 
261     /** Returns type of the entity referenced by the given ID */
262     virtual U2DataType getEntityTypeById(const U2DataId &id) const = 0;
263 
264     /** Returns current DBI state */
265     virtual U2DbiState getState() const = 0;
266 
267     /**
268         Database interface to access objects
269         All dbi implementations must support a subset of this interface
270         */
271     virtual U2ObjectDbi *getObjectDbi() = 0;
272 
273     /**
274         Database interface to access object relations.
275         */
276     virtual U2ObjectRelationsDbi *getObjectRelationsDbi();
277 
278     /**
279         U2Sequence related DBI routines
280         Not NULL only if U2DbiFeature_ReadSequences supported
281         */
282     virtual U2SequenceDbi *getSequenceDbi() = 0;
283 
284     /**
285         U2Feature related DBI routines
286         Not NULL only if U2DbiFeature_ReadFeatures supported
287         */
288     virtual U2FeatureDbi *getFeatureDbi() = 0;
289 
290     /**
291         U2Annotation related DBI routines
292         Not NULL only if U2DbiFeature_ReadMsa supported
293         */
294     virtual U2MsaDbi *getMsaDbi() = 0;
295 
296     /**
297         U2Annotation related DBI routines
298         Not NULL only if U2DbiFeature_ReadAssembly supported
299         */
300     virtual U2AssemblyDbi *getAssemblyDbi() = 0;
301 
302     /**
303         U2Attribute related DBI routines
304         Not NULL only if U2DbiFeature_ReadAttributes supported
305         */
306     virtual U2AttributeDbi *getAttributeDbi() = 0;
307 
308     /**
309         U2Variant related DBI routines
310         Not NULL only if U2DbiFeature_ReadVariants supported
311         */
312     virtual U2VariantDbi *getVariantDbi() = 0;
313 
314     /**
315         Cross database references handling routines
316         Not NULL only if U2DbiFeature_ReadCrossDatabaseReferences supported
317         */
318     virtual U2CrossDatabaseReferenceDbi *getCrossDatabaseReferenceDbi() = 0;
319 
320     /**
321         U2Mod related DBI routines
322         Not NULL only if U2DbiFeature_ReadModifications supported
323         */
324     virtual U2ModDbi *getModDbi() = 0;
325 
326     /**
327         UdrRecord related DBI routines
328         Not NULL only if U2DbiFeature_ReadUdr supported
329         */
330     virtual UdrDbi *getUdrDbi() = 0;
331 
332     /**
333         Reads database global properties.
334         Requires U2DbiFeature_ReadProperties support
335         */
336     virtual QString getProperty(const QString &name, const QString &defaultValue, U2OpStatus &os) = 0;
337 
338     /**
339         Sets database global properties.
340         Requires U2DbiFeature_WriteProperties support
341         */
342     virtual void setProperty(const QString &name, const QString &value, U2OpStatus &os) = 0;
343 
344     /**
345         Initializes execution of the block of operation through the one transaction
346         */
347     virtual void startOperationsBlock(U2OpStatus &os);
348 
349     virtual void stopOperationBlock(U2OpStatus &os);
350 
351     /** Returns a mutex that synchronizes access to internal database handler.
352         This method is supposed to be used by caching DBIs
353         in order to prevent cache inconsistency. */
354     virtual QMutex *getDbMutex() const;
355 
356     virtual bool isReadOnly() const = 0;
357 
358     virtual bool isTransactionActive() const = 0;
359 
360 protected:
361     /** Stores to database the following properties:
362         U2DbiOptions::APP_MIN_COMPATIBLE_VERSION */
363     void setVersionProperties(const Version &minVersion, U2OpStatus &os);
364 };
365 
366 /**
367     Base class for all *Dbi classes provided by U2Dbi
368     Contains reference to root-level dbi
369     */
370 class U2CORE_EXPORT U2ChildDbi {
371 protected:
372     U2ChildDbi(U2Dbi *_rootDbi);
373 
374 public:
375     virtual ~U2ChildDbi();
376 
377     U2Dbi *getRootDbi() const;
378 
379 private:
380     U2Dbi *rootDbi;
381 };
382 
383 }  // namespace U2
384 
385 #endif
386