Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Refactor previous commit to remove the new delegates as they are not strictly required. Also, remove superfluous newData local variable in the StepCallback method. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | logBind |
Files: | files | file ages | folders |
SHA1: |
c43fca0ae614eb03eeb5238beea29adc |
User & Date: | mistachkin 2012-02-19 08:34:17.884 |
Context
2012-02-19
| ||
13:22 | When converting a DateTime instance of an 'Unspecified' kind to a string, use the same kind as the connection, if available. Also, cleanup handling of the default formats for UTC and local time. Closed-Leaf check-in: dbdf2561a4 user: mistachkin tags: logBind | |
08:34 | Refactor previous commit to remove the new delegates as they are not strictly required. Also, remove superfluous newData local variable in the StepCallback method. check-in: c43fca0ae6 user: mistachkin tags: logBind | |
08:11 | Make sure that exceptions are never thrown back to native code from user-provided function and collation implementations. Also, log all such caught callback exceptions if the appropriate connection flag is set. Fix for ticket [8a426d12eb]. Pass connection flags into SQLiteFunction binding method and refactor internal interfaces to support this. Change type of _contextDataList (SQLiteFunction) dictionary keys from long to IntPtr. check-in: 6136a92dc5 user: mistachkin tags: logBind | |
Changes
Changes to System.Data.SQLite/SQLiteFunction.cs.
︙ | ︙ | |||
44 45 46 47 48 49 50 | /// code. /// </summary> private const int COR_E_EXCEPTION = unchecked((int)0x80131500); #endregion ///////////////////////////////////////////////////////////////////////// | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | /// code. /// </summary> private const int COR_E_EXCEPTION = unchecked((int)0x80131500); #endregion ///////////////////////////////////////////////////////////////////////// /// <summary> /// The base connection this function is attached to /// </summary> internal SQLiteBase _base; /// <summary> /// Internal array used to keep track of aggregate function context data /// </summary> private Dictionary<IntPtr, AggregateData> _contextDataList; /// <summary> /// The connection flags associated with this object (this should be the /// same value as the flags associated with the parent connection object). /// </summary> private SQLiteConnectionFlags _flags; /// <summary> /// Holds a reference to the callback function for user functions /// </summary> private SQLiteCallback _InvokeFunc; /// <summary> /// Holds a reference to the callbakc function for stepping in an aggregate function /// </summary> |
︙ | ︙ | |||
246 247 248 249 250 251 252 | if (disp != null) disp.Dispose(); } _contextDataList.Clear(); _contextDataList = null; _flags = SQLiteConnectionFlags.None; | < < < < | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | if (disp != null) disp.Dispose(); } _contextDataList.Clear(); _contextDataList = null; _flags = SQLiteConnectionFlags.None; _InvokeFunc = null; _StepFunc = null; _FinalFunc = null; _CompareFunc = null; _base = null; } |
︙ | ︙ | |||
465 466 467 468 469 470 471 | _base.ReturnBlob(context, (byte[])returnValue); return; } } /// <summary> /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. | | < < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > | | | < < | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < > | | | | | | < | < < | | | < | 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 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 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 | _base.ReturnBlob(context, (byte[])returnValue); return; } } /// <summary> /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. /// WARNING: Must not throw exceptions. /// </summary> /// <param name="context">A raw context pointer</param> /// <param name="nArgs">Number of arguments passed in</param> /// <param name="argsptr">A pointer to the array of arguments</param> internal void ScalarCallback(IntPtr context, int nArgs, IntPtr argsptr) { try { _context = context; SetReturnValue(context, Invoke(ConvertParams(nArgs, argsptr))); /* throw */ } #if !PLATFORM_COMPACTFRAMEWORK catch (Exception e) /* NOTE: Must catch ALL. */ { try { if ((_flags & SQLiteConnectionFlags.LogCallbackException) == SQLiteConnectionFlags.LogCallbackException) { SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format( "Caught exception in \"Invoke\" method: {0}", e)); /* throw */ } } catch { // do nothing. } } #else catch /* NOTE: Must catch ALL. */ { // do nothing (Windows CE). } #endif } /// <summary> /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. /// WARNING: Must not throw exceptions. /// </summary> /// <param name="ptr">Not used</param> /// <param name="len1">Length of the string pv1</param> /// <param name="ptr1">Pointer to the first string to compare</param> /// <param name="len2">Length of the string pv2</param> /// <param name="ptr2">Pointer to the second string to compare</param> /// <returns>Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater /// than the second. Returns 0 if an exception is caught.</returns> internal int CompareCallback(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2) { try { return Compare(SQLiteConvert.UTF8ToString(ptr1, len1), SQLiteConvert.UTF8ToString(ptr2, len2)); /* throw */ } #if !PLATFORM_COMPACTFRAMEWORK catch (Exception e) /* NOTE: Must catch ALL. */ { try { if ((_flags & SQLiteConnectionFlags.LogCallbackException) == SQLiteConnectionFlags.LogCallbackException) { SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format( "Caught exception in \"Compare\" method: {0}", e)); /* throw */ } } catch { // do nothing. } } #else catch /* NOTE: Must catch ALL. */ { // do nothing (Windows CE). } #endif return 0; } /// <summary> /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. /// WARNING: Must not throw exceptions. /// </summary> /// <param name="ptr">Not used</param> /// <param name="len1">Length of the string pv1</param> /// <param name="ptr1">Pointer to the first string to compare</param> /// <param name="len2">Length of the string pv2</param> /// <param name="ptr2">Pointer to the second string to compare</param> /// <returns>Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater /// than the second. Returns 0 if an exception is caught.</returns> internal int CompareCallback16(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2) { try { return Compare(SQLite3_UTF16.UTF16ToString(ptr1, len1), SQLite3_UTF16.UTF16ToString(ptr2, len2)); /* throw */ } #if !PLATFORM_COMPACTFRAMEWORK catch (Exception e) /* NOTE: Must catch ALL. */ { try { if ((_flags & SQLiteConnectionFlags.LogCallbackException) == SQLiteConnectionFlags.LogCallbackException) { SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format( "Caught exception in \"Compare\" method: {0}", e)); /* throw */ } } catch { // do nothing. } } #else catch /* NOTE: Must catch ALL. */ { // do nothing (Windows CE). } #endif return 0; } /// <summary> /// The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. /// WARNING: Must not throw exceptions. /// </summary> /// <remarks> /// This function takes care of doing the lookups and getting the important information put together to call the Step() function. /// That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so /// binary searches can be done to find the data. /// </remarks> /// <param name="context">A raw context pointer</param> /// <param name="nArgs">Number of arguments passed in</param> /// <param name="argsptr">A pointer to the array of arguments</param> internal void StepCallback(IntPtr context, int nArgs, IntPtr argsptr) { try { AggregateData data = null; if (_base != null) { IntPtr nAux = _base.AggregateContext(context); if ((_contextDataList != null) && !_contextDataList.TryGetValue(nAux, out data)) { data = new AggregateData(); _contextDataList[nAux] = data; } } if (data == null) data = new AggregateData(); try { _context = context; Step(ConvertParams(nArgs, argsptr), data._count, ref data._data); /* throw */ } finally { data._count++; } } #if !PLATFORM_COMPACTFRAMEWORK catch (Exception e) /* NOTE: Must catch ALL. */ { try { if ((_flags & SQLiteConnectionFlags.LogCallbackException) == SQLiteConnectionFlags.LogCallbackException) { SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format( "Caught exception in \"Step\" method: {1}", e)); /* throw */ } } catch { // do nothing. } } #else catch /* NOTE: Must catch ALL. */ { // do nothing (Windows CE). } #endif } /// <summary> /// An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. /// WARNING: Must not throw exceptions. /// </summary> /// <param name="context">A raw context pointer</param> internal void FinalCallback(IntPtr context) { try { object obj = null; if (_base != null) { IntPtr n = _base.AggregateContext(context); AggregateData aggData; if ((_contextDataList != null) && _contextDataList.TryGetValue(n, out aggData)) { obj = aggData._data; _contextDataList.Remove(n); } } try { _context = context; SetReturnValue(context, Final(obj)); /* throw */ } finally { IDisposable disp = obj as IDisposable; if (disp != null) disp.Dispose(); /* throw */ } } #if !PLATFORM_COMPACTFRAMEWORK catch (Exception e) /* NOTE: Must catch ALL. */ { try { if ((_flags & SQLiteConnectionFlags.LogCallbackException) == SQLiteConnectionFlags.LogCallbackException) { SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format( "Caught exception in \"Final\" method: {1}", e)); /* throw */ } } catch { // do nothing. } } #else catch /* NOTE: Must catch ALL. */ { // do nothing (Windows CE). } #endif } /// <summary> /// Using reflection, enumerate all assemblies in the current appdomain looking for classes that /// have a SQLiteFunctionAttribute attribute, and registering them accordingly. /// </summary> #if !PLATFORM_COMPACTFRAMEWORK [Security.Permissions.FileIOPermission(Security.Permissions.SecurityAction.Assert, AllFiles = Security.Permissions.FileIOPermissionAccess.PathDiscovery)] |
︙ | ︙ | |||
858 859 860 861 862 863 864 | foreach (SQLiteFunctionAttribute pr in _registeredFunctions) { f = (SQLiteFunction)Activator.CreateInstance(pr._instanceType); f._base = sqlbase; f._flags = flags; | < < < < | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | foreach (SQLiteFunctionAttribute pr in _registeredFunctions) { f = (SQLiteFunction)Activator.CreateInstance(pr._instanceType); f._base = sqlbase; f._flags = flags; f._InvokeFunc = (pr.FuncType == FunctionType.Scalar) ? new SQLiteCallback(f.ScalarCallback) : null; f._StepFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.StepCallback) : null; f._FinalFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteFinalCallback(f.FinalCallback) : null; f._CompareFunc = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback) : null; f._CompareFunc16 = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback16) : null; if (pr.FuncType != FunctionType.Collation) |
︙ | ︙ |