OracleCommandSet.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / DataOracleClient / System / Data / OracleClient / OracleCommandSet.cs / 1 / OracleCommandSet.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Data.OracleClient { 

    using System; 
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Data.Common; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.Text; 
    using System.Text.RegularExpressions;
 
    internal sealed class OracleCommandSet : IDisposable{
        static private readonly string _sqlTokenPattern =
                  @"[\s]+"                          // white space
                + @"|(?'([^']|'')*')"       // single quoted literal or double quoted literal/identifier 
                + @"|(?"
                    + @"(/\*([^\*]|\*[^/])*\*/)"    // c-style comment 
                    + @"|" 
                    + @"(--.*)"                     // ansi-sql style comment
                + @")" 
                + @"|(?:[\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_#$]+)" // parameter-marker
                + @"|(?select)"              // query statements
                + @"|(?"
                    + @"([\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_#$]+)"   // identifier 
                    + @"|"
                    + "(\"([^\"]|\"\")*\")"         // quoted identifier 
                + @")" 
                + @"|(?.)"                   // everything else
                ; 

        static private Regex    _sqlTokenParser;

        static private int      _commentGroup; 
        static private int      _identifierGroup;
        static private int      _parameterMarkerGroup; 
        static private int      _queryGroup; 
        static private int      _stringGroup;
        static private int      _otherGroup; 

        static private readonly string Declarations_Prefix = "declare\ntype refcursortype is ref cursor;\n";
        static private readonly string Declarations_CursorType = " refcursortype;\n";
 
        static private readonly string Body_Prefix = "begin\n" ;
        static private readonly string Body_Suffix = "end;" ; 
 
        static private readonly string Command_QueryPrefix_Part1 = "open ";
        static private readonly string Command_QueryPrefix_Part2 = " for "; 

        static private readonly string Command_Suffix_Part1 = ";\n:";
        static private readonly string Command_NonQuerySuffix_Part2 = " := sql%rowcount;\n";
 
        static private readonly string Command_QuerySuffix_Part2 = " := ";
        static private readonly string Command_QuerySuffix_Part3 = ";\n"; 
 
        private Hashtable       _usedParameterNames = new Hashtable(StringComparer.OrdinalIgnoreCase);
        private ArrayList       _commandList = new ArrayList(); 
        private OracleCommand   _batchCommand;
        private bool            _dirty;

        private sealed class LocalCommand { 
            internal readonly bool IsQuery;
            internal readonly string CommandText; 
            internal readonly DbParameter[] Parameters; 
            internal readonly string[] ParameterNames;
            internal readonly LocalParameter[] ParameterInsertionPoints; 
            internal OracleParameter ResultParameter;

            internal LocalCommand(string commandText, bool isQuery, DbParameter[] parameters, string[] parameterNames, LocalParameter[] parameterInsertionPoints) {
                Debug.Assert(0 <= commandText.Length, "no text"); 
                this.CommandText = commandText;
                this.IsQuery = isQuery; 
                this.Parameters = parameters; 
                this.ParameterNames = parameterNames;
                this.ParameterInsertionPoints = parameterInsertionPoints; 
            }
        }

        private struct LocalParameter { 
            internal readonly int ParameterIndex;
            internal readonly int InsertionPoint; 
            internal readonly int RemovalLength; 

            internal LocalParameter(int parameterIndex, int insertionPoint, int removalLength) { 
                Debug.Assert(0 <= parameterIndex, "negative index");
                Debug.Assert(0 <= insertionPoint, "negative insert");
                Debug.Assert(0 <= removalLength, "negative length");
                this.ParameterIndex = parameterIndex; 
                this.InsertionPoint = insertionPoint;
                this.RemovalLength = removalLength; 
            } 
        }
 
        public OracleCommandSet() : this(null, null) {
        }

 
        public OracleCommandSet(OracleConnection connection, OracleTransaction transaction) : base() {
            _batchCommand = new OracleCommand(); 
            Connection = connection; 
            Transaction = transaction;
        } 

        private OracleCommand BatchCommand {
            get {
                OracleCommand command = _batchCommand; 
                if (null == command) {
                    throw ADP.ObjectDisposed(this.GetType().Name); 
                } 
                return command;
            } 
        }

        /*/
        public bool CanOptimizeSet { 
            get {
                return true; 
            } 
        }
        */ 

        public int CommandCount {
            get {
                return CommandList.Count; 
            }
        } 
 
        private ArrayList CommandList {
            get { 
                ArrayList commandList = _commandList;
                if (null == commandList) {
                    throw ADP.ObjectDisposed(this.GetType().Name);
                } 
                return commandList;
            } 
        } 

        public int CommandTimeout { 
            set {
                BatchCommand.CommandTimeout = value;
            }
        } 

        public OracleConnection Connection { 
            set { 
                BatchCommand.Connection = value;
            } 
        }

        internal OracleTransaction Transaction {
             set { 
                BatchCommand.Transaction = (OracleTransaction)value;
            } 
        } 

        public void Append(OracleCommand command) { 
            ADP.CheckArgumentNull(command, "command");

            if (ADP.IsEmpty(command.CommandText)) {
                throw ADP.CommandTextRequired("Append"); 
            }
 
            // 

            ICollection collection = command.Parameters; 
            OracleParameter[] parameters = new OracleParameter[collection.Count];
            collection.CopyTo(parameters, 0);
            string[] parameterNames = new string[parameters.Length];
            if (0 < parameters.Length) { 
                for(int i = 0; i < parameters.Length; ++i) {
                    parameterNames[i] = parameters[i].ParameterName; 
 
                    OracleParameter p = command.CreateParameter();
                    parameters[i].CopyTo(p); 

                    // Deep clone the parameter value if byte[] or char[]
                    object obj = p.Value;
                    if (obj is byte[]) { 
                        byte[] value = (byte[])obj;
                        int offset = p.Offset; 
                        int size = p.Size; 
                        int countOfBytes = value.Length - offset;
                        if ((0 != size) && (size < countOfBytes)) { 
                            countOfBytes = size;
                        }
                        byte[] copy = new byte[Math.Max(countOfBytes, 0)];
                        Buffer.BlockCopy(value, offset, copy, 0, copy.Length); 
                        p.Offset = 0;
                        p.Value = copy; 
                    } 
                    else if (obj is char[]) {
                        char[] value = (char[])obj; 
                        int offset = p.Offset;
                        int size = p.Size;
                        int countOfChars = value.Length - offset;
                        if ((0 != size) && (size < countOfChars)) { 
                            countOfChars = size;
                        } 
                        char[] copy = new char[Math.Max(countOfChars, 0)]; 
                        Buffer.BlockCopy(value, offset, copy, 0, copy.Length*2);
                        p.Offset = 0; 
                        p.Value = copy;
                    }
                    else if (obj is ICloneable) {
                        p.Value = ((ICloneable)obj).Clone(); 
                    }
                    parameters[i] = p; 
                } 
            }
 
            string statementText = command.StatementText;
            bool    isQuery = false;
            LocalParameter[] parameterInsertions = ParseText(command, statementText, out isQuery);
 
            Debug.Assert(null != parameterInsertions, "null parameterInsertions");
 
#if TRACECOMMANDSET 
            foreach(LocalParameter local in parameterInsertions) {
                Debug.WriteLine("\t\t<"+parameters[local.ParameterIndex].ParameterName+"> " + local.InsertionPoint.ToString(CultureInfo.InvariantCulture) + " " + local.RemovalLength.ToString(CultureInfo.InvariantCulture)); 
            }
#endif //TRACECOMMANDSET
            LocalCommand cmd = new LocalCommand(statementText, isQuery, parameters, parameterNames, parameterInsertions);
            _dirty = true; 
            CommandList.Add(cmd);
        } 
 
        public void Clear() {
            DbCommand batchCommand = BatchCommand; 
            if (null != batchCommand) {
                batchCommand.Parameters.Clear();
                batchCommand.CommandText = null;
            } 
            ArrayList commandList = _commandList;
            if (null != commandList) { 
                commandList.Clear(); 
            }
            Hashtable usedParameterNames = _usedParameterNames; 
            if (null != usedParameterNames) {
                usedParameterNames.Clear();
            }
         } 

        public void Dispose() { 
            DbCommand command = _batchCommand; 
            _batchCommand = null;
            _commandList = null; 
            _usedParameterNames = null;

            if (null != command) {
                command.Dispose(); 
            }
        } 
 
        public int ExecuteNonQuery() {
            GenerateBatchCommandText(); 
            return BatchCommand.ExecuteNonQuery();
        }

        private void GenerateBatchCommandText() { 
            if (_dirty) {
                DbCommand batchCommand = BatchCommand; 
 
                StringBuilder declarations = new StringBuilder();
                StringBuilder body = new StringBuilder(); 

                int resultIndex = 1;
                int cursorIndex = 1;
                int paramIndex  = 1; 

                batchCommand.Parameters.Clear(); 
 
                declarations.Append(Declarations_Prefix);
                body.Append(Body_Prefix); 

                foreach (LocalCommand localCommand in CommandList) {
                    // Add each of the original commands parameters to the batch
                    // command, ensuring each parameter name is unique, ie. that 
                    // there wasn't a parameter name somewhere in the original
                    // command text that we didn't have a bound parameter for. 
                    foreach (DbParameter parameter in localCommand.Parameters) { 
                        string parameterName;
                        do { 
                            parameterName = "p" + paramIndex.ToString(CultureInfo.InvariantCulture);
                            paramIndex++;
                        } while (_usedParameterNames.ContainsKey(parameterName));
 
                        // Oracle doesn't care if multiple parameters are marked with ParameterDirection.ReturnValue
 
                        parameter.ParameterName = parameterName; 
                        batchCommand.Parameters.Add(parameter);
                    } 

                    // Generate a unique parameter name for the result parameter
                    // and add it to the batch command, indicating that it needs
                    // special processing by the execute to be put into the result 
                    // set.
                    string resultName; 
                    do { 
                        resultName = "r" + resultIndex.ToString(CultureInfo.InvariantCulture)+"_"+paramIndex.ToString(CultureInfo.InvariantCulture);
                        paramIndex++; 
                    } while (_usedParameterNames.ContainsKey(resultName));

                    OracleParameter resultParameter = new OracleParameter();
                    resultParameter.CommandSetResult = resultIndex++; 
                    resultParameter.Direction = ParameterDirection.Output;
                    resultParameter.ParameterName = resultName; 
                    batchCommand.Parameters.Add(resultParameter); 

                    // Append the appropriate text to the declarations and the body 
                    // sections, depending on whether an explicit cursor is needed
                    // or not.
                    int offset = body.Length;
 
                    if (localCommand.IsQuery) {
                        string cursorName = "c" + cursorIndex.ToString(CultureInfo.InvariantCulture); 
                        cursorIndex++; 

                        declarations.Append(cursorName); 
                        declarations.Append(Declarations_CursorType);

                        body.Append(Command_QueryPrefix_Part1);
                        body.Append(cursorName); 
                        body.Append(Command_QueryPrefix_Part2);
 
                        offset = body.Length; 
                        body.Append(localCommand.CommandText);
 
                        body.Append(Command_Suffix_Part1);
                        body.Append(resultName);
                        body.Append(Command_QuerySuffix_Part2);
                        body.Append(cursorName); 
                        body.Append(Command_QuerySuffix_Part3);
 
                        resultParameter.OracleType = OracleType.Cursor; 
                        // don't cache ResultParameter, always has 'RecordsAffected == -1'
                    } 
                    else {
                        string commandText = localCommand.CommandText;

                        body.Append(commandText.TrimEnd(';'));// remove extra semicolons, we're going to add our own... 

                        body.Append(Command_Suffix_Part1); 
                        body.Append(resultName); 
                        body.Append(Command_NonQuerySuffix_Part2);
 
                        resultParameter.OracleType = OracleType.Int32;
                        localCommand.ResultParameter = resultParameter;
                    }
 
                    // Now perform the parameter name replacement in the statement
                    // text; we saved the start of this statement's text in the 
                    // offset variable, and we simply do the replacement in the body 
                    // text.
                    foreach (LocalParameter localParameter in localCommand.ParameterInsertionPoints) { 
                        DbParameter parameter = localCommand.Parameters[localParameter.ParameterIndex];
                        string parameterMarker = ":" + parameter.ParameterName;

                        body.Remove(offset + localParameter.InsertionPoint, localParameter.RemovalLength); 
                        body.Insert(offset + localParameter.InsertionPoint, parameterMarker);
                        offset += (parameterMarker.Length - localParameter.RemovalLength); 
                    } 
                }
 
                // Now we get tricky; we append the body to the declarations, and
                // then we use the result as the actual command text for the batch
                // command.
                body.Append(Body_Suffix); 
                declarations.Append(body);
 
                batchCommand.CommandText = declarations.ToString(); 
#if TRACECOMMANDSET
                Debug.WriteLine(""+batchCommand.CommandText+""); 
#endif //TRACECOMMANDSET
                _dirty = false;
            }
        } 

        internal bool GetBatchedRecordsAffected(int commandIndex, out int recordsAffected) { 
            OracleParameter resultParameter = ((LocalCommand)CommandList[commandIndex]).ResultParameter; 
            if (null != resultParameter) {
                if (resultParameter.Value is Int32) { 
                    recordsAffected = (int)resultParameter.Value; // the records affected
                    return true;
                }
                recordsAffected = -1; 
                return false; // batch didn't complete
            } 
            recordsAffected = -1; 
            return true; // IsQuery == true
        } 

        internal DbParameter GetParameter(int commandIndex, int parameterIndex) {
            return ((LocalCommand)CommandList[commandIndex]).Parameters[parameterIndex];
        } 

        public int GetParameterCount(int commandIndex) { 
            return ((LocalCommand)CommandList[commandIndex]).Parameters.Length; 
        }
 
        static private Regex GetSqlTokenParser() {
            Regex parser = _sqlTokenParser;
            if (null == parser) {
                // due to workingset size issues ~1.5MB, don't use RegexOptions.Compiled 
                parser = new Regex(_sqlTokenPattern, RegexOptions.ExplicitCapture);
 
                _commentGroup= parser.GroupNumberFromName("comment"); 
                _identifierGroup = parser.GroupNumberFromName("identifier");
                _parameterMarkerGroup= parser.GroupNumberFromName("parametermarker"); 
                _queryGroup = parser.GroupNumberFromName("query");
                _stringGroup = parser.GroupNumberFromName("string");
                _otherGroup = parser.GroupNumberFromName("other");
 
                _sqlTokenParser = parser;
            } 
            return parser; 
        }
 
        private LocalParameter[] ParseText(OracleCommand command, string commandText, out bool isQuery) {
#if TRACECOMMANDSET
            Debug.WriteLine(String.Format("\n\n{0}", commandText));
#endif //TRACECOMMANDSET 
            OracleParameterCollection parameters = command.Parameters;
            ArrayList insertionPoints = new ArrayList(); 
 
            Regex parser = GetSqlTokenParser();
            isQuery = false; 
            bool keywordOrIdentiferFound = false;

            for (Match match = parser.Match(commandText); Match.Empty != match; match = match.NextMatch()) {
                if (match.Groups[_commentGroup].Success) { 
                    // no effect, just eat
                } 
                else if (match.Groups[_identifierGroup].Success 
                 || match.Groups[_stringGroup].Success
                 || match.Groups[_otherGroup].Success) { 
                    keywordOrIdentiferFound = true;
                }
                else if (match.Groups[_queryGroup].Success) {
                    if (!keywordOrIdentiferFound) { 
                        isQuery = true;
#if TRACECOMMANDSET 
                        Debug.WriteLine("...QueryStatementFound"); 
#endif //TRACECOMMANDSET
                    } 
                }
                else if (match.Groups[_parameterMarkerGroup].Success) {
                    string parameterMarker = match.Groups[_parameterMarkerGroup].Value;
                    string parameterName = parameterMarker.Substring(1); 

                    _usedParameterNames[parameterName] = null; 
 
                    int parameterIndex = parameters.IndexOf(parameterName);
 
                    // SQLBUDT #289921 - some folks will put the ":" in the
                    // parameter name in the collection, so we need to take
                    // that into account.
                    if (0 > parameterIndex) { 
                        string tempName = ":" + parameterName;
                        parameterIndex = parameters.IndexOf(tempName); 
                    } 

                    if (0 <= parameterIndex) { 
#if TRACECOMMANDSET
                        Debug.WriteLine(String.Format("...IsParameter({0})", parameterIndex));
#endif
                        insertionPoints.Add(new LocalParameter(parameterIndex, match.Index, match.Length)); 
                    }
                } 
            } 
            LocalParameter[] values = new LocalParameter[insertionPoints.Count];
            insertionPoints.CopyTo(values, 0); 
            return values;
        }

    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Data.OracleClient { 

    using System; 
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Data.Common; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.Text; 
    using System.Text.RegularExpressions;
 
    internal sealed class OracleCommandSet : IDisposable{
        static private readonly string _sqlTokenPattern =
                  @"[\s]+"                          // white space
                + @"|(?'([^']|'')*')"       // single quoted literal or double quoted literal/identifier 
                + @"|(?"
                    + @"(/\*([^\*]|\*[^/])*\*/)"    // c-style comment 
                    + @"|" 
                    + @"(--.*)"                     // ansi-sql style comment
                + @")" 
                + @"|(?:[\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_#$]+)" // parameter-marker
                + @"|(?select)"              // query statements
                + @"|(?"
                    + @"([\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_#$]+)"   // identifier 
                    + @"|"
                    + "(\"([^\"]|\"\")*\")"         // quoted identifier 
                + @")" 
                + @"|(?.)"                   // everything else
                ; 

        static private Regex    _sqlTokenParser;

        static private int      _commentGroup; 
        static private int      _identifierGroup;
        static private int      _parameterMarkerGroup; 
        static private int      _queryGroup; 
        static private int      _stringGroup;
        static private int      _otherGroup; 

        static private readonly string Declarations_Prefix = "declare\ntype refcursortype is ref cursor;\n";
        static private readonly string Declarations_CursorType = " refcursortype;\n";
 
        static private readonly string Body_Prefix = "begin\n" ;
        static private readonly string Body_Suffix = "end;" ; 
 
        static private readonly string Command_QueryPrefix_Part1 = "open ";
        static private readonly string Command_QueryPrefix_Part2 = " for "; 

        static private readonly string Command_Suffix_Part1 = ";\n:";
        static private readonly string Command_NonQuerySuffix_Part2 = " := sql%rowcount;\n";
 
        static private readonly string Command_QuerySuffix_Part2 = " := ";
        static private readonly string Command_QuerySuffix_Part3 = ";\n"; 
 
        private Hashtable       _usedParameterNames = new Hashtable(StringComparer.OrdinalIgnoreCase);
        private ArrayList       _commandList = new ArrayList(); 
        private OracleCommand   _batchCommand;
        private bool            _dirty;

        private sealed class LocalCommand { 
            internal readonly bool IsQuery;
            internal readonly string CommandText; 
            internal readonly DbParameter[] Parameters; 
            internal readonly string[] ParameterNames;
            internal readonly LocalParameter[] ParameterInsertionPoints; 
            internal OracleParameter ResultParameter;

            internal LocalCommand(string commandText, bool isQuery, DbParameter[] parameters, string[] parameterNames, LocalParameter[] parameterInsertionPoints) {
                Debug.Assert(0 <= commandText.Length, "no text"); 
                this.CommandText = commandText;
                this.IsQuery = isQuery; 
                this.Parameters = parameters; 
                this.ParameterNames = parameterNames;
                this.ParameterInsertionPoints = parameterInsertionPoints; 
            }
        }

        private struct LocalParameter { 
            internal readonly int ParameterIndex;
            internal readonly int InsertionPoint; 
            internal readonly int RemovalLength; 

            internal LocalParameter(int parameterIndex, int insertionPoint, int removalLength) { 
                Debug.Assert(0 <= parameterIndex, "negative index");
                Debug.Assert(0 <= insertionPoint, "negative insert");
                Debug.Assert(0 <= removalLength, "negative length");
                this.ParameterIndex = parameterIndex; 
                this.InsertionPoint = insertionPoint;
                this.RemovalLength = removalLength; 
            } 
        }
 
        public OracleCommandSet() : this(null, null) {
        }

 
        public OracleCommandSet(OracleConnection connection, OracleTransaction transaction) : base() {
            _batchCommand = new OracleCommand(); 
            Connection = connection; 
            Transaction = transaction;
        } 

        private OracleCommand BatchCommand {
            get {
                OracleCommand command = _batchCommand; 
                if (null == command) {
                    throw ADP.ObjectDisposed(this.GetType().Name); 
                } 
                return command;
            } 
        }

        /*/
        public bool CanOptimizeSet { 
            get {
                return true; 
            } 
        }
        */ 

        public int CommandCount {
            get {
                return CommandList.Count; 
            }
        } 
 
        private ArrayList CommandList {
            get { 
                ArrayList commandList = _commandList;
                if (null == commandList) {
                    throw ADP.ObjectDisposed(this.GetType().Name);
                } 
                return commandList;
            } 
        } 

        public int CommandTimeout { 
            set {
                BatchCommand.CommandTimeout = value;
            }
        } 

        public OracleConnection Connection { 
            set { 
                BatchCommand.Connection = value;
            } 
        }

        internal OracleTransaction Transaction {
             set { 
                BatchCommand.Transaction = (OracleTransaction)value;
            } 
        } 

        public void Append(OracleCommand command) { 
            ADP.CheckArgumentNull(command, "command");

            if (ADP.IsEmpty(command.CommandText)) {
                throw ADP.CommandTextRequired("Append"); 
            }
 
            // 

            ICollection collection = command.Parameters; 
            OracleParameter[] parameters = new OracleParameter[collection.Count];
            collection.CopyTo(parameters, 0);
            string[] parameterNames = new string[parameters.Length];
            if (0 < parameters.Length) { 
                for(int i = 0; i < parameters.Length; ++i) {
                    parameterNames[i] = parameters[i].ParameterName; 
 
                    OracleParameter p = command.CreateParameter();
                    parameters[i].CopyTo(p); 

                    // Deep clone the parameter value if byte[] or char[]
                    object obj = p.Value;
                    if (obj is byte[]) { 
                        byte[] value = (byte[])obj;
                        int offset = p.Offset; 
                        int size = p.Size; 
                        int countOfBytes = value.Length - offset;
                        if ((0 != size) && (size < countOfBytes)) { 
                            countOfBytes = size;
                        }
                        byte[] copy = new byte[Math.Max(countOfBytes, 0)];
                        Buffer.BlockCopy(value, offset, copy, 0, copy.Length); 
                        p.Offset = 0;
                        p.Value = copy; 
                    } 
                    else if (obj is char[]) {
                        char[] value = (char[])obj; 
                        int offset = p.Offset;
                        int size = p.Size;
                        int countOfChars = value.Length - offset;
                        if ((0 != size) && (size < countOfChars)) { 
                            countOfChars = size;
                        } 
                        char[] copy = new char[Math.Max(countOfChars, 0)]; 
                        Buffer.BlockCopy(value, offset, copy, 0, copy.Length*2);
                        p.Offset = 0; 
                        p.Value = copy;
                    }
                    else if (obj is ICloneable) {
                        p.Value = ((ICloneable)obj).Clone(); 
                    }
                    parameters[i] = p; 
                } 
            }
 
            string statementText = command.StatementText;
            bool    isQuery = false;
            LocalParameter[] parameterInsertions = ParseText(command, statementText, out isQuery);
 
            Debug.Assert(null != parameterInsertions, "null parameterInsertions");
 
#if TRACECOMMANDSET 
            foreach(LocalParameter local in parameterInsertions) {
                Debug.WriteLine("\t\t<"+parameters[local.ParameterIndex].ParameterName+"> " + local.InsertionPoint.ToString(CultureInfo.InvariantCulture) + " " + local.RemovalLength.ToString(CultureInfo.InvariantCulture)); 
            }
#endif //TRACECOMMANDSET
            LocalCommand cmd = new LocalCommand(statementText, isQuery, parameters, parameterNames, parameterInsertions);
            _dirty = true; 
            CommandList.Add(cmd);
        } 
 
        public void Clear() {
            DbCommand batchCommand = BatchCommand; 
            if (null != batchCommand) {
                batchCommand.Parameters.Clear();
                batchCommand.CommandText = null;
            } 
            ArrayList commandList = _commandList;
            if (null != commandList) { 
                commandList.Clear(); 
            }
            Hashtable usedParameterNames = _usedParameterNames; 
            if (null != usedParameterNames) {
                usedParameterNames.Clear();
            }
         } 

        public void Dispose() { 
            DbCommand command = _batchCommand; 
            _batchCommand = null;
            _commandList = null; 
            _usedParameterNames = null;

            if (null != command) {
                command.Dispose(); 
            }
        } 
 
        public int ExecuteNonQuery() {
            GenerateBatchCommandText(); 
            return BatchCommand.ExecuteNonQuery();
        }

        private void GenerateBatchCommandText() { 
            if (_dirty) {
                DbCommand batchCommand = BatchCommand; 
 
                StringBuilder declarations = new StringBuilder();
                StringBuilder body = new StringBuilder(); 

                int resultIndex = 1;
                int cursorIndex = 1;
                int paramIndex  = 1; 

                batchCommand.Parameters.Clear(); 
 
                declarations.Append(Declarations_Prefix);
                body.Append(Body_Prefix); 

                foreach (LocalCommand localCommand in CommandList) {
                    // Add each of the original commands parameters to the batch
                    // command, ensuring each parameter name is unique, ie. that 
                    // there wasn't a parameter name somewhere in the original
                    // command text that we didn't have a bound parameter for. 
                    foreach (DbParameter parameter in localCommand.Parameters) { 
                        string parameterName;
                        do { 
                            parameterName = "p" + paramIndex.ToString(CultureInfo.InvariantCulture);
                            paramIndex++;
                        } while (_usedParameterNames.ContainsKey(parameterName));
 
                        // Oracle doesn't care if multiple parameters are marked with ParameterDirection.ReturnValue
 
                        parameter.ParameterName = parameterName; 
                        batchCommand.Parameters.Add(parameter);
                    } 

                    // Generate a unique parameter name for the result parameter
                    // and add it to the batch command, indicating that it needs
                    // special processing by the execute to be put into the result 
                    // set.
                    string resultName; 
                    do { 
                        resultName = "r" + resultIndex.ToString(CultureInfo.InvariantCulture)+"_"+paramIndex.ToString(CultureInfo.InvariantCulture);
                        paramIndex++; 
                    } while (_usedParameterNames.ContainsKey(resultName));

                    OracleParameter resultParameter = new OracleParameter();
                    resultParameter.CommandSetResult = resultIndex++; 
                    resultParameter.Direction = ParameterDirection.Output;
                    resultParameter.ParameterName = resultName; 
                    batchCommand.Parameters.Add(resultParameter); 

                    // Append the appropriate text to the declarations and the body 
                    // sections, depending on whether an explicit cursor is needed
                    // or not.
                    int offset = body.Length;
 
                    if (localCommand.IsQuery) {
                        string cursorName = "c" + cursorIndex.ToString(CultureInfo.InvariantCulture); 
                        cursorIndex++; 

                        declarations.Append(cursorName); 
                        declarations.Append(Declarations_CursorType);

                        body.Append(Command_QueryPrefix_Part1);
                        body.Append(cursorName); 
                        body.Append(Command_QueryPrefix_Part2);
 
                        offset = body.Length; 
                        body.Append(localCommand.CommandText);
 
                        body.Append(Command_Suffix_Part1);
                        body.Append(resultName);
                        body.Append(Command_QuerySuffix_Part2);
                        body.Append(cursorName); 
                        body.Append(Command_QuerySuffix_Part3);
 
                        resultParameter.OracleType = OracleType.Cursor; 
                        // don't cache ResultParameter, always has 'RecordsAffected == -1'
                    } 
                    else {
                        string commandText = localCommand.CommandText;

                        body.Append(commandText.TrimEnd(';'));// remove extra semicolons, we're going to add our own... 

                        body.Append(Command_Suffix_Part1); 
                        body.Append(resultName); 
                        body.Append(Command_NonQuerySuffix_Part2);
 
                        resultParameter.OracleType = OracleType.Int32;
                        localCommand.ResultParameter = resultParameter;
                    }
 
                    // Now perform the parameter name replacement in the statement
                    // text; we saved the start of this statement's text in the 
                    // offset variable, and we simply do the replacement in the body 
                    // text.
                    foreach (LocalParameter localParameter in localCommand.ParameterInsertionPoints) { 
                        DbParameter parameter = localCommand.Parameters[localParameter.ParameterIndex];
                        string parameterMarker = ":" + parameter.ParameterName;

                        body.Remove(offset + localParameter.InsertionPoint, localParameter.RemovalLength); 
                        body.Insert(offset + localParameter.InsertionPoint, parameterMarker);
                        offset += (parameterMarker.Length - localParameter.RemovalLength); 
                    } 
                }
 
                // Now we get tricky; we append the body to the declarations, and
                // then we use the result as the actual command text for the batch
                // command.
                body.Append(Body_Suffix); 
                declarations.Append(body);
 
                batchCommand.CommandText = declarations.ToString(); 
#if TRACECOMMANDSET
                Debug.WriteLine(""+batchCommand.CommandText+""); 
#endif //TRACECOMMANDSET
                _dirty = false;
            }
        } 

        internal bool GetBatchedRecordsAffected(int commandIndex, out int recordsAffected) { 
            OracleParameter resultParameter = ((LocalCommand)CommandList[commandIndex]).ResultParameter; 
            if (null != resultParameter) {
                if (resultParameter.Value is Int32) { 
                    recordsAffected = (int)resultParameter.Value; // the records affected
                    return true;
                }
                recordsAffected = -1; 
                return false; // batch didn't complete
            } 
            recordsAffected = -1; 
            return true; // IsQuery == true
        } 

        internal DbParameter GetParameter(int commandIndex, int parameterIndex) {
            return ((LocalCommand)CommandList[commandIndex]).Parameters[parameterIndex];
        } 

        public int GetParameterCount(int commandIndex) { 
            return ((LocalCommand)CommandList[commandIndex]).Parameters.Length; 
        }
 
        static private Regex GetSqlTokenParser() {
            Regex parser = _sqlTokenParser;
            if (null == parser) {
                // due to workingset size issues ~1.5MB, don't use RegexOptions.Compiled 
                parser = new Regex(_sqlTokenPattern, RegexOptions.ExplicitCapture);
 
                _commentGroup= parser.GroupNumberFromName("comment"); 
                _identifierGroup = parser.GroupNumberFromName("identifier");
                _parameterMarkerGroup= parser.GroupNumberFromName("parametermarker"); 
                _queryGroup = parser.GroupNumberFromName("query");
                _stringGroup = parser.GroupNumberFromName("string");
                _otherGroup = parser.GroupNumberFromName("other");
 
                _sqlTokenParser = parser;
            } 
            return parser; 
        }
 
        private LocalParameter[] ParseText(OracleCommand command, string commandText, out bool isQuery) {
#if TRACECOMMANDSET
            Debug.WriteLine(String.Format("\n\n{0}", commandText));
#endif //TRACECOMMANDSET 
            OracleParameterCollection parameters = command.Parameters;
            ArrayList insertionPoints = new ArrayList(); 
 
            Regex parser = GetSqlTokenParser();
            isQuery = false; 
            bool keywordOrIdentiferFound = false;

            for (Match match = parser.Match(commandText); Match.Empty != match; match = match.NextMatch()) {
                if (match.Groups[_commentGroup].Success) { 
                    // no effect, just eat
                } 
                else if (match.Groups[_identifierGroup].Success 
                 || match.Groups[_stringGroup].Success
                 || match.Groups[_otherGroup].Success) { 
                    keywordOrIdentiferFound = true;
                }
                else if (match.Groups[_queryGroup].Success) {
                    if (!keywordOrIdentiferFound) { 
                        isQuery = true;
#if TRACECOMMANDSET 
                        Debug.WriteLine("...QueryStatementFound"); 
#endif //TRACECOMMANDSET
                    } 
                }
                else if (match.Groups[_parameterMarkerGroup].Success) {
                    string parameterMarker = match.Groups[_parameterMarkerGroup].Value;
                    string parameterName = parameterMarker.Substring(1); 

                    _usedParameterNames[parameterName] = null; 
 
                    int parameterIndex = parameters.IndexOf(parameterName);
 
                    // SQLBUDT #289921 - some folks will put the ":" in the
                    // parameter name in the collection, so we need to take
                    // that into account.
                    if (0 > parameterIndex) { 
                        string tempName = ":" + parameterName;
                        parameterIndex = parameters.IndexOf(tempName); 
                    } 

                    if (0 <= parameterIndex) { 
#if TRACECOMMANDSET
                        Debug.WriteLine(String.Format("...IsParameter({0})", parameterIndex));
#endif
                        insertionPoints.Add(new LocalParameter(parameterIndex, match.Index, match.Length)); 
                    }
                } 
            } 
            LocalParameter[] values = new LocalParameter[insertionPoints.Count];
            insertionPoints.CopyTo(values, 0); 
            return values;
        }

    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK