int mpkgSys::requestUninstall(string package_name, mpkgDatabase *db, DependencyTracker *DepTracker, bool purge) { //printf("requestUninstall by name !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); mDebug("requestUninstall of " + package_name); SQLRecord sqlSearch; sqlSearch.addField("package_name", package_name); if (!purge) sqlSearch.addField("package_installed", 1); else sqlSearch.addField("package_configexist",1); PACKAGE_LIST candidates; //printf("SLOW GET_PACKAGELIST CALL: %s %d\n", __func__, __LINE__); int ret = db->get_packagelist(sqlSearch, &candidates, true, false); mDebug("candidates to uninstall size = " + IntToStr(candidates.size())); int id=-1; if (ret == 0) { if (candidates.size()>1) { mError(_("Ambiguity in uninstall: multiple packages with some name are installed")); return MPKGERROR_AMBIGUITY; } if (candidates.IsEmpty()) { mError(_("Cannot remove package ") + package_name + _(": not installed")); return MPKGERROR_NOPACKAGE; } id = candidates[0].get_id(); if (id>=0) { return requestUninstall(id, db, DepTracker, purge); } else return MPKGERROR_NOPACKAGE; } else return ret; }
void mpkgSys::clean_queue(mpkgDatabase *db) { PACKAGE_LIST toInstall; SQLRecord sqlSearch; sqlSearch.setSearchMode(SEARCH_IN); sqlSearch.addField("package_action", ST_INSTALL); sqlSearch.addField("package_action", ST_REMOVE); sqlSearch.addField("package_action", ST_PURGE); sqlSearch.addField("package_action", ST_REPAIR); sqlSearch.addField("package_action", ST_UPDATE); db->get_packagelist(sqlSearch, &toInstall, true); for (size_t i=0; i<toInstall.size(); ++i) { db->set_action(toInstall[i].get_id(), ST_NONE, "clean"); } db->clear_unreachable_packages(); }
bool mpkg::checkPackageIntegrity(string pkgName) { SQLRecord sqlSearch; sqlSearch.addField("package_name", &pkgName); sqlSearch.addField("package_installed", ST_INSTALLED); PACKAGE_LIST table; get_packagelist(&sqlSearch, &table); if (table.size()==0) { mError(_("No package \"") + pkgName + _("\" is installed")); return true; } if (table.size()!=1) { mError(_("Received ") + IntToStr(table.size()) + _(" packages, ambiguity!")); return false; } return checkPackageIntegrity(table.get_package(0)); }
void mpkg::exportBase(string output_dir) { say("Exporting data to %s directory\n",output_dir.c_str()); // First of all, clear previous contents system("rm -rf " + output_dir+"; mkdir -p " + output_dir); PACKAGE_LIST allPackages; SQLRecord sqlSearch; sqlSearch.addField("package_installed", 1); get_packagelist(&sqlSearch, &allPackages); say("Received %d packages\n",allPackages.size()); for (int i=0; i<allPackages.size(); i++) { say("[%d/%d] Exporting package %s\n",i+1,allPackages.size(),allPackages.get_package(i)->get_name()->c_str()); db->exportPackage(output_dir, allPackages.get_package(i)); } }
bool mpkg::repair(string fname) { SQLRecord sqlSearch; sqlSearch.addField("package_name", &fname); sqlSearch.addField("package_installed", 1); PACKAGE_LIST p; get_packagelist(&sqlSearch, &p); if (p.size()==1) { return repair(p.get_package(0)); } else { say(_("Cannot repair or reinstall package %s: it is not installed\n"), fname.c_str()); return false; } }
// 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; }