using System; using System.Text; using MySql.Data.MySqlClient; using System.Data; using System.Threading; using System.Data.SqlClient; namespace Com.Dnet.Data { /// /// MySQL数据库连接源,支持MySQL5.0及前版本,.NET Framework2.0及前版本 /// public class DataSource { private static DataSource thisInstance = null; #region Poperty Make /* * Connection Timeout or Connect Timeout * The length of time (in seconds) to wait for a connection to * the server before terminating the attempt and generating an * error. */ private int nConnTimeOut = 30; public int CONNECTION_TIMEOUT { get { return nConnTimeOut; } set { nConnTimeOut = value; } } /* * Host or Server or Data Source or DataSource or Address or Addr or Network Address * The name or network address of the instance of MySQL to * which to connect. Multiple hosts can be specified separated * by &. This can be useful where multiple MySQL servers are * configured for replication and you are not concerned about * the precise server you are connecting to. No attempt is * made by the provider to synchronize writes to the database * so care should be taken when using this option. * In Unix environment with Mono, this can be a fully qualified * path to MySQL socket filename. With this configuration, the * Unix socket will be used instead of TCP/IP socket. Currently * only a single socket name can be given so accessing MySQL * in a replicated environment using Unix sockets is not * currently supported. */ private string strHost = "localhost"; public string HOST { get { return strHost; } set { strHost = value; } } /* * Port * The port MySQL is using to listen for connections. Specify -1 * for this value to use a named pipe connection (Windows only). * This value is ignored if Unix socket is used. */ private int nPort = 3306; public int PORT { get { return nPort; } set { nPort = value; } } /* * Protocol * Specifies the type of connection to make to the server. * Values can be: * socket or tcp for a socket connection * pipe for a named pipe connection * unix for a Unix socket connection * memory to use MySQL shared memory */ private string strProtocol = "Socket"; public string PROTOCOL { get { return strProtocol; } set { strProtocol = value; } } /* * CharSet or Character Set * * Specifies the character set that should be used to encode all * queries sent to the server. Resultsets are still returned in * the character set of the data returned. */ private string strCharset = "utf8"; public string CHARSET { get { return strCharset; } set { strCharset = value; } } /* * Logging * * When true, various pieces of information is output to * any configured TraceListeners. */ private bool bLogging = false; public bool LOGGING { get { return bLogging; } set { bLogging = value; } } /* * Allow Batch * * When true, multiple SQL statements can be sent with one command execution. * -Note- * Starting with MySQL 4.1.1, batch statements should be separated by the server-defined seperator character. * Commands sent to earlier versions of MySQL should be seperated with ';'. */ private bool bAllowBatch = true; public bool ALLOW_BATCH { get { return bAllowBatch; } set { bAllowBatch = value; } } /* * Encrypt * * When true, SSL/TLS encryption is used for all data sent between the client * and server if the server has a certificate installed. Recognized values * are true, false, yes, and no. */ //private bool bEncrypt = false; //public bool ENCRYPT //{ // get { return bEncrypt; } // set { bEncrypt = value; } //} /* * Database or Initial Catalog * * The name of the database to use intially */ private string strDatabase = "mysql"; public string DATABASE { get { return strDatabase; } set { strDatabase = value; } } /* * pwd or password * * The password for the MySQL account being used. */ private string strPwd = ""; public string PWD { get { return strPwd; } set { strPwd = value; } } /* * Persist Security Info * * When set to false or no (strongly recommended), * security-sensitive information, such as the password, * is not returned as part of the connection if the * connection is open or has ever been in an open state. * Resetting the connection string resets all connection * string values including the password. Recognized values * are true, false, yes, and no. */ private bool bPersistSecurityInfo = false; public bool PERSIST_SECURITY_INFO { get { return bPersistSecurityInfo; } set { bPersistSecurityInfo = value; } } /* * Uid or User Id or Username or User name * * The MySQL login account being used. */ private string strUid = ""; public string UID { get { return strUid; } set { strUid = value; } } /* * Shared Memory Name * * The name of the shared memory object to use for * communication if the connection protocol is set * to memory. */ private string strSharedMemoryName = "MYSQL"; public string SHARED_MEMORY_NAME { get { return strSharedMemoryName; } set { strSharedMemoryName = value; } } /* * Allow Zero Datetime * * True to have MySqlDataReader.GetValue() return a * MySqlDateTime for date or datetime columns that * have illegal values. False will cause a DateTime * object to be returned for legal values and an * exception will be thrown for illegal values. */ private bool bAllowZeroDatetime = false; public bool ALLOW_ZERO_TIME { get { return bAllowZeroDatetime; } set { bAllowZeroDatetime = value; } } /* * Convert Zero Datetime * * True to have MySqlDataReader.GetValue() and MySqlDataReader. * GetDateTime() return DateTime.MinValue for date or datetime * columns that have illegal values. */ private bool bConvertZeroDatetime = false; public bool CONVERT_ZERO_TIME { get { return bConvertZeroDatetime; } set { bConvertZeroDatetime = value; } } /* * Old Syntax * * Allows use of '@' symbol as a parameter marker. See MySqlCommand * for more info. * Note This is for compatibility only. All future code should be * written to use the new '?' parameter marker. */ private bool bOldSyntax = false; public bool OLD_SYNTAX { get { return bOldSyntax; } set { bOldSyntax = value; } } /* * Pipe Name * * When set to the name of a named pipe, the MySqlConnection will attempt * to connect to MySQL on that named pipe. * This settings only applies to the Windows platform. */ private string strPipeName = "mysql"; public string PIPE_NAME { get { return strPipeName; } set { strPipeName = value; } } /* * Use Performance Monitor * * Posts performance data that can be tracked using perfmon */ //private bool bUsePerformanceMonitor = false; //public bool USE_PERFORMANCE_MONITOR //{ // get { return bUsePerformanceMonitor; } // set { bUsePerformanceMonitor = value; } //} /* * Procedure Cache Size * * How many stored procedure definitions can be held in the cache */ private int nProcedureCacheSize = 25; public int PROCEDURE_CACHE_SIZE { get { return nProcedureCacheSize; } set { nProcedureCacheSize = value; } } /* * Ignore Prepare * * Instructs the provider to ignore any attempts to prepare commands. * This option was added to allow a user to disable prepared statements * in an entire application without modifying the code. A user might want * to do this if errors or bugs are encountered with MySQL prepared statements */ private bool bIgnorePrepare = true; public bool IGNORE_PREPARE { get { return bIgnorePrepare; } set { bIgnorePrepare = value; } } /* * Use Procedure Bodies * * Instructs the provider to attempt to call the procedure without first * resolving the metadata. Thjis is useful in situations where the calling * user does not have access to the mysql.proc table. To use this mode, the * parameters for the procedure must be added to the command in the same * order as they appear in the procedure definition and their types must be * explicitly set. */ //private bool bUseProcedureBodies = true; //public bool USE_PROCEDURE_BODIES //{ // get { return bUseProcedureBodies; } // set { bUseProcedureBodies = value; } //} /* * Connection Lifetime * * When a connection is returned to the pool, its creation time is compared * with the current time, and the connection is destroyed if that time span * (in seconds) exceeds the value specified by Connection Lifetime. This is * useful in clustered configurations to force load balancing between a running * server and a server just brought online. * A value of zero (0) causes pooled connections to have the maximum connection timeout. */ private int nConnectLifeTime = 0; public int CONNECT_LIFETIME { get { return nConnectLifeTime; } set { nConnectLifeTime = value; } } /* * Max Pool Size * * The maximum number of connections allowed in the pool. */ private int nMaxPoolSize = 100; public int MAX_POOLSIZE { get { return nMaxPoolSize; } set { nMaxPoolSize = value; } } /* * Min Pool Size * * The minimum number of connections allowed in the pool. */ private int nMinPoolSize = 0; public int MIN_POOLSIZE { get { return nMinPoolSize; } set { nMinPoolSize = value; } } /* * Pooling * * When true, the MySqlConnection object is drawn from the appropriate pool, * or if necessary, is created and added to the appropriate pool. Recognized * values are true, false, yes, and no. */ private bool bPooling = true; public bool POOLING { get { return bPooling; } set { bPooling = value; } } /* * Connection Reset * * Specifies whether the database connection should be reset when being drawn from * the pool. Leaving this as false will yeild much faster connection opens but the * user should understand the side effects of doing this such as temporary tables * and user variables from the previous session not being cleared out. */ private bool bConnectionReset = false; public bool CONNECTION_RESET { get { return bConnectionReset; } set { bConnectionReset = value; } } /* * Forced Break Time * * its creation time is compared with the current time, and the connection is destroyed * if that time span (in seconds) exceeds the value specified by Forced Break Time, * A value of zero (0) causes pooled connections to have the maximum connection timeout. */ private int nForceBreakTime = 0; public int FORCE_BREAKTIME { get { return nForceBreakTime; } set { nForceBreakTime = value; } } /* * ConnectionString * * You can use the ConnectionString property to connect to a database. The following example * illustrates a typical connection string. * "Persist Security Info=False;database=MyDB;server=MySqlServer;user id=myUser;Password=myPass" * The ConnectionString property can be set only when the connection is closed. * Many of the connection string values have corresponding read-only properties. * When the connection string is set, all of these properties are updated, except * when an error is detected. In this case, none of the properties are updated. */ private string strConnStr = ""; public string CONNECT_STRING { get { return strConnStr; } set { strConnStr = value; } } #endregion private DataSource() { } /** * 得到数据源 */ public static DataSource GetInstance() { return thisInstance; } /** * 初始化数据源 */ public static DataSource GetInstance(string host, string database, string uid, string pwd) { if (thisInstance == null) { thisInstance = new DataSource(); thisInstance.HOST = host; thisInstance.DATABASE = database; thisInstance.UID = uid; thisInstance.PWD = pwd; thisInstance.Initilize(); } return thisInstance; } /** * 得到数据库连接 */ public MySqlConnection GetConnection() { MySql.Data.MySqlClient.MySqlConnection objConn = new MySqlConnection(strConnStr); objConn.Open(); ConnectionBreakManager.Add(objConn, nForceBreakTime); return objConn; } /** * 连接字符串的初始化 */ public void Initilize() { StringBuilder connStr = new StringBuilder(); //keyword values connStr.Append("Connection Timeout=").Append(nConnTimeOut).Append(";"); connStr.Append("Host=").Append(strHost).Append(";"); connStr.Append("Port=").Append(nPort).Append(";"); connStr.Append("Protocol=").Append(strProtocol).Append(";"); connStr.Append("CharSet=").Append(strCharset).Append(";"); connStr.Append("Logging=").Append(bLogging).Append(";"); connStr.Append("Allow Batch=").Append(bAllowBatch).Append(";"); /* connStr.Append("Encrypt=").Append(bEncrypt).Append(";"); */ // Not Supported Yet connStr.Append("Database=").Append( strDatabase).Append(";"); connStr.Append("pwd=").Append(strPwd).Append(";"); connStr.Append("Persist Security Info=").Append(bPersistSecurityInfo).Append(";"); connStr.Append("Uid=").Append(strUid).Append(";"); connStr.Append("Shared Memory Name=").Append(strSharedMemoryName).Append(";"); connStr.Append("Allow Zero Datetime=").Append(bAllowZeroDatetime).Append(";"); connStr.Append("Convert Zero Datetime=").Append( bConvertZeroDatetime).Append(";"); connStr.Append("Old Syntax=").Append(bOldSyntax).Append(";"); connStr.Append("Pipe Name=").Append(strPipeName).Append(";"); /* connStr.Append("Use Performance Monitor=").Append(bUsePerformanceMonitor).Append(";"); */ // Not Supported Yet connStr.Append("Procedure Cache Size=").Append(nProcedureCacheSize).Append(";"); connStr.Append("Ignore Prepare=").Append(bIgnorePrepare).Append(";"); /* connStr.Append("Use Procedure Bodies=").Append(bUseProcedureBodies).Append(";"); */ // Not Supported Yet //connection pooling values connStr.Append("Connection Lifetime=").Append(nConnectLifeTime).Append(";"); connStr.Append("Max Pool Size=").Append(nMaxPoolSize).Append(";"); connStr.Append("Min Pool Size=").Append(nMinPoolSize).Append(";"); connStr.Append("Pooling=").Append(bPooling).Append(";"); connStr.Append("Connection Reset=").Append(bConnectionReset).Append(";"); strConnStr = connStr.ToString(); } } class ConnectionBreakManager { public static void Add(IDbConnection conn, int time) { if (time > 0) { //start thread // Thread myThread = new Thread(new ThreadStart(this.Task)); // myThread.IsBackground = true; // myThread.Start(); ConnectionLife objLife = new ConnectionLife(conn, time); ManagedThreadPool.QueueUserWorkItem(new WaitCallback(Task), objLife); } } static void Task(Object state) { ConnectionLife objConnectionLife = (ConnectionLife) state; IDbConnection myConn = objConnectionLife.CONNNECTION; int nForceBreakTime = objConnectionLife.FORCE_BREAKTIME; int nTime = nForceBreakTime * 1000; Thread.Sleep(nTime); if (!myConn.State.Equals(ConnectionState.Closed)) { myConn.Close(); } Thread.CurrentThread.Abort(); } private class ConnectionLife { private IDbConnection myConn = null; private int nForceBreakTime = 0; public IDbConnection CONNNECTION { get{return myConn;} } public int FORCE_BREAKTIME { get{return nForceBreakTime;} } public ConnectionLife(IDbConnection conn, int time) { myConn = conn; nForceBreakTime = time; } } } }