private static string GetKey(MyCatConnectionStringBuilder settings)
        {
            string key = "";

            lock (settings)
            {
                key = settings.ConnectionString;
            }
#if !NETSTANDARD1_3
            if (settings.IntegratedSecurity && !settings.ConnectionReset)
            {
                try
                {
                    // Append SID to the connection string to generate a key
                    // With Integrated security different Windows users with the same
                    // connection string may be mapped to different MySQL accounts.
                    System.Security.Principal.WindowsIdentity id =
                        System.Security.Principal.WindowsIdentity.GetCurrent();

                    key += ";" + id.User;
                }
                catch (System.Security.SecurityException ex)
                {
                    // Documentation for WindowsIdentity.GetCurrent() states
                    // SecurityException can be thrown. In this case the
                    // connection can only be pooled if reset is done.
                    throw new MyCatException(Resources.NoWindowsIdentity, ex);
                }
            }
#endif
            return(key);
        }
        public static MyNetworkStream CreateStream(MyCatConnectionStringBuilder settings, bool unix)
        {
            MyNetworkStream stream = null;

            IPAddress[] ipHE = GetHostEntry(settings.Server);
            foreach (IPAddress address in ipHE)
            {
                try
                {
                    stream = CreateSocketStream(settings, address, unix);
                    if (stream != null)
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    SocketException socketException = ex as SocketException;
                    // if the exception is a ConnectionRefused then we eat it as we may have other address
                    // to attempt
                    if (socketException == null)
                    {
                        throw;
                    }
                    if (socketException.SocketErrorCode != SocketError.ConnectionRefused)
                    {
                        throw;
                    }
                }
            }
            return(stream);
        }
        private static MyNetworkStream CreateSocketStream(MyCatConnectionStringBuilder settings, IPAddress ip, bool unix)
        {
            EndPoint endPoint;

            endPoint = new IPEndPoint(ip, (int)settings.Port);

            Socket socket = unix ?
                            new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) :
                            new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            if (settings.Keepalive > 0)
            {
                SetKeepAlive(socket, settings.Keepalive);
            }

            try
            {
                socket.Connect(endPoint);
            }
            catch (Exception ex)
            {
#if !NETSTANDARD1_3
                socket.Close();
#else
                socket.Dispose();
#endif
                throw ex;
            }

            MyNetworkStream stream = new MyNetworkStream(socket, true);
            GC.SuppressFinalize(socket);
            GC.SuppressFinalize(stream);
            return(stream);
        }
Example #4
0
 internal void Serialize(MyCatPacket packet, bool binary, MyCatConnectionStringBuilder settings)
 {
     if (!binary && (paramValue == null || paramValue == DBNull.Value))
     {
         packet.WriteStringNoNull("NULL");
     }
     else
     {
         if (ValueObject.MyCatDbType == MyCatDbType.Guid)
         {
             MyCatGuid g = (MyCatGuid)ValueObject;
             g.OldGuids  = settings.OldGuids;
             ValueObject = g;
         }
         if (ValueObject.MyCatDbType == MyCatDbType.Geometry)
         {
             MyCatGeometry v = (MyCatGeometry)ValueObject;
             if (v.IsNull && Value != null)
             {
                 MyCatGeometry.TryParse(Value.ToString(), out v);
             }
             ValueObject = v;
         }
         ValueObject.WriteValue(packet, binary, paramValue, Size);
     }
 }
Example #5
0
        private static Stream GetSharedMemoryStream(MyCatConnectionStringBuilder settings)
        {
            SharedMemoryStream str = new SharedMemoryStream(settings.SharedMemoryName);

            str.Open(settings.ConnectionTimeout);
            return(str);
        }
Example #6
0
        /// <summary>
        /// Assigns a new server driver to the connection object
        /// </summary>
        /// <param name="groupName">Group name</param>
        /// <param name="master">True if the server connection to assign must be a master</param>
        /// <param name="connection">MyCatConnection object where the new driver will be assigned</param>
        internal static void GetNewConnection(string groupName, bool master, MyCatConnection connection)
        {
            do
            {
                lock (thisLock)
                {
                    if (!IsReplicationGroup(groupName))
                    {
                        return;
                    }

                    ReplicationServerGroup group  = GetGroup(groupName);
                    ReplicationServer      server = group.GetServer(master, connection.Settings);

                    if (server == null)
                    {
                        throw new MyCatException(Properties.Resources.Replication_NoAvailableServer);
                    }

                    try
                    {
                        bool isNewServer = false;
                        if (connection.driver == null || !connection.driver.IsOpen)
                        {
                            isNewServer = true;
                        }
                        else
                        {
                            MyCatConnectionStringBuilder msb = new MyCatConnectionStringBuilder(server.ConnectionString);
                            if (!msb.Equals(connection.driver.Settings))
                            {
                                isNewServer = true;
                            }
                        }
                        if (isNewServer)
                        {
                            Driver driver = Driver.Create(new MyCatConnectionStringBuilder(server.ConnectionString));
                            connection.driver = driver;
                        }
                        return;
                    }
                    catch (MyCatException ex)
                    {
                        connection.driver  = null;
                        server.IsAvailable = false;
                        MyCatTrace.LogError(ex.Number, ex.ToString());
                        if (ex.Number == 1042)
                        {
                            // retry to open a failed connection and update its status
                            group.HandleFailover(server, ex);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            } while (true);
        }
Example #7
0
        public void ParseConnectionString()
        {
            var csb = new MyCatConnectionStringBuilder
            {
                ConnectionString = "Data Source=db-server;" +
                                   "Initial Catalog=schema_name;" +
                                   "Allow User Variables=true;" +
                                   "certificate file=file.pfx;" +
                                   "certificate password=Pass1234;" +
                                   "Character Set=latin1;" +
                                   "Compress=true;" +
                                   "connect timeout=30;" +
                                   "ConnectionReset=false;" +
                                   "Convert Zero Datetime=true;" +
#if !BASELINE
                                   "forcesynchronous=true;" +
#endif
                                   "Keep Alive=90;" +
                                   "minpoolsize=5;" +
                                   "maxpoolsize=15;" +
                                   "OldGuids=true;" +
                                   "persistsecurityinfo=yes;" +
                                   "Pooling=no;" +
                                   "Port=1234;" +
                                   "pwd=Pass1234;" +
                                   "Treat Tiny As Boolean=false;" +
                                   "ssl mode=verifyca;" +
                                   "Uid=username;" +
                                   "useaffectedrows=false"
            };

            Assert.Equal(true, csb.AllowUserVariables);
            Assert.Equal("file.pfx", csb.CertificateFile);
            Assert.Equal("Pass1234", csb.CertificatePassword);
            Assert.Equal("latin1", csb.CharacterSet);
            Assert.Equal(false, csb.ConnectionReset);
            Assert.Equal(30u, csb.ConnectionTimeout);
            Assert.Equal(true, csb.ConvertZeroDateTime);
            Assert.Equal("schema_name", csb.Database);
#if !BASELINE
            Assert.Equal(true, csb.ForceSynchronous);
#endif
            Assert.Equal(90u, csb.Keepalive);
            Assert.Equal(15u, csb.MaximumPoolSize);
            Assert.Equal(5u, csb.MinimumPoolSize);
            Assert.Equal("Pass1234", csb.Password);
            Assert.Equal(true, csb.OldGuids);
            Assert.Equal(true, csb.PersistSecurityInfo);
            Assert.Equal(false, csb.Pooling);
            Assert.Equal(1234u, csb.Port);
            Assert.Equal("db-server", csb.Server);
            Assert.Equal(false, csb.TreatTinyAsBoolean);
            Assert.Equal(MyCatSslMode.VerifyCA, csb.SslMode);
            Assert.Equal(false, csb.UseAffectedRows);
            Assert.Equal(true, csb.UseCompression);
            Assert.Equal("username", csb.UserID);
        }
Example #8
0
        private static Stream GetUnixSocketStream(MyCatConnectionStringBuilder settings)
        {
            if (Platform.IsWindows())
            {
                throw new InvalidOperationException(Resources.NoUnixSocketsOnWindows);
            }

            MyNetworkStream s = MyNetworkStream.CreateStream(settings, true);

            return(s);
        }
Example #9
0
        public static Stream GetStream(string server, uint port, string pipename, uint keepalive, DBVersion v, uint timeout)
        {
            MyCatConnectionStringBuilder settings = new MyCatConnectionStringBuilder();

            settings.Server            = server;
            settings.Port              = port;
            settings.PipeName          = pipename;
            settings.Keepalive         = keepalive;
            settings.ConnectionTimeout = timeout;
            return(GetStream(settings));
        }
Example #10
0
 public Driver(MyCatConnectionStringBuilder settings)
 {
     encoding = Encoding.UTF8;
     if (encoding == null)
     {
         throw new MyCatException(Resources.DefaultEncodingNotFound);
     }
     connectionString   = settings;
     serverCharSet      = "utf8";
     serverCharSetIndex = -1;
     maxPacketSize      = 1024;
     handler            = new NativeDriver(this);
 }
Example #11
0
        public MyCatRelationalConnection CreateMasterConnection()
        {
            var csb = new MyCatConnectionStringBuilder(ConnectionString)
            {
                Database = "mysql",
                Pooling  = false
            };

            var optionsBuilder = new DbContextOptionsBuilder();

            optionsBuilder.UseMyCat(csb.GetConnectionString(true));
            return(new MyCatRelationalConnection(optionsBuilder.Options, Logger));
        }
        public ConnectionSettings(MyCatConnectionStringBuilder csb)
        {
            ConnectionString = csb.ConnectionString;

            // Base Options
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && (csb.Server.StartsWith("/", StringComparison.Ordinal) || csb.Server.StartsWith("./", StringComparison.Ordinal)))
            {
                if (!File.Exists(csb.Server))
                {
                    throw new MyCatException("Cannot find Unix Socket at " + csb.Server);
                }
                ConnectionType = ConnectionType.Unix;
                UnixSocket     = Path.GetFullPath(csb.Server);
            }
            else
            {
                ConnectionType = ConnectionType.Tcp;
                Hostnames      = csb.Server.Split(',');
                Port           = (int)csb.Port;
            }
            UserID   = csb.UserID;
            Password = csb.Password;
            Database = csb.Database;

            // SSL/TLS Options
            SslMode             = csb.SslMode;
            CertificateFile     = csb.CertificateFile;
            CertificatePassword = csb.CertificatePassword;

            // Connection Pooling Options
            Pooling         = csb.Pooling;
            ConnectionReset = csb.ConnectionReset;
            if (csb.MinimumPoolSize > csb.MaximumPoolSize)
            {
                throw new MyCatException("MaximumPoolSize must be greater than or equal to MinimumPoolSize");
            }
            MinimumPoolSize = (int)csb.MinimumPoolSize;
            MaximumPoolSize = (int)csb.MaximumPoolSize;

            // Other Options
            AllowUserVariables  = csb.AllowUserVariables;
            ConnectionTimeout   = (int)csb.ConnectionTimeout;
            ConvertZeroDateTime = csb.ConvertZeroDateTime;
            ForceSynchronous    = csb.ForceSynchronous;
            Keepalive           = csb.Keepalive;
            OldGuids            = csb.OldGuids;
            PersistSecurityInfo = csb.PersistSecurityInfo;
            TreatTinyAsBoolean  = csb.TreatTinyAsBoolean;
            UseAffectedRows     = csb.UseAffectedRows;
            UseCompression      = csb.UseCompression;
        }
Example #13
0
        public MyCatRelationalConnection CreateMasterConnection(MyCatDatabaseHost node)
        {
            var csb = new MyCatConnectionStringBuilder(ConnectionString)
            {
                Database = "mysql",
                UserID   = node.Username,
                Server   = node.Host,
                Port     = node.Port,
                Password = node.Password,
                Pooling  = false
            };
            var optionsBuilder = new DbContextOptionsBuilder();

            optionsBuilder.UseMyCat(csb.GetConnectionString(true));
            return(new MyCatRelationalConnection(optionsBuilder.Options, Logger));
        }
        public static void ClearPool(MyCatConnectionStringBuilder settings)
        {
            Debug.Assert(settings != null);
            string text;

            try
            {
                text = GetKey(settings);
            }
            catch (MyCatException)
            {
                // Cannot retrieve windows identity for IntegratedSecurity=true
                // This can be ignored.
                return;
            }
            ClearPoolByText(text);
        }
Example #15
0
        public static Driver Create(MyCatConnectionStringBuilder settings)
        {
            Driver d = null;

#if !NETSTANDARD1_3
            try
            {
                if (MyCatTrace.QueryAnalysisEnabled || settings.Logging || settings.UseUsageAdvisor)
                {
                    d = new TracingDriver(settings);
                }
            }
            catch (TypeInitializationException ex)
            {
                if (!(ex.InnerException is SecurityException))
                {
                    throw ex;
                }
                //Only rethrow if InnerException is not a SecurityException. If it is a SecurityException then
                //we couldn't initialize MyCatTrace because we don't have unmanaged code permissions.
            }
#else
            if (settings.Logging || settings.UseUsageAdvisor)
            {
                throw new NotImplementedException("Logging not supported in this WinRT release.");
            }
#endif
            if (d == null)
            {
                d = new Driver(settings);
            }

            //this try was added as suggested fix submitted on MyCat Bug 72025, socket connections are left in CLOSE_WAIT status when connector fails to open a new connection.
            //the bug is present when the client try to get more connections that the server support or has configured in the max_connections variable.
            try
            {
                d.Open();
            }
            catch (Exception ex)
            {
                d.Dispose();
                throw ex;
            }
            return(d);
        }
        public void CancelQuery(int timeout)
        {
            MyCatConnectionStringBuilder cb = new MyCatConnectionStringBuilder(
                Settings.ConnectionString);

            cb.Pooling           = false;
            cb.AutoEnlist        = false;
            cb.ConnectionTimeout = (uint)timeout;

            using (MyCatConnection c = new MyCatConnection(cb.ConnectionString))
            {
                c.isKillQueryConnection = true;
                c.Open();
                string       commandText = "KILL QUERY " + ServerThread;
                MyCatCommand cmd         = new MyCatCommand(commandText, c);
                cmd.CommandTimeout = timeout;
                cmd.ExecuteNonQuery();
            }
        }
Example #17
0
        public void Defaults()
        {
            var csb = new MyCatConnectionStringBuilder();

            Assert.Equal(false, csb.AllowUserVariables);
            Assert.Equal(null, csb.CertificateFile);
            Assert.Equal(null, csb.CertificatePassword);
            Assert.Equal("", csb.CharacterSet);
#if BASELINE
            Assert.Equal(false, csb.ConnectionReset);
#else
            Assert.Equal(true, csb.ConnectionReset);
#endif
            Assert.Equal(15u, csb.ConnectionTimeout);
            Assert.Equal(false, csb.ConvertZeroDateTime);
            Assert.Equal("", csb.Database);
#if !BASELINE
            Assert.Equal(false, csb.ForceSynchronous);
#endif
            Assert.Equal(0u, csb.Keepalive);
            Assert.Equal(100u, csb.MaximumPoolSize);
            Assert.Equal(0u, csb.MinimumPoolSize);
            Assert.Equal("", csb.Password);
            Assert.Equal(false, csb.OldGuids);
            Assert.Equal(false, csb.PersistSecurityInfo);
            Assert.Equal(true, csb.Pooling);
            Assert.Equal(3306u, csb.Port);
            Assert.Equal("", csb.Server);
#if BASELINE
            Assert.Equal(MyCatSslMode.Prefered, csb.SslMode);
#else
            Assert.Equal(MyCatSslMode.None, csb.SslMode);
#endif
            Assert.Equal(true, csb.TreatTinyAsBoolean);
            Assert.Equal(false, csb.UseCompression);
            Assert.Equal("", csb.UserID);
#if BASELINE
            Assert.False(csb.UseAffectedRows);
#else
            Assert.True(csb.UseAffectedRows);
#endif
        }
        public virtual void CommitSchema(MyCatRelationalConnection _connection)
        {
            var csb = new MyCatConnectionStringBuilder(_connection.ConnectionString);

            using (var client = new HttpClient()
            {
                BaseAddress = new Uri("http://" + csb.Server + ":7066")
            })
            {
                var task = client.PostAsync("/", new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair <string, string>("Username", csb.UserID),
                    new KeyValuePair <string, string>("Password", csb.Password),
                    new KeyValuePair <string, string>("Database", csb.Database),
                    new KeyValuePair <string, string>("DataNodes", Newtonsoft.Json.JsonConvert.SerializeObject(DbContextOptions.FindExtension <MyCatOptionsExtension>().DataNodes)),
                    new KeyValuePair <string, string>("Schema", Newtonsoft.Json.JsonConvert.SerializeObject(Schema)),
                }));
                task.Wait();
            }
        }
        public static MyCatPool GetPool(MyCatConnectionStringBuilder settings)
        {
            string text = GetKey(settings);

            lock (pools)
            {
                MyCatPool pool;
                pools.TryGetValue(text, out pool);

                if (pool == null)
                {
                    pool = new MyCatPool(settings);
                    pools.Add(text, pool);
                }
                else
                {
                    pool.Settings = settings;
                }

                return(pool);
            }
        }
        public static DbContextOptionsBuilder UseMyCat(
            [NotNull] this DbContextOptionsBuilder optionsBuilder,
            [NotNull] DbConnection connection,
            [CanBeNull] Action <MyCatDbContextOptionsBuilder> MyCatOptionsAction = null)
        {
            Check.NotNull(optionsBuilder, nameof(optionsBuilder));
            Check.NotNull(connection, nameof(connection));

            var csb = new MyCatConnectionStringBuilder(connection.ConnectionString)
            {
                AllowUserVariables = true
            };

            connection.ConnectionString = csb.ConnectionString;
            var extension = GetOrCreateExtension(optionsBuilder);

            extension.Connection = connection;
            ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);

            MyCatOptionsAction?.Invoke(new MyCatDbContextOptionsBuilder(optionsBuilder));

            return(optionsBuilder);
        }
Example #21
0
        public static Stream GetStream(MyCatConnectionStringBuilder settings)
        {
            switch (settings.ConnectionProtocol)
            {
            case MyCatConnectionProtocol.Tcp: return(GetTcpStream(settings));

#if RT
            case MyCatConnectionProtocol.UnixSocket: throw new NotImplementedException();

            case MyCatConnectionProtocol.SharedMemory: throw new NotImplementedException();
#else
#if !NETSTANDARD1_3
            case MyCatConnectionProtocol.UnixSocket: return(GetUnixSocketStream(settings));

            case MyCatConnectionProtocol.SharedMemory: return(GetSharedMemoryStream(settings));
#endif
#endif
#if !NETSTANDARD1_3
            case MyCatConnectionProtocol.NamedPipe: return(GetNamedPipeStream(settings));
#endif
            }
            throw new InvalidOperationException(Resources.UnknownConnectionProtocol);
        }
        public MyCatPool(MyCatConnectionStringBuilder settings)
        {
            minSize = settings.MinimumPoolSize;
            maxSize = settings.MaximumPoolSize;

            available = (int)maxSize;
            autoEvent = new AutoResetEvent(false);

            if (minSize > maxSize)
            {
                minSize = maxSize;
            }
            this.settings = settings;
            inUsePool     = new List <Driver>((int)maxSize);
            idlePool      = new Queue <Driver>((int)maxSize);

            // prepopulate the idle pool to minSize
            for (int i = 0; i < minSize; i++)
            {
                EnqueueIdle(CreateNewPooledConnection());
            }

            procedureCache = new ProcedureCache((int)settings.ProcedureCacheSize);
        }
 public TracingDriver(MyCatConnectionStringBuilder settings)
     : base(settings)
 {
     driverId = Interlocked.Increment(ref driverCounter);
 }
Example #24
0
        public void SslModePreferredInvalidOperation()
        {
            var csb = new MyCatConnectionStringBuilder("ssl mode=preferred;");

            Assert.Throws <InvalidOperationException>(() => csb.SslMode);
        }
 internal protected virtual ReplicationServer GetServer(bool isMaster, MyCatConnectionStringBuilder settings)
 {
     return(GetServer(isMaster));
 }
 /// <include file='docs/MyCatConnection.xml' path='docs/DefaultCtor/*'/>
 public MyCatConnection()
 {
     //TODO: add event data to StateChange docs
     Settings = new MyCatConnectionStringBuilder();
     database = String.Empty;
 }
Example #27
0
        private static Stream GetNamedPipeStream(MyCatConnectionStringBuilder settings)
        {
            Stream stream = NamedPipeStream.Create(settings.PipeName, settings.Server, settings.ConnectionTimeout);

            return(stream);
        }
        /// <include file='docs/MyCatConnection.xml' path='docs/Open/*'/>
        public override void Open()
        {
            if (State == ConnectionState.Open)
            {
                Throw(new InvalidOperationException(Resources.ConnectionAlreadyOpen));
            }

#if !NETSTANDARD1_3
            // start up our interceptors
            exceptionInterceptor = new ExceptionInterceptor(this);
            commandInterceptor   = new CommandInterceptor(this);
#endif

            SetState(ConnectionState.Connecting, true);

            AssertPermissions();

#if !NETSTANDARD1_3
            // 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));
                }
            }
#endif

            try
            {
                MyCatConnectionStringBuilder currentSettings = Settings;
#if SUPPORT_REPLICATION
                // Load balancing
                if (ReplicationManager.IsReplicationGroup(Settings.Server))
                {
                    if (driver == null)
                    {
                        ReplicationManager.GetNewConnection(Settings.Server, false, this);
                    }
                    else
                    {
                        currentSettings = driver.Settings;
                    }
                }
#endif
#if !NETSTANDARD1_3
                if (Settings.Pooling)
                {
                    MyCatPool pool = MyCatPoolManager.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);
                }
#else
                if (driver == null || !driver.IsOpen)
                {
                    driver = Driver.Create(currentSettings);
                }
                procedureCache = new ProcedureCache((int)Settings.ProcedureCacheSize);
#endif
            }
            catch (Exception ex)
            {
                SetState(ConnectionState.Closed, true);
                throw ex;
            }

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

            if (!(driver.SupportsPasswordExpiration && driver.IsPasswordExpired))
            {
                if (Settings.Database != null && Settings.Database != String.Empty)
                {
                    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 !NETSTANDARD1_3
            if (Transaction.Current != null && Settings.AutoEnlist)
            {
                EnlistTransaction(Transaction.Current);
            }
#endif

            hasBeenOpen = true;
            SetState(ConnectionState.Open, true);
        }
Example #29
0
        private static Stream GetTcpStream(MyCatConnectionStringBuilder settings)
        {
            MyNetworkStream s = MyNetworkStream.CreateStream(settings, false);

            return(s);
        }