View Javadoc
1   /*
2    * Copyright (c) 2002-2022, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.util.sql;
35  
36  import fr.paris.lutece.portal.service.database.AppConnectionService;
37  import fr.paris.lutece.portal.service.database.PluginConnectionService;
38  import fr.paris.lutece.portal.service.plugin.Plugin;
39  import fr.paris.lutece.portal.service.util.AppException;
40  import fr.paris.lutece.portal.service.util.AppLogService;
41  import fr.paris.lutece.portal.service.util.NoDatabaseException;
42  
43  import org.apache.logging.log4j.LogManager;
44  import org.apache.logging.log4j.Logger;
45  import org.springframework.jdbc.datasource.DataSourceUtils;
46  
47  import org.springframework.transaction.support.TransactionSynchronizationManager;
48  
49  import java.io.InputStream;
50  import java.io.Reader;
51  import java.math.BigDecimal;
52  import java.net.URL;
53  import java.sql.Array;
54  import java.sql.Blob;
55  import java.sql.Clob;
56  import java.sql.Connection;
57  import java.sql.Date;
58  import java.sql.NClob;
59  import java.sql.PreparedStatement;
60  import java.sql.Ref;
61  import java.sql.ResultSet;
62  import java.sql.RowId;
63  import java.sql.SQLException;
64  import java.sql.SQLXML;
65  import java.sql.Statement;
66  import java.sql.Time;
67  import java.sql.Timestamp;
68  import java.sql.Types;
69  
70  import java.text.MessageFormat;
71  import java.util.ArrayList;
72  import java.util.Calendar;
73  import java.util.List;
74  
75  import javax.sql.DataSource;
76  
77  /**
78   * Prepared statement util class
79   *
80   * @since version 1.3
81   */
82  public class DAOUtil implements AutoCloseable
83  {
84      public static final String MSG_EXCEPTION_SELECT_ERROR = "Error selecting row id : ";
85      private static final String DEFAULT_MODULE_NAME = "lutece";
86      private static final String LOGGER_DEBUG_SQL = "lutece.debug.sql.";
87  
88      /** Connection Service providing connection from a defined pool */
89      private PluginConnectionService _connectionService;
90  
91      /** JDBC Connection */
92      private Connection _connection;
93      private List<Array> _arrays;
94  
95      /** Plugin name */
96      private String _strPluginName;
97  
98      /** Prepared statement */
99      private PreparedStatement _statement;
100 
101     /** result set */
102     private ResultSet _resultSet;
103 
104     /**
105      * GeneratedKeys ResultSet (optional, only when _autoGeneratedKeys is Statement.RETURN_GENERATED_KEYS)
106      */
107     private Integer _autoGeneratedKeys;
108     private ResultSet _generatedKeysResultSet;
109 
110     /** True if SQL request are logged */
111     private boolean _bReleased;
112     private String _strSQL;
113     private boolean _bTransactionnal;
114     private boolean _bLogQueries;
115 
116     /** The debug logger */
117     private Logger _logger;
118     private StringBuilder _sbLogs = new StringBuilder( );
119 
120     /**
121      * Creates a new DAOUtil object.
122      *
123      * @param sql
124      *            Sql Query for prepared Statement
125      */
126     public DAOUtil( String sql )
127     {
128         this( sql, null, null, true );
129     }
130 
131     /**
132      * Creates a new DAOUtil object.
133      *
134      * @param sql
135      *            Sql Query for prepared Statement
136      */
137     public DAOUtil( String sql, boolean logQueries )
138     {
139         this( sql, null, null, logQueries );
140     }
141 
142     /**
143      * Creates a new DAOUtil object.
144      *
145      * @param strSQL
146      *            sql query for prepared Statement
147      * @param plugin
148      *            The plugin using this database access
149      */
150     public DAOUtil( String strSQL, Plugin plugin )
151     {
152         this( strSQL, null, plugin, true );
153     }
154 
155     /**
156      * Creates a new DAOUtil object.
157      *
158      * @param strSQL
159      *            sql query for prepared Statement
160      * @param plugin
161      *            The plugin using this database access
162      */
163     public DAOUtil( String strSQL, Plugin plugin, boolean bLogQueries )
164     {
165         this( strSQL, null, plugin, bLogQueries );
166     }
167 
168     /**
169      * Creates a new DAOUtil object.
170      *
171      * @since 6.0.0
172      * @param sql
173      *            Sql Query for prepared Statement
174      * @param autoGeneratedKeys
175      *            a flag indicating whether auto-generated keys should be returned; For example one of <code>Statement.RETURN_GENERATED_KEYS</code> or
176      *            <code>Statement.NO_GENERATED_KEYS</code>. See {@link PreparedStatement#prepareStatement(String, int)}
177      */
178     public DAOUtil( String sql, Integer autoGeneratedKeys )
179     {
180         this( sql, autoGeneratedKeys, null, true );
181     }
182 
183     /**
184      * Creates a new DAOUtil object.
185      *
186      * @since 6.0.0
187      * @param strSQL
188      *            sql query for prepared Statement
189      * @param autoGeneratedKeys
190      *            a flag indicating whether auto-generated keys should be returned; For example one of <code>Statement.RETURN_GENERATED_KEYS</code> or
191      *            <code>Statement.NO_GENERATED_KEYS</code>. See {@link PreparedStatement#prepareStatement(String, int)}
192      * @param plugin
193      *            The plugin using this database access
194      */
195     public DAOUtil( String strSQL, Integer autoGeneratedKeys, Plugin plugin )
196     {
197         this( strSQL, autoGeneratedKeys, plugin, true );
198     }
199 
200     /**
201      * Creates a new DAOUtil object.
202      *
203      * @param bLogQueries
204      * @since 6.0.0
205      * @param strSQL
206      *            sql query for prepared Statement
207      * @param autoGeneratedKeys
208      *            a flag indicating whether auto-generated keys should be returned; For example one of <code>Statement.RETURN_GENERATED_KEYS</code> or
209      *            <code>Statement.NO_GENERATED_KEYS</code>. See {@link PreparedStatement#prepareStatement(String, int)}
210      * @param plugin
211      *            The plugin using this database access
212      */
213     public DAOUtil( String strSQL, Integer autoGeneratedKeys, Plugin plugin, boolean bLogQueries )
214     {
215         _bReleased = false;
216         _strSQL = strSQL;
217         _autoGeneratedKeys = autoGeneratedKeys;
218         _bLogQueries = bLogQueries;
219 
220         loadPlugin( plugin );
221 
222         // Use the logger name "lutece.debug.sql.<plugin_name>" to filter logs by
223         // plugins
224         _logger = LogManager.getLogger( LOGGER_DEBUG_SQL + _strPluginName );
225 
226         if ( _logger.isDebugEnabled( ) )
227         {
228             log( "Module : '" + _strPluginName + "' - SQL Statement : " + ( _bLogQueries ? _strSQL : "(query log disabled)" ) );
229         }
230 
231         try
232         {
233             MultiPluginTransaction transaction = TransactionManager.getCurrentTransaction( plugin );
234 
235             if ( transaction != null )
236             {
237                 _bTransactionnal = true;
238             }
239             else
240             {
241                 // We check if there is a managed transaction to get the transactionnal
242                 // connection
243                 if ( TransactionSynchronizationManager.isSynchronizationActive( ) )
244                 {
245                     _bTransactionnal = true;
246 
247                     DataSource ds = AppConnectionService.getPoolManager( ).getDataSource( _connectionService.getPoolName( ) );
248                     _connection = DataSourceUtils.getConnection( ds );
249 
250                     if ( _logger.isDebugEnabled( ) )
251                     {
252                         _logger.debug( "Transactionnal context is used for pool " + _connectionService.getPoolName( ) );
253                     }
254                 }
255                 else
256                 {
257                     // no transaction found, use the connection service directly
258                     _connection = _connectionService.getConnection( );
259                 }
260             }
261 
262             createStatement( transaction );
263         }
264         catch( SQLException e )
265         {
266             free( );
267             throw new AppException( getErrorMessage( e ), e );
268         }
269     }
270 
271     private void createStatement( MultiPluginTransaction transaction ) throws SQLException
272     {
273         if ( transaction != null )
274         {
275             if ( _autoGeneratedKeys != null )
276             {
277                 _statement = transaction.prepareStatement( _strSQL, _autoGeneratedKeys, _bLogQueries );
278             }
279             else
280             {
281                 _statement = transaction.prepareStatement( _strSQL, _bLogQueries );
282             }
283         }
284         else
285             if ( _connection != null )
286             {
287                 if ( _autoGeneratedKeys != null )
288                 {
289                     _statement = _connection.prepareStatement( _strSQL, _autoGeneratedKeys );
290                 }
291                 else
292                 {
293                     _statement = _connection.prepareStatement( _strSQL );
294                 }
295             }
296             else
297             {
298                 throw new AppException( "Database access error for component '" + _strPluginName + "'. Please check plugin installation and db.properties." );
299             }
300     }
301 
302     private void loadPlugin( Plugin plugin )
303     {
304         if ( plugin != null )
305         {
306             _strPluginName = plugin.getName( );
307             _connectionService = plugin.getConnectionService( );
308         }
309         else
310         {
311             _strPluginName = DEFAULT_MODULE_NAME;
312             _connectionService = AppConnectionService.getDefaultConnectionService( );
313         }
314 
315         if ( _connectionService == null )
316         {
317             throw new NoDatabaseException( "Database access error. Please check component installations and db.properties." );
318         }
319     }
320 
321     /**
322      * Build a formatted error message for a given exception
323      * 
324      * @param e
325      *            The exception
326      * @return The error message
327      */
328     private String getErrorMessage( Exception e )
329     {
330         StringBuilder sbError = new StringBuilder( "DAOUtil error : " );
331         sbError.append( e.getMessage( ) );
332         sbError.append( " - SQL statement : " );
333         sbError.append( " - Plugin : " );
334         sbError.append( _strPluginName );
335 
336         return sbError.toString( );
337     }
338 
339     /**
340      * Executes the update request and throws an error if the result is not 1
341      */
342     public void executeUpdate( )
343     {
344         try
345         {
346             _statement.executeUpdate( );
347             if ( _autoGeneratedKeys != null && _autoGeneratedKeys.equals( Statement.RETURN_GENERATED_KEYS ) )
348             {
349                 _generatedKeysResultSet = _statement.getGeneratedKeys( );
350             }
351         }
352         catch( SQLException e )
353         {
354             free( );
355             throw new AppException( getErrorMessage( e ), e );
356         }
357     }
358 
359     /**
360      * Executes a query
361      */
362     public void executeQuery( )
363     {
364         try
365         {
366             _resultSet = _statement.executeQuery( );
367         }
368         catch( SQLException e )
369         {
370             free( );
371             throw new AppException( getErrorMessage( e ), e );
372         }
373     }
374 
375     /**
376      * Log a message
377      * 
378      * @param strMessage
379      *            The message to log
380      */
381     private void log( String strMessage )
382     {
383         if ( _logger.isDebugEnabled( ) )
384         {
385             _sbLogs.append( strMessage );
386         }
387     }
388 
389     /**
390      * Log a parameter
391      * 
392      * @param oName
393      *            The parameter name
394      * @param oValue
395      *            The parameter value
396      */
397     private void logParameter( Object oName, Object oValue )
398     {
399         if ( _logger.isDebugEnabled( ) )
400         {
401             Object [ ] args = {
402                     oName, oValue
403             };
404             log( MessageFormat.format( "\n               Index : ''{0}''       Value : ''{1}'' ", args ) );
405         }
406     }
407 
408     /**
409      * Free connection
410      */
411     public final void free( )
412     {
413         if ( !_bReleased )
414         {
415             _logger.debug( _sbLogs );
416         }
417 
418         try
419         {
420             // Close statement if necessary
421             if ( _statement != null )
422             {
423                 _statement.close( );
424             }
425             if ( _arrays != null )
426             {
427                 for ( Array array : _arrays )
428                 {
429                     array.free( );
430                 }
431             }
432         }
433         catch( SQLException e )
434         {
435             throw new AppException( e.getMessage( ), e );
436         }
437         finally
438         {
439             // Free the connection - the connection is freed some other way in
440             // transactionnal context.
441             if ( ( _connectionService != null ) && !_bTransactionnal )
442             {
443                 _connectionService.freeConnection( _connection );
444                 _connectionService = null;
445             }
446 
447             _bReleased = true;
448         }
449     }
450 
451     /**
452      * Indicates whether the cursor is on the last row of this ResultSet object.
453      * 
454      * @return true if the cursor is on the last row; false otherwise
455      */
456     public boolean isLast( )
457     {
458         try
459         {
460             return _resultSet.isLast( );
461         }
462         catch( SQLException e )
463         {
464             free( );
465             throw new AppException( getErrorMessage( e ), e );
466         }
467     }
468 
469     /**
470      * Fills the prepared statement with a date value
471      *
472      * @param nIndex
473      *            parameter index
474      * @param date
475      *            date value
476      */
477     public void setDate( int nIndex, Date date )
478     {
479         try
480         {
481             _statement.setDate( nIndex, date );
482             logParameter( nIndex, date );
483         }
484         catch( SQLException e )
485         {
486             free( );
487             throw new AppException( getErrorMessage( e ), e );
488         }
489     }
490 
491     /**
492      * Fills the prepared statement with a date value
493      *
494      * @see PreparedStatement#setDate(int, Date, Calendar)
495      * @since 5.1.1
496      * @param nIndex
497      *            parameter index
498      * @param date
499      *            date value
500      * @param calendar
501      *            the calendar
502      */
503     public void setDate( int nIndex, Date date, Calendar calendar )
504     {
505         try
506         {
507             _statement.setDate( nIndex, date, calendar );
508             logParameter( nIndex, date );
509         }
510         catch( SQLException e )
511         {
512             free( );
513             throw new AppException( getErrorMessage( e ), e );
514         }
515     }
516 
517     /**
518      * Fills the prepared statement with a time value
519      *
520      * @param nIndex
521      *            parameter index
522      * @param time
523      *            time value
524      */
525     public void setTime( int nIndex, Time time )
526     {
527         try
528         {
529             _statement.setTime( nIndex, time );
530             logParameter( nIndex, time );
531         }
532         catch( SQLException e )
533         {
534             free( );
535             throw new AppException( getErrorMessage( e ), e );
536         }
537     }
538 
539     /**
540      * Fills the prepared statement with a time value
541      *
542      * @see PreparedStatement#setTime(int, Time, Calendar)
543      * @since 5.1.1
544      * @param nIndex
545      *            parameter index
546      * @param time
547      *            time value
548      * @param calendar
549      *            the calendat
550      */
551     public void setTime( int nIndex, Time time, Calendar calendar )
552     {
553         try
554         {
555             _statement.setTime( nIndex, time, calendar );
556             logParameter( nIndex, time );
557         }
558         catch( SQLException e )
559         {
560             free( );
561             throw new AppException( getErrorMessage( e ), e );
562         }
563     }
564 
565     /**
566      * Fills the prepared statement with a binary value stream
567      * 
568      * @param nIndex
569      *            parameter index
570      * @param iStream
571      *            the java input stream which contains the binary parameter value
572      * @param nBlength
573      *            the number of bytes in the stream
574      */
575     public void setBinaryStream( int nIndex, InputStream iStream, int nBlength )
576     {
577         try
578         {
579             _statement.setBinaryStream( nIndex, iStream, nBlength );
580         }
581         catch( SQLException e )
582         {
583             free( );
584             throw new AppException( getErrorMessage( e ), e );
585         }
586     }
587 
588     /**
589      * Fills the prepared statement with a binary value stream
590      * 
591      * @see PreparedStatement#setBinaryStream(int, InputStream, long)
592      * @since 5.1.1
593      * @param nIndex
594      *            parameter index
595      * @param iStream
596      *            the java input stream which contains the binary parameter value
597      * @param nBlength
598      *            the number of bytes in the stream
599      */
600     public void setBinaryStream( int nIndex, InputStream iStream, long nBlength )
601     {
602         try
603         {
604             _statement.setBinaryStream( nIndex, iStream, nBlength );
605         }
606         catch( SQLException e )
607         {
608             free( );
609             throw new AppException( getErrorMessage( e ), e );
610         }
611     }
612 
613     /**
614      * Fills the prepared statement with a binary value stream
615      * 
616      * @see PreparedStatement#setBinaryStream(int, InputStream)
617      * @since 5.1.1
618      * @param nIndex
619      *            parameter index
620      * @param iStream
621      *            the java input stream which contains the binary parameter value
622      */
623     public void setBinaryStream( int nIndex, InputStream iStream )
624     {
625         try
626         {
627             _statement.setBinaryStream( nIndex, iStream );
628         }
629         catch( SQLException e )
630         {
631             free( );
632             throw new AppException( getErrorMessage( e ), e );
633         }
634     }
635 
636     /**
637      * Gets a binary stream from a resultSet
638      *
639      * @param nIndex
640      *            column index
641      * @return InputStream instance
642      */
643     public InputStream getBinaryStream( int nIndex )
644     {
645         try
646         {
647             return _resultSet.getBinaryStream( nIndex );
648         }
649         catch( SQLException e )
650         {
651             free( );
652             throw new AppException( getErrorMessage( e ), e );
653         }
654     }
655 
656     /**
657      * Gets a blob from a resultset
658      *
659      * @param nIndex
660      *            column index
661      * @return Blob instance
662      */
663     public Blob getBlob( int nIndex )
664     {
665         try
666         {
667             return _resultSet.getBlob( nIndex );
668         }
669         catch( SQLException e )
670         {
671             free( );
672             throw new AppException( getErrorMessage( e ), e );
673         }
674     }
675 
676     /**
677      * Gets a blob from a resultset
678      *
679      * @param strColumnName
680      *            column name
681      *
682      * @return Blob instance
683      */
684     public Blob getBlob( String strColumnName )
685     {
686         try
687         {
688             return _resultSet.getBlob( strColumnName );
689         }
690         catch( SQLException e )
691         {
692             free( );
693             throw new AppException( getErrorMessage( e ), e );
694         }
695     }
696 
697     /**
698      * Fills the prepared statement with a blob value from a stream
699      * 
700      * @see PreparedStatement#setBlob(int, InputStream)
701      * @since 5.1.1
702      * @param nIndex
703      *            the index
704      * @param stream
705      *            the value
706      */
707     public void setBlob( int nIndex, InputStream stream )
708     {
709         try
710         {
711             _statement.setBlob( nIndex, stream );
712         }
713         catch( SQLException e )
714         {
715             free( );
716             throw new AppException( getErrorMessage( e ), e );
717         }
718     }
719 
720     /**
721      * Fills the prepared statement with a blob value from a stream
722      * 
723      * @see PreparedStatement#setBlob(int, InputStream, long)
724      * @since 5.1.1
725      * @param nIndex
726      *            the index
727      * @param stream
728      *            the value
729      * @param nLength
730      *            the number of bytes to read
731      */
732     public void setBlob( int nIndex, InputStream stream, long nLength )
733     {
734         try
735         {
736             _statement.setBlob( nIndex, stream, nLength );
737         }
738         catch( SQLException e )
739         {
740             free( );
741             throw new AppException( getErrorMessage( e ), e );
742         }
743     }
744 
745     /**
746      * Fills the prepared statement with a blob value
747      * 
748      * @see PreparedStatement#setBlob(int, InputStream)
749      * @since 5.1.1
750      * @param nIndex
751      *            the index
752      * @param blob
753      *            the value
754      */
755     public void setBlob( int nIndex, Blob blob )
756     {
757         try
758         {
759             _statement.setBlob( nIndex, blob );
760         }
761         catch( SQLException e )
762         {
763             free( );
764             throw new AppException( getErrorMessage( e ), e );
765         }
766     }
767 
768     /**
769      * Gets a byte array from a resultset
770      *
771      * @param nIndex
772      *            column index
773      *
774      * @return byte[] instance
775      */
776     public byte [ ] getBytes( int nIndex )
777     {
778         try
779         {
780             return _resultSet.getBytes( nIndex );
781         }
782         catch( SQLException e )
783         {
784             free( );
785             throw new AppException( getErrorMessage( e ), e );
786         }
787     }
788 
789     /**
790      * Gets a byte array from a resultset
791      *
792      * @param strColumnName
793      *            column name
794      *
795      * @return byte[] instance
796      */
797     public byte [ ] getBytes( String strColumnName )
798     {
799         try
800         {
801             return _resultSet.getBytes( strColumnName );
802         }
803         catch( SQLException e )
804         {
805             free( );
806             throw new AppException( getErrorMessage( e ), e );
807         }
808     }
809 
810     /**
811      * Gets a byte from a resultset
812      *
813      * @see ResultSet#getByte(int)
814      * @since 5.1.1
815      * @param nIndex
816      *            column index
817      * @return byte instance
818      */
819     public byte getByte( int nIndex )
820     {
821         try
822         {
823             return _resultSet.getByte( nIndex );
824         }
825         catch( SQLException e )
826         {
827             free( );
828             throw new AppException( getErrorMessage( e ), e );
829         }
830     }
831 
832     /**
833      * Gets a byte from a resultset
834      *
835      * @see ResultSet#getByte(int)
836      * @since 5.1.1
837      * @param strColumnName
838      *            column name
839      * @return byte instance
840      */
841     public byte getByte( String strColumnName )
842     {
843         try
844         {
845             return _resultSet.getByte( strColumnName );
846         }
847         catch( SQLException e )
848         {
849             free( );
850             throw new AppException( getErrorMessage( e ), e );
851         }
852     }
853 
854     /**
855      * Fills the prepared statement with a int value
856      *
857      * @param nIndex
858      *            parameter index in the prepared statement
859      * @param nValue
860      *            int value
861      */
862     public void setInt( int nIndex, int nValue )
863     {
864         try
865         {
866             _statement.setInt( nIndex, nValue );
867             logParameter( nIndex, nValue );
868         }
869         catch( SQLException e )
870         {
871             free( );
872             throw new AppException( getErrorMessage( e ), e );
873         }
874     }
875 
876     /**
877      * Fills the prepared statement with a Boolean value
878      *
879      * @param nIndex
880      *            parameter index in the prepared statement
881      * @param bValue
882      *            Boolean value
883      */
884     public void setBoolean( int nIndex, boolean bValue )
885     {
886         try
887         {
888             _statement.setInt( nIndex, ( bValue ) ? 1 : 0 );
889             logParameter( nIndex, bValue );
890         }
891         catch( SQLException e )
892         {
893             free( );
894             throw new AppException( getErrorMessage( e ), e );
895         }
896     }
897 
898     /**
899      * Fills the prepared statement with a byte value
900      * 
901      * @see PreparedStatement#setByte(int, byte)
902      * @since 5.1.1
903      * @param nIndex
904      *            parameter index in the prepared statement
905      * @param bValue
906      *            byte value
907      */
908     public void setByte( int nIndex, byte bValue )
909     {
910         try
911         {
912             _statement.setByte( nIndex, bValue );
913             logParameter( nIndex, bValue );
914         }
915         catch( SQLException e )
916         {
917             free( );
918             throw new AppException( getErrorMessage( e ), e );
919         }
920     }
921 
922     /**
923      * Fills the prepared statement with a byte array value
924      *
925      * @param nIndex
926      *            parameter index in the prepared statement
927      * @param tbValue
928      *            byte array value
929      */
930     public void setBytes( int nIndex, byte [ ] tbValue )
931     {
932         try
933         {
934             _statement.setBytes( nIndex, tbValue );
935         }
936         catch( SQLException e )
937         {
938             free( );
939             throw new AppException( getErrorMessage( e ), e );
940         }
941     }
942 
943     /**
944      * Fills the prepared statement with a string value
945      *
946      * @param nIndex
947      *            parameter index in the prepared statement
948      * @param strValue
949      *            string value
950      */
951     public void setString( int nIndex, String strValue )
952     {
953         try
954         {
955             _statement.setString( nIndex, strValue );
956             logParameter( nIndex, strValue );
957         }
958         catch( SQLException e )
959         {
960             free( );
961             throw new AppException( getErrorMessage( e ), e );
962         }
963     }
964 
965     /**
966      * Fills the prepared statement with a timestamp value
967      *
968      * @param nIndex
969      *            parameter index in the prepared statement
970      * @param ts
971      *            timestamp value
972      */
973     public void setTimestamp( int nIndex, Timestamp ts )
974     {
975         try
976         {
977             _statement.setTimestamp( nIndex, ts );
978             logParameter( nIndex, ts );
979         }
980         catch( SQLException e )
981         {
982             free( );
983             throw new AppException( getErrorMessage( e ), e );
984         }
985     }
986 
987     /**
988      * Fills the prepared statement with a timestamp value
989      *
990      * @see PreparedStatement#setTimestamp(int, Timestamp, Calendar)
991      * @since 5.1.1
992      * @param nIndex
993      *            parameter index in the prepared statement
994      * @param ts
995      *            timestamp value
996      * @param calendar
997      *            the calendar
998      */
999     public void setTimestamp( int nIndex, Timestamp ts, Calendar calendar )
1000     {
1001         try
1002         {
1003             _statement.setTimestamp( nIndex, ts, calendar );
1004             logParameter( nIndex, ts );
1005         }
1006         catch( SQLException e )
1007         {
1008             free( );
1009             throw new AppException( getErrorMessage( e ), e );
1010         }
1011     }
1012 
1013     /**
1014      * Fills the prepared statement with a double value
1015      * 
1016      * @param nIndex
1017      *            parameter index in the prepared statement
1018      * @param dValue
1019      *            The value
1020      */
1021     public void setDouble( int nIndex, double dValue )
1022     {
1023         try
1024         {
1025             _statement.setDouble( nIndex, dValue );
1026             logParameter( nIndex, dValue );
1027         }
1028         catch( SQLException e )
1029         {
1030             free( );
1031             throw new AppException( getErrorMessage( e ), e );
1032         }
1033     }
1034 
1035     /**
1036      * Sets null value for a "double" column
1037      * 
1038      * @param nIndex
1039      *            the index
1040      */
1041     public void setDoubleNull( int nIndex )
1042     {
1043         try
1044         {
1045             _statement.setNull( nIndex, Types.DOUBLE );
1046             logParameter( nIndex, "null" );
1047         }
1048         catch( SQLException e )
1049         {
1050             free( );
1051             throw new AppException( getErrorMessage( e ), e );
1052         }
1053     }
1054 
1055     /**
1056      * Gets the value of the designated column in the current row of this ResultSet object as a java.sql.Date object in the Java programming language.
1057      *
1058      * @param nIndex
1059      *            the first column is 1, the second is 2, ...
1060      *
1061      * @return the column value; if the value is SQL NULL, the value returned is null
1062      */
1063     public Date getDate( int nIndex )
1064     {
1065         try
1066         {
1067             return _resultSet.getDate( nIndex );
1068         }
1069         catch( SQLException e )
1070         {
1071             free( );
1072             throw new AppException( getErrorMessage( e ), e );
1073         }
1074     }
1075 
1076     /**
1077      * Gets the value of the designated column in the current row of this ResultSet object as a java.sql.Date object in the Java programming language.
1078      *
1079      * @param strColumnName
1080      *            name of the column, ...
1081      *
1082      * @return the column value; if the value is SQL NULL, the value returned is null
1083      */
1084     public Date getDate( String strColumnName )
1085     {
1086         try
1087         {
1088             return _resultSet.getDate( strColumnName );
1089         }
1090         catch( SQLException e )
1091         {
1092             free( );
1093             throw new AppException( getErrorMessage( e ), e );
1094         }
1095     }
1096 
1097     /**
1098      * Gets the value of the designated column in the current row of this ResultSet object as a java.sql.Date object in the Java programming language.
1099      *
1100      * @see ResultSet#getDate(int, Calendar)
1101      * @since 5.1.1
1102      * @param nIndex
1103      *            the first column is 1, the second is 2, ...
1104      * @param calendar
1105      *            the calendar
1106      * @return the column value; if the value is SQL NULL, the value returned is null
1107      */
1108     public Date getDate( int nIndex, Calendar calendar )
1109     {
1110         try
1111         {
1112             return _resultSet.getDate( nIndex, calendar );
1113         }
1114         catch( SQLException e )
1115         {
1116             free( );
1117             throw new AppException( getErrorMessage( e ), e );
1118         }
1119     }
1120 
1121     /**
1122      * Gets the value of the designated column in the current row of this ResultSet object as a java.sql.Date object in the Java programming language.
1123      *
1124      * @see ResultSet#getDate(String, Calendar)
1125      * @since 5.1.1
1126      * @param strColumnName
1127      *            name of the column, ...
1128      * @param calendar
1129      *            the calendar
1130      * @return the column value; if the value is SQL NULL, the value returned is null
1131      */
1132     public Date getDate( String strColumnName, Calendar calendar )
1133     {
1134         try
1135         {
1136             return _resultSet.getDate( strColumnName, calendar );
1137         }
1138         catch( SQLException e )
1139         {
1140             free( );
1141             throw new AppException( getErrorMessage( e ), e );
1142         }
1143     }
1144 
1145     /**
1146      * Gets the value of the designated column in the current row of this ResultSet object as a java.sql.Time object in the Java programming language.
1147      *
1148      * @param nIndex
1149      *            the first column is 1, the second is 2, ...
1150      *
1151      * @return the column value; if the value is SQL NULL, the value returned is null
1152      */
1153     public Time getTime( int nIndex )
1154     {
1155         try
1156         {
1157             return _resultSet.getTime( nIndex );
1158         }
1159         catch( SQLException e )
1160         {
1161             free( );
1162             throw new AppException( getErrorMessage( e ), e );
1163         }
1164     }
1165 
1166     /**
1167      * Gets the value of the designated column in the current row of this ResultSet object as a java.sql.Time object in the Java programming language.
1168      *
1169      * @param strColumnName
1170      *            name of the column, ...
1171      *
1172      * @return the column value; if the value is SQL NULL, the value returned is null
1173      */
1174     public Time getTime( String strColumnName )
1175     {
1176         try
1177         {
1178             return _resultSet.getTime( strColumnName );
1179         }
1180         catch( SQLException e )
1181         {
1182             free( );
1183             throw new AppException( getErrorMessage( e ), e );
1184         }
1185     }
1186 
1187     /**
1188      * Gets the value of the designated column in the current row of this ResultSet object as a java.sql.Time object in the Java programming language.
1189      *
1190      * @see ResultSet#getTime(int, Calendar)
1191      * @since 5.1.1
1192      * @param nIndex
1193      *            the first column is 1, the second is 2, ...
1194      * @param calendar
1195      *            the calendar
1196      * @return the column value; if the value is SQL NULL, the value returned is null
1197      */
1198     public Time getTime( int nIndex, Calendar calendar )
1199     {
1200         try
1201         {
1202             return _resultSet.getTime( nIndex, calendar );
1203         }
1204         catch( SQLException e )
1205         {
1206             free( );
1207             throw new AppException( getErrorMessage( e ), e );
1208         }
1209     }
1210 
1211     /**
1212      * Gets the value of the designated column in the current row of this ResultSet object as a java.sql.Time object in the Java programming language.
1213      *
1214      * @see ResultSet#getTime(String, Calendar)
1215      * @since 5.1.1
1216      * @param strColumnName
1217      *            name of the column, ...
1218      * @param calendar
1219      *            the calendar
1220      * @return the column value; if the value is SQL NULL, the value returned is null
1221      */
1222     public Time getTime( String strColumnName, Calendar calendar )
1223     {
1224         try
1225         {
1226             return _resultSet.getTime( strColumnName, calendar );
1227         }
1228         catch( SQLException e )
1229         {
1230             free( );
1231             throw new AppException( getErrorMessage( e ), e );
1232         }
1233     }
1234 
1235     /**
1236      * Gets the value of the designated column in the current row of this ResultSet object as a int
1237      *
1238      * @param nIndex
1239      *            the first column is 1, the second is 2, ...
1240      *
1241      * @return the column value; if the value is SQL NULL, the value returned is 0
1242      */
1243     public int getInt( int nIndex )
1244     {
1245         try
1246         {
1247             return _resultSet.getInt( nIndex );
1248         }
1249         catch( SQLException e )
1250         {
1251             free( );
1252             throw new AppException( getErrorMessage( e ), e );
1253         }
1254     }
1255 
1256     /**
1257      * Gets the value of the designated column in the current row of this ResultSet object as a int
1258      *
1259      * @param strColumnName
1260      *            column name
1261      *
1262      * @return the column value; if the value is SQL NULL, the value returned is 0
1263      */
1264     public int getInt( String strColumnName )
1265     {
1266         try
1267         {
1268             return _resultSet.getInt( strColumnName );
1269         }
1270         catch( SQLException e )
1271         {
1272             free( );
1273             throw new AppException( getErrorMessage( e ), e );
1274         }
1275     }
1276 
1277     /**
1278      * Gets the value of the designated column in the current row of this ResultSet object as a Boolean
1279      *
1280      * @param nIndex
1281      *            the first column is 1, the second is 2, ...
1282      *
1283      * @return the column value; if the value is SQL NULL, the value returned is FALSE
1284      */
1285     public boolean getBoolean( int nIndex )
1286     {
1287         try
1288         {
1289             return ( _resultSet.getInt( nIndex ) != 0 );
1290         }
1291         catch( SQLException e )
1292         {
1293             free( );
1294             throw new AppException( getErrorMessage( e ), e );
1295         }
1296     }
1297 
1298     /**
1299      * Gets the value of the designated column in the current row of this ResultSet object as a Boolean
1300      *
1301      * @param strColumnName
1302      *            column name
1303      *
1304      * @return the column value; if the value is SQL NULL, the value returned is FALSE
1305      */
1306     public boolean getBoolean( String strColumnName )
1307     {
1308         try
1309         {
1310             return ( _resultSet.getInt( strColumnName ) != 0 );
1311         }
1312         catch( SQLException e )
1313         {
1314             free( );
1315             throw new AppException( getErrorMessage( e ), e );
1316         }
1317     }
1318 
1319     /**
1320      * Gets the value of the designated column in the current row of this ResultSet object as a string
1321      *
1322      * @param nIndex
1323      *            the first column is 1, the second is 2, ...
1324      *
1325      * @return the column value; if the value is SQL NULL, the value returned is NULL
1326      */
1327     public String getString( int nIndex )
1328     {
1329         try
1330         {
1331             return _resultSet.getString( nIndex );
1332         }
1333         catch( SQLException e )
1334         {
1335             free( );
1336             throw new AppException( getErrorMessage( e ), e );
1337         }
1338     }
1339 
1340     /**
1341      * Gets the value of the designated column in the current row of this ResultSet object as a string
1342      *
1343      * @param strColumnName
1344      *            column name
1345      *
1346      * @return the column value; if the value is SQL NULL, the value returned is NULL
1347      */
1348     public String getString( String strColumnName )
1349     {
1350         try
1351         {
1352             return _resultSet.getString( strColumnName );
1353         }
1354         catch( SQLException e )
1355         {
1356             free( );
1357             throw new AppException( getErrorMessage( e ), e );
1358         }
1359     }
1360 
1361     /**
1362      * Gets the value of the designated column in the current row of this ResultSet object as a timestamp
1363      *
1364      * @param nIndex
1365      *            the first column is 1, the second is 2, ...
1366      *
1367      * @return the column value; if the value is SQL NULL, the value returned is NULL
1368      */
1369     public Timestamp getTimestamp( int nIndex )
1370     {
1371         try
1372         {
1373             return _resultSet.getTimestamp( nIndex );
1374         }
1375         catch( SQLException e )
1376         {
1377             free( );
1378             throw new AppException( getErrorMessage( e ), e );
1379         }
1380     }
1381 
1382     /**
1383      * Gets the value of the designated column in the current row of this ResultSet object as a Timestamp
1384      *
1385      * @param strColumnName
1386      *            column name
1387      *
1388      * @return the column value; if the value is SQL NULL, the value returned is NULL
1389      */
1390     public Timestamp getTimestamp( String strColumnName )
1391     {
1392         try
1393         {
1394             return _resultSet.getTimestamp( strColumnName );
1395         }
1396         catch( SQLException e )
1397         {
1398             free( );
1399             throw new AppException( getErrorMessage( e ), e );
1400         }
1401     }
1402 
1403     /**
1404      * Gets the value of the designated column in the current row of this ResultSet object as a timestamp
1405      *
1406      * @see ResultSet#getTimestamp(int, Calendar)
1407      * @since 5.1.1
1408      * @param nIndex
1409      *            the first column is 1, the second is 2, ...
1410      * @param calendar
1411      *            the calendar
1412      * @return the column value; if the value is SQL NULL, the value returned is NULL
1413      */
1414     public Timestamp getTimestamp( int nIndex, Calendar calendar )
1415     {
1416         try
1417         {
1418             return _resultSet.getTimestamp( nIndex, calendar );
1419         }
1420         catch( SQLException e )
1421         {
1422             free( );
1423             throw new AppException( getErrorMessage( e ), e );
1424         }
1425     }
1426 
1427     /**
1428      * Gets the value of the designated column in the current row of this ResultSet object as a Timestamp
1429      *
1430      * @see ResultSet#getTimestamp(String, Calendar)
1431      * @since 5.1.1
1432      * @param strColumnName
1433      *            column name
1434      * @param calendar
1435      *            the calendar
1436      * @return the column value; if the value is SQL NULL, the value returned is NULL
1437      */
1438     public Timestamp getTimestamp( String strColumnName, Calendar calendar )
1439     {
1440         try
1441         {
1442             return _resultSet.getTimestamp( strColumnName, calendar );
1443         }
1444         catch( SQLException e )
1445         {
1446             free( );
1447             throw new AppException( getErrorMessage( e ), e );
1448         }
1449     }
1450 
1451     /**
1452      * Gets the value of the designated column in the current row of this ResultSet object as a double
1453      * 
1454      * @param strColumnName
1455      *            column name
1456      * @return the column value; if the value is SQL NULL, the value returned is NULL
1457      */
1458     public double getDouble( String strColumnName )
1459     {
1460         try
1461         {
1462             return _resultSet.getDouble( strColumnName );
1463         }
1464         catch( SQLException e )
1465         {
1466             free( );
1467             throw new AppException( getErrorMessage( e ), e );
1468         }
1469     }
1470 
1471     /**
1472      * Gets the value of the designated column in the current row of this ResultSet object as a double
1473      * 
1474      * @param nIndex
1475      *            the first column is 1, the second is 2, ...
1476      *
1477      * @return the column value; if the value is SQL NULL, the value returned is 0
1478      */
1479     public double getDouble( int nIndex )
1480     {
1481         try
1482         {
1483             return _resultSet.getDouble( nIndex );
1484         }
1485         catch( SQLException e )
1486         {
1487             free( );
1488             throw new AppException( getErrorMessage( e ), e );
1489         }
1490     }
1491 
1492     /**
1493      * Gets the value of the designated column in the current row of this ResultSet object as a Object
1494      *
1495      * @param nIndex
1496      *            the first column is 1, the second is 2, ...
1497      *
1498      * @return the column value; if the value is SQL NULL, the value returned is NULL
1499      */
1500     public Object getObject( int nIndex )
1501     {
1502         try
1503         {
1504             return _resultSet.getObject( nIndex );
1505         }
1506         catch( SQLException e )
1507         {
1508             free( );
1509             throw new AppException( getErrorMessage( e ), e );
1510         }
1511     }
1512 
1513     /**
1514      * Gets the value of the designated column in the current row of this ResultSet object as a T
1515      *
1516      * @see ResultSet#getObject(int, Class)
1517      * @since 5.1.1
1518      * @param nIndex
1519      *            the first column is 1, the second is 2, ...
1520      * @param type
1521      *            the type
1522      * @param <T>
1523      *            the return type
1524      * @return the column value; if the value is SQL NULL, the value returned is NULL
1525      */
1526     public <T> T getObject( int nIndex, Class<T> type )
1527     {
1528         try
1529         {
1530             return _resultSet.getObject( nIndex, type );
1531         }
1532         catch( SQLException e )
1533         {
1534             free( );
1535             throw new AppException( getErrorMessage( e ), e );
1536         }
1537     }
1538 
1539     /**
1540      * Gets the value of the designated column in the current row of this ResultSet object as a Object
1541      *
1542      * @see ResultSet#getObject(int, java.util.Map)
1543      * @since 5.1.1
1544      * @param nIndex
1545      *            the first column is 1, the second is 2, ...
1546      * @param map
1547      *            the type map
1548      * @return the column value; if the value is SQL NULL, the value returned is NULL
1549      */
1550     public Object getObject( int nIndex, java.util.Map<String, Class<?>> map )
1551     {
1552         try
1553         {
1554             return _resultSet.getObject( nIndex, map );
1555         }
1556         catch( SQLException e )
1557         {
1558             free( );
1559             throw new AppException( getErrorMessage( e ), e );
1560         }
1561     }
1562 
1563     /**
1564      * Get the ResultSet
1565      * 
1566      * @return the resultSet
1567      */
1568     public ResultSet getResultSet( )
1569     {
1570         return _resultSet;
1571     }
1572 
1573     /**
1574      * Get the GeneratedKeys ResultSet
1575      *
1576      * @since 6.0.0
1577      * @return the GeneratedKeys ResultSet
1578      */
1579     public ResultSet getGeneratedKeysResultSet( )
1580     {
1581         return _generatedKeysResultSet;
1582     }
1583 
1584     /**
1585      * Gets the value of the designated column in the current row of this ResultSet object as an Object
1586      *
1587      * @param strColumnName
1588      *            column name
1589      *
1590      * @return the column value; if the value is SQL NULL, the value returned is NULL
1591      */
1592     public Object getObject( String strColumnName )
1593     {
1594         try
1595         {
1596             return _resultSet.getObject( strColumnName );
1597         }
1598         catch( SQLException e )
1599         {
1600             free( );
1601             throw new AppException( getErrorMessage( e ), e );
1602         }
1603     }
1604 
1605     /**
1606      * Gets the value of the designated column in the current row of this ResultSet object as an Object
1607      *
1608      * @see ResultSet#getObject(String, Class)
1609      * @since 5.1.1
1610      * @param strColumnName
1611      *            column name
1612      * @param type
1613      *            the type
1614      * @param <T>
1615      *            the return type
1616      *
1617      * @return the column value; if the value is SQL NULL, the value returned is NULL
1618      */
1619     public <T> T getObject( String strColumnName, Class<T> type )
1620     {
1621         try
1622         {
1623             return _resultSet.getObject( strColumnName, type );
1624         }
1625         catch( SQLException e )
1626         {
1627             free( );
1628             throw new AppException( getErrorMessage( e ), e );
1629         }
1630     }
1631 
1632     /**
1633      * Gets the value of the designated column in the current row of this ResultSet object as an Object
1634      *
1635      * @see ResultSet#getObject(String, java.util.Map)
1636      * @since 5.1.1
1637      * @param strColumnName
1638      *            column name
1639      * @param map
1640      *            type map
1641      * @return the column value; if the value is SQL NULL, the value returned is NULL
1642      */
1643     public Object getObject( String strColumnName, java.util.Map<String, Class<?>> map )
1644     {
1645         try
1646         {
1647             return _resultSet.getObject( strColumnName, map );
1648         }
1649         catch( SQLException e )
1650         {
1651             free( );
1652             throw new AppException( getErrorMessage( e ), e );
1653         }
1654     }
1655 
1656     /**
1657      * Moves the cursor down one row from its current position in the ResultSet.
1658      *
1659      * @return true if the new current row is valid; false if there are no more rows
1660      */
1661     public boolean next( )
1662     {
1663         try
1664         {
1665             return _resultSet.next( );
1666         }
1667         catch( SQLException e )
1668         {
1669             free( );
1670             throw new AppException( getErrorMessage( e ), e );
1671         }
1672     }
1673 
1674     /**
1675      * Moves the cursor down one row from its current position in the GeneratedKeys ResultSet.
1676      *
1677      * @since 6.0.0
1678      * @return true if the new current row is valid; false if there are no more rows
1679      */
1680     public boolean nextGeneratedKey( )
1681     {
1682         try
1683         {
1684             return _generatedKeysResultSet.next( );
1685         }
1686         catch( SQLException e )
1687         {
1688             free( );
1689             throw new AppException( getErrorMessage( e ), e );
1690         }
1691     }
1692 
1693     /**
1694      * Gets the value of the designated column in the current row of this GeneratedKeys ResultSet object as a byte
1695      *
1696      * @since 6.0.0
1697      * @param nIndex
1698      *            the first column is 1, the second is 2, ...
1699      *
1700      * @return the column value; if the value is SQL NULL, the value returned is 0
1701      */
1702     public byte getGeneratedKeyByte( int nIndex )
1703     {
1704         try
1705         {
1706             return _generatedKeysResultSet.getByte( nIndex );
1707         }
1708         catch( SQLException e )
1709         {
1710             free( );
1711             throw new AppException( getErrorMessage( e ), e );
1712         }
1713     }
1714 
1715     /**
1716      * Gets the value of the designated column in the current row of this GeneratedKeys ResultSet object as a short
1717      *
1718      * @since 6.0.0
1719      * @param nIndex
1720      *            the first column is 1, the second is 2, ...
1721      *
1722      * @return the column value; if the value is SQL NULL, the value returned is 0
1723      */
1724     public short getGeneratedKeyShort( int nIndex )
1725     {
1726         try
1727         {
1728             return _generatedKeysResultSet.getShort( nIndex );
1729         }
1730         catch( SQLException e )
1731         {
1732             free( );
1733             throw new AppException( getErrorMessage( e ), e );
1734         }
1735     }
1736 
1737     /**
1738      * Gets the value of the designated column in the current row of this GeneratedKeys ResultSet object as a int
1739      *
1740      * @since 6.0.0
1741      * @param nIndex
1742      *            the first column is 1, the second is 2, ...
1743      *
1744      * @return the column value; if the value is SQL NULL, the value returned is 0
1745      */
1746     public int getGeneratedKeyInt( int nIndex )
1747     {
1748         try
1749         {
1750             return _generatedKeysResultSet.getInt( nIndex );
1751         }
1752         catch( SQLException e )
1753         {
1754             free( );
1755             throw new AppException( getErrorMessage( e ), e );
1756         }
1757     }
1758 
1759     /**
1760      * Gets the value of the designated column in the current row of this GeneratedKeys ResultSet object as a long
1761      *
1762      * @since 6.0.0
1763      * @param nIndex
1764      *            the first column is 1, the second is 2, ...
1765      *
1766      * @return the column value; if the value is SQL NULL, the value returned is 0
1767      */
1768     public long getGeneratedKeyLong( int nIndex )
1769     {
1770         try
1771         {
1772             return _generatedKeysResultSet.getLong( nIndex );
1773         }
1774         catch( SQLException e )
1775         {
1776             free( );
1777             throw new AppException( getErrorMessage( e ), e );
1778         }
1779     }
1780 
1781     /**
1782      * Gets the value of the designated column in the current row of this GeneratedKeys ResultSet object as a BigDecimal
1783      *
1784      * @since 6.0.0
1785      * @param nIndex
1786      *            the first column is 1, the second is 2, ...
1787      *
1788      * @return the column value; if the value is SQL NULL, the value returned is 0
1789      */
1790     public BigDecimal getGeneratedKeyBigDecimal( int nIndex )
1791     {
1792         try
1793         {
1794             return _generatedKeysResultSet.getBigDecimal( nIndex );
1795         }
1796         catch( SQLException e )
1797         {
1798             free( );
1799             throw new AppException( getErrorMessage( e ), e );
1800         }
1801     }
1802 
1803     /**
1804      * Fills the prepared statement with a int null value
1805      * 
1806      * @param nIndex
1807      *            parameter index
1808      */
1809     public void setIntNull( int nIndex )
1810     {
1811         try
1812         {
1813             _statement.setNull( nIndex, Types.INTEGER );
1814             logParameter( nIndex, "null" );
1815         }
1816         catch( SQLException e )
1817         {
1818             free( );
1819             throw new AppException( getErrorMessage( e ), e );
1820         }
1821     }
1822 
1823     /**
1824      * Sets null value for a "long" column
1825      * 
1826      * @param nIndex
1827      *            the index
1828      */
1829     public void setLongNull( int nIndex )
1830     {
1831         try
1832         {
1833             _statement.setNull( nIndex, Types.BIGINT );
1834             logParameter( nIndex, "null" );
1835         }
1836         catch( SQLException e )
1837         {
1838             free( );
1839             throw new AppException( getErrorMessage( e ), e );
1840         }
1841     }
1842 
1843     /**
1844      * Sets a long value
1845      * 
1846      * @param nIndex
1847      *            the index
1848      * @param lValue
1849      *            the value
1850      */
1851     public void setLong( int nIndex, long lValue )
1852     {
1853         try
1854         {
1855             _statement.setLong( nIndex, lValue );
1856             logParameter( nIndex, lValue );
1857         }
1858         catch( SQLException e )
1859         {
1860             free( );
1861             throw new AppException( getErrorMessage( e ), e );
1862         }
1863     }
1864 
1865     /**
1866      * Gets the long value
1867      * 
1868      * @param nIndex
1869      *            the index
1870      * @return the long value
1871      */
1872     public long getLong( int nIndex )
1873     {
1874         try
1875         {
1876             return _resultSet.getLong( nIndex );
1877         }
1878         catch( SQLException e )
1879         {
1880             free( );
1881             throw new AppException( getErrorMessage( e ), e );
1882         }
1883     }
1884 
1885     /**
1886      * Gets the long value
1887      * 
1888      * @param strColumnName
1889      *            the column name
1890      * @return the long value
1891      */
1892     public long getLong( String strColumnName )
1893     {
1894         try
1895         {
1896             return _resultSet.getLong( strColumnName );
1897         }
1898         catch( SQLException e )
1899         {
1900             free( );
1901             throw new AppException( getErrorMessage( e ), e );
1902         }
1903     }
1904 
1905     /**
1906      * Set an Array value
1907      *
1908      * @see Connection#createArrayOf(String, Object[])
1909      * @see PreparedStatement#setArray(int, Array)
1910      * @since 5.1.1
1911      * @param nIndex
1912      *            the index
1913      * @param strTypename
1914      *            the type SQL name
1915      * @param elements
1916      *            the array value
1917      */
1918     public void setArray( int nIndex, String strTypename, Object [ ] elements )
1919     {
1920         try
1921         {
1922             Array x = _connection.createArrayOf( strTypename, elements );
1923             registerArray( x );
1924             _statement.setArray( nIndex, x );
1925         }
1926         catch( SQLException e )
1927         {
1928             free( );
1929             throw new AppException( getErrorMessage( e ), e );
1930         }
1931     }
1932 
1933     /**
1934      * Register an SQL Array to be able to free it later
1935      * 
1936      * @param array
1937      *            the array to register
1938      */
1939     private void registerArray( Array array )
1940     {
1941         if ( _arrays == null )
1942         {
1943             _arrays = new ArrayList<>( );
1944         }
1945         _arrays.add( array );
1946     }
1947 
1948     /**
1949      * Get an Array value
1950      * 
1951      * @see ResultSet#getArray(int)
1952      * @since 5.1.1
1953      * @param nIndex
1954      *            the index
1955      * @return the array value
1956      */
1957     public Array getArray( int nIndex )
1958     {
1959         try
1960         {
1961             Array res = _resultSet.getArray( nIndex );
1962             registerArray( res );
1963             return res;
1964         }
1965         catch( SQLException e )
1966         {
1967             free( );
1968             throw new AppException( getErrorMessage( e ), e );
1969         }
1970     }
1971 
1972     /**
1973      * Get an Array value
1974      * 
1975      * @see ResultSet#getArray(String)
1976      * @since 5.1.1
1977      * @param strColumnName
1978      *            the column name
1979      * @return the array value
1980      */
1981     public Array getArray( String strColumnName )
1982     {
1983         try
1984         {
1985             Array res = _resultSet.getArray( strColumnName );
1986             registerArray( res );
1987             return res;
1988         }
1989         catch( SQLException e )
1990         {
1991             free( );
1992             throw new AppException( getErrorMessage( e ), e );
1993         }
1994     }
1995 
1996     /**
1997      * Fills the prepared statement with an ascii value stream
1998      * 
1999      * @see PreparedStatement#setAsciiStream(int, InputStream)
2000      * @since 5.1.1
2001      * @param nIndex
2002      *            the index
2003      * @param stream
2004      *            the stream
2005      */
2006     public void setAsciiStream( int nIndex, InputStream stream )
2007     {
2008         try
2009         {
2010             _statement.setAsciiStream( nIndex, stream );
2011         }
2012         catch( SQLException e )
2013         {
2014             free( );
2015             throw new AppException( getErrorMessage( e ), e );
2016         }
2017     }
2018 
2019     /**
2020      * Fills the prepared statement with an ascii value stream
2021      * 
2022      * @see PreparedStatement#setAsciiStream(int, InputStream, int)
2023      * @since 5.1.1
2024      * @param nIndex
2025      *            the index
2026      * @param stream
2027      *            the stream
2028      * @param nLength
2029      *            the number of bytes to read
2030      */
2031     public void setAsciiStream( int nIndex, InputStream stream, int nLength )
2032     {
2033         try
2034         {
2035             _statement.setAsciiStream( nIndex, stream, nLength );
2036         }
2037         catch( SQLException e )
2038         {
2039             free( );
2040             throw new AppException( getErrorMessage( e ), e );
2041         }
2042     }
2043 
2044     /**
2045      * Fills the prepared statement with an ascii value stream
2046      * 
2047      * @see PreparedStatement#setAsciiStream(int, InputStream, long)
2048      * @since 5.1.1
2049      * @param nIndex
2050      *            the index
2051      * @param stream
2052      *            the stream
2053      * @param lLength
2054      *            the number of bytes to read
2055      */
2056     public void setAsciiStream( int nIndex, InputStream stream, long lLength )
2057     {
2058         try
2059         {
2060             _statement.setAsciiStream( nIndex, stream, lLength );
2061         }
2062         catch( SQLException e )
2063         {
2064             free( );
2065             throw new AppException( getErrorMessage( e ), e );
2066         }
2067     }
2068 
2069     /**
2070      * Get an ascii value stream
2071      * 
2072      * @see ResultSet#getAsciiStream(int)
2073      * @since 5.1.1
2074      * @param nIndex
2075      *            the index
2076      * @return the ascii stream
2077      */
2078     public InputStream getAsciiString( int nIndex )
2079     {
2080         try
2081         {
2082             return _resultSet.getAsciiStream( nIndex );
2083         }
2084         catch( SQLException e )
2085         {
2086             free( );
2087             throw new AppException( getErrorMessage( e ), e );
2088         }
2089     }
2090 
2091     /**
2092      * Get an ascii value stream
2093      * 
2094      * @see ResultSet#getAsciiStream(String)
2095      * @since 5.1.1
2096      * @param strColumnName
2097      *            the column name
2098      * @return the ascii stream
2099      */
2100     public InputStream getAsciiString( String strColumnName )
2101     {
2102         try
2103         {
2104             return _resultSet.getAsciiStream( strColumnName );
2105         }
2106         catch( SQLException e )
2107         {
2108             free( );
2109             throw new AppException( getErrorMessage( e ), e );
2110         }
2111     }
2112 
2113     /**
2114      * Fills the prepared Statement with a BigDecimal value
2115      * 
2116      * @see PreparedStatement#setBigDecimal(int, BigDecimal)
2117      * @since 5.1.1
2118      * @param nIndex
2119      *            the index
2120      * @param value
2121      *            the value
2122      */
2123     public void setBigDecimal( int nIndex, BigDecimal value )
2124     {
2125         try
2126         {
2127             _statement.setBigDecimal( nIndex, value );
2128             logParameter( nIndex, value );
2129         }
2130         catch( SQLException e )
2131         {
2132             free( );
2133             throw new AppException( getErrorMessage( e ), e );
2134         }
2135     }
2136 
2137     /**
2138      * Get a BigDecimal value
2139      * 
2140      * @see ResultSet#getBigDecimal(int)
2141      * @since 5.1.1
2142      * @param nIndex
2143      *            the index
2144      * @return the value
2145      */
2146     public BigDecimal getBigDecimal( int nIndex )
2147     {
2148         try
2149         {
2150             return _resultSet.getBigDecimal( nIndex );
2151         }
2152         catch( SQLException e )
2153         {
2154             free( );
2155             throw new AppException( getErrorMessage( e ), e );
2156         }
2157     }
2158 
2159     /**
2160      * Get a BigDecimal value
2161      * 
2162      * @see ResultSet#getBigDecimal(String)
2163      * @since 5.1.1
2164      * @param strColumnName
2165      *            the column name
2166      * @return the value
2167      */
2168     public BigDecimal getBigDecimal( String strColumnName )
2169     {
2170         try
2171         {
2172             return _resultSet.getBigDecimal( strColumnName );
2173         }
2174         catch( SQLException e )
2175         {
2176             free( );
2177             throw new AppException( getErrorMessage( e ), e );
2178         }
2179     }
2180 
2181     /**
2182      * Fills the prepared statement with a character stream
2183      *
2184      * @see PreparedStatement#setCharacterStream(int, Reader)
2185      * @since 5.1.1
2186      * @param nIndex
2187      *            the index
2188      * @param stream
2189      *            the stream
2190      */
2191     public void setCharacterStream( int nIndex, Reader stream )
2192     {
2193         try
2194         {
2195             _statement.setCharacterStream( nIndex, stream );
2196         }
2197         catch( SQLException e )
2198         {
2199             free( );
2200             throw new AppException( getErrorMessage( e ), e );
2201         }
2202     }
2203 
2204     /**
2205      * Fills the prepared statement with a character stream
2206      *
2207      * @see PreparedStatement#setCharacterStream(int, Reader, int)
2208      * @since 5.1.1
2209      * @param nIndex
2210      *            the index
2211      * @param stream
2212      *            the stream
2213      * @param nLength
2214      *            the number of bytes to read
2215      */
2216     public void setCharacterStream( int nIndex, Reader stream, int nLength )
2217     {
2218         try
2219         {
2220             _statement.setCharacterStream( nIndex, stream, nLength );
2221         }
2222         catch( SQLException e )
2223         {
2224             free( );
2225             throw new AppException( getErrorMessage( e ), e );
2226         }
2227     }
2228 
2229     /**
2230      * Fills the prepared statement with a character stream
2231      *
2232      * @see PreparedStatement#setCharacterStream(int, Reader, long)
2233      * @since 5.1.1
2234      * @param nIndex
2235      *            the index
2236      * @param stream
2237      *            the stream
2238      * @param nLength
2239      *            the number of bytes to read
2240      */
2241     public void setCharacterStream( int nIndex, Reader stream, long nLength )
2242     {
2243         try
2244         {
2245             _statement.setCharacterStream( nIndex, stream, nLength );
2246         }
2247         catch( SQLException e )
2248         {
2249             free( );
2250             throw new AppException( getErrorMessage( e ), e );
2251         }
2252     }
2253 
2254     /**
2255      * Get a character stream value
2256      *
2257      * @see ResultSet#getCharacterStream(int)
2258      * @since 5.1.1
2259      * @param nIndex
2260      *            the column index
2261      * @return the stream value
2262      */
2263     public Reader getCharacterStream( int nIndex )
2264     {
2265         try
2266         {
2267             return _resultSet.getCharacterStream( nIndex );
2268         }
2269         catch( SQLException e )
2270         {
2271             free( );
2272             throw new AppException( getErrorMessage( e ), e );
2273         }
2274     }
2275 
2276     /**
2277      * Get a character stream value
2278      *
2279      * @see ResultSet#getCharacterStream(String)
2280      * @since 5.1.1
2281      * @param strColumnName
2282      *            the column index
2283      * @return the stream value
2284      */
2285     public Reader getCharacterStream( String strColumnName )
2286     {
2287         try
2288         {
2289             return _resultSet.getCharacterStream( strColumnName );
2290         }
2291         catch( SQLException e )
2292         {
2293             free( );
2294             throw new AppException( getErrorMessage( e ), e );
2295         }
2296     }
2297 
2298     /**
2299      * Fills the prepared statement with a Clob stream
2300      *
2301      * @see PreparedStatement#setClob(int, Reader)
2302      * @since 5.1.1
2303      * @param nIndex
2304      *            the index
2305      * @param stream
2306      *            the value
2307      */
2308     public void setClob( int nIndex, Reader stream )
2309     {
2310         try
2311         {
2312             _statement.setClob( nIndex, stream );
2313         }
2314         catch( SQLException e )
2315         {
2316             free( );
2317             throw new AppException( getErrorMessage( e ), e );
2318         }
2319     }
2320 
2321     /**
2322      * Fills the prepared statement with a Clob stream
2323      *
2324      * @see PreparedStatement#setClob(int, Reader, long)
2325      * @since 5.1.1
2326      * @param nIndex
2327      *            the index
2328      * @param stream
2329      *            the value
2330      * @param nLength
2331      *            the number of bytes to read
2332      */
2333     public void setClob( int nIndex, Reader stream, long nLength )
2334     {
2335         try
2336         {
2337             _statement.setClob( nIndex, stream, nLength );
2338         }
2339         catch( SQLException e )
2340         {
2341             free( );
2342             throw new AppException( getErrorMessage( e ), e );
2343         }
2344     }
2345 
2346     /**
2347      * Fills the prepared statement with a Clob
2348      *
2349      * @see PreparedStatement#setClob(int, Clob)
2350      * @since 5.1.1
2351      * @param nIndex
2352      *            the index
2353      * @param clob
2354      *            the value
2355      */
2356     public void setClob( int nIndex, Clob clob )
2357     {
2358         try
2359         {
2360             _statement.setClob( nIndex, clob );
2361         }
2362         catch( SQLException e )
2363         {
2364             free( );
2365             throw new AppException( getErrorMessage( e ), e );
2366         }
2367     }
2368 
2369     /**
2370      * Get a Clob value
2371      *
2372      * @see ResultSet#getClob(int)
2373      * @since 5.1.1
2374      * @param nIndex
2375      *            the column index
2376      * @return the value
2377      */
2378     public Clob getClob( int nIndex )
2379     {
2380         try
2381         {
2382             return _resultSet.getClob( nIndex );
2383         }
2384         catch( SQLException e )
2385         {
2386             free( );
2387             throw new AppException( getErrorMessage( e ), e );
2388         }
2389     }
2390 
2391     /**
2392      * Get a Clob value
2393      *
2394      * @see ResultSet#getClob(String)
2395      * @since 5.1.1
2396      * @param strColumnName
2397      *            the column index
2398      * @return the value
2399      */
2400     public Clob getClob( String strColumnName )
2401     {
2402         try
2403         {
2404             return _resultSet.getClob( strColumnName );
2405         }
2406         catch( SQLException e )
2407         {
2408             free( );
2409             throw new AppException( getErrorMessage( e ), e );
2410         }
2411     }
2412 
2413     /**
2414      * Fills the prepared statement with a NClob stream
2415      *
2416      * @see PreparedStatement#setNClob(int, Reader)
2417      * @since 5.1.1
2418      * @param nIndex
2419      *            the index
2420      * @param stream
2421      *            the value
2422      */
2423     public void setNClob( int nIndex, Reader stream )
2424     {
2425         try
2426         {
2427             _statement.setNClob( nIndex, stream );
2428         }
2429         catch( SQLException e )
2430         {
2431             free( );
2432             throw new AppException( getErrorMessage( e ), e );
2433         }
2434     }
2435 
2436     /**
2437      * Fills the prepared statement with a NClob stream
2438      *
2439      * @see PreparedStatement#setNClob(int, Reader, long)
2440      * @since 5.1.1
2441      * @param nIndex
2442      *            the index
2443      * @param stream
2444      *            the value
2445      * @param nLength
2446      *            the number of bytes to read
2447      */
2448     public void setNClob( int nIndex, Reader stream, long nLength )
2449     {
2450         try
2451         {
2452             _statement.setNClob( nIndex, stream, nLength );
2453         }
2454         catch( SQLException e )
2455         {
2456             free( );
2457             throw new AppException( getErrorMessage( e ), e );
2458         }
2459     }
2460 
2461     /**
2462      * Fills the prepared statement with a NClob
2463      *
2464      * @see PreparedStatement#setNClob(int, NClob)
2465      * @since 5.1.1
2466      * @param nIndex
2467      *            the index
2468      * @param clob
2469      *            the value
2470      */
2471     public void setClob( int nIndex, NClob clob )
2472     {
2473         try
2474         {
2475             _statement.setNClob( nIndex, clob );
2476         }
2477         catch( SQLException e )
2478         {
2479             free( );
2480             throw new AppException( getErrorMessage( e ), e );
2481         }
2482     }
2483 
2484     /**
2485      * Get a NClob value
2486      *
2487      * @see ResultSet#getNClob(int)
2488      * @since 5.1.1
2489      * @param nIndex
2490      *            the column index
2491      * @return the value
2492      */
2493     public NClob getNClob( int nIndex )
2494     {
2495         try
2496         {
2497             return _resultSet.getNClob( nIndex );
2498         }
2499         catch( SQLException e )
2500         {
2501             free( );
2502             throw new AppException( getErrorMessage( e ), e );
2503         }
2504     }
2505 
2506     /**
2507      * Get a Clob value
2508      *
2509      * @see ResultSet#getClob(String)
2510      * @since 5.1.1
2511      * @param strColumnName
2512      *            the column index
2513      * @return the value
2514      */
2515     public NClob getNClob( String strColumnName )
2516     {
2517         try
2518         {
2519             return _resultSet.getNClob( strColumnName );
2520         }
2521         catch( SQLException e )
2522         {
2523             free( );
2524             throw new AppException( getErrorMessage( e ), e );
2525         }
2526     }
2527 
2528     /**
2529      * Fills the prepared statement with a float value
2530      *
2531      * @see PreparedStatement#setFloat(int, float)
2532      * @since 5.1.1
2533      * @param nIndex
2534      *            the index
2535      * @param fValue
2536      *            the value
2537      */
2538     public void setFloat( int nIndex, float fValue )
2539     {
2540         try
2541         {
2542             _statement.setFloat( nIndex, fValue );
2543             logParameter( nIndex, fValue );
2544         }
2545         catch( SQLException e )
2546         {
2547             free( );
2548             throw new AppException( getErrorMessage( e ), e );
2549         }
2550     }
2551 
2552     /**
2553      * Get a float value
2554      *
2555      * @see ResultSet#getFloat(String)
2556      * @since 5.1.1
2557      * @param strColumnName
2558      *            the column name
2559      * @return the value
2560      */
2561     public float getFloat( String strColumnName )
2562     {
2563         try
2564         {
2565             return _resultSet.getFloat( strColumnName );
2566         }
2567         catch( SQLException e )
2568         {
2569             free( );
2570             throw new AppException( getErrorMessage( e ), e );
2571         }
2572     }
2573 
2574     /**
2575      * Get a float value
2576      *
2577      * @see ResultSet#getFloat(int)
2578      * @since 5.1.1
2579      * @param nIndex
2580      *            the column index
2581      * @return the value
2582      */
2583     public float getFloat( int nIndex )
2584     {
2585         try
2586         {
2587             return _resultSet.getFloat( nIndex );
2588         }
2589         catch( SQLException e )
2590         {
2591             free( );
2592             throw new AppException( getErrorMessage( e ), e );
2593         }
2594     }
2595 
2596     /**
2597      * Fills the prepared statement with a character stream value
2598      *
2599      * @see PreparedStatement#setNCharacterStream(int, Reader)
2600      * @since 5.1.1
2601      * @param nIndex
2602      *            the index
2603      * @param stream
2604      *            the stream
2605      */
2606     public void setNCharacterStream( int nIndex, Reader stream )
2607     {
2608         try
2609         {
2610             _statement.setNCharacterStream( nIndex, stream );
2611         }
2612         catch( SQLException e )
2613         {
2614             free( );
2615             throw new AppException( getErrorMessage( e ), e );
2616         }
2617     }
2618 
2619     /**
2620      * Fills the prepared statement with a character stream value
2621      *
2622      * @see PreparedStatement#setNCharacterStream(int, Reader, long)
2623      * @since 5.1.1
2624      * @param nIndex
2625      *            the index
2626      * @param stream
2627      *            the stream
2628      * @param nLength
2629      *            the number of characters to read
2630      */
2631     public void setNCharacterStream( int nIndex, Reader stream, long nLength )
2632     {
2633         try
2634         {
2635             _statement.setNCharacterStream( nIndex, stream, nLength );
2636         }
2637         catch( SQLException e )
2638         {
2639             free( );
2640             throw new AppException( getErrorMessage( e ), e );
2641         }
2642     }
2643 
2644     /**
2645      * Get a character stream value
2646      *
2647      * @see ResultSet#getNCharacterStream(int)
2648      * @since 5.1.1
2649      * @param nIndex
2650      *            the index
2651      * @return the stream
2652      */
2653     public Reader getNCharacterStream( int nIndex )
2654     {
2655         try
2656         {
2657             return _resultSet.getNCharacterStream( nIndex );
2658         }
2659         catch( SQLException e )
2660         {
2661             free( );
2662             throw new AppException( getErrorMessage( e ), e );
2663         }
2664     }
2665 
2666     /**
2667      * Get a character stream value
2668      *
2669      * @see ResultSet#getNCharacterStream(String)
2670      * @since 5.1.1
2671      * @param strColumnName
2672      *            the column name
2673      * @return the stream
2674      */
2675     public Reader getNCharacterStream( String strColumnName )
2676     {
2677         try
2678         {
2679             return _resultSet.getNCharacterStream( strColumnName );
2680         }
2681         catch( SQLException e )
2682         {
2683             free( );
2684             throw new AppException( getErrorMessage( e ), e );
2685         }
2686     }
2687 
2688     /**
2689      * Fills the prepared statement with a String value
2690      *
2691      * @see PreparedStatement#setNString(int, String)
2692      * @since 5.1.1
2693      * @param nIndex
2694      *            the index
2695      * @param strValue
2696      *            the value
2697      */
2698     public void setNString( int nIndex, String strValue )
2699     {
2700         try
2701         {
2702             _statement.setNString( nIndex, strValue );
2703         }
2704         catch( SQLException e )
2705         {
2706             free( );
2707             throw new AppException( getErrorMessage( e ), e );
2708         }
2709     }
2710 
2711     /**
2712      * Get a String value
2713      *
2714      * @see ResultSet#getNString(int)
2715      * @since 5.1.1
2716      * @param nIndex
2717      *            the index
2718      * @return the String
2719      */
2720     public String getNString( int nIndex )
2721     {
2722         try
2723         {
2724             return _resultSet.getNString( nIndex );
2725         }
2726         catch( SQLException e )
2727         {
2728             free( );
2729             throw new AppException( getErrorMessage( e ), e );
2730         }
2731     }
2732 
2733     /**
2734      * Get a Stringvalue
2735      *
2736      * @see ResultSet#getNString(String)
2737      * @since 5.1.1
2738      * @param strColumnName
2739      *            the column name
2740      * @return the stream
2741      */
2742     public String getNString( String strColumnName )
2743     {
2744         try
2745         {
2746             return _resultSet.getNString( strColumnName );
2747         }
2748         catch( SQLException e )
2749         {
2750             free( );
2751             throw new AppException( getErrorMessage( e ), e );
2752         }
2753     }
2754 
2755     /**
2756      * Fills the prepared statement with a null value
2757      *
2758      * @see PreparedStatement#setNull(int, int)
2759      * @since 5.1.1
2760      * @param nIndex
2761      *            the index
2762      * @param nType
2763      *            the SQL type code defined in java.sql.Types
2764      */
2765     public void setNull( int nIndex, int nType )
2766     {
2767         try
2768         {
2769             _statement.setNull( nIndex, nType );
2770             logParameter( nIndex, "null" );
2771         }
2772         catch( SQLException e )
2773         {
2774             free( );
2775             throw new AppException( getErrorMessage( e ), e );
2776         }
2777     }
2778 
2779     /**
2780      * Fills the prepared statement with a null value
2781      *
2782      * @see PreparedStatement#setNull(int, int, String)
2783      * @since 5.1.1
2784      * @param nIndex
2785      *            the index
2786      * @param nType
2787      *            the SQL type code defined in java.sql.Types
2788      * @param strTypeName
2789      *            the type name
2790      */
2791     public void setNull( int nIndex, int nType, String strTypeName )
2792     {
2793         try
2794         {
2795             _statement.setNull( nIndex, nType, strTypeName );
2796             logParameter( nIndex, "null" );
2797         }
2798         catch( SQLException e )
2799         {
2800             free( );
2801             throw new AppException( getErrorMessage( e ), e );
2802         }
2803     }
2804 
2805     /**
2806      * Fills the prepared statement with an object value
2807      *
2808      * @see PreparedStatement#setObject(int, Object)
2809      * @since 5.1.1
2810      * @param nIndex
2811      *            the index
2812      * @param value
2813      *            the value
2814      */
2815     public void setObject( int nIndex, Object value )
2816     {
2817         try
2818         {
2819             _statement.setObject( nIndex, value );
2820             logParameter( nIndex, value );
2821         }
2822         catch( SQLException e )
2823         {
2824             free( );
2825             throw new AppException( getErrorMessage( e ), e );
2826         }
2827     }
2828 
2829     /**
2830      * Fills the prepared statement with an object value
2831      *
2832      * @see PreparedStatement#setObject(int, Object, int)
2833      * @since 5.1.1
2834      * @param nIndex
2835      *            the index
2836      * @param value
2837      *            the value
2838      * @param nType
2839      *            the target SQL type (as defined in java.sql.Types)
2840      */
2841     public void setObject( int nIndex, Object value, int nType )
2842     {
2843         try
2844         {
2845             _statement.setObject( nIndex, value, nType );
2846             logParameter( nIndex, value );
2847         }
2848         catch( SQLException e )
2849         {
2850             free( );
2851             throw new AppException( getErrorMessage( e ), e );
2852         }
2853     }
2854 
2855     /**
2856      * Fills the prepared statement with an object value
2857      *
2858      * @see PreparedStatement#setObject(int, Object, int, int)
2859      * @since 5.1.1
2860      * @param nIndex
2861      *            the index
2862      * @param value
2863      *            the value
2864      * @param nType
2865      *            the target SQL type (as defined in java.sql.Types)
2866      * @param nScaleOrLength
2867      *            the scale or length
2868      */
2869     public void setObject( int nIndex, Object value, int nType, int nScaleOrLength )
2870     {
2871         try
2872         {
2873             _statement.setObject( nIndex, value, nType, nScaleOrLength );
2874             logParameter( nIndex, value );
2875         }
2876         catch( SQLException e )
2877         {
2878             free( );
2879             throw new AppException( getErrorMessage( e ), e );
2880         }
2881     }
2882 
2883     /**
2884      * Get a Ref value
2885      *
2886      * @see ResultSet#getRef(int)
2887      * @since 5.1.1
2888      * @param nIndex
2889      *            the index
2890      * @return the ref
2891      */
2892     public Ref getRef( int nIndex )
2893     {
2894         try
2895         {
2896             return _resultSet.getRef( nIndex );
2897         }
2898         catch( SQLException e )
2899         {
2900             free( );
2901             throw new AppException( getErrorMessage( e ), e );
2902         }
2903     }
2904 
2905     /**
2906      * Get a Ref value
2907      *
2908      * @see ResultSet#getRef(String)
2909      * @since 5.1.1
2910      * @param strColumnName
2911      *            the column name
2912      * @return the ref
2913      */
2914     public Ref getRef( String strColumnName )
2915     {
2916         try
2917         {
2918             return _resultSet.getRef( strColumnName );
2919         }
2920         catch( SQLException e )
2921         {
2922             free( );
2923             throw new AppException( getErrorMessage( e ), e );
2924         }
2925     }
2926 
2927     /**
2928      * Fills the prepared statement with an Ref value
2929      *
2930      * @see PreparedStatement#setRef(int, Ref)
2931      * @since 5.1.1
2932      * @param nIndex
2933      *            the index
2934      * @param ref
2935      *            the Ref
2936      */
2937     public void setRef( int nIndex, Ref ref )
2938     {
2939         try
2940         {
2941             _statement.setRef( nIndex, ref );
2942             logParameter( nIndex, ref );
2943         }
2944         catch( SQLException e )
2945         {
2946             free( );
2947             throw new AppException( getErrorMessage( e ), e );
2948         }
2949     }
2950 
2951     /**
2952      * Fills the prepared statement with a RowId value
2953      *
2954      * @see PreparedStatement#setRowId(int, RowId)
2955      * @since 5.1.1
2956      * @param nIndex
2957      *            the index
2958      * @param rowId
2959      *            the value
2960      */
2961     public void setRowId( int nIndex, RowId rowId )
2962     {
2963         try
2964         {
2965             _statement.setRowId( nIndex, rowId );
2966             logParameter( nIndex, rowId );
2967         }
2968         catch( SQLException e )
2969         {
2970             free( );
2971             throw new AppException( getErrorMessage( e ), e );
2972         }
2973     }
2974 
2975     /**
2976      * Get a RowId value
2977      *
2978      * @see ResultSet#getRowId(int)
2979      * @since 5.1.1
2980      * @param nIndex
2981      *            the index
2982      * @return the rowId
2983      */
2984     public RowId getRowId( int nIndex )
2985     {
2986         try
2987         {
2988             return _resultSet.getRowId( nIndex );
2989         }
2990         catch( SQLException e )
2991         {
2992             free( );
2993             throw new AppException( getErrorMessage( e ), e );
2994         }
2995     }
2996 
2997     /**
2998      * Get a RowId value
2999      *
3000      * @see ResultSet#getRowId(String)
3001      * @since 5.1.1
3002      * @param strColumnName
3003      *            the column name
3004      * @return the rowId
3005      */
3006     public RowId getRowId( String strColumnName )
3007     {
3008         try
3009         {
3010             return _resultSet.getRowId( strColumnName );
3011         }
3012         catch( SQLException e )
3013         {
3014             free( );
3015             throw new AppException( getErrorMessage( e ), e );
3016         }
3017     }
3018 
3019     /**
3020      * Fills the prepared statement with a short value
3021      *
3022      * @see PreparedStatement#setShort(int, short)
3023      * @since 5.1.1
3024      * @param nIndex
3025      *            the index
3026      * @param shortValue
3027      *            the value
3028      */
3029     public void setShort( int nIndex, short shortValue )
3030     {
3031         try
3032         {
3033             _statement.setShort( nIndex, shortValue );
3034             logParameter( nIndex, shortValue );
3035         }
3036         catch( SQLException e )
3037         {
3038             free( );
3039             throw new AppException( getErrorMessage( e ), e );
3040         }
3041     }
3042 
3043     /**
3044      * Get a short value
3045      *
3046      * @see ResultSet#getShort(String)
3047      * @since 5.1.1
3048      * @param strColumnName
3049      *            the column name
3050      * @return the value
3051      */
3052     public short getShort( String strColumnName )
3053     {
3054         try
3055         {
3056             return _resultSet.getShort( strColumnName );
3057         }
3058         catch( SQLException e )
3059         {
3060             free( );
3061             throw new AppException( getErrorMessage( e ), e );
3062         }
3063     }
3064 
3065     /**
3066      * Get a short value
3067      *
3068      * @see ResultSet#getShort(int)
3069      * @since 5.1.1
3070      * @param nIndex
3071      *            the column index
3072      * @return the value
3073      */
3074     public short getShort( int nIndex )
3075     {
3076         try
3077         {
3078             return _resultSet.getShort( nIndex );
3079         }
3080         catch( SQLException e )
3081         {
3082             free( );
3083             throw new AppException( getErrorMessage( e ), e );
3084         }
3085     }
3086 
3087     /**
3088      * Fills the prepared statement with a SQLXML value
3089      *
3090      * @see PreparedStatement#setSQLXML(int, SQLXML)
3091      * @since 5.1.1
3092      * @param nIndex
3093      *            the index
3094      * @param value
3095      *            the value
3096      */
3097     public void setSQLXML( int nIndex, SQLXML value )
3098     {
3099         try
3100         {
3101             _statement.setSQLXML( nIndex, value );
3102             logParameter( nIndex, value );
3103         }
3104         catch( SQLException e )
3105         {
3106             free( );
3107             throw new AppException( getErrorMessage( e ), e );
3108         }
3109     }
3110 
3111     /**
3112      * Get a SQLXML value
3113      *
3114      * @see ResultSet#getSQLXML(String)
3115      * @since 5.1.1
3116      * @param strColumnName
3117      *            the column name
3118      * @return the value
3119      */
3120     public SQLXML getSQLXML( String strColumnName )
3121     {
3122         try
3123         {
3124             return _resultSet.getSQLXML( strColumnName );
3125         }
3126         catch( SQLException e )
3127         {
3128             free( );
3129             throw new AppException( getErrorMessage( e ), e );
3130         }
3131     }
3132 
3133     /**
3134      * Get a SQLXML value
3135      *
3136      * @see ResultSet#getSQLXML(int)
3137      * @since 5.1.1
3138      * @param nIndex
3139      *            the column index
3140      * @return the value
3141      */
3142     public SQLXML getSQLXML( int nIndex )
3143     {
3144         try
3145         {
3146             return _resultSet.getSQLXML( nIndex );
3147         }
3148         catch( SQLException e )
3149         {
3150             free( );
3151             throw new AppException( getErrorMessage( e ), e );
3152         }
3153     }
3154 
3155     /**
3156      * Fills the prepared statement with a URL value
3157      *
3158      * @see PreparedStatement#setURL(int, URL)
3159      * @since 5.1.1
3160      * @param nIndex
3161      *            the index
3162      * @param url
3163      *            the URL
3164      */
3165     public void setURL( int nIndex, URL url )
3166     {
3167         try
3168         {
3169             _statement.setURL( nIndex, url );
3170             logParameter( nIndex, url );
3171         }
3172         catch( SQLException e )
3173         {
3174             free( );
3175             throw new AppException( getErrorMessage( e ), e );
3176         }
3177     }
3178 
3179     /**
3180      * Get a URL value
3181      *
3182      * @see ResultSet#getURL(String)
3183      * @since 5.1.1
3184      * @param strColumnName
3185      *            the column name
3186      * @return the value
3187      */
3188     public URL getURL( String strColumnName )
3189     {
3190         try
3191         {
3192             return _resultSet.getURL( strColumnName );
3193         }
3194         catch( SQLException e )
3195         {
3196             free( );
3197             throw new AppException( getErrorMessage( e ), e );
3198         }
3199     }
3200 
3201     /**
3202      * Get a URL value
3203      *
3204      * @see ResultSet#getURL(int)
3205      * @since 5.1.1
3206      * @param nIndex
3207      *            the column index
3208      * @return the value
3209      */
3210     public URL getURL( int nIndex )
3211     {
3212         try
3213         {
3214             return _resultSet.getURL( nIndex );
3215         }
3216         catch( SQLException e )
3217         {
3218             free( );
3219             throw new AppException( getErrorMessage( e ), e );
3220         }
3221     }
3222 
3223     /**
3224      * Adds a set of parameters to this <code>PreparedStatement</code> object's batch of commands.
3225      * 
3226      * @since 7.0.0
3227      */
3228     public void addBatch( )
3229     {
3230         try
3231         {
3232             _statement.addBatch( );
3233         }
3234         catch( SQLException e )
3235         {
3236             free( );
3237             throw new AppException( getErrorMessage( e ), e );
3238         }
3239     }
3240 
3241     /**
3242      * Adds the given SQL command to the current list of commands for this <code>Statement</code> object. The commands in this list can be executed as a batch
3243      * by calling the method <code>executeBatch</code>.
3244      * <P>
3245      * <strong>Note:</strong>This method cannot be called on a <code>PreparedStatement</code> or <code>CallableStatement</code>.
3246      * 
3247      * @since 7.0.0
3248      * @param sql
3249      *            typically this is a SQL <code>INSERT</code> or <code>UPDATE</code> statement this method is called on a closed <code>Statement</code>, the
3250      *            driver does not support batch updates, the method is called on a <code>PreparedStatement</code> or <code>CallableStatement</code>
3251      * @see #executeBatch
3252      * @see DatabaseMetaData#supportsBatchUpdates
3253      */
3254     public void addBatch( String sql )
3255     {
3256         try
3257         {
3258             _statement.addBatch( sql );
3259         }
3260         catch( SQLException e )
3261         {
3262             free( );
3263             throw new AppException( getErrorMessage( e ), e );
3264         }
3265     }
3266 
3267     /**
3268      * Empties this <code>Statement</code> object's current list of SQL commands.
3269      * 
3270      * @since 7.0.0
3271      * @see #addBatch
3272      * @see DatabaseMetaData#supportsBatchUpdates
3273      */
3274     void clearBatch( )
3275     {
3276 
3277         try
3278         {
3279             _statement.clearBatch( );
3280         }
3281         catch( SQLException e )
3282         {
3283             free( );
3284             throw new AppException( getErrorMessage( e ), e );
3285         }
3286     }
3287 
3288     /**
3289      * Clears the current parameter values immediately.
3290      * <P>
3291      * In general, parameter values remain in force for repeated use of a statement. Setting a parameter value automatically clears its previous value. However,
3292      * in some cases it is useful to immediately release the resources used by the current parameter values; this can be done by calling the method
3293      * <code>clearParameters</code>.
3294      * 
3295      * @since 7.0.0
3296      */
3297     public void clearParameters( )
3298     {
3299         try
3300         {
3301             _statement.clearParameters( );
3302         }
3303         catch( SQLException e )
3304         {
3305             free( );
3306             throw new AppException( getErrorMessage( e ), e );
3307         }
3308     }
3309 
3310     /**
3311      * Submits a batch of commands to the database for execution and if all commands execute successfully, returns an array of update counts.
3312      * 
3313      * @since 7.0.0
3314      * @return The elements of the array that is returned are ordered to correspond to the commands in the batch, which are ordered according to the order in
3315      *         which they were added to the batch.
3316      */
3317     public int [ ] executeBatch( )
3318     {
3319         try
3320         {
3321             return _statement.executeBatch( );
3322         }
3323         catch( SQLException e )
3324         {
3325             free( );
3326             throw new AppException( getErrorMessage( e ), e );
3327         }
3328     }
3329 
3330     /**
3331      * {@inheritDoc}
3332      */
3333     @Override
3334     protected void finalize( ) throws Throwable
3335     {
3336         if ( !_bReleased )
3337         {
3338             free( );
3339             AppLogService.error(
3340                     "A call to DAOUtil.free() seems to be missing or an unexpected exception has occured during the use of a DAOUtil object - plugin : {} - SQL statement : {}",
3341                     _strPluginName, _strSQL );
3342         }
3343 
3344         super.finalize( );
3345     }
3346 
3347     /**
3348      * {@inheritDoc}
3349      */
3350     @Override
3351     public void close( )
3352     {
3353         free( );
3354     }
3355 }