Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | First attempt at making virtual table support work on the .NET Compact Framework. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | virtualTables |
Files: | files | file ages | folders |
SHA1: |
78e8297a835ca07341e26447c44e2a46 |
User & Date: | mistachkin 2013-06-25 11:55:41.393 |
Context
2013-06-25
| ||
19:49 | Modify native argument marshalling so that it will work properly on the .NET Compact Framework. check-in: 9946328e41 user: mistachkin tags: virtualTables | |
11:55 | First attempt at making virtual table support work on the .NET Compact Framework. check-in: 78e8297a83 user: mistachkin tags: virtualTables | |
09:53 | When marshalling from/to the SQLiteIndex class, only marshal data members of the needed direction. The SQLiteVirtualTableCursorEnumerable class should implement the IDisposable pattern. More work on docs. check-in: c6a8523c45 user: mistachkin tags: virtualTables | |
Changes
Changes to SQLite.Interop/src/win/interop.c.
︙ | ︙ | |||
329 330 331 332 333 334 335 336 337 338 339 340 341 342 | sqlite3InteropDebug("sqlite3_prepare_interop(): sqlite3_prepare16(%p, \"%s\", %d, %p) returned %d.\n", db, sql, nchars, ppstmt, n); #endif *plen = (*pztail != 0) ? wcslen((wchar_t *)*pztail) * sizeof(wchar_t) : 0; return n; } SQLITE_API int WINAPI sqlite3_bind_double_interop(sqlite3_stmt *stmt, int iCol, double *val) { return sqlite3_bind_double(stmt,iCol,*val); } SQLITE_API int WINAPI sqlite3_bind_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val) | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | sqlite3InteropDebug("sqlite3_prepare_interop(): sqlite3_prepare16(%p, \"%s\", %d, %p) returned %d.\n", db, sql, nchars, ppstmt, n); #endif *plen = (*pztail != 0) ? wcslen((wchar_t *)*pztail) * sizeof(wchar_t) : 0; return n; } SQLITE_API void *WINAPI sqlite3_create_disposable_module_interop( sqlite3 *db, const char *zName, sqlite3_module *pModule, int iVersion, int (*xCreate)(sqlite3*, void *, int, const char *const*, sqlite3_vtab **, char**), int (*xConnect)(sqlite3*, void *, int, const char *const*, sqlite3_vtab **, char**), int (*xBestIndex)(sqlite3_vtab *, sqlite3_index_info*), int (*xDisconnect)(sqlite3_vtab *), int (*xDestroy)(sqlite3_vtab *), int (*xOpen)(sqlite3_vtab *, sqlite3_vtab_cursor **), int (*xClose)(sqlite3_vtab_cursor*), int (*xFilter)(sqlite3_vtab_cursor*, int, const char *, int, sqlite3_value **), int (*xNext)(sqlite3_vtab_cursor*), int (*xEof)(sqlite3_vtab_cursor*), int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int), int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *), int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *), int (*xBegin)(sqlite3_vtab *), int (*xSync)(sqlite3_vtab *), int (*xCommit)(sqlite3_vtab *), int (*xRollback)(sqlite3_vtab *), int (*xFindFunction)(sqlite3_vtab *, int, const char *, void (**pxFunc)(sqlite3_context*, int, sqlite3_value**), void **ppArg), int (*xRename)(sqlite3_vtab *, const char *), int (*xSavepoint)(sqlite3_vtab *, int), int (*xRelease)(sqlite3_vtab *, int), int (*xRollbackTo)(sqlite3_vtab *, int), void *pClientData, void(*xDestroyModule)(void*) ){ memset(pModule, 0, sizeof(*pModule)); pModule->iVersion = iVersion; pModule->xCreate = xCreate; pModule->xConnect = xConnect; pModule->xBestIndex = xBestIndex; pModule->xDisconnect = xDisconnect; pModule->xDestroy = xDestroy; pModule->xOpen = xOpen; pModule->xClose = xClose; pModule->xFilter = xFilter; pModule->xNext = xNext; pModule->xEof = xEof; pModule->xColumn = xColumn; pModule->xRowid = xRowid; pModule->xUpdate = xUpdate; pModule->xBegin = xBegin; pModule->xSync = xSync; pModule->xCommit = xCommit; pModule->xRollback = xRollback; pModule->xFindFunction = xFindFunction; pModule->xRename = xRename; pModule->xSavepoint = xSavepoint; pModule->xRelease = xRelease; pModule->xRollbackTo = xRollbackTo; return sqlite3_create_disposable_module(db, zName, pModule, pClientData, xDestroyModule); } SQLITE_API void WINAPI sqlite3_dispose_module_interop(void *pModule) { sqlite3_dispose_module(pModule); } SQLITE_API int WINAPI sqlite3_bind_double_interop(sqlite3_stmt *stmt, int iCol, double *val) { return sqlite3_bind_double(stmt,iCol,*val); } SQLITE_API int WINAPI sqlite3_bind_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val) |
︙ | ︙ |
Changes to System.Data.SQLite/SQLite3.cs.
︙ | ︙ | |||
1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 | try { pName = SQLiteString.Utf8IntPtrFromString(module.Name); UnsafeNativeMethods.sqlite3_module nativeModule = module.CreateNativeModule(); if (UnsafeNativeMethods.sqlite3_create_disposable_module( _sql, pName, ref nativeModule, IntPtr.Zero, null) != IntPtr.Zero) { if (_modules == null) _modules = new Dictionary<string, SQLiteModule>(); _modules.Add(module.Name, module); } else | > > > > > > > > > > > > > > > > > | 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 | try { pName = SQLiteString.Utf8IntPtrFromString(module.Name); UnsafeNativeMethods.sqlite3_module nativeModule = module.CreateNativeModule(); #if !PLATFORM_COMPACTFRAMEWORK if (UnsafeNativeMethods.sqlite3_create_disposable_module( _sql, pName, ref nativeModule, IntPtr.Zero, null) != IntPtr.Zero) #else if (UnsafeNativeMethods.sqlite3_create_disposable_module_interop( _sql, pName, module.CreateNativeModuleInterop(), nativeModule.iVersion, nativeModule.xCreate, nativeModule.xConnect, nativeModule.xBestIndex, nativeModule.xDisconnect, nativeModule.xDestroy, nativeModule.xOpen, nativeModule.xClose, nativeModule.xFilter, nativeModule.xNext, nativeModule.xEof, nativeModule.xColumn, nativeModule.xRowId, nativeModule.xUpdate, nativeModule.xBegin, nativeModule.xSync, nativeModule.xCommit, nativeModule.xRollback, nativeModule.xFindFunction, nativeModule.xRename, nativeModule.xSavepoint, nativeModule.xRelease, nativeModule.xRollbackTo, IntPtr.Zero, null) != IntPtr.Zero) #endif { if (_modules == null) _modules = new Dictionary<string, SQLiteModule>(); _modules.Add(module.Name, module); } else |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteModule.cs.
︙ | ︙ | |||
5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 | /// This field is used to store the native sqlite3_module structure /// associated with this object instance. /// </summary> private UnsafeNativeMethods.sqlite3_module nativeModule; /////////////////////////////////////////////////////////////////////// /// <summary> /// This field is used to store the virtual table instances associated /// with this module. The native pointer to the sqlite3_vtab derived /// structure is used to key into this collection. /// </summary> private Dictionary<IntPtr, SQLiteVirtualTable> tables; | > > > > > > > > > > > | 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 | /// This field is used to store the native sqlite3_module structure /// associated with this object instance. /// </summary> private UnsafeNativeMethods.sqlite3_module nativeModule; /////////////////////////////////////////////////////////////////////// #if PLATFORM_COMPACTFRAMEWORK /// <summary> /// This field is used to hold the block of native memory that contains /// the native sqlite3_module structure associated with this object /// instance when running on the .NET Compact Framework. /// </summary> private IntPtr pNativeModule; #endif /////////////////////////////////////////////////////////////////////// /// <summary> /// This field is used to store the virtual table instances associated /// with this module. The native pointer to the sqlite3_vtab derived /// structure is used to key into this collection. /// </summary> private Dictionary<IntPtr, SQLiteVirtualTable> tables; |
︙ | ︙ | |||
5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 | /// default) <see cref="ISQLiteNativeModule" /> interface /// implementation. /// </returns> internal UnsafeNativeMethods.sqlite3_module CreateNativeModule() { return CreateNativeModule(GetNativeModuleImpl()); } #endregion /////////////////////////////////////////////////////////////////////// #region Private Methods /// <summary> /// Creates and returns the native sqlite_module structure using the | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | /// default) <see cref="ISQLiteNativeModule" /> interface /// implementation. /// </returns> internal UnsafeNativeMethods.sqlite3_module CreateNativeModule() { return CreateNativeModule(GetNativeModuleImpl()); } /////////////////////////////////////////////////////////////////////// #if PLATFORM_COMPACTFRAMEWORK /// <summary> /// Creates and returns a memory block obtained from the SQLite core /// library used to store the native sqlite3_module structure for this /// object instance when running on the .NET Compact Framework. /// </summary> /// <returns> /// The native pointer to the native sqlite3_module structure. /// </returns> internal IntPtr CreateNativeModuleInterop() { if (pNativeModule == IntPtr.Zero) { // // HACK: No easy way to determine the size of the native // sqlite_module structure when running on the .NET // Compact Framework; therefore, just base the size // on what we know: // // There is one integer member. // There are 22 function pointers. // pNativeModule = SQLiteMemory.Allocate( sizeof(int) + (22 * IntPtr.Size)); if (pNativeModule == IntPtr.Zero) throw new OutOfMemoryException("sqlite3_module"); } return pNativeModule; } #endif #endregion /////////////////////////////////////////////////////////////////////// #region Private Methods /// <summary> /// Creates and returns the native sqlite_module structure using the |
︙ | ︙ | |||
7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 | ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// try { UnsafeNativeMethods.sqlite3_dispose_module( ref nativeModule); } catch (Exception e) { try { if (LogExceptions) { | > > > > > > > > > > > > > > > | 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 | ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// try { #if !PLATFORM_COMPACTFRAMEWORK UnsafeNativeMethods.sqlite3_dispose_module( ref nativeModule); #else if (pNativeModule != IntPtr.Zero) { try { UnsafeNativeMethods.sqlite3_dispose_module_interop( pNativeModule); } finally { SQLiteMemory.Free(pNativeModule); } } #endif } catch (Exception e) { try { if (LogExceptions) { |
︙ | ︙ |
Changes to System.Data.SQLite/UnsafeNativeMethods.cs.
︙ | ︙ | |||
1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 | internal static extern void sqlite3_value_int64_interop(IntPtr p, out Int64 value); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_result_double_interop(IntPtr context, ref double value); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_result_int64_interop(IntPtr context, ref Int64 value); #endif // PLATFORM_COMPACTFRAMEWORK && !SQLITE_STANDARD #endregion /////////////////////////////////////////////////////////////////////////// #region Native Delegates | > > > > > > > > > > > > > > | 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 | internal static extern void sqlite3_value_int64_interop(IntPtr p, out Int64 value); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_result_double_interop(IntPtr context, ref double value); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_result_int64_interop(IntPtr context, ref Int64 value); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_create_disposable_module_interop( IntPtr db, IntPtr name, IntPtr pModule, int iVersion, xCreate xCreate, xConnect xConnect, xBestIndex xBestIndex, xDisconnect xDisconnect, xDestroy xDestroy, xOpen xOpen, xClose xClose, xFilter xFilter, xNext xNext, xEof xEof, xColumn xColumn, xRowId xRowId, xUpdate xUpdate, xBegin xBegin, xSync xSync, xCommit xCommit, xRollback xRollback, xFindFunction xFindFunction, xRename xRename, xSavepoint xSavepoint, xRelease xRelease, xRollbackTo xRollbackTo, IntPtr pClientData, xDestroyModule xDestroyModule); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_dispose_module_interop(IntPtr pModule); #endif // PLATFORM_COMPACTFRAMEWORK && !SQLITE_STANDARD #endregion /////////////////////////////////////////////////////////////////////////// #region Native Delegates |
︙ | ︙ |
Changes to testce/TestCases.cs.
︙ | ︙ | |||
215 216 217 218 219 220 221 222 223 224 225 226 227 228 | 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++; } | > > > > | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | 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 { ManagedVirtualTable(cnn); frm.WriteLine("SUCCESS - ManagedVirtualTable"); passed++; } catch (Exception) { frm.WriteLine("FAIL - ManagedVirtualTable"); 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++; } |
︙ | ︙ | |||
941 942 943 944 945 946 947 948 949 950 951 952 953 954 | foreach (long value in new long[] { cnn2.LastInsertRowId, cnn2.MemoryUsed, cnn2.MemoryHighwater }) { // do nothing. } return; } throw new NotSupportedException("not a SQLite connection"); } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 | foreach (long value in new long[] { cnn2.LastInsertRowId, cnn2.MemoryUsed, cnn2.MemoryHighwater }) { // do nothing. } return; } throw new NotSupportedException("not a SQLite connection"); } // Make sure that managed virtual table support works on the .NET Compact Framework. internal void ManagedVirtualTable(DbConnection cnn) { SQLiteConnection cnn2 = cnn as SQLiteConnection; if (cnn2 != null) { string[] result = new string[5]; cnn2.CreateModule(new SQLiteModuleEnumerable("enumMod", new string[] { "one", "two", "three", "4", "5.0" })); using (SQLiteCommand command = cnn2.CreateCommand()) { command.CommandText = "CREATE VIRTUAL TABLE enumTab USING enumMod;"; command.ExecuteNonQuery(); } using (SQLiteCommand command = cnn2.CreateCommand()) { command.CommandText = "SELECT * FROM enumTab;"; using (SQLiteDataReader dataReader = command.ExecuteReader()) { int index = 0; while (dataReader.Read()) result[index++] = dataReader[0].ToString(); if (result[0] != "one") throw new ArgumentException("one"); if (result[1] != "two") throw new ArgumentException("two"); if (result[2] != "three") throw new ArgumentException("three"); if (result[3] != "4") throw new ArgumentException("4"); if (result[4] != "5.0") throw new ArgumentException("5.0"); } } using (SQLiteCommand command = cnn2.CreateCommand()) { command.CommandText = "UPDATE enumTab SET x = 1;"; try { command.ExecuteNonQuery(); throw new InvalidOperationException( "UPDATE should throw exception"); } catch (SQLiteException) { // do nothing. } } return; } throw new NotSupportedException("not a SQLite connection"); } |
︙ | ︙ |