/********************************************************
* ADO.NET 2.0 Data Provider for SQLite Version 3.X
* Written by Robert Simpson (robert@blackcastlesoft.com)
*
* Released to the public domain, use at your own risk!
********************************************************/
namespace System.Data.SQLite
{
using System;
using System.Data.Common;
using System.ComponentModel;
using System.Collections;
using System.Globalization;
using System.Reflection;
#if !PLATFORM_COMPACTFRAMEWORK
///
/// SQLite implementation of DbConnectionStringBuilder.
///
[DefaultProperty("DataSource")]
[DefaultMember("Item")]
public sealed class SQLiteConnectionStringBuilder : DbConnectionStringBuilder
{
///
/// Properties of this class
///
private Hashtable _properties;
///
/// Constructs a new instance of the class
///
///
/// Default constructor
///
public SQLiteConnectionStringBuilder()
{
Initialize(null);
}
///
/// Constructs a new instance of the class using the specified connection string.
///
/// The connection string to parse
public SQLiteConnectionStringBuilder(string connectionString)
{
Initialize(connectionString);
}
///
/// Private initializer, which assigns the connection string and resets the builder
///
/// The connection string to assign
private void Initialize(string cnnString)
{
_properties = new Hashtable(StringComparer.OrdinalIgnoreCase);
try
{
base.GetProperties(_properties);
}
catch(NotImplementedException)
{
FallbackGetProperties(_properties);
}
if (String.IsNullOrEmpty(cnnString) == false)
ConnectionString = cnnString;
}
///
/// Gets/Sets the default version of the SQLite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library.
///
[Browsable(true)]
[DefaultValue(3)]
public int Version
{
get
{
object value;
TryGetValue("version", out value);
return Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
set
{
if (value != 3)
throw new NotSupportedException();
this["version"] = value;
}
}
///
/// Gets/Sets the synchronization mode (file flushing) of the connection string. Default is "Normal".
///
[DisplayName("Synchronous")]
[Browsable(true)]
[DefaultValue(SynchronizationModes.Normal)]
public SynchronizationModes SyncMode
{
get
{
object value;
TryGetValue("synchronous", out value);
if (value is string)
return (SynchronizationModes)TypeDescriptor.GetConverter(typeof(SynchronizationModes)).ConvertFrom(value);
else return (SynchronizationModes)value;
}
set
{
this["synchronous"] = value;
}
}
///
/// Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding.
///
[DisplayName("Use UTF-16 Encoding")]
[Browsable(true)]
[DefaultValue(false)]
public bool UseUTF16Encoding
{
get
{
object value;
TryGetValue("useutf16encoding", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["useutf16encoding"] = value;
}
}
///
/// Gets/Sets whether or not to use connection pooling. The default is "False"
///
[Browsable(true)]
[DefaultValue(false)]
public bool Pooling
{
get
{
object value;
TryGetValue("pooling", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["pooling"] = value;
}
}
///
/// Gets/Sets whethor not to store GUID's in binary format. The default is True
/// which saves space in the database.
///
[DisplayName("Binary GUID")]
[Browsable(true)]
[DefaultValue(true)]
public bool BinaryGUID
{
get
{
object value;
TryGetValue("binaryguid", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["binaryguid"] = value;
}
}
///
/// Gets/Sets the filename to open on the connection string.
///
[DisplayName("Data Source")]
[Browsable(true)]
[DefaultValue("")]
public string DataSource
{
get
{
object value;
TryGetValue("data source", out value);
return (value != null) ? value.ToString() : null;
}
set
{
this["data source"] = value;
}
}
///
/// An alternate to the data source property
///
[DisplayName("URI")]
[Browsable(true)]
[DefaultValue(null)]
public string Uri
{
get
{
object value;
TryGetValue("uri", out value);
return (value != null) ? value.ToString() : null;
}
set
{
this["uri"] = value;
}
}
///
/// An alternate to the data source property that uses the SQLite URI syntax.
///
[DisplayName("Full URI")]
[Browsable(true)]
[DefaultValue(null)]
public string FullUri
{
get
{
object value;
TryGetValue("fulluri", out value);
return (value != null) ? value.ToString() : null;
}
set
{
this["fulluri"] = value;
}
}
///
/// Gets/sets the default command timeout for newly-created commands. This is especially useful for
/// commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible.
///
[DisplayName("Default Timeout")]
[Browsable(true)]
[DefaultValue(30)]
public int DefaultTimeout
{
get
{
object value;
TryGetValue("default timeout", out value);
return Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
set
{
this["default timeout"] = value;
}
}
///
/// Gets/sets the default maximum sleep time for newly-created commands.
///
[DisplayName("Default Maximum Sleep Time")]
[Browsable(true)]
[DefaultValue(150)]
public int DefaultMaximumSleepTime
{
get
{
object value;
TryGetValue("defaultmaximumsleeptime", out value);
return Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
set
{
this["defaultmaximumsleeptime"] = value;
}
}
///
/// Gets/sets the busy timeout to use with the SQLite core library.
///
[DisplayName("Busy Timeout")]
[Browsable(true)]
[DefaultValue(0)]
public int BusyTimeout
{
get
{
object value;
TryGetValue("busytimeout", out value);
return Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
set
{
this["busytimeout"] = value;
}
}
///
/// EXPERIMENTAL --
/// The wait timeout to use with
/// method.
/// This is only used when waiting for the enlistment to be reset
/// prior to enlisting in a transaction, and then only when the
/// appropriate connection flag is set.
///
[DisplayName("Wait Timeout")]
[Browsable(true)]
[DefaultValue(30000)]
public int WaitTimeout
{
get
{
object value;
TryGetValue("waittimeout", out value);
return Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
set
{
this["waittimeout"] = value;
}
}
///
/// Gets/sets the maximum number of retries when preparing SQL to be executed.
/// This normally only applies to preparation errors resulting from the database
/// schema being changed.
///
[DisplayName("Prepare Retries")]
[Browsable(true)]
[DefaultValue(3)]
public int PrepareRetries
{
get
{
object value;
TryGetValue("prepareretries", out value);
return Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
set
{
this["prepareretries"] = value;
}
}
///
/// Gets/sets the maximum number of retries when stepping SQL to be executed.
/// This normally only applies to stepping errors resulting from the database
/// being locked.
///
[DisplayName("Step Retries")]
[Browsable(true)]
[DefaultValue(40)]
public int StepRetries
{
get
{
object value;
TryGetValue("stepretries", out value);
return Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
set
{
this["stepretries"] = value;
}
}
///
/// Gets/sets the approximate number of virtual machine instructions between
/// progress events. In order for progress events to actually fire, the event
/// handler must be added to the event
/// as well.
///
[DisplayName("Progress Ops")]
[Browsable(true)]
[DefaultValue(0)]
public int ProgressOps
{
get
{
object value;
TryGetValue("progressops", out value);
return Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
set
{
this["progressops"] = value;
}
}
///
/// Determines whether or not the connection will automatically participate
/// in the current distributed transaction (if one exists)
///
[Browsable(true)]
[DefaultValue(true)]
public bool Enlist
{
get
{
object value;
TryGetValue("enlist", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["enlist"] = value;
}
}
///
/// If set to true, will throw an exception if the database specified in the connection
/// string does not exist. If false, the database will be created automatically.
///
[DisplayName("Fail If Missing")]
[Browsable(true)]
[DefaultValue(false)]
public bool FailIfMissing
{
get
{
object value;
TryGetValue("failifmissing", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["failifmissing"] = value;
}
}
///
/// If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger
/// database sizes.
///
[DisplayName("Legacy Format")]
[Browsable(true)]
[DefaultValue(false)]
public bool LegacyFormat
{
get
{
object value;
TryGetValue("legacy format", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["legacy format"] = value;
}
}
///
/// When enabled, the database will be opened for read-only access and writing will be disabled.
///
[DisplayName("Read Only")]
[Browsable(true)]
[DefaultValue(false)]
public bool ReadOnly
{
get
{
object value;
TryGetValue("read only", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["read only"] = value;
}
}
///
/// Gets/sets the database encryption password
///
[Browsable(true)]
[PasswordPropertyText(true)]
[DefaultValue("")]
public string Password
{
get
{
object value;
TryGetValue("password", out value);
return (value != null) ? value.ToString() : null;
}
set
{
this["password"] = value;
}
}
///
/// Gets/sets the database encryption hexadecimal password
///
[DisplayName("Hexadecimal Password")]
[Browsable(true)]
[PasswordPropertyText(true)]
[DefaultValue(null)]
public byte[] HexPassword
{
get
{
object value;
if (TryGetValue("hexpassword", out value))
{
if (value is string)
return SQLiteConnection.FromHexString((string)value);
else if (value != null)
return (byte[])value;
}
return null;
}
set
{
this["hexpassword"] = SQLiteConnection.ToHexString(value);
}
}
///
/// Gets/sets the database encryption textual password
///
[DisplayName("Textual Password")]
[Browsable(true)]
[PasswordPropertyText(true)]
[DefaultValue(null)]
public string TextPassword
{
get
{
object value;
if (TryGetValue("textpassword", out value))
return (value != null) ? value.ToString() : null;
return null;
}
set
{
this["textpassword"] = value;
}
}
///
/// Gets/sets the database encryption textual password in hexadecimal
///
[DisplayName("Textual Hexadecimal Password")]
[Browsable(true)]
[PasswordPropertyText(true)]
[DefaultValue(null)]
public byte[] TextHexPassword
{
get
{
object value;
if (TryGetValue("texthexpassword", out value))
{
if (value is string)
return SQLiteConnection.FromHexString((string)value);
else if (value != null)
return (byte[])value;
}
return null;
}
set
{
this["texthexpassword"] = SQLiteConnection.ToHexString(value);
}
}
///
/// Gets/Sets the page size for the connection.
///
[DisplayName("Page Size")]
[Browsable(true)]
[DefaultValue(4096)]
public int PageSize
{
get
{
object value;
TryGetValue("page size", out value);
return Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
set
{
this["page size"] = value;
}
}
///
/// Gets/Sets the maximum number of pages the database may hold
///
[DisplayName("Maximum Page Count")]
[Browsable(true)]
[DefaultValue(0)]
public int MaxPageCount
{
get
{
object value;
TryGetValue("max page count", out value);
return Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
set
{
this["max page count"] = value;
}
}
///
/// Gets/Sets the cache size for the connection.
///
[DisplayName("Cache Size")]
[Browsable(true)]
[DefaultValue(-2000)]
public int CacheSize
{
get
{
object value;
TryGetValue("cache size", out value);
return Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
set
{
this["cache size"] = value;
}
}
///
/// Gets/Sets the DateTime format for the connection.
///
[DisplayName("DateTime Format")]
[Browsable(true)]
[DefaultValue(SQLiteDateFormats.Default)]
public SQLiteDateFormats DateTimeFormat
{
get
{
object value;
if (TryGetValue("datetimeformat", out value))
{
if (value is SQLiteDateFormats)
return (SQLiteDateFormats)value;
else if (value != null)
return (SQLiteDateFormats)TypeDescriptor.GetConverter(
typeof(SQLiteDateFormats)).ConvertFrom(value);
}
return SQLiteDateFormats.Default;
}
set
{
this["datetimeformat"] = value;
}
}
///
/// Gets/Sets the DateTime kind for the connection.
///
[DisplayName("DateTime Kind")]
[Browsable(true)]
[DefaultValue(DateTimeKind.Unspecified)]
public DateTimeKind DateTimeKind
{
get
{
object value;
if (TryGetValue("datetimekind", out value))
{
if (value is DateTimeKind)
return (DateTimeKind)value;
else if (value != null)
return (DateTimeKind)TypeDescriptor.GetConverter(
typeof(DateTimeKind)).ConvertFrom(value);
}
return DateTimeKind.Unspecified;
}
set
{
this["datetimekind"] = value;
}
}
///
/// Gets/sets the DateTime format string used for formatting
/// and parsing purposes.
///
[DisplayName("DateTime Format String")]
[Browsable(true)]
[DefaultValue(null)]
public string DateTimeFormatString
{
get
{
object value;
if (TryGetValue("datetimeformatstring", out value))
{
if (value is string)
return (string)value;
else if (value != null)
return value.ToString();
}
return null;
}
set
{
this["datetimeformatstring"] = value;
}
}
///
/// Gets/Sets the placeholder base schema name used for
/// .NET Framework compatibility purposes.
///
[DisplayName("Base Schema Name")]
[Browsable(true)]
[DefaultValue(SQLiteConnection.DefaultBaseSchemaName)]
public string BaseSchemaName
{
get
{
object value;
if (TryGetValue("baseschemaname", out value))
{
if (value is string)
return (string)value;
else if (value != null)
return value.ToString();
}
return null;
}
set
{
this["baseschemaname"] = value;
}
}
///
/// Determines how SQLite handles the transaction journal file.
///
[Browsable(true)]
[DefaultValue(SQLiteJournalModeEnum.Default)]
[DisplayName("Journal Mode")]
public SQLiteJournalModeEnum JournalMode
{
get
{
object value;
TryGetValue("journal mode", out value);
if (value is string)
return (SQLiteJournalModeEnum)TypeDescriptor.GetConverter(typeof(SQLiteJournalModeEnum)).ConvertFrom(value);
else
return (SQLiteJournalModeEnum)value;
}
set
{
this["journal mode"] = value;
}
}
///
/// Sets the default isolation level for transactions on the connection.
///
[Browsable(true)]
[DefaultValue(IsolationLevel.Serializable)]
[DisplayName("Default Isolation Level")]
public IsolationLevel DefaultIsolationLevel
{
get
{
object value;
TryGetValue("default isolationlevel", out value);
if (value is string)
return (IsolationLevel)TypeDescriptor.GetConverter(typeof(IsolationLevel)).ConvertFrom(value);
else
return (IsolationLevel)value;
}
set
{
this["default isolationlevel"] = value;
}
}
///
/// Gets/sets the default database type for the connection.
///
[DisplayName("Default Database Type")]
[Browsable(true)]
[DefaultValue(SQLiteConnection.BadDbType)]
public DbType DefaultDbType
{
get
{
object value;
if (TryGetValue("defaultdbtype", out value))
{
if (value is string)
return (DbType)TypeDescriptor.GetConverter(
typeof(DbType)).ConvertFrom(value);
else if (value != null)
return (DbType)value;
}
return SQLiteConnection.BadDbType;
}
set
{
this["defaultdbtype"] = value;
}
}
///
/// Gets/sets the default type name for the connection.
///
[DisplayName("Default Type Name")]
[Browsable(true)]
[DefaultValue(null)]
public string DefaultTypeName
{
get
{
object value;
TryGetValue("defaulttypename", out value);
return (value != null) ? value.ToString() : null;
}
set
{
this["defaulttypename"] = value;
}
}
///
/// Gets/sets the VFS name for the connection.
///
[DisplayName("VFS Name")]
[Browsable(true)]
[DefaultValue(null)]
public string VfsName
{
get
{
object value;
TryGetValue("vfsname", out value);
return (value != null) ? value.ToString() : null;
}
set
{
this["vfsname"] = value;
}
}
///
/// If enabled, use foreign key constraints
///
[DisplayName("Foreign Keys")]
[Browsable(true)]
[DefaultValue(false)]
public bool ForeignKeys
{
get
{
object value;
TryGetValue("foreign keys", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["foreign keys"] = value;
}
}
///
/// Enable or disable the recursive trigger capability.
///
[DisplayName("Recursive Triggers")]
[Browsable(true)]
[DefaultValue(false)]
public bool RecursiveTriggers
{
get
{
object value;
TryGetValue("recursive triggers", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["recursive triggers"] = value;
}
}
///
/// If non-null, this is the version of ZipVFS to use. This requires the
/// System.Data.SQLite interop assembly -AND- primary managed assembly to
/// be compiled with the INTEROP_INCLUDE_ZIPVFS option; otherwise, this
/// property does nothing.
///
[DisplayName("ZipVFS Version")]
[Browsable(true)]
[DefaultValue(null)]
public string ZipVfsVersion
{
get
{
object value;
TryGetValue("zipvfsversion", out value);
return (value != null) ? value.ToString() : null;
}
set
{
this["zipvfsversion"] = value;
}
}
///
/// Gets/Sets the extra behavioral flags.
///
[Browsable(true)]
[DefaultValue(SQLiteConnectionFlags.Default)]
public SQLiteConnectionFlags Flags
{
get
{
object value;
if (TryGetValue("flags", out value))
{
if (value is SQLiteConnectionFlags)
return (SQLiteConnectionFlags)value;
else if (value != null)
return (SQLiteConnectionFlags)TypeDescriptor.GetConverter(
typeof(SQLiteConnectionFlags)).ConvertFrom(value);
}
return SQLiteConnectionFlags.Default;
}
set
{
this["flags"] = value;
}
}
///
/// If enabled, apply the default connection settings to opened databases.
///
[DisplayName("Set Defaults")]
[Browsable(true)]
[DefaultValue(true)]
public bool SetDefaults
{
get
{
object value;
TryGetValue("setdefaults", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["setdefaults"] = value;
}
}
///
/// If enabled, attempt to resolve the provided data source file name to a
/// full path before opening.
///
[DisplayName("To Full Path")]
[Browsable(true)]
[DefaultValue(true)]
public bool ToFullPath
{
get
{
object value;
TryGetValue("tofullpath", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["tofullpath"] = value;
}
}
///
/// If enabled, skip using the configured default connection flags.
///
[DisplayName("No Default Flags")]
[Browsable(true)]
[DefaultValue(false)]
public bool NoDefaultFlags
{
get
{
object value;
TryGetValue("nodefaultflags", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["nodefaultflags"] = value;
}
}
///
/// If enabled, skip using the configured shared connection flags.
///
[DisplayName("No Shared Flags")]
[Browsable(true)]
[DefaultValue(false)]
public bool NoSharedFlags
{
get
{
object value;
TryGetValue("nosharedflags", out value);
return SQLiteConvert.ToBoolean(value);
}
set
{
this["nosharedflags"] = value;
}
}
///
/// Helper function for retrieving values from the connectionstring
///
/// The keyword to retrieve settings for
/// The resulting parameter value
/// Returns true if the value was found and returned
public override bool TryGetValue(string keyword, out object value)
{
bool b = base.TryGetValue(keyword, out value);
if (!_properties.ContainsKey(keyword)) return b;
PropertyDescriptor pd = _properties[keyword] as PropertyDescriptor;
if (pd == null) return b;
// Attempt to coerce the value into something more solid
if (b)
{
if (pd.PropertyType == typeof(Boolean))
value = SQLiteConvert.ToBoolean(value);
else if (pd.PropertyType != typeof(byte[]))
value = TypeDescriptor.GetConverter(pd.PropertyType).ConvertFrom(value);
}
else
{
DefaultValueAttribute att = pd.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;
if (att != null)
{
value = att.Value;
b = true;
}
}
return b;
}
///
/// Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties()
///
/// The hashtable to fill with property descriptors
private void FallbackGetProperties(Hashtable propertyList)
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(this, true))
{
if (descriptor.Name != "ConnectionString" && propertyList.ContainsKey(descriptor.DisplayName) == false)
{
propertyList.Add(descriptor.DisplayName, descriptor);
}
}
}
}
#endif
}