System.Data.SQLite
Check-in [2042b718d3]
Not logged in

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

Overview
Comment:Work around the inability of the .NET Compact Framework to marshal Int64 P/Invoke parameters and return types by value. Fix for ticket [dd45aba387].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2042b718d312122fd9b389939e7621180ea25b7c
User & Date: mistachkin 2012-10-10 13:08:58
References
2013-01-01
19:32 Closed ticket [dd45aba387]: connection properties LastInsertRowId, MemoryUsed, and MemoryHighwater do not work on Win CE plus 3 other changes artifact: f32b16692b user: mistachkin
2012-10-10
13:11 Fixed ticket [dd45aba387]. artifact: 37831a0b52 user: mistachkin
Context
2012-10-10
13:56
Re-order the #if statements used for native library/assembly selection to reflect the necessity of using the custom interop assembly when compiled for the .NET Compact Framework. check-in: affb80d75d user: mistachkin tags: trunk
13:08
Work around the inability of the .NET Compact Framework to marshal Int64 P/Invoke parameters and return types by value. Fix for ticket [dd45aba387]. check-in: 2042b718d3 user: mistachkin tags: trunk
2012-10-09
15:01
Fix typo in documentation of environment variables. check-in: 3ded2648fc user: mistachkin tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to SQLite.Interop/src/win/interop.c.

310
311
312
313
314
315
316















317
318
319
320
321
322
323
	*val = sqlite3_column_double(stmt,iCol);
}

SQLITE_API void WINAPI sqlite3_column_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val)
{
	*val = sqlite3_column_int64(stmt,iCol);
}
















SQLITE_API const unsigned char * WINAPI sqlite3_column_text_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const unsigned char *pval = sqlite3_column_text(stmt, iCol);
  *plen = (pval != 0) ? strlen((char *)pval) : 0;
  return pval;
}







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







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
	*val = sqlite3_column_double(stmt,iCol);
}

SQLITE_API void WINAPI sqlite3_column_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val)
{
	*val = sqlite3_column_int64(stmt,iCol);
}

SQLITE_API void WINAPI sqlite3_last_insert_rowid_interop(sqlite3 *db, sqlite_int64 *rowId)
{
	*rowId = sqlite3_last_insert_rowid(db);
}

SQLITE_API void WINAPI sqlite3_memory_used_interop(sqlite_int64 *nBytes)
{
	*nBytes = sqlite3_memory_used();
}

SQLITE_API void WINAPI sqlite3_memory_highwater_interop(int resetFlag, sqlite_int64 *nBytes)
{
	*nBytes = sqlite3_memory_highwater(resetFlag);
}

SQLITE_API const unsigned char * WINAPI sqlite3_column_text_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const unsigned char *pval = sqlite3_column_text(stmt, iCol);
  *plen = (pval != 0) ? strlen((char *)pval) : 0;
  return pval;
}

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

224
225
226
227
228
229
230

231





232
233
234
235
236
237
238
...
240
241
242
243
244
245
246

247





248
249
250
251
252
253
254

255





256
257
258
259
260
261
262
      }
    }

    internal override long LastInsertRowId
    {
      get
      {

        return UnsafeNativeMethods.sqlite3_last_insert_rowid(_sql);





      }
    }

    internal override int Changes
    {
      get
      {
................................................................................
      }
    }

    internal override long MemoryUsed
    {
      get
      {

        return UnsafeNativeMethods.sqlite3_memory_used();





      }
    }

    internal override long MemoryHighwater
    {
      get
      {

        return UnsafeNativeMethods.sqlite3_memory_highwater(0);





      }
    }

    internal override SQLiteErrorCode SetMemoryStatus(bool value)
    {
        return StaticSetMemoryStatus(value);
    }







>

>
>
>
>
>







 







>

>
>
>
>
>







>

>
>
>
>
>







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
...
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
      }
    }

    internal override long LastInsertRowId
    {
      get
      {
#if !PLATFORM_COMPACTFRAMEWORK
        return UnsafeNativeMethods.sqlite3_last_insert_rowid(_sql);
#else
        long rowId = 0;
        UnsafeNativeMethods.sqlite3_last_insert_rowid_interop(_sql, ref rowId);
        return rowId;
#endif
      }
    }

    internal override int Changes
    {
      get
      {
................................................................................
      }
    }

    internal override long MemoryUsed
    {
      get
      {
#if !PLATFORM_COMPACTFRAMEWORK
        return UnsafeNativeMethods.sqlite3_memory_used();
#else
        long bytes = 0;
        UnsafeNativeMethods.sqlite3_memory_used_interop(ref bytes);
        return bytes;
#endif
      }
    }

    internal override long MemoryHighwater
    {
      get
      {
#if !PLATFORM_COMPACTFRAMEWORK
        return UnsafeNativeMethods.sqlite3_memory_highwater(0);
#else
        long bytes = 0;
        UnsafeNativeMethods.sqlite3_memory_highwater_interop(0, ref bytes);
        return bytes;
#endif
      }
    }

    internal override SQLiteErrorCode SetMemoryStatus(bool value)
    {
        return StaticSetMemoryStatus(value);
    }

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

874
875
876
877
878
879
880

881
882

883
884
885
886
887
888
889
890
891
892
893
894

895
896

897
898
899
900
901

902
903

904
905
906
907
908
909
910
911
912
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern void sqlite3_interrupt(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]

#else
    [DllImport(SQLITE_DLL)]

#endif
    internal static extern long sqlite3_last_insert_rowid(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_changes(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]

#else
    [DllImport(SQLITE_DLL)]

#endif
    internal static extern long sqlite3_memory_used();

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]

#else
    [DllImport(SQLITE_DLL)]

#endif
    internal static extern long sqlite3_memory_highwater(int resetFlag);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern SQLiteErrorCode sqlite3_shutdown();







>


>

<










>


>

<



>


>

<







874
875
876
877
878
879
880
881
882
883
884
885

886
887
888
889
890
891
892
893
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908

909
910
911
912
913
914
915
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern void sqlite3_interrupt(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
    internal static extern long sqlite3_last_insert_rowid(IntPtr db);
#else
    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_last_insert_rowid_interop(IntPtr db, ref long rowId);
#endif


#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_changes(IntPtr db);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
    internal static extern long sqlite3_memory_used();
#else
    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_memory_used_interop(ref long bytes);
#endif


#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
    internal static extern long sqlite3_memory_highwater(int resetFlag);
#else
    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_memory_highwater_interop(int resetFlag, ref long bytes);
#endif


#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern SQLiteErrorCode sqlite3_shutdown();

Changes to testce/TestCases.cs.

185
186
187
188
189
190
191




192
193
194
195
196
197
198
...
894
895
896
897
898
899
900



















901
902
903
904
905
906
907
      try { UserAggregate(cnn); frm.WriteLine("SUCCESS - UserAggregate"); passed++; }
      catch (Exception) { frm.WriteLine("FAIL - UserAggregate"); failed++; }

      total++;
      try { UserCollation(cnn); frm.WriteLine("SUCCESS - UserCollation"); passed++; }
      catch (Exception) { frm.WriteLine("FAIL - UserCollation"); failed++; }





      total++;
      try { MultipleThreadStress(cnn); frm.WriteLine("SUCCESS - MultipleThreadStress"); passed++; }
      catch (Exception) { frm.WriteLine("FAIL - MultipleThreadStress"); failed++; }

      total++;
      try { DropTable(cnn); frm.WriteLine("SUCCESS - DropTable"); passed++; }
      catch (Exception) { frm.WriteLine("FAIL - DropTable"); failed++; }
................................................................................
        // and "Field3" will be next, followed by a NULL.  Our user-defined collating sequence will 
        // deliberately place them out of order so Field3 is first.
        cmd.CommandText = "SELECT Field3 FROM TestCase ORDER BY Field3 COLLATE MYSEQUENCE DESC";
        string s = (string)cmd.ExecuteScalar();
        if (s != "Field3") throw new ArgumentOutOfRangeException("MySequence didn't sort properly");
      }
    }




















    private int nextId = 0;
    private const int MAX_THREADS = 3;
    private const int MAX_ITERATIONS = 100;
    private ManualResetEvent goEvent = new ManualResetEvent(false);

    private static int GetThreadId()







>
>
>
>







 







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







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
...
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
      try { UserAggregate(cnn); frm.WriteLine("SUCCESS - UserAggregate"); passed++; }
      catch (Exception) { frm.WriteLine("FAIL - UserAggregate"); failed++; }

      total++;
      try { UserCollation(cnn); frm.WriteLine("SUCCESS - UserCollation"); passed++; }
      catch (Exception) { frm.WriteLine("FAIL - UserCollation"); failed++; }

      total++;
      try { Int64Properties(cnn); frm.WriteLine("SUCCESS - Int64Properties"); passed++; }
      catch (Exception) { frm.WriteLine("FAIL - Int64Properties"); failed++; }

      total++;
      try { MultipleThreadStress(cnn); frm.WriteLine("SUCCESS - MultipleThreadStress"); passed++; }
      catch (Exception) { frm.WriteLine("FAIL - MultipleThreadStress"); failed++; }

      total++;
      try { DropTable(cnn); frm.WriteLine("SUCCESS - DropTable"); passed++; }
      catch (Exception) { frm.WriteLine("FAIL - DropTable"); failed++; }
................................................................................
        // and "Field3" will be next, followed by a NULL.  Our user-defined collating sequence will 
        // deliberately place them out of order so Field3 is first.
        cmd.CommandText = "SELECT Field3 FROM TestCase ORDER BY Field3 COLLATE MYSEQUENCE DESC";
        string s = (string)cmd.ExecuteScalar();
        if (s != "Field3") throw new ArgumentOutOfRangeException("MySequence didn't sort properly");
      }
    }

    // Make sure that Int64 property values can be used on the .NET Compact Framework.
    internal void Int64Properties(DbConnection cnn)
    {
        SQLiteConnection cnn2 = cnn as SQLiteConnection;

        if (cnn2 != null)
        {
            foreach (long value in new long[] {
                    cnn2.LastInsertRowId, cnn2.MemoryUsed,
                    cnn2.MemoryHighwater
                })
            {
                // do nothing.
            }
        }

        throw new NotSupportedException("not a SQLite connection");
    }

    private int nextId = 0;
    private const int MAX_THREADS = 3;
    private const int MAX_ITERATIONS = 100;
    private ManualResetEvent goEvent = new ManualResetEvent(false);

    private static int GetThreadId()