getString() public method

public getString ( ) : string
return string
示例#1
0
        public NuoDbDataReader(NuoDbConnection connection, int handle, EncodedDataStream dataStream, NuoDbCommand statement, bool readColumnNames)
        {
            this.connection = connection;
            this.handle = handle;
            this.pendingRows = dataStream;
            this.statement = statement;

            if (this.handle != -1)
                this.connection.InternalConnection.RegisterResultSet(this.handle);

            this.numberColumns = this.pendingRows != null ? this.pendingRows.getInt() : 0;
            this.values = new Value[numberColumns];

            if (readColumnNames)
            {
                this.columnNames = new string[numberColumns];
                for (int n = 0; n < numberColumns; ++n)
                {
                    columnNames[n] = dataStream.getString();
                }
            }
            else
            {
                //RemPreparedStatement ps = (RemPreparedStatement)statement;
                //columnNames = ps.columnNames;
            }
        }
        public override DataTable GetSchemaTable()
        {
            if (metadata != null)
                return metadata;

            #if DEBUG
            System.Diagnostics.Trace.WriteLine("NuoDbDataReader.GetSchemaTable(" + statement.CommandText + ")");
            #endif
            EncodedDataStream dataStream = new EncodedDataStream();
            dataStream.startMessage(Protocol.GetMetaData);
            dataStream.encodeInt(handle);
            connection.InternalConnection.sendAndReceive(dataStream);
            int numberColumns = dataStream.getInt();

            metadata = new DataTable("SchemaTable");

            // Info on the schema of this table is at http://msdn.microsoft.com/en-us/library/system.data.odbc.odbcdatareader.getschematable.aspx
            // The zero-based ordinal of the column. This column cannot contain a null value.
            metadata.Columns.Add("ColumnOrdinal", typeof(int));
            // The name of the column; this might not be unique. If the column name cannot be determined, a null value is returned.
            // This name always reflects the most recent naming of the column in the current view or command text.
            metadata.Columns.Add("ColumnName", typeof(string));
            // The maximum possible length of a value in the column. For columns that use a fixed-length data type, this is the size of the data type.
            metadata.Columns.Add("ColumnSize", typeof(int));
            // If DbType is a numeric data type, this is the maximum precision of the column. The precision depends on the
            // definition of the column. If DbType is not a numeric data type, do not use the data in this column.
            // If the underlying ODBC driver returns a precision value for a non-numeric data type, this value is used in the schema table.
            metadata.Columns.Add("NumericPrecision", typeof(int));
            // If DbType is Decimal, the number of digits to the right of the decimal point. Otherwise, this is a null value.
            // If the underlying ODBC driver returns a precision value for a non-numeric data type, this value is used in the schema table.
            metadata.Columns.Add("NumericScale", typeof(int));
            // The name of the catalog in the data store that contains the column. NULL if the base catalog name cannot be determined.
            // The default for this column is a null value.
            metadata.Columns.Add("BaseCatalogName", typeof(string));
            // The name of the schema in the data source that contains the column. NULL if the base catalog name cannot be determined.
            // The default for this column is a null value.
            metadata.Columns.Add("BaseSchemaName", typeof(string));
            // The name of the table or view in the data store that contains the column. A null value if the base table name cannot be determined.
            // The default of this column is a null value.
            metadata.Columns.Add("BaseTableName", typeof(string));
            // The name of the column in the data store. This might be different from the column name returned in the ColumnName column if an alias was used.
            // A null value if the base column name cannot be determined or if the rowset column is derived, but not identical to, a column in the data store.
            // The default for this column is a null value.
            metadata.Columns.Add("BaseColumnName", typeof(string));
            // Maps to the common language runtime type of DbType.
            metadata.Columns.Add("DataType", typeof(Type));
            // The underlying driver type.
            metadata.Columns.Add("ProviderType", typeof(int));
            // true if the column contains a Binary Long Object (BLOB) that contains very long data. The definition of very long data is driver-specific.
            metadata.Columns.Add("IsLong", typeof(bool));
            // true if the column assigns values to new rows in fixed increments; otherwise false. The default for this column is false.
            metadata.Columns.Add("IsAutoIncrement", typeof(bool));
            // true if the column cannot be modified; otherwise false.
            metadata.Columns.Add("IsReadOnly", typeof(bool));
            // true: No two rows in the base table (the table returned in BaseTableName) can have the same value in this column.
            // IsUnique is guaranteed to be true if the column represents a key by itself or if there is a constraint of type UNIQUE that applies only to this column.
            // false: The column can contain duplicate values in the base table. The default for this column is false.
            metadata.Columns.Add("IsUnique", typeof(bool));
            // true: The column is one of a set of columns in the rowset that, taken together, uniquely identify the row.
            // The set of columns with IsKey set to true must uniquely identify a row in the rowset. There is no requirement that this set of columns is a minimal set of columns. This set of columns may be generated from a base table primary key, a unique constraint, or a unique index.
            // false: The column is not required to uniquely identify the row.
            metadata.Columns.Add("IsKey", typeof(bool));
            // Set if the column contains a persistent row identifier that cannot be written to, and has no meaningful value except to identity the row.
            metadata.Columns.Add("IsRowVersion", typeof(bool));
            // true if the consumer can set the column to a null value or if the driver cannot determine whether the consumer can set the column to a null value.
            // Otherwise, false. A column may contain null values, even if it cannot be set to a null value.
            metadata.Columns.Add("AllowDBNull", typeof(bool));

            // The SQLDataReader also returns these columns:
            // Returns a string representing the data type of the specified column.
            metadata.Columns.Add("DataTypeName", typeof(string));
            // true: The column is an identity column.
            // false: The column is not an identity column.
            metadata.Columns.Add("IsIdentity", typeof(bool));
            // true: The column is an expression column.
            // false: The column is not an expression column.
            metadata.Columns.Add("IsExpression", typeof(bool));

            metadata.BeginLoadData();
            for (int n = 0; n < numberColumns; ++n)
            {
                DataRow row = metadata.NewRow();
                row["ColumnOrdinal"] = n;
                // data fields must be read in this exact order!
                row["BaseCatalogName"] = dataStream.getString();
                row["BaseSchemaName"] = dataStream.getString();
                row["BaseTableName"] = dataStream.getString();
                row["BaseColumnName"] = dataStream.getString();
                row["ColumnName"] = dataStream.getString();
                string collationSequence = dataStream.getString();
                row["DataTypeName"] = dataStream.getString();
                row["ProviderType"] = NuoDbConnectionInternal.mapJavaSqlToDbType(dataStream.getInt());
                row["ColumnSize"] = dataStream.getInt();
                row["NumericPrecision"] = dataStream.getInt();
                row["NumericScale"] = dataStream.getInt();
                if (((DbType)row["ProviderType"] == DbType.Int16 || (DbType)row["ProviderType"] == DbType.Int32 || (DbType)row["ProviderType"] == DbType.Int64) &&
                    (int)row["NumericScale"] != 0)
                {
                    row["ProviderType"] = DbType.Decimal;
                }
                row["DataType"] = Type.GetType(NuoDbConnectionInternal.mapNuoDbToNetType((string)row["DataTypeName"], (int)row["NumericPrecision"], (int)row["NumericScale"]));
                int flags = dataStream.getInt();
                const int rsmdSearchable = (1 << 1);
                const int rsmdAutoIncrement = (1 << 2);
                const int rsmdCaseSensitive = (1 << 3);
                const int rsmdCurrency = (1 << 4);
                const int rsmdDefinitelyWritable = (1 << 5);
                const int rsmdWritable = (1 << 6);
                const int rsmdReadOnly = (1 << 7);
                const int rsmdSigned = (1 << 8);
                const int rsmdNullable = (1 << 9);
                row["IsAutoIncrement"] = (flags & rsmdAutoIncrement) != 0;
                row["IsReadOnly"] = (flags & rsmdReadOnly) != 0;
                row["AllowDBNull"] = (flags & rsmdNullable) != 0;
                // for the moment, set the column to be a normal one; later we will look for primary indexes
                row["IsKey"] = row["IsIdentity"] = row["IsUnique"] = false;
                row["IsLong"] = row["IsRowVersion"] = row["IsExpression"] = false;
                metadata.Rows.Add(row);

            #if DEBUG
                System.Diagnostics.Trace.WriteLine("-> " + row["ColumnName"] + ", " +
                                                            row["DataTypeName"] + "(" + row["NumericPrecision"] + "," + row["NumericScale"] + ") " +
                                                            row["DataType"]);
            #endif
            }
            metadata.EndLoadData();
            // fill in the IsPrimary column
            Dictionary<string, DataTable> schemas = new Dictionary<string, DataTable>();
            foreach (DataRow row in metadata.Rows)
            {
                string key = row["BaseSchemaName"] + "|" + row["BaseTableName"];
                DataTable indexInfo = null;
                if (!schemas.ContainsKey(key))
                {
                    indexInfo = connection.GetSchema("IndexColumns", new string[] { null, (string)row["BaseSchemaName"], (string)row["BaseTableName"] });
                    schemas.Add(key, indexInfo);
                }
                else
                    indexInfo = schemas[key];
                DataRow[] rows = indexInfo.Select(String.Format("INDEXCOLUMN_NAME = '{0}' AND INDEXCOLUMN_ISPRIMARY = true", row["BaseColumnName"]));
                if (rows != null && rows.Length > 0)
                {
                    row.BeginEdit();
                    row["IsKey"] = row["IsIdentity"] = true;
                    row.EndEdit();
                }
            }
            return metadata;
        }
        private void doOpen(string hostName)
        {
            string databaseName = parsedConnectionString.Database;

            int index = hostName.IndexOf(':');
            int port = PORT;
            if (index != -1)
            {
                try
                {
                    port = Int32.Parse(hostName.Substring(index + 1));
                }
                catch (FormatException e)
                {
                    throw new ArgumentException("Invalid port number in connection string", "ConnectionString", e);
                }
                hostName = hostName.Substring(0, index);
            }
            dataStream = new EncodedDataStream();
            authenticating = false;

            try
            {
                StringDictionary properties = new StringDictionary();
                Tag tag = new Tag("Connection");
                tag.addAttribute("Service", "SQL2");
                tag.addAttribute("Database", databaseName);
                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.ServerKey))
                {
                    tag.addAttribute("Server", parsedConnectionString.Server);
                    properties["Server"] = parsedConnectionString.Server;
                }
                string userName = null;
                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.UserKey))
                {
                    properties["User"] = userName = parsedConnectionString.User;
                    tag.addAttribute("User", userName);
                }

                string password = null;
                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.PasswordKey))
                {
                    password = parsedConnectionString.Password;
                }

                string cipher = DEFAULT_CIPHER;
                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.SchemaKey))
                {
                    tag.addAttribute("Schema", parsedConnectionString.Schema);
                    properties["Schema"] = parsedConnectionString.Schema;
                }
                // see comment below ... for now these are the only two types that
                // we can support in the client code
                if ((!cipher.Equals("RC4")) && (!cipher.Equals("None")))
                    throw new NuoDbSqlException("Unknown cipher: " + cipher);
                tag.addAttribute("Cipher", cipher);

                string xml = tag.ToString();
                CryptoSocket brokerSocket = new CryptoSocket(hostName, port);
                inputStream = brokerSocket.InputStream;
                outputStream = brokerSocket.OutputStream;

                dataStream.write(xml);
                dataStream.send(outputStream);

                dataStream.getMessage(inputStream);
                string response = dataStream.readString();
                brokerSocket.Close();
                Tag responseTag = new Tag();
                responseTag.parse(response);

                if (responseTag.Name.Equals("Error"))
                {
                    throw new NuoDbSqlException(responseTag.getAttribute("text", "error text not found"));
                }

                serverAddress = responseTag.getAttribute("Address", null);
                serverPort = responseTag.getIntAttribute("Port", 0);

                if (serverAddress == null || serverPort == 0)
                {
                    throw new NuoDbSqlException("no NuoDB nodes are available for database \"" + databaseName + "\"");
                }

                socket = new CryptoSocket(serverAddress, serverPort);
                //socket.TcpNoDelay = true;
                inputStream = socket.InputStream;
                outputStream = socket.OutputStream;
                dataStream.reset();
                dataStream.write(xml);
                dataStream.send(outputStream);

                RemotePassword remotePassword = new RemotePassword();
                string userKey = remotePassword.genClientKey();

                dataStream.startMessage(Protocol.OpenDatabase);
                dataStream.encodeInt(Protocol.PROTOCOL_VERSION);
                dataStream.encodeString(databaseName);

                getProcessConnection(databaseName);
                string dbUUId = processConnection.DatabaseUUId.ToString();

                // see if the app set the TimeZone. If so, it will be sent to the server
                // so set the local TZ to be the same. If not, send the current default
                // TZ  to the server. (Of course, this affects this connection only)
                /*
                                String timeZone = properties.getProperty(TIMEZONE_NAME);

                                if (timeZone == null)
                                {
                                    // Save the default at the time the connection was opened
                                    TimeZone tz = TimeZone.getDefault();
                                    sqlContext.setTimeZone(tz);
                                    sqlContext.setTimeZoneId(tz.getID());
                                    properties.setProperty(TIMEZONE_NAME, tz.getID());
                                }
                                else
                                {
                                    TimeZone tz = TimeZone.getTimeZone(timeZone);
                                    sqlContext.setTimeZone(tz);
                                    sqlContext.setTimeZoneId(tz.getID());
                                }
                */
                int count = properties.Count + 1 + ((dbUUId == null) ? 0 : 1); // Add LastCommitInfo and DatabaseUUId

                dataStream.encodeInt(count);
                foreach (DictionaryEntry property in properties)
                {
                    string name = (string)property.Key;
                    string value = (string)property.Value;
                    dataStream.encodeString(name);
                    dataStream.encodeString(value);
                }

                // LastCommitInfo and DatabaseUUId are sent as properties. This avoids sending another
                // message and keeps them from being protocol version sensitive

                string lastCommitParam = getProcessConnection(databaseName).getLastCommitInfo();
                dataStream.encodeString("LastCommitInfo");
                dataStream.encodeString(lastCommitParam);

                if (dbUUId != null)
                {
                    dataStream.encodeString("DatabaseUUId");
                    dataStream.encodeString(dbUUId);
                }

                // This  would have been the last commit txn id if that scheme was ever fully
                // implemented but it wasn't and this is now obsolete. keep it for compatibility with older servers

                dataStream.encodeLong(0);
                dataStream.encodeString(userKey);
                sendAndReceive(dataStream);

                protocolVersion = dataStream.getInt();
                string serverKey = dataStream.getString();
                string salt = dataStream.getString();
                dataStream.ProtocolVersion = protocolVersion;

                if (protocolVersion >= Protocol.PROTOCOL_VERSION5)
                {
                    processConnection.DatabaseUUId = dataStream.getUUId();
                }

                string upperUserName = userName.ToUpper();
                byte[] key = remotePassword.computeSessionKey(upperUserName, password, salt, serverKey);

                // NOTE: unlike the C++ implementation we only support RC4 in .NET
                // and it's a hard-coded class (instead of the factory interface
                // on the C++ CryptoSocket) so there's no checking to see which
                // cipher was requested here

                inputStream.encrypt(new CipherRC4(key));
                outputStream.encrypt(new CipherRC4(key));

                dataStream.startMessage(Protocol.Authentication);
                dataStream.encodeString("Success!");
                authenticating = true;
                sendAndReceive(dataStream);

                // if the caller requested a cipher of None and we got here then the
                // server accpeted it and expects us to disable crypto now

                if (cipher.Equals("None"))
                {
                    inputStream.encrypt(null);
                    outputStream.encrypt(null);
                }
            }
            catch (NuoDbSqlException e)
            {
            #if DEBUG
                System.Diagnostics.Trace.WriteLine("NuoDBConnection::doOpen(): exception " + e.ToString());
            #endif
                if (authenticating)
                {
                    throw new NuoDbSqlException("Authentication failed for database \"" + databaseName + "\"", e);
                }

                throw e;
            }
            catch (IOException exception)
            {
            #if DEBUG
                System.Diagnostics.Trace.WriteLine("NuoDBConnection::doOpen(): exception " + exception.ToString());
            #endif
                if (socket != null && socket.Connected)
                {
                    try
                    {
                        socket.Close();
                        socket = null;
                    }
                    catch (IOException)
                    {
                        // just ignore
                    }
                }

                throw new NuoDbSqlException(exception.ToString());
            }
            catch (XmlException exception)
            {
            #if DEBUG
                System.Diagnostics.Trace.WriteLine("NuoDBConnection::doOpen(): exception " + exception.ToString());
            #endif
                if (socket != null && socket.Connected)
                {
                    try
                    {
                        socket.Close();
                        socket = null;
                    }
                    catch (IOException)
                    {
                        // just ignore
                    }
                }

                throw new NuoDbSqlException(exception.ToString());
            }
        }
        internal void sendAndReceive(EncodedDataStream stream)
        {
            try
            {
                lock (this)
                {
                    stream.send(outputStream);
                    stream.getMessage(inputStream);
                    int status = stream.getInt();

                    if (status != 0)
                    {
                        string message = stream.getString();
                        string sqlState = "";

                        if (protocolVersion >= Protocol.PROTOCOL_VERSION2)
                        {
                            sqlState = stream.getString();
                        }

                        // If empty string, use the state from NuoDbSqlCode

                        if (StringUtils.size(sqlState) == 0)
                        {
                            sqlState = NuoDbSqlCode.FindSQLState(status);
                        }

                        throw new NuoDbSqlException(message, sqlState, status);
                    }
                }
            }
            catch (IOException exception)
            {
                throw new NuoDbSqlException(exception);
            }
        }
        private void doOpen(string hostName)
        {
            networkErrorOccurred = false;
            string databaseName = parsedConnectionString.Database;

            int index = hostName.IndexOf(':');
            int port = PORT;
            if (index != -1)
            {
                try
                {
                    port = Int32.Parse(hostName.Substring(index + 1));
                }
                catch (FormatException e)
                {
                    throw new ArgumentException("Invalid port number in connection string", "ConnectionString", e);
                }
                hostName = hostName.Substring(0, index);
            }
            dataStream = new EncodedDataStream();
            authenticating = false;

            try
            {
                StringDictionary properties = new StringDictionary();
                Tag tag = new Tag("Connection");
                tag.addAttribute("Service", "SQL2");
                tag.addAttribute("Database", databaseName);
                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.ServerKey))
                {
                    tag.addAttribute("Server", parsedConnectionString.Server);
                    properties["Server"] = parsedConnectionString.Server;
                }
                string userName = null;
                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.UserKey))
                {
                    properties["User"] = userName = parsedConnectionString.User;
                    tag.addAttribute("User", userName);
                }
                else
                {
                    throw new ArgumentException("Username is missing in connection string", "ConnectionString");
                }

                string password = "";
                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.PasswordKey))
                {
                    password = parsedConnectionString.Password;
                }

                string cipher = DEFAULT_CIPHER;
                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.CipherKey))
                {
                    properties["Cipher"] = cipher = parsedConnectionString.Cipher;
                }
                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.SchemaKey))
                {
                    tag.addAttribute("Schema", parsedConnectionString.Schema);
                    properties["Schema"] = parsedConnectionString.Schema;
                }

                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.LBTagKey))
                {
                    properties["LBTag"] = parsedConnectionString.LBTag;
                }
                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.ClientInfoKey))
                {
                    properties["clientInfo"] = parsedConnectionString.ClientInfo;
                }
                properties["clientProcessID"] = Process.GetCurrentProcess().Id.ToString();
                // see comment below ... for now these are the only two types that
                // we can support in the client code
                if ((!cipher.Equals("RC4")) && (!cipher.Equals("None")))
                    throw new NuoDbSqlException("Unknown cipher: " + cipher);
                tag.addAttribute("Cipher", cipher);

                string xml = tag.ToString();
                CryptoSocket brokerSocket = new CryptoSocket(hostName, port);
                inputStream = brokerSocket.InputStream;
                outputStream = brokerSocket.OutputStream;

                dataStream.write(xml);
                dataStream.send(outputStream);

                dataStream.getMessage(inputStream);
                string response = dataStream.readString();
                brokerSocket.Close();
                Tag responseTag = new Tag();
                responseTag.parse(response);

                if (responseTag.Name.Equals("Error"))
                {
                    throw new NuoDbSqlException(responseTag.getAttribute("text", "error text not found"));
                }

                serverAddress = responseTag.getAttribute("Address", null);
                serverPort = responseTag.getIntAttribute("Port", 0);

                if (serverAddress == null || serverPort == 0)
                {
                    throw new NuoDbSqlException("no NuoDB nodes are available for database \"" + databaseName + "\"");
                }

                socket = new CryptoSocket(serverAddress, serverPort);
                //socket.TcpNoDelay = true;
                inputStream = socket.InputStream;
                outputStream = socket.OutputStream;
                dataStream.reset();
                dataStream.write(xml);
                dataStream.send(outputStream);

                RemotePassword remotePassword = new RemotePassword();
                string userKey = remotePassword.genClientKey();

                dataStream.startMessage(Protocol.OpenDatabase);
                dataStream.encodeInt(Protocol.PROTOCOL_VERSION);
                dataStream.encodeString(databaseName);

                getProcessConnection(databaseName);
                string dbUUId = processConnection.DatabaseUUId.ToString();

            #if __MonoCS__
                // On Mono, timezone support is too much platform dependent
                sqlContext.TimeZone = TimeZoneInfo.Local;
            #else
                // see if the app set the TimeZone. If so, it will be sent to the server
                // so set the local TZ to be the same. If not, send the current default
                // TZ  to the server. (Of course, this affects this connection only)
                if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.TimeZoneKey))
                {
                    string tzone = parsedConnectionString.TimeZone;
                    properties["TimeZone"] = tzone;
                    sqlContext.TimeZone = OlsonDatabase.FindWindowsTimeZone(tzone);
                }
                else
                {
                    // Save the default at the time the connection was opened
                    string tzone = TimeZoneInfo.Local.Id;
                    properties["TimeZone"] = OlsonDatabase.FindOlsonTimeZone(tzone);
                    // As described in http://msdn.microsoft.com/en-us/library/system.timezoneinfo.local.aspx TimeZoneInfo.Local
                    // always applies the DST setting of the current time, even if the DST settings of the tested date used different
                    // rules; so we fetch the complete definition from the database
                    sqlContext.TimeZone = TimeZoneInfo.FindSystemTimeZoneById(tzone);
                }
            #endif

                int count = properties.Count + 1 + ((dbUUId == null) ? 0 : 1); // Add LastCommitInfo and DatabaseUUId

                dataStream.encodeInt(count);
                foreach (DictionaryEntry property in properties)
                {
                    string name = (string)property.Key;
                    string value = (string)property.Value;
                    dataStream.encodeString(name);
                    dataStream.encodeString(value);
                }

                // LastCommitInfo and DatabaseUUId are sent as properties. This avoids sending another
                // message and keeps them from being protocol version sensitive

                string lastCommitParam = getProcessConnection(databaseName).getLastCommitInfo();
                dataStream.encodeString("LastCommitInfo");
                dataStream.encodeString(lastCommitParam);

                if (dbUUId != null)
                {
                    dataStream.encodeString("DatabaseUUId");
                    dataStream.encodeString(dbUUId);
                }

                // This  would have been the last commit txn id if that scheme was ever fully
                // implemented but it wasn't and this is now obsolete. keep it for compatibility with older servers

                dataStream.encodeLong(0);
                dataStream.encodeString(userKey);
                sendAndReceive(dataStream);

                protocolVersion = dataStream.getInt();
                string serverKey = dataStream.getString();
                string salt = dataStream.getString();
                dataStream.ProtocolVersion = protocolVersion;

                if (protocolVersion >= Protocol.PROTOCOL_VERSION5)
                {
                    processConnection.DatabaseUUId = dataStream.getUUId();
                }

                string upperUserName = userName.ToUpper();
                byte[] key = remotePassword.computeSessionKey(upperUserName, password, salt, serverKey);

                // NOTE: unlike the C++ implementation we only support RC4 in .NET
                // and it's a hard-coded class (instead of the factory interface
                // on the C++ CryptoSocket) so there's no checking to see which
                // cipher was requested here

                inputStream.encrypt(new CipherRC4(key));
                outputStream.encrypt(new CipherRC4(key));

                dataStream.startMessage(Protocol.Authentication);
                dataStream.encodeString("Success!");
                authenticating = true;
                sendAndReceive(dataStream);

                // if the caller requested a cipher of None and we got here then the
                // server accepted it and expects us to disable crypto now

                if (cipher.Equals("None"))
                {
                    inputStream.encrypt(null);
                    outputStream.encrypt(null);
                }
            }
            catch (NuoDbSqlException e)
            {
            #if DEBUG
                System.Diagnostics.Trace.WriteLine("NuoDBConnection::doOpen(): exception " + e.ToString());
            #endif
                if (authenticating)
                {
                    throw new NuoDbSqlException("Authentication failed for database \"" + databaseName + "\"");
                }

                throw e;
            }
            catch (IOException exception)
            {
            #if DEBUG
                System.Diagnostics.Trace.WriteLine("NuoDBConnection::doOpen(): exception " + exception.ToString());
            #endif
                networkErrorOccurred = true;
                if (socket != null && socket.Connected)
                {
                    try
                    {
                        socket.Close();
                        socket = null;
                    }
                    catch (IOException)
                    {
                        // just ignore
                    }
                }

                throw new NuoDbSqlException(exception.ToString());
            }
            catch (XmlException exception)
            {
            #if DEBUG
                System.Diagnostics.Trace.WriteLine("NuoDBConnection::doOpen(): exception " + exception.ToString());
            #endif
                if (socket != null && socket.Connected)
                {
                    try
                    {
                        socket.Close();
                        socket = null;
                    }
                    catch (IOException)
                    {
                        // just ignore
                    }
                }

                throw new NuoDbSqlException(exception.ToString());
            }

            if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.ApplicationIntentKey))
            {
                string applicationIntent = parsedConnectionString.ApplicationIntent;
                if (applicationIntent.Equals("ReadOnly", StringComparison.InvariantCultureIgnoreCase))
                {
                    dataStream.startMessage(Protocol.SetReadOnly);
                    dataStream.encodeBoolean(true);
                    sendAsync(dataStream);
                }
            }
            if (parsedConnectionString.ContainsKey(NuoDbConnectionStringBuilder.IsolationLevelKey))
            {
                string isolationLevel = parsedConnectionString.IsolationLevel;
                int level = 0;
                if (isolationLevel.Equals("ReadCommitted", StringComparison.InvariantCultureIgnoreCase))
                {
                    // static const int TRANSACTION_READ_COMMITTED    = 2;
                    level = 2;
                }
                else if (isolationLevel.Equals("Serializable", StringComparison.InvariantCultureIgnoreCase))
                {
                    // static const int TRANSACTION_SERIALIZABLE      = 8;
                    level = 8;
                }
                else if (isolationLevel.Equals("WriteCommitted", StringComparison.InvariantCultureIgnoreCase))
                {
                    // static const int TRANSACTION_WRITE_COMMITTED   = 5;
                    level = 5;
                }
                else if (isolationLevel.Equals("ConsistentRead", StringComparison.InvariantCultureIgnoreCase))
                {
                    // static const int TRANSACTION_CONSISTENT_READ   = 7;
                    level = 7;
                }
                else
                {
                    throw new NuoDbSqlException("\"" + isolationLevel + "\" is not a valid isolation level");
                }
                dataStream.startMessage(Protocol.SetTransactionIsolation);
                dataStream.encodeInt(level);
                sendAndReceive(dataStream);
            }
        }