System.Data.SQLite
Check-in [4b1c267ac6]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Further portability enhancements for the native library pre-loader and the 'vtshim' extension loader, permitting it to work better on POSIX.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4b1c267ac6734dc6b612bb2e0c930cdc6fc6658e
User & Date: mistachkin 2016-03-23 17:50:41
Context
2016-03-23
17:52
Adjust tests related to extension loading to make them work better for POSIX. check-in: a5895007d1 user: mistachkin tags: trunk
17:50
Further portability enhancements for the native library pre-loader and the 'vtshim' extension loader, permitting it to work better on POSIX. check-in: 4b1c267ac6 user: mistachkin tags: trunk
05:38
Fix compilation issues when the native library pre-loader is not enabled. check-in: fd918a4eef user: mistachkin tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to System.Data.SQLite/SQLite3.cs.

81
82
83
84
85
86
87
88
89

90
91
92
93


94
95
96
97
98
99
100
....
2430
2431
2432
2433
2434
2435
2436



































2437
2438
2439
2440
2441
2442
2443
....
2454
2455
2456
2457
2458
2459
2460





2461
2462
2463
2464
2465
2466
2467
2468

2469
2470
2471
2472
2473
2474
2475
    protected Dictionary<SQLiteFunctionAttribute, SQLiteFunction> _functions;

#if INTEROP_VIRTUAL_TABLE
    /// <summary>
    /// This is the name of the native library file that contains the
    /// "vtshim" extension [wrapper].
    /// </summary>
    protected string _shimExtensionFileName =
#if (SQLITE_STANDARD || USE_INTEROP_DLL || PLATFORM_COMPACTFRAMEWORK) && PRELOAD_NATIVE_LIBRARY

        UnsafeNativeMethods.GetNativeLibraryFileNameOnly();
#else
        UnsafeNativeMethods.SQLITE_DLL;
#endif



    /// <summary>
    /// This is the name of the native entry point for the "vtshim"
    /// extension [wrapper].
    /// </summary>
    protected string _shimExtensionProcName = "sqlite3_vtshim_init";

................................................................................
    internal override void ReturnText(IntPtr context, string value)
    {
      byte[] b = ToUTF8(value);
      UnsafeNativeMethods.sqlite3_result_text(context, ToUTF8(value), b.Length - 1, (IntPtr)(-1));
    }

#if INTEROP_VIRTUAL_TABLE



































    /// <summary>
    /// Calls the native SQLite core library in order to create a disposable
    /// module containing the implementation of a virtual table.
    /// </summary>
    /// <param name="module">
    /// The module object to be used when creating the native disposable module.
    /// </param>
................................................................................
            module.LogErrors = ((flags & SQLiteConnectionFlags.LogModuleError) == SQLiteConnectionFlags.LogModuleError);
            module.LogExceptions = ((flags & SQLiteConnectionFlags.LogModuleException) == SQLiteConnectionFlags.LogModuleException);
        }

        if (_sql == null)
            throw new SQLiteException("connection has an invalid handle");






        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(true);
        LoadExtension(_shimExtensionFileName, _shimExtensionProcName);


        if (module.CreateDisposableModule(_sql))
        {
            if (_modules == null)
                _modules = new Dictionary<string, SQLiteModule>();

            _modules.Add(module.Name, module);







|
<
>
|
|
|
|
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
|
|

|
|

|
|
>







81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
....
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
....
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
    protected Dictionary<SQLiteFunctionAttribute, SQLiteFunction> _functions;

#if INTEROP_VIRTUAL_TABLE
    /// <summary>
    /// This is the name of the native library file that contains the
    /// "vtshim" extension [wrapper].
    /// </summary>
    protected string _shimExtensionFileName = null;


    /// <summary>
    /// This is the flag indicate whether the native library file that
    /// contains the "vtshim" extension must be dynamically loaded by
    /// this class prior to use.
    /// </summary>
    protected bool? _shimIsLoadNeeded = null;

    /// <summary>
    /// This is the name of the native entry point for the "vtshim"
    /// extension [wrapper].
    /// </summary>
    protected string _shimExtensionProcName = "sqlite3_vtshim_init";

................................................................................
    internal override void ReturnText(IntPtr context, string value)
    {
      byte[] b = ToUTF8(value);
      UnsafeNativeMethods.sqlite3_result_text(context, ToUTF8(value), b.Length - 1, (IntPtr)(-1));
    }

#if INTEROP_VIRTUAL_TABLE
    /// <summary>
    /// Determines the file name of the native library containing the native
    /// "vtshim" extension -AND- whether it should be dynamically loaded by
    /// this class.
    /// </summary>
    /// <param name="isLoadNeeded">
    /// This output parameter will be set to non-zero if the returned native
    /// library file name should be dynamically loaded prior to attempting
    /// the creation of native disposable extension modules.
    /// </param>
    /// <returns>
    /// The file name of the native library containing the native "vtshim"
    /// extension -OR- null if it cannot be determined.
    /// </returns>
    private string GetShimExtensionFileName(
        ref bool isLoadNeeded /* out */
        )
    {
        if (_shimIsLoadNeeded != null)
            isLoadNeeded = (bool)_shimIsLoadNeeded;
        else
            isLoadNeeded = UnsafeNativeMethods.IsWindows(); /* COMPAT */

        string fileName = _shimExtensionFileName;

        if (fileName != null)
            return fileName;

#if (SQLITE_STANDARD || USE_INTEROP_DLL || PLATFORM_COMPACTFRAMEWORK) && PRELOAD_NATIVE_LIBRARY
        return UnsafeNativeMethods.GetNativeLibraryFileNameOnly(); /* COMPAT */
#else
        return null;
#endif
    }

    /// <summary>
    /// Calls the native SQLite core library in order to create a disposable
    /// module containing the implementation of a virtual table.
    /// </summary>
    /// <param name="module">
    /// The module object to be used when creating the native disposable module.
    /// </param>
................................................................................
            module.LogErrors = ((flags & SQLiteConnectionFlags.LogModuleError) == SQLiteConnectionFlags.LogModuleError);
            module.LogExceptions = ((flags & SQLiteConnectionFlags.LogModuleException) == SQLiteConnectionFlags.LogModuleException);
        }

        if (_sql == null)
            throw new SQLiteException("connection has an invalid handle");

        bool isLoadNeeded = false;
        string fileName = GetShimExtensionFileName(ref isLoadNeeded);

        if (isLoadNeeded)
        {
            if (fileName == 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(true);
            LoadExtension(fileName, _shimExtensionProcName);
        }

        if (module.CreateDisposableModule(_sql))
        {
            if (_modules == null)
                _modules = new Dictionary<string, SQLiteModule>();

            _modules.Add(module.Name, module);

Changes to System.Data.SQLite/UnsafeNativeMethods.cs.

160
161
162
163
164
165
166
























167
168
169
170
171
172
173
...
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
...
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
....
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
....
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
          }

          return false;
      }

      /////////////////////////////////////////////////////////////////////////

























      /// <summary>
      /// This is a wrapper around the
      /// <see cref="String.Format(IFormatProvider,String,Object[])" /> method.
      /// On Mono, it has to call the method overload without the
      /// <see cref="IFormatProvider" /> parameter, due to a bug in Mono.
      /// </summary>
      /// <param name="provider">
................................................................................

      /////////////////////////////////////////////////////////////////////////

      #region Private Data
      /// <summary>
      /// The native module file name for the native SQLite library or null.
      /// </summary>
      private static string _SQLiteNativeModuleFileName = null;

      /////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// The native module handle for the native SQLite library or the value
      /// IntPtr.Zero.
      /// </summary>
      private static IntPtr _SQLiteNativeModuleHandle = IntPtr.Zero;
................................................................................
      {
          string fileNameOnly = GetSettingValue(
              "PreLoadSQLite_LibraryFileNameOnly", null);

          if (fileNameOnly != null)
              return fileNameOnly;

          return SQLITE_DLL;
      }

      /////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// Searches for the native SQLite library in the directory containing
      /// the assembly currently being executed as well as the base directory
      /// for the current application domain.
................................................................................
      /// </returns>
      private static string FixUpDllFileName(
          string fileName /* in */
          )
      {
          if (!String.IsNullOrEmpty(fileName))
          {
              PlatformID platformId = Environment.OSVersion.Platform;

              if ((platformId == PlatformID.Win32S) ||
                  (platformId == PlatformID.Win32Windows) ||
                  (platformId == PlatformID.Win32NT) ||
                  (platformId == PlatformID.WinCE))
              {
                  if (!fileName.EndsWith(DllFileExtension,
                          StringComparison.OrdinalIgnoreCase))
                  {
                      return fileName + DllFileExtension;
                  }
              }
................................................................................
              //       return a valid native module handle, return IntPtr.Zero,
              //       or throw an exception.  This must use the appropriate
              //       P/Invoke method for the current operating system.
              //
              nativeModuleFileName = fileName;

#if !PLATFORM_COMPACTFRAMEWORK
              if ((Environment.OSVersion.Platform == PlatformID.Unix) ||
                  (Environment.OSVersion.Platform == PlatformID.MacOSX))
              {
                  nativeModuleHandle = dlopen(fileName, RTLD_DEFAULT);
              }
              else
#endif
              {
                  nativeModuleHandle = LoadLibrary(fileName);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|







 







|
<
<
<
<
<







 







|
<







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
...
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
...
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
....
1086
1087
1088
1089
1090
1091
1092
1093





1094
1095
1096
1097
1098
1099
1100
....
1413
1414
1415
1416
1417
1418
1419
1420

1421
1422
1423
1424
1425
1426
1427
          }

          return false;
      }

      /////////////////////////////////////////////////////////////////////////

      /// <summary>
      /// Determines if the current process is running on one of the Windows
      /// [sub-]platforms.
      /// </summary>
      /// <returns>
      /// Non-zero when running on Windows; otherwise, zero.
      /// </returns>
      internal static bool IsWindows()
      {
          PlatformID platformId = Environment.OSVersion.Platform;

          if ((platformId == PlatformID.Win32S) ||
              (platformId == PlatformID.Win32Windows) ||
              (platformId == PlatformID.Win32NT) ||
              (platformId == PlatformID.WinCE))
          {
              return true;
          }

          return false;
      }

      /////////////////////////////////////////////////////////////////////////

      /// <summary>
      /// This is a wrapper around the
      /// <see cref="String.Format(IFormatProvider,String,Object[])" /> method.
      /// On Mono, it has to call the method overload without the
      /// <see cref="IFormatProvider" /> parameter, due to a bug in Mono.
      /// </summary>
      /// <param name="provider">
................................................................................

      /////////////////////////////////////////////////////////////////////////

      #region Private Data
      /// <summary>
      /// The native module file name for the native SQLite library or null.
      /// </summary>
      internal static string _SQLiteNativeModuleFileName = null;

      /////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// The native module handle for the native SQLite library or the value
      /// IntPtr.Zero.
      /// </summary>
      private static IntPtr _SQLiteNativeModuleHandle = IntPtr.Zero;
................................................................................
      {
          string fileNameOnly = GetSettingValue(
              "PreLoadSQLite_LibraryFileNameOnly", null);

          if (fileNameOnly != null)
              return fileNameOnly;

          return SQLITE_DLL; /* COMPAT */
      }

      /////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// Searches for the native SQLite library in the directory containing
      /// the assembly currently being executed as well as the base directory
      /// for the current application domain.
................................................................................
      /// </returns>
      private static string FixUpDllFileName(
          string fileName /* in */
          )
      {
          if (!String.IsNullOrEmpty(fileName))
          {
              if (IsWindows())





              {
                  if (!fileName.EndsWith(DllFileExtension,
                          StringComparison.OrdinalIgnoreCase))
                  {
                      return fileName + DllFileExtension;
                  }
              }
................................................................................
              //       return a valid native module handle, return IntPtr.Zero,
              //       or throw an exception.  This must use the appropriate
              //       P/Invoke method for the current operating system.
              //
              nativeModuleFileName = fileName;

#if !PLATFORM_COMPACTFRAMEWORK
              if (!IsWindows())

              {
                  nativeModuleHandle = dlopen(fileName, RTLD_DEFAULT);
              }
              else
#endif
              {
                  nativeModuleHandle = LoadLibrary(fileName);