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>
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.
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.
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.
26
#include <KDbTristate>
30
#include "kexiprojectdata.h"
31
#include "kexipartitem.h"
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.
41
#define KEXIPROJECT_VERSION_MAJOR 1
42
#define KEXIPROJECT_VERSION_MINOR 0
59
typedef QList<MissingPart> MissingPartsList;
63
* @brief A single project's controller and data structure.
64
* It contains data connection, state, etc.
66
class KEXICORE_EXPORT KexiProject : public QObject, public KDbObject, public KDbResultable
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);
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,
85
/*! \return major version of KexiProject object.
86
This information is retrieved from database when existing project is opened. */
87
int versionMajor() const;
89
/*! \return minor version of KexiProject object.
90
@see versionMajor() */
91
int versionMinor() const;
93
/*! Opens existing project using project data.
94
\return true on success */
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);
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()).
113
Since KexiProject inherits KDbObject, it is possible to get error message
114
and other information on error.
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);
121
* @return true if a we are connected to a database
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()
134
int typeIdForPluginId(const QString &pluginId) const;
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()
141
QString pluginIdForTypeId(int typeId) const;
144
* @return all items of a type \a i in this project
146
KexiPart::ItemDict* items(KexiPart::Info *i);
149
* @return all items of a plugin ID \a pluginId in this project
150
* It is a convenience function.
152
KexiPart::ItemDict* itemsForPluginId(const QString &pluginId);
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().
158
void getSortedItems(KexiPart::ItemList *list, KexiPart::Info *i);
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().
164
void getSortedItemsForPluginId(KexiPart::ItemList *list, const QString &pluginId);
167
* @return item corresponding with plugin ID \a pluginId and name \a name
169
KexiPart::Item* itemForPluginId(const QString &pluginId, const QString &name);
172
* @return item of type \a i and name \a name
174
KexiPart::Item* item(KexiPart::Info *i, const QString &name);
177
* @return item for \a identifier
179
KexiPart::Item* item(int identifier);
182
* @return the database connection associated with this project
184
KDbConnection *dbConnection() const;
187
* @return the project's data
189
KexiProjectData *data() const;
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);
200
KexiWindow* openObject(QWidget* parent, const QString &pluginId,
201
const QString& name, Kexi::ViewMode viewMode = Kexi::DataViewMode);
203
/*! Remove a part instance pointed by \a item.
204
\return true on success. */
205
bool removeObject(KexiPart::Item* item);
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);
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);
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).
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().
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());
232
//! Added for convenience.
233
KexiPart::Item* createPartItem(KexiPart::Part *part,
234
const QString& suggestedCaption = QString());
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().
240
void addStoredItem(KexiPart::Info *info, KexiPart::Item *item);
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);
248
* @returns parts metioned in the project meta tables but not available locally
250
KexiPart::MissingPartsList missingParts() const;
252
KDbParser* sqlParser();
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);
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);
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);
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();
279
//! Closes connection. @return true on success.
280
bool closeConnection();
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);
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);
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
302
\sa loadUserDataBlock() storeUserDataBlock() removeUserDataBlock() KDbConnection::copyDataBlock(). */
303
bool copyUserDataBlock(int sourceObjectID, int destObjectID, const QString &dataID = QString());
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());
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();
319
//! Used in open() and open(bool*).
320
tristate openInternal(bool *incompatibleWithKexi);
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".
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.)
337
@param insideTransaction Embed entire creation process inside a transaction
339
\return true on successful object's creation. Objects are created only once, they are not overwritten.
341
bool createInternalStructures(bool insideTransaction);
343
/*! \return Kexi part for \a item. */
344
KexiPart::Part *findPartFor(const KexiPart::Item& item);
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();
351
/** signal emitted on error */
352
void error(const QString &title, KDbObject *obj);
354
/** signal emitted on error (not KDb-related) */
355
void error(const QString &msg, const QString &desc);
357
/** New \a item has been stored. */
358
void newItemStored(KexiPart::Item *item);
360
/** instance pointed by \a item is removed */
361
void itemRemoved(const KexiPart::Item &item);
363
/** instance pointed by \a item is renamed */
364
void itemRenamed(const KexiPart::Item &item, const QString& oldName);
366
/** caption for instance pointed by \a item is changed */
367
void itemCaptionChanged(const KexiPart::Item &item, const QString& oldCaption);
370
bool createIdForPart(const KexiPart::Info& info);
373
/*! Checks whether the project's connection is read-only.
374
If so, error message is set and false is returned. */
375
bool checkWritable();
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();
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.
387
* Use @ref missingParts() to get a list of missing parts.
388
* @see typeIdForPluginId()
390
bool checkProject(const QString& singlePluginId = QString());
395
friend class KexiMainWindow;
396
friend class KexiWindow;
397
friend class Private;