System.Data.SQLite

Check-in [232364a514]
Login

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

Overview
Comment:Add additional tests for the SQLiteLog.Initialize method. Add 'No_SQLiteLog' environment variable to disable the SQLiteLog subsystem initialization.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 232364a514e7a6478cee0d658549076cd7c305d5
User & Date: mistachkin 2019-05-15 01:08:23.996
Context
2019-05-15
01:49
Bump version number. Update version history docs. check-in: 95e0135ad1 user: mistachkin tags: trunk
01:28
Experimental changes to the SQLiteLog class to enable forced use of the managed logging callback. Leaf check-in: 5cd4a102a9 user: mistachkin tags: sqliteLog
01:08
Add additional tests for the SQLiteLog.Initialize method. Add 'No_SQLiteLog' environment variable to disable the SQLiteLog subsystem initialization. check-in: 232364a514 user: mistachkin tags: trunk
2019-05-14
20:22
Slightly improve error handling in the SQLiteLog.Initialize method. check-in: 0f34d6ea03 user: mistachkin tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to Doc/Extra/Provider/environment.html.
186
187
188
189
190
191
192







193
194
195
196
197
198
199
          <td>No_SQLiteGetSettingValue</td>
          <td>If this environment variable is set [to anything], all calls to
          the GetSettingValue method will return the default value.  This will
          effectively prevent all other setting values from having any effect,
          including those specified via other supported environment variables
          or in the associated XML configuration file.</td>
        </tr>







        <tr valign="top">
          <td>No_SQLiteXmlConfigFile</td>
          <td>If this environment variable is set [to anything], calls to the
          GetSettingValue method will never result in the XML configuration
          file being read; instead, the default value will be returned.  This
          will effectively prevent any setting values specified via the XML
          configuration file from having any effect.</td>







>
>
>
>
>
>
>







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
          <td>No_SQLiteGetSettingValue</td>
          <td>If this environment variable is set [to anything], all calls to
          the GetSettingValue method will return the default value.  This will
          effectively prevent all other setting values from having any effect,
          including those specified via other supported environment variables
          or in the associated XML configuration file.</td>
        </tr>
        <tr valign="top">
          <td>No_SQLiteLog</td>
          <td>If this environment variable is set [to anything], the SQLite
          logging subsystem will not be initialized by the SQLiteLog class;
          however, it may still be initialized by external components (i.e.
          something other than System.Data.SQLite).</td>
        </tr>
        <tr valign="top">
          <td>No_SQLiteXmlConfigFile</td>
          <td>If this environment variable is set [to anything], calls to the
          GetSettingValue method will never result in the XML configuration
          file being read; instead, the default value will be returned.  This
          will effectively prevent any setting values specified via the XML
          configuration file from having any effect.</td>
Changes to System.Data.SQLite/Configurations/System.Data.SQLite.dll.config.
141
142
143
144
145
146
147










148
149
150
151
152
153
154
                      does not make any sense to use it here as it will never
                      be consulted.  For this setting to work properly, it must
                      be set via an environment variable.
    -->
    <!--
    <add key="No_SQLiteGetSettingValue" value="1" />
    -->











    <!--
        NOTE: If this environment variable is set [to anything], calls to the
              GetSettingValue method will never result in the XML configuration
              file being read; instead, the default value will be returned.
              This will effectively prevent any setting values specified via
              the XML configuration file from having any effect.







>
>
>
>
>
>
>
>
>
>







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
                      does not make any sense to use it here as it will never
                      be consulted.  For this setting to work properly, it must
                      be set via an environment variable.
    -->
    <!--
    <add key="No_SQLiteGetSettingValue" value="1" />
    -->

    <!--
        NOTE: If this environment variable is set [to anything], the SQLite
              logging subsystem will not be initialized by the SQLiteLog class;
              however, it may still be initialized by external components (i.e.
              something other than System.Data.SQLite).
    -->
    <!--
    <add key="No_SQLiteLog" value="1" />
    -->

    <!--
        NOTE: If this environment variable is set [to anything], calls to the
              GetSettingValue method will never result in the XML configuration
              file being read; instead, the default value will be returned.
              This will effectively prevent any setting values specified via
              the XML configuration file from having any effect.
Changes to System.Data.SQLite/SQLiteLog.cs.
118
119
120
121
122
123
124










125
126
127
128
129
130
131
        /// The base SQLite object to interop with.
        /// </summary>
        private static SQLiteBase _sql;
#endif

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











        /// <summary>
        /// This will be non-zero if an attempt was already made to initialize
        /// the (managed) logging subsystem.
        /// </summary>
        private static int _attemptedInitialize;

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







>
>
>
>
>
>
>
>
>
>







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
        /// The base SQLite object to interop with.
        /// </summary>
        private static SQLiteBase _sql;
#endif

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

        /// <summary>
        /// The number of times that the <see cref="Initialize(string)" />
        /// has been called when the logging subystem was actually eligible
        /// to be initialized (i.e. without the "No_SQLiteLog" environment
        /// variable being set).
        /// </summary>
        private static int _initializeCallCount;

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

        /// <summary>
        /// This will be non-zero if an attempt was already made to initialize
        /// the (managed) logging subsystem.
        /// </summary>
        private static int _attemptedInitialize;

        ///////////////////////////////////////////////////////////////////////
154
155
156
157
158
159
160




















161
162
163
164
165
166
167
        /// The name of the managed class that called this method.  This
        /// parameter may be null.
        /// </param>
        internal static void Initialize(
            string className
            )
        {




















            //
            // NOTE: First, check if the managed logging subsystem is always
            //       supposed to at least attempt to initialize itself.  In
            //       order to do this, several fairly complex steps must be
            //       taken, including calling a P/Invoke (interop) method;
            //       therefore, by default, attempt to perform these steps
            //       once.







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







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
        /// The name of the managed class that called this method.  This
        /// parameter may be null.
        /// </param>
        internal static void Initialize(
            string className
            )
        {
            //
            // NOTE: See if the logging subsystem has been totally disabled.
            //       If so, do nothing.
            //
            if (UnsafeNativeMethods.GetSettingValue(
                    "No_SQLiteLog", null) != null)
            {
                return;
            }

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

            //
            // NOTE: Keep track of exactly how many times this method is
            //       called (i.e. per-AppDomain, of course).
            //
            Interlocked.Increment(ref _initializeCallCount);

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

            //
            // NOTE: First, check if the managed logging subsystem is always
            //       supposed to at least attempt to initialize itself.  In
            //       order to do this, several fairly complex steps must be
            //       taken, including calling a P/Invoke (interop) method;
            //       therefore, by default, attempt to perform these steps
            //       once.
Changes to Tests/basic.eagle.
5133
5134
5135
5136
5137
5138
5139










































































































5140
5141
5142
5143
5144
5145
5146
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error code db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{1 {attempt to write a readonly database} 0 1 4}}











































































































###############################################################################

reportSQLiteResources $test_channel

###############################################################################








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







5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error code db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{1 {attempt to write a readonly database} 0 1 4}}

###############################################################################

runTest {test data-1.98 {create SQLiteConnection objects w/logging} -setup {
  proc threadStart {} {
    for {set i 0} {$i < 1000} {incr i} {
      set c($i) [object create System.Data.SQLite.SQLiteConnection]
      incr ::count
    }
  }

  saveEnvironmentVariables [list No_SQLiteLog] savedEnv

  unset -nocomplain env(No_SQLiteLog)
} -body {
  object invoke -flags +NonPublic \
      System.Data.SQLite.SQLiteLog _initializeCallCount 0

  for {set i 0} {$i < 20} {incr i} {
    set thread($i) [createThread threadStart false 1048576]
    $thread($i) Name [appendArgs "test data-1.98 #" $i]
  }

  set count 0

  foreach i [array names thread] {
    startThread $thread($i)
  }

  foreach i [array names thread] {
    $thread($i) Join
  }

  list $count [object invoke -flags +NonPublic \
      System.Data.SQLite.SQLiteLog _initializeCallCount]
} -cleanup {
  restoreEnvironmentVariables [list No_SQLiteLog] savedEnv

  if {[info exists thread]} then {
    foreach i [array names thread] {
      if {[info exists thread($i)] && [cleanupThread $thread($i)]} then {
        unset -nocomplain thread($i)
      }
    }
  }

  catch {object removecallback threadStart}

  unset -nocomplain thread i count

  rename threadStart ""
} -constraints {eagle command.object SQLite System.Data.SQLite} -result \
{20000 20000}}

###############################################################################

runTest {test data-1.99 {create SQLiteConnection objects w/o logging} -setup {
  proc threadStart {} {
    for {set i 0} {$i < 1000} {incr i} {
      set c($i) [object create System.Data.SQLite.SQLiteConnection]
      incr ::count
    }
  }

  saveEnvironmentVariables [list No_SQLiteLog] savedEnv

  set env(No_SQLiteLog) 1
} -body {
  object invoke -flags +NonPublic \
      System.Data.SQLite.SQLiteLog _initializeCallCount 0

  for {set i 0} {$i < 20} {incr i} {
    set thread($i) [createThread threadStart false 1048576]
    $thread($i) Name [appendArgs "test data-1.99 #" $i]
  }

  set count 0

  foreach i [array names thread] {
    startThread $thread($i)
  }

  foreach i [array names thread] {
    $thread($i) Join
  }

  list $count [object invoke -flags +NonPublic \
      System.Data.SQLite.SQLiteLog _initializeCallCount]
} -cleanup {
  restoreEnvironmentVariables [list No_SQLiteLog] savedEnv

  if {[info exists thread]} then {
    foreach i [array names thread] {
      if {[info exists thread($i)] && [cleanupThread $thread($i)]} then {
        unset -nocomplain thread($i)
      }
    }
  }

  catch {object removecallback threadStart}

  unset -nocomplain thread i count

  rename threadStart ""
} -constraints {eagle command.object SQLite System.Data.SQLite} -result \
{20000 0}}

###############################################################################

reportSQLiteResources $test_channel

###############################################################################