System.Data.SQLite
Check-in [8e0bb4c6cd]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Allow semi-colons in the data source file name. Fix for ticket [e47b3d8346].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8e0bb4c6cde559d6a5277cb00fb4785396a1988e
User & Date: mistachkin 2013-05-01 00:06:00
References
2013-05-01
00:29 Ticket [e47b3d8346] Opening connection fails when data source path contains semi-colon character. status still Pending with 4 other changes artifact: bdf31e7154 user: mistachkin
Context
2013-05-01
00:28
Update to comments and version history docs. check-in: 37f936471c user: mistachkin tags: trunk
00:06
Allow semi-colons in the data source file name. Fix for ticket [e47b3d8346]. check-in: 8e0bb4c6cd user: mistachkin tags: trunk
2013-04-30
00:29
Update release version to 1.0.86.0. check-in: 545d22c1ff user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to System.Data.SQLite/SQLiteConnection.cs.

  1398   1398       internal static SortedList<string, string> ParseConnectionString(string connectionString)
  1399   1399       {
  1400   1400         string s = connectionString;
  1401   1401         int n;
  1402   1402         SortedList<string, string> ls = new SortedList<string, string>(StringComparer.OrdinalIgnoreCase);
  1403   1403   
  1404   1404         // First split into semi-colon delimited values.
  1405         -      string[] arParts = s.Split(';');
         1405  +      string[] arParts = SQLiteConvert.NewSplit(s, ';', true);
  1406   1406   
  1407   1407         int x = arParts.Length;
  1408   1408         // For each semi-colon piece, split into key and value pairs by the presence of the = sign
  1409   1409         for (n = 0; n < x; n++)
  1410   1410         {
  1411   1411           if (arParts[n] == null)
  1412   1412             continue;

Changes to System.Data.SQLite/SQLiteConvert.cs.

   502    502         }
   503    503   
   504    504         string[] ar = new string[ls.Count];
   505    505         ls.CopyTo(ar, 0);
   506    506   
   507    507         return ar;
   508    508       }
          509  +
          510  +    /// <summary>
          511  +    /// Splits the specified string into multiple strings based on a separator
          512  +    /// and returns the result as an array of strings.
          513  +    /// </summary>
          514  +    /// <param name="value">
          515  +    /// The string to split into pieces based on the separator character.  If
          516  +    /// this string is null, null will always be returned.  If this string is
          517  +    /// empty, an array of zero strings will always be returned.
          518  +    /// </param>
          519  +    /// <param name="separator">
          520  +    /// The character used to divide the original string into sub-strings.
          521  +    /// This character cannot be a backslash or a double-quote; otherwise, no
          522  +    /// work will be performed and null will be returned.
          523  +    /// </param>
          524  +    /// <param name="keepQuote">
          525  +    /// If this parameter is non-zero, all double-quote characters will be
          526  +    /// retained in the returned list of strings; otherwise, they will be
          527  +    /// dropped.
          528  +    /// </param>
          529  +    /// <returns>
          530  +    /// The new array of strings or null if the input string is null -OR- the
          531  +    /// separator character is a double-quote (i.e. the character that is
          532  +    /// normally used to escape separator characters).
          533  +    /// </returns>
          534  +    internal static string[] NewSplit(
          535  +        string value,
          536  +        char separator,
          537  +        bool keepQuote
          538  +        )
          539  +    {
          540  +        const char EscapeChar = '\\';
          541  +        const char QuoteChar = '\"';
          542  +
          543  +        //
          544  +        // NOTE: It is illegal for the separator character to be either a
          545  +        //       backslash or a double-quote because both of those characters
          546  +        //       are used for escaping other characters (e.g. the separator
          547  +        //       character).
          548  +        //
          549  +        if ((separator == EscapeChar) || (separator == QuoteChar))
          550  +            return null;
          551  +
          552  +        if (value == null)
          553  +            return null;
          554  +
          555  +        int length = value.Length;
          556  +
          557  +        if (length == 0)
          558  +            return new string[0];
          559  +
          560  +        List<string> list = new List<string>();
          561  +        StringBuilder element = new StringBuilder();
          562  +        int index = 0;
          563  +        bool escape = false;
          564  +        bool quote = false;
          565  +
          566  +        while (index < length)
          567  +        {
          568  +            char character = value[index++];
          569  +
          570  +            if (escape)
          571  +            {
          572  +                //
          573  +                // HACK: Only consider the escape character to be an actual
          574  +                //       "escape" if it is followed by a reserved character;
          575  +                //       otherwise, emit the original escape character and
          576  +                //       the current character in an effort to help preserve
          577  +                //       the original string content.
          578  +                //
          579  +                if ((character != EscapeChar) &&
          580  +                    (character != QuoteChar) &&
          581  +                    (character != separator))
          582  +                {
          583  +                    element.Append(EscapeChar);
          584  +                }
          585  +
          586  +                element.Append(character);
          587  +                escape = false;
          588  +            }
          589  +            else if (character == EscapeChar)
          590  +            {
          591  +                escape = true;
          592  +            }
          593  +            else if (character == QuoteChar)
          594  +            {
          595  +                if (keepQuote)
          596  +                    element.Append(character);
          597  +
          598  +                quote = !quote;
          599  +            }
          600  +            else if (character == separator)
          601  +            {
          602  +                if (quote)
          603  +                {
          604  +                    element.Append(character);
          605  +                }
          606  +                else
          607  +                {
          608  +                    list.Add(element.ToString());
          609  +                    element.Length = 0;
          610  +                }
          611  +            }
          612  +            else
          613  +            {
          614  +                element.Append(character);
          615  +            }
          616  +        }
          617  +
          618  +        //
          619  +        // NOTE: An unbalanced escape or quote character in the string is
          620  +        //       considered to be a fatal error; therefore, return null.
          621  +        //
          622  +        if (escape || quote)
          623  +            return null;
          624  +
          625  +        if (element.Length > 0)
          626  +            list.Add(element.ToString());
          627  +
          628  +        return list.ToArray();
          629  +    }
   509    630   
   510    631       /// <summary>
   511    632       /// Convert a value to true or false.
   512    633       /// </summary>
   513    634       /// <param name="source">A string or number representing true or false</param>
   514    635       /// <returns></returns>
   515    636       public static bool ToBoolean(object source)

Added Tests/tkt-e47b3d8346.eagle.

            1  +###############################################################################
            2  +#
            3  +# tkt-e47b3d8346.eagle --
            4  +#
            5  +# Written by Joe Mistachkin.
            6  +# Released to the public domain, use at your own risk!
            7  +#
            8  +###############################################################################
            9  +
           10  +package require Eagle
           11  +package require Eagle.Library
           12  +package require Eagle.Test
           13  +
           14  +runTestPrologue
           15  +
           16  +###############################################################################
           17  +
           18  +package require System.Data.SQLite.Test
           19  +runSQLiteTestPrologue
           20  +
           21  +###############################################################################
           22  +
           23  +runTest {test tkt-e47b3d8346-1.1 {parse semi-colon in data source} -setup {
           24  +  unset -nocomplain result list pair
           25  +} -body {
           26  +  set result [list]
           27  +
           28  +  set list [object invoke -flags +NonPublic \
           29  +      System.Data.SQLite.SQLiteConnection ParseConnectionString \
           30  +      {Data Source="C:\full\path\to\file.db;more.data.here";}]
           31  +
           32  +  object foreach -alias pair $list {
           33  +    lappend result [list [$pair Key] [$pair Value]]
           34  +  }
           35  +
           36  +  set result
           37  +} -cleanup {
           38  +  unset -nocomplain result list pair
           39  +} -constraints {eagle System.Data.SQLite} -result \
           40  +{{{Data Source} {C:\full\path\to\file.db;more.data.here}}}}
           41  +
           42  +###############################################################################
           43  +
           44  +runSQLiteTestEpilogue
           45  +runTestEpilogue