Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix disposal semantics for classes derived from the SQLiteModuleBase class. Use the String.Format method consistently. Enable virtual table related native memory allocation tracking on the .NET Compact Framework. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | virtualTables |
Files: | files | file ages | folders |
SHA1: |
f9041807b3bc2a21e72640b23f496703 |
User & Date: | mistachkin 2013-06-21 06:27:07.748 |
Context
2013-06-21
| ||
06:33 | Always attempt to log virtual table errors. check-in: b5a342952a user: mistachkin tags: virtualTables | |
06:27 | Fix disposal semantics for classes derived from the SQLiteModuleBase class. Use the String.Format method consistently. Enable virtual table related native memory allocation tracking on the .NET Compact Framework. check-in: f9041807b3 user: mistachkin tags: virtualTables | |
06:06 | Modularize various aspects of the virtual table handling in the example SQLiteVirtualTableCursorEnumerable class. check-in: 5033bacee1 user: mistachkin tags: virtualTables | |
Changes
Changes to System.Data.SQLite/SQLite3.cs.
︙ | ︙ | |||
705 706 707 708 709 710 711 712 713 714 715 716 717 718 | } protected static void LogBind(SQLiteStatementHandle handle, int index) { IntPtr handleIntPtr = handle; SQLiteLog.LogMessage(String.Format( "Binding statement {0} paramter #{1} as NULL...", handleIntPtr, index)); } protected static void LogBind(SQLiteStatementHandle handle, int index, ValueType value) { IntPtr handleIntPtr = handle; | > | 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 | } protected static void LogBind(SQLiteStatementHandle handle, int index) { IntPtr handleIntPtr = handle; SQLiteLog.LogMessage(String.Format( CultureInfo.CurrentCulture, "Binding statement {0} paramter #{1} as NULL...", handleIntPtr, index)); } protected static void LogBind(SQLiteStatementHandle handle, int index, ValueType value) { IntPtr handleIntPtr = handle; |
︙ | ︙ | |||
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 | int value = UnsafeNativeMethods.sqlite3_bind_parameter_count(handle); if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) { IntPtr handleIntPtr = handle; SQLiteLog.LogMessage(String.Format( "Statement {0} paramter count is {1}.", handleIntPtr, value)); } return value; } | > | 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 | int value = UnsafeNativeMethods.sqlite3_bind_parameter_count(handle); if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) { IntPtr handleIntPtr = handle; SQLiteLog.LogMessage(String.Format( CultureInfo.CurrentCulture, "Statement {0} paramter count is {1}.", handleIntPtr, value)); } return value; } |
︙ | ︙ | |||
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 | #endif if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) { IntPtr handleIntPtr = handle; SQLiteLog.LogMessage(String.Format( "Statement {0} paramter #{1} name is {{{2}}}.", handleIntPtr, index, name)); } return name; } internal override int Bind_ParamIndex(SQLiteStatement stmt, SQLiteConnectionFlags flags, string paramName) { SQLiteStatementHandle handle = stmt._sqlite_stmt; int index = UnsafeNativeMethods.sqlite3_bind_parameter_index(handle, ToUTF8(paramName)); if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) { IntPtr handleIntPtr = handle; SQLiteLog.LogMessage(String.Format( "Statement {0} paramter index of name {{{1}}} is #{2}.", handleIntPtr, paramName, index)); } return index; } | > > | 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 | #endif if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) { IntPtr handleIntPtr = handle; SQLiteLog.LogMessage(String.Format( CultureInfo.CurrentCulture, "Statement {0} paramter #{1} name is {{{2}}}.", handleIntPtr, index, name)); } return name; } internal override int Bind_ParamIndex(SQLiteStatement stmt, SQLiteConnectionFlags flags, string paramName) { SQLiteStatementHandle handle = stmt._sqlite_stmt; int index = UnsafeNativeMethods.sqlite3_bind_parameter_index(handle, ToUTF8(paramName)); if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) { IntPtr handleIntPtr = handle; SQLiteLog.LogMessage(String.Format( CultureInfo.CurrentCulture, "Statement {0} paramter index of name {{{1}}} is #{2}.", handleIntPtr, paramName, index)); } return index; } |
︙ | ︙ | |||
1624 1625 1626 1627 1628 1629 1630 | /// method. /// </param> internal override void DisposeModule(SQLiteModuleBase module) { if (module == null) throw new ArgumentNullException("module"); | < | < < < < | 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 | /// method. /// </param> internal override void DisposeModule(SQLiteModuleBase module) { if (module == null) throw new ArgumentNullException("module"); module.Dispose(); } internal override IntPtr AggregateContext(IntPtr context) { return UnsafeNativeMethods.sqlite3_aggregate_context(context, 1); } |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteConnection.cs.
︙ | ︙ | |||
1465 1466 1467 1468 1469 1470 1471 | arParts = SQLiteConvert.Split(s, ';'); else #endif arParts = SQLiteConvert.NewSplit(s, ';', true, ref error); if (arParts == null) { | | | 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 | arParts = SQLiteConvert.Split(s, ';'); else #endif arParts = SQLiteConvert.NewSplit(s, ';', true, ref error); if (arParts == null) { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Invalid ConnectionString format, cannot parse: {0}", (error != null) ? error : "could not split connection string into properties")); } int x = (arParts != null) ? arParts.Length : 0; // For each semi-colon piece, split into key and value pairs by the presence of the = sign for (n = 0; n < x; n++) |
︙ | ︙ | |||
1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 | bool enable ) { CheckDisposed(); if (_sql == null) throw new InvalidOperationException(String.Format( "Database connection not valid for {0} extensions.", enable ? "enabling" : "disabling")); _sql.SetLoadExtension(enable); } /// <summary> | > | 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 | bool enable ) { CheckDisposed(); if (_sql == null) throw new InvalidOperationException(String.Format( CultureInfo.CurrentCulture, "Database connection not valid for {0} extensions.", enable ? "enabling" : "disabling")); _sql.SetLoadExtension(enable); } /// <summary> |
︙ | ︙ | |||
1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 | { string value = text.Substring(index, 2); if (!TryParseByte(value, NumberStyles.HexNumber, out result[index / 2])) { error = String.Format( "string contains \"{0}\", which cannot be converted to a byte value", value); return null; } } | > | 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 | { string value = text.Substring(index, 2); if (!TryParseByte(value, NumberStyles.HexNumber, out result[index / 2])) { error = String.Format( CultureInfo.CurrentCulture, "string contains \"{0}\", which cannot be converted to a byte value", value); return null; } } |
︙ | ︙ | |||
1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 | { string error = null; byte[] hexPasswordBytes = FromHexString(hexPassword, ref error); if (hexPasswordBytes == null) { throw new FormatException(String.Format( "Cannot parse 'HexPassword' property value into byte values: {0}", error)); } _sql.SetPassword(hexPasswordBytes); } else | > | 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 | { string error = null; byte[] hexPasswordBytes = FromHexString(hexPassword, ref error); if (hexPasswordBytes == null) { throw new FormatException(String.Format( CultureInfo.CurrentCulture, "Cannot parse 'HexPassword' property value into byte values: {0}", error)); } _sql.SetPassword(hexPasswordBytes); } else |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteConvert.cs.
︙ | ︙ | |||
944 945 946 947 948 949 950 951 952 953 954 955 956 957 | return value.typeName; } string defaultTypeName = String.Empty; #if !NET_COMPACT_20 && TRACE_WARNING Trace.WriteLine(String.Format( "WARNING: Type mapping failed, returning default name \"{0}\" for type {1}.", defaultTypeName, typ)); #endif return defaultTypeName; } | > | 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 | return value.typeName; } string defaultTypeName = String.Empty; #if !NET_COMPACT_20 && TRACE_WARNING Trace.WriteLine(String.Format( CultureInfo.CurrentCulture, "WARNING: Type mapping failed, returning default name \"{0}\" for type {1}.", defaultTypeName, typ)); #endif return defaultTypeName; } |
︙ | ︙ | |||
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 | } } DbType defaultDbType = DbType.Object; #if !NET_COMPACT_20 && TRACE_WARNING Trace.WriteLine(String.Format( "WARNING: Type mapping failed, returning default type {0} for name \"{1}\".", defaultDbType, Name)); #endif return defaultDbType; } #endregion | > | 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 | } } DbType defaultDbType = DbType.Object; #if !NET_COMPACT_20 && TRACE_WARNING Trace.WriteLine(String.Format( CultureInfo.CurrentCulture, "WARNING: Type mapping failed, returning default type {0} for name \"{1}\".", defaultDbType, Name)); #endif return defaultDbType; } #endregion |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteLog.cs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ namespace System.Data.SQLite { using System; using System.Data.Common; using System.Diagnostics; /// <summary> /// Event data for logging event handlers. /// </summary> public class LogEventArgs : EventArgs { /// <summary> | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ namespace System.Data.SQLite { using System; using System.Data.Common; using System.Diagnostics; using System.Globalization; /// <summary> /// Event data for logging event handlers. /// </summary> public class LogEventArgs : EventArgs { /// <summary> |
︙ | ︙ | |||
522 523 524 525 526 527 528 | bool success = false; if (errorCode is SQLiteErrorCode) success = ((SQLiteErrorCode)errorCode == SQLiteErrorCode.Ok); else if (errorCode is int) success = ((int)errorCode == 0); | | > | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 | bool success = false; if (errorCode is SQLiteErrorCode) success = ((SQLiteErrorCode)errorCode == SQLiteErrorCode.Ok); else if (errorCode is int) success = ((int)errorCode == 0); Trace.WriteLine(String.Format( CultureInfo.CurrentCulture, "SQLite {0} ({1}): {2}", success ? "message" : "error", errorCode, message)); #endif } } } |
Changes to System.Data.SQLite/SQLiteModuleBase.cs.
︙ | ︙ | |||
1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 | /////////////////////////////////////////////////////////////////////////// #region SQLiteMemory Class internal static class SQLiteMemory { #region Private Data #if TRACK_MEMORY_BYTES private static int bytesAllocated; private static int maximumBytesAllocated; #endif #endregion /////////////////////////////////////////////////////////////////////// #region Memory Allocation Helper Methods public static IntPtr Allocate(int size) { IntPtr pMemory = UnsafeNativeMethods.sqlite3_malloc(size); #if TRACK_MEMORY_BYTES if (pMemory != IntPtr.Zero) { int blockSize = Size(pMemory); if (blockSize > 0) { Interlocked.Add(ref bytesAllocated, blockSize); Interlocked.Add(ref maximumBytesAllocated, blockSize); } } #endif return pMemory; } | > > > > > > > > > > > > > > | 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 | /////////////////////////////////////////////////////////////////////////// #region SQLiteMemory Class internal static class SQLiteMemory { #region Private Data #if TRACK_MEMORY_BYTES #if PLATFORM_COMPACTFRAMEWORK private static object syncRoot = new object(); #endif /////////////////////////////////////////////////////////////////////// private static int bytesAllocated; private static int maximumBytesAllocated; #endif #endregion /////////////////////////////////////////////////////////////////////// #region Memory Allocation Helper Methods public static IntPtr Allocate(int size) { IntPtr pMemory = UnsafeNativeMethods.sqlite3_malloc(size); #if TRACK_MEMORY_BYTES if (pMemory != IntPtr.Zero) { int blockSize = Size(pMemory); if (blockSize > 0) { #if !PLATFORM_COMPACTFRAMEWORK Interlocked.Add(ref bytesAllocated, blockSize); Interlocked.Add(ref maximumBytesAllocated, blockSize); #else lock (syncRoot) { bytesAllocated += blockSize; maximumBytesAllocated += blockSize; } #endif } } #endif return pMemory; } |
︙ | ︙ | |||
1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 | { #if TRACK_MEMORY_BYTES if (pMemory != IntPtr.Zero) { int blockSize = Size(pMemory); if (blockSize > 0) Interlocked.Add(ref bytesAllocated, -blockSize); } #endif UnsafeNativeMethods.sqlite3_free(pMemory); } #endregion } | > > > > > > > > > | 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 | { #if TRACK_MEMORY_BYTES if (pMemory != IntPtr.Zero) { int blockSize = Size(pMemory); if (blockSize > 0) { #if !PLATFORM_COMPACTFRAMEWORK Interlocked.Add(ref bytesAllocated, -blockSize); #else lock (syncRoot) { bytesAllocated -= blockSize; } #endif } } #endif UnsafeNativeMethods.sqlite3_free(pMemory); } #endregion } |
︙ | ︙ | |||
2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 | if ((tables != null) && tables.TryGetValue(pVtab, out table)) { return table; } SetTableError(pVtab, String.Format( "managed table for {0} not found", pVtab)); return null; } /////////////////////////////////////////////////////////////////////// | > | 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 | if ((tables != null) && tables.TryGetValue(pVtab, out table)) { return table; } SetTableError(pVtab, String.Format( CultureInfo.CurrentCulture, "managed table for {0} not found", pVtab)); return null; } /////////////////////////////////////////////////////////////////////// |
︙ | ︙ | |||
2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 | if ((cursors != null) && cursors.TryGetValue(pCursor, out cursor)) { return cursor; } SetTableError(pVtab, String.Format( "managed cursor for {0} not found", pCursor)); return null; } /////////////////////////////////////////////////////////////////////// | > | 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 | if ((cursors != null) && cursors.TryGetValue(pCursor, out cursor)) { return cursor; } SetTableError(pVtab, String.Format( CultureInfo.CurrentCulture, "managed cursor for {0} not found", pCursor)); return null; } /////////////////////////////////////////////////////////////////////// |
︙ | ︙ | |||
3307 3308 3309 3310 3311 3312 3313 | // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// | > | > > | > > > > > > > > > > > > > > | 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 | // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// try { UnsafeNativeMethods.sqlite3_dispose_module( ref nativeModule); } catch (Exception e) { try { SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION, String.Format(CultureInfo.CurrentCulture, "Caught exception in \"Dispose\" method: {0}", e)); /* throw */ } catch { // do nothing. } } disposed = true; } } #endregion /////////////////////////////////////////////////////////////////////// |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteModuleEnumerable.cs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /******************************************************** * 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.Collections; namespace System.Data.SQLite { #region SQLiteVirtualTableCursorEnumerable Class /* NOT SEALED */ public class SQLiteVirtualTableCursorEnumerable : SQLiteVirtualTableCursor { | > | 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.Collections; using System.Globalization; namespace System.Data.SQLite { #region SQLiteVirtualTableCursorEnumerable Class /* NOT SEALED */ public class SQLiteVirtualTableCursorEnumerable : SQLiteVirtualTableCursor { |
︙ | ︙ | |||
89 90 91 92 93 94 95 | #region SQLiteModuleEnumerable Class /* NOT SEALED */ public class SQLiteModuleEnumerable : SQLiteModuleNoop { #region Private Constants private static readonly string declareSql = String.Format( | > | | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | #region SQLiteModuleEnumerable Class /* NOT SEALED */ public class SQLiteModuleEnumerable : SQLiteModuleNoop { #region Private Constants private static readonly string declareSql = String.Format( CultureInfo.CurrentCulture, "CREATE TABLE {0}(x);", typeof(SQLiteModuleEnumerable).Name); #endregion /////////////////////////////////////////////////////////////////////// #region Private Data /// <summary> /// The <see cref="IEnumerable" /> instance containing the backing data |
︙ | ︙ | |||
420 421 422 423 424 425 426 | SQLiteVirtualTable table, SQLiteValue[] values, ref long rowId ) { CheckDisposed(); | | | | 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 | SQLiteVirtualTable table, SQLiteValue[] values, ref long rowId ) { CheckDisposed(); SetTableError(table, String.Format(CultureInfo.CurrentCulture, "virtual table \"{0}\" is read-only", table.TableName)); return SQLiteErrorCode.Error; } /////////////////////////////////////////////////////////////////////// public override SQLiteErrorCode Rename( SQLiteVirtualTable table, string newName ) { CheckDisposed(); if (!table.Rename(newName)) { SetTableError(table, String.Format(CultureInfo.CurrentCulture, "failed to rename virtual table from \"{0}\" to \"{1}\"", table.TableName, newName)); return SQLiteErrorCode.Error; } return SQLiteErrorCode.Ok; |
︙ | ︙ |