Decompiled source of SQLite4BepInEx v1.0.0
BepInEx/plugins/SQLite/System.Data.SQLite.dll
Decompiled 9 hours ago
The result has been truncated due to the large size, download it to view full contents!
#define TRACE using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Data.Common; using System.Data.SQLite; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Threading; using System.Transactions; using System.Xml; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("System.Data.SQLite Core")] [assembly: AssemblyDescription("ADO.NET Data Provider for SQLite")] [assembly: AssemblyCompany("https://system.data.sqlite.org/")] [assembly: AssemblyProduct("System.Data.SQLite")] [assembly: AssemblyCopyright("Copyright © 2004-2008 Hipp, Wyrick & Company, Inc.")] [assembly: AssemblyConfiguration("Release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] [assembly: InternalsVisibleTo("System.Data.SQLite.Linq, PublicKey=002400000480000094000000060200000024000052534131000400000100010005a288de5687c4e1b621ddff5d844727418956997f475eb829429e411aff3e93f97b70de698b972640925bdd44280df0a25a843266973704137cbb0e7441c1fe7cae4e2440ae91ab8cde3933febcb1ac48dd33b40e13c421d8215c18a4349a436dd499e3c385cc683015f886f6c10bd90115eb2bd61b67750839e3a19941dc9c")] [assembly: InternalsVisibleTo("System.Data.SQLite.EF6, PublicKey=002400000480000094000000060200000024000052534131000400000100010005a288de5687c4e1b621ddff5d844727418956997f475eb829429e411aff3e93f97b70de698b972640925bdd44280df0a25a843266973704137cbb0e7441c1fe7cae4e2440ae91ab8cde3933febcb1ac48dd33b40e13c421d8215c18a4349a436dd499e3c385cc683015f886f6c10bd90115eb2bd61b67750839e3a19941dc9c")] [assembly: NeutralResourcesLanguage("en")] [assembly: ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [assembly: SecurityRules(SecurityRuleSet.Level1)] [assembly: AssemblyFileVersion("1.0.119.0")] [assembly: AssemblySourceId("f5bd41f18507b13a1d6896fa9ed544e6e3b133c0")] [assembly: AssemblySourceTimeStamp("2024-09-24 14:38:06 UTC")] [assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")] [assembly: AssemblyVersion("1.0.119.0")] namespace System.Data.SQLite { [AttributeUsage(AttributeTargets.Assembly, Inherited = false)] public sealed class AssemblySourceIdAttribute : Attribute { private string sourceId; public string SourceId => sourceId; public AssemblySourceIdAttribute(string value) { sourceId = value; } } [AttributeUsage(AttributeTargets.Assembly, Inherited = false)] public sealed class AssemblySourceTimeStampAttribute : Attribute { private string sourceTimeStamp; public string SourceTimeStamp => sourceTimeStamp; public AssemblySourceTimeStampAttribute(string value) { sourceTimeStamp = value; } } internal enum FlagsOperation { None = 0, Add = 1, Remove = 2, Set = 4, Default = 1 } [Flags] internal enum TraceCategory { None = 0, Self = 0x1000, Log = 0x2000, Connection = 0x4000, Detection = 0x8000, Handle = 0x10000, Preload = 0x20000, Shared = 0x40000, Statement = 0x80000, Warning = 0x100000, Verify = 0x200000, Complain = 0x400000, Exception = 0x800000, Crash = 0x1000000, Timing = 0x2000000, All = 0x3FFF000, Default = 0x3F63000 } internal static class HelperMethods { private const string DisplayNullObject = "<nullObject>"; private const string DisplayEmptyString = "<emptyString>"; private const string DisplayStringFormat = "\"{0}\""; private const string DisplayNullArray = "<nullArray>"; private const string DisplayEmptyArray = "<emptyArray>"; private const string TraceDateTimeFormat = "yyyy-MM-dd HH:mm:ss.fffffff"; private const char ArrayOpen = '['; private const string ElementSeparator = ", "; private const char ArrayClose = ']'; private static readonly char[] SpaceChars = new char[6] { '\t', '\n', '\r', '\v', '\f', ' ' }; private static readonly char[] SeparatorChars = new char[4] { '\t', '\n', ' ', ',' }; private static readonly object staticSyncRoot = new object(); private static readonly string MonoRuntimeType = "Mono.Runtime"; private static readonly string DotNetCoreLibType = "System.CoreLib"; private static bool? isMono = null; private static bool? isDotNetCore = null; private static bool? debuggerBreak = null; private static TraceCategory traceCategories = TraceCategory.Default; private static bool traceCategoriesSet = false; private static int GetProcessId() { return Process.GetCurrentProcess()?.Id ?? 0; } private static bool IsMono() { try { lock (staticSyncRoot) { if (!isMono.HasValue) { isMono = Type.GetType(MonoRuntimeType) != null; } return isMono.Value; } } catch { } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool IsTraceCategoryEnabled(TraceCategory category) { return (traceCategories & category) == category; } internal static void ResetBreakIntoDebugger() { lock (staticSyncRoot) { debuggerBreak = null; } } internal static void MaybeBreakIntoDebugger(bool enabled) { lock (staticSyncRoot) { if (debuggerBreak.HasValue) { return; } } if (enabled) { try { Console.WriteLine(StringFormat(CultureInfo.CurrentCulture, "Attach a debugger to process {0} and press any key to continue.", GetProcessId())); Console.ReadKey(); } catch (Exception ex) { try { Trace(StringFormat(CultureInfo.CurrentCulture, "Failed to issue debugger prompt, {0} may be unusable: {1}", typeof(Console), ex), TraceCategory.Shared); } catch { } } try { Debugger.Break(); lock (staticSyncRoot) { debuggerBreak = true; return; } } catch { lock (staticSyncRoot) { debuggerBreak = false; } throw; } } lock (staticSyncRoot) { debuggerBreak = false; } } internal static int GetThreadId() { return AppDomain.GetCurrentThreadId(); } internal static bool IsWindows() { PlatformID platform = Environment.OSVersion.Platform; if (platform == PlatformID.Win32S || platform == PlatformID.Win32Windows || platform == PlatformID.Win32NT || platform == PlatformID.WinCE) { return true; } return false; } internal static string StringFormat(IFormatProvider provider, string format, params object[] args) { if (IsMono()) { return string.Format(format, args); } return string.Format(provider, format, args); } internal static bool IsDotNetCore() { try { lock (staticSyncRoot) { if (!isDotNetCore.HasValue) { isDotNetCore = Type.GetType(DotNetCoreLibType) != null; } return isDotNetCore.Value; } } catch { } return false; } internal static TraceCategory? ParseTraceCategories(string value) { if (string.IsNullOrEmpty(value)) { return null; } string[] array = value.Split(SeparatorChars, StringSplitOptions.RemoveEmptyEntries); if (array == null) { return null; } int num = array.Length; if (num == 0) { return null; } TraceCategory traceCategory = TraceCategory.Default; FlagsOperation flagsOperation = FlagsOperation.Add; for (int i = 0; i < num; i++) { string text = array[i]; if (string.IsNullOrEmpty(text)) { continue; } text = text.Trim(); if (string.IsNullOrEmpty(text)) { continue; } switch (text[0]) { case '+': flagsOperation = FlagsOperation.Add; text = text.Substring(1); break; case '-': flagsOperation = FlagsOperation.Remove; text = text.Substring(1); break; case '=': flagsOperation = FlagsOperation.Set; text = text.Substring(1); break; } text = text.Trim(); if (string.IsNullOrEmpty(text)) { continue; } TraceCategory? traceCategory2 = null; try { traceCategory2 = (TraceCategory)Enum.Parse(typeof(TraceCategory), text, ignoreCase: true); } catch (Exception) { } if (traceCategory2.HasValue) { switch (flagsOperation) { case FlagsOperation.Add: traceCategory |= traceCategory2.Value; break; case FlagsOperation.Remove: traceCategory &= ~traceCategory2.Value; break; case FlagsOperation.Set: traceCategory = traceCategory2.Value; break; } } } return traceCategory; } internal static bool AreTraceCategoriesSet() { return traceCategoriesSet; } internal static void SetTraceCategories(TraceCategory categories) { traceCategories = categories; traceCategoriesSet = true; Trace($"Trace categories overridden to: {categories}", TraceCategory.Self); } [Conditional("TRACE")] internal static void Trace(string message, TraceCategory category) { if (IsTraceCategoryEnabled(category)) { System.Diagnostics.Trace.WriteLine(string.Format("[{0}] System.Data.SQLite ({1}): {2}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff"), category, message)); } } internal static string ToDisplayString(object value) { if (value == null) { return "<nullObject>"; } string text = value.ToString(); if (text.Length == 0) { return "<emptyString>"; } if (text.IndexOfAny(SpaceChars) < 0) { return text; } return StringFormat(CultureInfo.InvariantCulture, "\"{0}\"", text); } internal static string ToDisplayString(Array array) { if (array == null) { return "<nullArray>"; } if (array.Length == 0) { return "<emptyArray>"; } StringBuilder stringBuilder = new StringBuilder(); foreach (object item in array) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(ToDisplayString(item)); } if (stringBuilder.Length > 0) { stringBuilder.Insert(0, '['); stringBuilder.Append(']'); } return stringBuilder.ToString(); } internal static bool HasFlags(SQLiteConnectionFlags flags, SQLiteConnectionFlags hasFlags) { return (flags & hasFlags) == hasFlags; } internal static bool LogPrepare(SQLiteConnectionFlags flags) { return HasFlags(flags, SQLiteConnectionFlags.LogPrepare); } internal static bool LogPreBind(SQLiteConnectionFlags flags) { return HasFlags(flags, SQLiteConnectionFlags.LogPreBind); } internal static bool LogBind(SQLiteConnectionFlags flags) { return HasFlags(flags, SQLiteConnectionFlags.LogBind); } internal static bool LogCallbackExceptions(SQLiteConnectionFlags flags) { return HasFlags(flags, SQLiteConnectionFlags.LogCallbackException); } internal static bool LogBackup(SQLiteConnectionFlags flags) { return HasFlags(flags, SQLiteConnectionFlags.LogBackup); } internal static bool NoLogModule(SQLiteConnectionFlags flags) { return HasFlags(flags, SQLiteConnectionFlags.NoLogModule); } internal static bool LogModuleError(SQLiteConnectionFlags flags) { return HasFlags(flags, SQLiteConnectionFlags.LogModuleError); } internal static bool LogModuleException(SQLiteConnectionFlags flags) { return HasFlags(flags, SQLiteConnectionFlags.LogModuleException); } internal static bool LogRetry(SQLiteConnectionFlags flags) { return HasFlags(flags, SQLiteConnectionFlags.LogRetry); } } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SQLiteLogCallback(IntPtr pUserData, int errorCode, IntPtr pMessage); internal class SQLite3 : SQLiteBase { private static object syncRoot = new object(); private IntPtr dbName = IntPtr.Zero; internal const string PublicKey = "002400000480000094000000060200000024000052534131000400000100010005a288de5687c4e1b621ddff5d844727418956997f475eb829429e411aff3e93f97b70de698b972640925bdd44280df0a25a843266973704137cbb0e7441c1fe7cae4e2440ae91ab8cde3933febcb1ac48dd33b40e13c421d8215c18a4349a436dd499e3c385cc683015f886f6c10bd90115eb2bd61b67750839e3a19941dc9c"; internal const string DesignerVersion = "1.0.119.0"; private const string PoolHashFileNamePrefix = "SQLITE_POOL_HASH:"; protected internal SQLiteConnectionHandle _sql; protected string _fileName; protected string _returnToFileName; protected int _maxPoolSize; protected SQLiteConnectionFlags _flags; private bool _setLogCallback; protected bool _usePool; private bool _returnToPool; protected int _poolVersion; private int _cancelCount; private bool _buildingSchema; protected Dictionary<SQLiteFunctionAttribute, SQLiteFunction> _functions; protected string _shimExtensionFileName; protected bool? _shimIsLoadNeeded; protected string _shimExtensionProcName = "sqlite3_vtshim_init"; protected Dictionary<string, SQLiteModule> _modules; private bool _forceLogPrepare; private bool _forceLogRetry; private bool disposed; private static bool? have_errstr = null; private static bool? have_stmt_readonly = null; private static bool? forceLogLifecycle = null; private const int MINIMUM_PAGE_SIZE = 512; private const int MAXIMUM_PAGE_SIZE = 65536; private const int PAGE_SIZE_OFFSET = 16; internal override bool ForceLogPrepare => _forceLogPrepare; internal override bool ForceLogRetry => _forceLogRetry; internal override string Version => SQLiteVersion; internal override int VersionNumber => SQLiteVersionNumber; internal static string ProviderDefineConstants => SQLiteConvert.ToString(SQLiteDefineConstants.OptionList, emptyOnNull: true); internal static string DefineConstants { get { Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); IList<string>[] array = new IList<string>[2] { SQLiteDefineConstants.OptionList, InteropCompileOptionList }; foreach (IList<string> list in array) { if (list == null) { continue; } foreach (string item in list) { if (item != null) { string text = null; if (dictionary.TryGetValue(item, out var value)) { value++; } else if (!item.StartsWith("INTEROP_", StringComparison.OrdinalIgnoreCase)) { text = $"INTEROP_{item}"; value = ((!dictionary.TryGetValue(text, out value)) ? 1 : (value + 1)); } else { value = 1; } dictionary[item] = value; if (text != null) { dictionary[text] = value; } } } } IList<string> list2 = new List<string>(); foreach (KeyValuePair<string, int> item2 in dictionary) { if (item2.Value >= 2) { list2.Add(item2.Key); } } return SQLiteConvert.ToString(list2, emptyOnNull: true); } } internal static string SQLiteVersion => SQLiteConvert.UTF8ToString(UnsafeNativeMethods.sqlite3_libversion(), -1); internal static int SQLiteVersionNumber => UnsafeNativeMethods.sqlite3_libversion_number(); internal static string SQLiteSourceId => SQLiteConvert.UTF8ToString(UnsafeNativeMethods.sqlite3_sourceid(), -1); internal static IList<string> SQLiteCompileOptionList { get { IList<string> list = new List<string>(); int num = 0; IntPtr intPtr = UnsafeNativeMethods.sqlite3_compileoption_get(num++); while (intPtr != IntPtr.Zero) { list.Add(SQLiteConvert.UTF8ToString(intPtr, -1)); intPtr = UnsafeNativeMethods.sqlite3_compileoption_get(num++); } return list; } } internal static string SQLiteCompileOptions => SQLiteConvert.ToString(SQLiteCompileOptionList, emptyOnNull: true); internal static string InteropVersion => SQLiteConvert.UTF8ToString(UnsafeNativeMethods.interop_libversion(), -1); internal static string InteropSourceId => SQLiteConvert.UTF8ToString(UnsafeNativeMethods.interop_sourceid(), -1); internal static IList<string> InteropCompileOptionList { get { IList<string> list = new List<string>(); int num = 0; IntPtr intPtr = UnsafeNativeMethods.interop_compileoption_get(num++); while (intPtr != IntPtr.Zero) { list.Add(SQLiteConvert.UTF8ToString(intPtr, -1)); intPtr = UnsafeNativeMethods.interop_compileoption_get(num++); } return list; } } internal static string InteropCompileOptions => SQLiteConvert.ToString(InteropCompileOptionList, emptyOnNull: true); internal override bool AutoCommit => SQLiteBase.IsAutocommit(_sql, _sql); internal override long LastInsertRowId => UnsafeNativeMethods.sqlite3_last_insert_rowid(_sql); internal override int Changes => UnsafeNativeMethods.sqlite3_changes_interop(_sql); internal override long MemoryUsed => StaticMemoryUsed; internal static long StaticMemoryUsed => UnsafeNativeMethods.sqlite3_memory_used(); internal override long MemoryHighwater => StaticMemoryHighwater; internal static long StaticMemoryHighwater => UnsafeNativeMethods.sqlite3_memory_highwater(0); internal override bool OwnHandle { get { if (_sql == null) { throw new SQLiteException("no connection handle available"); } return _sql.OwnHandle; } } internal override IDictionary<SQLiteFunctionAttribute, SQLiteFunction> Functions => _functions; internal SQLite3(SQLiteDateFormats fmt, DateTimeKind kind, string fmtString, IntPtr db, string fileName, bool ownHandle) : base(fmt, kind, fmtString) { InitializeForceLogPrepare(); InitializeForceLogRetry(); SQLiteConnectionPool.CreateAndInitialize(null, UnsafeNativeMethods.GetSettingValue("SQLite_StrongConnectionPool", null) != null, force: false); if (db != IntPtr.Zero) { _sql = new SQLiteConnectionHandle(db, ownHandle); _fileName = fileName; _returnToFileName = fileName; if (SQLiteConnection.CanOnChanged(null, ignoreDisposed: false)) { SQLiteConnection.OnChanged(null, new ConnectionEventArgs(SQLiteConnectionEventType.NewCriticalHandle, null, null, null, null, _sql, fileName, new object[7] { typeof(SQLite3), fmt, kind, fmtString, db, fileName, ownHandle })); } } } private void InitializeForceLogPrepare() { if (UnsafeNativeMethods.GetSettingValue("SQLite_ForceLogPrepare", null) != null) { _forceLogPrepare = true; } else { _forceLogPrepare = false; } } private void InitializeForceLogRetry() { if (UnsafeNativeMethods.GetSettingValue("SQLite_ForceLogRetry", null) != null) { _forceLogRetry = true; } else { _forceLogRetry = false; } } private void CheckDisposed() { if (disposed) { throw new ObjectDisposedException(typeof(SQLite3).Name); } } protected override void Dispose(bool disposing) { try { if (!disposed) { DisposeModules(); Close(disposing: true); } } finally { base.Dispose(disposing); disposed = true; } } private void DisposeModules() { if (_modules == null) { return; } foreach (KeyValuePair<string, SQLiteModule> module in _modules) { module.Value?.Dispose(); } _modules.Clear(); } internal override bool Close(bool disposing) { SQLiteBase.BumpCloseCount(); if (_sql != null) { if (!_sql.OwnHandle) { _sql = null; return wasDisposed; } bool flag = HelperMethods.HasFlags(_flags, SQLiteConnectionFlags.UnbindFunctionsOnClose); while (true) { string text = HandleToString(); if (_returnToPool || _usePool) { if (SQLiteBase.ResetConnection(_sql, _sql, !disposing) && UnhookNativeCallbacks(includeTrace: true, includeGlobal: true, !disposing)) { if (flag) { if (SQLiteFunction.UnbindAllFunctions(this, _flags, registered: false)) { HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "UnbindFunctions (Pool) Success: {0}", text), TraceCategory.Connection); } else { HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "UnbindFunctions (Pool) Failure: {0}", text), TraceCategory.Connection); } } DisposeModules(); SQLiteConnectionPool.Add(_returnToFileName, _sql, _poolVersion); if (SQLiteConnection.CanOnChanged(null, ignoreDisposed: false)) { SQLiteConnection.OnChanged(null, new ConnectionEventArgs(SQLiteConnectionEventType.ClosedToPool, null, null, null, null, _sql, _returnToFileName, new object[4] { typeof(SQLite3), !disposing, _returnToFileName, _poolVersion })); } HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Close (Pool) Success: {0}", text), TraceCategory.Connection); break; } HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Close (Pool) Failure: {0}", text), TraceCategory.Connection); _returnToFileName = _fileName; _returnToPool = false; _usePool = false; continue; } UnhookNativeCallbacks(includeTrace: false, disposing, !disposing); if (flag) { if (SQLiteFunction.UnbindAllFunctions(this, _flags, registered: false)) { HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "UnbindFunctions Success: {0}", text), TraceCategory.Connection); } else { HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "UnbindFunctions Failure: {0}", text), TraceCategory.Connection); } } _sql.Dispose(); wasDisposed = true; FreeDbName(!disposing); HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Close: {0}", text), TraceCategory.Connection); break; } _sql = null; } if (wasDisposed) { GC.SuppressFinalize(this); } return wasDisposed; } internal override byte[] Serialize(string schema) { bool flag = true; IntPtr intPtr = IntPtr.Zero; IntPtr intPtr2 = IntPtr.Zero; try { if (_sql == null) { return null; } if (schema != null) { intPtr = SQLiteString.Utf8IntPtrFromString(schema); } SQLiteSerializeFlags sQLiteSerializeFlags = SQLiteSerializeFlags.SQLITE_SERIALIZE_NOCOPY; long dataSize = 0L; intPtr2 = UnsafeNativeMethods.sqlite3_serialize(_sql, intPtr, ref dataSize, sQLiteSerializeFlags); if (intPtr2 != IntPtr.Zero) { flag = false; } else { dataSize = 0L; sQLiteSerializeFlags &= ~SQLiteSerializeFlags.SQLITE_SERIALIZE_NOCOPY; intPtr2 = UnsafeNativeMethods.sqlite3_serialize(_sql, intPtr, ref dataSize, sQLiteSerializeFlags); } if (intPtr2 == IntPtr.Zero) { throw new SQLiteException(SQLiteErrorCode.Error, "cannot serialize database"); } if (dataSize < 0) { throw new ArgumentException("data size cannot be negative"); } if (dataSize > int.MaxValue) { throw new ArgumentException($"data size cannot exceed {int.MaxValue}"); } return SQLiteBytes.FromIntPtr(intPtr2, (int)dataSize); } finally { if (flag && intPtr2 != IntPtr.Zero) { SQLiteMemory.Free(intPtr2); intPtr2 = IntPtr.Zero; } if (intPtr != IntPtr.Zero) { SQLiteMemory.Free(intPtr); intPtr = IntPtr.Zero; } } } internal override void Deserialize(string schema, byte[] data, bool readOnly) { bool flag = true; IntPtr intPtr = IntPtr.Zero; IntPtr intPtr2 = IntPtr.Zero; try { if (_sql == null) { throw new SQLiteException("no connection handle available"); } if (data == null) { throw new ArgumentNullException("data"); } long num = data.LongLength; if (num < 0) { throw new ArgumentException("data size cannot be negative"); } if (num > int.MaxValue) { throw new ArgumentException($"data size cannot exceed {int.MaxValue}"); } intPtr2 = SQLiteMemory.Allocate64((ulong)num); if (intPtr2 == IntPtr.Zero) { throw new SQLiteException(SQLiteErrorCode.NoMem, "cannot deserialize database"); } Marshal.Copy(data, 0, intPtr2, (int)num); if (schema != null) { intPtr = SQLiteString.Utf8IntPtrFromString(schema); } SQLiteDeserializeFlags sQLiteDeserializeFlags = SQLiteDeserializeFlags.SQLITE_DESERIALIZE_FREEONCLOSE; sQLiteDeserializeFlags = ((!readOnly) ? (sQLiteDeserializeFlags | SQLiteDeserializeFlags.SQLITE_DESERIALIZE_RESIZEABLE) : (sQLiteDeserializeFlags | SQLiteDeserializeFlags.SQLITE_DESERIALIZE_READONLY)); SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_deserialize(_sql, intPtr, intPtr2, num, num, sQLiteDeserializeFlags); if (sQLiteErrorCode == SQLiteErrorCode.Ok) { flag = false; return; } throw new SQLiteException(sQLiteErrorCode, GetLastError()); } finally { if (flag && intPtr2 != IntPtr.Zero) { SQLiteMemory.Free(intPtr2); intPtr2 = IntPtr.Zero; } if (intPtr != IntPtr.Zero) { SQLiteMemory.Free(intPtr); intPtr = IntPtr.Zero; } } } protected string HandleToString() { if (_sql == null) { return "<null>"; } return _sql.ToString(); } private int GetCancelCount() { return Interlocked.CompareExchange(ref _cancelCount, 0, 0); } private bool ShouldThrowForCancel() { return GetCancelCount() > 0; } private int ResetCancelCount() { return Interlocked.CompareExchange(ref _cancelCount, 0, _cancelCount); } internal override void Cancel() { try { } finally { Interlocked.Increment(ref _cancelCount); UnsafeNativeMethods.sqlite3_interrupt(_sql); } } internal override bool IsCanceled() { return UnsafeNativeMethods.sqlite3_is_interrupted(_sql) != 0; } internal override void BindFunction(SQLiteFunctionAttribute functionAttribute, SQLiteFunction function, SQLiteConnectionFlags flags) { if (functionAttribute == null) { throw new ArgumentNullException("functionAttribute"); } if (function == null) { throw new ArgumentNullException("function"); } SQLiteFunction.BindFunction(this, functionAttribute, function, flags); if (_functions == null) { _functions = new Dictionary<SQLiteFunctionAttribute, SQLiteFunction>(); } _functions[functionAttribute] = function; } internal override bool UnbindFunction(SQLiteFunctionAttribute functionAttribute, SQLiteConnectionFlags flags) { if (functionAttribute == null) { throw new ArgumentNullException("functionAttribute"); } if (_functions == null) { return false; } if (_functions.TryGetValue(functionAttribute, out var value) && SQLiteFunction.UnbindFunction(this, functionAttribute, value, flags) && _functions.Remove(functionAttribute)) { return true; } return false; } internal override bool IsReadOnly(string name) { IntPtr intPtr = IntPtr.Zero; try { if (name != null) { intPtr = SQLiteString.Utf8IntPtrFromString(name); } return UnsafeNativeMethods.sqlite3_db_readonly(_sql, intPtr) switch { -1 => throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "database \"{0}\" not found", name)), 0 => false, _ => true, }; } finally { if (intPtr != IntPtr.Zero) { SQLiteMemory.Free(intPtr); intPtr = IntPtr.Zero; } } } internal override SQLiteErrorCode SetMemoryStatus(bool value) { return StaticSetMemoryStatus(value); } internal static SQLiteErrorCode StaticSetMemoryStatus(bool value) { return UnsafeNativeMethods.sqlite3_config_int(SQLiteConfigOpsEnum.SQLITE_CONFIG_MEMSTATUS, value ? 1 : 0); } internal override SQLiteErrorCode ReleaseMemory() { return UnsafeNativeMethods.sqlite3_db_release_memory(_sql); } internal static SQLiteErrorCode StaticReleaseMemory(int nBytes, bool reset, bool compact, ref int nFree, ref bool resetOk, ref uint nLargest) { SQLiteErrorCode sQLiteErrorCode = SQLiteErrorCode.Ok; int num = UnsafeNativeMethods.sqlite3_release_memory(nBytes); uint largest = 0u; bool flag = false; if (HelperMethods.IsWindows()) { if (sQLiteErrorCode == SQLiteErrorCode.Ok && reset) { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_win32_reset_heap(); if (sQLiteErrorCode == SQLiteErrorCode.Ok) { flag = true; } } if (sQLiteErrorCode == SQLiteErrorCode.Ok && compact) { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_win32_compact_heap(ref largest); } } else if (reset || compact) { sQLiteErrorCode = SQLiteErrorCode.NotFound; } nFree = num; nLargest = largest; resetOk = flag; return sQLiteErrorCode; } internal override SQLiteErrorCode Shutdown() { return StaticShutdown(directories: false); } internal static SQLiteErrorCode StaticShutdown(bool directories) { SQLiteErrorCode sQLiteErrorCode = SQLiteErrorCode.Ok; if (directories) { if (HelperMethods.IsWindows()) { if (sQLiteErrorCode == SQLiteErrorCode.Ok) { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_win32_set_directory(1u, null); } if (sQLiteErrorCode == SQLiteErrorCode.Ok) { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_win32_set_directory(2u, null); } } else { HelperMethods.Trace("Shutdown: Cannot reset directories on this platform.", TraceCategory.Connection); } } if (sQLiteErrorCode == SQLiteErrorCode.Ok) { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_shutdown(); } return sQLiteErrorCode; } internal override bool IsOpen() { if (_sql != null && !_sql.IsInvalid) { return !_sql.IsClosed; } return false; } internal override string GetFileName(string dbName) { if (_sql == null) { return null; } return SQLiteConvert.UTF8ToString(UnsafeNativeMethods.sqlite3_db_filename_bytes(_sql, SQLiteConvert.ToUTF8(dbName)), -1); } protected static bool IsAllowedToUsePool(SQLiteOpenFlagsEnum openFlags) { return openFlags == SQLiteOpenFlagsEnum.Default; } internal override void Open(string strFilename, string vfsName, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool) { SQLiteBase.BumpOpenCount(); if (_sql != null) { Close(disposing: false); } if (_sql != null) { throw new SQLiteException("connection handle is still active"); } _maxPoolSize = maxPoolSize; _returnToPool = false; _usePool = usePool; if (_usePool && !IsAllowedToUsePool(openFlags)) { _usePool = false; } _fileName = strFilename; _returnToFileName = strFilename; _flags = connectionFlags; if (usePool) { _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion); if (SQLiteConnection.CanOnChanged(null, ignoreDisposed: false)) { SQLiteConnection.OnChanged(null, new ConnectionEventArgs(SQLiteConnectionEventType.OpenedFromPool, null, null, null, null, _sql, strFilename, new object[8] { typeof(SQLite3), strFilename, vfsName, connectionFlags, openFlags, maxPoolSize, usePool, _poolVersion })); } HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Open (Pool): {0}", HandleToString()), TraceCategory.Connection); if (_sql == null && HelperMethods.HasFlags(_flags, SQLiteConnectionFlags.ConnectionPoolOnly)) { throw new SQLiteException("no pooled connection available"); } } if (_sql == null) { try { } finally { IntPtr zero = IntPtr.Zero; uint id = (uint)Process.GetCurrentProcess().Id; zero = ((IntPtr.Size != 8) ? new IntPtr(-875717512 | (int)id) : new IntPtr(0x5C71B8C9CBCD9C78L | (long)id)); int num = 0; if (!HelperMethods.HasFlags(connectionFlags, SQLiteConnectionFlags.NoExtensionFunctions)) { num |= 1; } if (HelperMethods.HasFlags(connectionFlags, SQLiteConnectionFlags.NoCoreFunctions)) { num |= 2; } SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_open_interop(SQLiteConvert.ToUTF8(strFilename), SQLiteConvert.ToUTF8(vfsName), openFlags, num, ref zero); HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Open: {0}", zero), TraceCategory.Connection); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, null); } _sql = new SQLiteConnectionHandle(zero, ownHandle: true); SQLiteBase.BumpCreateCount(); } lock (_sql) { } if (SQLiteConnection.CanOnChanged(null, ignoreDisposed: false)) { SQLiteConnection.OnChanged(null, new ConnectionEventArgs(SQLiteConnectionEventType.NewCriticalHandle, null, null, null, null, _sql, strFilename, new object[7] { typeof(SQLite3), strFilename, vfsName, connectionFlags, openFlags, maxPoolSize, usePool })); } } if (!HelperMethods.HasFlags(connectionFlags, SQLiteConnectionFlags.NoBindFunctions)) { if (_functions == null) { _functions = new Dictionary<SQLiteFunctionAttribute, SQLiteFunction>(); } foreach (KeyValuePair<SQLiteFunctionAttribute, SQLiteFunction> item in SQLiteFunction.BindFunctions(this, connectionFlags)) { _functions[item.Key] = item.Value; } } SetTimeout(0); GC.KeepAlive(_sql); } internal override void ClearPool() { SQLiteConnectionPool.ClearPool(_fileName); } internal override int CountPool() { Dictionary<string, int> counts = null; int openCount = 0; int closeCount = 0; int totalCount = 0; SQLiteConnectionPool.GetCounts(_fileName, ref counts, ref openCount, ref closeCount, ref totalCount); return totalCount; } internal override void SetTimeout(int nTimeoutMS) { IntPtr intPtr = _sql; if (intPtr == IntPtr.Zero) { throw new SQLiteException("no connection handle available"); } SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_busy_timeout(intPtr, nTimeoutMS); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override bool Step(SQLiteStatement stmt) { Random random = null; int num = 0; int num2 = 0; int num3 = 0; int stepRetries = SQLiteCommand.GetStepRetries(stmt._command); uint tickCount = (uint)Environment.TickCount; uint num4 = (uint)(stmt._command._commandTimeout * 1000); int maximumSleepTime = stmt._command._maximumSleepTime; SQLiteConnectionFlags flags = SQLiteCommand.GetFlags(stmt._command); ResetCancelCount(); SQLiteErrorCode sQLiteErrorCode2; while (true) { SQLiteErrorCode sQLiteErrorCode; try { } finally { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_step(stmt._sqlite_stmt); } if (ShouldThrowForCancel()) { if (sQLiteErrorCode == SQLiteErrorCode.Ok || sQLiteErrorCode == SQLiteErrorCode.Row || sQLiteErrorCode == SQLiteErrorCode.Done) { sQLiteErrorCode = SQLiteErrorCode.Interrupt; } throw new SQLiteException(sQLiteErrorCode, null); } switch (sQLiteErrorCode) { case SQLiteErrorCode.Ok: continue; case SQLiteErrorCode.Interrupt: return false; case SQLiteErrorCode.Row: return true; case SQLiteErrorCode.Done: return false; case SQLiteErrorCode.Schema: num++; if (stepRetries >= 0 && num > stepRetries) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } stmt._stepSchemaRetries++; break; case SQLiteErrorCode.Busy: case SQLiteErrorCode.Locked: num2++; if (stepRetries >= 0 && num2 > stepRetries) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } stmt._stepLockRetries++; break; default: throw new SQLiteException(sQLiteErrorCode, GetLastError()); } sQLiteErrorCode2 = Reset(stmt); switch (sQLiteErrorCode2) { case SQLiteErrorCode.Ok: throw new SQLiteException(sQLiteErrorCode, GetLastError()); case SQLiteErrorCode.Busy: case SQLiteErrorCode.Locked: { if (stmt._command == null) { break; } if (random == null) { random = new Random(); } if ((uint)(Environment.TickCount - (int)tickCount) > num4) { throw new SQLiteException(sQLiteErrorCode2, GetLastError()); } int num5 = random.Next(1, maximumSleepTime); if (_forceLogRetry || HelperMethods.LogRetry(flags)) { string text = stmt._sqlStatement; if (text == null || text.Length == 0 || text.Trim().Length == 0) { text = "<nothing>"; } SQLiteLog.LogMessage(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Will retry {0} ==> {1} step #{2}, #{3} after {4}ms ({5}): {{{6}}}", sQLiteErrorCode, sQLiteErrorCode2, num, num2, num5, num3, text)); } Thread.Sleep(num5); num3++; continue; } } break; } throw new SQLiteException(sQLiteErrorCode2, GetLastError()); } internal static string GetErrorString(SQLiteErrorCode rc) { try { if (!have_errstr.HasValue) { int sQLiteVersionNumber = SQLiteVersionNumber; have_errstr = sQLiteVersionNumber >= 3007015; } if (have_errstr.Value) { IntPtr intPtr = UnsafeNativeMethods.sqlite3_errstr(rc); if (intPtr != IntPtr.Zero) { return Marshal.PtrToStringAnsi(intPtr); } } } catch (EntryPointNotFoundException) { } return SQLiteBase.FallbackGetErrorString(rc); } internal override bool IsReadOnly(SQLiteStatement stmt) { try { if (!have_stmt_readonly.HasValue) { int sQLiteVersionNumber = SQLiteVersionNumber; have_stmt_readonly = sQLiteVersionNumber >= 3007004; } if (have_stmt_readonly.Value) { return UnsafeNativeMethods.sqlite3_stmt_readonly(stmt._sqlite_stmt) != 0; } } catch (EntryPointNotFoundException) { } return false; } internal override SQLiteErrorCode Reset(SQLiteStatement stmt) { SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_reset_interop(stmt._sqlite_stmt); switch (sQLiteErrorCode) { case SQLiteErrorCode.Schema: { string strRemain = null; using (SQLiteStatement sQLiteStatement = Prepare(null, stmt._command, stmt._sqlStatement, null, (uint)(stmt._command._commandTimeout * 1000), ref strRemain)) { stmt._sqlite_stmt.Dispose(); if (sQLiteStatement != null) { stmt._sqlite_stmt = sQLiteStatement._sqlite_stmt; sQLiteStatement._sqlite_stmt = null; } stmt.BindParameters(); } return SQLiteErrorCode.Unknown; } case SQLiteErrorCode.Busy: case SQLiteErrorCode.Locked: return sQLiteErrorCode; default: throw new SQLiteException(sQLiteErrorCode, GetLastError()); case SQLiteErrorCode.Ok: return sQLiteErrorCode; } } internal override string GetLastError() { return GetLastError(null); } internal override string GetLastError(string defValue) { string text = SQLiteBase.GetLastError(_sql, _sql); if (string.IsNullOrEmpty(text)) { text = defValue; } return text; } internal static bool ForceLogLifecycle() { lock (syncRoot) { if (!forceLogLifecycle.HasValue) { if (UnsafeNativeMethods.GetSettingValue("SQLite_ForceLogLifecycle", null) != null) { forceLogLifecycle = true; } else { forceLogLifecycle = false; } } return forceLogLifecycle.Value; } } internal override SQLiteStatement Prepare(SQLiteConnection cnn, SQLiteCommand command, string strSql, SQLiteStatement previous, uint timeoutMS, ref string strRemain) { if (!string.IsNullOrEmpty(strSql)) { strSql = strSql.Trim(); } if (!string.IsNullOrEmpty(strSql)) { string text = cnn?._baseSchemaName; if (!string.IsNullOrEmpty(text)) { strSql = strSql.Replace(HelperMethods.StringFormat(CultureInfo.InvariantCulture, "[{0}].", text), string.Empty); strSql = strSql.Replace(HelperMethods.StringFormat(CultureInfo.InvariantCulture, "{0}.", text), string.Empty); } } SQLiteConnectionFlags flags = SQLiteConnection.GetFlags(cnn); if (_forceLogPrepare || HelperMethods.LogPrepare(flags)) { string text2 = strSql; if (text2 == null || text2.Length == 0 || text2.Trim().Length == 0) { text2 = "<nothing>"; } SQLiteLog.LogMessage(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Preparing {{{0}}}...", text2)); } SQLiteErrorCode sQLiteErrorCode = SQLiteErrorCode.Schema; int num = 0; int num2 = 0; int num3 = 0; int prepareRetries = SQLiteCommand.GetPrepareRetries(command); int maximumSleepTime = SQLiteCommand.GetMaximumSleepTime(command); byte[] array = SQLiteConvert.ToUTF8(strSql); string text3 = null; SQLiteStatement sQLiteStatement = null; Random random = null; uint tickCount = (uint)Environment.TickCount; ResetCancelCount(); bool flag = false; SQLiteStatementHandle sQLiteStatementHandle = null; try { GCHandle gCHandle = GCHandle.Alloc(array, GCHandleType.Pinned); try { IntPtr ptrRemain = IntPtr.Zero; int nRemain = 0; while (sQLiteErrorCode == SQLiteErrorCode.Schema || sQLiteErrorCode == SQLiteErrorCode.Locked || sQLiteErrorCode == SQLiteErrorCode.Busy) { try { } finally { IntPtr pSql = gCHandle.AddrOfPinnedObject(); IntPtr stmt = IntPtr.Zero; nRemain = 0; sQLiteErrorCode = UnsafeNativeMethods.sqlite3_prepare_interop(_sql, pSql, array.Length - 1, ref stmt, ref ptrRemain, ref nRemain); if (sQLiteErrorCode == SQLiteErrorCode.Ok && stmt != IntPtr.Zero) { sQLiteStatementHandle?.Dispose(); sQLiteStatementHandle = new SQLiteStatementHandle(_sql, stmt); } } if (sQLiteStatementHandle != null && SQLiteConnection.CanOnChanged(null, ignoreDisposed: false)) { SQLiteConnection.OnChanged(null, new ConnectionEventArgs(SQLiteConnectionEventType.NewCriticalHandle, null, null, null, null, sQLiteStatementHandle, strSql, new object[5] { typeof(SQLite3), cnn, strSql, previous, timeoutMS })); } if (ShouldThrowForCancel()) { if (sQLiteErrorCode == SQLiteErrorCode.Ok || sQLiteErrorCode == SQLiteErrorCode.Row || sQLiteErrorCode == SQLiteErrorCode.Done) { sQLiteErrorCode = SQLiteErrorCode.Interrupt; } throw new SQLiteException(sQLiteErrorCode, null); } switch (sQLiteErrorCode) { case SQLiteErrorCode.Schema: num++; if (prepareRetries < 0 || num <= prepareRetries) { continue; } throw new SQLiteException(sQLiteErrorCode, GetLastError()); case SQLiteErrorCode.Error: if (string.Compare(GetLastError(), "near \"TYPES\": syntax error", StringComparison.OrdinalIgnoreCase) == 0) { int num5 = strSql.IndexOf(';'); if (num5 == -1) { num5 = strSql.Length - 1; } text3 = strSql.Substring(0, num5 + 1); strSql = strSql.Substring(num5 + 1); strRemain = string.Empty; while (sQLiteStatement == null && strSql.Length > 0) { sQLiteStatement = Prepare(cnn, command, strSql, previous, timeoutMS, ref strRemain); strSql = strRemain; } if (sQLiteStatement != null) { sQLiteStatement._prepareSchemaRetries = num; sQLiteStatement._prepareLockRetries = num2; sQLiteStatement.SetTypes(text3); } return sQLiteStatement; } if (_buildingSchema || string.Compare(GetLastError(), 0, "no such table: TEMP.SCHEMA", 0, 26, StringComparison.OrdinalIgnoreCase) != 0) { continue; } strRemain = string.Empty; _buildingSchema = true; try { if (((IServiceProvider)SQLiteFactory.Instance).GetService(typeof(ISQLiteSchemaExtensions)) is ISQLiteSchemaExtensions iSQLiteSchemaExtensions) { iSQLiteSchemaExtensions.BuildTempSchema(cnn); } while (sQLiteStatement == null && strSql.Length > 0) { sQLiteStatement = Prepare(cnn, command, strSql, previous, timeoutMS, ref strRemain); strSql = strRemain; } if (sQLiteStatement != null) { sQLiteStatement._prepareSchemaRetries = num; sQLiteStatement._prepareLockRetries = num2; } return sQLiteStatement; } finally { _buildingSchema = false; } case SQLiteErrorCode.Busy: case SQLiteErrorCode.Locked: { num2++; if (prepareRetries >= 0 && num2 > prepareRetries) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } if (random == null) { random = new Random(); } if ((uint)(Environment.TickCount - (int)tickCount) > timeoutMS) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } int num4 = random.Next(1, maximumSleepTime); if (_forceLogRetry || HelperMethods.LogRetry(flags)) { string text4 = strSql; if (text4 == null || text4.Length == 0 || text4.Trim().Length == 0) { text4 = "<nothing>"; } SQLiteLog.LogMessage(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Will retry {0} prepare #{1} after {2}ms ({3}): {{{4}}}", sQLiteErrorCode, num2, num4, num3, text4)); } Thread.Sleep(num4); num3++; continue; } default: continue; case SQLiteErrorCode.Interrupt: break; } break; } if (ShouldThrowForCancel()) { if (sQLiteErrorCode == SQLiteErrorCode.Ok || sQLiteErrorCode == SQLiteErrorCode.Row || sQLiteErrorCode == SQLiteErrorCode.Done) { sQLiteErrorCode = SQLiteErrorCode.Interrupt; } throw new SQLiteException(sQLiteErrorCode, null); } switch (sQLiteErrorCode) { case SQLiteErrorCode.Interrupt: return null; default: throw new SQLiteException(sQLiteErrorCode, GetLastError()); case SQLiteErrorCode.Ok: strRemain = SQLiteConvert.UTF8ToString(ptrRemain, nRemain); if (sQLiteStatementHandle != null) { sQLiteStatement = new SQLiteStatement(this, flags, sQLiteStatementHandle, strSql.Substring(0, strSql.Length - strRemain.Length), previous); } if (sQLiteStatement != null) { sQLiteStatement._prepareSchemaRetries = num; sQLiteStatement._prepareLockRetries = num2; } flag = true; return sQLiteStatement; } } finally { gCHandle.Free(); } } finally { if (!flag) { sQLiteStatementHandle?.Dispose(); } } } protected static void LogBind(SQLiteStatementHandle handle, int index) { IntPtr intPtr = handle; SQLiteLog.LogMessage(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Binding statement {0} paramter #{1} as NULL...", intPtr, index)); } protected static void LogBind(SQLiteStatementHandle handle, int index, ValueType value) { IntPtr intPtr = handle; SQLiteLog.LogMessage(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...", intPtr, index, value.GetType(), value)); } private static string FormatDateTime(DateTime value) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(value.ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFK")); stringBuilder.Append(' '); stringBuilder.Append(value.Kind); stringBuilder.Append(' '); stringBuilder.Append(value.Ticks); return stringBuilder.ToString(); } protected static void LogBind(SQLiteStatementHandle handle, int index, DateTime value) { IntPtr intPtr = handle; SQLiteLog.LogMessage(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...", intPtr, index, typeof(DateTime), FormatDateTime(value))); } protected static void LogBind(SQLiteStatementHandle handle, int index, string value) { IntPtr intPtr = handle; SQLiteLog.LogMessage(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...", intPtr, index, typeof(string), (value != null) ? value : "<null>")); } private static string ToHexadecimalString(byte[] array) { if (array == null) { return null; } StringBuilder stringBuilder = new StringBuilder(array.Length * 2); int num = array.Length; for (int i = 0; i < num; i++) { stringBuilder.Append(array[i].ToString("x2")); } return stringBuilder.ToString(); } protected static void LogBind(SQLiteStatementHandle handle, int index, byte[] value) { IntPtr intPtr = handle; SQLiteLog.LogMessage(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...", intPtr, index, typeof(byte[]), (value != null) ? ToHexadecimalString(value) : "<null>")); } internal override void Bind_Double(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, double value) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, value); } SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_bind_double(sqlite_stmt, index, value); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override void Bind_Int32(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, int value) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, value); } SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_bind_int(sqlite_stmt, index, value); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override void Bind_UInt32(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, uint value) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, value); } SQLiteErrorCode sQLiteErrorCode; if (HelperMethods.HasFlags(flags, SQLiteConnectionFlags.BindUInt32AsInt64)) { long value2 = value; sQLiteErrorCode = UnsafeNativeMethods.sqlite3_bind_int64(sqlite_stmt, index, value2); } else { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_bind_uint(sqlite_stmt, index, value); } if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override void Bind_Int64(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, long value) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, value); } SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_bind_int64(sqlite_stmt, index, value); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override void Bind_UInt64(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, ulong value) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, value); } SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_bind_uint64(sqlite_stmt, index, value); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override void Bind_Boolean(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, bool value) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, value); } int value2 = (value ? 1 : 0); SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_bind_int(sqlite_stmt, index, value2); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override void Bind_Text(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, string value) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, value); } byte[] array = SQLiteConvert.ToUTF8(value); if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, array); } SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_bind_text(sqlite_stmt, index, array, array.Length - 1, (IntPtr)(-1)); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override void Bind_DateTime(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, DateTime dt) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, dt); } if (HelperMethods.HasFlags(flags, SQLiteConnectionFlags.BindDateTimeWithKind) && _datetimeKind != 0 && dt.Kind != 0 && dt.Kind != _datetimeKind) { if (_datetimeKind == DateTimeKind.Utc) { dt = dt.ToUniversalTime(); } else if (_datetimeKind == DateTimeKind.Local) { dt = dt.ToLocalTime(); } } switch (_datetimeFormat) { case SQLiteDateFormats.Ticks: { long ticks = dt.Ticks; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, ticks); } SQLiteErrorCode sQLiteErrorCode4 = UnsafeNativeMethods.sqlite3_bind_int64(sqlite_stmt, index, ticks); if (sQLiteErrorCode4 != 0) { throw new SQLiteException(sQLiteErrorCode4, GetLastError()); } break; } case SQLiteDateFormats.JulianDay: { double num = SQLiteConvert.ToJulianDay(dt); if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, num); } SQLiteErrorCode sQLiteErrorCode2 = UnsafeNativeMethods.sqlite3_bind_double(sqlite_stmt, index, num); if (sQLiteErrorCode2 != 0) { throw new SQLiteException(sQLiteErrorCode2, GetLastError()); } break; } case SQLiteDateFormats.UnixEpoch: { long num2 = dt.Subtract(SQLiteConvert.UnixEpoch).Ticks / 10000000; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, num2); } SQLiteErrorCode sQLiteErrorCode3 = UnsafeNativeMethods.sqlite3_bind_int64(sqlite_stmt, index, num2); if (sQLiteErrorCode3 != 0) { throw new SQLiteException(sQLiteErrorCode3, GetLastError()); } break; } default: { byte[] array = ToUTF8(dt); if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, array); } SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_bind_text(sqlite_stmt, index, array, array.Length - 1, (IntPtr)(-1)); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } break; } } } internal override void Bind_Blob(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, byte[] blobData) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index, blobData); } SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_bind_blob(sqlite_stmt, index, blobData, blobData.Length, (IntPtr)(-1)); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override void Bind_Null(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; if (_forceLogPrepare || HelperMethods.LogBind(flags)) { LogBind(sqlite_stmt, index); } SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_bind_null(sqlite_stmt, index); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override int Bind_ParamCount(SQLiteStatement stmt, SQLiteConnectionFlags flags) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; int num = UnsafeNativeMethods.sqlite3_bind_parameter_count(sqlite_stmt); if (_forceLogPrepare || HelperMethods.LogBind(flags)) { IntPtr intPtr = sqlite_stmt; SQLiteLog.LogMessage(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Statement {0} paramter count is {1}.", intPtr, num)); } return num; } internal override string Bind_ParamName(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; int len = 0; string text = SQLiteConvert.UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name_interop(sqlite_stmt, index, ref len), len); if (_forceLogPrepare || HelperMethods.LogBind(flags)) { IntPtr intPtr = sqlite_stmt; SQLiteLog.LogMessage(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Statement {0} paramter #{1} name is {{{2}}}.", intPtr, index, text)); } return text; } internal override int Bind_ParamIndex(SQLiteStatement stmt, SQLiteConnectionFlags flags, string paramName) { SQLiteStatementHandle sqlite_stmt = stmt._sqlite_stmt; int num = UnsafeNativeMethods.sqlite3_bind_parameter_index(sqlite_stmt, SQLiteConvert.ToUTF8(paramName)); if (_forceLogPrepare || HelperMethods.LogBind(flags)) { IntPtr intPtr = sqlite_stmt; SQLiteLog.LogMessage(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Statement {0} paramter index of name {{{1}}} is #{2}.", intPtr, paramName, num)); } return num; } internal override int ColumnCount(SQLiteStatement stmt) { return UnsafeNativeMethods.sqlite3_column_count(stmt._sqlite_stmt); } internal override string ColumnName(SQLiteStatement stmt, int index) { int len = 0; IntPtr intPtr = UnsafeNativeMethods.sqlite3_column_name_interop(stmt._sqlite_stmt, index, ref len); if (intPtr == IntPtr.Zero) { throw new SQLiteException(SQLiteErrorCode.NoMem, GetLastError()); } return SQLiteConvert.UTF8ToString(intPtr, len); } internal override TypeAffinity ColumnAffinity(SQLiteStatement stmt, int index) { return UnsafeNativeMethods.sqlite3_column_type(stmt._sqlite_stmt, index); } internal override string ColumnType(SQLiteStatement stmt, int index, ref TypeAffinity nAffinity) { int len = 0; IntPtr intPtr = UnsafeNativeMethods.sqlite3_column_decltype_interop(stmt._sqlite_stmt, index, ref len); nAffinity = ColumnAffinity(stmt, index); if (intPtr != IntPtr.Zero && (len > 0 || len == -1)) { string text = SQLiteConvert.UTF8ToString(intPtr, len); if (!string.IsNullOrEmpty(text)) { return text; } } string[] typeDefinitions = stmt.TypeDefinitions; if (typeDefinitions != null && index < typeDefinitions.Length && typeDefinitions[index] != null) { return typeDefinitions[index]; } return string.Empty; } internal override int ColumnIndex(SQLiteStatement stmt, string columnName) { int num = ColumnCount(stmt); for (int i = 0; i < num; i++) { if (string.Compare(columnName, ColumnName(stmt, i), StringComparison.OrdinalIgnoreCase) == 0) { return i; } } return -1; } internal override string ColumnOriginalName(SQLiteStatement stmt, int index) { int len = 0; return SQLiteConvert.UTF8ToString(UnsafeNativeMethods.sqlite3_column_origin_name_interop(stmt._sqlite_stmt, index, ref len), len); } internal override string ColumnDatabaseName(SQLiteStatement stmt, int index) { int len = 0; return SQLiteConvert.UTF8ToString(UnsafeNativeMethods.sqlite3_column_database_name_interop(stmt._sqlite_stmt, index, ref len), len); } internal override string ColumnTableName(SQLiteStatement stmt, int index) { int len = 0; return SQLiteConvert.UTF8ToString(UnsafeNativeMethods.sqlite3_column_table_name_interop(stmt._sqlite_stmt, index, ref len), len); } internal override bool DoesTableExist(string dataBase, string table) { string dataType = null; string collateSequence = null; bool notNull = false; bool primaryKey = false; bool autoIncrement = false; return ColumnMetaData(dataBase, table, null, canThrow: false, ref dataType, ref collateSequence, ref notNull, ref primaryKey, ref autoIncrement); } internal override bool ColumnMetaData(string dataBase, string table, string column, bool canThrow, ref string dataType, ref string collateSequence, ref bool notNull, ref bool primaryKey, ref bool autoIncrement) { IntPtr ptrDataType = IntPtr.Zero; IntPtr ptrCollSeq = IntPtr.Zero; int notNull2 = 0; int primaryKey2 = 0; int autoInc = 0; int dtLen = 0; int csLen = 0; SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_table_column_metadata_interop(_sql, SQLiteConvert.ToUTF8(dataBase), SQLiteConvert.ToUTF8(table), SQLiteConvert.ToUTF8(column), ref ptrDataType, ref ptrCollSeq, ref notNull2, ref primaryKey2, ref autoInc, ref dtLen, ref csLen); if (canThrow && sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } dataType = SQLiteConvert.UTF8ToString(ptrDataType, dtLen); collateSequence = SQLiteConvert.UTF8ToString(ptrCollSeq, csLen); notNull = notNull2 == 1; primaryKey = primaryKey2 == 1; autoIncrement = autoInc == 1; return sQLiteErrorCode == SQLiteErrorCode.Ok; } internal override object GetObject(SQLiteStatement stmt, int index) { switch (ColumnAffinity(stmt, index)) { case TypeAffinity.Int64: return GetInt64(stmt, index); case TypeAffinity.Double: return GetDouble(stmt, index); case TypeAffinity.Text: return GetText(stmt, index); case TypeAffinity.Blob: { long bytes = GetBytes(stmt, index, 0, null, 0, 0); if (bytes > 0 && bytes <= int.MaxValue) { byte[] array = new byte[(int)bytes]; GetBytes(stmt, index, 0, array, 0, (int)bytes); return array; } break; } case TypeAffinity.Null: return DBNull.Value; } throw new NotImplementedException(); } internal override double GetDouble(SQLiteStatement stmt, int index) { return UnsafeNativeMethods.sqlite3_column_double(stmt._sqlite_stmt, index); } internal override bool GetBoolean(SQLiteStatement stmt, int index) { return SQLiteConvert.ToBoolean(GetObject(stmt, index), CultureInfo.InvariantCulture, viaFramework: false); } internal override sbyte GetSByte(SQLiteStatement stmt, int index) { return (sbyte)(GetInt32(stmt, index) & 0xFF); } internal override byte GetByte(SQLiteStatement stmt, int index) { return (byte)((uint)GetInt32(stmt, index) & 0xFFu); } internal override short GetInt16(SQLiteStatement stmt, int index) { return (short)(GetInt32(stmt, index) & 0xFFFF); } internal override ushort GetUInt16(SQLiteStatement stmt, int index) { return (ushort)((uint)GetInt32(stmt, index) & 0xFFFFu); } internal override int GetInt32(SQLiteStatement stmt, int index) { return UnsafeNativeMethods.sqlite3_column_int(stmt._sqlite_stmt, index); } internal override uint GetUInt32(SQLiteStatement stmt, int index) { return (uint)GetInt32(stmt, index); } internal override long GetInt64(SQLiteStatement stmt, int index) { return UnsafeNativeMethods.sqlite3_column_int64(stmt._sqlite_stmt, index); } internal override ulong GetUInt64(SQLiteStatement stmt, int index) { return (ulong)GetInt64(stmt, index); } internal override string GetText(SQLiteStatement stmt, int index) { int len = 0; return SQLiteConvert.UTF8ToString(UnsafeNativeMethods.sqlite3_column_text_interop(stmt._sqlite_stmt, index, ref len), len); } internal override DateTime GetDateTime(SQLiteStatement stmt, int index) { if (_datetimeFormat == SQLiteDateFormats.Ticks) { return SQLiteConvert.TicksToDateTime(GetInt64(stmt, index), _datetimeKind); } if (_datetimeFormat == SQLiteDateFormats.JulianDay) { return SQLiteConvert.ToDateTime(GetDouble(stmt, index), _datetimeKind); } if (_datetimeFormat == SQLiteDateFormats.UnixEpoch) { return SQLiteConvert.UnixEpochToDateTime(GetInt64(stmt, index), _datetimeKind); } int len = 0; return ToDateTime(UnsafeNativeMethods.sqlite3_column_text_interop(stmt._sqlite_stmt, index, ref len), len); } internal override long GetBytes(SQLiteStatement stmt, int index, int nDataOffset, byte[] bDest, int nStart, int nLength) { int num = UnsafeNativeMethods.sqlite3_column_bytes(stmt._sqlite_stmt, index); if (bDest == null) { return num; } int num2 = nLength; if (num2 + nStart > bDest.Length) { num2 = bDest.Length - nStart; } if (num2 + nDataOffset > num) { num2 = num - nDataOffset; } if (num2 > 0) { Marshal.Copy((IntPtr)(UnsafeNativeMethods.sqlite3_column_blob(stmt._sqlite_stmt, index).ToInt64() + nDataOffset), bDest, nStart, num2); } else { num2 = 0; } return num2; } internal override char GetChar(SQLiteStatement stmt, int index) { return Convert.ToChar(GetUInt16(stmt, index)); } internal override long GetChars(SQLiteStatement stmt, int index, int nDataOffset, char[] bDest, int nStart, int nLength) { int num = nLength; string text = GetText(stmt, index); int length = text.Length; if (bDest == null) { return length; } if (num + nStart > bDest.Length) { num = bDest.Length - nStart; } if (num + nDataOffset > length) { num = length - nDataOffset; } if (num > 0) { text.CopyTo(nDataOffset, bDest, nStart, num); } else { num = 0; } return num; } internal override bool IsNull(SQLiteStatement stmt, int index) { return ColumnAffinity(stmt, index) == TypeAffinity.Null; } internal override int AggregateCount(IntPtr context) { return UnsafeNativeMethods.sqlite3_aggregate_count(context); } internal override SQLiteErrorCode CreateFunction(FunctionType type, string strFunction, int nArgs, SQLiteFunctionFlags flags, bool needCollSeq, SQLiteCallback func, SQLiteCallback funcstep, SQLiteFinalCallback funcfinal, SQLiteFinalCallback funcvalue, SQLiteCallback funcinverse, bool canThrow) { SQLiteFunctionFlags nType = SQLiteFunctionFlags.SQLITE_UTF16 | (flags & ~SQLiteFunctionFlags.ENCODING_MASK); SQLiteFunctionFlags nType2 = SQLiteFunctionFlags.SQLITE_UTF8 | (flags & ~SQLiteFunctionFlags.ENCODING_MASK); SQLiteErrorCode sQLiteErrorCode; if (type == FunctionType.Window) { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_create_window_function_interop(_sql, SQLiteConvert.ToUTF8(strFunction), nArgs, nType, IntPtr.Zero, funcstep, funcfinal, funcvalue, funcinverse, needCollSeq ? 1 : 0); if (sQLiteErrorCode == SQLiteErrorCode.Ok) { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_create_window_function_interop(_sql, SQLiteConvert.ToUTF8(strFunction), nArgs, nType2, IntPtr.Zero, funcstep, funcfinal, funcvalue, funcinverse, needCollSeq ? 1 : 0); } } else { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_create_function_interop(_sql, SQLiteConvert.ToUTF8(strFunction), nArgs, nType, IntPtr.Zero, func, funcstep, funcfinal, needCollSeq ? 1 : 0); if (sQLiteErrorCode == SQLiteErrorCode.Ok) { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_create_function_interop(_sql, SQLiteConvert.ToUTF8(strFunction), nArgs, nType2, IntPtr.Zero, func, funcstep, funcfinal, needCollSeq ? 1 : 0); } } if (canThrow && sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } return sQLiteErrorCode; } internal override SQLiteErrorCode CreateCollation(string strCollation, SQLiteCollation func, SQLiteCollation func16, bool canThrow) { SQLiteFunctionFlags nType = SQLiteFunctionFlags.SQLITE_UTF16LE; SQLiteFunctionFlags nType2 = SQLiteFunctionFlags.SQLITE_UTF8; SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_create_collation(_sql, SQLiteConvert.ToUTF8(strCollation), nType, IntPtr.Zero, func16); if (sQLiteErrorCode == SQLiteErrorCode.Ok) { sQLiteErrorCode = UnsafeNativeMethods.sqlite3_create_collation(_sql, SQLiteConvert.ToUTF8(strCollation), nType2, IntPtr.Zero, func); } if (canThrow && sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } return sQLiteErrorCode; } internal override int ContextCollateCompare(CollationEncodingEnum enc, IntPtr context, string s1, string s2) { Encoding encoding = null; switch (enc) { case CollationEncodingEnum.UTF8: encoding = Encoding.UTF8; break; case CollationEncodingEnum.UTF16LE: encoding = Encoding.Unicode; break; case CollationEncodingEnum.UTF16BE: encoding = Encoding.BigEndianUnicode; break; } byte[] bytes = encoding.GetBytes(s1); byte[] bytes2 = encoding.GetBytes(s2); return UnsafeNativeMethods.sqlite3_context_collcompare_interop(context, bytes, bytes.Length, bytes2, bytes2.Length); } internal override int ContextCollateCompare(CollationEncodingEnum enc, IntPtr context, char[] c1, char[] c2) { Encoding encoding = null; switch (enc) { case CollationEncodingEnum.UTF8: encoding = Encoding.UTF8; break; case CollationEncodingEnum.UTF16LE: encoding = Encoding.Unicode; break; case CollationEncodingEnum.UTF16BE: encoding = Encoding.BigEndianUnicode; break; } byte[] bytes = encoding.GetBytes(c1); byte[] bytes2 = encoding.GetBytes(c2); return UnsafeNativeMethods.sqlite3_context_collcompare_interop(context, bytes, bytes.Length, bytes2, bytes2.Length); } internal override CollationSequence GetCollationSequence(SQLiteFunction func, IntPtr context) { CollationSequence result = default(CollationSequence); int len = 0; int type = 0; int enc = 0; IntPtr nativestring = UnsafeNativeMethods.sqlite3_context_collseq_interop(context, ref type, ref enc, ref len); result.Name = SQLiteConvert.UTF8ToString(nativestring, len); result.Type = (CollationTypeEnum)type; result._func = func; result.Encoding = (CollationEncodingEnum)enc; return result; } internal override long GetParamValueBytes(IntPtr p, int nDataOffset, byte[] bDest, int nStart, int nLength) { int num = UnsafeNativeMethods.sqlite3_value_bytes(p); if (bDest == null) { return num; } int num2 = nLength; if (num2 + nStart > bDest.Length) { num2 = bDest.Length - nStart; } if (num2 + nDataOffset > num) { num2 = num - nDataOffset; } if (num2 > 0) { Marshal.Copy((IntPtr)(UnsafeNativeMethods.sqlite3_value_blob(p).ToInt64() + nDataOffset), bDest, nStart, num2); } else { num2 = 0; } return num2; } internal override double GetParamValueDouble(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_double(ptr); } internal override int GetParamValueInt32(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_int(ptr); } internal override long GetParamValueInt64(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_int64(ptr); } internal override string GetParamValueText(IntPtr ptr) { int len = 0; return SQLiteConvert.UTF8ToString(UnsafeNativeMethods.sqlite3_value_text_interop(ptr, ref len), len); } internal override TypeAffinity GetParamValueType(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_type(ptr); } internal override uint GetParamValueSubType(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_subtype(ptr); } internal override TypeAffinity GetParamValueNumericType(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_numeric_type(ptr); } internal override int GetParamValueNoChange(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_nochange(ptr); } internal override int GetParamValueFromBind(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_frombind(ptr); } internal override void ReturnBlob(IntPtr context, byte[] value) { UnsafeNativeMethods.sqlite3_result_blob(context, value, value.Length, (IntPtr)(-1)); } internal override void ReturnDouble(IntPtr context, double value) { UnsafeNativeMethods.sqlite3_result_double(context, value); } internal override void ReturnError(IntPtr context, string value) { UnsafeNativeMethods.sqlite3_result_error(context, SQLiteConvert.ToUTF8(value), value.Length); } internal override void ReturnInt32(IntPtr context, int value) { UnsafeNativeMethods.sqlite3_result_int(context, value); } internal override void ReturnInt64(IntPtr context, long value) { UnsafeNativeMethods.sqlite3_result_int64(context, value); } internal override void ReturnNull(IntPtr context) { UnsafeNativeMethods.sqlite3_result_null(context); } internal override void ReturnText(IntPtr context, string value) { byte[] array = SQLiteConvert.ToUTF8(value); UnsafeNativeMethods.sqlite3_result_text(context, SQLiteConvert.ToUTF8(value), array.Length - 1, (IntPtr)(-1)); } internal override void ReturnSubType(IntPtr context, uint value) { UnsafeNativeMethods.sqlite3_result_subtype(context, value); } private string GetShimExtensionFileName(ref bool isLoadNeeded) { if (_shimIsLoadNeeded.HasValue) { isLoadNeeded = _shimIsLoadNeeded.Value; } else { isLoadNeeded = HelperMethods.IsWindows(); } string shimExtensionFileName = _shimExtensionFileName; if (shimExtensionFileName != null) { return shimExtensionFileName; } return UnsafeNativeMethods.GetNativeLibraryFileNameOnly(); } internal override void CreateModule(SQLiteModule module, SQLiteConnectionFlags flags) { if (module == null) { throw new ArgumentNullException("module"); } if (HelperMethods.NoLogModule(flags)) { module.LogErrors = HelperMethods.LogModuleError(flags); module.LogExceptions = HelperMethods.LogModuleException(flags); } if (_sql == null) { throw new SQLiteException("connection has an invalid handle"); } bool isLoadNeeded = false; string shimExtensionFileName = GetShimExtensionFileName(ref isLoadNeeded); if (isLoadNeeded) { if (shimExtensionFileName == null) { throw new SQLiteException("the file name for the \"vtshim\" extension is unknown"); } if (_shimExtensionProcName == null) { throw new SQLiteException("the entry point for the \"vtshim\" extension is unknown"); } SetLoadExtension(bOnOff: true); LoadExtension(shimExtensionFileName, _shimExtensionProcName); } if (module.CreateDisposableModule(_sql)) { if (_modules == null) { _modules = new Dictionary<string, SQLiteModule>(); } _modules.Add(module.Name, module); if (_usePool) { _usePool = false; HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "CreateModule (Pool) Disabled: {0}", HandleToString()), TraceCategory.Connection); } return; } throw new SQLiteException(GetLastError()); } internal override void DisposeModule(SQLiteModule module, SQLiteConnectionFlags flags) { if (module == null) { throw new ArgumentNullException("module"); } module.Dispose(); } internal override IntPtr AggregateContext(IntPtr context) { return UnsafeNativeMethods.sqlite3_aggregate_context(context, 1); } internal override SQLiteErrorCode DeclareVirtualTable(SQLiteModule module, string strSql, ref string error) { if (_sql == null) { error = "connection has an invalid handle"; return SQLiteErrorCode.Error; } IntPtr intPtr = IntPtr.Zero; try { intPtr = SQLiteString.Utf8IntPtrFromString(strSql); SQLiteErrorCode num = UnsafeNativeMethods.sqlite3_declare_vtab(_sql, intPtr); if (num == SQLiteErrorCode.Ok && module != null) { module.Declared = true; } if (num != 0) { error = GetLastError(); } return num; } finally { if (intPtr != IntPtr.Zero) { SQLiteMemory.Free(intPtr); intPtr = IntPtr.Zero; } } } internal override SQLiteErrorCode DeclareVirtualFunction(SQLiteModule module, int argumentCount, string name, ref string error) { if (_sql == null) { error = "connection has an invalid handle"; return SQLiteErrorCode.Error; } IntPtr intPtr = IntPtr.Zero; try { intPtr = SQLiteString.Utf8IntPtrFromString(name); SQLiteErrorCode num = UnsafeNativeMethods.sqlite3_overload_function(_sql, intPtr, argumentCount); if (num != 0) { error = GetLastError(); } return num; } finally { if (intPtr != IntPtr.Zero) { SQLiteMemory.Free(intPtr); intPtr = IntPtr.Zero; } } } private static string GetStatusDbOpsNames() { StringBuilder stringBuilder = new StringBuilder(); string[] names = Enum.GetNames(typeof(SQLiteStatusOpsEnum)); foreach (string value in names) { if (!string.IsNullOrEmpty(value)) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(value); } } return stringBuilder.ToString(); } private static string GetLimitOpsNames() { StringBuilder stringBuilder = new StringBuilder(); string[] names = Enum.GetNames(typeof(SQLiteLimitOpsEnum)); foreach (string value in names) { if (!string.IsNullOrEmpty(value)) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(value); } } return stringBuilder.ToString(); } private static string GetConfigDbOpsNames() { StringBuilder stringBuilder = new StringBuilder(); string[] names = Enum.GetNames(typeof(SQLiteConfigDbOpsEnum)); foreach (string value in names) { if (!string.IsNullOrEmpty(value)) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(value); } } return stringBuilder.ToString(); } internal override SQLiteErrorCode GetStatusParameter(SQLiteStatusOpsEnum option, bool reset, ref int current, ref int highwater) { if (!Enum.IsDefined(typeof(SQLiteStatusOpsEnum), option)) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "unrecognized status option, must be: {0}", GetStatusDbOpsNames())); } return UnsafeNativeMethods.sqlite3_db_status(_sql, option, ref current, ref highwater, reset ? 1 : 0); } internal override int SetLimitOption(SQLiteLimitOpsEnum option, int value) { if (!Enum.IsDefined(typeof(SQLiteLimitOpsEnum), option)) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "unrecognized limit option, must be: {0}", GetLimitOpsNames())); } return UnsafeNativeMethods.sqlite3_limit(_sql, option, value); } internal override SQLiteErrorCode SetConfigurationOption(SQLiteConfigDbOpsEnum option, object value) { if (!Enum.IsDefined(typeof(SQLiteConfigDbOpsEnum), option)) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "unrecognized configuration option, must be: {0}", GetConfigDbOpsNames())); } switch (option) { case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_NONE: return SQLiteErrorCode.Ok; case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_MAINDBNAME: { if (value == null) { throw new ArgumentNullException("value"); } if (!(value is string)) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "configuration value type mismatch, must be of type {0}", typeof(string))); } SQLiteErrorCode sQLiteErrorCode = SQLiteErrorCode.Error; IntPtr intPtr = IntPtr.Zero; try { intPtr = SQLiteString.Utf8IntPtrFromString((string)value); if (intPtr == IntPtr.Zero) { throw new SQLiteException(SQLiteErrorCode.NoMem, "cannot allocate database name"); } sQLiteErrorCode = UnsafeNativeMethods.sqlite3_db_config_charptr(_sql, option, intPtr); if (sQLiteErrorCode == SQLiteErrorCode.Ok) { FreeDbName(canThrow: true); dbName = intPtr; intPtr = IntPtr.Zero; } } finally { if (sQLiteErrorCode != 0 && intPtr != IntPtr.Zero) { SQLiteMemory.Free(intPtr); intPtr = IntPtr.Zero; } } return sQLiteErrorCode; } case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_LOOKASIDE: if (!(value is object[] array)) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "configuration value type mismatch, must be of type {0}", typeof(object[]))); } if (!(array[0] is IntPtr)) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "configuration element zero (0) type mismatch, must be of type {0}", typeof(IntPtr))); } if (!(array[1] is int)) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "configuration element one (1) type mismatch, must be of type {0}", typeof(int))); } if (!(array[2] is int)) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "configuration element two (2) type mismatch, must be of type {0}", typeof(int))); } return UnsafeNativeMethods.sqlite3_db_config_intptr_two_ints(_sql, option, (IntPtr)array[0], (int)array[1], (int)array[2]); case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_ENABLE_FKEY: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_ENABLE_TRIGGER: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_ENABLE_QPSG: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_TRIGGER_EQP: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_RESET_DATABASE: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_DEFENSIVE: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_WRITABLE_SCHEMA: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_LEGACY_ALTER_TABLE: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_DQS_DML: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_DQS_DDL: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_ENABLE_VIEW: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_LEGACY_FILE_FORMAT: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_TRUSTED_SCHEMA: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_STMT_SCANSTATUS: case SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_REVERSE_SCANORDER: { if (!(value is bool)) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "configuration value type mismatch, must be of type {0}", typeof(bool))); } int result = 0; return UnsafeNativeMethods.sqlite3_db_config_int_refint(_sql, option, ((bool)value) ? 1 : 0, ref result); } default: throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "unsupported configuration option {0}", option)); } } internal override void SetLoadExtension(bool bOnOff) { SQLiteErrorCode sQLiteErrorCode = ((SQLiteVersionNumber < 3013000) ? UnsafeNativeMethods.sqlite3_enable_load_extension(_sql, bOnOff ? (-1) : 0) : SetConfigurationOption(SQLiteConfigDbOpsEnum.SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, bOnOff)); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override void LoadExtension(string fileName, string procName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } IntPtr pError = IntPtr.Zero; try { byte[] bytes = Encoding.UTF8.GetBytes(fileName + "\0"); byte[] procName2 = null; if (procName != null) { procName2 = Encoding.UTF8.GetBytes(procName + "\0"); } SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_load_extension(_sql, bytes, procName2, ref pError); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, SQLiteConvert.UTF8ToString(pError, -1)); } } finally { if (pError != IntPtr.Zero) { UnsafeNativeMethods.sqlite3_free(pError); pError = IntPtr.Zero; } } } internal override void SetExtendedResultCodes(bool bOnOff) { SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_extended_result_codes(_sql, bOnOff ? (-1) : 0); if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } } internal override SQLiteErrorCode ResultCode() { return UnsafeNativeMethods.sqlite3_errcode(_sql); } internal override SQLiteErrorCode ExtendedResultCode() { return UnsafeNativeMethods.sqlite3_extended_errcode(_sql); } internal override void LogMessage(SQLiteErrorCode iErrCode, string zMessage) { StaticLogMessage(iErrCode, zMessage); } internal static void StaticLogMessage(SQLiteErrorCode iErrCode, string zMessage) { UnsafeNativeMethods.sqlite3_log(iErrCode, SQLiteConvert.ToUTF8(zMessage)); } private static int GetLegacyDatabasePageSize(SQLiteConnection connection, string fileName, byte[] passwordBytes, int? pageSize) { if (pageSize.HasValue) { return pageSize.Value; } using FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None); byte[] array = new byte[512]; int num = array.Length; int num2 = fileStream.Read(array, 0, num); if (num2 != num) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.InvariantCulture, "read {0} encrypted page bytes, expected {1} (1)", num2, num)); } byte[] outputBytes = null; DecryptLegacyDatabasePage(connection, passwordBytes, array, ref outputBytes); if (outputBytes == null) { throw new SQLiteException("failed to decrypt page (1)"); } int num3 = outputBytes.Length; if (num3 != num) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.InvariantCulture, "got {0} decrypted page bytes, expected {1} (1)", num3, num)); } int num4 = 18; if (num3 < num4) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.InvariantCulture, "got {0} decrypted page bytes, need at least {1}", num3, num4)); } return (outputBytes[16] << 8) | outputBytes[17]; } private static void DecryptLegacyDatabasePage(SQLiteConnection connection, byte[] passwordBytes, byte[] inputBytes, ref byte[] outputBytes) { using SQLiteCommand sQLiteCommand = connection.CreateCommand(); sQLiteCommand.CommandText = "SELECT cryptoapi_decrypt(?, ?);"; SQLiteParameter sQLiteParameter = sQLiteCommand.CreateParameter(); sQLiteParameter.ParameterName = "dataBlob"; sQLiteParameter.DbType = DbType.Binary; sQLiteParameter.Value = inputBytes; sQLiteCommand.Parameters.Add(sQLiteParameter); sQLiteParameter = sQLiteCommand.CreateParameter(); sQLiteParameter.ParameterName = "passwordBlob"; sQLiteParameter.DbType = DbType.Binary; sQLiteParameter.Value = passwordBytes; sQLiteCommand.Parameters.Add(sQLiteParameter); using SQLiteDataReader sQLiteDataReader = sQLiteCommand.ExecuteReader(); List<byte> list = null; while (sQLiteDataReader.Read()) { if (sQLiteDataReader[0] is byte[] array) { if (list == null) { list = new List<byte>(array.Length); } list.AddRange(array); } } if (list != null) { outputBytes = list.ToArray(); } } private static void DecryptLegacyDatabasePage(SQLiteConnection connection, FileStream inputStream, FileStream outputStream, int pageSize, byte[] passwordBytes, byte[] inputBytes, ref long totalReadCount, ref long totalWriteCount) { if (inputBytes == null) { throw new SQLiteException("invalid input buffer"); } int num = inputBytes.Length; if (num != pageSize) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.InvariantCulture, "input buffer is sized {0} bytes, need {1}", num, pageSize)); } Array.Clear(inputBytes, 0, num); int num2 = inputStream.Read(inputBytes, 0, pageSize); if (num2 != pageSize) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.InvariantCulture, "read {0} encrypted page bytes, expected {1} (2)", num2, pageSize)); } totalReadCount += num2; byte[] outputBytes = null; DecryptLegacyDatabasePage(connection, passwordBytes, inputBytes, ref outputBytes); if (outputBytes == null) { throw new SQLiteException("failed to decrypt page (2)"); } int num3 = outputBytes.Length; if (num3 != num) { throw new SQLiteException(HelperMethods.StringFormat(CultureInfo.InvariantCulture, "got {0} decrypted page bytes, expected {1} (2)", num3, num)); } outputStream.Write(outputBytes, 0, num3); totalWriteCount += num3; } internal static string DecryptLegacyDatabase(string fileName, byte[] passwordBytes, int? pageSize, SQLiteProgressEventHandler progress) { SQLiteExtra.Verify(null); if (string.IsNullOrEmpty(fileName)) { throw new SQLiteException("invalid file name"); } if (!File.Exists(fileName)) { throw new SQLiteException("named file does not exist"); } using SQLiteConnection sQLiteConnection = new SQLiteConnection(); if (progress != null) { sQLiteConnection.Progress += progress; } sQLiteConnection.ConnectionString = SQLiteCommand.DefaultConnectionString; sQLiteConnection.Open(); sQLiteConnection.EnableExtensions(enable: true); sQLiteConnection.LoadExtension(UnsafeNativeMethods.GetNativeModuleFileName(), "sqlite3_cryptoapi_init"); int legacyDatabasePageSize = GetLegacyDatabasePageSize(sQLiteConnection, fileName, passwordBytes, pageSize); if (legacyDatabasePageSize == 0) { throw new SQLiteException("page size cannot be zero"); } if (legacyDatabasePageSize < 512 || legacyDatabasePageSize > 65536) { throw new SQLiteException("page size out-of-range"); } if (((uint)legacyDatabasePageSize & (true ? 1u : 0u)) != 0) { throw new SQLiteException("page size is odd"); } long length = new FileInfo(fileName).Length; if (length % legacyDatabasePageSize != 0L) { throw new SQLiteException("data not multiple of page size"); } using FileStream inputStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None); string text = string.Format("{0}-decrypted-{1}-{2}", fileName, DateTime.UtcNow.ToString("yyyy_MM_dd"), Environment.TickCount.ToString("X")); using (FileStream outputStream = new FileStream(text, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { byte[] inputBytes = new byte[legacyDatabasePageSize]; long totalReadCount = 0L; long totalWriteCount = 0L; while (totalReadCount < length) { DecryptLegacyDatabasePage(sQLiteConnection, inputStream, outputStream, legacyDatabasePageSize, passwordBytes, inputBytes, ref totalReadCount, ref totalWriteCount); } if (totalReadCount != length) { throw new SQLiteException("encrypted data was not totally read"); } if (totalWriteCount != totalReadCount) { throw new SQLiteException("decrypted data was not totally written"); } } return text; } private static void ZeroPassword(byte[] passwordBytes) { if (passwordBytes != null) { for (int i = 0; i < passwordBytes.Length; i++) { byte b = (passwordBytes[i] = (byte)((i + 1) % 255)); passwordBytes[i] ^= b; } } } private static byte[] CalculatePoolHash(string fileName, byte[] passwordBytes, bool asText) { try { using SHA512 sHA = SHA512.Create(); sHA.Initialize(); byte[] bytes; if (fileName != null) { bytes = Encoding.Unicode.GetBytes(fileName); sHA.TransformBlock(bytes, 0, bytes.Length, null, 0); } if (passwordBytes != null) { sHA.TransformBlock(passwordBytes, 0, passwordBytes.Length, null, 0); } bytes = BitConverter.GetBytes(asText); sHA.TransformFinalBlock(bytes, 0, bytes.Length); return sHA.Hash; } catch (Exception ex) { try { Trace.WriteLine(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Failed to calculate pool hash: {0}", ex)); } catch { } } return null; } private static string CalculatePoolFileName(string fileName, byte[] poolHash) { if (string.IsNullOrEmpty(fileName)) { return null; } if (poolHash == null) { return null; } string text = "SQLITE_POOL_HASH:"; string text2 = HelperMethods.StringFormat(CultureInfo.InvariantCulture, ":{0}", Convert.ToBase64String(poolHash)); if (fileName.StartsWith(text, StringComparison.Ordinal)) { return null; } return HelperMethods.StringFormat(CultureInfo.InvariantCulture, "{0}:{1}{2}", text, fileName, text2); } private bool TryToUsePool(int maxPoolSize, string fileName, byte[] passwordBytes, bool asText, ref string returnToFileName) { if (string.IsNullOrEmpty(fileName)) { return false; } byte[] array = CalculatePoolHash(fileName, passwordBytes, asText); if (array == null) { return false; } string text = CalculatePoolFileName(fileName, array); if (text == null) { return false; } bool flag = false; SQLiteConnectionHandle sQLiteConnectionHandle = null; try { sQLiteConnectionHandle = SQLiteConnectionPool.Remove(text, maxPoolSize, out var version); if (sQLiteConnectionHandle != null) { SQLiteConnectionPool.ClearPool(fileName); SQLiteConnection.OnChanged(null, new ConnectionEventArgs(SQLiteConnectionEventType.OpenedFromPool, null, null, null, null, sQLiteConnectionHandle, text, new object[1] { fileName })); if (_sql != null) { UnhookNativeCallbacks(includeTrace: false, includeGlobal: true, canThrow: true); _sql.Dispose(); _sql = null; FreeDbName(canThrow: true); } _fileName = text; _sql = sQLiteConnectionHandle; _poolVersion = version; flag = true; } } finally { if (!flag && sQLiteConnectionHandle != null) { sQLiteConnectionHandle.Dispose(); sQLiteConnectionHandle = null; } } returnToFileName = text; return flag; } internal override void SetPassword(byte[] passwordBytes, bool asText) { string returnToFileName = null; if (_usePool && TryToUsePool(_maxPoolSize, _fileName, passwordBytes, asText, ref returnToFileName)) { if (returnToFileName != null) { _returnToFileName = returnToFileName; } _returnToPool = true; return; } SQLiteExtra.Verify(null); int keylen = ((asText && passwordBytes != null) ? (-1) : ((passwordBytes != null) ? passwordBytes.Length : 0)); SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_key(_sql, passwordBytes, keylen); if (HelperMethods.HasFlags(_flags, SQLiteConnectionFlags.HidePassword)) { ZeroPassword(passwordBytes); } if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } if (_usePool) { if (returnToFileName != null) { _returnToFileName = returnToFileName; } _usePool = false; _returnToPool = true; HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "SetPassword (Pool) Disabled: {0}", HandleToString()), TraceCategory.Connection); } } internal override void ChangePassword(byte[] newPasswordBytes, bool asText) { SQLiteExtra.Verify(null); int keylen = ((asText && newPasswordBytes != null) ? (-1) : ((newPasswordBytes != null) ? newPasswordBytes.Length : 0)); SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_rekey(_sql, newPasswordBytes, keylen); if (HelperMethods.HasFlags(_flags, SQLiteConnectionFlags.HidePassword)) { ZeroPassword(newPasswordBytes); } if (sQLiteErrorCode != 0) { throw new SQLiteException(sQLiteErrorCode, GetLastError()); } if (_usePool) { _returnToFileName = _fileName; _usePool = false; _returnToPool = false; HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "ChangePassword (Pool) Disabled: {0}", HandleToString()), TraceCategory.Connection); } } internal override void SetBusyHook(SQLiteBusyCallback func) { UnsafeNativeMethods.sqlite3_busy_handler(_sql, func, IntPtr.Zero); } internal override void SetProgressHook(int nOps, SQLiteProgressCallback func) { UnsafeNativeMethods.sqlite3_progress_handler(_sql, nOps, func, IntPtr.Zero); } internal override void SetAuthorizerHook(SQLiteAuthorizerCallback func) { UnsafeNativeMethods.sqlite3_set_authorizer(_sql, func, IntPtr.Zero); } internal override void SetUpdateHook(SQLiteUpdateCallback func) { UnsafeNativeMethods.sqlite3_update_hook(_sql, func, IntPtr.Zero); } internal override void SetCommitHook(SQLiteCommitCallback func) { UnsafeNativeMethods.sqlite3_commit_hook(_sql, func, IntPtr.Zero); } internal override void SetTraceCallback(SQLiteTraceCallback func) { UnsafeNativeMethods.sqlite3_trace(_sql, func, IntPtr.Zero); } internal override void SetTraceCallback2(SQLiteTraceFlags mask, SQLiteTraceCallback2 func) { UnsafeNativeMethods.sqlite3_trace_v2(_sql, mask, func, IntPtr.Zero); } internal override void SetRollbackHook(SQLiteRollbackCallback func) { UnsafeNativeMethods.sqlite3_rollback_hook(_sql, func, IntPtr.Zero); } internal override SQLiteErrorCode SetLogCallback(SQLiteLogCallback func) { SQLiteErrorCode sQLiteErrorCode = UnsafeNativeMethods.sqlite3_config_log(SQLiteConfigOpsEnum.SQLITE_CONFIG_LOG, func, IntPtr.Zero); if (sQLiteErrorCode == SQLiteErrorCode.Ok) { _setLogCallback = func != null; HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "SetLogCallback: SUCCESS ==> {0}", _setLogCallback ? "SET" : "UNSET"), TraceCategory.Connection); } else { HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "SetLogCallback: FAILURE ==> {0}", sQLiteErrorCode), TraceCategory.Connection); } return sQLiteErrorCode; } internal override SQLiteTransactionState GetTransactionState(string schema) { if (_sql == null) { return SQLiteTransactionState.SQLITE_TXN_UNKNOWN; } IntPtr intPtr = IntPtr.Zero; try { if (schema != null) { intPtr = SQLiteString.Utf8IntPtrFromString(schema); } return UnsafeNativeMethods.sqlite3_txn_state(_sql, intPtr); } finally { if (intPtr != IntPtr.Zero) { SQLiteMemory.Free(intPtr); intPtr = IntPtr.Zero; } } } private static void AppendError(StringBuilder builder, string message) { builder?.AppendLine(message); } private bool UnhookTraceCallback(StringBuilder builder) { try { if (UnsafeNativeMethods.sqlite3_libversion_number() >= 3014000) { SetTraceCallback2(SQLiteTraceFlags.SQLITE_TRACE_NONE, null); } else { SetTraceCallback(null); } return true; } catch (Exception ex) { try { HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Failed to unset trace callback: {0}", ex), TraceCategory.Connection); } catch { } AppendError(builder, "failed to unset trace callback"); return false; } } private bool UnhookNativeCallbacks(bool includeTrace, bool includeGlobal, bool canThrow) { bool flag = true; SQLiteErrorCode errorCode = SQLiteErrorCode.Ok; StringBuilder stringBuilder = new StringBuilder(); if (includeTrace && !UnhookTraceCallback(stringBuilder)) { errorCode = SQLiteErrorCode.Error; flag = false; } try { SetRollbackHook(null); } catch (Exception ex) { try { HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Failed to unset rollback hook: {0}", ex), TraceCategory.Connection); } catch { } AppendError(stringBuilder, "failed to unset rollback hook"); errorCode = SQLiteErrorCode.Error; flag = false; } try { SetCommitHook(null); } catch (Exception ex2) { try { HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Failed to unset commit hook: {0}", ex2), TraceCategory.Connection); } catch { } AppendError(stringBuilder, "failed to unset commit hook"); errorCode = SQLiteErrorCode.Error; flag = false; } try { SetUpdateHook(null); } catch (Exception ex3) { try { HelperMethods.Trace(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Failed to unset update hook: {0}", ex3), TraceCategory.Connection); } catch { } AppendError(stringBuilder, "failed to unset update hook"); errorCode = SQLiteErrorCode.Error; flag = false; } try { SetAuthorizerHook(null); } catch (Exception ex4) { try { HelperMethods.Trace(HelperM