~ubuntu-branches/debian/sid/kexi/sid

« back to all changes in this revision

Viewing changes to src/core/kexiproject.h

  • Committer: Package Import Robot
  • Author(s): Pino Toscano
  • Date: 2017-06-24 20:10:10 UTC
  • Revision ID: package-import@ubuntu.com-20170624201010-5lrzd5r2vwthwifp
Tags: upstream-3.0.1.1
ImportĀ upstreamĀ versionĀ 3.0.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of the KDE project
 
2
   Copyright (C) 2003 Lucijan Busch <lucijan@kde.org>
 
3
   Copyright (C) 2003-2012 Jarosław Staniek <staniek@kde.org>
 
4
 
 
5
   This library is free software; you can redistribute it and/or
 
6
   modify it under the terms of the GNU Library General Public
 
7
   License as published by the Free Software Foundation; either
 
8
   version 2 of the License, or (at your option) any later version.
 
9
 
 
10
   This library is distributed in the hope that it will be useful,
 
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
   Library General Public License for more details.
 
14
 
 
15
   You should have received a copy of the GNU Library General Public License
 
16
   along with this library; see the file COPYING.LIB.  If not, write to
 
17
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
18
 * Boston, MA 02110-1301, USA.
 
19
*/
 
20
 
 
21
#ifndef KEXIPROJECT_H
 
22
#define KEXIPROJECT_H
 
23
 
 
24
#include <QObject>
 
25
 
 
26
#include <KDbTristate>
 
27
#include <KDbObject>
 
28
#include <KDbResult>
 
29
 
 
30
#include "kexiprojectdata.h"
 
31
#include "kexipartitem.h"
 
32
#include "kexi.h"
 
33
 
 
34
/*! KexiProject implementation version.
 
35
 It is altered after every change:
 
36
 - major number is increased after KexiProject storage format change,
 
37
 - minor is increased after adding binary-incompatible change.
 
38
 Use KexiProject::versionMajor() and KexiProject::versionMinor() to get real project's version.
 
39
*/
 
40
 
 
41
#define KEXIPROJECT_VERSION_MAJOR 1
 
42
#define KEXIPROJECT_VERSION_MINOR 0
 
43
 
 
44
class QFileInfo;
 
45
class KDbConnection;
 
46
class KDbParser;
 
47
class KexiMainWindow;
 
48
class KexiWindow;
 
49
 
 
50
namespace KexiPart
 
51
{
 
52
class Part;
 
53
class Info;
 
54
 
 
55
struct MissingPart {
 
56
    QString name;
 
57
    QString id;
 
58
};
 
59
typedef QList<MissingPart> MissingPartsList;
 
60
}
 
61
 
 
62
/**
 
63
 * @brief A single project's controller and data structure.
 
64
 * It contains data connection, state, etc.
 
65
 */
 
66
class KEXICORE_EXPORT KexiProject : public QObject, public KDbObject, public KDbResultable
 
67
{
 
68
    Q_OBJECT
 
69
 
 
70
public:
 
71
    /*! Constructor 1. Creates a new object using \a pdata.
 
72
     \a handler can be provided to receive error messages during
 
73
     entire KexiProject object's lifetime. */
 
74
    explicit KexiProject(const KexiProjectData& pdata, KDbMessageHandler* handler = 0);
 
75
 
 
76
    /*! Constructor 2. Like above but sets predefined connections \a conn.
 
77
     The connection should be created using the same connection data
 
78
     as pdata->connectionData(). The connection will become owned by created KexiProject
 
79
     object, so do not destroy it. */
 
80
    KexiProject(const KexiProjectData& pdata, KDbMessageHandler* handler,
 
81
                KDbConnection* conn);
 
82
 
 
83
    ~KexiProject();
 
84
 
 
85
    /*! \return major version of KexiProject object.
 
86
     This information is retrieved from database when existing project is opened. */
 
87
    int versionMajor() const;
 
88
 
 
89
    /*! \return minor version of KexiProject object.
 
90
     @see versionMajor() */
 
91
    int versionMinor() const;
 
92
 
 
93
    /*! Opens existing project using project data.
 
94
     \return true on success */
 
95
    tristate open();
 
96
 
 
97
    /*! Like open().
 
98
     \return true on success.
 
99
     Additional \a incompatibleWithKexi, is set to false on failure when
 
100
     connection for the project was successfully started bu the project
 
101
     is probably not compatible with Kexi - no valid "kexidb_major_ver"
 
102
     value in "kexi__db" table.
 
103
     This is often the case for native server-based databases.
 
104
     If so, Kexi application can propose importing the database
 
105
     or linking it to parent project (the latter isn't yet implemented).
 
106
     For other types of errors the variable is set to true. */
 
107
    tristate open(bool *incompatibleWithKexi);
 
108
 
 
109
    /*! Creates new, empty project using project data.
 
110
     If \a forceOverwrite is true, existing database project is silently overwritten.
 
111
     KDbConnection is created (accessible then with KexiProject::dbConnection()).
 
112
 
 
113
     Since KexiProject inherits KDbObject, it is possible to get error message
 
114
     and other information on error.
 
115
 
 
116
     \return true on success, false on failure, and cancelled when database exists
 
117
     but \a forceOverwrite is false. */
 
118
    tristate create(bool forceOverwrite = false);
 
119
 
 
120
    /**
 
121
     * @return true if a we are connected to a database
 
122
     */
 
123
    bool isConnected();
 
124
 
 
125
    /**
 
126
     * @return internal numeric type identifier for plugin ID @a pluginId.
 
127
     * -1 is returned if the ID is unknown.
 
128
     * While the plugin IDs are unique strings like "org.kexi-project.table",
 
129
     * the type identifiers are specific to the given physically stored project
 
130
     * because sets of plugins can differ from between various Kexi installations
 
131
     * and configurations.
 
132
     * @see pluginIdForTypeId()
 
133
     */
 
134
    int typeIdForPluginId(const QString &pluginId) const;
 
135
 
 
136
    /**
 
137
     * @return plugin ID for a numeric type ID @a typeId.
 
138
     * Empty string is returned if the plugin ID is unknown.
 
139
     * @see typeIdForPluginId()
 
140
     */
 
141
    QString pluginIdForTypeId(int typeId) const;
 
142
 
 
143
    /**
 
144
     * @return all items of a type \a i in this project
 
145
     */
 
146
    KexiPart::ItemDict* items(KexiPart::Info *i);
 
147
 
 
148
    /**
 
149
     * @return all items of a plugin ID \a pluginId in this project
 
150
     * It is a convenience function.
 
151
     */
 
152
    KexiPart::ItemDict* itemsForPluginId(const QString &pluginId);
 
153
 
 
154
    /**
 
155
     * Puts a list of items of a type \a i in this project into \a list.
 
156
     * You can then sort this list using ItemList::sort().
 
157
     */
 
158
    void getSortedItems(KexiPart::ItemList  *list, KexiPart::Info *i);
 
159
 
 
160
    /**
 
161
     * Puts a sorted list of items that use a plugin ID \a pluginId into \a list.
 
162
     * You can then sort this list using KexiPart::ItemList::sort().
 
163
     */
 
164
    void getSortedItemsForPluginId(KexiPart::ItemList *list, const QString &pluginId);
 
165
 
 
166
    /**
 
167
     * @return item corresponding with plugin ID \a pluginId and name \a name
 
168
     */
 
169
    KexiPart::Item* itemForPluginId(const QString &pluginId, const QString &name);
 
170
 
 
171
    /**
 
172
     * @return item of type \a i and name \a name
 
173
     */
 
174
    KexiPart::Item* item(KexiPart::Info *i, const QString &name);
 
175
 
 
176
    /**
 
177
     * @return item for \a identifier
 
178
     */
 
179
    KexiPart::Item* item(int identifier);
 
180
 
 
181
    /**
 
182
     * @return the database connection associated with this project
 
183
     */
 
184
    KDbConnection *dbConnection() const;
 
185
 
 
186
    /**
 
187
     * @return the project's data
 
188
     */
 
189
    KexiProjectData *data() const;
 
190
 
 
191
    /*! Opens object pointed by \a item in a view \a viewMode.
 
192
     \a staticObjectArgs can be passed for static object
 
193
     (only works when part for this item is of type KexiPart::StaticPart).
 
194
     The new widget will be a child of \a parent. */
 
195
    KexiWindow* openObject(QWidget* parent, KexiPart::Item *item,
 
196
                           Kexi::ViewMode viewMode = Kexi::DataViewMode,
 
197
                           QMap<QString, QVariant>* staticObjectArgs = 0);
 
198
 
 
199
    //! For convenience
 
200
    KexiWindow* openObject(QWidget* parent, const QString &pluginId,
 
201
                           const QString& name, Kexi::ViewMode viewMode = Kexi::DataViewMode);
 
202
 
 
203
    /*! Remove a part instance pointed by \a item.
 
204
     \return true on success. */
 
205
    bool removeObject(KexiPart::Item* item);
 
206
 
 
207
    /*! Renames a part instance pointed by \a item to a new name \a newName.
 
208
     \return true on success. */
 
209
    bool renameObject(KexiPart::Item* item, const QString& newName);
 
210
 
 
211
    /*! Renames a part instance pointed by \a item to a new name \a newName.
 
212
     \return true on success. */
 
213
    bool setObjectCaption(KexiPart::Item* item, const QString& newCaption);
 
214
 
 
215
    /*! Creates part item for given part \a info.
 
216
     Newly item will not be saved to the backend but stored in memory only
 
217
     (owned by project), and marked as "neverSaved" (see KexiPart::Item::neverSaved()).
 
218
     The item will have assigned a new unique caption like e.g. "Table15",
 
219
     and unique name like "table15", but no specific identifier
 
220
     (because id will be assigned on creation at the backend side).
 
221
 
 
222
     If \a suggestedCaption is not empty, it will be set as a caption
 
223
     (with number suffix, to avoid duplicated, e.g. "employees7"
 
224
     for "employees" sugested name). Name will be then built based
 
225
     on this caption using KDb::stringToIdentifier().
 
226
 
 
227
     This method is used before creating new object.
 
228
     \return newly created part item or NULL on any error. */
 
229
    KexiPart::Item* createPartItem(KexiPart::Info *info,
 
230
                                   const QString& suggestedCaption = QString());
 
231
 
 
232
    //! Added for convenience.
 
233
    KexiPart::Item* createPartItem(KexiPart::Part *part,
 
234
                                   const QString& suggestedCaption = QString());
 
235
 
 
236
    /*! Adds item \a item after it is successfully stored as an instance of part
 
237
     pointed by \a info. Also clears 'neverSaved' flag if \a item.
 
238
     Used by KexiWindow::storeNewData().
 
239
     @internal */
 
240
    void addStoredItem(KexiPart::Info *info, KexiPart::Item *item);
 
241
 
 
242
    /*! removes \a item from internal dictionaries. The item is destroyed
 
243
     after successful removal.
 
244
     Used to delete an unstored part item previously created with createPartItem(). */
 
245
    void deleteUnstoredItem(KexiPart::Item *item);
 
246
 
 
247
    /**
 
248
     * @returns parts metioned in the project meta tables but not available locally
 
249
     */
 
250
    KexiPart::MissingPartsList missingParts() const;
 
251
 
 
252
    KDbParser* sqlParser();
 
253
 
 
254
    /*! Shows dialog for creating new blank project,
 
255
     ans creates one. Dialog is not shown if option for automatic creation
 
256
     is checked or Kexi::startupHandler().projectData() was provided from command line.
 
257
     \a cancelled is set to true if creation has been cancelled (e.g. user answered
 
258
     no when asked for database overwriting, etc.
 
259
     \return true if database was created, false on error or when cancel was pressed */
 
260
    static KexiProject* createBlankProject(bool *cancelled, const KexiProjectData& data,
 
261
                                           KDbMessageHandler* handler = 0);
 
262
 
 
263
    /*! Drops project described by \a data. \return true on success.
 
264
     Use with care: Any KexiProject objects allocated for this project will become invalid! */
 
265
    static tristate dropProject(const KexiProjectData& data,
 
266
                                KDbMessageHandler* handler, bool dontAsk = false);
 
267
 
 
268
    //! Helper method to ask user "Could not  open file for reading and writing. Do you want to
 
269
    //! open the file as read only?". @return true if user agrees, false if user cancels opening.
 
270
    static bool askForOpeningNonWritableFileAsReadOnly(QWidget *parent, const QFileInfo &finfo);
 
271
 
 
272
    /*! Generates ID for private "document" like Relations window.
 
273
     Private IDs are negative numbers (while ID regular part instance's IDs are >0)
 
274
     Private means that the object is not stored as-is in the project but is somewhat
 
275
     generated and in most cases there is at most one unique instance document of such type (part).
 
276
     To generate this ID, just app-wide internal counter is used. */
 
277
    virtual int generatePrivateID();
 
278
 
 
279
    //! Closes connection. @return true on success.
 
280
    bool closeConnection();
 
281
 
 
282
    /*! Loads current user's data block, referenced by \a objectID and \a dataID
 
283
     and puts it to \a dataString.
 
284
     \return true on success, false on failure and cancelled when there is no such data block
 
285
     \sa storeUserDataBlock() removeUserDataBlock() copyUserDataBlock() KDbConnection::loadDataBlock(). */
 
286
    tristate loadUserDataBlock(int objectID, const QString& dataID, QString *dataString);
 
287
 
 
288
    /*! Stores current user's data block \a dataString, referenced by \a objectID and \a dataID.
 
289
     The block will be stored in "kexi__userdata" table
 
290
     If there is already such record in the table, it's simply overwritten.
 
291
     \return true on success
 
292
     \sa loadUserDataBlock() removeUserDataBlock() copyUserDataBlock() KDbConnection::storeDataBlock(). */
 
293
    bool storeUserDataBlock(int objectID, const QString& dataID, const QString &dataString);
 
294
 
 
295
    /*! Copies urrent user's data blocks referenced by \a sourceObjectID and pointed
 
296
     by optional \a dataID.
 
297
     \return true on success. Does not fail if blocks do not exist.
 
298
     Prior to copying, existing user data blocks are removed even if there is nothing to copy.
 
299
     Copied data blocks will have \a destObjectID object identifier assigned.
 
300
     Note that if \a dataID is not specified, all user data blocks found for the \a sourceObjectID
 
301
     will be copied.
 
302
     \sa loadUserDataBlock() storeUserDataBlock() removeUserDataBlock() KDbConnection::copyDataBlock(). */
 
303
    bool copyUserDataBlock(int sourceObjectID, int destObjectID, const QString &dataID = QString());
 
304
 
 
305
    /*! Removes current user's data block referenced by \a objectID and \a dataID.
 
306
     \return true on success. Does not fail if the block does not exist.
 
307
     Note that if \a dataID is not specified, all data blocks for this user and object will be removed.
 
308
     \sa loadUserDataBlock() storeUserDataBlock() copyUserDataBlock() KDbConnection::removeDataBlock(). */
 
309
    bool removeUserDataBlock(int objectID, const QString& dataID = QString());
 
310
 
 
311
protected:
 
312
    /*! Creates connection using project data.
 
313
     The connection will be readonly if data()->isReadOnly().
 
314
     \return true on success, otherwise false and appropriate error is set. */
 
315
    bool createConnection();
 
316
 
 
317
    bool initProject();
 
318
 
 
319
    //! Used in open() and open(bool*).
 
320
    tristate openInternal(bool *incompatibleWithKexi);
 
321
 
 
322
    /*! Kexi itself can define a number of internal database objects (mostly data structures),
 
323
     usually tables for it's own purposes.
 
324
     Even while at KDb library level, such "system" tables, like "kexi__objects", "kexi__objectdata"
 
325
     are created automatically on database project creation, this is not enough: there are objects
 
326
     needed specifically for Kexi but not for other applications utilizing the KDb library.
 
327
     Example table created here for now is "kexi__blobs".
 
328
 
 
329
     This method is called on create() and open(): creates necessary objects
 
330
     if they are not yet existing. This especially allows to create to create these objects
 
331
     (on open) within a project made with previous Kexi version not supporting
 
332
     all currently defined structurtes. We're trying to be here as much backward compatible as possible.
 
333
     For this purpose, here's the complete list of currently created objects:
 
334
     - "kexi__blobs" - a table containing BLOBs data that can be accessed globally at Kexi projects
 
335
       from within any database-aware view (table views, forms, reports, etc.)
 
336
 
 
337
     @param insideTransaction Embed entire creation process inside a transaction
 
338
 
 
339
     \return true on successful object's creation. Objects are created only once, they are not overwritten.
 
340
    */
 
341
    bool createInternalStructures(bool insideTransaction);
 
342
 
 
343
    /*! \return Kexi part for \a item. */
 
344
    KexiPart::Part *findPartFor(const KexiPart::Item& item);
 
345
 
 
346
    //! Closes connection without altering the m_result if is actually set. @return true on success.
 
347
    //! Used on failed operations such as useDatabase().
 
348
    bool closeConnectionInternal();
 
349
 
 
350
Q_SIGNALS:
 
351
    /** signal emitted on error */
 
352
    void error(const QString &title, KDbObject *obj);
 
353
 
 
354
    /** signal emitted on error (not KDb-related) */
 
355
    void error(const QString &msg, const QString &desc);
 
356
 
 
357
    /** New \a item has been stored. */
 
358
    void newItemStored(KexiPart::Item *item);
 
359
 
 
360
    /** instance pointed by \a item is removed */
 
361
    void itemRemoved(const KexiPart::Item &item);
 
362
 
 
363
    /** instance pointed by \a item is renamed */
 
364
    void itemRenamed(const KexiPart::Item &item, const QString& oldName);
 
365
 
 
366
    /** caption for instance pointed by \a item is changed */
 
367
    void itemCaptionChanged(const KexiPart::Item &item, const QString& oldCaption);
 
368
 
 
369
protected:
 
370
    bool createIdForPart(const KexiPart::Info& info);
 
371
 
 
372
private:
 
373
    /*! Checks whether the project's connection is read-only.
 
374
     If so, error message is set and false is returned. */
 
375
    bool checkWritable();
 
376
 
 
377
    /*! Retrieves basic information (pluginId, typeId, name, caption)
 
378
     about all items of all types for this project.
 
379
     @return true on success. */
 
380
    bool retrieveItems();
 
381
 
 
382
    /**
 
383
     * Checks project's kexi__part table.
 
384
     * @a singlePluginId can be provided to only check specified part.
 
385
     * Internal identifiers of part(s) are remembered.
 
386
     *
 
387
     * Use @ref missingParts() to get a list of missing parts.
 
388
     * @see typeIdForPluginId()
 
389
     */
 
390
    bool checkProject(const QString& singlePluginId = QString());
 
391
 
 
392
    class Private;
 
393
    Private * const d;
 
394
 
 
395
    friend class KexiMainWindow;
 
396
    friend class KexiWindow;
 
397
    friend class Private;
 
398
};
 
399
 
 
400
#endif