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 "SQLiteObjectRelationsDbi.h"
23 
24 #include <U2Core/U2ObjectTypeUtils.h>
25 #include <U2Core/U2SafePoints.h>
26 
27 namespace U2 {
28 
SQLiteObjectRelationsDbi(SQLiteDbi * dbi)29 SQLiteObjectRelationsDbi::SQLiteObjectRelationsDbi(SQLiteDbi *dbi)
30     : U2ObjectRelationsDbi(dbi), SQLiteChildDBICommon(dbi) {
31 }
32 
initSqlSchema(U2OpStatus & os)33 void SQLiteObjectRelationsDbi::initSqlSchema(U2OpStatus &os) {
34     SQLiteWriteQuery("CREATE TABLE IF NOT EXISTS ObjectRelation (object INTEGER NOT NULL, "
35                      "reference INTEGER NOT NULL, role INTEGER NOT NULL, "
36                      "PRIMARY KEY(object, reference), "
37                      "FOREIGN KEY(object) REFERENCES Object(id) ON DELETE CASCADE,"
38                      "FOREIGN KEY(reference) REFERENCES Object(id) ON DELETE CASCADE)",
39                      db,
40                      os)
41         .execute();
42     CHECK_OP(os, );
43 
44     SQLiteWriteQuery("CREATE INDEX IF NOT EXISTS ObjectRelationRole ON ObjectRelation(role)", db, os).execute();
45 }
46 
createObjectRelation(U2ObjectRelation & relation,U2OpStatus & os)47 void SQLiteObjectRelationsDbi::createObjectRelation(U2ObjectRelation &relation, U2OpStatus &os) {
48     static const QString queryString("INSERT INTO ObjectRelation (object, reference, role) VALUES(?1, ?2, ?3)");
49     SQLiteWriteQuery q(queryString, db, os);
50     CHECK_OP(os, );
51     q.bindDataId(1, relation.id);
52     q.bindDataId(2, relation.referencedObject);
53     q.bindInt32(3, relation.relationRole);
54     q.insert();
55 }
56 
getObjectRelations(const U2DataId & object,U2OpStatus & os)57 QList<U2ObjectRelation> SQLiteObjectRelationsDbi::getObjectRelations(const U2DataId &object,
58                                                                      U2OpStatus &os) {
59     QList<U2ObjectRelation> result;
60 
61     static const QString queryString = "SELECT o.type, o.name, o_r.object, o_r.reference, o_r.role FROM ObjectRelation AS o_r "
62                                        "INNER JOIN Object AS o ON o.id = o_r.reference WHERE o_r.object = ?1";
63     SQLiteReadQuery q(queryString, db, os);
64     CHECK_OP(os, result);
65     q.bindDataId(1, object);
66     while (q.step()) {
67         U2ObjectRelation relation;
68         const U2DataType objectType = U2DbiUtils::toType(object);
69         const U2DataType referenceType = q.getInt32(0);
70         relation.referencedType = U2ObjectTypeUtils::toGObjectType(referenceType);
71         relation.referencedName = q.getCString(1);
72         relation.id = q.getDataId(2, objectType);
73         relation.referencedObject = q.getDataId(3, referenceType);
74         relation.relationRole = static_cast<GObjectRelationRole>(q.getInt32(4));
75         result << relation;
76         CHECK_OP(os, result);
77     }
78 
79     return result;
80 }
81 
getReferenceRelatedObjects(const U2DataId & reference,GObjectRelationRole relationRole,U2OpStatus & os)82 QList<U2DataId> SQLiteObjectRelationsDbi::getReferenceRelatedObjects(const U2DataId &reference,
83                                                                      GObjectRelationRole relationRole,
84                                                                      U2OpStatus &os) {
85     QList<U2DataId> result;
86 
87     static const QString queryString = "SELECT o.id, o.type FROM Object AS o INNER JOIN ObjectRelation AS o_r "
88                                        "ON o.id = o_r.object WHERE o_r.reference = ?1 AND o_r.role = ?2";
89     SQLiteReadQuery q(queryString, db, os);
90     CHECK_OP(os, result);
91     q.bindDataId(1, reference);
92     q.bindInt32(2, relationRole);
93     while (q.step()) {
94         const U2DataType objType = q.getInt32(1);
95         result.append(q.getDataId(0, objType));
96         CHECK_OP(os, result);
97     }
98 
99     return result;
100 }
101 
removeObjectRelation(U2ObjectRelation & relation,U2OpStatus & os)102 void SQLiteObjectRelationsDbi::removeObjectRelation(U2ObjectRelation &relation, U2OpStatus &os) {
103     static const QString queryString("DELETE FROM ObjectRelation "
104                                      "WHERE object = ?1 AND reference = ?2");
105     SQLiteWriteQuery q(queryString, db, os);
106     CHECK_OP(os, );
107     q.bindDataId(1, relation.id);
108     q.bindDataId(2, relation.referencedObject);
109     q.execute();
110 }
111 
removeAllObjectRelations(const U2DataId & object,U2OpStatus & os)112 void SQLiteObjectRelationsDbi::removeAllObjectRelations(const U2DataId &object, U2OpStatus &os) {
113     static const QString queryString("DELETE FROM ObjectRelation WHERE object = ?1 OR reference = ?1");
114     SQLiteWriteQuery q(queryString, db, os);
115     CHECK_OP(os, );
116     q.bindDataId(1, object);
117     q.execute();
118 }
119 
removeReferencesForObject(const U2DataId & object,U2OpStatus & os)120 void SQLiteObjectRelationsDbi::removeReferencesForObject(const U2DataId &object, U2OpStatus &os) {
121     static const QString queryString("DELETE FROM ObjectRelation WHERE object = ?1");
122     SQLiteWriteQuery q(queryString, db, os);
123     CHECK_OP(os, );
124     q.bindDataId(1, object);
125     q.execute();
126 }
127 
128 }  // namespace U2
129