예제 #1
0
        /// <summary>
        /// Downloads a remote package file to a local location.
        /// </summary>
        /// <param name="fastPackageReference"></param>
        /// <param name="destLocation"></param>
        /// <param name="request">An object passed in from the PackageManagement that contains functions that can be used to interact with its Provider</param>
        public void DownloadPackage(string fastPackageReference, string destLocation, NuGetRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod3, PackageProviderName, fastPackageReference, destLocation);

            // Enforce use of TLS 1.2 when sending request
            var securityProtocol = System.Net.ServicePointManager.SecurityProtocol;

            System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

            try {
                var pkgItem = request.GetPackageByFastpath(fastPackageReference);
                if (pkgItem == null)
                {
                    request.WriteError(ErrorCategory.InvalidArgument, fastPackageReference, Constants.Messages.UnableToResolvePackage);
                    return;
                }

                pkgItem.PackageSource.Repository.DownloadPackage(new PublicObjectView(pkgItem), destLocation, request);
            } catch (Exception ex) {
                ex.Dump(request);
                request.WriteError(ErrorCategory.InvalidOperation, fastPackageReference, ex.Message);
            } finally {
                // Change back to user specified security protocol
                System.Net.ServicePointManager.SecurityProtocol = securityProtocol;
            }
        }
예제 #2
0
        /// <summary>
        /// Installs a given package.
        /// </summary>
        /// <param name="fastPackageReference">A provider supplied identifier that specifies an exact package</param>
        /// <param name="request">An object passed in from the PackageManagement that contains functions that can be used to interact with its Provider</param>
        public void InstallPackage(string fastPackageReference, NuGetRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod3, PackageProviderName, "InstallPackage", fastPackageReference);

            // Enforce use of TLS 1.2 when sending request
            var securityProtocol = System.Net.ServicePointManager.SecurityProtocol;

            System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

            try {
                var pkgItem = request.GetPackageByFastpath(fastPackageReference);
                if (pkgItem == null)
                {
                    request.WriteError(ErrorCategory.InvalidArgument, fastPackageReference, Constants.Messages.UnableToResolvePackage);
                    return;
                }

                if ((pkgItem.PackageSource == null) || (pkgItem.PackageSource.Location == null) || (pkgItem.Package == null))
                {
                    request.Debug(Resources.Messages.VariableCheck, "PackageSource or PackageSource.Location or Package object", "null");
                    request.WriteError(ErrorCategory.ObjectNotFound, fastPackageReference, Constants.Messages.UnableToResolvePackage, pkgItem.Id);
                    return;
                }

                request.Debug(Resources.Messages.VariableCheck, "Package version", pkgItem.Version);
                request.Debug(Resources.Messages.VariableCheck, "Request's Destination", request.Destination);

                // got this far, let's install the package we came here for.
                if (!pkgItem.PackageSource.Repository.InstallPackage(new PublicObjectView(pkgItem), request))
                {
                    // package itself didn't install. Write error
                    request.WriteError(ErrorCategory.InvalidResult, pkgItem.Id, Constants.Messages.PackageFailedInstallOrDownload, pkgItem.Id, CultureInfo.CurrentCulture.TextInfo.ToLower(Constants.Install));

                    return;
                }
            } catch (Exception ex) {
                ex.Dump(request);
                request.WriteError(ErrorCategory.InvalidOperation, fastPackageReference, ex.Message);
            } finally {
                // Change back to user specified security protocol
                System.Net.ServicePointManager.SecurityProtocol = securityProtocol;
            }
        }
        /// <summary>
        /// Installs a given package.
        /// </summary>
        /// <param name="fastPackageReference">A provider supplied identifier that specifies an exact package</param>
        /// <param name="request">An object passed in from the PackageManagement that contains functions that can be used to interact with its Provider</param>
        public void InstallPackage(string fastPackageReference, NuGetRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod3, PackageProviderName, "InstallPackage", fastPackageReference);

            try {
                var pkgItem = request.GetPackageByFastpath(fastPackageReference);
                if (pkgItem == null)
                {
                    request.WriteError(ErrorCategory.InvalidArgument, fastPackageReference, Constants.Messages.UnableToResolvePackage);
                    return;
                }

                if ((pkgItem.PackageSource == null) || (pkgItem.PackageSource.Location == null) || (pkgItem.Package == null))
                {
                    request.Debug(Resources.Messages.VariableCheck, "PackageSource or PackageSource.Location or Package object", "null");
                    request.WriteError(ErrorCategory.ObjectNotFound, fastPackageReference, Constants.Messages.UnableToResolvePackage, pkgItem.Id);
                    return;
                }

                request.Debug(Resources.Messages.VariableCheck, "Package version", pkgItem.Version);
                request.Debug(Resources.Messages.VariableCheck, "Request's Destination", request.Destination);

                // got this far, let's install the package we came here for.
                if (!NuGetClient.InstallOrDownloadPackageHelper(pkgItem, request, Constants.Install,
                                                                (packageItem, progressTracker) => NuGetClient.InstallSinglePackage(packageItem, request, progressTracker)))
                {
                    // package itself didn't install. Write error
                    request.WriteError(ErrorCategory.InvalidResult, pkgItem.Id, Constants.Messages.PackageFailedInstallOrDownload, pkgItem.Id, CultureInfo.CurrentCulture.TextInfo.ToLower(Constants.Install));

                    return;
                }
            } catch (Exception ex) {
                ex.Dump(request);
                request.WriteError(ErrorCategory.InvalidOperation, fastPackageReference, ex.Message);
            }
        }
        /// <summary>
        /// Downloads a remote package file to a local location.
        /// </summary>
        /// <param name="fastPackageReference"></param>
        /// <param name="destLocation"></param>
        /// <param name="request">An object passed in from the PackageManagement that contains functions that can be used to interact with its Provider</param>
        public void DownloadPackage(string fastPackageReference, string destLocation, NuGetRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod3, PackageProviderName, fastPackageReference, destLocation);

            try {
                var pkgItem = request.GetPackageByFastpath(fastPackageReference);
                if (pkgItem == null)
                {
                    request.WriteError(ErrorCategory.InvalidArgument, fastPackageReference, Constants.Messages.UnableToResolvePackage);
                    return;
                }

                pkgItem.PackageSource.Repository.DownloadPackage(new PublicObjectView(pkgItem), destLocation, request);
            } catch (Exception ex) {
                ex.Dump(request);
                request.WriteError(ErrorCategory.InvalidOperation, fastPackageReference, ex.Message);
            }
        }
        /// <summary>
        /// Downloads a remote package file to a local location.
        /// </summary>
        /// <param name="fastPackageReference"></param>
        /// <param name="destLocation"></param>
        /// <param name="request">An object passed in from the PackageManagement that contains functions that can be used to interact with its Provider</param>
        public void DownloadPackage(string fastPackageReference, string destLocation, NuGetRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            request.Debug(Resources.Messages.DebugInfoCallMethod3, PackageProviderName, fastPackageReference, destLocation);

            try {
                var pkgItem = request.GetPackageByFastpath(fastPackageReference);
                if (pkgItem == null)
                {
                    request.WriteError(ErrorCategory.InvalidArgument, fastPackageReference, Constants.Messages.UnableToResolvePackage);
                    return;
                }

                NuGetClient.InstallOrDownloadPackageHelper(pkgItem, request, Constants.Download,
                                                           (packageItem, progressTracker) => NuGetClient.DownloadSinglePackage(packageItem, request, destLocation, progressTracker));
            } catch (Exception ex) {
                ex.Dump(request);
                request.WriteError(ErrorCategory.InvalidOperation, fastPackageReference, ex.Message);
            }
        }
        /// <summary>
        /// This is called when the user is adding (or updating) a package source
        ///
        /// If this PROVIDER doesn't support user-defined package sources, remove this method.
        /// </summary>
        /// <param name="name">The name of the package source. If this parameter is null or empty the PROVIDER should use the location as the name (if the PROVIDER actually stores names of package sources)</param>
        /// <param name="location">The location (ie, directory, URL, etc) of the package source. If this is null or empty, the PROVIDER should use the name as the location (if valid)</param>
        /// <param name="trusted">A boolean indicating that the user trusts this package source. Packages returned from this source should be marked as 'trusted'</param>
        /// <param name="request">An object passed in from the PackageManagement that contains functions that can be used to interact with its Provider</param>
        public void AddPackageSource(string name, string location, bool trusted, NuGetRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }
            try {
                request.Debug(string.Format(CultureInfo.InvariantCulture, "AddPackageSource - ProviderName = '{0}', name='{1}', location='{2}', trusted='{3}'", PackageProviderName, name, location, trusted));

                // Error out if a user does not provide package source Name
                if (string.IsNullOrWhiteSpace(name))
                {
                    request.WriteError(ErrorCategory.InvalidArgument, Constants.Parameters.Name, Constants.Messages.MissingRequiredParameter, Constants.Parameters.Name);
                    return;
                }

                if (string.IsNullOrWhiteSpace(location))
                {
                    request.WriteError(ErrorCategory.InvalidArgument, Constants.Parameters.Location, Constants.Messages.MissingRequiredParameter, Constants.Parameters.Location);
                    return;
                }

                request.Debug(Resources.Messages.DebugInfoCallMethod, PackageProviderName, "GetOptionValue");
                // if this is supposed to be an update, there will be a dynamic parameter set for IsUpdatePackageSource
                var isUpdate = request.GetOptionValue(Constants.Parameters.IsUpdate).IsTrue();

                request.Debug(Resources.Messages.VariableCheck, "IsUpdate", isUpdate);

                // if your source supports credentials you get get them too:
                // string username =request.Username;
                // SecureString password = request.Password;
                // feel free to send back an error here if your provider requires credentials for package sources.

                // check first that we're not clobbering an existing source, unless this is an update

                request.Debug(Resources.Messages.DebugInfoCallMethod, PackageProviderName, string.Format(CultureInfo.InvariantCulture, "FindRegisteredSource -name'{0}'", name));

                var src = request.FindRegisteredSource(name);

                if (src != null && !isUpdate)
                {
                    // tell the user that there's one here already
                    request.WriteError(ErrorCategory.InvalidArgument, name, Constants.Messages.PackageSourceExists, name);
                    return;
                }

                // conversely, if it didn't find one, and it is an update, that's bad too:
                if (src == null && isUpdate)
                {
                    // you can't find that package source? Tell that to the user
                    request.WriteError(ErrorCategory.ObjectNotFound, name, Constants.Messages.UnableToResolveSource, name);
                    return;
                }

                // ok, we know that we're ok to save this source
                // next we check if the location is valid (if we support that kind of thing)

                var validated = false;

                if (!request.SkipValidate.Value)
                {
                    // the user has not opted to skip validating the package source location, so check if the source is valid
                    validated = request.ValidateSourceLocation(location);

                    if (!validated)
                    {
                        request.WriteError(ErrorCategory.InvalidData, name, Constants.Messages.SourceLocationNotValid, location);
                        return;
                    }

                    request.Verbose(Resources.Messages.SuccessfullyValidated, name);
                }

                // it's good to check just before you actually write something to see if the user has cancelled the operation
                if (request.IsCanceled)
                {
                    return;
                }

                // looking good -- store the package source.
                request.AddPackageSource(name, location, trusted, validated);

                // Yield the package source back to the caller.
                request.YieldPackageSource(name, location, trusted, true /*since we just registered it*/, validated);
            }
            catch (Exception e)
            {
                e.Dump(request);
            }
        }
예제 #7
0
        /// <summary>
        /// Returns the validated uri. Returns null if we cannot validate it
        /// </summary>
        /// <param name="query"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        internal static Uri ValidateUri(Uri query, NuGetRequest request)
        {
            // Validation takes place in two steps:
            //  1. Validate the given URI is valid, resolving redirection
            //  2. Validate we can hit the query service
            NetworkCredential credentials = null;
            var client = request.ClientWithoutAcceptHeader;

            var response = PathUtility.GetHttpResponse(client, query.AbsoluteUri, (() => request.IsCanceled),
                                                       ((msg, num) => request.Verbose(Resources.Messages.RetryingDownload, msg, num)), (msg) => request.Verbose(msg), (msg) => request.Debug(msg));

            if (response == null)
            {
                return(null);
            }

            // if response is not success, we need to check for redirection
            if (!response.IsSuccessStatusCode)
            {
                // Check for redirection (http status code 3xx)
                if (response.StatusCode == HttpStatusCode.MultipleChoices || response.StatusCode == HttpStatusCode.MovedPermanently ||
                    response.StatusCode == HttpStatusCode.Found || response.StatusCode == HttpStatusCode.SeeOther ||
                    response.StatusCode == HttpStatusCode.TemporaryRedirect)
                {
                    // get the redirected direction
                    string location = response.Headers.GetValues("Location").FirstOrDefault();
                    if (String.IsNullOrWhiteSpace(location))
                    {
                        return(null);
                    }

                    // make a new query based on location
                    query = new Uri(location);
                }
                else
                {
                    if (response.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        // If the uri is not validated, try again using credentials retrieved from credential provider
                        // First call to the credential provider is to get credentials, but if those credentials fail,
                        // we call the cred provider again to ask the user for new credentials, and then search try to validate uri again using new creds
                        credentials = request.GetCredsFromCredProvider(query.AbsoluteUri.ToString(), request, false);
                        var newClient = PathUtility.GetHttpClientHelper(credentials.UserName, credentials.SecurePassword, null);

                        var newResponse = PathUtility.GetHttpResponse(newClient, query.AbsoluteUri, (() => request.IsCanceled),
                                                                      ((msg, num) => request.Verbose(Resources.Messages.RetryingDownload, msg, num)), (msg) => request.Verbose(msg), (msg) => request.Debug(msg));
                        query = new Uri(newResponse.RequestMessage.RequestUri.AbsoluteUri);

                        request.SetHttpClient(newClient);

                        if (newResponse.StatusCode == HttpStatusCode.Unauthorized)
                        {
                            // Calling the credential provider for a second time, using -IsRetry
                            credentials = request.GetCredsFromCredProvider(query.AbsoluteUri.ToString(), request, true);
                            newClient   = PathUtility.GetHttpClientHelper(credentials.UserName, credentials.SecurePassword, null);

                            newResponse = PathUtility.GetHttpResponse(newClient, query.AbsoluteUri, (() => request.IsCanceled),
                                                                      ((msg, num) => request.Verbose(Resources.Messages.RetryingDownload, msg, num)), (msg) => request.Verbose(msg), (msg) => request.Debug(msg));
                            query = new Uri(newResponse.RequestMessage.RequestUri.AbsoluteUri);

                            request.SetHttpClient(newClient);

                            if (newResponse.StatusCode == HttpStatusCode.Unauthorized)
                            {
                                request.WriteError(ErrorCategory.PermissionDenied, "ValidateUri", Resources.Messages.AccessPermissionDenied, query);
                                return(null);
                            }
                        }
                    }
                    else
                    {
                        // other status code is wrong
                        return(null);
                    }
                }
            }
            else
            {
                query = new Uri(response.RequestMessage.RequestUri.AbsoluteUri);
            }

            IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(new PackageRepositoryCreateParameters(query.AbsoluteUri, request, locationValid: true));

            if (repo.ResourceProvider != null)
            {
                // If the query feed exists, it's a non-local repo
                // Check the query feed to make sure it's available
                // Optionally we could change this to check the packages feed for availability
                if (repo.ResourceProvider.QueryFeed == null || !repo.ResourceProvider.QueryFeed.IsAvailable(new RequestWrapper(request, credentials)))
                {
                    return(null);
                }
            }

            return(query);
        }
예제 #8
0
        /// <summary>
        /// Returns the validated uri. Returns null if we cannot validate it
        /// </summary>
        /// <param name="query"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        internal static Uri ValidateUri(Uri query, NuGetRequest request)
        {
            // Validation takes place in two steps:
            //  1. Validate the given URI is valid, resolving redirection
            //  2. Validate we can hit the query service
            var client = request.ClientWithoutAcceptHeader;

            var response = PathUtility.GetHttpResponse(client, query.AbsoluteUri, (() => request.IsCanceled),
                                                       ((msg, num) => request.Verbose(Resources.Messages.RetryingDownload, msg, num)), (msg) => request.Verbose(msg), (msg) => request.Debug(msg));

            if (response == null)
            {
                return(null);
            }

            // if response is not success, we need to check for redirection
            if (!response.IsSuccessStatusCode)
            {
                // Check for redirection (http status code 3xx)
                if (response.StatusCode == HttpStatusCode.MultipleChoices || response.StatusCode == HttpStatusCode.MovedPermanently ||
                    response.StatusCode == HttpStatusCode.Found || response.StatusCode == HttpStatusCode.SeeOther ||
                    response.StatusCode == HttpStatusCode.TemporaryRedirect)
                {
                    // get the redirected direction
                    string location = response.Headers.GetValues("Location").FirstOrDefault();
                    if (String.IsNullOrWhiteSpace(location))
                    {
                        return(null);
                    }

                    // make a new query based on location
                    query = new Uri(location);
                }
                else
                {
                    if (response.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        request.WriteError(ErrorCategory.PermissionDenied, "ValidateUri", Resources.Messages.AccessPermissionDenied, query);
                    }

                    // other status code is wrong
                    return(null);
                }
            }
            else
            {
                query = new Uri(response.RequestMessage.RequestUri.AbsoluteUri);
            }

            IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(new PackageRepositoryCreateParameters(query.AbsoluteUri, request, locationValid: true));

            if (repo.ResourceProvider != null)
            {
                // If the query feed exists, it's a non-local repo
                // Check the query feed to make sure it's available
                // Optionally we could change this to check the packages feed for availability
                if (repo.ResourceProvider.QueryFeed == null || !repo.ResourceProvider.QueryFeed.IsAvailable(new RequestWrapper(request)))
                {
                    return(null);
                }
            }

            return(query);
        }
예제 #9
0
        private bool DownloadSinglePackage(PackageItem pkgItem, NuGetRequest request, string destLocation, ProgressTracker progressTracker)
        {
            try
            {
                request.Debug(Messages.DebugInfoCallMethod, "NuGetFilesFeed3", "DownloadSinglePackage");
                if (string.IsNullOrWhiteSpace(pkgItem.PackageFilename) || pkgItem.PackageSource == null || pkgItem.PackageSource.Location == null ||
                    (pkgItem.PackageSource.IsSourceAFile && pkgItem.Package == null))
                {
                    request.WriteError(ErrorCategory.ObjectNotFound, pkgItem.Id, Constants.Messages.UnableToResolvePackage, pkgItem.Id);
                    return(false);
                }

                // this is if the user says -force
                bool force = request.GetOptionValue("Force") != null;

                // combine the path and the file name
                destLocation = Path.Combine(destLocation, pkgItem.PackageFilename);

                // if the file already exists
                if (File.Exists(destLocation))
                {
                    // if no force, just return
                    if (!force)
                    {
                        request.Verbose(Constants.Messages.SkippedDownloadedPackage, pkgItem.Id);
                        request.YieldPackage(pkgItem, pkgItem.PackageSource.Name);
                        return(true);
                    }

                    // here we know it is forced, so delete
                    FileUtility.DeleteFile(destLocation, isThrow: false);

                    // if after we try delete, it is still there, tells the user we can't perform the action
                    if (File.Exists(destLocation))
                    {
                        request.WriteError(ErrorCategory.ResourceUnavailable, destLocation, Constants.Messages.UnableToOverwriteExistingFile, destLocation);
                        return(false);
                    }
                }

                bool downloadSuccessful = false;

                try
                {
                    // if no repository, we can't do anything
                    if (pkgItem.PackageSource.Repository == null)
                    {
                        return(false);
                    }

                    if (pkgItem.PackageSource.Repository.IsFile)
                    {
                        using (var input = File.OpenRead(pkgItem.Package.FullFilePath))
                        {
                            using (var output = new FileStream(destLocation, FileMode.Create, FileAccess.Write, FileShare.Read))
                            {
                                input.CopyTo(output);
                                downloadSuccessful = true;
                            }
                        }
                    }
                    else
                    {
                        string httpquery = MakeDownloadUri(pkgItem);
                        if (!String.IsNullOrEmpty(httpquery))
                        {
                            downloadSuccessful = NuGetClient.DownloadPackage(pkgItem.Id, pkgItem.Version, destLocation, httpquery, request, pkgItem.PackageSource, progressTracker);
                        }
                        else
                        {
                            downloadSuccessful = false;
                            request.Warning(Messages.FailedToCreateDownloadUri, pkgItem.Id, pkgItem.Version);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ex.Dump(request);
                    return(false);
                }

                if (downloadSuccessful)
                {
                    request.Verbose(Resources.Messages.SuccessfullyDownloaded, pkgItem.Id);
                    // provide the directory we save to to yieldpackage
                    request.YieldPackage(pkgItem, pkgItem.PackageSource.Name, Path.GetDirectoryName(destLocation));
                }

                return(downloadSuccessful);
            } finally
            {
                request.Debug(Messages.DebugInfoReturnCall, "NuGetFilesFeed3", "DownloadSinglePackage");
            }
        }
예제 #10
0
        /// <summary>
        /// Returns the validated uri. Returns null if we cannot validate it
        /// </summary>
        /// <param name="query"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        internal static Uri ValidateUri(Uri query, NuGetRequest request)
        {
            var client = request.ClientWithoutAcceptHeader;

            var response = PathUtility.GetHttpResponse(client, query.AbsoluteUri, (() => request.IsCanceled),
                                                       ((msg, num) => request.Verbose(Resources.Messages.RetryingDownload, msg, num)), (msg) => request.Verbose(msg), (msg) => request.Debug(msg));

            if (response == null)
            {
                return(null);
            }

            // if response is not success, we need to check for redirection
            if (!response.IsSuccessStatusCode)
            {
                // Check for redirection (http status code 3xx)
                if (response.StatusCode == HttpStatusCode.MultipleChoices || response.StatusCode == HttpStatusCode.MovedPermanently ||
                    response.StatusCode == HttpStatusCode.Found || response.StatusCode == HttpStatusCode.SeeOther ||
                    response.StatusCode == HttpStatusCode.TemporaryRedirect)
                {
                    // get the redirected direction
                    string location = response.Headers.GetValues("Location").FirstOrDefault();
                    if (String.IsNullOrWhiteSpace(location))
                    {
                        return(null);
                    }

                    // make a new query based on location
                    query = new Uri(location);
                }
                else
                {
                    if (response.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        request.WriteError(ErrorCategory.PermissionDenied, "ValidateUri", Resources.Messages.AccessPermissionDenied, query);
                    }

                    // other status code is wrong
                    return(null);
                }
            }
            else
            {
                query = new Uri(response.RequestMessage.RequestUri.AbsoluteUri);
            }

            //Making a query like: www.nuget.org/api/v2/FindPackagesById()?id='FoooBarr' to check the server available.
            //'FoooBarr' is an any random package id
            string queryUri = "FoooBarr".MakeFindPackageByIdQuery(PathUtility.UriCombine(query.AbsoluteUri, NuGetConstant.FindPackagesById));

            response = PathUtility.GetHttpResponse(client, queryUri, (() => request.IsCanceled),
                                                   ((msg, num) => request.Verbose(Resources.Messages.RetryingDownload, msg, num)), (msg) => request.Verbose(msg), (msg) => request.Debug(msg));


            // The link is not valid
            if (response == null || !response.IsSuccessStatusCode)
            {
                return(null);
            }

            return(query);
        }