System.Data.SQLite
Check-in [49bc443383]
Not logged in

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

Overview
Comment:Initial work on getting the native library pre-loader to work on non-Windows (POSIX) platforms.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 49bc4433831550ba55d4211bc773c4d8cb5c5141
User & Date: mistachkin 2016-03-23 05:10:17
Original Comment: Initial work on getting the native library pre-loader to work on non-Windows platforms.
Context
2016-03-23
05:22
More test constraints for Mono 4.2. check-in: d92e5e9396 user: mistachkin tags: trunk
05:10
Initial work on getting the native library pre-loader to work on non-Windows (POSIX) platforms. check-in: 49bc443383 user: mistachkin tags: trunk
04:56
Improvements to the native library pre-loader to make it capable of dynamically determining the base file name (without directory information) of the native SQLite library to be pre-loaded. Further, add support for the 'PreLoadSQLite_ModuleFileNameOnly' configuration setting and environment variable. check-in: 4436cf5d76 user: mistachkin tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Doc/Extra/Provider/environment.html.

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
          used instead of the application base directory by the native
          library pre-loader.  This environment variable can be especially
          useful in ASP.NET and other hosted environments where direct control
          of the location of the managed assemblies is not under the control
          of the application.</td>
        </tr>
        <tr valign="top">
          <td>PreLoadSQLite_ModuleFileNameOnly</td>
          <td>If this configuration variable is set [to anything], it will be
          used as the base file name (without directory information) for the
          native SQLite module to be pre-loaded (e.g. "sqlite3.dll" or
          "libsqlite3.so.0").</td>
        </tr>
        <tr valign="top">
          <td>PreLoadSQLite_ProcessorArchitecture</td>
          <td>If this environment variable is set [to anything], it will be
          used instead of the processor architecture value contained in the
          PROCESSOR_ARCHITECTURE environment variable to help build the path







|


|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
          used instead of the application base directory by the native
          library pre-loader.  This environment variable can be especially
          useful in ASP.NET and other hosted environments where direct control
          of the location of the managed assemblies is not under the control
          of the application.</td>
        </tr>
        <tr valign="top">
          <td>PreLoadSQLite_LibraryFileNameOnly</td>
          <td>If this configuration variable is set [to anything], it will be
          used as the base file name (without directory information) for the
          native SQLite library to be pre-loaded (e.g. "sqlite3.dll" or
          "libsqlite3.so.0").</td>
        </tr>
        <tr valign="top">
          <td>PreLoadSQLite_ProcessorArchitecture</td>
          <td>If this environment variable is set [to anything], it will be
          used instead of the processor architecture value contained in the
          PROCESSOR_ARCHITECTURE environment variable to help build the path

Changes to System.Data.SQLite/Configurations/System.Data.SQLite.dll.config.

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
    <!--
    <add key="PreLoadSQLite_BaseDirectory" value="" />
    -->

    <!--
        NOTE: If this configuration variable is set [to anything], it will be
              used as the base file name (without directory information) for
              the native SQLite module to be pre-loaded (e.g. "sqlite3.dll"
              or "libsqlite3.so.0").
    -->
    <!--
    <add key="PreLoadSQLite_ModuleFileNameOnly" value="" />
    -->

    <!--
        NOTE: If this configuration variable is set [to anything], it will be
              used instead of the processor architecture value contained in the
              PROCESSOR_ARCHITECTURE environment variable to help build the
              path of the native library to pre-load.







|



|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
    <!--
    <add key="PreLoadSQLite_BaseDirectory" value="" />
    -->

    <!--
        NOTE: If this configuration variable is set [to anything], it will be
              used as the base file name (without directory information) for
              the native SQLite library to be pre-loaded (e.g. "sqlite3.dll"
              or "libsqlite3.so.0").
    -->
    <!--
    <add key="PreLoadSQLite_LibraryFileNameOnly" value="" />
    -->

    <!--
        NOTE: If this configuration variable is set [to anything], it will be
              used instead of the processor architecture value contained in the
              PROCESSOR_ARCHITECTURE environment variable to help build the
              path of the native library to pre-load.

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

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

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

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








|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

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

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

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

756
757
758
759
760
761
762






















































763
764
765
766
767
768
769
...
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
...
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
....
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
....
1334
1335
1336
1337
1338
1339
1340
1341

1342
1343










1344

1345
1346
1347
1348
1349
1350
1351
#endif
          CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto,
#if !PLATFORM_COMPACTFRAMEWORK
          BestFitMapping = false, ThrowOnUnmappableChar = true,
#endif
          SetLastError = true)]
      private static extern IntPtr LoadLibrary(string fileName);























































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

#if PLATFORM_COMPACTFRAMEWORK
      /// <summary>
      /// This is the P/Invoke method that wraps the native Win32 GetSystemInfo
      /// function.  See the MSDN documentation for full details on what it
................................................................................
      /// Determines the base file name (without any directory information)
      /// for the native SQLite library to be pre-loaded by this class.
      /// </summary>
      /// <returns>
      /// The base file name for the native SQLite library to be pre-loaded by
      /// this class -OR- null if its value cannot be determined.
      /// </returns>
      internal static string GetNativeModuleFileNameOnly()
      {
          string fileNameOnly = GetSettingValue(
              "PreLoadSQLite_ModuleFileNameOnly", null);

          if (fileNameOnly != null)
              return fileNameOnly;

          return SQLITE_DLL;
      }

................................................................................
              return false; /* DISABLED */
          }

          //
          // NOTE: Determine the base file name for the native SQLite library.
          //       If this is not known by this class, we cannot continue.
          //
          string fileNameOnly = GetNativeModuleFileNameOnly();

          if (fileNameOnly == null)
              return false;

          //
          // NOTE: Build the list of base directories and processor/platform
          //       names.  These lists will be used to help locate the native
................................................................................
          if (baseDirectory == null)
              return false;

          //
          // NOTE: Determine the base file name for the native SQLite library.
          //       If this is not known by this class, we cannot continue.
          //
          string fileNameOnly = GetNativeModuleFileNameOnly();

          if (fileNameOnly == null)
              return false;

          //
          // NOTE: If the native SQLite library exists in the base directory
          //       itself, stop now.
................................................................................
                  // do nothing.
              }
#endif

              //
              // NOTE: Attempt to load the native library.  This will either
              //       return a valid native module handle, return IntPtr.Zero,
              //       or throw an exception.

              //
              nativeModuleFileName = fileName;










              nativeModuleHandle = LoadLibrary(fileName);


              return (nativeModuleHandle != IntPtr.Zero);
          }
#if !NET_COMPACT_20 && TRACE_PRELOAD
          catch (Exception e)
#else
          catch (Exception)







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







 







|


|







 







|







 







|







 







|
>


>
>
>
>
>
>
>
>
>
>
|
>







756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
...
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
...
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
....
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
....
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
#endif
          CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto,
#if !PLATFORM_COMPACTFRAMEWORK
          BestFitMapping = false, ThrowOnUnmappableChar = true,
#endif
          SetLastError = true)]
      private static extern IntPtr LoadLibrary(string fileName);

#if !PLATFORM_COMPACTFRAMEWORK
      /////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// This is the P/Invoke method that wraps the native Unix dlopen
      /// function.  See the POSIX documentation for full details on what it
      /// does.
      /// </summary>
      /// <param name="fileName">
      /// The name of the executable library.
      /// </param>
      /// <param name="mode">
      /// This must be a combination of the individual bit flags RTLD_LAZY,
      /// RTLD_NOW, RTLD_GLOBAL, and/or RTLD_LOCAL.
      /// </param>
      /// <returns>
      /// The native module handle upon success -OR- IntPtr.Zero on failure.
      /// </returns>
      [DllImport("__Internal", EntryPoint = "dlopen",
          CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi,
          BestFitMapping = false, ThrowOnUnmappableChar = true,
          SetLastError = true)]
      private static extern IntPtr dlopen(string fileName, int mode);

      /////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// For use with dlopen(), bind function calls lazily.
      /// </summary>
      private const int RTLD_LAZY = 0x1;

      /////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// For use with dlopen(), bind function calls immediately.
      /// </summary>
      private const int RTLD_NOW = 0x2;

      /////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// For use with dlopen(), make symbols globally available.
      /// </summary>
      private const int RTLD_GLOBAL = 0x100;

      /////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// For use with dlopen(), opposite of RTLD_GLOBAL, and the default.
      /// </summary>
      private const int RTLD_LOCAL = 0x000;

      /////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// For use with dlopen(), the defaults used by this class.
      /// </summary>
      private const int RTLD_DEFAULT = RTLD_NOW | RTLD_GLOBAL;
#endif

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

#if PLATFORM_COMPACTFRAMEWORK
      /// <summary>
      /// This is the P/Invoke method that wraps the native Win32 GetSystemInfo
      /// function.  See the MSDN documentation for full details on what it
................................................................................
      /// Determines the base file name (without any directory information)
      /// for the native SQLite library to be pre-loaded by this class.
      /// </summary>
      /// <returns>
      /// The base file name for the native SQLite library to be pre-loaded by
      /// this class -OR- null if its value cannot be determined.
      /// </returns>
      internal static string GetNativeLibraryFileNameOnly()
      {
          string fileNameOnly = GetSettingValue(
              "PreLoadSQLite_LibraryFileNameOnly", null);

          if (fileNameOnly != null)
              return fileNameOnly;

          return SQLITE_DLL;
      }

................................................................................
              return false; /* DISABLED */
          }

          //
          // NOTE: Determine the base file name for the native SQLite library.
          //       If this is not known by this class, we cannot continue.
          //
          string fileNameOnly = GetNativeLibraryFileNameOnly();

          if (fileNameOnly == null)
              return false;

          //
          // NOTE: Build the list of base directories and processor/platform
          //       names.  These lists will be used to help locate the native
................................................................................
          if (baseDirectory == null)
              return false;

          //
          // NOTE: Determine the base file name for the native SQLite library.
          //       If this is not known by this class, we cannot continue.
          //
          string fileNameOnly = GetNativeLibraryFileNameOnly();

          if (fileNameOnly == null)
              return false;

          //
          // NOTE: If the native SQLite library exists in the base directory
          //       itself, stop now.
................................................................................
                  // do nothing.
              }
#endif

              //
              // NOTE: Attempt to load the native library.  This will either
              //       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);
              }

              return (nativeModuleHandle != IntPtr.Zero);
          }
#if !NET_COMPACT_20 && TRACE_PRELOAD
          catch (Exception e)
#else
          catch (Exception)