?? sqliteconnection.cs
字號:
/// <summary>
/// Manual distributed transaction enlistment support
/// </summary>
/// <param name="transaction">The distributed transaction to enlist in</param>
public override void EnlistTransaction(System.Transactions.Transaction transaction)
{
if (_transactionLevel > 0 && transaction != null)
throw new ArgumentException("Unable to enlist in transaction, a local transaction already exists");
if (_enlistment != null && transaction != _enlistment._scope)
throw new ArgumentException("Already enlisted in a transaction");
_enlistment = new SQLiteEnlistment(this, transaction);
}
#endif
/// <summary>
/// Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value
/// </summary>
/// <param name="opts">The Key/Value pair array to look in</param>
/// <param name="key">The key to find</param>
/// <param name="defValue">The default value to return if the key is not found</param>
/// <returns>The value corresponding to the specified key, or the default value if not found.</returns>
static internal string FindKey(KeyValuePair<string, string>[] opts, string key, string defValue)
{
int x = opts.Length;
for (int n = 0; n < x; n++)
{
if (String.Compare(opts[n].Key, key, true, CultureInfo.InvariantCulture) == 0)
{
return opts[n].Value;
}
}
return defValue;
}
/// <summary>
/// Opens the connection using the parameters found in the <see cref="ConnectionString">ConnectionString</see>
/// </summary>
public override void Open()
{
if (_connectionState != ConnectionState.Closed)
throw new InvalidOperationException();
Close();
KeyValuePair<string, string>[] opts = ParseConnectionString();
string fileName;
if (Convert.ToInt32(FindKey(opts, "Version", "3"), CultureInfo.InvariantCulture) != 3)
throw new NotSupportedException("Only SQLite Version 3 is supported at this time");
fileName = FindKey(opts, "Data Source", "");
if (String.IsNullOrEmpty(fileName))
throw new ArgumentException("Data Source cannot be empty. Use :memory: to open an in-memory database");
if (String.Compare(fileName, ":MEMORY:", true, CultureInfo.InvariantCulture) == 0)
fileName = ":memory:";
#if PLATFORM_COMPACTFRAMEWORK
else if (fileName.StartsWith(".\\"))
fileName = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase) + fileName.Substring(1);
#endif
try
{
bool bUTF16 = (Convert.ToBoolean(FindKey(opts, "UseUTF16Encoding", "False"), CultureInfo.InvariantCulture) == true);
SQLiteDateFormats dateFormat = String.Compare(FindKey(opts, "DateTimeFormat", "ISO8601"), "ticks", true, CultureInfo.InvariantCulture) == 0 ? SQLiteDateFormats.Ticks : SQLiteDateFormats.ISO8601;
if (bUTF16) // SQLite automatically sets the encoding of the database to UTF16 if called from sqlite3_open16()
_sql = new SQLite3_UTF16(dateFormat);
else
_sql = new SQLite3(dateFormat);
fileName = ExpandFileName(fileName);
try
{
if (IO.File.Exists(fileName) == false)
throw new IO.FileNotFoundException(String.Format(CultureInfo.CurrentCulture, "Unable to locate file \"{0}\", creating new database.", fileName));
}
catch
{
}
_sql.Open(fileName);
_binaryGuid = (Convert.ToBoolean(FindKey(opts, "BinaryGUID", "True"), CultureInfo.InvariantCulture) == true);
string password = FindKey(opts, "Password", null);
if (String.IsNullOrEmpty(password) == false)
_sql.SetPassword(System.Text.UTF8Encoding.UTF8.GetBytes(password));
else if (_password != null)
_sql.SetPassword(_password);
_password = null;
_dataSource = System.IO.Path.GetFileNameWithoutExtension(fileName);
OnStateChange(ConnectionState.Open);
_version++;
using (SQLiteCommand cmd = CreateCommand())
{
string defValue;
defValue = FindKey(opts, "Synchronous", "Normal");
if (String.Compare(defValue, "Normal", true, CultureInfo.InvariantCulture) != 0)
{
cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Synchronous={0}", defValue);
cmd.ExecuteNonQuery();
}
defValue = FindKey(opts, "Cache Size", "2000");
if (Convert.ToInt32(defValue) != 2000)
{
cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Cache_Size={0}", defValue);
cmd.ExecuteNonQuery();
}
if (fileName != ":memory:")
{
defValue = FindKey(opts, "Page Size", "1024");
if (Convert.ToInt32(defValue) != 1024)
{
cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Page_Size={0}", defValue);
cmd.ExecuteNonQuery();
}
}
}
#if !PLATFORM_COMPACTFRAMEWORK
if (FindKey(opts, "Enlist", "Y").ToUpper()[0] == 'Y' && Transactions.Transaction.Current != null)
EnlistTransaction(Transactions.Transaction.Current);
#endif
}
catch (SQLiteException)
{
OnStateChange(ConnectionState.Broken);
throw;
}
}
/// <summary>
/// Returns the version of the underlying SQLite database engine
/// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
public override string ServerVersion
{
get
{
if (_connectionState != ConnectionState.Open)
throw new InvalidOperationException();
return _sql.Version;
}
}
/// <summary>
/// Returns the state of the connection.
/// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
public override ConnectionState State
{
get
{
return _connectionState;
}
}
/// <summary>
/// Change the password (or assign a password) to an open database.
/// </summary>
/// <remarks>
/// No readers or writers may be active for this process. The database must already be open
/// and if it already was password protected, the existing password must already have been supplied.
/// </remarks>
/// <param name="newPassword">The new password to assign to the database</param>
public void ChangePassword(string newPassword)
{
ChangePassword(String.IsNullOrEmpty(newPassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(newPassword));
}
/// <summary>
/// Change the password (or assign a password) to an open database.
/// </summary>
/// <remarks>
/// No readers or writers may be active for this process. The database must already be open
/// and if it already was password protected, the existing password must already have been supplied.
/// </remarks>
/// <param name="newPassword">The new password to assign to the database</param>
public void ChangePassword(byte[] newPassword)
{
if (_connectionState != ConnectionState.Open)
throw new InvalidOperationException("Database must be opened before changing the password.");
_sql.ChangePassword(newPassword);
}
/// <summary>
/// Sets the password for a password-protected database. A password-protected database is
/// unusable for any operation until the password has been set.
/// </summary>
/// <param name="databasePassword">The password for the database</param>
public void SetPassword(string databasePassword)
{
SetPassword(String.IsNullOrEmpty(databasePassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(databasePassword));
}
/// <summary>
/// Sets the password for a password-protected database. A password-protected database is
/// unusable for any operation until the password has been set.
/// </summary>
/// <param name="databasePassword">The password for the database</param>
public void SetPassword(byte[] databasePassword)
{
if (_connectionState != ConnectionState.Closed)
throw new InvalidOperationException("Password can only be set before the database is opened.");
if (databasePassword != null)
if (databasePassword.Length == 0) databasePassword = null;
_password = databasePassword;
}
private const string _dataDirectory = "|DataDirectory|";
/// <summary>
/// Expand the filename of the data source, resolving the |DataDirectory| macro as appropriate.
/// </summary>
/// <param name="sourceFile">The database filename to expand</param>
/// <returns>The expanded path and filename of the filename</returns>
private string ExpandFileName(string sourceFile)
{
if (String.IsNullOrEmpty(sourceFile)) return sourceFile;
if (sourceFile.StartsWith(_dataDirectory, StringComparison.OrdinalIgnoreCase))
{
string dataDirectory;
#if PLATFORM_COMPACTFRAMEWORK
dataDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase);
#else
dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory") as string;
if (String.IsNullOrEmpty(dataDirectory))
dataDirectory = AppDomain.CurrentDomain.BaseDirectory;
#endif
if (sourceFile.Length > _dataDirectory.Length)
{
if (sourceFile[_dataDirectory.Length] == System.IO.Path.DirectorySeparatorChar ||
sourceFile[_dataDirectory.Length] == System.IO.Path.AltDirectorySeparatorChar)
sourceFile = sourceFile.Remove(_dataDirectory.Length, 1);
}
sourceFile = System.IO.Path.Combine(dataDirectory, sourceFile.Substring(_dataDirectory.Length));
}
return sourceFile;
}
///<overloads>
/// The following commands are used to extract schema information out of the database. Valid schema types are:
/// <list type="bullet">
/// <item>
/// <description>MetaDataCollections</description>
/// </item>
/// <item>
/// <description>DataSourceInformation</description>
/// </item>
/// <item>
/// <description>Catalogs</description>
/// </item>
/// <item>
/// <description>Columns</description>
/// </item>
/// <item>
/// <description>ForeignKeys</description>
/// </item>
/// <item>
/// <description>Indexes</description>
/// </item>
/// <item>
/// <description>IndexColumns</description>
/// </item>
/// <item>
/// <description>Tables</description>
/// </item>
/// <item>
/// <description>Views</description>
/// </item>
/// <item>
/// <description>ViewColumns</description>
/// </item>
/// </list>
/// </overloads>
/// <summary>
/// Returns the MetaDataCollections schema
/// </summary>
/// <returns>A DataTable of the MetaDataCollections schema</returns>
public override DataTable GetSchema()
{
return GetSchema("MetaDataCollections", null);
}
/// <summary>
/// Returns schema information of the specified collection
/// </summary>
/// <param name="collectionName">The schema collection to retrieve</param>
/// <returns>A DataTable of the specified collection</returns>
public override DataTable GetSchema(string collectionName)
{
return GetSchema(collectionName, new string[0]);
}
/// <summary>
/// Retrieves schema information using the specified constraint(s) for the specified collection
/// </summary>
/// <param name="collectionName">The collection to retrieve</param>
/// <param name="restrictionValues">The restrictions to impose</param>
/// <returns>A DataTable of the specified collection</returns>
public override DataTable GetSchema(string collectionName, string[] restrictionValues)
{
if (_connectionState != ConnectionState.Open)
throw new InvalidOperationException();
string[] parms = new string[5];
if (restrictionValues == null) restrictionValues = new string[0];
restrictionValues.CopyTo(parms, 0);
switch (collectionName.ToUpper(CultureInfo.InvariantCulture))
{
case "METADATACOLLECTIONS":
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -