예제 #1
0
        /*
        ** Name: RsltUpd
        **
        ** Description:
        **	Class constructor.
        **
        ** Input:
        **	conn		Associated connection.
        **	stmt		Associated statement.
        **	rsmd		ResultSet meta-data.
        **	stmt_id		Statement ID.
        **	cursor		Cursor name.
        **
        ** Output:
        **	None.
        **
        ** Returns:
        **	None.
        **
        ** History:
        **	 4-Aug-03 (gordy)
        **	    Created.
        **	 6-Oct-03 (gordy)
        **	    Disable pre-loading in super-class.
        */
        public RsltUpd( 
			DrvConn  	conn,
			AdvanStmt	stmt,
			AdvanRSMD	rsmd,
			long     	stmt_id,
			String   	cursor
			)
            : base(conn, stmt, rsmd, stmt_id, cursor, 1, false)
        {
            /*
            ** Updatable cursors only permit a single row per fetch,
            ** so pre-fetching and pre-loading is disabled.
            */
            tr_id = "Upd[" + inst_id + "]";
            disablePreFetch();
            return;
        }
예제 #2
0
        private long stmt_id = 0; // Server statement ID.

        #endregion Fields

        #region Constructors

        /*
        ** Name: RsltFtch
        **
        ** Description:
        **	Class constructor.
        **
        ** Input:
        **	conn		Associated connection.
        **	stmt		Associated statement.
        **	rsmd		ResultSet meta-data.
        **	stmt_id		Statement ID.
        **	preFetch	Pre-fetch row count.
        **
        ** Output:
        **	None.
        **
        ** Returns:
        **	None.
        **
        ** History:
        **	14-May-99 (gordy)
        **	    Created.
        **	15-Nov-99 (gordy)
        **	    Added max row count and max column length.
        **	13-Dec-99 (gordy)
        **	    Added fetch limit and multi-row data set.
        **	 4-Oct-00 (gordy)
        **	    Create unique ID for standardized internal tracing.
        **	 3-Nov-00 (gordy)
        **	    Parameters changed for 2.0 extensions.
        **	23-Jan-01 (gordy)
        **	    Changed parameter type to AdvanStmt for backward compatibility.
        **	31-Oct-02 (gordy)
        **	    Adapted for generic GCF driver.  Statement info maintained here.
        **	 4-Aug-03 (gordy)
        **	    Pre-fetch handling moved entirely into this class.
        */
        public RsltFtch( 
			DrvConn	conn,
			AdvanStmt	stmt, 
			AdvanRSMD	rsmd, 
			long	stmt_id,
			int		preFetch
			)
            : base(conn, rsmd)
        {
            this.stmt = stmt;
            this.stmt_id = stmt_id;
            rs_max_len = stmt.rs_max_len;
            rs_fetch_dir = stmt.rs_fetch_dir;
            rs_max_rows = stmt.rs_max_rows;
            rs_fetch_size = (rs_max_rows > 0  &&  rs_max_rows < preFetch)
                ? rs_max_rows : preFetch;
            tr_id = "Ftch[" + inst_id + "]";

            /*
            ** Row pre-fetching must be disabled if there is a BLOB column.
            */
            for( int col = 0; col < rsmd.count; col++ )
                if ( ProviderTypeMgr.isLong(rsmd.desc[ col ].sql_type) )
                {
                    rowCacheEnabled = false;
                    break;
                }

            return;
        }
예제 #3
0
        /*
        ** Name: createStatement
        **
        ** Description:
        **	Creates a Statement object associated with the
        **	connection.
        **
        ** Input:
        **	None.
        **
        ** Output:
        **	None.
        **
        ** Returns:
        **	Statement   A new Statement object.
        **
        ** History:
        **	 5-May-99 (gordy)
        **	    Created.
        **	30-Oct-00 (gordy)
        **	    Need to pass Connection object to statement.  The
        **	    associated DbConn can be obtained via getDbConn().
        **	    Pass default ResultSet type and concurrency.
        **	18-Apr-01 (gordy)
        **	    Added support for Distributed Transaction Management Connections.
        **	20-Aug-01 (gordy)
        **	    Use default concurrency.*/
        internal AdvanStmt createStatement()
        {
            if (trace.enabled())
                trace.log(title + ".createStatement()");
            warnings = null;

            if (conn.is_dtmc)
            {
                if (trace.enabled(1))
                    trace.write(tr_id + ": not permitted when DTMC");
                throw SqlEx.get( ERR_GC4019_UNSUPPORTED );
            }

            AdvanStmt stmt = new AdvanStmt(
                this.conn,
                DrvConst.TYPE_FORWARD_ONLY,
                DrvConst.DRV_CRSR_DBMS,
                DrvConst.CLOSE_CURSORS_AT_COMMIT);

            if (trace.enabled())
                trace.log(title + ".createStatement(): " + stmt);
            return (stmt);
        }
예제 #4
0
	private void Execute()
	{
		/*
		* Common code for ExecuteNonQuery and ExecuteReader.
		*/

		// There must be a valid and open connection.
		if (_connection == null || _connection.State != ConnectionState.Open)
			throw new InvalidOperationException("Connection must valid and open");

		// if a DataReader is open then connection is too busy for anything else
		CheckIfDataReaderAlreadyOpen();

		// set transaction context, autocommit/manualcommit, isolation level
		SetTransactionContext();

		// if need to force a re-Prepare because CommandText changed
		if (forceRePrepare)
		{
			forceRePrepare = false;  // no longer need to force a re-Prepare
			if (advanStmt != null)   // close and clear
			{
				advanStmt.close();
				advanStmt = null;
			}
		}  // end if (forceRePrepare)

		AdvanCall advanCall = null;
		AdvanPrep advanPrep = null;

		int      paramCount;
		if (Parameters != null  &&  Parameters.Count > 0)
			paramCount = Parameters.Count;
		else
			paramCount = 0;

		if (this.isaProcedureCall())
		{
			string callSyntaxString = this.BuildCallProcedureSyntax();
			try
			{
				advanCall = _connection.advanConnect.prepareCall( callSyntaxString );
			}
			catch( SqlEx ex )  { throw ex.createProviderException(); }
			advanStmt = advanCall;  // advanStmt -> AdvanStmt obj
		}
		else  // not a procedure call
		{
			// if we have parameters then we must internally prepare the command.
			if (paramCount > 0)
				// If not already prepared, prepare the command
				// since we need to pass parameters.
				// If already prepared then advanStmt has an AdvanPrep object.
				if (advanStmt == null  ||  advanStmt as AdvanPrep == null)
					PrepareStmt();  // Build the statement as a prepared stmt.
					                // advanStmt -> AdvanStmt obj
		}

		try
		{
		if (advanStmt == null)  // if not AdvanCall nor AdvanPrep then AdvanStmt
			advanStmt = _connection.advanConnect.createStatement();
		else
			advanPrep = advanStmt as AdvanPrep; // prepared execution?
		}
		catch( SqlEx ex )  { throw ex.createProviderException(); }

		// if parameter list present then build up ParamSet.

		// default the parameter list to the 
		// existing command.Parameters collection.
		IngresParameterCollection parameters = Parameters;
		if (paramCount > 0)
		{
			// if named parameter markers are being used
			// rebuild the parameter list in the order of the markers.
			StringCollection  parameterMarkers = advanPrep.parameterMarkers;

			if (parameterMarkers.Count > 0 &&       // rebuild if "?myparm",
				parameterMarkers[0].Length > 1)     // but not if "?"
			{
				parameters = new IngresParameterCollection();

				//  Try to match "?myparm" or "myparm" against the
				//  IngresCommand.Parameters collection and 
				//  re-order it into a new parameter collection.
				foreach (String parameterMarker in parameterMarkers)
				{
					string marker = parameterMarker;  // look for "?myparm"

					if (Parameters.Contains(marker) == false)
					{
						if (marker.Length > 1)     // instead of "?myparm"
							marker = marker.Substring(1);  // try "myparm"

						if (Parameters.Contains(marker) == false)
							throw new SqlEx(
								"Named parameter marker \"" +
								parameterMarker + "\" " +
								"was not found in the IngresCommand.Parameters " +
								"collection.");
					}
					IngresParameter parm = Parameters[marker];
					parameters.Add(parm.Clone());
				}  // end foreach (String parameterMarker in Markers)
			}  // endif Markers.Count > 0 && Markers[0].Length > 1


			int paramIndex = -1;
			foreach(IngresParameter parm in parameters)
			{
				paramIndex++;
				// if Output or ReturnValue parm then there is no value yet.
				if (parm.Direction == ParameterDirection.ReturnValue)
					continue;
				else
				if (parm.Direction == ParameterDirection.Output)
				{
					if (advanCall != null)
						advanCall.registerOutParameter(paramIndex, parm.ProviderType);
					continue;
				}
				else
				if (parm.Direction == ParameterDirection.InputOutput)
				{
					if (advanCall != null)
						advanCall.registerOutParameter(paramIndex, parm.ProviderType);
					// fall through to send out the Input value
				}

				if (parm.Value == null)
				{
					string parmName = parm.ParameterName;
					if (parmName == null)
						parmName = "";

					string msg =
						"Parameter '{0}' in ParameterCollection " +
						"at index {1} has Parameter.Value equal to null.  " +
						"Set Parameter.Value equal to DBNull.Value " +
						"if sending a null parameter to the database.";
					throw new IngresException(
						String.Format(msg, parmName, paramIndex));
				}

				try
				{
					if (Convert.IsDBNull(parm.Value))
						advanPrep.setNull(
							paramIndex, ProviderType.DBNull);
					else
						advanPrep.setObject(
							paramIndex, parm.Value, parm.ProviderType,
							parm.Scale, parm.Size);
				}
				catch( SqlEx ex )  { throw ex.createProviderException(); }
			}
		}

		// Execute the command, prepared command, or call procedure
		try
		{
			if (advanCall != null)
			{
				advanCall.execute();             // call procedure
				// if parms are present, check for Return Value parm
				if (this.Parameters.Count > 0)
				{
					int procRsltIndex = -1;      // Result param index
					if (this.Parameters[0].Direction ==
						    ParameterDirection.ReturnValue)
						procRsltIndex = 0;
					else
					if (this.Parameters[this.Parameters.Count-1].Direction ==
						    ParameterDirection.ReturnValue)
						procRsltIndex = this.Parameters.Count-1;

					// if ReturnValue is in parm list, set the value in parm
					if (procRsltIndex >= 0)
					{
						object obj =
							advanCall.getObject(procRsltIndex);

						try
						{
						Type type = ProviderTypeMgr.GetNETType(
							this.Parameters[procRsltIndex].ProviderType);
						// if DbType == Byte, a better conversion match is Byte
						if (this.Parameters[procRsltIndex].DbType == DbType.Byte)
							type = typeof(System.Byte);
						// if possible, convert to target type
							if (obj != null )
								obj = Convert.ChangeType(obj, type);
						}
						catch (InvalidCastException ex)
						{
							throw new IngresException(
								"InvalidCastException thrown while converting "+
								"DB procedure return value to target data type " +
								"as specified by IngresParameter.", ex);
						}
						this.Parameters[procRsltIndex].Value = obj;
					}  // if (procRsltIndex >= 0)

					// retrieve the value for Output and InputOutput parms
					int i = -1;  // parameter index [0:parmcnt-1]
					foreach(IngresParameter parm in this.Parameters)
					{
						i++;  // bump up parameter index
						// skip parm if Input or ReturnValue
						if (parm.Direction != ParameterDirection.Output  &&
							parm.Direction != ParameterDirection.InputOutput)
							continue;
						this.Parameters[i].Value = 
							advanCall.getObject(i);  // retrieve the output value
					}  // end foreach IngresParameter

				}  // if (this.Parameters.Count > 0)
			}
			else
			if (advanPrep != null)
				advanPrep.execute();             // execute prepared statement
			else
				advanStmt.execute(CommandTextAsBuilt); // execute statement directly
		}
		catch( SqlEx ex )  { throw ex.createProviderException(); }

		FireInfoMessageEvent();  // call the delegates with any warning messages

	}  // Execute
예제 #5
0
	private void OnConnectionStateChange(
		object sender, StateChangeEventArgs args)
	{
		// if connection closing, clear out old context
		if (args.CurrentState == ConnectionState.Closed)
		{
			this.advanStmt = null;   // clear out old statement
		}
	}
예제 #6
0
		/// <summary>
		/// Release allocated resources of the Command and base Component.
		/// </summary>
		/// <param name="disposing">
		/// true if object is being explicitly disposed of, not finalized.
		/// false if method is called by runtime from inside the finalizer.
		/// </param>
	protected override void Dispose(bool disposing)
	{
		/*if disposing == true  Object is being explicitly disposed of, not finalized
		  if disposing == false then method called by runtime from inside the
									finalizer and we should not reference other 
									objects. */
		lock(this)
		{
			try
			{
				if (disposing)
				{
					Connection = null;
					_transaction = null;
					_commandText = null;
					_parameters = null;
					advanStmt   = null;
				}
			}
			finally
			{
				base.Dispose(disposing);  // let component base do its cleanup
			}
		}
	}
예제 #7
0
	private void PrepareStmt()
	{
		try
		{
			if (advanStmt != null)  // close and clear any other statement
			{
				advanStmt.close();
				advanStmt = null;
			}

			forceRePrepare = false;  // no longer need to force a re-Prepare

			// Prepare the command.
			advanStmt = _connection.advanConnect.prepareStatement(
				CommandTextAsBuilt);
		}
		catch( SqlEx ex )  { throw ex.createProviderException(); }

		FireInfoMessageEvent();  // call the delegates with any warning messages
	}  // PrepareStmt
예제 #8
0
        /*
        ** Name: RsltSlct
        **
        ** Description:
        **	Class constructor.
        **
        **	Initial row cache may be pre-loaded, but only if the
        **	message stream is active and DATA messages available.
        **
        ** Input:
        **	conn		Associated connection.
        **	stmt		Associated statement.
        **	rsmd		ResultSet meta-data.
        **	stmt_id		Statement ID.
        **	preFetch	Pre-fetch row count.
        **	preLoad		Load initial row cache.
        **
        ** Output:
        **	None.
        **
        ** Returns:
        **	None.
        **
        ** History:
        **	17-May-00 (gordy)
        **	    Created.
        **	 4-Oct-00 (gordy)
        **	    Create unique ID for standardized internal tracing.
        **	27-Oct-00 (gordy)
        **	    New super-class constructor doesn't take cursor name.
        **	15-Nov-00 (gordy)
        **	    Changed parameters for 2.0 support.
        **	23-Jan-01 (gordy)
        **	    Changed parameter type to AdvanStmt for backward compatibility.
        **	31-Oct-02 (gordy)
        **	    Adapted for generic GCF driver.
        **	 6-Oct-03 (gordy)
        **	    Added preLoad parameter to read initial row cache from server.
        */
        public RsltSlct( 
			DrvConn	conn,
			AdvanStmt	stmt, 
			AdvanRSMD	rsmd, 
			long	stmt_id,
			int		preFetch,
			bool	do_preLoad )
            : base(conn, stmt, rsmd, stmt_id, preFetch)
        {
            tr_id = "Slct[" + inst_id + "]";

            /*
            ** Pre-load row cache if requested.
            */
            if ( do_preLoad  &&  preLoad() )
            {
                /*
                ** Close the statement when end-of-data detected.
                **
                ** Note that our caller only locks the connection,
                ** and expects the connection to be unlocked when
                ** data stream is done.  Our closeCursor() method
                ** will unlock the connection as needed.
                */
                try { closeCursor(); }
                catch( SqlEx ) {}
            }

            return;
        }