System.Data.SQLite
Check-in [4436cf5d76]
Not logged in

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

Overview
Comment: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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4436cf5d767ace47b3b62695da116a785c39b910
User & Date: mistachkin 2016-03-23 04:56:46
Context
2016-03-23
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
04:31
Make the native library and procedure name parameters used inside SQLite3.CreateModule into protected fields instead of constants. check-in: 0fc0143d37 user: mistachkin tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

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

135
136
137
138
139
140
141







142
143
144
145
146
147
148
          <td>If this environment variable is set [to anything], it will be
          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_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
          of the native library to pre-load.</td>
        </tr>







>
>
>
>
>
>
>







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
          <td>If this environment variable is set [to anything], it will be
          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
          of the native library to pre-load.</td>
        </tr>

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

83
84
85
86
87
88
89










90
91
92
93
94
95
96
              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.
    -->
    <!--
    <add key="PreLoadSQLite_BaseDirectory" 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.
    -->







>
>
>
>
>
>
>
>
>
>







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
              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.
    -->
    <!--
    <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.
    -->

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

81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
....
2449
2450
2451
2452
2453
2454
2455






2456
2457
2458
2459
2460
2461
2462
    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 = UnsafeNativeMethods.SQLITE_DLL;


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

................................................................................
            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");







        SetLoadExtension(true);
        LoadExtension(_shimExtensionFileName, _shimExtensionProcName);

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







|
>







 







>
>
>
>
>
>







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
....
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
    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 =
        UnsafeNativeMethods.GetNativeModuleFileNameOnly();

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

................................................................................
            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>();

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

832
833
834
835
836
837
838




















839
840
841
842
843
844
845
...
860
861
862
863
864
865
866









867
868
869
870
871
872
873
...
888
889
890
891
892
893
894
895

896
897
898
899
900
901
902
....
1210
1211
1212
1213
1214
1215
1216









1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
....
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
....
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
      /// IntPtr.Zero.
      /// </summary>
      private static IntPtr _SQLiteNativeModuleHandle = IntPtr.Zero;
      #endregion

      /////////////////////////////////////////////////////////////////////////
      /// <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.
      /// </summary>
      /// <param name="baseDirectory">
      /// Upon success, this parameter will be modified to refer to the base
      /// directory containing the native SQLite library.
................................................................................
      {
          if (GetSettingValue(
                "PreLoadSQLite_NoSearchForDirectory", null) != null)
          {
              return false; /* DISABLED */
          }










          //
          // NOTE: Build the list of base directories and processor/platform
          //       names.  These lists will be used to help locate the native
          //       SQLite core library (or interop assembly) to pre-load into
          //       this process.
          //
          string[] directories = {
................................................................................

              foreach (string subDirectory in subDirectories)
              {
                  if (subDirectory == null)
                      continue;

                  string fileName = FixUpDllFileName(MaybeCombinePath(
                      MaybeCombinePath(directory, subDirectory), SQLITE_DLL));


                  //
                  // NOTE: If the SQLite DLL file exists, return success.
                  //       Prior to returning, set the base directory and
                  //       processor architecture to reflect the location
                  //       where it was found.
                  //
................................................................................

          //
          // NOTE: If we failed to query the base directory, stop now.
          //
          if (baseDirectory == null)
              return false;










          //
          // NOTE: If the native SQLite library exists in the base directory
          //       itself, stop now.
          //
          string fileName = FixUpDllFileName(MaybeCombinePath(
              baseDirectory, SQLITE_DLL));

          if (File.Exists(fileName))
              return false;

          //
          // NOTE: If the specified processor architecture is null, use the
          //       default.
................................................................................
              return false;

          //
          // NOTE: Build the full path and file name for the native SQLite
          //       library using the processor architecture name.
          //
          fileName = FixUpDllFileName(MaybeCombinePath(MaybeCombinePath(
              baseDirectory, processorArchitecture), SQLITE_DLL));

          //
          // NOTE: If the file name based on the processor architecture name
          // is not found, try using the associated platform name.
          //
          if (!File.Exists(fileName))
          {
................................................................................
                  return false;

              //
              // NOTE: Build the full path and file name for the native SQLite
              //       library using the platform name.
              //
              fileName = FixUpDllFileName(MaybeCombinePath(MaybeCombinePath(
                  baseDirectory, platformName), SQLITE_DLL));

              //
              // NOTE: If the file does not exist, skip trying to load it.
              //
              if (!File.Exists(fileName))
                  return false;
          }







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







 







>
>
>
>
>
>
>
>
>







 







|
>







 







>
>
>
>
>
>
>
>
>




|
|







 







|







 







|







832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
...
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
...
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
....
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
....
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
....
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
      /// IntPtr.Zero.
      /// </summary>
      private static IntPtr _SQLiteNativeModuleHandle = IntPtr.Zero;
      #endregion

      /////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// 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;
      }

      /////////////////////////////////////////////////////////////////////////
      /// <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.
      /// </summary>
      /// <param name="baseDirectory">
      /// Upon success, this parameter will be modified to refer to the base
      /// directory containing the native SQLite library.
................................................................................
      {
          if (GetSettingValue(
                "PreLoadSQLite_NoSearchForDirectory", null) != null)
          {
              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
          //       SQLite core library (or interop assembly) to pre-load into
          //       this process.
          //
          string[] directories = {
................................................................................

              foreach (string subDirectory in subDirectories)
              {
                  if (subDirectory == null)
                      continue;

                  string fileName = FixUpDllFileName(MaybeCombinePath(
                      MaybeCombinePath(directory, subDirectory),
                      fileNameOnly));

                  //
                  // NOTE: If the SQLite DLL file exists, return success.
                  //       Prior to returning, set the base directory and
                  //       processor architecture to reflect the location
                  //       where it was found.
                  //
................................................................................

          //
          // NOTE: If we failed to query the base directory, stop now.
          //
          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.
          //
          string fileName = FixUpDllFileName(MaybeCombinePath(baseDirectory,
              fileNameOnly));

          if (File.Exists(fileName))
              return false;

          //
          // NOTE: If the specified processor architecture is null, use the
          //       default.
................................................................................
              return false;

          //
          // NOTE: Build the full path and file name for the native SQLite
          //       library using the processor architecture name.
          //
          fileName = FixUpDllFileName(MaybeCombinePath(MaybeCombinePath(
              baseDirectory, processorArchitecture), fileNameOnly));

          //
          // NOTE: If the file name based on the processor architecture name
          // is not found, try using the associated platform name.
          //
          if (!File.Exists(fileName))
          {
................................................................................
                  return false;

              //
              // NOTE: Build the full path and file name for the native SQLite
              //       library using the platform name.
              //
              fileName = FixUpDllFileName(MaybeCombinePath(MaybeCombinePath(
                  baseDirectory, platformName), fileNameOnly));

              //
              // NOTE: If the file does not exist, skip trying to load it.
              //
              if (!File.Exists(fileName))
                  return false;
          }