From kde-commits Wed Aug 31 22:12:37 2011 From: Stephane Mankowski Date: Wed, 31 Aug 2011 22:12:37 +0000 To: kde-commits Subject: [skrooge/Feature] /: Correction: Cascading delete in categories and Message-Id: <20110831221237.0BBD5A6078 () git ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=131482877829124 Git commit 8ae1b10088503c09837ff149b6542fc8d990e907 by Stephane Mankowski. Committed on 01/09/2011 at 00:10. Pushed by smankowski into branch 'Feature'. Correction: Cascading delete in categories and bookmarks M +1 -1 skgbankmodeler/skgcategoryobject.h M +1 -0 CHANGELOG M +8 -8 skgbasemodeler/skgnodeobject.cpp M +4 -5 plugins/skrooge/skrooge_categories/skgcategoriesplugin.cpp M +8 -8 skgbankmodeler/skgcategoryobject.cpp M +40 -15 skgbasemodeler/skgdocument.cpp M +47 -41 skgbankmodeler/skgdocumentbank.cpp M +2 -2 plugins/generic/skg_bookmark/skgbookmarkplugin.cpp M +1 -1 plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.cpp M +26 -0 tests/skgbankmodelertest/skgtestcategory.cpp M +1 -1 plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.cpp M +1 -1 skgbasemodeler/skgnodeobject.h http://commits.kde.org/skrooge/8ae1b10088503c09837ff149b6542fc8d990e907 diff --git a/CHANGELOG b/CHANGELOG index 74f9d6b..698569a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,7 @@ skrooge (1.0.0) *Correction: To improve performances, the refresh of graphs is done for graphs in current page *Correction: "Delete unused" of category page tries a delete only on categories really not used *Correction: Various correction in bookmarks (enable/disable in menu, bad management in parent/child relation) + *Correction: Cascading delete in categories and bookmarks *New feature: New function to bookmark all opened page in one click *New feature: Addition of "Once a week" for scheduled operations *New feature: Merge of trackers by drag & drop diff --git a/plugins/generic/skg_bookmark/skgbookmarkplugin.cpp b/plugins/generic/skg_bookmark/skgbookmarkplugin.cpp index e4533ee..6061376 100644 --- a/plugins/generic/skg_bookmark/skgbookmarkplugin.cpp +++ b/plugins/generic/skg_bookmark/skgbookmarkplugin.cpp @@ -235,9 +235,9 @@ void SKGBookmarkPlugin::onShowBookmarkMenu() callerMenu->clear(); //Build query - QString wc = "r_node_id=0 OR r_node_id IS NULL OR r_node_id=''"; + QString wc = "rd_node_id=0 OR rd_node_id IS NULL OR rd_node_id=''"; int idParent = callerMenu->property("id").toInt(); - if(idParent != 0) wc = "r_node_id=" % SKGServices::intToString(idParent); + if(idParent != 0) wc = "rd_node_id=" % SKGServices::intToString(idParent); //Build new menu SKGObjectBase::SKGListSKGObjectBase listNode; diff --git a/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.cpp b/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.cpp index f3241ea..49bde35 100644 --- a/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.cpp +++ b/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.cpp @@ -98,7 +98,7 @@ SKGBookmarkPluginDockWidget::SKGBookmarkPluginDockWidget(SKGDocument* iDocument) m_mainMenu->addAction(SKGMainPanel::getMainPanel()->getGlobalAction("tab_overwritebookmark")); //Add model - m_modelview = new SKGObjectModelBase(getDocument(), "v_node", "1=1 ORDER BY f_sortorder, t_name", this, "r_node_id"); + m_modelview = new SKGObjectModelBase(getDocument(), "v_node", "1=1 ORDER BY f_sortorder, t_name", this, "rd_node_id"); SKGSortFilterProxyModel* modelproxy = new SKGSortFilterProxyModel(this); modelproxy->setSourceModel(m_modelview); ui.kBookmarksList->setModel(modelproxy); diff --git a/plugins/skrooge/skrooge_categories/skgcategoriesplugin.cpp b/plugins/skrooge/skrooge_categories/skgcategoriesplugin.cpp index 98e0844..69ce8f6 100644 --- a/plugins/skrooge/skrooge_categories/skgcategoriesplugin.cpp +++ b/plugins/skrooge/skrooge_categories/skgcategoriesplugin.cpp @@ -218,11 +218,10 @@ void SKGCategoriesPlugin::deleteUnusedCategories() const if(pos != -1) categoriesUsed.push_back(cat.left(pos)); } - if(categoriesUsed.count() && !err) { - - //Modification of category object - QString sql = "DELETE FROM category WHERE t_fullname NOT IN ('" % categoriesUsed.join("','") % "')"; - ; + if(!err) { + QString sql; + if(categoriesUsed.count()) sql = "DELETE FROM category WHERE t_fullname NOT IN ('" % categoriesUsed.join("','") % "')"; + else sql = "DELETE FROM category"; err = m_currentBankDocument->executeSqliteOrder(sql); } diff --git a/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.cpp b/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.cpp index 760339a..d86d3b2 100644 --- a/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.cpp +++ b/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.cpp @@ -59,7 +59,7 @@ SKGCategoriesPluginWidget::SKGCategoriesPluginWidget(SKGDocumentBank* iDocument) ui.kModifyCategoryButton->setIcon(KIcon("dialog-ok-apply")); ui.kDeleteUnusedButton->setIcon(KIcon("edit-delete")); - ui.kCategoriesView->setModel(new SKGObjectModel(static_cast(getDocument()), "v_category_display", "1=0", this, "r_category_id", false)); + ui.kCategoriesView->setModel(new SKGObjectModel(static_cast(getDocument()), "v_category_display", "1=0", this, "rd_category_id", false)); ui.kCategoriesView->getView()->setRootIsDecorated(true); ui.kCategoriesView->getView()->resizeColumnToContents(0); ui.kCategoriesView->getView()->header()->setStretchLastSection(false); diff --git a/skgbankmodeler/skgcategoryobject.cpp b/skgbankmodeler/skgcategoryobject.cpp index 3f7a402..e5cfdf7 100644 --- a/skgbankmodeler/skgcategoryobject.cpp +++ b/skgbankmodeler/skgcategoryobject.cpp @@ -71,10 +71,10 @@ QString SKGCategoryObject::getWhereclauseId() const if(!(getAttribute("t_name").isEmpty())) { output = "t_name='" % SKGServices::stringToSqlString(getAttribute("t_name")) % '\''; } - QString r_category_id = getAttribute("r_category_id"); + QString rd_category_id = getAttribute("rd_category_id"); if(!output.isEmpty()) output += " AND "; - if(r_category_id.isEmpty()) output += "(r_category_id=0 OR r_category_id IS NULL OR r_category_id='')"; - else output += "r_category_id=" % r_category_id; + if(rd_category_id.isEmpty()) output += "(rd_category_id=0 OR rd_category_id IS NULL OR rd_category_id='')"; + else output += "rd_category_id=" % rd_category_id; } return output; } @@ -163,7 +163,7 @@ SKGError SKGCategoryObject::addCategory(SKGCategoryObject& oCategory) if(getID() == 0) err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database." , QString("SKGCategoryObject::addCategory"))); else { oCategory = SKGCategoryObject(static_cast(getDocument())); - err = oCategory.setAttribute("r_category_id", SKGServices::intToString(getID())); + err = oCategory.setAttribute("rd_category_id", SKGServices::intToString(getID())); } return err; } @@ -186,20 +186,20 @@ SKGError SKGCategoryObject::setParentCategory(const SKGCategoryObject& iCategory } } while(!err && current.getID() != 0); - if(!err) err = setAttribute("r_category_id", SKGServices::intToString(iCategory.getID())); + if(!err) err = setAttribute("rd_category_id", SKGServices::intToString(iCategory.getID())); } return err; } SKGError SKGCategoryObject::removeParentCategory() { - return setAttribute("r_category_id", ""); + return setAttribute("rd_category_id", ""); } SKGError SKGCategoryObject::getParentCategory(SKGCategoryObject& oCategory) const { SKGError err; - QString parent_id = getAttribute("r_category_id"); + QString parent_id = getAttribute("rd_category_id"); if(!parent_id.isEmpty()) err = getDocument()->getObject("v_category", "id=" % parent_id , oCategory); return err; } @@ -225,7 +225,7 @@ SKGError SKGCategoryObject::getRootCategory(SKGCategoryObject& oCategory) const SKGError SKGCategoryObject::getCategories(SKGListSKGObjectBase& oCategoryList) const { return getDocument()->getObjects("v_category", - "r_category_id=" % SKGServices::intToString(getID()), + "rd_category_id=" % SKGServices::intToString(getID()), oCategoryList); } diff --git a/skgbankmodeler/skgcategoryobject.h b/skgbankmodeler/skgcategoryobject.h index d37916f..01f6ab7 100644 --- a/skgbankmodeler/skgcategoryobject.h +++ b/skgbankmodeler/skgcategoryobject.h @@ -182,7 +182,7 @@ public: protected: /** * Get where clause needed to identify objects. - * For this class, the whereclause is based on name + r_category_id + * For this class, the whereclause is based on name + rd_category_id * @return the where clause */ virtual QString getWhereclauseId() const; diff --git a/skgbankmodeler/skgdocumentbank.cpp b/skgbankmodeler/skgdocumentbank.cpp index 0b412ee..49d4457 100644 --- a/skgbankmodeler/skgdocumentbank.cpp +++ b/skgbankmodeler/skgdocumentbank.cpp @@ -165,7 +165,7 @@ SKGError SKGDocumentBank::endTransaction(bool succeedded) QString SKGDocumentBank::getViewsIndexesAndTriggersVersion() { - return "2011.08.19_" % getParameter("SKG_LANGUAGE"); + return "2011.08.31_" % getParameter("SKG_LANGUAGE"); } SKGError SKGDocumentBank::refreshViewsIndexesAndTriggers() @@ -212,48 +212,35 @@ SKGError SKGDocumentBank::refreshViewsIndexesAndTriggers() << "DROP TRIGGER IF EXISTS cpt_category_fullname3" /* << "CREATE TRIGGER cpt_category_fullname1 " //This trigger must be the first "AFTER UPDATE OF t_fullname ON category BEGIN " - "UPDATE category SET t_name=t_name WHERE r_category_id=new.id;" + "UPDATE category SET t_name=t_name WHERE rd_category_id=new.id;" "END"*/ << "DROP TRIGGER IF EXISTS cpt_category_fullname1" << "CREATE TRIGGER cpt_category_fullname1 " "AFTER INSERT ON category BEGIN " "UPDATE category SET t_fullname=" - "CASE WHEN r_category_id IS NULL OR r_category_id='' OR r_category_id=0 THEN new.t_name ELSE (SELECT c.t_fullname FROM category c WHERE c.id=new.r_category_id)||'" % OBJECTSEPARATOR % "'||new.t_name END " + "CASE WHEN rd_category_id IS NULL OR rd_category_id='' OR rd_category_id=0 THEN new.t_name ELSE (SELECT c.t_fullname FROM category c WHERE c.id=new.rd_category_id)||'" % OBJECTSEPARATOR % "'||new.t_name END " "WHERE id=new.id;" "END" << "DROP TRIGGER IF EXISTS cpt_category_fullname2" << "CREATE TRIGGER cpt_category_fullname2 " - "AFTER UPDATE OF t_name, r_category_id ON category BEGIN " + "AFTER UPDATE OF t_name, rd_category_id ON category BEGIN " "UPDATE category SET t_fullname=" - "CASE WHEN r_category_id IS NULL OR r_category_id='' OR r_category_id=0 THEN new.t_name ELSE (SELECT c.t_fullname FROM category c WHERE c.id=new.r_category_id)||'" % OBJECTSEPARATOR % "'||new.t_name END " + "CASE WHEN rd_category_id IS NULL OR rd_category_id='' OR rd_category_id=0 THEN new.t_name ELSE (SELECT c.t_fullname FROM category c WHERE c.id=new.rd_category_id)||'" % OBJECTSEPARATOR % "'||new.t_name END " "WHERE id=new.id;" - "UPDATE category SET t_name=t_name WHERE r_category_id=new.id;" + "UPDATE category SET t_name=t_name WHERE rd_category_id=new.id;" "END" - //-- Cascading delete - WARNING rewriten for skrooge to support recursive mode - << "DROP TRIGGER IF EXISTS fkdc_category_parent_id_category_id" - << "CREATE TRIGGER fkdc_category_parent_id_category_id " - "BEFORE DELETE ON category " - "FOR EACH ROW BEGIN " - " DELETE FROM category WHERE category.t_fullname LIKE OLD.t_fullname||'" % OBJECTSEPARATOR % "%'; " - "END " - //-- Reparent suboperation on parent category when a category is removed << "DROP TRIGGER IF EXISTS fkdc_category_delete" << "CREATE TRIGGER fkdc_category_delete " "BEFORE DELETE ON category " "FOR EACH ROW BEGIN " - " UPDATE suboperation SET r_category_id=OLD.r_category_id WHERE r_category_id=OLD.id; " + " UPDATE suboperation SET r_category_id=OLD.rd_category_id WHERE r_category_id=OLD.id; " "END " - /* "CREATE TRIGGER fkdc_category_parent_id_category_id " - "BEFORE DELETE ON category " - "FOR EACH ROW BEGIN " - " DELETE FROM category WHERE category.r_category_id=OLD.id; " - "END "*/ - + << "DROP TRIGGER IF EXISTS fkdc_category_parent_id_category_id" ; /** * This constant is used to initialized the data model (index creation) @@ -271,9 +258,9 @@ SKGError SKGDocumentBank::refreshViewsIndexesAndTriggers() << "CREATE INDEX idx_account_bank_id ON account(rd_bank_id)" << "CREATE INDEX idx_account_type ON account(t_type)" - << "CREATE INDEX idx_category_category_id ON category(r_category_id)" + << "CREATE INDEX idx_category_category_id ON category(rd_category_id)" << "CREATE INDEX idx_category_t_fullname ON category(t_fullname)" - << "CREATE UNIQUE INDEX uidx_category_parent_id_name ON category(t_name,r_category_id)" + << "CREATE UNIQUE INDEX uidx_category_parent_id_name ON category(t_name,rd_category_id)" << "CREATE UNIQUE INDEX uidx_category_fullname ON category(t_fullname)" << "CREATE INDEX idx_operation_account_id ON operation (rd_account_id)" @@ -816,11 +803,11 @@ SKGError SKGDocumentBank::migrate(bool& oMigrationDone) "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," "t_name TEXT NOT NULL DEFAULT '' CHECK (t_name NOT LIKE '%" % OBJECTSEPARATOR % "%')," "t_fullname TEXT," - "r_category_id INT," + "rd_category_id INT," "t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N'))" ")" - << "CREATE TABLE vm_category_display_tmp( id INT, t_name TEXT, t_fullname TEXT, r_category_id INT, i_NBOPERATIONS, f_REALCURRENTAMOUNT, t_bookmarked)" + << "CREATE TABLE vm_category_display_tmp( id INT, t_name TEXT, t_fullname TEXT, rd_category_id INT, i_NBOPERATIONS, f_REALCURRENTAMOUNT, t_bookmarked)" // ================================================================== //Table operation @@ -944,7 +931,7 @@ SKGError SKGDocumentBank::migrate(bool& oMigrationDone) if(!err) err = this->executeSqliteOrders(BankInitialDataModel); //Set new version - version = "6.8"; + version = "6.9"; if(!err) err = SKGDocument::setParameter("SKG_DB_BANK_VERSION", version); } @@ -1651,7 +1638,7 @@ SKGError SKGDocumentBank::migrate(bool& oMigrationDone) << "" << "6.3" << "6.4" - << "CREATE TABLE vm_category_display_tmp( id INT, t_name TEXT, t_fullname TEXT, r_category_id INT, i_NBOPERATIONS, f_REALCURRENTAMOUNT)" + << "CREATE TABLE vm_category_display_tmp( id INT, t_name TEXT, t_fullname TEXT, rd_category_id INT, i_NBOPERATIONS, f_REALCURRENTAMOUNT)" //============ << "" << "6.4" @@ -1670,7 +1657,7 @@ SKGError SKGDocumentBank::migrate(bool& oMigrationDone) << "6.6" << "6.7" << "DROP TABLE IF EXISTS vm_category_display_tmp" - << "CREATE TABLE vm_category_display_tmp( id INT, t_name TEXT, t_fullname TEXT, r_category_id INT, i_NBOPERATIONS, f_REALCURRENTAMOUNT, t_bookmarked)" + << "CREATE TABLE vm_category_display_tmp( id INT, t_name TEXT, t_fullname TEXT, rd_category_id INT, i_NBOPERATIONS, f_REALCURRENTAMOUNT, t_bookmarked)" //============ << "" << "6.7" @@ -1694,6 +1681,25 @@ SKGError SKGDocumentBank::migrate(bool& oMigrationDone) << "DROP TABLE IF EXISTS recurrentoperation" << "ALTER TABLE recurrentoperation2 RENAME TO recurrentoperation" + //============ + << "" + << "6.8" + << "6.9" + << "CREATE TABLE category2 (" + "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," + "t_name TEXT NOT NULL DEFAULT '' CHECK (t_name NOT LIKE '%" % OBJECTSEPARATOR % "%')," + "t_fullname TEXT," + "rd_category_id INT," + "t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N'))" + ")" + << "INSERT INTO category2 (id, t_name, t_fullname, rd_category_id, t_bookmarked) " + "SELECT id, t_name, t_fullname, r_category_id, t_bookmarked FROM category" + + << "DROP TABLE IF EXISTS category" + << "ALTER TABLE category2 RENAME TO category" + + << "DROP TABLE IF EXISTS vm_category_display_tmp" + << "CREATE TABLE vm_category_display_tmp( id INT, t_name TEXT, t_fullname TEXT, rd_category_id INT, i_NBOPERATIONS, f_REALCURRENTAMOUNT, t_bookmarked)" ; } @@ -1796,7 +1802,7 @@ SKGError SKGDocumentBank::dump(int iMode) if(iMode & DUMPCATEGORY) { SKGTRACE << "=== DUMPCATEGORY ===" << endl; - err.addError(dumpSelectSqliteOrder("SELECT * FROM v_category_display ORDER BY r_category_id, id")); + err.addError(dumpSelectSqliteOrder("SELECT * FROM v_category_display ORDER BY rd_category_id, id")); } SKGTRACE << "=== END DUMP BANK DOCUMENT ===" << endl; @@ -1805,7 +1811,7 @@ SKGError SKGDocumentBank::dump(int iMode) return err; } -SKGError SKGDocumentBank::addOrModifyUnitValue(const QString& iUnitName, const QDate& iDate, double iValue, SKGUnitValueObject* oValue) +SKGError SKGDocumentBank::addOrModifyUnitValue(const QString & iUnitName, const QDate & iDate, double iValue, SKGUnitValueObject * oValue) { SKGError err; SKGTRACEINRC(10, "SKGDocumentBank::addOrModifyUnitValue", err); @@ -1888,7 +1894,7 @@ SKGServices::SKGUnitInfo SKGDocumentBank::getSecondaryUnit() return output; } -void SKGDocumentBank::refreshCache(const QString& iTable) +void SKGDocumentBank::refreshCache(const QString & iTable) { if(iTable == "unit") { SKGStringListList result; @@ -1918,7 +1924,7 @@ void SKGDocumentBank::refreshCache(const QString& iTable) } } -SKGError SKGDocumentBank::addOrModifyAccount(const QString& iName, const QString& iNumber, const QString& iBankName) +SKGError SKGDocumentBank::addOrModifyAccount(const QString & iName, const QString & iNumber, const QString & iBankName) { SKGError err; SKGTRACEINRC(10, "SKGDocumentBank::addOrModifyAccount", err); @@ -1950,7 +1956,7 @@ QString SKGDocumentBank::getDocumentHeader() const return "SKROOGE"; } -QList SKGDocumentBank::getDisplaySchemas(const QString& iRealTable) const +QList SKGDocumentBank::getDisplaySchemas(const QString & iRealTable) const { QList listSchema; @@ -2205,7 +2211,7 @@ QList SKGDocumentBank::getDisplaySchemas(const QS return listSchema ; } -QIcon SKGDocumentBank::getIcon(const QString& iString) const +QIcon SKGDocumentBank::getIcon(const QString & iString) const { QString att = iString.toLower(); @@ -2273,7 +2279,7 @@ QIcon SKGDocumentBank::getIcon(const QString& iString) const return SKGDocument::getIcon(iString); } -QString SKGDocumentBank::getDisplay(const QString& iString) const +QString SKGDocumentBank::getDisplay(const QString & iString) const { QString output = iString.toLower(); @@ -2376,14 +2382,14 @@ QString SKGDocumentBank::getDisplay(const QString& iString) const return SKGDocument::getDisplay(iString); } -QString SKGDocumentBank::getRealAttribute(const QString& iString) const +QString SKGDocumentBank::getRealAttribute(const QString & iString) const { if(iString.endsWith(QLatin1String("t_BANK"))) return "bank.rd_bank_id.t_name"; if(iString.endsWith(QLatin1String("t_BANK_NUMBER"))) return "bank.rd_bank_id.t_bank_number"; return SKGDocument::getRealAttribute(iString); } -SKGServices::AttributeType SKGDocumentBank::getAttributeType(const QString& iAttributeName) const +SKGServices::AttributeType SKGDocumentBank::getAttributeType(const QString & iAttributeName) const { SKGServices::AttributeType output = SKGServices::TEXT; if(iAttributeName == "t_status" || iAttributeName == "t_imported") return SKGServices::TRISTATE; @@ -2393,7 +2399,7 @@ SKGServices::AttributeType SKGDocumentBank::getAttributeType(const QString& iAtt } -QString SKGDocumentBank::getBudget(const QString& iMonth) +QString SKGDocumentBank::getBudget(const QString & iMonth) { SKGTRACEIN(10, "SKGDocumentBank::getBudget"); QString html; @@ -2447,7 +2453,7 @@ QString SKGDocumentBank::getBudget(const QString& iMonth) return html; } -QString SKGDocumentBank::get5MainCategories(const QString& iMonth, bool iChart) +QString SKGDocumentBank::get5MainCategories(const QString & iMonth, bool iChart) { SKGTRACEIN(10, "SKGDocumentBank::get5MainCategories"); QString html; @@ -2493,7 +2499,7 @@ QString SKGDocumentBank::get5MainCategories(const QString& iMonth, bool iChart) return html; } -QString SKGDocumentBank::get5MainCategoriesVariation(const QString& iMonth, const QString& iPreviousMonth, bool iOnlyIssues) +QString SKGDocumentBank::get5MainCategoriesVariation(const QString & iMonth, const QString & iPreviousMonth, bool iOnlyIssues) { SKGTRACEIN(10, "SKGDocumentBank::get5MainCategoriesVariation"); QString html; @@ -2506,7 +2512,7 @@ QString SKGDocumentBank::get5MainCategoriesVariation(const QString& iMonth, cons return html; } -QStringList SKGDocumentBank::get5MainCategoriesVariationList(const QString& iMonth, const QString& iPreviousMonth, bool iOnlyIssues, QStringList* oCategoryList) +QStringList SKGDocumentBank::get5MainCategoriesVariationList(const QString & iMonth, const QString & iPreviousMonth, bool iOnlyIssues, QStringList * oCategoryList) { SKGTRACEIN(10, "SKGDocumentBank::get5MainCategoriesVariationList"); //Compute input string diff --git a/skgbasemodeler/skgdocument.cpp b/skgbasemodeler/skgdocument.cpp index 42241ae..5d87017 100644 --- a/skgbasemodeler/skgdocument.cpp +++ b/skgbasemodeler/skgdocument.cpp @@ -930,7 +930,7 @@ SKGError SKGDocument::load(const QString & name, const QString & password, bool "f_sortorder FLOAT," "t_autostart VARCHAR(1) DEFAULT 'N' CHECK (t_autostart IN ('Y', 'N'))," "t_data TEXT," - "r_node_id INT CONSTRAINT fk_id REFERENCES node(id) ON DELETE CASCADE)" + "rd_node_id INT CONSTRAINT fk_id REFERENCES node(id) ON DELETE CASCADE)" // ================================================================== //Table doctransaction @@ -1181,33 +1181,27 @@ SKGError SKGDocument::refreshViewsIndexesAndTriggers() << "DROP TRIGGER IF EXISTS cpt_node_fullname3" /*<< "CREATE TRIGGER cpt_node_fullname1 " //This trigger must be the first "AFTER UPDATE OF t_fullname ON node BEGIN " - "UPDATE node SET t_name=t_name WHERE r_node_id=new.id;" + "UPDATE node SET t_name=t_name WHERE rd_node_id=new.id;" "END"*/ << "DROP TRIGGER IF EXISTS cpt_node_fullname1" << "CREATE TRIGGER cpt_node_fullname1 " "AFTER INSERT ON node BEGIN " "UPDATE node SET t_fullname=" - "CASE WHEN new.r_node_id IS NULL OR new.r_node_id='' OR new.r_node_id=0 THEN new.t_name ELSE (SELECT c.t_fullname from node c where c.id=new.r_node_id)||'" % OBJECTSEPARATOR % "'||new.t_name END " + "CASE WHEN new.rd_node_id IS NULL OR new.rd_node_id='' OR new.rd_node_id=0 THEN new.t_name ELSE (SELECT c.t_fullname from node c where c.id=new.rd_node_id)||'" % OBJECTSEPARATOR % "'||new.t_name END " "WHERE id=new.id;" "END" << "DROP TRIGGER IF EXISTS cpt_node_fullname2" << "CREATE TRIGGER cpt_node_fullname2 " - "AFTER UPDATE OF t_name, r_node_id ON node BEGIN " + "AFTER UPDATE OF t_name, rd_node_id ON node BEGIN " "UPDATE node SET t_fullname=" - "CASE WHEN new.r_node_id IS NULL OR new.r_node_id='' OR new.r_node_id=0 THEN new.t_name ELSE (SELECT c.t_fullname from node c where c.id=new.r_node_id)||'" % OBJECTSEPARATOR % "'||new.t_name END " + "CASE WHEN new.rd_node_id IS NULL OR new.rd_node_id='' OR new.rd_node_id=0 THEN new.t_name ELSE (SELECT c.t_fullname from node c where c.id=new.rd_node_id)||'" % OBJECTSEPARATOR % "'||new.t_name END " "WHERE id=new.id;" - "UPDATE node SET t_name=t_name WHERE r_node_id=new.id;" + "UPDATE node SET t_name=t_name WHERE rd_node_id=new.id;" "END" - //-- Cascading delete - WARNING rewriten to support recursive mode << "DROP TRIGGER IF EXISTS fkdc_node_parent_id_node_id" - << "CREATE TRIGGER fkdc_node_parent_id_node_id " - "BEFORE DELETE ON node " - "FOR EACH ROW BEGIN " - " DELETE FROM node WHERE node.t_fullname LIKE OLD.t_fullname||'" % OBJECTSEPARATOR % "%'; " - "END" ; /** @@ -1218,7 +1212,7 @@ SKGError SKGDocument::refreshViewsIndexesAndTriggers() << "CREATE UNIQUE INDEX uidx_parameters_uuid_parent_name ON parameters (t_uuid_parent, t_name)" << "DROP INDEX IF EXISTS uidx_node_parent_id_name" - << "CREATE UNIQUE INDEX uidx_node_parent_id_name ON node(t_name,r_node_id)" + << "CREATE UNIQUE INDEX uidx_node_parent_id_name ON node(t_name,rd_node_id)" << "DROP INDEX IF EXISTS uidx_node_fullname" << "CREATE UNIQUE INDEX uidx_node_fullname ON node(t_fullname)" @@ -1324,10 +1318,10 @@ SKGError SKGDocument::migrate(bool& oMigrationDone) if(!err && version.isEmpty()) { //First creation - SKGTRACEL(10) << "Migration from 0 to 1.3" << endl; + SKGTRACEL(10) << "Migration from 0 to 1.4" << endl; //Set new version - version = "1.3"; + version = "1.4"; if(!err) err = setParameter("SKG_DB_VERSION", version); //Set sqlite creation version @@ -1503,6 +1497,37 @@ SKGError SKGDocument::migrate(bool& oMigrationDone) if(!err) err = SKGDocument::setParameter("SKG_DB_VERSION", version); oMigrationDone = true; } + if(!err && version == "1.3") { + //Migration from version 1.0 to 1.1 + SKGTRACEL(10) << "Migration from 1.3 to 1.4" << endl; + + QStringList sql; + sql << "CREATE TABLE node2 (" + "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," + "t_name TEXT NOT NULL DEFAULT '' CHECK (t_name NOT LIKE '%" % OBJECTSEPARATOR % "%')," + "t_fullname TEXT," + "t_icon TEXT DEFAULT ''," + "f_sortorder FLOAT," + "t_autostart VARCHAR(1) DEFAULT 'N' CHECK (t_autostart IN ('Y', 'N'))," + "t_data TEXT," + "rd_node_id INT CONSTRAINT fk_id REFERENCES node(id) ON DELETE CASCADE)" + + << "INSERT INTO node2 (id, t_name, t_fullname, t_icon, f_sortorder, t_autostart, t_data, rd_node_id) " + "SELECT id, t_name, t_fullname, t_icon, f_sortorder, t_autostart, t_data, r_node_id FROM node" + + << "DROP TABLE IF EXISTS node" + << "ALTER TABLE node2 RENAME TO node" + ; + + err = executeSqliteOrders(sql); + + //Set new version + version = "1.4"; + if(!err) err = SKGDocument::setParameter("SKG_DB_VERSION", version); + oMigrationDone = true; + } + + //Refresh views if(!err) err = refreshViewsIndexesAndTriggers(); diff --git a/skgbasemodeler/skgnodeobject.cpp b/skgbasemodeler/skgnodeobject.cpp index c7f4c95..4b53305 100644 --- a/skgbasemodeler/skgnodeobject.cpp +++ b/skgbasemodeler/skgnodeobject.cpp @@ -66,10 +66,10 @@ QString SKGNodeObject::getWhereclauseId() const if(!(getAttribute("t_name").isEmpty())) { output = "t_name='" % SKGServices::stringToSqlString(getAttribute("t_name")) % '\''; } - QString r_node_id = getAttribute("r_node_id"); + QString rd_node_id = getAttribute("rd_node_id"); if(!output.isEmpty()) output += " AND "; - if(r_node_id.isEmpty()) output += "(r_node_id=0 OR r_node_id IS NULL OR r_node_id='')"; - else output += "r_node_id=" % r_node_id; + if(rd_node_id.isEmpty()) output += "(rd_node_id=0 OR rd_node_id IS NULL OR rd_node_id='')"; + else output += "rd_node_id=" % rd_node_id; } return output; } @@ -209,14 +209,14 @@ SKGError SKGNodeObject::addNode(SKGNodeObject& oNode) if(getID() == 0) err = SKGError(ERR_FAIL, i18nc("Error message: Something failed because of a database issue", "%1 failed because linked object is not yet saved in the database.", QString("SKGNodeObject::addNode"))); else { oNode = SKGNodeObject(getDocument()); - err = oNode.setAttribute("r_node_id", SKGServices::intToString(getID())); + err = oNode.setAttribute("rd_node_id", SKGServices::intToString(getID())); } return err; } SKGError SKGNodeObject::removeParentNode() { - return setAttribute("r_node_id", ""); + return setAttribute("rd_node_id", ""); } SKGError SKGNodeObject::setParentNode(const SKGNodeObject& iNode) @@ -237,7 +237,7 @@ SKGError SKGNodeObject::setParentNode(const SKGNodeObject& iNode) } } while(!err && current.getID() != 0); - if(!err) err = setAttribute("r_node_id", SKGServices::intToString(iNode.getID())); + if(!err) err = setAttribute("rd_node_id", SKGServices::intToString(iNode.getID())); } return err; } @@ -245,14 +245,14 @@ SKGError SKGNodeObject::setParentNode(const SKGNodeObject& iNode) SKGError SKGNodeObject::getParentNode(SKGNodeObject& oNode) const { SKGError err; - QString parent_id = getAttribute("r_node_id"); + QString parent_id = getAttribute("rd_node_id"); if(!parent_id.isEmpty()) err = getDocument()->getObject("v_node", "id=" % parent_id , oNode); return err; } SKGError SKGNodeObject::getNodes(SKGListSKGObjectBase& oNodeList) const { - return getDocument()->getObjects("v_node", "r_node_id=" % SKGServices::intToString(getID()) % " ORDER BY f_sortorder, t_name", oNodeList); + return getDocument()->getObjects("v_node", "rd_node_id=" % SKGServices::intToString(getID()) % " ORDER BY f_sortorder, t_name", oNodeList); } #include "skgnodeobject.moc" diff --git a/skgbasemodeler/skgnodeobject.h b/skgbasemodeler/skgnodeobject.h index d020b1f..a258412 100644 --- a/skgbasemodeler/skgnodeobject.h +++ b/skgbasemodeler/skgnodeobject.h @@ -217,7 +217,7 @@ public: protected: /** * Get where clause needed to identify objects. - * For this class, the whereclause is based on name + r_node_id + * For this class, the whereclause is based on name + rd_node_id * @return the where clause */ virtual QString getWhereclauseId() const; diff --git a/tests/skgbankmodelertest/skgtestcategory.cpp b/tests/skgbankmodelertest/skgtestcategory.cpp index 7d7e840..0840b55 100644 --- a/tests/skgbankmodelertest/skgtestcategory.cpp +++ b/tests/skgbankmodelertest/skgtestcategory.cpp @@ -235,6 +235,32 @@ int main(int argc, char** argv) SKGTESTERROR("CAT:merge", categoryB.merge(categoryA), true); } } + + //Cascading delete + { + SKGDocumentBank document1; + SKGTESTERROR("document1.initialize()", document1.initialize(), true); + SKGError err; + { + //Scope of the transaction + SKGBEGINTRANSACTION(document1, "NODE_T1", err); + + SKGCategoryObject categoryA; + SKGTESTERROR("NOD:createPathCategory", SKGCategoryObject::createPathCategory(&document1, "A" , categoryA), true); + SKGCategoryObject categoryC; + SKGTESTERROR("NOD:createPathCategory", SKGCategoryObject::createPathCategory(&document1, 'A' % OBJECTSEPARATOR % 'B' % OBJECTSEPARATOR % 'C', categoryC), true); + + QStringList oResult; + SKGTESTERROR("CAT:getDistinctValues", document1.getDistinctValues("category", "id", oResult), true); + SKGTEST("CAT:oResult.size", oResult.size(), 3); + + //Delete + SKGTESTERROR("CAT:remove", categoryA.remove(), true); + + SKGTESTERROR("CAT:getDistinctValues", document1.getDistinctValues("category", "id", oResult), true); + SKGTEST("CAT:oResult.size", oResult.size(), 0); + } + } //End test SKGENDTEST(); }