Example #1
0
	private IngresConnection _connection; // = null;

	/*
	 * The constructors are marked as internal because an application
	 * can't create an IngresDataReader directly.  It is created only
	 * by executing one of the reader methods in the IngresCommand.
	 */

	internal IngresDataReader(
		AdvanRslt    resultset,
		IngresConnection connection,
		CommandBehavior  commandBehavior,
		int              recordsAffected,
		MetaData         keyInfoMetaData)
	{
		if (resultset == null)  // if no result set, build an empty one
		{
			resultset = connection.advanConnect.CreateEmptyResultSet();
		}
		_resultset   = resultset;
		_fieldCount  = resultset.rsmd.getColumnCount();
		_connection  = connection;
		_valueList   = new Object[_fieldCount];
		_isOpen      = true;
		_commandBehavior = commandBehavior;
		_recordsAffected = recordsAffected;
		_keyInfoMetaData = keyInfoMetaData;
		if (connection != null)
			connection.ActiveDataReader = this;
			// only one active DataReader allowed at a time
		FireInfoMessageEvent();  // call the delegates with any warning messages
	}
Example #2
0
	public           void Close()
#endif
	{
		_isOpen = false;
		if (_resultset != null  && _fieldCount > 0)  // if result present, close it
		{
			try
			{
				_resultset.close();
			}
			catch( SqlEx ex )  { throw ex.createProviderException(); }
			FireInfoMessageEvent();  // call the delegates with any messages
			_resultset = null;
		}
		if (_connection != null)
		{
			_connection.ActiveDataReader = null;
			// If ExecuteReader(CommandBehavior.CloseConnection) was
			// specified then the associated Connection object is closed
			// when the DataReader object is closed.
			if ((_commandBehavior & CommandBehavior.CloseConnection) != 0)
				_connection.Close();
		}

	}
Example #3
0
        /*
        ** Name: exec
        **
        ** Description:
        **	Send SQL statement to server and process results.
        **	A cursor is opened when executing a SELECT and a
        **	result-set is generated.  Non-SELECT statements
        **	are simply executed and the row count is updated.
        **
        ** Input:
        **	text	    Statement text.
        **	mode	    Execute mode: QUERY, UPDATE, UNKNOWN.
        **
        ** Output:
        **	None.
        **
        ** Returns:
        **	void.
        **
        ** History:
        **	26-Oct-99 (gordy)
        **	    Extracted from interface methods.
        **	15-Nov-99 (gordy)
        **	    Pass max row count and column length to result set.
        **	16-Nov-99 (gordy)
        **	    Added query timeouts.
        **	13-Dec-99 (gordy)
        **	    Added fetch limit.
        **	16-May-00 (gordy)
        **	    Move SQL parsing back into individual query processing
        **	    sections so that it occurs after parser.getCursonName().
        **	19-May-00 (gordy)
        **	    If select loops have been enabled, and a cursor name has
        **	    not been assigned, execute queries directly rather than
        **	    opening a cursor.  Locking had to be reorganized since
        **	    select loops are not unlocked until the result set is
        **	    closed.  Also needed additional handling when executing
        **	    (supposedly) non-queries and get a result set by mistake.
        **	28-Mar-01 (gordy)
        **	    Call result-set shut() to avoid top-level tracing.
        **	20-Jun-01 (gordy)
        **	    Pass cursor name to result-set according to spec:
        **	    NULL if READONLY and not provided by application.
        **	21-Jun-01 (gordy)
        **	    Re-worked parsing to eliminate redundant code.  Parser
        **	    parameter replaced with simple query text string.  Query
        **	    parameter replaced with mode to convey caller intent.
        **	20-Aug-01 (gordy)
        **	    Use cursor type constants.  Send READONLY flag to server.
        **	    Warn if cursor mode changed to READONLY.
        **	25-Oct-01 (gordy)
        **	    Select loops are only supported at PROTO_2 and above.
        **	31-Oct-01 (gordy)
        **	    Timezone now passed to AdvanSQL.
        **	31-Oct-02 (gordy)
        **	    Adapted for generic GCF driver.
        **	19-Feb-03 (gordy)
        **	    Added method to calculate fetch size.
        **	15-Apr-03 (gordy)
        **	    Added connection timezones separate from date formatters.
        **	 7-Jul-03 (gordy)
        **	    Added Ingres timezone config which affects date/time literals.
        **	 4-Aug-03 (gordy)
        **	    Created neew result-set class for updatable cursors.
        **	20-Aug-03 (gordy)
        **	    Send AUTO_CLOSE flag for query statements.
        **	12-Sep-03 (gordy)
        **	    Timezone replaced by GMT indicator.
        **	 6-Oct-03 (gordy)
        **	    Fetch first block of rows for select-loops and read-only cursors.
        **	19-Jun-06 (gordy)
        **	    I give up... GMT indicator replaced with connection.
        */
        private void exec( String text, int mode )
        {
            SqlParse	parser = new SqlParse( text, conn );
            int		type = parser.getQueryType();
            AdvanRSMD	rsmd;
            String	cursor = null;

            clearResults();

            if ( mode == UNKNOWN )
                mode = (type == SqlParse.QT_SELECT) ? QUERY : UPDATE;

            if ( type == SqlParse.QT_DELETE  ||  type == SqlParse.QT_UPDATE )
                cursor = parser.getCursorName();

            msg.LockConnection();
            try
            {
                String	sql = parser.parseSQL( parse_escapes );

                if ( mode == QUERY )
                {
                    int	concurrency = getConcurrency( parser.getConcurrency() );

                    if (
                        conn.select_loops  &&  crsr_name == null  &&
                        concurrency != DrvConst.DRV_CRSR_UPDATE  &&
                        conn.msg_protocol_level >= MSG_PROTO_2
                        )
                    {
                        /*
                        ** Select statement using a select loop.
                        */
                        bool needEOG = true;
                        msg.begin( MSG_QUERY );
                        msg.write( MSG_QRY_EXQ );

                        if ( conn.msg_protocol_level >= MSG_PROTO_3 )
                        {
                            msg.write( MSG_QP_FLAGS );
                            msg.write( (short)4 );
                            msg.write( MSG_QF_FETCH_FIRST | MSG_QF_AUTO_CLOSE );
                            needEOG = false;
                        }

                        msg.write( MSG_QP_QTXT );
                        msg.write( sql );
                        msg.done( true );

                        if ( (rsmd = readResults( timeout, needEOG )) == null )
                            throw SqlEx.get( ERR_GC4017_NO_RESULT_SET );

                        resultSet = new RsltSlct( conn, this, rsmd, rslt_val_stmt,
                            getPreFetchSize(), msg.moreMessages());
                    }
                    else
                    {
                        /*
                        ** Select statement using a cursor.  Generate a
                        ** cursor ID if not provided by the application.
                        */
                        short	flags = 0;
                        bool	needEOG = true;
                        cursor = (crsr_name != null) ? crsr_name
                            : conn.getUniqueID( crsr_prefix );

                        /*
                        ** Parser removes FOR READONLY clause because it isn't
                        ** a part of Ingres SELECT syntax.  Tell server that
                        ** cursor should be READONLY (kludge older protocol
                        ** by restoring clause to query).
                        */
                        if ( concurrency == DrvConst.DRV_CRSR_READONLY )
                            if ( conn.msg_protocol_level < MSG_PROTO_2 )
                                sql += " for readonly";
                            else  if ( conn.msg_protocol_level < MSG_PROTO_3 )
                                flags |= MSG_QF_READONLY;
                            else
                            {
                                flags |= MSG_QF_READONLY | MSG_QF_FETCH_FIRST;
                                needEOG = false;
                            }

                        if ( conn.msg_protocol_level >= MSG_PROTO_3 )
                            flags |= MSG_QF_AUTO_CLOSE;

                        msg.begin( MSG_QUERY );
                        msg.write( MSG_QRY_OCQ );

                        if ( flags != 0 )
                        {
                            msg.write( MSG_QP_FLAGS );
                            msg.write( (short)2 );
                            msg.write( flags );
                        }

                        msg.write( MSG_QP_CRSR_NAME );
                        msg.write( cursor );
                        msg.write( MSG_QP_QTXT );
                        msg.write( sql );
                        msg.done( true );

                        if ( (rsmd = readResults( timeout, needEOG )) == null )
                            throw SqlEx.get( ERR_GC4017_NO_RESULT_SET );

                        /*
                        ** The cursor name is passed to the result-set
                        ** for updatable cursors or if provided by the
                        ** application (2.1 API spec).
                        */
                        if ( (rslt_flags & MSG_RF_READ_ONLY) == 0 )
                        {
                            resultSet = new RsltUpd( conn, this,
                                rsmd, rslt_val_stmt, cursor );
                            if ( msg.moreMessages() )  readResults( timeout, needEOG );
                        }
                        else
                        {
                            if ( rs_concur == DrvConst.DRV_CRSR_UPDATE )
                                setWarning( SqlEx.get( ERR_GC4016_RS_CHANGED ) );

                            resultSet = new RsltCurs( conn, this, rsmd, rslt_val_stmt,
                                crsr_name, getPreFetchSize(),
                                msg.moreMessages() );
                        }

                        msg.UnlockConnection();
                    }
                }
                else  if ( cursor != null )
                {
                    /*
                    ** Positioned Delete/Update.
                    */
                    msg.begin( MSG_QUERY );
                    msg.write( (type == SqlParse.QT_DELETE) ? MSG_QRY_CDEL
                        : MSG_QRY_CUPD );
                    msg.write( MSG_QP_CRSR_NAME );
                    msg.write( cursor );
                    msg.write( MSG_QP_QTXT );
                    msg.write( sql );
                    msg.done( true );

                    if ( readResults( timeout, true ) != null )	// shouldn't happen
                        throw SqlEx.get( ERR_GC4018_RESULT_SET_NOT_PERMITTED );
                    msg.UnlockConnection();
                }
                else
                {
                    /*
                    ** Non-query statement.
                    */
                    msg.begin( MSG_QUERY );
                    msg.write( MSG_QRY_EXQ );
                    msg.write( MSG_QP_QTXT );
                    msg.write( sql );
                    msg.done( true );

                    if ( (rsmd = readResults( timeout, true )) == null )
                        msg.UnlockConnection();		// We be done.
                    else
                    {
                        /*
                        ** Query unexpectedly returned a result-set.
                        ** We need to cleanup the tuple stream and
                        ** statement in the server.  The easiest
                        ** way to do this is go ahead and create a
                        ** result-set and close it.
                        */
                        resultSet = new RsltSlct( conn, this, rsmd,
                            rslt_val_stmt, 1, false );
                        try { resultSet.shut(); }
                        catch( SqlEx ) {}
                        resultSet = null;
                        throw SqlEx.get( ERR_GC4018_RESULT_SET_NOT_PERMITTED );
                    }
                }
            }
            catch( SqlEx ex )
            {
                if ( trace.enabled() )
                    trace.log( title + ".execute(): error executing query" );
                if ( trace.enabled( 1 ) )  ex.trace( trace );
                msg.UnlockConnection();
                throw ex;
            }

            return;
        }
Example #4
0
	/*
	** Dispose
	**
	** History:
	**	27-Aug-02 (thoda04)
	**	    Created.
	*/

	/// <summary>
	/// Release resources used by IngresDataReader.
	/// </summary>
	/// <param name="disposing"></param>
	protected override void Dispose(bool disposing)
	{
		/*if disposing == true  then method called by user code
		  if disposing == false then method called by runtime from inside the
		                            finalizer and we should not reference other 
		                            objects. */
		if (disposing)
		{
			Close();
			_connection  = null;
			_resultset   = null;
		}
	}
Example #5
0
        /*
        ** Name: clearQueryResults
        **
        ** Description:
        **	Clears the direct results of a query: update count and result-set.
        **	Clearing the result-set is optional and controlled by close parameter.
        **
        ** Input:
        **	close	Close result-set?
        **
        ** Output:
        **	None.
        **
        ** Returns:
        **	void.
        **
        ** History:
        **	19-Feb-03 (gordy)
        **	    Created.
        */
        protected void clearQueryResults( bool close )
        {
            lock(this)
            {
                if ( close  &&  resultSet != null )
                {
                    try { resultSet.shut(); }
                    catch( SqlEx ) {}
                    resultSet = null;
                }

                rslt_rowcount = false;
                rslt_val_rowcnt = 0;
                return;
            }
        }