1 /***************************************************************************
2  *   SPDX-FileCopyrightText: 2006 Andreas Gungl <a.gungl@gmx.de>           *
3  *                                                                         *
4  *   SPDX-License-Identifier: LGPL-2.0-or-later                            *
5  ***************************************************************************/
6 
7 #include "entity.h"
8 #include "countquerybuilder.h"
9 #include "datastore.h"
10 
11 #include <QSqlDatabase>
12 #include <QVariant>
13 
14 using namespace Akonadi::Server;
15 
Entity()16 Entity::Entity()
17     : m_id(-1)
18 {
19 }
20 
Entity(qint64 id)21 Entity::Entity(qint64 id)
22     : m_id(id)
23 {
24 }
25 
~Entity()26 Entity::~Entity()
27 {
28 }
29 
id() const30 qint64 Entity::id() const
31 {
32     return m_id;
33 }
34 
setId(qint64 id)35 void Entity::setId(qint64 id)
36 {
37     m_id = id;
38 }
39 
isValid() const40 bool Entity::isValid() const
41 {
42     return m_id != -1;
43 }
44 
database()45 QSqlDatabase Entity::database()
46 {
47     return DataStore::self()->database();
48 }
49 
countImpl(const QString & tableName,const QString & column,const QVariant & value)50 int Entity::countImpl(const QString &tableName, const QString &column, const QVariant &value)
51 {
52     QSqlDatabase db = database();
53     if (!db.isOpen()) {
54         return -1;
55     }
56 
57     CountQueryBuilder builder(tableName);
58     builder.addValueCondition(column, Query::Equals, value);
59 
60     if (!builder.exec()) {
61         qCWarning(AKONADISERVER_LOG) << "Error counting records in table" << tableName;
62         return -1;
63     }
64 
65     return builder.result();
66 }
67 
removeImpl(const QString & tableName,const QString & column,const QVariant & value)68 bool Entity::removeImpl(const QString &tableName, const QString &column, const QVariant &value)
69 {
70     QSqlDatabase db = database();
71     if (!db.isOpen()) {
72         return false;
73     }
74 
75     QueryBuilder builder(tableName, QueryBuilder::Delete);
76     builder.addValueCondition(column, Query::Equals, value);
77 
78     if (!builder.exec()) {
79         qCWarning(AKONADISERVER_LOG) << "Error during deleting records from table" << tableName;
80         return false;
81     }
82     return true;
83 }
84 
relatesToImpl(const QString & tableName,const QString & leftColumn,const QString & rightColumn,qint64 leftId,qint64 rightId)85 bool Entity::relatesToImpl(const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 leftId, qint64 rightId)
86 {
87     QSqlDatabase db = database();
88     if (!db.isOpen()) {
89         return false;
90     }
91 
92     CountQueryBuilder builder(tableName);
93     builder.addValueCondition(leftColumn, Query::Equals, leftId);
94     builder.addValueCondition(rightColumn, Query::Equals, rightId);
95 
96     if (!builder.exec()) {
97         qCWarning(AKONADISERVER_LOG) << "Error during counting records in table" << tableName;
98         return false;
99     }
100 
101     return builder.result() > 0;
102 }
103 
addToRelationImpl(const QString & tableName,const QString & leftColumn,const QString & rightColumn,qint64 leftId,qint64 rightId)104 bool Entity::addToRelationImpl(const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 leftId, qint64 rightId)
105 {
106     QSqlDatabase db = database();
107     if (!db.isOpen()) {
108         return false;
109     }
110 
111     QueryBuilder qb(tableName, QueryBuilder::Insert);
112     qb.setColumnValue(leftColumn, leftId);
113     qb.setColumnValue(rightColumn, rightId);
114     qb.setIdentificationColumn(QString());
115 
116     if (!qb.exec()) {
117         qCWarning(AKONADISERVER_LOG) << "Error during adding a record to table" << tableName;
118         return false;
119     }
120 
121     return true;
122 }
123 
removeFromRelationImpl(const QString & tableName,const QString & leftColumn,const QString & rightColumn,qint64 leftId,qint64 rightId)124 bool Entity::removeFromRelationImpl(const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 leftId, qint64 rightId)
125 {
126     QSqlDatabase db = database();
127     if (!db.isOpen()) {
128         return false;
129     }
130 
131     QueryBuilder builder(tableName, QueryBuilder::Delete);
132     builder.addValueCondition(leftColumn, Query::Equals, leftId);
133     builder.addValueCondition(rightColumn, Query::Equals, rightId);
134 
135     if (!builder.exec()) {
136         qCWarning(AKONADISERVER_LOG) << "Error during removing a record from relation table" << tableName;
137         return false;
138     }
139 
140     return true;
141 }
142 
clearRelationImpl(const QString & tableName,const QString & leftColumn,const QString & rightColumn,qint64 id,RelationSide side)143 bool Entity::clearRelationImpl(const QString &tableName, const QString &leftColumn, const QString &rightColumn, qint64 id, RelationSide side)
144 {
145     QSqlDatabase db = database();
146     if (!db.isOpen()) {
147         return false;
148     }
149 
150     QueryBuilder builder(tableName, QueryBuilder::Delete);
151     switch (side) {
152     case Left:
153         builder.addValueCondition(leftColumn, Query::Equals, id);
154         break;
155     case Right:
156         builder.addValueCondition(rightColumn, Query::Equals, id);
157         break;
158     default:
159         qFatal("Invalid enum value");
160     }
161     if (!builder.exec()) {
162         qCWarning(AKONADISERVER_LOG) << "Error during clearing relation table" << tableName << "for ID" << id;
163         return false;
164     }
165 
166     return true;
167 }
168