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