Index: System.Data.SQLite/SQLiteConnection.cs
==================================================================
--- System.Data.SQLite/SQLiteConnection.cs
+++ System.Data.SQLite/SQLiteConnection.cs
@@ -1408,10 +1408,19 @@
///
/// The extra connection flags to be used for all opened connections.
///
private static SQLiteConnectionFlags _sharedFlags;
+ ///
+ /// The instance (for this thread) that
+ /// had the most recent call to .
+ ///
+#if !PLATFORM_COMPACTFRAMEWORK
+ [ThreadStatic()]
+#endif
+ private static SQLiteConnection _lastConnectionInOpen;
+
#if SQLITE_STANDARD && !PLATFORM_COMPACTFRAMEWORK
///
/// Used to hold the active library version number of SQLite.
///
private static int _versionNumber;
@@ -2025,11 +2034,11 @@
///
/// Non-zero if the cached setting was found; otherwise, zero.
///
internal bool TryGetCachedSetting(
string name, /* in */
- string @default, /* in */
+ object @default, /* in */
out object value /* out */
)
{
if ((name == null) || (_cachedSettings == null))
{
@@ -2453,14 +2462,50 @@
internal static SortedList ParseConnectionString(
string connectionString,
bool parseViaFramework,
bool allowNameOnly
)
+ {
+ return ParseConnectionString(
+ null, connectionString, parseViaFramework, allowNameOnly);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Parses a connection string into component parts using the custom
+ /// connection string parser. An exception may be thrown if the syntax
+ /// of the connection string is incorrect.
+ ///
+ ///
+ /// The connection that will be using the parsed connection string.
+ ///
+ ///
+ /// The connection string to parse.
+ ///
+ ///
+ /// Non-zero to parse the connection string using the algorithm provided
+ /// by the framework itself. This is not applicable when running on the
+ /// .NET Compact Framework.
+ ///
+ ///
+ /// Non-zero if names are allowed without values.
+ ///
+ ///
+ /// The list of key/value pairs corresponding to the parameters specified
+ /// within the connection string.
+ ///
+ private static SortedList ParseConnectionString(
+ SQLiteConnection connection,
+ string connectionString,
+ bool parseViaFramework,
+ bool allowNameOnly
+ )
{
return parseViaFramework ?
- ParseConnectionStringViaFramework(connectionString, false) :
- ParseConnectionString(connectionString, allowNameOnly);
+ ParseConnectionStringViaFramework(connection, connectionString, false) :
+ ParseConnectionString(connection, connectionString, allowNameOnly);
}
///////////////////////////////////////////////////////////////////////////////////////////////
private void SetupSQLiteBase(SortedList opts)
@@ -2969,16 +3014,73 @@
else if (path.StartsWith ("/", StringComparison.OrdinalIgnoreCase))
return path;
else
throw new InvalidOperationException ("Invalid connection string: invalid URI");
}
+
+ ///
+ /// Determines if the legacy connection string parser should be used.
+ ///
+ ///
+ /// The connection that will be using the parsed connection string.
+ ///
+ ///
+ /// Non-zero if the legacy connection string parser should be used.
+ ///
+ private static bool ShouldUseLegacyConnectionStringParser(
+ SQLiteConnection connection
+ )
+ {
+ string name = "No_SQLiteConnectionNewParser";
+ object value; /* NOT USED */
+
+ if ((connection != null) &&
+ connection.TryGetCachedSetting(name, null, out value))
+ {
+ return true;
+ }
+
+ if ((connection == null) &&
+ TryGetLastCachedSetting(name, null, out value))
+ {
+ return true;
+ }
+
+ return (UnsafeNativeMethods.GetSettingValue(name, null) != null);
+ }
+
+ ///
+ /// Parses a connection string into component parts using the custom
+ /// connection string parser. An exception may be thrown if the syntax
+ /// of the connection string is incorrect.
+ ///
+ ///
+ /// The connection string to parse.
+ ///
+ ///
+ /// Non-zero if names are allowed without values.
+ ///
+ ///
+ /// The list of key/value pairs corresponding to the parameters specified
+ /// within the connection string.
+ ///
+ private static SortedList ParseConnectionString(
+ string connectionString,
+ bool allowNameOnly
+ )
+ {
+ return ParseConnectionString(null, connectionString, allowNameOnly);
+ }
///
/// Parses a connection string into component parts using the custom
/// connection string parser. An exception may be thrown if the syntax
/// of the connection string is incorrect.
///
+ ///
+ /// The connection that will be using the parsed connection string.
+ ///
///
/// The connection string to parse.
///
///
/// Non-zero if names are allowed without values.
@@ -2986,10 +3088,11 @@
///
/// The list of key/value pairs corresponding to the parameters specified
/// within the connection string.
///
private static SortedList ParseConnectionString(
+ SQLiteConnection connection,
string connectionString,
bool allowNameOnly
)
{
string s = connectionString;
@@ -2998,11 +3101,11 @@
// First split into semi-colon delimited values.
string error = null;
string[] arParts;
- if (UnsafeNativeMethods.GetSettingValue("No_SQLiteConnectionNewParser", null) != null)
+ if (ShouldUseLegacyConnectionStringParser(connection))
arParts = SQLiteConvert.Split(s, ';');
else
arParts = SQLiteConvert.NewSplit(s, ';', true, ref error);
if (arParts == null)
@@ -3043,10 +3146,13 @@
/// exception may be thrown if the connection string is invalid or cannot be
/// parsed. When compiled for the .NET Compact Framework, the custom
/// connection string parser is always used instead because the framework
/// provided one is unavailable there.
///
+ ///
+ /// The connection that will be using the parsed connection string.
+ ///
///
/// The connection string to parse.
///
///
/// Non-zero to throw an exception if any connection string values are not of
@@ -3053,10 +3159,11 @@
/// the type. This is not applicable when running on
/// the .NET Compact Framework.
///
/// The list of key/value pairs.
private static SortedList ParseConnectionStringViaFramework(
+ SQLiteConnection connection,
string connectionString,
bool strict
)
{
#if !PLATFORM_COMPACTFRAMEWORK
@@ -3096,11 +3203,11 @@
//
// NOTE: On the .NET Compact Framework, always use our custom connection
// string parser as the built-in (i.e. framework provided) one is
// unavailable.
//
- return ParseConnectionString(connectionString, false);
+ return ParseConnectionString(connection, connectionString, false);
#endif
}
#if !PLATFORM_COMPACTFRAMEWORK
///
@@ -3496,10 +3603,12 @@
///
public override void Open()
{
CheckDisposed();
+ _lastConnectionInOpen = this; /* THREAD-SAFE: per-thread datum. */
+
OnChanged(this, new ConnectionEventArgs(
SQLiteConnectionEventType.Opening, null, null, null, null, null,
null, null));
if (_connectionState != ConnectionState.Closed)
@@ -3506,11 +3615,11 @@
throw new InvalidOperationException();
Close();
SortedList opts = ParseConnectionString(
- _connectionString, _parseViaFramework, false);
+ this, _connectionString, _parseViaFramework, false);
OnChanged(this, new ConnectionEventArgs(
SQLiteConnectionEventType.ConnectionString, null, null, null, null,
null, _connectionString, new object[] { opts }));
@@ -4397,24 +4506,65 @@
{
return null;
}
}
}
+
+ ///
+ /// Queries and returns the value of the specified setting, using the
+ /// cached setting names and values for the last connection that used
+ /// by the method, when available.
+ ///
+ ///
+ /// The name of the setting.
+ ///
+ ///
+ /// The value to be returned if the setting has not been set explicitly
+ /// or cannot be determined.
+ ///
+ ///
+ /// The value of the cached setting is stored here if found; otherwise,
+ /// the value of is stored here.
+ ///
+ ///
+ /// Non-zero if the cached setting was found; otherwise, zero.
+ ///
+ private static bool TryGetLastCachedSetting(
+ string name,
+ object @default,
+ out object value
+ )
+ {
+ if (_lastConnectionInOpen == null)
+ {
+ value = @default;
+ return false;
+ }
+
+ return _lastConnectionInOpen.TryGetCachedSetting(
+ name, @default, out value);
+ }
///
/// The default connection flags to be used for all opened connections
/// when they are not present in the connection string.
///
public static SQLiteConnectionFlags DefaultFlags
{
get
{
- object enumValue;
+ string name = "DefaultFlags_SQLiteConnection";
+ object value;
- enumValue = TryParseEnum(typeof(SQLiteConnectionFlags),
- UnsafeNativeMethods.GetSettingValue(
- "DefaultFlags_SQLiteConnection", null), true);
+ if (!TryGetLastCachedSetting(name, null, out value))
+ value = UnsafeNativeMethods.GetSettingValue(name, null);
+
+ if (value == null)
+ return FallbackDefaultFlags;
+
+ object enumValue = TryParseEnum(
+ typeof(SQLiteConnectionFlags), value.ToString(), true);
if (enumValue is SQLiteConnectionFlags)
return (SQLiteConnectionFlags)enumValue;
return FallbackDefaultFlags;