/* ** 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; }
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; }
/* ** 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); }
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
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 } }
/// <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 } } }
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
/* ** 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; }