Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add initial marshalling infrastructure and start implementing the xCreate and xConnect virtual table methods. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | virtualTables |
Files: | files | file ages | folders |
SHA1: |
bf5505be7a7b89649dac56a26aa6dbbe |
User & Date: | mistachkin 2013-06-07 00:04:41.445 |
Context
2013-06-07
| ||
00:28 | Keep track of whether the DeclareVirtualTable method has been called by a virtual table module. check-in: 091ead1daf user: mistachkin tags: virtualTables | |
00:04 | Add initial marshalling infrastructure and start implementing the xCreate and xConnect virtual table methods. check-in: bf5505be7a user: mistachkin tags: virtualTables | |
2013-06-06
| ||
19:36 | Support creating a SQLiteConnection instance from a pre-existing native connection handle (i.e. one that cannot be disposed). check-in: b6c0bcadb3 user: mistachkin tags: virtualTables | |
Changes
Changes to System.Data.SQLite/SQLite3.cs.
︙ | ︙ | |||
1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 | UnsafeNativeMethods.sqlite3_result_text(context, ToUTF8(value), b.Length - 1, (IntPtr)(-1)); } internal override IntPtr AggregateContext(IntPtr context) { return UnsafeNativeMethods.sqlite3_aggregate_context(context, 1); } /// <summary> /// Enables or disabled extension loading by SQLite. /// </summary> /// <param name="bOnOff"> /// True to enable loading of extensions, false to disable. /// </param> | > > > > > > > > > > > > > > > > > > > > > > > > > | 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 | UnsafeNativeMethods.sqlite3_result_text(context, ToUTF8(value), b.Length - 1, (IntPtr)(-1)); } internal override IntPtr AggregateContext(IntPtr context) { return UnsafeNativeMethods.sqlite3_aggregate_context(context, 1); } /// <summary> /// Calls the native SQLite core library in order to declare a virtual table /// in response to a call into the xCreate or xConnect virtual table methods. /// </summary> /// <param name="strSql"> /// The string containing the SQL statement describing the virtual table to /// be declared. /// </param> /// <param name="error"> /// Upon success, the contents of this parameter are undefined. Upon failure, /// it should contain an appropriate error message. /// </param> /// <returns> /// A standard SQLite return code. /// </returns> internal override SQLiteErrorCode DeclareVirtualTable(string strSql, ref string error) { SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_declare_vtab( _sql, SQLiteModuleBase.Utf8IntPtrFromString(strSql)); if (n != SQLiteErrorCode.Ok) error = GetLastError(); return n; } /// <summary> /// Enables or disabled extension loading by SQLite. /// </summary> /// <param name="bOnOff"> /// True to enable loading of extensions, false to disable. /// </param> |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteBase.cs.
︙ | ︙ | |||
197 198 199 200 201 202 203 204 205 206 207 208 209 210 | internal abstract void ReturnDouble(IntPtr context, double value); internal abstract void ReturnError(IntPtr context, string value); internal abstract void ReturnInt32(IntPtr context, Int32 value); internal abstract void ReturnInt64(IntPtr context, Int64 value); internal abstract void ReturnNull(IntPtr context); internal abstract void ReturnText(IntPtr context, string value); /// <summary> /// Enables or disabled extension loading by SQLite. /// </summary> /// <param name="bOnOff"> /// True to enable loading of extensions, false to disable. /// </param> internal abstract void SetLoadExtension(bool bOnOff); | > > > > > > > > > > > > > > > > > | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | internal abstract void ReturnDouble(IntPtr context, double value); internal abstract void ReturnError(IntPtr context, string value); internal abstract void ReturnInt32(IntPtr context, Int32 value); internal abstract void ReturnInt64(IntPtr context, Int64 value); internal abstract void ReturnNull(IntPtr context); internal abstract void ReturnText(IntPtr context, string value); /// <summary> /// Calls the native SQLite core library in order to declare a virtual table /// in response to a call into the xCreate or xConnect virtual table methods. /// </summary> /// <param name="strSql"> /// The string containing the SQL statement describing the virtual table to /// be declared. /// </param> /// <param name="error"> /// Upon success, the contents of this parameter are undefined. Upon failure, /// it should contain an appropriate error message. /// </param> /// <returns> /// A standard SQLite return code. /// </returns> internal abstract SQLiteErrorCode DeclareVirtualTable(string strSql, ref string error); /// <summary> /// Enables or disabled extension loading by SQLite. /// </summary> /// <param name="bOnOff"> /// True to enable loading of extensions, false to disable. /// </param> internal abstract void SetLoadExtension(bool bOnOff); |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteModuleBase.cs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Joe Mistachkin (joe@mistachkin.com) * * Released to the public domain, use at your own risk! ********************************************************/ using System.Runtime.InteropServices; using System.Security; #if !NET_40 using System.Security.Permissions; #endif namespace System.Data.SQLite { | > > < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Joe Mistachkin (joe@mistachkin.com) * * Released to the public domain, use at your own risk! ********************************************************/ using System.Runtime.InteropServices; using System.Security; #if !NET_40 using System.Security.Permissions; #endif using System.Text; namespace System.Data.SQLite { public sealed class SQLiteContext { } /////////////////////////////////////////////////////////////////////// |
︙ | ︙ | |||
80 81 82 83 84 85 86 | int argc, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] IntPtr[] argv ); public interface ISQLiteNativeModule { | | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | int argc, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] IntPtr[] argv ); public interface ISQLiteNativeModule { SQLiteErrorCode xCreate(IntPtr pDb, IntPtr pAux, int argc, ref IntPtr[] argv, ref IntPtr pVtab, ref IntPtr pError); SQLiteErrorCode xConnect(IntPtr pDb, IntPtr pAux, int argc, ref IntPtr[] argv, ref IntPtr pVtab, ref IntPtr pError); SQLiteErrorCode xBestIndex(IntPtr pVtab, IntPtr index); SQLiteErrorCode xDisconnect(IntPtr pVtab); SQLiteErrorCode xDestroy(IntPtr pVtab); SQLiteErrorCode xOpen(IntPtr pVtab, ref IntPtr cursor); SQLiteErrorCode xClose(IntPtr cursor); SQLiteErrorCode xFilter(IntPtr cursor, int idxNum, IntPtr idxStr, int argc, IntPtr[] argv); SQLiteErrorCode xNext(IntPtr cursor); |
︙ | ︙ | |||
137 138 139 140 141 142 143 144 145 146 147 148 149 150 | #if NET_40 [SecurityCritical()] #else [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] #endif public abstract class SQLiteModuleBase : ISQLiteManagedModule, ISQLiteNativeModule, IDisposable { #region Unsafe Native Methods Class [SuppressUnmanagedCodeSecurity()] internal static class UnsafeNativeMethods2 { // https://www.sqlite.org/vtab.html | > > | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | #if NET_40 [SecurityCritical()] #else [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] #endif public abstract class SQLiteModuleBase : ISQLiteManagedModule, ISQLiteNativeModule, IDisposable { private static Encoding Utf8Encoding = Encoding.UTF8; #region Unsafe Native Methods Class [SuppressUnmanagedCodeSecurity()] internal static class UnsafeNativeMethods2 { // https://www.sqlite.org/vtab.html |
︙ | ︙ | |||
237 238 239 240 241 242 243 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate SQLiteErrorCode xCreate( | | | | | | 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate SQLiteErrorCode xCreate( IntPtr pDb, IntPtr pAux, int argc, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] ref IntPtr[] argv, ref IntPtr pVtab, ref IntPtr pError ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate SQLiteErrorCode xConnect( IntPtr pDb, IntPtr pAux, int argc, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] ref IntPtr[] argv, ref IntPtr pVtab, ref IntPtr pError ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate SQLiteErrorCode xBestIndex( [MarshalAs(UnmanagedType.LPStruct)] IntPtr pVtab, [MarshalAs(UnmanagedType.LPStruct)] |
︙ | ︙ | |||
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | module.xRename = new UnsafeNativeMethods2.xRename(xRename); module.xSavepoint = new UnsafeNativeMethods2.xSavepoint(xSavepoint); module.xRelease = new UnsafeNativeMethods2.xRelease(xRelease); module.xRollbackTo = new UnsafeNativeMethods2.xRollbackTo(xRollbackTo); return module; } #endregion /////////////////////////////////////////////////////////////////////// #region Public Constructors public SQLiteModuleBase() { } #endregion /////////////////////////////////////////////////////////////////////// #region ISQLiteNativeModule Members public SQLiteErrorCode xCreate( | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > | > | > > > > > | < | > > | | > > > > > > | > | | > > > > > > > > > > > > > > > > > > > > > > > > | | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 | module.xRename = new UnsafeNativeMethods2.xRename(xRename); module.xSavepoint = new UnsafeNativeMethods2.xSavepoint(xSavepoint); module.xRelease = new UnsafeNativeMethods2.xRelease(xRelease); module.xRollbackTo = new UnsafeNativeMethods2.xRollbackTo(xRollbackTo); return module; } private static int ThirtyBits = 0x3fffffff; /////////////////////////////////////////////////////////////////////// private static byte[] GetUtf8BytesFromString(string value) { if (value == null) return null; return Utf8Encoding.GetBytes(value); } /////////////////////////////////////////////////////////////////////// private static string GetStringFromUtf8Bytes(byte[] bytes) { if (bytes == null) return null; return Utf8Encoding.GetString(bytes); } /////////////////////////////////////////////////////////////////////// private static IntPtr Allocate(int size) { return UnsafeNativeMethods.sqlite3_malloc(size); } /////////////////////////////////////////////////////////////////////// private static void Free(IntPtr pMemory) { UnsafeNativeMethods.sqlite3_free(pMemory); } /////////////////////////////////////////////////////////////////////// private static int ProbeForUtf8ByteLength(IntPtr pValue, int limit) { int length = 0; if (pValue != IntPtr.Zero) { do { if (Marshal.ReadByte(pValue, length) == 0) break; if (length >= limit) break; length++; } while (true); } return length; } /////////////////////////////////////////////////////////////////////// private static string StringFromUtf8IntPtr(IntPtr pValue) { if (pValue == IntPtr.Zero) return null; int length = ProbeForUtf8ByteLength(pValue, ThirtyBits); if (length > 0) { byte[] bytes = new byte[length]; Marshal.Copy(pValue, bytes, 0, length); return GetStringFromUtf8Bytes(bytes); } return String.Empty; } /////////////////////////////////////////////////////////////////////// private static string[] StringArrayFromUtf8IntPtrArray( IntPtr[] pValues ) { if (pValues == null) return null; string[] result = new string[pValues.Length]; for (int index = 0; index < result.Length; index++) result[index] = StringFromUtf8IntPtr(pValues[index]); return result; } /////////////////////////////////////////////////////////////////////// internal static IntPtr Utf8IntPtrFromString(string value) { if (value == null) return IntPtr.Zero; IntPtr result = IntPtr.Zero; byte[] bytes = GetUtf8BytesFromString(value); if (bytes == null) return IntPtr.Zero; int length = bytes.Length; result = Allocate(length + 1); Marshal.Copy(bytes, 0, result, length); Marshal.WriteByte(result, length, 0); return result; } /////////////////////////////////////////////////////////////////////// private static IntPtr[] Utf8IntPtrArrayFromStringArray( string[] values ) { if (values == null) return null; IntPtr[] result = new IntPtr[values.Length]; for (int index = 0; index < result.Length; index++) result[index] = Utf8IntPtrFromString(values[index]); return result; } #endregion /////////////////////////////////////////////////////////////////////// #region Public Constructors public SQLiteModuleBase() { } #endregion /////////////////////////////////////////////////////////////////////// #region Protected Members protected virtual IntPtr AllocateVirtualTable() { int size = Marshal.SizeOf(typeof( UnsafeNativeMethods2.sqlite3_vtab)); return Allocate(size); } /////////////////////////////////////////////////////////////////////// protected virtual void FreeVirtualTable(IntPtr pVtab) { Free(pVtab); } /////////////////////////////////////////////////////////////////////// protected virtual SQLiteErrorCode DeclareVirtualTable( SQLiteConnection connection, string sql, ref string error ) { if (connection == null) { error = "invalid connection"; return SQLiteErrorCode.Error; } SQLiteBase sqliteBase = connection._sql; if (sqliteBase == null) { error = "connection has invalid handle"; return SQLiteErrorCode.Error; } return sqliteBase.DeclareVirtualTable(sql, ref error); } #endregion /////////////////////////////////////////////////////////////////////// #region ISQLiteNativeModule Members public SQLiteErrorCode xCreate( IntPtr pDb, IntPtr pAux, int argc, ref IntPtr[] argv, ref IntPtr pVtab, ref IntPtr pError ) { try { using (SQLiteConnection connection = new SQLiteConnection( pDb, false)) { string error = null; if (Create(connection, pAux, StringArrayFromUtf8IntPtrArray(argv), ref error) == SQLiteErrorCode.Ok) { pVtab = AllocateVirtualTable(); } else { pError = Utf8IntPtrFromString(error); } } } catch (Exception e) /* NOTE: Must catch ALL. */ { pError = Utf8IntPtrFromString(e.ToString()); } return SQLiteErrorCode.Error; } /////////////////////////////////////////////////////////////////////// public SQLiteErrorCode xConnect( IntPtr pDb, IntPtr pAux, int argc, ref IntPtr[] argv, ref IntPtr pVtab, ref IntPtr pError ) { try { using (SQLiteConnection connection = new SQLiteConnection( pDb, false)) { string error = null; if (Connect(connection, pAux, StringArrayFromUtf8IntPtrArray(argv), ref error) == SQLiteErrorCode.Ok) { pVtab = AllocateVirtualTable(); } else { pError = Utf8IntPtrFromString(error); } } } catch (Exception e) /* NOTE: Must catch ALL. */ { pError = Utf8IntPtrFromString(e.ToString()); } return SQLiteErrorCode.Error; } /////////////////////////////////////////////////////////////////////// public SQLiteErrorCode xBestIndex( IntPtr pVtab, IntPtr index |
︙ | ︙ |
Changes to System.Data.SQLite/UnsafeNativeMethods.cs.
︙ | ︙ | |||
1558 1559 1560 1561 1562 1563 1564 | #else [DllImport(SQLITE_DLL)] #endif internal static extern int sqlite3_backup_pagecount(IntPtr backup); #if !PLATFORM_COMPACTFRAMEWORK [UnmanagedFunctionPointer(CallingConvention.Cdecl)] | < > | < < < < < < < < < < | 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 | #else [DllImport(SQLITE_DLL)] #endif internal static extern int sqlite3_backup_pagecount(IntPtr backup); #if !PLATFORM_COMPACTFRAMEWORK [UnmanagedFunctionPointer(CallingConvention.Cdecl)] #endif public delegate void xDestroyModule(IntPtr pClientData); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern SQLiteErrorCode sqlite3_create_module_v2(IntPtr db, IntPtr name, IntPtr pModule, IntPtr pClientData, xDestroyModule xDestroy); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern SQLiteErrorCode sqlite3_declare_vtab(IntPtr db, IntPtr zSQL); |
︙ | ︙ |