-------- Mensaje original --------
Asunto:         problem in .NET provider
Fecha:  Sat, 20 Oct 2007 15:34:00 +0200
De:     Peter Turcan <[EMAIL PROTECTED]>
Para:   [EMAIL PROTECTED]



Hello Carlos!

For first, thank you for your great work on .NET Firebird provider!
I have found problem in it, when there is Turkish regional settings.
Problem is in program FbConnectionString.cs, where you are initializing HashTable this way:
Hashtable synonyms = new
Hashtable(StringComparer.CurrentCultureIgnoreCase);

but I don't know why, this hash table, especially
GetKey procedure in FbConnectionStringBuilder.cs
doesn't work.

So in FbConnectionString.cs I have changed StringComparer property to:
Hashtable synonyms = new Hashtable(StringComparer.OrdinalIgnoreCase);

and everything works ok.
(see source from version 2.0.1, but in the latest 2.1.0RC2 it is still the same code)

I think, it will be fine to incude this patch into full version
all the best,
Peter



--
Carlos Guzmán Álvarez
Vigo-Spain

Blog            : http://carlosga.wordpress.com/
FirebirdClient  : http://www.firebirdsql.org/
XMPP Client     : http://code.google.com/p/xmppclient/
ohloh           : http://www.ohloh.net/accounts/4138

/*
 *      Firebird ADO.NET Data provider for .NET and Mono 
 * 
 *         The contents of this file are subject to the Initial 
 *         Developer's Public License Version 1.0 (the "License"); 
 *         you may not use this file except in compliance with the 
 *         License. You may obtain a copy of the License at 
 *         http://www.firebirdsql.org/index.php?op=doc&id=idpl
 *
 *         Software distributed under the License is distributed on 
 *         an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either 
 *         express or implied. See the License for the specific 
 *         language governing rights and limitations under the License.
 * 
 *      Copyright (c) 2004-2005 Carlos Guzman Alvarez
 *      All Rights Reserved.
 */

using System;
using System.Collections;
using System.Data;
using System.Globalization;
using System.Text.RegularExpressions;

using FirebirdSql.Data.Common;

namespace FirebirdSql.Data.FirebirdClient
{
        internal sealed class FbConnectionString
        {
                #region · Static Fields ·

                public static readonly Hashtable Synonyms = GetSynonyms();

                #endregion

                #region · Static Methods ·

                // This is somethig     that should     be needed in .NET 2.0
                // for use with the     DbConnectionOptions     or 
DbConnectionString classes.
                private static Hashtable GetSynonyms()
                {
//                      Hashtable synonyms = new 
Hashtable(StringComparer.CurrentCultureIgnoreCase);
            Hashtable synonyms = new 
Hashtable(StringComparer.OrdinalIgnoreCase);

                        synonyms.Add("data source", "data source");
                        synonyms.Add("datasource", "data source");
                        synonyms.Add("server", "data source");
                        synonyms.Add("host", "data source");
                        synonyms.Add("port", "port number");
                        synonyms.Add("port number", "port number");
            synonyms.Add("database", "initial catalog");
            synonyms.Add("initial catalog", "initial catalog");
                        synonyms.Add("user id", "user id");
            synonyms.Add("userid", "user id");
                        synonyms.Add("uid", "user id");
                        synonyms.Add("user", "user id");
                        synonyms.Add("user name", "user id");
            synonyms.Add("username", "user id");
            synonyms.Add("password", "password");
                        synonyms.Add("user password", "password");
            synonyms.Add("userpassword", "password");
            synonyms.Add("dialect", "dialect");
                        synonyms.Add("pooling", "pooling");
                        synonyms.Add("max pool size", "max pool size");
            synonyms.Add("maxpoolsize", "max pool size");
                        synonyms.Add("min pool size", "min pool size");
            synonyms.Add("minpoolsize", "min pool size");
            synonyms.Add("character set", "character set");
            synonyms.Add("charset", "character set");
                        synonyms.Add("connection lifetime", "connection 
lifetime");
            synonyms.Add("connectionlifetime", "connection lifetime");
            synonyms.Add("timeout", "connection timeout");
                        synonyms.Add("connection timeout", "connection 
timeout");
            synonyms.Add("connectiontimeout", "connection timeout");
                        synonyms.Add("packet size", "packet size");
            synonyms.Add("packetsize", "packet size");
                        synonyms.Add("role", "role name");
                        synonyms.Add("role name", "role name");
                        synonyms.Add("fetch size", "fetch size");
                        synonyms.Add("fetchsize", "fetch size");
                        synonyms.Add("server type", "server type");
                        synonyms.Add("servertype", "server type");
                        synonyms.Add("isolation level", "isolation level");
            synonyms.Add("isolationlevel", "isolation level"); 
            synonyms.Add("records affected", "records affected");
            synonyms.Add("context connection", "context connection");
            synonyms.Add("enlist", "enlist");
                        return synonyms;
                }

                #endregion

                #region · Fields ·

                private Hashtable   options;
                private bool        isServiceConnectionString;

                #endregion

                #region · Properties ·

                public string UserID
                {
                        get { return this.GetString("user id"); }
                }

                public string Password
                {
                        get { return this.GetString("password"); }
                }

                public string DataSource
                {
                        get { return this.GetString("data source"); }
                }

                public int Port
                {
                        get { return this.GetInt32("port number"); }
                }

                public string Database
                {
            get { return this.GetString("initial catalog"); }
                }

                public short PacketSize
                {
                        get { return this.GetInt16("packet size"); }
                }

                public string Role
                {
                        get { return this.GetString("role name"); }
                }

                public byte Dialect
                {
                        get { return this.GetByte("dialect"); }
                }

                public string Charset
                {
                        get { return this.GetString("character set"); }
                }

                public int ConnectionTimeout
                {
                        get { return this.GetInt32("connection timeout"); }
                }

                public bool Pooling
                {
                        get { return this.GetBoolean("pooling"); }
                }

                public long ConnectionLifeTime
                {
                        get { return this.GetInt64("connection lifetime"); }
                }

                public int MinPoolSize
                {
                        get { return this.GetInt32("min pool size"); }
                }

                public int MaxPoolSize
                {
                        get { return this.GetInt32("max pool size"); }
                }

                public int FetchSize
                {
                        get { return this.GetInt32("fetch size"); }
                }

                public FbServerType ServerType
                {
                        get { return (FbServerType)this.GetInt32("server 
type"); }
                }

                public IsolationLevel IsolationLevel
                {
                        get { return this.GetIsolationLevel("isolation level"); 
}
                }

        public bool ReturnRecordsAffected
        {
            get { return this.GetBoolean("records affected"); }
        }

        public bool ContextConnection
        {
            get { return this.GetBoolean("context connection"); }
        }

        public bool Enlist
        {
            get { return this.GetBoolean("enlist"); }
        }

        #endregion

                #region · Constructors ·

                public FbConnectionString()
                {
                        this.SetDefaultOptions();
                }

                public FbConnectionString(string connectionString)
                {
                        this.Load(connectionString);
                }

                internal FbConnectionString(bool isServiceConnectionString)
                {
                        this.isServiceConnectionString = 
isServiceConnectionString;
                        this.SetDefaultOptions();
                }

                #endregion

                #region · Methods ·

                public void Load(string connectionString)
                {
                        this.SetDefaultOptions();

                        if (connectionString != null && connectionString.Length 
> 0)
                        {
                                Hashtable synonyms = GetSynonyms();
                                MatchCollection keyPairs = 
Regex.Matches(connectionString, @"([\w\s\d]*)\s*=\s*([^;]*)");

                                foreach (Match keyPair in keyPairs)
                                {
                                        if (keyPair.Groups.Count == 3)
                                        {
                                                string[] values = new string[] 
                                                {
                                                        
keyPair.Groups[1].Value.Trim(),
                                                        
keyPair.Groups[2].Value.Trim()
                                                };

                                                if (values.Length == 2 &&
                                                        values[0] != null && 
values[0].Length > 0 &&
                                                        values[1] != null && 
values[1].Length > 0)
                                                {
                                                        values[0] = 
values[0].ToLower(CultureInfo.CurrentCulture);

                                                        if 
(synonyms.Contains(values[0]))
                                                        {
                                                                string key = 
(string)synonyms[values[0]];
                                if (key == "server type")
                                {
                                    switch 
(this.UnquoteString(values[1].Trim()))
                                    {
                                        case "Default":
                                            this.options[key] = 
FbServerType.Default;
                                            break;

                                        case "Embedded":
                                            this.options[key] = 
FbServerType.Embedded;
                                            break;

                                        case "Context":
                                            this.options[key] = 
FbServerType.Context;
                                            break;

                                        default:
                                            this.options[key] = 
this.UnquoteString(values[1].Trim());
                                            break;
                                    }
                                }
                                else
                                {
                                                                    
this.options[key] = this.UnquoteString(values[1].Trim());
                                }
                                                        }
                                                }
                                        }
                                }

                                if (this.ContextConnection || this.ServerType 
== FbServerType.Context)
                                {
                    // When Context connection is true we should get the 
currently active connection
                    // on the Firebird Server
                    this.options["server type"]         = FbServerType.Context;
                                        this.options["pooling"]             = 
false;
                    this.options["context connection"]  = true;
                                }
                                else
                                {
                                        if (this.Database != null && 
this.Database.Length > 0)
                                        {
                                                
this.ParseConnectionInfo(this.Database);
                                        }
                                }
                        }
                }

                public void Validate()
                {
                        if (!this.ContextConnection)
                        {
                                if ((this.UserID == null || this.UserID.Length 
== 0) ||
                                        (this.Password == null || 
this.Password.Length == 0) ||
                                        ((this.Database == null || 
this.Database.Length == 0) && !this.isServiceConnectionString) ||
                                        ((this.DataSource == null || 
this.DataSource.Length == 0) && this.ServerType != FbServerType.Embedded) ||
                                        (this.Charset == null || 
this.Charset.Length == 0) ||
                                        this.Port == 0 ||
                                        (!Enum.IsDefined(typeof(FbServerType), 
this.ServerType)) ||
                                        (this.MinPoolSize > this.MaxPoolSize))
                                {
                                        throw new ArgumentException("An invalid 
connection string argument has been supplied or a required connection string 
argument has not been supplied.");
                                }
                                else
                                {
                                        if (this.Dialect < 1 || this.Dialect > 
3)
                                        {
                                                throw new 
ArgumentException("Incorrect database dialect it should be 1, 2, or 3.");
                                        }
                                        if (this.PacketSize < 512 || 
this.PacketSize > 32767)
                                        {
                                                throw new 
ArgumentException(String.Format(CultureInfo.CurrentCulture, "'Packet Size' 
value of {0} is not valid.\r\nThe value should be an integer >= 512 and <= 
32767.", this.PacketSize));
                                        }

                                        this.CheckIsolationLevel();
                                }
                        }
                }

                #endregion

                #region · Private Methods ·

                private void SetDefaultOptions()
                {
                        if (this.options == null)
                        {
                                this.options = new Hashtable();
                        }

                        this.options.Clear();

                        // Add default key pairs values
                        this.options.Add("data source", "");
                        this.options.Add("port number", 3050);
                        this.options.Add("user id", "SYSDBA");
                        this.options.Add("password", "masterkey");
                        this.options.Add("role name", String.Empty);
                        this.options.Add("catalog", String.Empty);
                        this.options.Add("character set", "None");
                        this.options.Add("dialect", 3);
                        this.options.Add("packet size", 8192);
                        this.options.Add("pooling", true);
                        this.options.Add("connection lifetime", 0);
                        this.options.Add("min pool size", 0);
                        this.options.Add("max pool size", 100);
                        this.options.Add("connection timeout", 15);
                        this.options.Add("fetch size", 200);
                        this.options.Add("server type", FbServerType.Default);
                        this.options.Add("isolation level", 
IsolationLevel.ReadCommitted.ToString());
            this.options.Add("records affected", true);
            this.options.Add("context connection", false);
            this.options.Add("enlist", false);
                }

        private void ParseConnectionInfo(string connectInfo)
        {
            string database = null;
            string dataSource = null;
            int portNumber = -1;

            // allows standard syntax //host:port/....
            // and old fb syntax host/port:....
            connectInfo = connectInfo.Trim();
            char hostSepChar;
            char portSepChar;

            if (connectInfo.StartsWith("//"))
            {
                connectInfo = connectInfo.Substring(2);
                hostSepChar = '/';
                portSepChar = ':';
            }
            else
            {
                hostSepChar = ':';
                portSepChar = '/';
            }

            int sep = connectInfo.IndexOf(hostSepChar);
            if (sep == 0 || sep == connectInfo.Length - 1)
            {
                throw new ArgumentException("An invalid connection string 
argument has been supplied or a required connection string argument has not 
been supplied.");
            }
            else if (sep > 0)
            {
                dataSource = connectInfo.Substring(0, sep);
                database = connectInfo.Substring(sep + 1);
                int portSep = dataSource.IndexOf(portSepChar);

                if (portSep == 0 || portSep == dataSource.Length - 1)
                {
                    throw new ArgumentException("An invalid connection string 
argument has been supplied or a required connection string argument has not 
been supplied.");
                }
                else if (portSep > 0)
                {
                    portNumber = Int32.Parse(dataSource.Substring(portSep + 1), 
CultureInfo.InvariantCulture);
                    dataSource = dataSource.Substring(0, portSep);
                }
                else if (portSep < 0 && dataSource.Length == 1)
                {
                    if (this.DataSource == null || this.DataSource.Length == 0)
                    {
                        dataSource = "localhost";
                    }
                    else
                    {
                        dataSource = null;
                    }

                    database = connectInfo;
                }
            }
            else if (sep == -1)
            {
                database = connectInfo;
            }

            this.options["initial catalog"] = database;
            if (dataSource != null)
            {
                this.options["data source"] = dataSource;
            }
            if (portNumber != -1)
            {
                this.options["port"] = portNumber;
            }
        }

                private string GetString(string key)
                {
                        if (this.options.Contains(key))
                        {
                                return (string)this.options[key];
                        }

                        return null;
                }

                private bool GetBoolean(string key)
                {
                        if (this.options.Contains(key))
                        {
                                return 
Boolean.Parse(this.options[key].ToString());
                        }

                        return false;
                }

                private byte GetByte(string key)
                {
                        if (this.options.Contains(key))
                        {
                                return Convert.ToByte(this.options[key], 
CultureInfo.CurrentCulture);
                        }

                        return 0;
                }

                private short GetInt16(string key)
                {
                        if (this.options.Contains(key))
                        {
                                return Convert.ToInt16(this.options[key], 
CultureInfo.InvariantCulture);
                        }

                        return 0;
                }

                private int GetInt32(string key)
                {
                        if (this.options.Contains(key))
                        {
                                return Convert.ToInt32(this.options[key], 
CultureInfo.InvariantCulture);
                        }

                        return 0;
                }

                private long GetInt64(string key)
                {
                        if (this.options.Contains(key))
                        {
                                return Convert.ToInt64(this.options[key], 
CultureInfo.InvariantCulture);
                        }

                        return 0;
                }

                private IsolationLevel GetIsolationLevel(string key)
                {
                        if (this.options.Contains(key))
                        {
                                string il = 
this.options[key].ToString().ToLower(CultureInfo.CurrentCulture);
                                switch (il)
                                {
                                        case "readcommitted":
                                                return 
IsolationLevel.ReadCommitted;

                                        case "readuncommitted":
                                                return 
IsolationLevel.ReadUncommitted;

                                        case "repeatableread":
                                                return 
IsolationLevel.RepeatableRead;

                                        case "serializable":
                                                return 
IsolationLevel.Serializable;

                                        case "chaos":
                                                return IsolationLevel.Chaos;

                                        case "unspecified":
                                                return 
IsolationLevel.Unspecified;
                                }
                        }

                        return IsolationLevel.ReadCommitted;
                }

                private void CheckIsolationLevel()
                {
                        string il = this.options["isolation 
level"].ToString().ToLower(CultureInfo.CurrentCulture);
                        switch (il)
                        {
                                case "readcommitted":
                                case "readuncommitted":
                                case "repeatableread":
                                case "serializable":
                                case "chaos":
                                case "unspecified":
                                        break;

                                default:
                                        throw new ArgumentException("Specified 
Isolation Level is not valid.");
                        }
                }

        private string UnquoteString(string value)
        {
            string unquoted = value;

            if (unquoted.StartsWith("\""))
            {
                unquoted = unquoted.Remove(0, 1);
            }
            if (unquoted.EndsWith("\""))
            {
                unquoted = unquoted.Remove(unquoted.Length - 1, 1);
            }

            return unquoted;
        }

                #endregion
        }
}

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Firebird-net-provider mailing list
Firebird-net-provider@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/firebird-net-provider

Reply via email to