Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Work in progress for ticket [8d928c3e88]. These changes are not yet fully tested. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | tkt-8d928c3e88 |
Files: | files | file ages | folders |
SHA1: |
0b6d0e63ca2b1cd2a0125aef7117e422 |
User & Date: | mistachkin 2015-01-08 04:55:10.227 |
Context
2015-01-08
| ||
17:42 | More work on testability. check-in: d8ed5e99ae user: mistachkin tags: tkt-8d928c3e88 | |
04:55 | Work in progress for ticket [8d928c3e88]. These changes are not yet fully tested. check-in: 0b6d0e63ca user: mistachkin tags: tkt-8d928c3e88 | |
2015-01-07
| ||
01:11 | Configuration file cleanup: omit the 'remove' element for the legacy 'System.Data.SQLite' provider from the LINQ-specific and EF6-specific configuration files. check-in: 573499eaf2 user: mistachkin tags: trunk | |
Changes
Changes to System.Data.SQLite.Linq/SQL Generation/SqlGenerator.cs.
︙ | ︙ | |||
871 872 873 874 875 876 877 | switch (typeKind) { case PrimitiveTypeKind.Int32: result.Append(e.Value.ToString()); break; case PrimitiveTypeKind.Binary: | < | < | > > > > | 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 | switch (typeKind) { case PrimitiveTypeKind.Int32: result.Append(e.Value.ToString()); break; case PrimitiveTypeKind.Binary: ToBlobLiteral((byte[])e.Value, result); break; case PrimitiveTypeKind.Boolean: result.Append((bool)e.Value ? "1" : "0"); break; case PrimitiveTypeKind.Byte: result.Append(e.Value.ToString()); break; case PrimitiveTypeKind.DateTime: result.Append(EscapeSingleQuote(SQLiteConvert.ToString( (System.DateTime)e.Value, _manifest._dateTimeFormat, _manifest._dateTimeKind, _manifest._dateTimeFormatString), false /* IsUnicode */)); break; case PrimitiveTypeKind.Decimal: string strDecimal = ((Decimal)e.Value).ToString(CultureInfo.InvariantCulture); // if the decimal value has no decimal part, cast as decimal to preserve type // if the number has precision > int64 max precision, it will be handled as decimal by sql server // and does not need cast. if precision is lest then 20, then cast using Max(literal precision, sql default precision) |
︙ | ︙ | |||
919 920 921 922 923 924 925 | break; case PrimitiveTypeKind.Double: result.Append(((Double)e.Value).ToString(CultureInfo.InvariantCulture)); break; case PrimitiveTypeKind.Guid: | > > > > > > | > | 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 | break; case PrimitiveTypeKind.Double: result.Append(((Double)e.Value).ToString(CultureInfo.InvariantCulture)); break; case PrimitiveTypeKind.Guid: { object value = e.Value; if (_manifest._binaryGuid && (value is Guid)) ToBlobLiteral(((Guid)value).ToByteArray(), result); else result.Append(EscapeSingleQuote(e.Value.ToString(), false /* IsUnicode */)); } break; case PrimitiveTypeKind.Int16: result.Append(e.Value.ToString()); break; case PrimitiveTypeKind.Int64: |
︙ | ︙ | |||
2687 2688 2689 2690 2691 2692 2693 | } private static ISqlFragment HandleGetDateFunction(SqlGenerator sqlgen, DbFunctionExpression e) { SqlBuilder result = new SqlBuilder(); Debug.Assert(e.Arguments.Count == 0, "Canonical getdate function should have no arguments"); | | | | 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 | } private static ISqlFragment HandleGetDateFunction(SqlGenerator sqlgen, DbFunctionExpression e) { SqlBuilder result = new SqlBuilder(); Debug.Assert(e.Arguments.Count == 0, "Canonical getdate function should have no arguments"); switch (sqlgen._manifest._dateTimeFormat) { case SQLiteDateFormats.Ticks: result.Append("(STRFTIME('%s', 'now') * 10000000 + 621355968000000000)"); break; case SQLiteDateFormats.JulianDay: result.Append("CAST(STRFTIME('%J', 'now') AS double)"); break; default: result.Append("STRFTIME('%Y-%m-%d %H:%M:%S', 'now')"); break; } return result; } private static ISqlFragment HandleGetUtcDateFunction(SqlGenerator sqlgen, DbFunctionExpression e) { SqlBuilder result = new SqlBuilder(); Debug.Assert(e.Arguments.Count == 0, "Canonical getutcdate function should have no arguments"); switch (sqlgen._manifest._dateTimeFormat) { case SQLiteDateFormats.Ticks: result.Append("(STRFTIME('%s', 'now', 'utc') * 10000000 + 621355968000000000)"); break; case SQLiteDateFormats.JulianDay: result.Append("CAST(STRFTIME('%J', 'now', 'utc') AS double)"); break; |
︙ | ︙ | |||
2767 2768 2769 2770 2771 2772 2773 | { result.Append("CAST(STRFTIME('"); // expand the datepart literal as tsql kword result.Append(trans); result.Append("', "); | | | | 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 | { result.Append("CAST(STRFTIME('"); // expand the datepart literal as tsql kword result.Append(trans); result.Append("', "); switch (sqlgen._manifest._dateTimeFormat) { case SQLiteDateFormats.Ticks: result.Append(String.Format("(({0} - 621355968000000000) / 10000000.0)", e.Arguments[1].Accept(sqlgen))); break; default: result.Append(e.Arguments[1].Accept(sqlgen)); break; } result.Append(") AS integer)"); } else { result.Append("CAST(SUBSTR(STRFTIME('%f', "); switch (sqlgen._manifest._dateTimeFormat) { case SQLiteDateFormats.Ticks: result.Append(String.Format("(({0} - 621355968000000000) / 10000000.0)", e.Arguments[1].Accept(sqlgen))); break; default: result.Append(e.Arguments[1].Accept(sqlgen)); break; |
︙ | ︙ | |||
2810 2811 2812 2813 2814 2815 2816 | /// <param name="e"></param> /// <returns></returns> private static ISqlFragment HandleCanonicalFunctionDateAdd(SqlGenerator sqlgen, DbFunctionExpression e) { SqlBuilder result = new SqlBuilder(); Debug.Assert(e.Arguments.Count == 2, "Canonical datepart functions should have exactly two arguments"); | | | 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 | /// <param name="e"></param> /// <returns></returns> private static ISqlFragment HandleCanonicalFunctionDateAdd(SqlGenerator sqlgen, DbFunctionExpression e) { SqlBuilder result = new SqlBuilder(); Debug.Assert(e.Arguments.Count == 2, "Canonical datepart functions should have exactly two arguments"); switch (sqlgen._manifest._dateTimeFormat) { case SQLiteDateFormats.Ticks: result.Append(String.Format("(STRFTIME('%s', JULIANDAY({1}) + ({0} / 86400.0)) * 10000000 + 621355968000000000)", e.Arguments[0].Accept(sqlgen), e.Arguments[1].Accept(sqlgen))); break; case SQLiteDateFormats.JulianDay: result.Append(String.Format("CAST(STRFTIME('%J', JULIANDAY({1}) + ({0} / 86400.0)) AS double)", e.Arguments[0].Accept(sqlgen), e.Arguments[1].Accept(sqlgen))); break; |
︙ | ︙ | |||
2837 2838 2839 2840 2841 2842 2843 | /// <param name="e"></param> /// <returns></returns> private static ISqlFragment HandleCanonicalFunctionDateSubtract(SqlGenerator sqlgen, DbFunctionExpression e) { SqlBuilder result = new SqlBuilder(); Debug.Assert(e.Arguments.Count == 2, "Canonical datepart functions should have exactly two arguments"); | | | 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 | /// <param name="e"></param> /// <returns></returns> private static ISqlFragment HandleCanonicalFunctionDateSubtract(SqlGenerator sqlgen, DbFunctionExpression e) { SqlBuilder result = new SqlBuilder(); Debug.Assert(e.Arguments.Count == 2, "Canonical datepart functions should have exactly two arguments"); switch (sqlgen._manifest._dateTimeFormat) { case SQLiteDateFormats.Ticks: result.Append(String.Format("CAST((({0} - 621355968000000000) / 10000000.0) - (({1} - 621355968000000000) / 10000000.0) * 86400.0 AS integer)", e.Arguments[0].Accept(sqlgen), e.Arguments[1].Accept(sqlgen))); break; default: result.Append(String.Format("CAST((JULIANDAY({1}) - JULIANDAY({0})) * 86400.0 AS integer)", e.Arguments[0].Accept(sqlgen), e.Arguments[1].Accept(sqlgen))); break; |
︙ | ︙ | |||
2873 2874 2875 2876 2877 2878 2879 | SqlBuilder result = new SqlBuilder(); result.Append("CAST(STRFTIME('"); result.Append(trans); result.Append("', "); Debug.Assert(e.Arguments.Count == 1, "Canonical datepart functions should have exactly one argument"); | | | 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 | SqlBuilder result = new SqlBuilder(); result.Append("CAST(STRFTIME('"); result.Append(trans); result.Append("', "); Debug.Assert(e.Arguments.Count == 1, "Canonical datepart functions should have exactly one argument"); switch (sqlgen._manifest._dateTimeFormat) { case SQLiteDateFormats.Ticks: result.Append(String.Format("(({0} - 621355968000000000) / 10000000.0)", e.Arguments[0].Accept(sqlgen))); break; default: result.Append(e.Arguments[0].Accept(sqlgen)); break; |
︙ | ︙ | |||
3421 3422 3423 3424 3425 3426 3427 | selectStatement.From.AppendLine(); selectStatement.From.Append(") "); return selectStatement; } | < | 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 | selectStatement.From.AppendLine(); selectStatement.From.Append(") "); return selectStatement; } /// <summary> /// Before we embed a string literal in a SQL string, we should /// convert all ' to '', and enclose the whole string in single quotes. /// </summary> /// <param name="s"></param> /// <param name="isUnicode"></param> /// <returns>The escaped sql string.</returns> |
︙ | ︙ | |||
3957 3958 3959 3960 3961 3962 3963 | // Should we actually support this? //result.Append(QuoteIdentifier((string)function.MetadataProperties["Schema"].Value ?? "dbo")); //result.Append("."); result.Append(QuoteIdentifier(storeFunctionName)); } } | > > > > > > > > > > > > > > > > > > | > | > > > | > | > | | > | | > | 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 | // Should we actually support this? //result.Append(QuoteIdentifier((string)function.MetadataProperties["Schema"].Value ?? "dbo")); //result.Append("."); result.Append(QuoteIdentifier(storeFunctionName)); } } /// <summary> /// Appends the literal BLOB string representation of the specified /// byte array to the <see cref="StringBuilder" />, creating it if /// necessary. /// </summary> /// <param name="bytes"> /// The byte array to be formatted as a literal BLOB string. /// </param> /// <param name="builder"> /// The <see cref="StringBuilder" /> object to use. If null, a new /// instance will be created. /// </param> private static void ToBlobLiteral( byte[] bytes, SqlBuilder builder ) { int capacity = (bytes != null) ? (bytes.Length * 2) + 3 : 4; if (bytes == null) { builder.Append("NULL"); /* TODO: Reasonable? */ return; } builder.Append(" X'"); for (int index = 0; index < bytes.Length; index++) { builder.Append(hexDigits[(bytes[index] & 0xF0) >> 4]); builder.Append(hexDigits[bytes[index] & 0x0F]); } builder.Append("' "); } /// <summary> /// Helper method for the Group By visitor /// Returns true if at least one of the aggregates in the given list /// has an argument that is not a <see cref="DbPropertyExpression"/> /// over <see cref="DbVariableReferenceExpression"/> |
︙ | ︙ |
Changes to System.Data.SQLite.Linq/SQLiteProviderManifest.cs.
︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #if USE_ENTITY_FRAMEWORK_6 namespace System.Data.SQLite.EF6 #else namespace System.Data.SQLite.Linq #endif { using System; using System.Data; using System.Reflection; using System.IO; using System.Xml; using System.Data.Common; #if USE_ENTITY_FRAMEWORK_6 using System.Data.Entity.Core; using System.Data.Entity.Core.Common; using System.Data.Entity.Core.Metadata.Edm; #else using System.Data.Metadata.Edm; #endif /// <summary> /// The Provider Manifest for SQL Server /// </summary> internal sealed class SQLiteProviderManifest : DbXmlEnabledProviderManifest { | > | > > > | | > > > > | > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | #if USE_ENTITY_FRAMEWORK_6 namespace System.Data.SQLite.EF6 #else namespace System.Data.SQLite.Linq #endif { using System; using System.Collections.Generic; using System.Data; using System.Reflection; using System.IO; using System.Xml; using System.Data.Common; #if USE_ENTITY_FRAMEWORK_6 using System.Data.Entity.Core; using System.Data.Entity.Core.Common; using System.Data.Entity.Core.Metadata.Edm; #else using System.Data.Metadata.Edm; #endif /// <summary> /// The Provider Manifest for SQL Server /// </summary> internal sealed class SQLiteProviderManifest : DbXmlEnabledProviderManifest { internal SQLiteDateFormats _dateTimeFormat; internal DateTimeKind _dateTimeKind; internal string _dateTimeFormatString; internal bool _binaryGuid; /// <summary> /// Constructs the provider manifest. /// </summary> /// <remarks> /// Previously, the manifest token was interpreted as a <see cref="SQLiteDateFormats" />, /// because the <see cref="DateTime" /> functions are vastly different depending on the /// connection was opened. However, the manifest token may specify a connection string /// instead. WARNING: Only the "DateTimeFormat", "DateTimeKind", "DateTimeFormatString", /// and "BinaryGUID" connection parameters are extracted from it. All other connection /// parameters, if any are present, are silently ignored. /// </remarks> /// <param name="manifestToken"> /// A token used to infer the capabilities of the store. /// </param> public SQLiteProviderManifest(string manifestToken) : base(GetProviderManifest()) { SetFromOptions(ParseProviderManifestToken(manifestToken)); } private static XmlReader GetProviderManifest() { return GetXmlResource("System.Data.SQLite.SQLiteProviderServices.ProviderManifest.xml"); } /// <summary> /// Attempts to parse a provider manifest token. It must contain either a /// legacy string that specifies the <see cref="SQLiteDateFormats" /> value /// -OR- string that uses the standard connection string syntax; otherwise, /// the results are undefined. /// </summary> /// <param name="manifestToken"> /// The manifest token to parse. /// </param> /// <returns> /// The dictionary containing the connection string parameters. /// </returns> internal static SortedList<string, string> ParseProviderManifestToken( string manifestToken ) { return SQLiteConnection.ParseConnectionString(manifestToken, false, true); } /// <summary> /// Attempts to set the provider manifest options from the specified /// connection string parameters. An exception may be thrown if one /// or more of the connection string parameter values do not conform /// to the expected type. /// </summary> /// <param name="opts"> /// The dictionary containing the connection string parameters. /// </param> internal void SetFromOptions( SortedList<string, string> opts ) { _dateTimeFormat = SQLiteConnection.DefaultDateTimeFormat; _dateTimeKind = SQLiteConnection.DefaultDateTimeKind; _dateTimeFormatString = SQLiteConnection.DefaultDateTimeFormatString; _binaryGuid = /* SQLiteConnection.DefaultBinaryGUID; */ false; /* COMPAT: Legacy. */ if (opts == null) return; #if !PLATFORM_COMPACTFRAMEWORK string[] names = Enum.GetNames(typeof(SQLiteDateFormats)); #else string[] names = { SQLiteDateFormats.Ticks.ToString(), SQLiteDateFormats.ISO8601.ToString(), SQLiteDateFormats.JulianDay.ToString(), SQLiteDateFormats.UnixEpoch.ToString(), SQLiteDateFormats.InvariantCulture.ToString(), SQLiteDateFormats.CurrentCulture.ToString(), "Default" }; #endif foreach (string name in names) { if (String.IsNullOrEmpty(name)) continue; object value = SQLiteConnection.FindKey(opts, name, null); if (value == null) continue; _dateTimeFormat = (SQLiteDateFormats)Enum.Parse( typeof(SQLiteDateFormats), name, true); } object enumValue; enumValue = SQLiteConnection.TryParseEnum( typeof(SQLiteDateFormats), SQLiteConnection.FindKey( opts, "DateTimeFormat", null), true); if (enumValue is SQLiteDateFormats) _dateTimeFormat = (SQLiteDateFormats)enumValue; enumValue = SQLiteConnection.TryParseEnum( typeof(DateTimeKind), SQLiteConnection.FindKey( opts, "DateTimeKind", null), true); if (enumValue is DateTimeKind) _dateTimeKind = (DateTimeKind)enumValue; string stringValue = SQLiteConnection.FindKey( opts, "DateTimeFormatString", null); if (stringValue != null) _dateTimeFormatString = stringValue; stringValue = SQLiteConnection.FindKey( opts, "BinaryGUID", null); if (stringValue != null) _binaryGuid = SQLiteConvert.ToBoolean(stringValue); } /// <summary> /// Returns manifest information for the provider /// </summary> /// <param name="informationType">The name of the information to be retrieved.</param> /// <returns>An XmlReader at the begining of the information requested.</returns> protected override XmlReader GetDbInformation(string informationType) |
︙ | ︙ |
Changes to System.Data.SQLite.Linq/SQLiteProviderServices.cs.
︙ | ︙ | |||
106 107 108 109 110 111 112 | command.Dispose(); throw; } } protected override string GetDbProviderManifestToken(DbConnection connection) { | | | < | | < < < | < < | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | command.Dispose(); throw; } } protected override string GetDbProviderManifestToken(DbConnection connection) { if (connection == null) throw new ArgumentNullException("connection"); if (String.IsNullOrEmpty(connection.ConnectionString)) throw new ArgumentNullException("ConnectionString"); return connection.ConnectionString; } protected override DbProviderManifest GetDbProviderManifest(string versionHint) { return new SQLiteProviderManifest(versionHint); } |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteConnection.cs.
︙ | ︙ | |||
348 349 350 351 352 353 354 | internal const IsolationLevel DeferredIsolationLevel = IsolationLevel.ReadCommitted; internal const IsolationLevel ImmediateIsolationLevel = IsolationLevel.Serializable; private const SQLiteConnectionFlags DefaultFlags = SQLiteConnectionFlags.Default; private const SQLiteSynchronousEnum DefaultSynchronous = SQLiteSynchronousEnum.Default; private const SQLiteJournalModeEnum DefaultJournalMode = SQLiteJournalModeEnum.Default; private const IsolationLevel DefaultIsolationLevel = IsolationLevel.Serializable; | | | | | | 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 | internal const IsolationLevel DeferredIsolationLevel = IsolationLevel.ReadCommitted; internal const IsolationLevel ImmediateIsolationLevel = IsolationLevel.Serializable; private const SQLiteConnectionFlags DefaultFlags = SQLiteConnectionFlags.Default; private const SQLiteSynchronousEnum DefaultSynchronous = SQLiteSynchronousEnum.Default; private const SQLiteJournalModeEnum DefaultJournalMode = SQLiteJournalModeEnum.Default; private const IsolationLevel DefaultIsolationLevel = IsolationLevel.Serializable; internal const SQLiteDateFormats DefaultDateTimeFormat = SQLiteDateFormats.Default; internal const DateTimeKind DefaultDateTimeKind = DateTimeKind.Unspecified; internal const string DefaultDateTimeFormatString = null; private const string DefaultDataSource = null; private const string DefaultUri = null; private const string DefaultFullUri = null; private const string DefaultHexPassword = null; private const string DefaultPassword = null; private const int DefaultVersion = 3; private const int DefaultPageSize = 1024; private const int DefaultMaxPageCount = 0; private const int DefaultCacheSize = 2000; private const int DefaultMaxPoolSize = 100; private const int DefaultConnectionTimeout = 30; private const bool DefaultNoSharedFlags = false; private const bool DefaultFailIfMissing = false; private const bool DefaultReadOnly = false; internal const bool DefaultBinaryGUID = true; private const bool DefaultUseUTF16Encoding = false; private const bool DefaultToFullPath = true; private const bool DefaultPooling = false; // TODO: Maybe promote this to static property? private const bool DefaultLegacyFormat = false; private const bool DefaultForeignKeys = false; private const bool DefaultEnlist = true; private const bool DefaultSetDefaults = true; |
︙ | ︙ | |||
1195 1196 1197 1198 1199 1200 1201 | if (handle.IsClosed) throw new InvalidOperationException("The connection handle is closed."); } /////////////////////////////////////////////////////////////////////////////////////////////// | > > > > > > > > > > > > > > > > > > > > | | > | | 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 | if (handle.IsClosed) throw new InvalidOperationException("The connection handle is closed."); } /////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Parses a connection string into component parts using the custom /// connection string parser. An exception may be thrown if the syntax /// of the connection string is incorrect. /// </summary> /// <param name="connectionString"> /// The connection string to parse. /// </param> /// <param name="parseViaFramework"> /// Non-zero to parse the connection string using the algorithm provided /// by the framework itself. This is not applicable when running on the /// .NET Compact Framework. /// </param> /// <param name="allowNameOnly"> /// Non-zero if names are allowed without values. /// </param> /// <returns> /// The list of key/value pairs corresponding to the parameters specified /// within the connection string. /// </returns> internal static SortedList<string, string> ParseConnectionString( string connectionString, bool parseViaFramework, bool allowNameOnly ) { return parseViaFramework ? ParseConnectionStringViaFramework(connectionString, false) : ParseConnectionString(connectionString, allowNameOnly); } /////////////////////////////////////////////////////////////////////////////////////////////// private void SetupSQLiteBase(SortedList<string, string> opts) { object enumValue; |
︙ | ︙ | |||
1886 1887 1888 1889 1890 1891 1892 | else if (path.StartsWith ("/", StringComparison.OrdinalIgnoreCase)) return path; else throw new InvalidOperationException ("Invalid connection string: invalid URI"); } /// <summary> | | | > | > > > > > | > > > | > > > | 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 | else if (path.StartsWith ("/", StringComparison.OrdinalIgnoreCase)) return path; else throw new InvalidOperationException ("Invalid connection string: invalid URI"); } /// <summary> /// Parses a connection string into component parts using the custom /// connection string parser. An exception may be thrown if the syntax /// of the connection string is incorrect. /// </summary> /// <param name="connectionString"> /// The connection string to parse. /// </param> /// <param name="allowNameOnly"> /// Non-zero if names are allowed without values. /// </param> /// <returns> /// The list of key/value pairs corresponding to the parameters specified /// within the connection string. /// </returns> private static SortedList<string, string> ParseConnectionString( string connectionString, bool allowNameOnly ) { string s = connectionString; int n; SortedList<string, string> ls = new SortedList<string, string>(StringComparer.OrdinalIgnoreCase); // First split into semi-colon delimited values. string error = null; |
︙ | ︙ | |||
1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 | if (arParts[n].Length == 0) continue; int indexOf = arParts[n].IndexOf('='); if (indexOf != -1) ls.Add(UnwrapString(arParts[n].Substring(0, indexOf).Trim()), UnwrapString(arParts[n].Substring(indexOf + 1).Trim())); else throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Invalid ConnectionString format for part \"{0}\", no equal sign found", arParts[n])); } return ls; } /// <summary> /// Parses a connection string using the built-in (i.e. framework provided) /// connection string parser class and returns the key/value pairs. An /// exception may be thrown if the connection string is invalid or cannot be /// parsed. When compiled for the .NET Compact Framework, the custom /// connection string parser is always used instead because the framework /// provided one is unavailable there. /// </summary> /// <param name="connectionString"> /// The connection string to parse. /// </param> /// <param name="strict"> /// Non-zero to throw an exception if any connection string values are not of | > > | > | | 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 | if (arParts[n].Length == 0) continue; int indexOf = arParts[n].IndexOf('='); if (indexOf != -1) ls.Add(UnwrapString(arParts[n].Substring(0, indexOf).Trim()), UnwrapString(arParts[n].Substring(indexOf + 1).Trim())); else if (allowNameOnly) ls.Add(UnwrapString(arParts[n].Trim()), String.Empty); else throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Invalid ConnectionString format for part \"{0}\", no equal sign found", arParts[n])); } return ls; } /// <summary> /// Parses a connection string using the built-in (i.e. framework provided) /// connection string parser class and returns the key/value pairs. An /// exception may be thrown if the connection string is invalid or cannot be /// parsed. When compiled for the .NET Compact Framework, the custom /// connection string parser is always used instead because the framework /// provided one is unavailable there. /// </summary> /// <param name="connectionString"> /// The connection string to parse. /// </param> /// <param name="strict"> /// Non-zero to throw an exception if any connection string values are not of /// the <see cref="String" /> type. This is not applicable when running on /// the .NET Compact Framework. /// </param> /// <returns>The list of key/value pairs.</returns> private static SortedList<string, string> ParseConnectionStringViaFramework( string connectionString, bool strict ) { #if !PLATFORM_COMPACTFRAMEWORK DbConnectionStringBuilder connectionStringBuilder = new DbConnectionStringBuilder(); |
︙ | ︙ | |||
1995 1996 1997 1998 1999 2000 2001 | return result; #else // // NOTE: On the .NET Compact Framework, always use our custom connection // string parser as the built-in (i.e. framework provided) one is // unavailable. // | | | 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 | return result; #else // // NOTE: On the .NET Compact Framework, always use our custom connection // string parser as the built-in (i.e. framework provided) one is // unavailable. // return ParseConnectionString(connectionString, false); #endif } #if !PLATFORM_COMPACTFRAMEWORK /// <summary> /// Manual distributed transaction enlistment support /// </summary> |
︙ | ︙ | |||
2402 2403 2404 2405 2406 2407 2408 | if (_connectionState != ConnectionState.Closed) throw new InvalidOperationException(); Close(); SortedList<string, string> opts = ParseConnectionString( | | | 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 | if (_connectionState != ConnectionState.Closed) throw new InvalidOperationException(); Close(); SortedList<string, string> opts = ParseConnectionString( _connectionString, _parseViaFramework, false); OnChanged(this, new ConnectionEventArgs( SQLiteConnectionEventType.ConnectionString, null, null, null, null, null, _connectionString, new object[] { opts })); object enumValue; |
︙ | ︙ |
Changes to Tests/basic.eagle.
︙ | ︙ | |||
2257 2258 2259 2260 2261 2262 2263 | "OneTwo=ThreeFour" "\"OneTwo\"=\"ThreeFour\"" \ "One Two=Three Four" "\"One Two\"=\"Three Four\"" \ "OneTwo=ThreeFour;" "\"OneTwo\"=\"ThreeFour\";" \ "One Two=Three Four;" "\"One Two\"=\"Three Four\";"] foreach string $strings { set list [object invoke -flags +NonPublic \ | | > | 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 | "OneTwo=ThreeFour" "\"OneTwo\"=\"ThreeFour\"" \ "One Two=Three Four" "\"One Two\"=\"Three Four\"" \ "OneTwo=ThreeFour;" "\"OneTwo\"=\"ThreeFour\";" \ "One Two=Three Four;" "\"One Two\"=\"Three Four\";"] foreach string $strings { set list [object invoke -flags +NonPublic \ System.Data.SQLite.SQLiteConnection ParseConnectionString \ $string false] object foreach -alias pair $list { lappend result [list [$pair Key] [$pair Value]] } } set result |
︙ | ︙ |
Added Tests/tkt-8d928c3e88.eagle.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | ############################################################################### # # tkt-8d928c3e88.eagle -- # # Written by Joe Mistachkin. # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle package require Eagle.Library package require Eagle.Test runTestPrologue ############################################################################### package require System.Data.SQLite.Test runSQLiteTestPrologue runSQLiteTestFilesPrologue ############################################################################### runTest {test tkt-8d928c3e88-1.1 {LINQ with BinaryGUID} -body { # # NOTE: Re-copy the reference database file used for this unit test to the # build directory in case it has been changed by a previous test run. # file copy -force $northwindEfDbFile \ [file join [getBuildDirectory] [file tail $northwindEfDbFile]] set result [list] set output "" set code [catch { testClrExec $testLinqExeFile [list -eventflags Wait -directory \ [file dirname $testLinqExeFile] -nocarriagereturns -stdout output \ -success 0] -binaryguid } error] tlog "---- BEGIN STDOUT OUTPUT\n" tlog $output tlog "\n---- END STDOUT OUTPUT\n" lappend result $code if {$code == 0} then { lappend result [string trim $output] } else { lappend result [string trim $error] } set result } -cleanup { unset -nocomplain code output error result } -constraints {eagle monoToDo SQLite file_System.Data.SQLite.dll testExec\ file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db} \ -result {}} ############################################################################### runSQLiteTestFilesEpilogue runSQLiteTestEpilogue runTestEpilogue |
Changes to Tests/tkt-e47b3d8346.eagle.
︙ | ︙ | |||
23 24 25 26 27 28 29 | runTest {test tkt-e47b3d8346-1.1 {parse semi-colon in data source} -setup { unset -nocomplain result list pair } -body { set result [list] set list [object invoke -flags +NonPublic \ System.Data.SQLite.SQLiteConnection ParseConnectionString \ | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | runTest {test tkt-e47b3d8346-1.1 {parse semi-colon in data source} -setup { unset -nocomplain result list pair } -body { set result [list] set list [object invoke -flags +NonPublic \ System.Data.SQLite.SQLiteConnection ParseConnectionString \ {Data Source="C:\full\path\to\file.db;more.data.here";} false] object foreach -alias pair $list { lappend result [list [$pair Key] [$pair Value]] } set result } -cleanup { |
︙ | ︙ |
Changes to testlinq/Program.cs.
︙ | ︙ | |||
126 127 128 129 130 131 132 133 134 135 136 137 138 139 | return EFTransactionTest(value); } case "update": { return UpdateTest(); } default: { Console.WriteLine("unknown test \"{0}\"", arg); return 1; } } } | > > > > | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | return EFTransactionTest(value); } case "update": { return UpdateTest(); } case "binaryguid": { return BinaryGuidTest(); } default: { Console.WriteLine("unknown test \"{0}\"", arg); return 1; } } } |
︙ | ︙ | |||
472 473 474 475 476 477 478 479 480 481 482 483 484 485 | db.AcceptAllChanges(); } } Console.WriteLine( "inserted {0} updated {1}", counts[0], counts[1]); } return 0; } private static int DateTimeTest() { using (northwindEFEntities db = new northwindEFEntities()) | > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | db.AcceptAllChanges(); } } Console.WriteLine( "inserted {0} updated {1}", counts[0], counts[1]); } return 0; } // // NOTE: Used to test the BinaryGUID fix (i.e. BLOB literal formatting // of GUID values when the BinaryGUID connection property has been // enabled). // private static int BinaryGuidTest() { using (northwindEFEntities db = new northwindEFEntities()) { string sql = "SELECT VALUE GUID '25334ef0-bd18-43e6-863f-ae5d376ac75e' FROM Orders AS o WHERE o.OrderID = 10248;"; ObjectQuery<string> query = db.CreateQuery<string>(sql); foreach (string s in query) Console.WriteLine(s); sql = "SELECT VALUE GUID '25334ef0-bd18-43e6-863f-ae5d376ac75e' FROM Orders AS o WHERE o.OrderID = 10248;"; query = db.CreateQuery<string>(sql); foreach (string s in query) Console.WriteLine(s); } return 0; } private static int DateTimeTest() { using (northwindEFEntities db = new northwindEFEntities()) |
︙ | ︙ |