int mpkgSys::requestUninstall(int package_id, mpkgDatabase *db, DependencyTracker *DepTracker, bool purge) { //printf("requestUninstall by ID, !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!ignoreDeps = %d\n", ignoreDeps); mDebug("requestUninstall\n"); PACKAGE tmpPackage; int ret = db->get_package(package_id, &tmpPackage); mDebug("uninstall called for id " + IntToStr(package_id) + ", name = " + tmpPackage.get_name() + "-" + tmpPackage.get_fullversion()); bool process=false; if (ret == 0) { if (tmpPackage.configexist()) { if (purge) { mDebug("action set to purge"); tmpPackage.set_action(ST_PURGE, "direct"); process=true; } else if (tmpPackage.installed()) { mDebug("action is remove"); tmpPackage.set_action(ST_REMOVE, "direct"); process=true; } } else { say(_("%s-%s doesn't present in the system\n"), tmpPackage.get_name().c_str(), tmpPackage.get_fullversion().c_str()); } if (process) { mDebug("Processing deps"); if (!ignoreDeps) { //printf("added to remove queue\n"); DepTracker->addToRemoveQuery(tmpPackage); } else { if (purge) db->set_action(tmpPackage.get_id(), ST_PURGE, "direct"); else db->set_action(tmpPackage.get_id(), ST_REMOVE, "direct"); } return 0; } else { if (purge) mError(_("Package ") + tmpPackage.get_name() + " "+ tmpPackage.get_fullversion() + _(" is already purged")); else mError(_("Package ") + tmpPackage.get_name() + " " + tmpPackage.get_fullversion() + _(" is already purged")); ; return MPKGERROR_IMPOSSIBLE; } } else { return ret; } }
// New, very very fast function. The only one who should be used, if fact int mpkgSys::requestInstall(vector<string> package_name, vector<string> package_version, vector<string> package_build, mpkgDatabase *db, DependencyTracker *DepTracker, vector<string> *eList) { // First of all, check for local packages vector<int> localPackages; vector<bool> isLocal(package_name.size(), false); LocalPackage *_p; string pkgType; for (size_t i=0; i<package_name.size(); i++) { pkgType=getExtension(package_name[i]); if (pkgType=="txz" || pkgType == "tbz" || pkgType == "tlz" || pkgType=="tgz" || pkgType == "spkg") { if (FileExists(package_name[i])) { _p = new LocalPackage(package_name[i]); _p->injectFile(); db->emerge_to_db(&_p->data); package_name[i] = _p->data.get_name(); package_version[i] = _p->data.get_version(); package_build[i] = _p->data.get_build(); isLocal[i]=true; //printf("\nDetected local package\nFilename: %s\nName:%s\nVersion:%s\n", _p->data.get_filename().c_str(), _p->data.get_name().c_str(), _p->data.get_version().c_str()); localPackages.push_back(_p->data.get_id()); delete _p; } } } vector<string> errorList; //printf("using error list\n"); // Creating DB cache // 1. Creating a request for all packages which are in package_name vector. SQLRecord sqlSearch; sqlSearch.setSearchMode(SEARCH_IN); for (size_t i=0; i<package_name.size(); i++) { if (isLocal[i]) { continue; } sqlSearch.addField("package_name", package_name[i]); } // 2. Requesting database by search array PACKAGE_LIST pCache; //printf("SLOW GET_PACKAGELIST CALL: %s %d\n", __func__, __LINE__); int query_ret = db->get_packagelist(sqlSearch, &pCache, true, false); if (query_ret != 0) { errorList.push_back(mError("Error querying database")); if (eList) *eList = errorList; return MPKGERROR_SQLQUERYERROR; } // 3. Temporary matrix, temporary list (for each package), and result list vector<PACKAGE_LIST> tmpMatrix; PACKAGE_LIST *tmpList=new PACKAGE_LIST; PACKAGE_LIST resultList; PACKAGE_LIST uninstallList; // 4. Search by cache for installed ones, check for availability and select the appropriate versions // 4.1 Building matrix: one vector per list of packages with same name for (size_t i=0; i<package_name.size(); i++) { delete tmpList; tmpList = new PACKAGE_LIST; for (size_t t=0; t<pCache.size(); t++) { if (pCache.at(t).get_name() == package_name[i]) { if (isLocal[i] && pCache[t].get_id()!=localPackages[i]) continue; tmpList->add(pCache.at(t)); } } tmpMatrix.push_back(*tmpList); } //printf("tmpMatrix[0] size = %d\n", tmpMatrix[0].size()); // So, the matrix has been created. // In case of any error, collect all of them, and return MPKGERROR_IMPOSSIBLE // Sizes of tmpMatrix and input vectors are the same, so we can use any of them PACKAGE *outPackage = NULL, *installedOne = NULL; for (size_t i=0; i<tmpMatrix.size(); i++) { delete tmpList; tmpList = new PACKAGE_LIST; for (size_t t=0; t<tmpMatrix[i].size(); t++) { // Filling the tmpList with reachable (=installed or available) ones for each package if (tmpMatrix[i].at(t).available(true) || tmpMatrix[i].at(t).installed()) { if (package_version[i].empty() || tmpMatrix[i].at(t).get_version() == package_version[i]) { if (package_build[i].empty() || package_build[i]==tmpMatrix[i].at(t).get_build()) tmpList->add(tmpMatrix[i][t]); } } } // Now, we have a list of all good candidates. We will filter already installed ones separately for better UI output. tmpList->initVersioning(); outPackage = tmpList->getMaxVersion(); //if (outPackage) printf("outPackage VERSION: %s\n", outPackage->get_fullversion().c_str()); installedOne = (PACKAGE *) tmpMatrix[i].getInstalledOne(); if (outPackage == NULL) { string errorText = _("Requested package ") + package_name[i]; if (!package_version[i].empty()) errorText += "-" + package_version[i]; if (!package_build[i].empty()) errorText += "-" + package_build[i]; if (!installedOne) errorList.push_back(mError(errorText + _(" cannot be found"))); else errorList.push_back(mError(errorText + _(" is already installed"))); } else { //printf("____________________________CHECK FOR UPDATE, installedOne: %p_____________________________\n", installedOne); // Check for update if (installedOne && outPackage->get_id() != installedOne->get_id()) { // This is update //printf("added to uninstall: %d\n", installedOne->get_id()); uninstallList.add(*installedOne); } resultList.add(*outPackage); } } delete tmpList; // Special addition for local packages installed using -z key: check for installed one for (size_t i=0; i<isLocal.size(); ++i) { if (!isLocal[i]) continue; for (size_t t=0; t<pCache.size(); ++t) { if (pCache[t].installed() && pCache[t].get_id()!=localPackages[i] && pCache[t].get_name()==package_name[i]) { requestUninstall(pCache.get_package_ptr(t), db, DepTracker); } } } // Now, check resultList for installed ones and unavailable ones for (size_t i=0; i<resultList.size(); i++) { if (resultList[i].installed()) { mWarning(_("Package ") + resultList[i].get_name() + "-" + resultList[i].get_fullversion() + _(" is already installed")); } else { if (!resultList[i].available(true)) { errorList.push_back(mError(_("Package ") + resultList[i].get_name() + "-" + resultList[i].get_fullversion() + _(" is unavailable"))); } } } // NEW: ignore already installed packages tmpList = new PACKAGE_LIST; for (size_t i=0; i<resultList.size(); ++i) { if (!resultList[i].installed()) { tmpList->add(resultList[i]); } } resultList = *tmpList; delete tmpList; //printf("resultList size = %d\n", resultList.size()); if (errorList.empty()) { // Push to database __requestInstallPkgList(&resultList, db, DepTracker); for (size_t i=0; i<uninstallList.size(); i++) requestUninstall(uninstallList.get_package_ptr(i), db, DepTracker); } else { mError(_("Errors detected, cannot continue")); if (eList) *eList = errorList; return MPKGERROR_IMPOSSIBLE; } if (eList) *eList = errorList; return 0; }