예제 #1
0
        /// <summary>
        /// Parses the connection data.
        /// </summary>
        /// <param name="connectionData">The connection string or connection URI.</param>
        /// <returns>An updated connection string representation of the provided connection string or connection URI.</returns>
        protected internal string ParseConnectionData(string connectionData)
        {
            FailoverManager.Reset();

            if (Regex.IsMatch(connectionData, @"^mysqlx(\+\w+)?://.*", RegexOptions.IgnoreCase))
            {
                return(ParseConnectionUri(connectionData));
            }
            else
            {
                return(ParseConnectionString(connectionData));
            }
        }
예제 #2
0
        /// <summary>
        /// Parses the connection string.
        /// </summary>
        /// <param name="connectionString">The connection string in basic or URI format.</param>
        /// <returns>An updated connection string in basic format.</returns>
        /// <remarks>The format (basic or URI) of the connection string is determined as well as the
        /// prescence of multiple hosts.</remarks>
        protected internal string ParseConnectionString(string connectionString)
        {
            FailoverManager.Reset();

            // Connection string is in URI format.
            if (Regex.IsMatch(connectionString, @"^mysqlx(\+\w+)?://.*", RegexOptions.IgnoreCase))
            {
                return(ParseUriConnectionString(connectionString));
            }
            else
            {
                return(ParseBasicConnectionString(connectionString));
            }
        }
예제 #3
0
        /// <include file='docs/MySqlConnection.xml' path='docs/Close/*'/>
        public override void Close()
        {
            if (driver != null)
            {
                driver.IsPasswordExpired = false;
            }

            if (State == ConnectionState.Closed)
            {
                return;
            }

            if (Reader != null)
            {
                Reader.Close();
            }

            // if the reader was opened with CloseConnection then driver
            // will be null on the second time through
            if (driver != null)
            {
                //TODO: Add support for 452 and 46X
                if (driver.currentTransaction == null)
                {
                    CloseFully();
                }
                //TODO: Add support for 452 and 46X
                else
                {
                    driver.IsInActiveUse = false;
                }
            }

            if (Settings.ConnectionProtocol == MySqlConnectionProtocol.Tcp && Settings.IsSshEnabled())
            {
                _sshHandler?.StopClient();
            }

            FailoverManager.Reset();
            MySqlPoolManager.Hosts = null;

            SetState(ConnectionState.Closed, true);
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the BaseSession class based on the specified anonymous type object.
        /// </summary>
        /// <param name="connectionData">The connection data as an anonymous type used to create the session.</param>
        /// <param name="client">A <see cref="Client"/> object.</param>
        /// <exception cref="ArgumentNullException"><paramref name="connectionData"/> is null.</exception>
        /// <remarks>
        /// <para>Multiple hosts can be specified as part of the <paramref name="connectionData"/>, which enables client-side failover when trying to
        /// establish a connection.</para>
        /// <para>&#160;</para>
        /// <para>To assign multiple hosts, create a property similar to the connection string examples shown in
        /// <see cref="BaseSession(string)"/>. Note that the value of the property must be a string.
        /// </para>
        /// </remarks>
        internal BaseSession(object connectionData, Client client = null) : this()
        {
            if (connectionData == null)
            {
                throw new ArgumentNullException("connectionData");
            }

            _client = client;
            if (client == null)
            {
                FailoverManager.Reset();
            }

            var values = Tools.GetDictionaryFromAnonymous(connectionData);

            if (!values.Keys.Any(s => s.ToLowerInvariant() == PORT_CONNECTION_OPTION_KEYWORD))
            {
                values.Add(PORT_CONNECTION_OPTION_KEYWORD, X_PROTOCOL_DEFAULT_PORT);
            }

            bool hostsParsed = false;

            foreach (var value in values)
            {
                if (!Settings.ContainsKey(value.Key))
                {
                    throw new KeyNotFoundException(string.Format(ResourcesX.InvalidConnectionStringAttribute, value.Key));
                }

                Settings.SetValue(value.Key, value.Value);
                if (!hostsParsed && !string.IsNullOrEmpty(Settings[SERVER_CONNECTION_OPTION_KEYWORD].ToString()))
                {
                    var server = value.Value.ToString();
                    if (IsUnixSocket(server))
                    {
                        Settings.SetValue(value.Key, server = NormalizeUnixSocket(server));
                    }

                    FailoverManager.ParseHostList(server, true, false);
                    if (FailoverManager.FailoverGroup != null && FailoverManager.FailoverGroup.Hosts?.Count > 1)
                    {
                        Settings[SERVER_CONNECTION_OPTION_KEYWORD] = null;
                    }
                    else if (FailoverManager.FailoverGroup != null)
                    {
                        Settings[SERVER_CONNECTION_OPTION_KEYWORD] = FailoverManager.FailoverGroup.Hosts[0].Host;
                    }

                    hostsParsed = true;
                }
            }
            this._connectionString = Settings.ToString();

            Settings.AnalyzeConnectionString(this._connectionString, true, _isDefaultPort);
            if (FailoverManager.FailoverGroup != null && FailoverManager.FailoverGroup.Hosts?.Count > 1)
            {
                // Multiple hosts were specified.
                _internalSession          = FailoverManager.AttemptConnectionXProtocol(this._connectionString, out this._connectionString, _isDefaultPort, client);
                Settings.ConnectionString = _connectionString;
            }
            else
            {
                if (Settings.DnsSrv)
                {
                    var dnsSrvRecords = DnsResolver.GetDnsSrvRecords(Settings.Server);
                    FailoverManager.SetHostList(dnsSrvRecords.ConvertAll(r => new FailoverServer(r.Target, r.Port, null)),
                                                FailoverMethod.Sequential);
                    _internalSession          = FailoverManager.AttemptConnectionXProtocol(this._connectionString, out this._connectionString, _isDefaultPort, client);
                    Settings.ConnectionString = this._connectionString;
                }
                else
                {
                    _internalSession = InternalSession.GetSession(Settings);
                }
            }

            if (!string.IsNullOrWhiteSpace(Settings.Database))
            {
                DefaultSchema = GetSchema(Settings.Database);
            }
        }
예제 #5
0
        /// <include file='docs/MySqlConnection.xml' path='docs/Open/*'/>
        public override void Open()
        {
            if (State == ConnectionState.Open)
            {
                Throw(new InvalidOperationException(Resources.ConnectionAlreadyOpen));
            }

            // start up our interceptors
            _exceptionInterceptor = new ExceptionInterceptor(this);
            commandInterceptor    = new CommandInterceptor(this);

            SetState(ConnectionState.Connecting, true);

            AssertPermissions();

            //TODO: SUPPORT FOR 452 AND 46X
            // if we are auto enlisting in a current transaction, then we will be
            // treating the connection as pooled
            if (Settings.AutoEnlist && Transaction.Current != null)
            {
                driver = DriverTransactionManager.GetDriverInTransaction(Transaction.Current);
                if (driver != null &&
                    (driver.IsInActiveUse ||
                     !driver.Settings.EquivalentTo(this.Settings)))
                {
                    Throw(new NotSupportedException(Resources.MultipleConnectionsInTransactionNotSupported));
                }
            }

            MySqlConnectionStringBuilder currentSettings = Settings;

            try
            {
                if (Settings.ConnectionProtocol == MySqlConnectionProtocol.Tcp && Settings.IsSshEnabled())
                {
                    _sshHandler = new Ssh(
                        Settings.SshHostName,
                        Settings.SshUserName,
                        Settings.SshPassword,
                        Settings.SshKeyFile,
                        Settings.SshPassphrase,
                        Settings.SshPort,
                        Settings.Server,
                        Settings.Port,
                        false
                        );
                    _sshHandler.StartClient();
                }

                if (!Settings.Pooling || MySqlPoolManager.Hosts == null)
                {
                    FailoverManager.Reset();

                    if (Settings.DnsSrv)
                    {
                        var dnsSrvRecords = DnsResolver.GetDnsSrvRecords(Settings.Server);
                        FailoverManager.SetHostList(dnsSrvRecords.ConvertAll(r => new FailoverServer(r.Target, r.Port, null)),
                                                    FailoverMethod.Sequential);
                    }
                    else
                    {
                        FailoverManager.ParseHostList(Settings.Server, false);
                    }
                }

                // Load balancing && Failover
                if (ReplicationManager.IsReplicationGroup(Settings.Server))
                {
                    if (driver == null)
                    {
                        ReplicationManager.GetNewConnection(Settings.Server, false, this);
                    }
                    else
                    {
                        currentSettings = driver.Settings;
                    }
                }
                else if (FailoverManager.FailoverGroup != null && !Settings.Pooling)
                {
                    FailoverManager.AttemptConnection(this, Settings.ConnectionString, out string connectionString);
                    currentSettings.ConnectionString = connectionString;
                }

                if (Settings.Pooling)
                {
                    if (FailoverManager.FailoverGroup != null)
                    {
                        FailoverManager.AttemptConnection(this, Settings.ConnectionString, out string connectionString, true);
                        currentSettings.ConnectionString = connectionString;
                    }

                    MySqlPool pool = MySqlPoolManager.GetPool(currentSettings);
                    if (driver == null || !driver.IsOpen)
                    {
                        driver = pool.GetConnection();
                    }
                    ProcedureCache = pool.ProcedureCache;
                }
                else
                {
                    if (driver == null || !driver.IsOpen)
                    {
                        driver = Driver.Create(currentSettings);
                    }
                    ProcedureCache = new ProcedureCache((int)Settings.ProcedureCacheSize);
                }
            }
            catch (Exception)
            {
                SetState(ConnectionState.Closed, true);
                throw;
            }

            SetState(ConnectionState.Open, false);
            driver.Configure(this);

            if (driver.IsPasswordExpired && Settings.Pooling)
            {
                MySqlPoolManager.ClearPool(currentSettings);
            }

            if (!(driver.SupportsPasswordExpiration && driver.IsPasswordExpired))
            {
                if (!string.IsNullOrEmpty(Settings.Database))
                {
                    ChangeDatabase(Settings.Database);
                }
            }

            // setup our schema provider
            _schemaProvider = new ISSchemaProvider(this);
            PerfMonitor     = new PerformanceMonitor(this);

            // if we are opening up inside a current transaction, then autoenlist
            // TODO: control this with a connection string option
            if (Transaction.Current != null && Settings.AutoEnlist)
            {
                EnlistTransaction(Transaction.Current);
            }

            hasBeenOpen = true;
            SetState(ConnectionState.Open, true);
        }