Commit c3e97e6e authored by Grégory Mantelet's avatar Grégory Mantelet
Browse files

[TAP] Add an optional feature to enable quick fix of input ADQL query on error:

`fix_on_fail` in the configuration file. By default, this feature is disabled.

_With 15cd5944, this commit finishes the resolution of the GitHub issue #104 ._
parent 15cd5944
Loading
Loading
Loading
Loading
+101 −78
Original line number Diff line number Diff line
@@ -2,21 +2,21 @@ package tap;

/*
 * This file is part of TAPLibrary.
 * 
 *
 * TAPLibrary is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 *
 * TAPLibrary is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 *
 * Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 *                       Astronomisches Rechen Institut (ARI)
 */

@@ -49,7 +49,7 @@ import uws.service.log.UWSLog.LogLevel;

/**
 * <p>Let process completely an ADQL query.</p>
 * 
 *
 * <p>Thus, this class aims to apply the following actions (in the given order):</p>
 * <ol>
 * 	<li>Upload the user tables, if any</li>
@@ -58,54 +58,54 @@ import uws.service.log.UWSLog.LogLevel;
 * 	<li>Format and write the result</li>
 * 	<li>Drop all uploaded tables from the "database"</li>
 * </ol>
 * 
 *
 * <h3>Job execution mode</h3>
 * 
 *
 * <p>
 * 	This executor is able to process queries coming from a synchronous job (the result must be written directly in the HTTP response)
 * 	and from an asynchronous job (the result must be written, generally, in a file). Two start(...) functions let deal with
 * 	the differences between the two job execution modes: {@link #start(AsyncThread)} for asynchronous jobs
 * 	and {@link #start(Thread, String, TAPParameters, HttpServletResponse)} for synchronous jobs.
 * </p>
 * 
 *
 * <h3>Input/Output formats</h3>
 * 
 *
 * <p>Uploaded tables must be provided in VOTable format.</p>
 * 
 *
 * <p>
 * 	Query results must be formatted in the format specified by the user in the job parameters. A corresponding formatter ({@link OutputFormat})
 * 	is asked to the description of the TAP service ({@link ServiceConnection}). If none can be found, VOTable will be chosen by default.
 * </p>
 * 
 *
 * <h3>Executor customization</h3>
 * 
 *
 * <p>It is totally possible to customize some parts of the ADQL query processing. However, the main algorithm must remain the same and is implemented
 * 	by {@link #start()}. This function is final, like {@link #start(AsyncThread)} and {@link #start(Thread, String, TAPParameters, HttpServletResponse)},
 * 	which are just preparing the execution for {@link #start()} in function of the job execution mode (asynchronous or synchronous).
 * </p>
 * 
 *
 * <p><i>Note:
 * 	{@link #start()} is using the Template Method Design Pattern: it defines the skeleton/algorithm of the processing, and defers some steps
 * 	to other functions.
 * </i></p>
 * 
 *
 * <p>
 * 	So, you are able to customize almost all individual steps of the ADQL query processing: {@link #parseADQL()}, {@link #executeADQL(ADQLQuery)} and
 * 	{@link #writeResult(TableIterator, OutputFormat, OutputStream)}.
 * </p>
 * 
 *
 * <p><i>Note:
 * 	Note that the formatting of the result is done by an OutputFormat and that the executor is just calling the appropriate function of the formatter.
 * </i></p>
 * 
 *
 * <p>
 * 	There is no way in this executor to customize the upload. However, it does not mean it can not be customized.
 * 	Indeed you can do it easily by extending {@link Uploader} and by providing the new class inside your {@link TAPFactory} implementation
 * (see {@link TAPFactory#createUploader(DBConnection)}).
 * </p>
 * 
 *
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 2.1 (04/2017)
 * @version 2.3 (03/2019)
 */
public class ADQLExecutor {

@@ -139,7 +139,7 @@ public class ADQLExecutor {

	/**
	 * Build an {@link ADQLExecutor}.
	 * 
	 *
	 * @param service	The description of the TAP service.
	 */
	public ADQLExecutor(final ServiceConnection service){
@@ -149,7 +149,7 @@ public class ADQLExecutor {

	/**
	 * Get the logger used by this executor.
	 * 
	 *
	 * @return	The used logger.
	 */
	public final TAPLog getLogger(){
@@ -158,12 +158,12 @@ public class ADQLExecutor {

	/**
	 * <p>Get the report of the query execution. It helps indicating the execution progression and the duration of each step.</p>
	 * 
	 *
	 * <p><i>Note:
	 * 	Before starting the execution (= before the call of a "start(...)" function), this function will return NULL.
	 * 	It is set when the query processing starts and remains not NULL after that (even when the execution is finished).
	 * </i></p>
	 * 
	 *
	 * @return	The execution report.
	 */
	public final TAPExecutionReport getExecReport(){
@@ -173,11 +173,11 @@ public class ADQLExecutor {
	/**
	 * <p>Get the object to use in order to write the query result in the appropriate format
	 * (either the asked one, or else VOTable).</p>
	 * 
	 *
	 * @return	The appropriate result formatter to use. <i>Can not be NULL!</i>
	 * 
	 *
	 * @throws TAPException	If no format corresponds to the asked one and if no default format (for VOTable) can be found.
	 * 
	 *
	 * @see ServiceConnection#getOutputFormat(String)
	 */
	protected OutputFormat getFormatter() throws TAPException{
@@ -196,19 +196,19 @@ public class ADQLExecutor {

	/**
	 * <p>Start the asynchronous processing of the ADQL query.</p>
	 * 
	 *
	 * <p>
	 * 	This function initialize the execution report, get the execution parameters (including the query to process)
	 * 	and then call {@link #start()}.
	 * </p>
	 * 
	 *
	 * @param thread	The asynchronous thread which asks the query processing.
	 * 
	 *
	 * @return	The resulting execution report.
	 * 
	 *
	 * @throws UWSException			If any error occurs while executing the ADQL query.
	 * @throws InterruptedException	If the job has been interrupted (by the user or a time-out).
	 * 
	 *
	 * @see #start()
	 */
	public final TAPExecutionReport start(final AsyncThread thread) throws UWSException, InterruptedException{
@@ -244,16 +244,16 @@ public class ADQLExecutor {

	/**
	 * <p>Create the database connection required for the ADQL execution.</p>
	 * 
	 *
	 * <p><i>Note: This function has no effect if the DB connection already exists.</i></p>
	 * 
	 *
	 * @param jobID	ID of the job which will be executed by this {@link ADQLExecutor}.
	 *             	This ID will be the database connection ID.
	 * 
	 *
	 * @throws TAPException	If the DB connection creation fails.
	 * 
	 *
	 * @see TAPFactory#getConnection(String)
	 * 
	 *
	 * @since 2.0
	 */
	public final void initDBConnection(final String jobID) throws TAPException{
@@ -264,7 +264,7 @@ public class ADQLExecutor {
	/**
	 * Cancel the current SQL query execution or result set fetching if any is currently running.
	 * If no such process is on going, this function has no effect.
	 * 
	 *
	 * @since 2.1
	 */
	public final void cancelQuery(){
@@ -274,20 +274,20 @@ public class ADQLExecutor {

	/**
	 * <p>Start the synchronous processing of the ADQL query.</p>
	 * 
	 *
	 * <p>This function initialize the execution report and then call {@link #start()}.</p>
	 * 
	 *
	 * @param thread	The synchronous thread which asks the query processing.
	 * @param jobId		ID of the corresponding job.
	 * @param params	All execution parameters (including the query to process).
	 * @param response	Object in which the result or the error must be written.
	 * 
	 *
	 * @return	The resulting execution report.
	 * 
	 *
	 * @throws TAPException			If any error occurs while executing the ADQL query.
	 * @throws IOException			If any error occurs while writing the result in the given {@link HttpServletResponse}.
	 * @throws InterruptedException	If the job has been interrupted (by the user or a time-out).
	 * 
	 *
	 * @see #start()
	 */
	public final TAPExecutionReport start(final Thread thread, final String jobId, final TAPParameters params, final HttpServletResponse response) throws TAPException, IOException, InterruptedException{
@@ -308,7 +308,7 @@ public class ADQLExecutor {

	/**
	 * <p>Process the ADQL query.</p>
	 * 
	 *
	 * <p>This function calls the following function (in the same order):</p>
	 * <ol>
	 * 	<li>{@link TAPFactory#getConnection(String)}</li>
@@ -319,16 +319,16 @@ public class ADQLExecutor {
	 * 	<li>{@link #dropUploadedTables()}</li>
	 * 	<li>{@link TAPFactory#freeConnection(DBConnection)}</li>
	 * </ol>
	 * 
	 *
	 * <p>
	 * 	The execution report is updated gradually. Besides a job parameter - progression - is set at each step of the process in order to
	 * 	notify the user of the progression of the query execution. This parameter is removed at the end of the execution if it is successful.
	 * </p>
	 * 
	 *
	 * <p>The "interrupted" flag of the associated thread is often tested so that stopping the execution as soon as possible.</p>
	 * 
	 *
	 * @return	The updated execution report.
	 * 
	 *
	 * @throws TAPException			If any error occurs while executing the ADQL query.
	 * @throws UWSException			If any error occurs while executing the ADQL query.
	 * @throws IOException			If an error happens while writing the result in the specified {@link HttpServletResponse}.
@@ -434,18 +434,18 @@ public class ADQLExecutor {
	/**
	 * <p>Memorize the time at which the step starts, the step ID and update the job parameter "progression"
	 * (to notify the user about the progression of the query processing).</p>
	 * 
	 *
	 * <p><i>Note:
	 * 	If for some reason the job parameter "progression" can not be updated, no error will be thrown. A WARNING message
	 * 	will be just written in the log.
	 * </i></p>
	 * 
	 *
	 * <p><i>Note:
	 * 	This function is designed to work with {@link #endStep()}, which must be called after it, when the step is finished (successfully or not).
	 * </i></p>
	 * 
	 *
	 * @param progression	ID of the starting step.
	 * 
	 *
	 * @see #endStep()
	 */
	private void startStep(final ExecutionProgression progression){
@@ -464,16 +464,16 @@ public class ADQLExecutor {

	/**
	 * <p>Set the duration of the current step in the execution report.</p>
	 * 
	 *
	 * <p><i>Note:
	 * 	The start time and the ID of the step are then forgotten.
	 * </i></p>
	 * 
	 *
	 * <p><i>Note:
	 * 	This function is designed to work with {@link #startStep(ExecutionProgression)}, which must be called before it, when the step is starting.
	 * 	It marks the end of a step.
	 * </i></p>
	 * 
	 *
	 * @see #startStep(ExecutionProgression)
	 */
	private void endStep(){
@@ -489,11 +489,11 @@ public class ADQLExecutor {

	/**
	 * <p>Create in the "database" all tables uploaded by the user (only for this specific query execution).</p>
	 * 
	 *
	 * <p><i>Note:
	 * 	Obviously, nothing is done if no table has been uploaded.
	 * </i></p>
	 * 
	 *
	 * @throws TAPException	If any error occurs while reading the uploaded table
	 *                     	or while importing them in the database.
	 */
@@ -510,23 +510,23 @@ public class ADQLExecutor {

	/**
	 * <p>Parse the ADQL query provided in the parameters by the user.</p>
	 * 
	 *
	 * <p>The query factory and the query checker are got from the TAP factory.</p>
	 * 
	 *
	 * <p>
	 * 	The configuration of this TAP service list all allowed coordinate systems. These are got here and provided to the query checker
	 * 	in order to ensure the coordinate systems used in the query are in this list.
	 * </p>
	 * 
	 *
	 * <p>
	 * 	The row limit specified in the ADQL query (with TOP) is checked and adjusted (if needed). Indeed, this limit
	 * 	can not exceed MAXREC given in parameter and the maximum value specified in the configuration of this TAP service.
	 * 	In the case no row limit is specified in the query or the given value is greater than MAXREC, (MAXREC+1) is used by default.
	 * 	The "+1" aims to detect overflows.
	 * </p>
	 * 
	 *
	 * @return	The object representation of the ADQL query.
	 * 
	 *
	 * @throws ParseException			If the given ADQL query can not be parsed or if the construction of the object representation has failed.
	 * @throws InterruptedException		If the thread has been interrupted.
	 * @throws TAPException				If the TAP factory is unable to create the ADQL factory or the query checker.
@@ -551,7 +551,30 @@ public class ADQLExecutor {
			parser.setQueryChecker(service.getFactory().createQueryChecker(uploadSchema));

		// Parse the ADQL query:
		ADQLQuery query = parser.parseQuery(tapParams.getQuery());
		ADQLQuery query = null;
		// if the fixOnFail option is enabled...
		if (service.fixOnFailEnabled()){
			try{
				// try parsing the query:
				query = parser.parseQuery(tapParams.getQuery());
			}catch(ParseException pe){
				// if it fails...
				// ...log the auto fix attempt:
				logger.logTAP(LogLevel.INFO, report, "PARSING", "Parse attempt of the original input query failed! Trying auto-fix...", null);
				// ...try fixing the query:
				String fixedQuery = parser.tryQuickFix(tapParams.getQuery());
				// ...log the auto fixed query, if successful:
				logger.logTAP(LogLevel.INFO, report, "PARSING", "Auto-fixed query: " + fixedQuery.replaceAll("(\t|\r?\n)+", " "), null);
				// ...keep this fixed query in the exec report:
				report.fixedQuery = fixedQuery;
				// ...and finally try parsing it a last time:
				query = parser.parseQuery(fixedQuery);
			}
		}
		// if not enabled, parse immediately the query:
		else{
			query = parser.parseQuery(tapParams.getQuery());
		}

		// Set or check the row limit:
		final int limit = query.getSelect().getLimit();
@@ -566,22 +589,22 @@ public class ADQLExecutor {

	/**
	 * <p>Execute in "database" the given object representation of an ADQL query.</p>
	 * 
	 *
	 * <p>By default, this function is just calling {@link DBConnection#executeQuery(ADQLQuery)} and then it returns the value returned by this call.</p>
	 * 
	 *
	 * <p><i>Note:
	 * 	An INFO message is logged at the end of the query execution in order to report the result status (success or error)
	 * 	and the execution duration.
	 * </i></p>
	 * 
	 *
	 * @param adql	The object representation of the ADQL query to execute.
	 * 
	 *
	 * @return	The result of the query.
	 * 
	 *
	 * @throws InterruptedException	If the thread has been interrupted.
	 * @throws DBCancelledException	If the inner DB connection has been canceled.
	 * @throws TAPException			If the {@link DBConnection} has failed to deal with the given ADQL query.
	 * 
	 *
	 * @see DBConnection#executeQuery(ADQLQuery)
	 */
	protected TableIterator executeADQL(final ADQLQuery adql) throws InterruptedException, DBCancelledException, TAPException{
@@ -617,21 +640,21 @@ public class ADQLExecutor {
	/**
	 * <p>Write the given query result into the appropriate format in the appropriate output
	 * (HTTP response for a synchronous execution, otherwise a file or any output provided by UWS).</p>
	 * 
	 *
	 * <p>This function prepare the output in function of the execution type (synchronous or asynchronous).
	 * 	Once prepared, the result, the output and the formatter to use are given to {@link #writeResult(TableIterator, OutputFormat, OutputStream)}
	 * 	which will really process the result formatting and writing.
	 * </p>
	 * 
	 *
	 * @param queryResult	The result of the query execution in database.
	 * 
	 *
	 * @throws InterruptedException	If the thread has been interrupted.
	 * @throws IOException			If an error happens while writing the result in the {@link HttpServletResponse}.
	 *                    			<i>That kind of error can be thrown only in synchronous mode.
	 *                    			In asynchronous, the error is stored as job error report and is never propagated.</i>
	 * @throws TAPException			If an error occurs while getting the appropriate formatter or while formatting or writing (synchronous execution) the result.
	 * @throws UWSException			If an error occurs while getting the output stream or while writing (asynchronous execution) the result.
	 * 
	 *
	 * @see #writeResult(TableIterator, OutputFormat, OutputStream)
	 */
	protected final void writeResult(final TableIterator queryResult) throws InterruptedException, IOException, TAPException, UWSException{
@@ -707,18 +730,18 @@ public class ADQLExecutor {

	/**
	 * <p>Format and write the given result in the given output with the given formatter.</p>
	 * 
	 *
	 * <p>By default, this function is just calling {@link OutputFormat#writeResult(TableIterator, OutputStream, TAPExecutionReport, Thread)}.</p>
	 * 
	 *
	 * <p><i>Note:
	 * 	{@link OutputFormat#writeResult(TableIterator, OutputStream, TAPExecutionReport, Thread)} is often testing the "interrupted" flag of the
	 * 	thread in order to stop as fast as possible if the user has cancelled the job or if the thread has been interrupted for another reason.
	 * </i></p>
	 * 
	 *
	 * @param queryResult	Query result to format and to output.
	 * @param formatter		The object able to write the result in the appropriate format.
	 * @param output		The stream in which the result must be written.
	 * 
	 *
	 * @throws InterruptedException	If the thread has been interrupted.
	 * @throws IOException			If there is an error while writing the result in the given stream.
	 * @throws TAPException			If there is an error while formatting the result.
@@ -729,11 +752,11 @@ public class ADQLExecutor {

	/**
	 * <p>Drop all tables uploaded by the user from the database.</p>
	 * 
	 *
	 * <p><i>Note:
	 * 	By default, if an error occurs while dropping a table from the database, the error will just be logged ; it won't be thrown/propagated.
	 * </i></p>
	 * 
	 *
	 * @throws TAPException	If a grave error occurs. <i>By default, no exception is thrown ; they are just logged.</i>
	 */
	protected void dropUploadedTables() throws TAPException{
+15 −2
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ package tap;
 * You should have received a copy of the GNU Lesser General Public License
 * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2012-2018 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 * Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 *                       Astronomisches Rechen Institut (ARI)
 */

@@ -44,7 +44,7 @@ import uws.service.file.UWSFileManager;
 * </p>
 *
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 2.3 (09/2018)
 * @version 2.3 (03/2019)
 */
public interface ServiceConnection {

@@ -744,4 +744,17 @@ public interface ServiceConnection {
	 */
	public int[] getFetchSize();

	/**
	 * <i><b>[MANDATORY]</b></i>
	 * <p>This function tells whether TAP-Lib should automatically try to fix a
	 * query whose parsing failed because of a token error. After this fix
	 * attempt the query is parsed again for a last time.</p>
	 *
	 * @return	<i>true</i> to allow automatic fix attempt in case of error,
	 *        	<i>false</i> to disable this option.
	 *
	 * @since 2.3
	 */
	public boolean fixOnFailEnabled();

}
+62 −33
Original line number Diff line number Diff line
package tap;

import adql.db.DBColumn;

/*
 * This file is part of TAPLibrary.
 * 
 *
 * TAPLibrary is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 *
 * TAPLibrary is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 *
 * Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 *                       Astronomisches Rechen Institut (ARI)
 */

import tap.parameters.TAPParameters;
import adql.db.DBColumn;

/**
 * <p>Report the execution (including the parsing and the output writing) of an ADQL query.
 * It gives information on the job parameters, the job ID, whether it is a synchronous task or not, times of each execution step (uploading, parsing, executing and writing),
 * the resulting columns and the success or not of the execution.</p>
 * 
 * <p>This report is completely filled by {@link ADQLExecutor}, and aims to be used/read only at the end of the job or when it is definitely finished.</p>
 * 
 * Report the execution (including the parsing and the output writing) of an
 * ADQL query.
 *
 * <p>
 * 	It gives information on the job parameters, the job ID, whether it is a
 * 	synchronous task or not, times of each execution step (uploading, parsing,
 * 	executing and writing), the resulting columns and the success or not of the
 * 	execution.
 * </p>
 *
 * <p>
 * 	This report is completely filled by {@link ADQLExecutor}, and aims to be
 * 	used/read only at the end of the job or when it is definitely finished.
 * </p>
 *
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 2.0 (04/2015)
 * @version 2.3 (03/2019)
 */
public class TAPExecutionReport {

	/** ID of the job whose the execution is reported here. */
	public final String jobID;

	/** Indicate whether this execution is done in a synchronous or asynchronous job. */
	/** Indicate whether this execution is done in a synchronous or asynchronous
	 * job. */
	public final boolean synchronous;

	/** List of all parameters provided in the user request. */
	public final TAPParameters parameters;

	/** Input ADQL query after an automatic fix by TAP-Lib.
	 * <p>This field is set only if the option fix_on_fail is enabled in the TAP
	 * configuration and that a query has been fixed.</p>
	 * @since 2.3 */
	public String fixedQuery = null;

	/** List of all resulting columns. <i>Empty array, if not yet known.</i> */
	public DBColumn[] resultingColumns = new DBColumn[0];

@@ -51,21 +68,26 @@ public class TAPExecutionReport {
	 * @since 2.0 */
	public long nbRows = -1;

	/** Duration of all execution steps. <i>For the moment only 4 steps (in the order): uploading, parsing, executing and writing.</i> */
	protected final long[] durations = new long[]{-1,-1,-1,-1};
	/** Duration of all execution steps. <i>For the moment only 4 steps (in the
	 * order): uploading, parsing, executing and writing.</i> */
	protected final long[] durations = new long[]{ -1, -1, -1, -1 };

	/** Total duration of the job execution. */
	protected long totalDuration = -1;

	/** Indicate whether this job has ended successfully or not. <i>At the beginning or while executing, this field is always FALSE.</i> */
	/** Indicate whether this job has ended successfully or not.
	 * <i>At the beginning or while executing, this field is always FALSE.</i> */
	public boolean success = false;

	/**
	 * Build an empty execution report.
	 * 
	 * @param jobID			ID of the job whose the execution must be described here.
	 * @param synchronous	<i>true</i> if the job is synchronous, <i>false</i> otherwise.
	 * @param params		List of all parameters provided by the user for the execution.
	 *
	 * @param jobID			ID of the job whose the execution must be described
	 *             			here.
	 * @param synchronous	<i>true</i> if the job is synchronous,
	 *                   	<i>false</i> otherwise.
	 * @param params		List of all parameters provided by the user for the
	 *              		execution.
	 */
	public TAPExecutionReport(final String jobID, final boolean synchronous, final TAPParameters params){
		this.jobID = jobID;
@@ -74,14 +96,20 @@ public class TAPExecutionReport {
	}

	/**
	 * <p>Map the execution progression with an index inside the {@link #durations} array.</p>
	 * 
	 * <p><i><b>Warning:</b> for the moment, only {@link ExecutionProgression#UPLOADING}, {@link ExecutionProgression#PARSING},
	 * {@link ExecutionProgression#EXECUTING_ADQL} and {@link ExecutionProgression#WRITING_RESULT} are managed.</i></p>
	 * 
	 * Map the execution progression with an index inside the {@link #durations}
	 * array.
	 *
	 * <p><i><b>Warning:</b>
	 * 	for the moment, only {@link ExecutionProgression#UPLOADING},
	 * 	{@link ExecutionProgression#PARSING},
	 * 	{@link ExecutionProgression#EXECUTING_ADQL} and
	 * 	{@link ExecutionProgression#WRITING_RESULT} are managed.
	 * </i></p>
	 *
	 * @param tapProgression	Execution progression.
	 * 
	 * @return	Index in the array {@link #durations}, or -1 if the given execution progression is not managed.
	 *
	 * @return	Index in the array {@link #durations},
	 *        	or -1 if the given execution progression is not managed.
	 */
	protected int getIndexDuration(final ExecutionProgression tapProgression){
		switch(tapProgression){
@@ -100,11 +128,12 @@ public class TAPExecutionReport {

	/**
	 * Get the duration corresponding to the given job execution step.
	 * 
	 *
	 * @param tapStep	Job execution step.
	 * 
	 * @return	The corresponding duration (in ms), or -1 if this step has not been (yet) processed.
	 * 
	 *
	 * @return	The corresponding duration (in ms), or -1 if this step has not
	 *        	been (yet) processed.
	 *
	 * @see #getIndexDuration(ExecutionProgression)
	 */
	public final long getDuration(final ExecutionProgression tapStep){
@@ -117,7 +146,7 @@ public class TAPExecutionReport {

	/**
	 * Set the duration corresponding to the given execution step.
	 * 
	 *
	 * @param tapStep	Job execution step.
	 * @param duration	Duration (in ms) of the given execution step.
	 */
+45 −17

File changed.

Preview size limit exceeded, changes collapsed.

+11 −2
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ package tap.config;
 * You should have received a copy of the GNU Lesser General Public License
 * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2015-2018 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 * Copyright 2015-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 *                       Astronomisches Rechen Institut (ARI)
 */

@@ -41,7 +41,7 @@ import tap.backup.DefaultTAPBackupManager;
 * </i></p>
 *
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 2.3 (11/2018)
 * @version 2.3 (03/2019)
 * @since 2.0
 */
public final class TAPConfiguration {
@@ -172,6 +172,15 @@ public final class TAPConfiguration {
	public final static String KEY_ASYNC_FETCH_SIZE = "async_fetch_size";
	/** Default value of the property {@link #KEY_ASYNC_FETCH_SIZE}: {@value #DEFAULT_ASYNC_FETCH_SIZE}. */
	public final static int DEFAULT_ASYNC_FETCH_SIZE = 10000;
	/** Name/Key of the property specifying whether the fixOnFail option is
	 * enabled or not. This option lets automatically fix the input ADQL query
	 * if its tokenization fails.
	 * @since 2.3  */
	public final static String KEY_FIX_ON_FAIL = "fix_on_fail";
	/** Default value of the property {@link #KEY_FIX_ON_FAIL}:
	 * {@value #DEFAULT_FIX_ON_FAIL}.
	 * @since 2.3  */
	public final static boolean DEFAULT_FIX_ON_FAIL = false;
	/** Name/Key of the property specifying the name of the DataSource into the JDNI. */
	public final static String KEY_DATASOURCE_JNDI_NAME = "datasource_jndi_name";
	/** Name/Key of the property specifying the full class name of the JDBC driver.
Loading