SQLRETURN RLibrarySession::UninstallLibrary()

in language-extensions/R/src/RLibrarySession.cpp [266:351]


SQLRETURN RLibrarySession::UninstallLibrary(
	const SQLCHAR *libraryInstallDirectory,
	SQLINTEGER    libraryInstallDirectoryLength)
{
	LOG("RLibrarySession::UninstallLibrary");
	SQLRETURN result = SQL_ERROR;

	string errorString;

	string installDir = string(static_cast<const char*>(
			static_cast<const void*>(libraryInstallDirectory)), libraryInstallDirectoryLength);
	installDir = Utilities::NormalizePathString(installDir);

	try
	{
		// Uninstall the given libName from the installDir path.
		//
		string uninstallScript = "remove.packages(pkgs = '" + m_libraryName +
			"', lib = '" + installDir + "');";
		ExecuteScript(uninstallScript);

		bool isInstalled = IsLibraryInstalledAtPath(installDir);
		if (isInstalled)
		{
			throw runtime_error("remove.packages() failed to uninstall the package " +
				m_libraryName + ".");
		}

		result = SQL_SUCCESS;
	}
	catch (const exception & ex)
	{
		result = SQL_ERROR;
		errorString = string(ex.what());
	}
	catch (...)
	{
		result = SQL_ERROR;
		errorString = "Unexpected exception occurred in function UninstallLibrary().";
	}

	// If remove.packages fails for some reason, we try to manually uninstall the package
	// by deleting the top level package folder.
	//
	if (result != SQL_SUCCESS && fs::exists(installDir))
	{
		LOG_ERROR(errorString);
		string libraryDir = Utilities::NormalizePathString(
			fs::path(installDir).append(m_libraryName).string());

		// Clean up the library directory folder
		//
		if (fs::exists(libraryDir))
		{
			LOG("Failed to completely uninstall " + m_libraryName + " with remove.packages,"
				" so deleting files manually...");

			error_code errorCode;

			// returnValue is SQL_ERROR(-1) if there is an error, otherwise it is the
			// number of files deleted.
			//
			uintmax_t returnValue = fs::remove_all(libraryDir, errorCode);
			if (returnValue == static_cast<uintmax_t>(SQL_ERROR))
			{
				result = errorCode.value();
				LOG_ERROR("Failed to manually delete the directory with error code "
					+ to_string(result) + ".");
			}
			else
			{
				// If we successfully removed all the files, then we have a SUCCESS result.
				//
				result = SQL_SUCCESS;
				LOG("Manual deletion succeeded.");
			}
		}
		else
		{
			result = SQL_SUCCESS;
			LOG("Even though there was an error, library directory does not exist.");
		}
	}

	return result;
}