22#include <tqapplication.h>
29#include <kexiutils/identifier.h>
31#include <kexidb/connection.h>
32#include <kexidb/cursor.h>
33#include <kexidb/driver.h>
34#include <kexidb/drivermanager.h>
35#include <kexidb/utils.h>
36#include <kexidb/parser/parser.h>
37#include <kexidb/msghandler.h>
38#include <kexidb/dbproperties.h>
39#include <kexiutils/utils.h>
41#include "kexiproject.h"
42#include "kexipartmanager.h"
43#include "kexipartitem.h"
44#include "kexipartinfo.h"
46#include "kexidialogbase.h"
48#include "keximainwindow.h"
49#include "kexiblobbuffer.h"
50#include "kexiguimsghandler.h"
54class KexiProject::Private
61 , tempPartItemID_Counter(-1)
66 itemDictsCache.setAutoDelete( true);
67 unstoredItems.setAutoDelete( true);
75 TQGuardedPtr<KexiDB::Connection> connection;
76 TQGuardedPtr<KexiProjectData> data;
81 TQIntDict<KexiPart::ItemDict> itemDictsCache;
83 TQPtrDict<KexiPart::Item> unstoredItems;
84 int tempPartItemID_Counter;
86 KexiDB::Parser* sqlParser;
114 : TQObject(), Object(handler)
124 : TQObject(), Object(handler)
128 if (d->data->connectionData() == d->connection->data())
129 d->connection = conn;
131 kdWarning() << "KexiProject::KexiProject(): passed connection's data ("
133 << d->data->connectionData()->serverInfoString() << ")" << endl;
138KexiProject::~KexiProject()
146 return d->connection;
156 return d->versionMajor;
161 return d->versionMinor;
179 if (incompatibleWithKexi)
180 *incompatibleWithKexi = false;
181 kdDebug() << "KexiProject::open(): " << d->data->databaseName() << " "<< d->data->connectionData()->driverName << endl;
183 i18n( "Could not open project \"%1\".").arg(d->data->databaseName()));
186 kdDebug() << "KexiProject::open(): !createConnection()" << endl;
190 KexiGUIMessageHandler msgHandler;
191 if (!d->connection->useDatabase(d->data->databaseName(), true, &cancel, &msgHandler))
196 kdDebug() << "KexiProject::open(): !d->connection->useDatabase() "
197 << d->data->databaseName() << " "<< d->data->connectionData()->driverName << endl;
199 if (d->connection->errorNum() == ERR_NO_DB_PROPERTY) {
202 if ( !d->data->connectionData()->driverName.lower().startsWith( "sqlite")) {
204 if (incompatibleWithKexi)
205 *incompatibleWithKexi = true;
228 i18n( "Could not create project \"%1\".").arg(d->data->databaseName()));
234 if (d->connection->databaseExists( d->data->databaseName() )) {
237 if (!d->connection->dropDatabase( d->data->databaseName() )) {
242 kdDebug() << "--- DB '" << d->data->databaseName() << "' dropped ---"<< endl;
244 if (!d->connection->createDatabase( d->data->databaseName() )) {
249 kdDebug() << "--- DB '" << d->data->databaseName() << "' created ---"<< endl;
251 if (!d->connection->useDatabase(d->data->databaseName()))
253 kdDebug() << "--- DB '" << d->data->databaseName() << "' USE ERROR ---"<< endl;
258 kdDebug() << "--- DB '" << d->data->databaseName() << "' used ---"<< endl;
271 if (!props. setValue( "kexiproject_major_ver", d->versionMajor)
272 || !props. setCaption( "kexiproject_major_ver", i18n( "Project major version"))
273 || !props. setValue( "kexiproject_minor_ver", d->versionMinor)
274 || !props. setCaption( "kexiproject_minor_ver", i18n( "Project minor version"))
275 || !props. setValue( "project_caption", d->data->caption())
276 || !props. setCaption( "project_caption", i18n( "Project caption"))
277 || !props. setValue( "project_desc", d->data->description())
278 || !props. setCaption( "project_desc", i18n( "Project description")) )
292 if (trans. active() && !d->connection->commitTransaction(trans))
296 return initProject();
302 if (insideTransaction) {
312 int storedMajorVersion = props. value( "kexiproject_major_ver").toInt(&ok);
314 storedMajorVersion = 0;
315 int storedMinorVersion = props. value( "kexiproject_minor_ver").toInt(&ok);
317 storedMinorVersion = 1;
319 bool containsKexi__blobsTable = d->connection->drv_containsTable( "kexi__blobs");
321 bool contains_o_folder_id = containsKexi__blobsTable && true == d->connection->querySingleNumber(
322 "SELECT COUNT(o_folder_id) FROM kexi__blobs", dummy, 0, false);
323 bool add_folder_id_column = false;
326 if (storedMajorVersion<=0) {
327 d->versionMajor = KEXIPROJECT_VERSION_MAJOR;
328 d->versionMinor = KEXIPROJECT_VERSION_MINOR;
331 if (!d->connection->isReadOnly()) {
332 if (!props. setValue( "kexiproject_major_ver", d->versionMajor)
333 || !props. setCaption( "kexiproject_major_ver", i18n( "Project major version"))
334 || !props. setValue( "kexiproject_minor_ver", d->versionMinor)
335 || !props. setCaption( "kexiproject_minor_ver", i18n( "Project minor version")) ) {
340 if (containsKexi__blobsTable) {
342 if (!d->connection->isReadOnly()) {
343 if (!contains_o_folder_id) {
344 add_folder_id_column = true;
349 if (storedMajorVersion!=d->versionMajor || storedMajorVersion!=d->versionMinor) {
351 d->versionMajor = storedMajorVersion;
352 d->versionMinor = storedMinorVersion;
357 KexiDB::Field::PrimaryKey | KexiDB::Field::AutoInc, KexiDB::Field::Unsigned) )
369 if (containsKexi__blobsTable) {
371 d->connection->insertInternalTableSchema(t_blobs);
372 if (add_folder_id_column && !d->connection->isReadOnly()) {
376 kexi__blobsCopy->setName( "kexi__blobs__copy");
377 if (!d->connection->drv_createTable( *kexi__blobsCopy )) {
378 delete kexi__blobsCopy;
383 if (!d->connection->executeSQL(
384 TQString::fromLatin1( "INSERT INTO kexi__blobs (o_data, o_name, o_caption, o_mime, o_folder_id) "
385 "SELECT o_data, o_name, o_caption, o_mime, 0 FROM kexi__blobs") )
387 || !d->connection->executeSQL(TQString::fromLatin1( "DROP TABLE kexi__blobs"))
389 || !d->connection->drv_alterTableName(*kexi__blobsCopy, "kexi__blobs")
393 delete kexi__blobsCopy;
397 delete kexi__blobsCopy;
402 if (!d->connection->isReadOnly()) {
403 if (!d->connection->createTable( t_blobs, true )) {
420 bool containsKexi__partsTable = d->connection->drv_containsTable( "kexi__parts");
421 bool partsTableOk = true;
422 if (containsKexi__partsTable) {
424 d->connection->insertInternalTableSchema(t_parts);
427 if (!d->connection->isReadOnly()) {
428 partsTableOk = d->connection->createTable( t_parts, true );
432 partsTableOk = d->connection->insertRecord(*fl, TQVariant(1), TQVariant( "Tables"),
433 TQVariant( "kexi/table"), TQVariant( "http://koffice.org/kexi/"));
436 partsTableOk = d->connection->insertRecord(*fl, TQVariant(2), TQVariant( "Queries"),
437 TQVariant( "kexi/query"), TQVariant( "http://koffice.org/kexi/"));
446 if (insideTransaction) {
469 int connectionOptions = 0;
470 if (d->data->isReadOnly())
472 d->connection = driver-> createConnection(*d->data->connectionData(), connectionOptions);
475 kdDebug() << "KexiProject::open(): uuups failed " << driver-> errorMsg() << endl;
480 if (!d->connection->connect())
483 kdDebug() << "KexiProject::createConnection(): error connecting: " << (d->connection ? d->connection->errorMsg() : TQString()) << endl;
490 KexiBLOBBuffer::setConnection(d->connection);
496KexiProject::closeConnection()
501 if (!d->connection->disconnect()) {
506 delete d->connection;
512KexiProject::initProject()
515 kdDebug() << "KexiProject::open(): checking project parts..." << endl;
523 KexiDB::DatabaseProperties &props = d->connection->databaseProperties();
524 TQString str( props. value( "project_caption").toString() );
526 d->data->setCaption( str );
527 str = props. value( "project_desc").toString();
529 d->data->setDescription( str );
543 if(d->connection && d->connection->isDatabaseUsed())
552 kdDebug() << "KexiProject::items()" << endl;
557 KexiPart::ItemDict *dict = d->itemDictsCache[ i-> projectPartID() ];
562 "SELECT o_id, o_name, o_caption FROM kexi__objects WHERE o_type = "
568 dict = new KexiPart::ItemDict(1009);
569 dict->setAutoDelete( true);
575 int ident = cursor-> value(0).toInt(&ok);
576 TQString objName( cursor-> value(1).toString() );
578 if ( ok && (ident>0) && !d->connection->isInternalTableSchema(objName)
581 it->setIdentifier(ident);
583 it->setName(objName);
584 it->setCaption(cursor-> value(2).toString());
586 dict->insert(it->identifier(), it);
590 d->connection->deleteCursor(cursor);
607 KexiPart::ItemDict* dict = items(i);
610 for (KexiPart::ItemDictIterator it(*dict); it.current(); ++it)
611 list.append(it.current());
626 KexiPart::ItemDict *dict = items(info);
627 item->setNeverSaved( false );
628 d->unstoredItems.take( item);
629 dict->insert( item->identifier(), item );
640 const TQString l_name = name.lower();
641 for (KexiPart::ItemDictIterator it( *dict ); it.current(); ++it) {
642 if (it.current()->name().lower()==l_name)
651 KexiPart::ItemDict *dict = items(i);
654 const TQString l_name = name.lower();
655 for (KexiPart::ItemDictIterator it( *dict ); it.current(); ++it) {
656 if (it.current()->name().lower()==l_name)
665 KexiPart::ItemDict *dict;
666 for (TQIntDictIterator<KexiPart::ItemDict> it(d->itemDictsCache); (dict = it.current()); ++it) {
726 int viewMode, TQMap<TQString,TQString>* staticObjectArgs)
729 if (viewMode!=Kexi::DataViewMode && data()->userMode())
738 if (part->lastOperationStatus().error())
739 setError(i18n( "Opening object \"%1\" failed.").arg( item.name())+ "<br>"
740 +part->lastOperationStatus().message,
741 part->lastOperationStatus().description);
748 const TQString& name, int viewMode)
751 return it ? openObject(wnd, *it, viewMode) : 0;
756 if (!d->connection->isReadOnly())
758 setError(i18n( "This project is opened as read only."));
765 if ( data()->userMode())
778 if (! item.neverSaved()) {
784 if (!d->connection->removeObject( item.identifier() )) {
797 KexiPart::ItemDict *dict = d->itemDictsCache[ part->info()-> projectPartID() ];
798 if (!(dict && dict->remove( item.identifier() )))
799 d->unstoredItems.remove(& item);
807 if ( data()->userMode())
811 TQString newName = _newName.stripWhiteSpace();
814 if (newName.isEmpty()) {
815 setError( i18n( "Could not set empty name for this object.") );
819 setError( i18n( "Could not use this name. Object with name \"%1\" already exists.")
826 i18n( "Could not rename object \"%1\".").arg( item.name()) );
838 setError(part->lastOperationStatus().message, part->lastOperationStatus().description);
841 if (!d->connection->executeSQL( "update kexi__objects set o_name="
843 + " where o_id=" + TQString::number( item.identifier()) )) {
851 TQCString oldName( item.name().latin1() );
852 item.setName( newName );
860 if ( data()->userMode())
870 KexiPart::ItemDict *dict = items(info);
876 if (suggestedCaption.isEmpty()) {
885 KexiPart::ItemDictIterator it(*dict);
886 TQPtrDictIterator<KexiPart::Item> itUnstored(d->unstoredItems);
888 new_name = base_name;
890 new_name += TQString::number(n);
891 for (it.toFirst(); it.current(); ++it) {
892 if (it.current()->name().lower()==new_name)
895 if ( it.current() ) {
899 for (itUnstored.toFirst(); itUnstored.current(); ++itUnstored) {
900 if (itUnstored.current()->name().lower()==new_name)
903 if ( !itUnstored.current() )
911 TQString new_caption( suggestedCaption.isEmpty() ? part-> instanceCaption() : suggestedCaption);
913 new_caption += TQString::number(n);
916 item->setIdentifier( --d->tempPartItemID_Counter );
918 item->setName(new_name);
919 item->setCaption(new_caption);
920 item->setNeverSaved( true);
921 d->unstoredItems.insert( item, item);
934 d->unstoredItems.remove( item);
947static const TQString warningNoUndo = i18n( "Warning: entire project's data will be removed.");
960 if (KMessageBox::Yes != KMessageBox::warningYesNo(0, "<qt>"+i18n(
961 "The project %1 already exists.\n"
962 "Do you want to replace it with a new, blank one?")
964 TQString(), KGuiItem(i18n( "Replace")), KStdGuiItem::cancel() ))
977 kdDebug() << "KexiProject::createBlankProject(): new project created --- " << endl;
987 if (!dontAsk && KMessageBox::Yes != KMessageBox::warningYesNo(0,
988 i18n( "Do you want to drop the project \"%1\"?").arg( data->KexiDB::SchemaData::objectName())+ "\n"+warningNoUndo ))
997 i18n( "Could not drop this project. Database connection for this project has been opened as read only."));
1023#include "kexiproject.moc"
TQString serverInfoString(bool addUser=true) const A user-friendly string for the server.
Provides database connection, allowing queries and data modification.
virtual bool isReadOnly() const
bool dropDatabase(const TQString &dbName=TQString()) Drops database with name dbName.
Transaction beginTransaction() Creates new transaction handle and starts a new transaction.
ConnectionData * data() const
Cursor * executeQuery(const TQString &statement, uint cursor_options=0)
Provides database cursor functionality.
virtual TQVariant value(uint i)=0
Connection * connection() const
A set of storable database properties.
bool setValue(const TQString &name, const TQVariant &value)
TQVariant value(const TQString &name)
bool setCaption(const TQString &name, const TQString &caption)
Driver * driver(const TQString &name)
Generic database abstraction.
Connection * createConnection(ConnectionData &conn_data, int options=0)
@ ReadOnlyConnection set to perform read only connection
FieldList * subList(const TQString &n1, const TQString &n2=TQString(), const TQString &n3=TQString(), const TQString &n4=TQString(), const TQString &n5=TQString(), const TQString &n6=TQString(), const TQString &n7=TQString(), const TQString &n8=TQString(), const TQString &n9=TQString(), const TQString &n10=TQString(), const TQString &n11=TQString(), const TQString &n12=TQString(), const TQString &n13=TQString(), const TQString &n14=TQString(), const TQString &n15=TQString(), const TQString &n16=TQString(), const TQString &n17=TQString(), const TQString &n18=TQString())
FieldList & addField(Field *field)
virtual void showErrorMessage(const TQString &title, const TQString &details=TQString())=0
virtual void clearError()
virtual void setError(int code=ERR_OTHER, const TQString &msg=TQString())
const TQString & errorMsg() const
Parser for SQL statements.
Helper class for using inside methods for given connection.
const Transaction transaction() const
void setTransaction(const Transaction &trans)
This class encapsulates transaction handle.
Base class for child window of Kexi's main application window.
Kexi's main window interface This interface is implemented by KexiMainWindowImpl class.
Information about a Kexi Part (plugin).
int projectPartID() const
TQCString mimeType() const
Part item list with reimplemented compareItems() method.
Information about a single object that can be instantiated using Kexi Part.
Part * partForMimeType(const TQString &mimeTypt)
Info * infoForMimeType(const TQString &mimeType)
void lookup() queries ktrader and creates a list of available parts
The main class for kexi frontend parts like tables, queries, forms and reports.
KexiDialogBase * openInstance(KexiMainWindow *win, KexiPart::Item &item, int viewMode=Kexi::DataViewMode, TQMap< TQString, TQString > *staticObjectArgs=0)
TQString instanceCaption() const
virtual bool remove(KexiMainWindow *win, KexiPart::Item &item)
virtual tristate rename(KexiMainWindow *win, KexiPart::Item &item, const TQString &newName)
TQCString instanceName() const
Kexi project core data member.
TQString infoString(bool nobr=true) const
A project's main controller.
KexiPart::ItemDict * items(KexiPart::Info *i)
tristate openInternal(bool *incompatibleWithKexi) Used in open() and open(bool&).
KexiDialogBase * openObject(KexiMainWindow *wnd, KexiPart::Item &item, int viewMode=Kexi::DataViewMode, TQMap< TQString, TQString > *staticObjectArgs=0)
KexiPart::Part * findPartFor(KexiPart::Item &item)
KexiProjectData * data() const
bool createConnection() used to emit objectCreated() signal
bool removeObject(KexiMainWindow *wnd, KexiPart::Item &item)
KexiPart::Item * itemForMimeType(const TQCString &mimeType, const TQString &name)
KexiPart::Item * item(KexiPart::Info *i, const TQString &name)
KexiPart::ItemDict * itemsForMimeType(const TQCString &mimeType)
static tristate dropProject(KexiProjectData *data, KexiDB::MessageHandler *handler, bool dontAsk=false)
void getSortedItems(KexiPart::ItemList &list, KexiPart::Info *i) Puts a list of items of a type i in this project into list.
bool createInternalStructures(bool insideTransaction)
bool renameObject(KexiMainWindow *wnd, KexiPart::Item &item, const TQString &newName)
KexiProject(KexiProjectData *pdata, KexiDB::MessageHandler *handler=0)
void addStoredItem(KexiPart::Info *info, KexiPart::Item *item)
void itemRemoved(const KexiPart::Item &item) instance pointed by item is removed
void deleteUnstoredItem(KexiPart::Item *item)
void newItemStored(KexiPart::Item &item) New item has been stored.
KexiDB::Connection * dbConnection() const
void getSortedItemsForMimeType(KexiPart::ItemList &list, const TQCString &mimeType) Puts a sorted list of items of a type mimeType in this project into list.
static KexiProject * createBlankProject(bool &cancelled, KexiProjectData *data, KexiDB::MessageHandler *handler=0)
KexiPart::Item * createPartItem(KexiPart::Info *info, const TQString &suggestedCaption=TQString())
void itemRenamed(const KexiPart::Item &item, const TQCString &oldName) instance pointed by item is renamed
tristate create(bool forceOverwrite=false)
bool checkWritable() new table schema created
3-state logical type with three values: true, false and cancelled and convenient operators.
KEXIUTILS_EXPORT TQString string2Identifier(const TQString &s)
KEXIUTILS_EXPORT bool isIdentifier(const TQString &s)
KEXICORE_EXPORT KexiPart::Manager & partManager() shared part manager
KEXICORE_EXPORT KexiDB::DriverManager & driverManager() shared driver manager
|