Skip to content
Snippets Groups Projects
Select Git revision
  • 496e769c4ce85f3ce3305ece6e618317d3bd7a92
  • master default protected
  • ia2
  • adql2.1-ia2
  • private_rows
5 results

CentroidFunction.java

Blame
    • gmantele's avatar
      496e769c
      [ADQL,TAP] Add STC-S and UDFs support in the ADQL parser. Now, it is possible... · 496e769c
      gmantele authored
      [ADQL,TAP] Add STC-S and UDFs support in the ADQL parser. Now, it is possible to provide a list of allowed UDFs, regions and coordinate systems. The ServiceConnection of TAP is now able to provide these lists and to propagate them to the ADQLExecutor. UDFs and allowed regions are now listed automatically in the /capabilities resource of TAP. The type 'geometry' is now fully supported in ADQL. That's why the new function 'isGeometry()' has been added to all ADQLOperand extensions. Now the DBChecker is also able to check roughly types of columns and UDFs (unknown when parsing syntactically a query). The syntax of STC-S regions (expressed in the REGION function) are now checked by DBChecker. However, for the moment, geometries are not serialized in STC-S in the output....but it should be possible in some way in the next commit(s).
      496e769c
      History
      [ADQL,TAP] Add STC-S and UDFs support in the ADQL parser. Now, it is possible...
      gmantele authored
      [ADQL,TAP] Add STC-S and UDFs support in the ADQL parser. Now, it is possible to provide a list of allowed UDFs, regions and coordinate systems. The ServiceConnection of TAP is now able to provide these lists and to propagate them to the ADQLExecutor. UDFs and allowed regions are now listed automatically in the /capabilities resource of TAP. The type 'geometry' is now fully supported in ADQL. That's why the new function 'isGeometry()' has been added to all ADQLOperand extensions. Now the DBChecker is also able to check roughly types of columns and UDFs (unknown when parsing syntactically a query). The syntax of STC-S regions (expressed in the REGION function) are now checked by DBChecker. However, for the moment, geometries are not serialized in STC-S in the output....but it should be possible in some way in the next commit(s).
    uploadsManager.js 6.38 KiB
    /*
     * This file is part of vospace-ui
     * Copyright (C) 2021 Istituto Nazionale di Astrofisica
     * SPDX-License-Identifier: GPL-3.0-or-later
     */
    import Vue from 'vue';
    import client from 'api-client';
    
    function resetArray(array) {
      array.splice(0, array.length);
    }
    
    export default {
      state: {
        files: [], // array of selected files
        progress: [], // array of upload progress percentages (for tracking upload progress)
        cancellations: [], // array of axios cancel tokens (for aborting uploads)
        deletionStatuses: [], // status of upload deletions (true if request is being aborted, false otherwise)
        errors: [], // errors happened during downloads
        creatingMetadata: false, // true when nodes metadata is being created (pre-upload phase)
        uploadInProgress: false, // true when data is being uploaded
      },
      mutations: {
        setFilesToUpload(state, files) {
          state.files = files;
        },
        resetUploadState(state) {
          resetArray(state.progress);
          resetArray(state.cancellations);
          resetArray(state.deletionStatuses);
          resetArray(state.errors);
        },
        setDeletion(state, data) {
          Vue.set(state.deletionStatuses, data.index, data.value);
        },
        setProgress(state, data) {
          Vue.set(state.progress, data.index, data.percent);
        },
        setCreatingMetadata(state, value) {
          state.creatingMetadata = value;
        },
        setUploadInProgress(state, value) {
          state.uploadInProgress = value;
        },
        setPreUploadResults(state, preUploadResults) {
          for (let result of preUploadResults) {
            if (Object.keys(result).includes('request')) {
              state.cancellations.push(result.source); // axios cancellation token
              state.deletionStatuses.push(null);
              state.errors.push(null);
            } else {
              state.cancellations.push(null);
              state.deletionStatuses.push(null);
              state.errors.push(result);
            }
          }
          state.uploadInProgress = true;
        },
        setError(state, data) {
          Vue.set(state.errors, data.index, data.error);
        }
      },
      actions: {
        upload({ state, rootState, commit, dispatch }, bvModal) {
    
          // Progress bars initialization
          for (let index = 0; index < state.files.length; index++) {
            let file = state.files[index];
            let reader = new FileReader();
    
            reader.addEventListener('progress', (event) => {
              if (event.loaded && event.total) {
                let percent = (event.loaded / event.total) * 100;
                commit('setProgress', { index, percent });
              }
            });
    
            reader.readAsDataURL(file);
          }
    
          commit('setCreatingMetadata', true);
    
          // Create nodes metadata and obtain upload URLs
          dispatch('prepareUpload')
            .then((preUploadResults) => {
              commit('setCreatingMetadata', false);
    
              let promises = [];
              for (let result of preUploadResults) {
                if (Object.keys(result).includes('request')) {
                  promises.push(result.request); // upload http promise
                } else {
                  // fictitious promise for failed pre-upload event
                  promises.push(new Promise(resolve => resolve()));
                }
              }
    
              commit('setPreUploadResults', preUploadResults);
    
              // wait until all downloads have been completed (both successfully or not)
              return Promise.allSettled(promises);
            })
            .then((responses) => {
    
              let deletionPromises = [];
              for (let index = 0; index < responses.length; index++) {
                let error = state.errors[index];
                let response = responses[index];
    
                if (response.status === 'fulfilled' && error === null) {
                  commit('setProgress', { index, percent: 100 });
                } else {
                  if (state.deletionStatuses[index] || error === null) {
                    // delete node metadata both when user aborted the upload and when it failed
                    deletionPromises.push(client.deleteNodes(['/' + rootState.path + '/' + state.files[index].name], true));
                    if (state.deletionStatuses[index] === null) {
                      // e.g. server became unreachable during the upload
                      commit('setError', { index, error: 'Unable to upload file' });
                    }
                  }
                }
              }
    
              // if there are some deletion promises, wait them
              return Promise.allSettled(deletionPromises);
            })
            .then(deletionResults => {
              // verify if metadata of aborted uploads has been correctly removed
              let resultIndex = 0;
              for (let i = 0; i < state.deletionStatuses.length; i++) {
                let deletionStatus = state.deletionStatuses[i];
                if (deletionStatus !== null) {
                  let deletionResult = deletionResults[resultIndex];
                  if (deletionResult.status === 'fulfilled') {
                    commit('setDeletion', { index: i, value: false });
                  } else {
                    commit('setError', { index: i, error: 'Failed to delete node metadata. Manual cleanup may be required.' });
                  }
                  resultIndex++;
                }
              }
            })
            .finally(() => {
              // Reload current node when all uploads completed
              dispatch('setPath', rootState.path);
              commit('setCreatingMetadata', false);
              commit('setUploadInProgress', false);
              let hasErrors = state.errors.filter(e => e !== null).length > 0;
              if (!hasErrors) {
                bvModal.hide('upload-files-modal');
              }
            });
        },
        prepareUpload({ state, rootState }) {
          let names = [];
          for (let file of state.files) {
            names.push(file.name);
          }
          return new Promise((resolve, reject) => {
            client.prepareForUpload(rootState.path, names)
              .then(preUploadResponses => {
                let uploads = [];
                for (let i = 0; i < state.files.length; i++) {
                  let uploadUrl = preUploadResponses[i].url;
                  if (uploadUrl !== null) {
                    uploads.push(client.uploadFile(uploadUrl, state.files[i]));
                  } else {
                    uploads.push(preUploadResponses[i].error);
                  }
                }
                resolve(uploads);
              })
              .catch(error => reject(error));
          });
        },
        cancelUpload({ state, commit }, index) {
          commit('setDeletion', { index, value: true });
          state.cancellations[index].cancel();
        }
      }
    }