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 | SQL archive |
Timelines: | family | ancestors | descendants | both | virtualTables |
Files: | files | file ages | folders |
SHA1: |
78e8297a835ca07341e26447c44e2a46 |
User & Date: | mistachkin 2013-06-25 11:55:41 |
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 .... 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 .... 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 |
/// 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; ................................................................................ /// 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 ................................................................................ ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// try { UnsafeNativeMethods.sqlite3_dispose_module( ref nativeModule); } catch (Exception e) { try { if (LogExceptions) { |
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 .... 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 .... 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 |
/// 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; ................................................................................ /// 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 ................................................................................ ////////////////////////////////////// // 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
...
941
942
943
944
945
946
947
948
949
950
951
952
953
954
|
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++; }
................................................................................
foreach (long value in new long[] {
cnn2.LastInsertRowId, cnn2.MemoryUsed,
cnn2.MemoryHighwater
})
{
// do nothing.
}
return;
}
throw new NotSupportedException("not a SQLite connection");
}
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
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
|
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++; } ................................................................................ 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"); } |