From: <car...@us...> - 2006-03-13 21:45:35
|
Revision: 23 Author: carlosga_fb Date: 2006-03-13 13:45:11 -0800 (Mon, 13 Mar 2006) ViewCVS: http://svn.sourceforge.net/pgsqlclient/?rev=23&view=rev Log Message: ----------- Modified Paths: -------------- pgsqlclient/source/PostgreSql/Data/PostgreSql.Data.PostgreSqlClient.csproj pgsqlclient/source/PostgreSql/Data/PostgreSqlClient/PgConnection.cs pgsqlclient/source/PostgreSql/Data/PostgreSqlClient/PgConnectionInternal.cs pgsqlclient/source/PostgreSql/Data/Protocol/PgOutputPacket.cs pgsqlclient/source/PostgreSql/Data/Protocol/PgParameter.cs pgsqlclient/source/PostgreSql/Data/Protocol/PgResponsePacket.cs pgsqlclient/source/PostgreSql/Data/Protocol/PgStatement.cs pgsqlclient/source/PostgreSql/Data/Protocol/PgType.cs pgsqlclient/source/PostgreSql.Data.PostgreSqlClient.suo pgsqlclient/source/SecureSocketLayer/SecureSocketLayer.csproj Added Paths: ----------- pgsqlclient/source/PostgreSql/Data/Protocol/PgDatabase.cs Removed Paths: ------------- pgsqlclient/source/PostgreSql/Data/Protocol/PgDbClient.cs Modified: pgsqlclient/source/PostgreSql/Data/PostgreSql.Data.PostgreSqlClient.csproj =================================================================== --- pgsqlclient/source/PostgreSql/Data/PostgreSql.Data.PostgreSqlClient.csproj 2006-03-13 21:42:55 UTC (rev 22) +++ pgsqlclient/source/PostgreSql/Data/PostgreSql.Data.PostgreSqlClient.csproj 2006-03-13 21:45:11 UTC (rev 23) @@ -12,13 +12,15 @@ <AssemblyName>PostgreSql.Data.PgSqlClient</AssemblyName> <StartupObject> </StartupObject> + <SignAssembly>true</SignAssembly> + <AssemblyOriginatorKeyFile>PostgreSql.Data.PostgreSqlClient.snk</AssemblyOriginatorKeyFile> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> <DebugType>full</DebugType> <Optimize>false</Optimize> <OutputPath>bin\Debug\</OutputPath> - <DefineConstants>DEBUG;TRACE</DefineConstants> + <DefineConstants>TRACE;DEBUG;CUSTOM_SSL</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> @@ -32,7 +34,6 @@ </PropertyGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> - <Compile Include="AssemblyInfo.cs" /> <Compile Include="Design\ParameterCollection\PgParameterCollectionEditor.cs" /> <Compile Include="Design\ParameterCollection\PgParameterConverter.cs" /> <Compile Include="PostgreSqlClient\PgCommand.cs"> @@ -67,6 +68,17 @@ <Compile Include="PostgreSqlClient\PgRowUpdatingEventHandler.cs" /> <Compile Include="PostgreSqlClient\PgTransaction.cs" /> <Compile Include="PostgreSqlClient\PostgreSqlClientFactory.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + <Compile Include="Properties\Settings.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTimeSharedInput>True</DesignTimeSharedInput> + <DependentUpon>Settings.settings</DependentUpon> + </Compile> <Compile Include="Protocol\InfoMessageCallback.cs" /> <Compile Include="Protocol\NotificationCallback.cs" /> <Compile Include="Protocol\PgAuthMethods.cs" /> @@ -127,6 +139,11 @@ <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="Properties\Resources.resx"> + <SubType>Designer</SubType> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> <EmbeddedResource Include="Schema\MetaData.xml" /> </ItemGroup> <ItemGroup> @@ -138,4 +155,11 @@ <Name>SecureSocketLayer</Name> </ProjectReference> </ItemGroup> + <ItemGroup> + <None Include="PostgreSql.Data.PostgreSqlClient.snk" /> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + </ItemGroup> </Project> \ No newline at end of file Modified: pgsqlclient/source/PostgreSql/Data/PostgreSqlClient/PgConnection.cs =================================================================== --- pgsqlclient/source/PostgreSql/Data/PostgreSqlClient/PgConnection.cs 2006-03-13 21:42:55 UTC (rev 22) +++ pgsqlclient/source/PostgreSql/Data/PostgreSqlClient/PgConnection.cs 2006-03-13 21:45:11 UTC (rev 23) @@ -353,7 +353,7 @@ { lock (this.connectionInternal) { - PgDbClient database = this.connectionInternal.Database; + PgDatabase database = this.connectionInternal.Database; // Remove info message callback this.connectionInternal.Database.InfoMessage = null; Modified: pgsqlclient/source/PostgreSql/Data/PostgreSqlClient/PgConnectionInternal.cs =================================================================== --- pgsqlclient/source/PostgreSql/Data/PostgreSqlClient/PgConnectionInternal.cs 2006-03-13 21:42:55 UTC (rev 22) +++ pgsqlclient/source/PostgreSql/Data/PostgreSqlClient/PgConnectionInternal.cs 2006-03-13 21:45:11 UTC (rev 23) @@ -28,7 +28,7 @@ #region \xB7 Fields \xB7 private PgConnection owningConnection; - private PgDbClient database; + private PgDatabase database; private PgConnectionOptions options; private PgTransaction activeTransaction; private ArrayList preparedCommands; @@ -39,7 +39,7 @@ #region \xB7 Properties \xB7 - public PgDbClient Database + public PgDatabase Database { get { return this.database; } } @@ -113,7 +113,7 @@ { try { - this.database = new PgDbClient(this.options); + this.database = new PgDatabase(this.options); this.database.Connect(); } catch (PgClientException ex) Copied: pgsqlclient/source/PostgreSql/Data/Protocol/PgDatabase.cs (from rev 11, pgsqlclient/source/PostgreSql/Data/Protocol/PgDbClient.cs) =================================================================== --- pgsqlclient/source/PostgreSql/Data/Protocol/PgDatabase.cs (rev 0) +++ pgsqlclient/source/PostgreSql/Data/Protocol/PgDatabase.cs 2006-03-13 21:45:11 UTC (rev 23) @@ -0,0 +1,863 @@ +/* + * PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ + * + * 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. + * + * 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) 2003, 2005 Carlos Guzman Alvarez + * All Rights Reserved. + */ + +using System; +using System.Data; +using System.IO; +using System.Collections; +using System.Text; +using System.Net; +using System.Net.Sockets; + +#if (CUSTOM_SSL) +using SecureSocketLayer.Net.Security; +#else +using System.Net.Security; +#endif + +namespace PostgreSql.Data.Protocol +{ + internal class PgDatabase + { + #region \xB7 Static Properties \xB7 + + public static readonly PgTypeCollection DataTypes = new PgTypeCollection(); + public static readonly PgCharactersetCollection Charactersets = new PgCharactersetCollection(); + + #endregion + + #region \xB7 Static Methods \xB7 + + public static void InitializeTypes() + { + if (DataTypes.Count > 0) + { + return; + } + + DataTypes.Add(16 , "bool" , PgDataType.Boolean , 0, PgTypeFormat.Binary, 1); + DataTypes.Add(17 , "bytea" , PgDataType.Binary , 0, PgTypeFormat.Binary, 0); + DataTypes.Add(18 , "char" , PgDataType.Char , 0, PgTypeFormat.Text, 0); + DataTypes.Add(19 , "name" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); + DataTypes.Add(20 , "int8" , PgDataType.Int8 , 0, PgTypeFormat.Binary, 8); + DataTypes.Add(21 , "int2" , PgDataType.Int2 , 0, PgTypeFormat.Binary, 2); + DataTypes.Add(22 , "int2vector" , PgDataType.Vector , 21, PgTypeFormat.Binary, 2); + DataTypes.Add(23 , "int4" , PgDataType.Int4 , 0, PgTypeFormat.Binary, 4); + DataTypes.Add(24 , "regproc" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); + DataTypes.Add(25 , "text" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); + DataTypes.Add(26 , "oid" , PgDataType.Int4 , 0, PgTypeFormat.Binary, 4); + DataTypes.Add(30 , "oidvector" , PgDataType.Vector , 26, PgTypeFormat.Binary, 4); + DataTypes.Add(600 , "point" , PgDataType.Point , 701, PgTypeFormat.Binary, 16); + DataTypes.Add(601 , "lseg" , PgDataType.LSeg , 600, PgTypeFormat.Binary, 32); + DataTypes.Add(602 , "path" , PgDataType.Path , 0, PgTypeFormat.Binary, 16); + DataTypes.Add(603 , "box" , PgDataType.Box , 600, PgTypeFormat.Binary, 32); + DataTypes.Add(604 , "polygon" , PgDataType.Polygon , 0, PgTypeFormat.Binary, 16); + DataTypes.Add(628 , "line" , PgDataType.Line , 701, PgTypeFormat.Binary, 32); + DataTypes.Add(629 , "_line" , PgDataType.Array , 628, PgTypeFormat.Binary, 32); + DataTypes.Add(718 , "circle" , PgDataType.Circle , 0, PgTypeFormat.Binary, 24); + DataTypes.Add(719 , "_circle" , PgDataType.Array , 718, PgTypeFormat.Binary, 24); + DataTypes.Add(700 , "float4" , PgDataType.Float , 0, PgTypeFormat.Binary, 4); + DataTypes.Add(701 , "float8" , PgDataType.Double , 0, PgTypeFormat.Binary, 8); + DataTypes.Add(705 , "unknown" , PgDataType.Binary , 0, PgTypeFormat.Binary, 0); + DataTypes.Add(790 , "money" , PgDataType.Currency , 0, PgTypeFormat.Binary, 4); + DataTypes.Add(829 , "macaddr" , PgDataType.VarChar , 0, PgTypeFormat.Text, 6); + DataTypes.Add(869 , "inet" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); + DataTypes.Add(1000 , "_bool" , PgDataType.Array , 16, PgTypeFormat.Binary, 1); + DataTypes.Add(1005 , "_int2" , PgDataType.Array , 21, PgTypeFormat.Binary, 2); + DataTypes.Add(1007 , "_int4" , PgDataType.Array , 23, PgTypeFormat.Binary, 4); + DataTypes.Add(1009 , "_text" , PgDataType.Array , 25, PgTypeFormat.Binary, 0); + DataTypes.Add(1016 , "_int8" , PgDataType.Array , 20, PgTypeFormat.Binary, 8); + DataTypes.Add(1017 , "_point" , PgDataType.Array , 600, PgTypeFormat.Binary, 16); + DataTypes.Add(1018 , "_lseg" , PgDataType.Array , 601, PgTypeFormat.Binary, 32); + DataTypes.Add(1019 , "_path" , PgDataType.Array , 602, PgTypeFormat.Binary, -1); + DataTypes.Add(1020 , "_box" , PgDataType.Array , 603, PgTypeFormat.Binary, 32); + DataTypes.Add(1021 , "_float4" , PgDataType.Array , 700, PgTypeFormat.Binary, 4); + DataTypes.Add(1027 , "_polygon" , PgDataType.Array , 604, PgTypeFormat.Binary, 16); + DataTypes.Add(1033 , "aclitem" , PgDataType.VarChar , 0, PgTypeFormat.Text, 12); + DataTypes.Add(1034 , "_aclitem" , PgDataType.Array , 1033, PgTypeFormat.Text, 0); + DataTypes.Add(1042 , "bpchar" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); + DataTypes.Add(1043 , "varchar" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); + DataTypes.Add(1082 , "date" , PgDataType.Date , 0, PgTypeFormat.Binary, 4); + DataTypes.Add(1083 , "time" , PgDataType.Time , 0, PgTypeFormat.Text, 8); + DataTypes.Add(1114 , "timestamp" , PgDataType.Timestamp , 0, PgTypeFormat.Text, 8); + DataTypes.Add(1184 , "timestamptz" , PgDataType.TimestampWithTZ, 0, PgTypeFormat.Binary, 8); + DataTypes.Add(1186 , "interval" , PgDataType.Interval , 0, PgTypeFormat.Binary, 12); + DataTypes.Add(1266 , "timetz" , PgDataType.TimeWithTZ , 0, PgTypeFormat.Binary, 12); + DataTypes.Add(1560 , "bit" , PgDataType.Byte , 0, PgTypeFormat.Text, 1); + DataTypes.Add(1562 , "varbit" , PgDataType.Byte , 0, PgTypeFormat.Binary, 0); + DataTypes.Add(1700 , "numeric" , PgDataType.Decimal , 0, PgTypeFormat.Text, 8); + DataTypes.Add(1790 , "refcursor" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); + DataTypes.Add(2277 , "anyarray" , PgDataType.Array , 0, PgTypeFormat.Binary, 8); + } + + public static void InitializeCharSets() + { + if (Charactersets.Count > 0) + { + return; + } + + Charactersets.Add("SQL_ASCII" , "ascii"); // ASCII + Charactersets.Add("EUC_JP" , "euc-jp"); // Japanese EUC + Charactersets.Add("EUC_CN" , "euc-cn"); // Chinese EUC + Charactersets.Add("UNICODE" , "UTF-8"); // Unicode (UTF-8) + Charactersets.Add("LATIN1" , "iso-8859-1"); // ISO 8859-1/ECMA 94 (Latin alphabet no.1) + Charactersets.Add("LATIN2" , "iso-8859-2"); // ISO 8859-2/ECMA 94 (Latin alphabet no.2) + Charactersets.Add("LATIN4" , 1257); // ISO 8859-4/ECMA 94 (Latin alphabet no.4) + Charactersets.Add("ISO_8859_7" , 1253); // ISO 8859-7/ECMA 118 (Latin/Greek) + Charactersets.Add("LATIN9" , "iso-8859-15"); // ISO 8859-15 (Latin alphabet no.9) + Charactersets.Add("KOI8" , "koi8-r"); // KOI8-R(U) + Charactersets.Add("WIN" , "windows-1251"); // Windows CP1251 + Charactersets.Add("WIN1256" , "windows-1256"); // Windows CP1256 (Arabic) + Charactersets.Add("WIN1256" , "windows-1256"); // Windows CP1256 (Arabic) + Charactersets.Add("WIN1256" , "windows-1258"); // TCVN-5712/Windows CP1258 (Vietnamese) + Charactersets.Add("WIN1256" , "windows-874"); // Windows CP874 (Thai) + } + + #endregion + + #region \xB7 Callbacks \xB7 + + public NotificationCallback Notification + { + get { return this.notification; } + set { this.notification = value; } + } + + public InfoMessageCallback InfoMessage + { + get { return this.infoMessage; } + set { this.infoMessage = value; } + } + + #endregion + + #region \xB7 Fields \xB7 + + private NotificationCallback notification; + private InfoMessageCallback infoMessage; + + private int handle; + private int secretKey; + private Hashtable parameterStatus; + private Socket socket; + private NetworkStream networkStream; + private SslStream secureStream; + private BinaryReader receive; + private BinaryWriter send; + private PgConnectionOptions options; + private Encoding encoding; + private char transactionStatus; + + #endregion + + #region \xB7 Properties \xB7 + + public int Handle + { + get { return this.handle; } + } + + public int SecretKey + { + get { return this.secretKey; } + } + + public Hashtable ParameterStatus + { + get + { + if (this.parameterStatus == null) + { + this.parameterStatus = Hashtable.Synchronized(new Hashtable()); + } + return this.parameterStatus; + } + } + + public PgConnectionOptions Options + { + get { return this.options; } + } + + public Encoding Encoding + { + get { return this.encoding; } + } + + #endregion + + #region \xB7 Internal Properties \xB7 + + internal SslStream SecureStream + { + get { return this.secureStream; } + } + + internal BinaryReader Receive + { + get { return this.receive; } + } + + internal BinaryWriter Send + { + get { return this.send; } + } + + #endregion + + #region \xB7 Constructors \xB7 + + public PgDatabase(string connectionString) + : this(new PgConnectionOptions(connectionString)) + { + } + + public PgDatabase(PgConnectionOptions options) + { + this.options = options; + this.encoding = Encoding.Default; + + GC.SuppressFinalize(this); + } + + #endregion + + #region \xB7 Database Methods \xB7 + + public void Connect() + { + try + { + PgDatabase.InitializeTypes(); + PgDatabase.InitializeCharSets(); + + this.InitializeSocket(); + + lock (this) + { + if (this.options.SSL) + { + // Send SSL request message + if (this.SslRequest()) + { + this.secureStream = new SslStream(this.networkStream, false); + + this.SecureStream.AuthenticateAsClient(this.options.DataSource); + + this.receive = new BinaryReader(this.SecureStream); + this.send = new BinaryWriter(this.SecureStream); + } + } + + // Send Startup message + PgOutputPacket packet = new PgOutputPacket(this.Encoding); + + packet.Write(PgCodes.PROTOCOL_VERSION3); + packet.WriteNullString("user"); + packet.WriteNullString(this.options.UserID); + + if (this.options.Database != null && this.options.Database.Length > 0) + { + packet.WriteNullString("database"); + packet.WriteNullString(this.options.Database); + } + + packet.WriteNullString("DateStyle"); + packet.WriteNullString(PgCodes.DATE_STYLE); + packet.Write((byte)0); // Terminator + + this.SendSimplePacket(packet); + + PgResponsePacket response = null; + + do + { + response = this.ReceiveResponsePacket(); + this.ProcessResponsePacket(response); + } + while (!response.IsReadyForQuery); + } + } + catch (IOException ex) + { + this.Detach(); + throw new PgClientException(ex.Message); + } + catch (PgClientException) + { + this.Detach(); + throw; + } + } + + public void Disconnect() + { + try + { + // Send packet to the server + PgOutputPacket packet = new PgOutputPacket(); + this.SendPacket(packet, PgFrontEndCodes.TERMINATE); + + this.Detach(); + } + catch (IOException ex) + { + throw new PgClientException(ex.Message); + } + catch (PgClientException) + { + throw; + } + } + + #endregion + + #region \xB7 Send Methods \xB7 + + internal void SendPacket(PgOutputPacket packet, char type) + { + this.Write(packet.GetPacketBytes(type)); + } + + internal void SendSimplePacket(PgOutputPacket packet) + { + this.Write(packet.GetSimplePacketBytes()); + } + + private void Write(byte[] buffer) + { + this.Write(buffer, 0, buffer.Length); + } + + private void Write(byte[] buffer, int index, int count) + { + try + { + this.send.Write(buffer, index, count); + this.send.Flush(); + } + catch (IOException) + { + throw; + } + } + + #endregion + + #region \xB7 Response Methods \xB7 + + public PgResponsePacket ReceiveResponsePacket() + { + PgResponsePacket responsePacket = null; + + lock (this) + { + responsePacket = this.ReceiveStandardPacket(); + + switch (responsePacket.Message) + { + case PgBackendCodes.ERROR_RESPONSE: + // Read the error message and trow the exception + PgClientException ex = this.ProcessErrorPacket(responsePacket); + + // Perform a sync + this.Sync(); + + // Throw the PostgreSQL exception + throw ex; + + case PgBackendCodes.NOTICE_RESPONSE: + // Read the notice message and raise an InfoMessage event + this.InfoMessage(this.ProcessErrorPacket(responsePacket)); + break; + + case PgBackendCodes.NOTIFICATION_RESPONSE: + this.ProcessNotificationResponse(responsePacket); + break; + } + } + + return responsePacket; + } + + private PgResponsePacket ReceiveStandardPacket() + { + PgResponsePacket responsePacket = null; + + try + { + char type = this.receive.ReadChar(); + int length = IPAddress.HostToNetworkOrder(this.receive.ReadInt32()) - 4; + + // Read the message data + byte[] buffer = new byte[length]; + int received = 0; + + while (received < length) + { + received += this.receive.Read(buffer, received, length - received); + } + + responsePacket = new PgResponsePacket(type, this.Encoding, buffer); + } + catch (IOException) + { + throw; + } + + return responsePacket; + } + + private void ProcessResponsePacket(PgResponsePacket packet) + { + switch (packet.Message) + { + case PgBackendCodes.AUTHENTICATION: + this.ProcessAuthPacket(packet); + break; + + case PgBackendCodes.PARAMETER_STATUS: + this.ProcessParameterStatus(packet); + break; + + case PgBackendCodes.READY_FOR_QUERY: + this.transactionStatus = packet.ReadChar(); + break; + + case PgBackendCodes.BACKEND_KEY_DATA: + // BackendKeyData + this.handle = packet.ReadInt32(); + this.secretKey = packet.ReadInt32(); + break; + } + } + + private void ProcessParameterStatus(PgResponsePacket packet) + { + string parameterName = packet.ReadNullString(); + string parameterValue = packet.ReadNullString(); + + this.ParameterStatus.Add(parameterName, parameterValue); + + switch (parameterName) + { + case "client_encoding": + this.encoding = Charactersets[parameterValue].Encoding; + break; + } + } + + private void ProcessAuthPacket(PgResponsePacket packet) + { + // Authentication response + int authType = packet.ReadInt32(); + + PgOutputPacket outPacket = new PgOutputPacket(this.Encoding); + + switch (authType) + { + case PgCodes.AUTH_OK: + // Authentication successful + return; + + case PgCodes.AUTH_KERBEROS_V4: + // Kerberos V4 authentication is required + break; + + case PgCodes.AUTH_KERBEROS_V5: + // Kerberos V5 authentication is required + break; + + case PgCodes.AUTH_CLEARTEXT_PASSWORD: + // Cleartext password is required + outPacket.WriteNullString(this.options.Password); + break; + + case PgCodes.AUTH_CRYPT_PASSWORD: + // crypt()-encrypted password is required + break; + + case PgCodes.AUTH_MD5_PASSWORD: + // MD5-encrypted password is required + + // First read salt to use when encrypting the password + byte[] salt = packet.ReadBytes(4); + + // Second calculate md5 of password + user + string userHash = MD5Authentication.GetMD5Hash( + this.Encoding.GetBytes(this.options.UserID), this.options.Password); + + // Third calculate real MD5 hash + string hash = MD5Authentication.GetMD5Hash(salt, userHash); + + // Finally write the md5 hash to the packet + outPacket.WriteNullString(PgCodes.MD5_PREFIX + hash); + break; + + case PgCodes.AUTH_SCM_CREDENTIAL: + // SCM credentials message is required + break; + } + + // Send the packet to the server + this.SendPacket(outPacket, PgFrontEndCodes.PASSWORD_MESSAGE); + } + + private PgClientException ProcessErrorPacket(PgResponsePacket packet) + { + char type = ' '; + PgClientError error = new PgClientError(); + + while (type != PgErrorCodes.END) + { + type = packet.ReadChar(); + switch (type) + { + case PgErrorCodes.SEVERITY: + error.Severity = packet.ReadNullString(); + break; + + case PgErrorCodes.CODE: + error.Code = packet.ReadNullString(); + break; + + case PgErrorCodes.MESSAGE: + error.Message = packet.ReadNullString(); + break; + + case PgErrorCodes.DETAIL: + error.Detail = packet.ReadNullString(); + break; + + case PgErrorCodes.HINT: + error.Hint = packet.ReadNullString(); + break; + + case PgErrorCodes.POSITION: + error.Position = packet.ReadNullString(); + break; + + case PgErrorCodes.WHERE: + error.Where = packet.ReadNullString(); + break; + + case PgErrorCodes.FILE: + error.File = packet.ReadNullString(); + break; + + case PgErrorCodes.LINE: + error.Line = Convert.ToInt32(packet.ReadNullString()); + break; + + case PgErrorCodes.ROUTINE: + error.Routine = packet.ReadNullString(); + break; + } + } + + PgClientException exception = new PgClientException(error.Message); + + exception.Errors.Add(error); + + return exception; + } + + private void ProcessNotificationResponse(PgResponsePacket packet) + { + int processID = packet.ReadInt32(); + string condition = packet.ReadNullString(); + string additional = packet.ReadNullString(); + + if (this.Notification != null) + { + this.Notification(processID, condition, additional); + } + } + + #endregion + + #region \xB7 Transaction Methods \xB7 + + public void BeginTransaction(IsolationLevel isolationLevel) + { + string sql = "START TRANSACTION ISOLATION LEVEL "; + + switch (isolationLevel) + { + case IsolationLevel.ReadCommitted: + sql += "READ COMMITTED"; + break; + + case IsolationLevel.ReadUncommitted: + throw new NotSupportedException("Read uncommitted transaction isolation is not supported"); + + case IsolationLevel.RepeatableRead: + throw new NotSupportedException("Repeatable read transaction isolation is not supported"); + + case IsolationLevel.Serializable: + sql += "SERIALIZABLE"; + break; + } + + PgStatement stmt = CreateStatement(sql); + stmt.Query(); + + if (stmt.Tag != "START TRANSACTION") + { + throw new PgClientException("A transaction is currently active. Parallel transactions are not supported."); + } + + this.transactionStatus = stmt.TransactionStatus; + } + + public void CommitTransaction() + { + PgStatement stmt = CreateStatement("COMMIT TRANSACTION"); + stmt.Query(); + + if (stmt.Tag != "COMMIT") + { + throw new PgClientException("There are no transaction for commit."); + } + + this.transactionStatus = stmt.TransactionStatus; + } + + public void RollbackTransction() + { + PgStatement stmt = CreateStatement("ROLLBACK TRANSACTION"); + stmt.Query(); + + if (stmt.Tag != "ROLLBACK") + { + throw new PgClientException("There are no transaction for rollback."); + } + + this.transactionStatus = stmt.TransactionStatus; + } + + #endregion + + #region \xB7 Client Methods \xB7 + + public void Flush() + { + lock (this) + { + try + { + PgOutputPacket packet = new PgOutputPacket(this.Encoding); + + // Send packet to the server + this.SendPacket(packet, PgFrontEndCodes.FLUSH); + } + catch (Exception) + { + throw; + } + } + } + + public void Sync() + { + lock (this) + { + try + { + PgOutputPacket packet = new PgOutputPacket(this.Encoding); + + // Send packet to the server + this.SendPacket(packet, PgFrontEndCodes.SYNC); + + // Receive response + PgResponsePacket response = null; + + do + { + response = this.ReceiveResponsePacket(); + this.ProcessResponsePacket(response); + } + while (!response.IsReadyForQuery); + } + catch + { + PgResponsePacket response = null; + + do + { + response = this.ReceiveResponsePacket(); + this.ProcessResponsePacket(response); + } + while (!response.IsReadyForQuery); + + throw; + } + } + } + + public void CancelRequest() + { + lock (this) + { + try + { + PgOutputPacket packet = new PgOutputPacket(); + + packet.Write((int)16); + packet.Write(PgCodes.CANCEL_REQUEST); + packet.Write(this.Handle); + packet.Write(this.SecretKey); + + // Send packet to the server + this.SendSimplePacket(packet); + } + catch (Exception) + { + throw; + } + } + } + + public bool SslRequest() + { + bool sslAvailable = false; + + lock (this) + { + try + { + PgOutputPacket packet = new PgOutputPacket(); + + packet.Write(PgCodes.SSL_REQUEST); + + // Send packet to the server + this.SendSimplePacket(packet); + + // Receive server response + switch (Convert.ToChar(this.networkStream.ReadByte())) + { + case 'S': + sslAvailable = true; + break; + + default: + sslAvailable = false; + break; + } + } + catch + { + throw; + } + } + + return sslAvailable; + } + + #endregion + + #region \xB7 Methods \xB7 + + public void SendInfoMessage(PgClientException exception) + { + if (this.InfoMessage != null) + { + this.InfoMessage(exception); + } + } + + public PgStatement CreateStatement() + { + return new PgStatement(this); + } + + public PgStatement CreateStatement(string stmtText) + { + return new PgStatement(this, stmtText); + } + + public PgStatement CreateStatement(string parseName, string portalName) + { + return new PgStatement(this, parseName, portalName); + } + + public PgStatement CreateStatement(string parseName, string portalName, string stmtText) + { + return new PgStatement(this, parseName, portalName, stmtText); + } + + #endregion + + #region \xB7 Private Methods \xB7 + + private void InitializeSocket() + { + IPAddress hostadd = Dns.GetHostEntry(this.options.DataSource).AddressList[0]; + + this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + // Set Receive Buffer size. + this.socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, this.options.PacketSize); + + // Set Send Buffer size. + this.socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, this.options.PacketSize); + + // Disables the Nagle algorithm for send coalescing. + this.socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1); + + // Make the socket to connect to the Server + this.socket.Connect(new IPEndPoint(hostadd, this.options.PortNumber)); + this.networkStream = new NetworkStream(socket, true); + + // Create objects for read & write + this.receive = new BinaryReader(new BufferedStream(this.networkStream)); + this.send = new BinaryWriter(new BufferedStream(this.networkStream)); + + // The socket and stream shouldn't be automatically collected by the GC + GC.SuppressFinalize(this.socket); + GC.SuppressFinalize(this.networkStream); + GC.SuppressFinalize(this.receive); + GC.SuppressFinalize(this.send); + } + + private void Detach() + { + // Close streams + if (this.secureStream != null) + { + try + { + this.secureStream.Close(); + } + catch + { + } + } + if (this.networkStream != null) + { + this.networkStream.Close(); + } + if (this.socket != null) + { + this.socket.Close(); + } + } + + #endregion + } +} Deleted: pgsqlclient/source/PostgreSql/Data/Protocol/PgDbClient.cs =================================================================== --- pgsqlclient/source/PostgreSql/Data/Protocol/PgDbClient.cs 2006-03-13 21:42:55 UTC (rev 22) +++ pgsqlclient/source/PostgreSql/Data/Protocol/PgDbClient.cs 2006-03-13 21:45:11 UTC (rev 23) @@ -1,858 +0,0 @@ -/* - * PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ - * - * 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. - * - * 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) 2003, 2005 Carlos Guzman Alvarez - * All Rights Reserved. - */ - -using System; -using System.Data; -using System.IO; -using System.Collections; -using System.Text; -using System.Net; -using System.Net.Sockets; -using System.Net.Security; - -namespace PostgreSql.Data.Protocol -{ - internal class PgDbClient - { - #region \xB7 Static Properties \xB7 - - public static readonly PgTypeCollection DataTypes = new PgTypeCollection(); - public static readonly PgCharactersetCollection Charactersets = new PgCharactersetCollection(); - - #endregion - - #region \xB7 Static Methods \xB7 - - public static void InitializeTypes() - { - if (DataTypes.Count > 0) - { - return; - } - - DataTypes.Add(16 , "bool" , PgDataType.Boolean , 0, PgTypeFormat.Binary, 1); - DataTypes.Add(17 , "bytea" , PgDataType.Binary , 0, PgTypeFormat.Binary, 0); - DataTypes.Add(18 , "char" , PgDataType.Char , 0, PgTypeFormat.Text, 0); - DataTypes.Add(19 , "name" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); - DataTypes.Add(20 , "int8" , PgDataType.Int8 , 0, PgTypeFormat.Binary, 8); - DataTypes.Add(21 , "int2" , PgDataType.Int2 , 0, PgTypeFormat.Binary, 2); - DataTypes.Add(22 , "int2vector" , PgDataType.Vector , 21, PgTypeFormat.Binary, 2); - DataTypes.Add(23 , "int4" , PgDataType.Int4 , 0, PgTypeFormat.Binary, 4); - DataTypes.Add(24 , "regproc" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); - DataTypes.Add(25 , "text" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); - DataTypes.Add(26 , "oid" , PgDataType.Int4 , 0, PgTypeFormat.Binary, 4); - DataTypes.Add(30 , "oidvector" , PgDataType.Vector , 26, PgTypeFormat.Binary, 4); - DataTypes.Add(600 , "point" , PgDataType.Point , 701, PgTypeFormat.Binary, 16); - DataTypes.Add(601 , "lseg" , PgDataType.LSeg , 600, PgTypeFormat.Binary, 32); - DataTypes.Add(602 , "path" , PgDataType.Path , 0, PgTypeFormat.Binary, 16); - DataTypes.Add(603 , "box" , PgDataType.Box , 600, PgTypeFormat.Binary, 32); - DataTypes.Add(604 , "polygon" , PgDataType.Polygon , 0, PgTypeFormat.Binary, 16); - DataTypes.Add(628 , "line" , PgDataType.Line , 701, PgTypeFormat.Binary, 32); - DataTypes.Add(629 , "_line" , PgDataType.Array , 628, PgTypeFormat.Binary, 32); - DataTypes.Add(718 , "circle" , PgDataType.Circle , 0, PgTypeFormat.Binary, 24); - DataTypes.Add(719 , "_circle" , PgDataType.Array , 718, PgTypeFormat.Binary, 24); - DataTypes.Add(700 , "float4" , PgDataType.Float , 0, PgTypeFormat.Binary, 4); - DataTypes.Add(701 , "float8" , PgDataType.Double , 0, PgTypeFormat.Binary, 8); - DataTypes.Add(705 , "unknown" , PgDataType.Binary , 0, PgTypeFormat.Binary, 0); - DataTypes.Add(790 , "money" , PgDataType.Currency , 0, PgTypeFormat.Binary, 4); - DataTypes.Add(829 , "macaddr" , PgDataType.VarChar , 0, PgTypeFormat.Text, 6); - DataTypes.Add(869 , "inet" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); - DataTypes.Add(1000 , "_bool" , PgDataType.Array , 16, PgTypeFormat.Binary, 1); - DataTypes.Add(1005 , "_int2" , PgDataType.Array , 21, PgTypeFormat.Binary, 2); - DataTypes.Add(1007 , "_int4" , PgDataType.Array , 23, PgTypeFormat.Binary, 4); - DataTypes.Add(1009 , "_text" , PgDataType.Array , 25, PgTypeFormat.Binary, 0); - DataTypes.Add(1016 , "_int8" , PgDataType.Array , 20, PgTypeFormat.Binary, 8); - DataTypes.Add(1017 , "_point" , PgDataType.Array , 600, PgTypeFormat.Binary, 16); - DataTypes.Add(1018 , "_lseg" , PgDataType.Array , 601, PgTypeFormat.Binary, 32); - DataTypes.Add(1019 , "_path" , PgDataType.Array , 602, PgTypeFormat.Binary, -1); - DataTypes.Add(1020 , "_box" , PgDataType.Array , 603, PgTypeFormat.Binary, 32); - DataTypes.Add(1021 , "_float4" , PgDataType.Array , 700, PgTypeFormat.Binary, 4); - DataTypes.Add(1027 , "_polygon" , PgDataType.Array , 604, PgTypeFormat.Binary, 16); - DataTypes.Add(1033 , "aclitem" , PgDataType.VarChar , 0, PgTypeFormat.Text, 12); - DataTypes.Add(1034 , "_aclitem" , PgDataType.Array , 1033, PgTypeFormat.Text, 0); - DataTypes.Add(1042 , "bpchar" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); - DataTypes.Add(1043 , "varchar" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); - DataTypes.Add(1082 , "date" , PgDataType.Date , 0, PgTypeFormat.Binary, 4); - DataTypes.Add(1083 , "time" , PgDataType.Time , 0, PgTypeFormat.Text, 8); - DataTypes.Add(1114 , "timestamp" , PgDataType.Timestamp , 0, PgTypeFormat.Text, 8); - DataTypes.Add(1184 , "timestamptz" , PgDataType.TimestampWithTZ, 0, PgTypeFormat.Binary, 8); - DataTypes.Add(1186 , "interval" , PgDataType.Interval , 0, PgTypeFormat.Binary, 12); - DataTypes.Add(1266 , "timetz" , PgDataType.TimeWithTZ , 0, PgTypeFormat.Binary, 12); - DataTypes.Add(1560 , "bit" , PgDataType.Byte , 0, PgTypeFormat.Text, 1); - DataTypes.Add(1562 , "varbit" , PgDataType.Byte , 0, PgTypeFormat.Binary, 0); - DataTypes.Add(1700 , "numeric" , PgDataType.Decimal , 0, PgTypeFormat.Text, 8); - DataTypes.Add(1790 , "refcursor" , PgDataType.VarChar , 0, PgTypeFormat.Text, 0); - DataTypes.Add(2277 , "anyarray" , PgDataType.Array , 0, PgTypeFormat.Binary, 8); - } - - public static void InitializeCharSets() - { - if (Charactersets.Count > 0) - { - return; - } - - Charactersets.Add("SQL_ASCII" , "ascii"); // ASCII - Charactersets.Add("EUC_JP" , "euc-jp"); // Japanese EUC - Charactersets.Add("EUC_CN" , "euc-cn"); // Chinese EUC - Charactersets.Add("UNICODE" , "UTF-8"); // Unicode (UTF-8) - Charactersets.Add("LATIN1" , "iso-8859-1"); // ISO 8859-1/ECMA 94 (Latin alphabet no.1) - Charactersets.Add("LATIN2" , "iso-8859-2"); // ISO 8859-2/ECMA 94 (Latin alphabet no.2) - Charactersets.Add("LATIN4" , 1257); // ISO 8859-4/ECMA 94 (Latin alphabet no.4) - Charactersets.Add("ISO_8859_7" , 1253); // ISO 8859-7/ECMA 118 (Latin/Greek) - Charactersets.Add("LATIN9" , "iso-8859-15"); // ISO 8859-15 (Latin alphabet no.9) - Charactersets.Add("KOI8" , "koi8-r"); // KOI8-R(U) - Charactersets.Add("WIN" , "windows-1251"); // Windows CP1251 - Charactersets.Add("WIN1256" , "windows-1256"); // Windows CP1256 (Arabic) - Charactersets.Add("WIN1256" , "windows-1256"); // Windows CP1256 (Arabic) - Charactersets.Add("WIN1256" , "windows-1258"); // TCVN-5712/Windows CP1258 (Vietnamese) - Charactersets.Add("WIN1256" , "windows-874"); // Windows CP874 (Thai) - } - - #endregion - - #region \xB7 Callbacks \xB7 - - public NotificationCallback Notification - { - get { return this.notification; } - set { this.notification = value; } - } - - public InfoMessageCallback InfoMessage - { - get { return this.infoMessage; } - set { this.infoMessage = value; } - } - - #endregion - - #region \xB7 Fields \xB7 - - private NotificationCallback notification; - private InfoMessageCallback infoMessage; - - private int handle; - private int secretKey; - private Hashtable parameterStatus; - private Socket socket; - private NetworkStream networkStream; - private SslStream secureStream; - private BinaryReader receive; - private BinaryWriter send; - private PgConnectionOptions options; - private Encoding encoding; - private char transactionStatus; - - #endregion - - #region \xB7 Properties \xB7 - - public int Handle - { - get { return this.handle; } - } - - public int SecretKey - { - get { return this.secretKey; } - } - - public Hashtable ParameterStatus - { - get - { - if (this.parameterStatus == null) - { - this.parameterStatus = Hashtable.Synchronized(new Hashtable()); - } - return this.parameterStatus; - } - } - - public PgConnectionOptions Options - { - get { return this.options; } - } - - public Encoding Encoding - { - get { return this.encoding; } - } - - #endregion - - #region \xB7 Internal Properties \xB7 - - internal SslStream SecureStream - { - get { return this.secureStream; } - } - - internal BinaryReader Receive - { - get { return this.receive; } - } - - internal BinaryWriter Send - { - get { return this.send; } - } - - #endregion - - #region \xB7 Constructors \xB7 - - public PgDbClient(string connectionString) - : this(new PgConnectionOptions(connectionString)) - { - } - - public PgDbClient(PgConnectionOptions options) - { - this.options = options; - this.encoding = Encoding.Default; - - GC.SuppressFinalize(this); - } - - #endregion - - #region \xB7 Database Methods \xB7 - - public void Connect() - { - try - { - PgDbClient.InitializeTypes(); - PgDbClient.InitializeCharSets(); - - this.InitializeSocket(); - - lock (this) - { - if (this.options.SSL) - { - // Send SSL request message - if (this.SslRequest()) - { - this.secureStream = new SslStream(this.networkStream, false); - - this.SecureStream.AuthenticateAsClient(this.options.DataSource); - - this.receive = new BinaryReader(this.SecureStream); - this.send = new BinaryWriter(this.SecureStream); - } - } - - // Send Startup message - PgOutputPacket packet = new PgOutputPacket(this.Encoding); - - packet.Write(PgCodes.PROTOCOL_VERSION3); - packet.WriteNullString("user"); - packet.WriteNullString(this.options.UserID); - - if (this.options.Database != null && this.options.Database.Length > 0) - { - packet.WriteNullString("database"); - packet.WriteNullString(this.options.Database); - } - - packet.WriteNullString("DateStyle"); - packet.WriteNullString(PgCodes.DATE_STYLE); - packet.Write((byte)0); // Terminator - - this.SendSimplePacket(packet); - - PgResponsePacket response = null; - - do - { - response = this.ReceiveResponsePacket(); - this.ProcessResponsePacket(response); - } - while (!response.IsReadyForQuery); - } - } - catch (IOException ex) - { - this.Detach(); - throw new PgClientException(ex.Message); - } - catch (PgClientException) - { - this.Detach(); - throw; - } - } - - public void Disconnect() - { - try - { - // Send packet to the server - PgOutputPacket packet = new PgOutputPacket(); - this.SendPacket(packet, PgFrontEndCodes.TERMINATE); - - this.Detach(); - } - catch (IOException ex) - { - throw new PgClientException(ex.Message); - } - catch (PgClientException) - { - throw; - } - } - - #endregion - - #region \xB7 Send Methods \xB7 - - internal void SendPacket(PgOutputPacket packet, char type) - { - this.Write(packet.GetPacketBytes(type)); - } - - internal void SendSimplePacket(PgOutputPacket packet) - { - this.Write(packet.GetSimplePacketBytes()); - } - - private void Write(byte[] buffer) - { - this.Write(buffer, 0, buffer.Length); - } - - private void Write(byte[] buffer, int index, int count) - { - try - { - this.send.Write(buffer, index, count); - this.send.Flush(); - } - catch (IOException) - { - throw; - } - } - - #endregion - - #region \xB7 Response Methods \xB7 - - public PgResponsePacket ReceiveResponsePacket() - { - PgResponsePacket responsePacket = null; - - lock (this) - { - responsePacket = this.ReceiveStandardPacket(); - - switch (responsePacket.Message) - { - case PgBackendCodes.ERROR_RESPONSE: - // Read the error message and trow the exception - PgClientException ex = this.ProcessErrorPacket(responsePacket); - - // Perform a sync - this.Sync(); - - // Throw the PostgreSQL exception - throw ex; - - case PgBackendCodes.NOTICE_RESPONSE: - // Read the notice message and raise an InfoMessage event - this.InfoMessage(this.ProcessErrorPacket(responsePacket)); - break; - - case PgBackendCodes.NOTIFICATION_RESPONSE: - this.ProcessNotificationResponse(responsePacket); - break; - } - } - - return responsePacket; - } - - private PgResponsePacket ReceiveStandardPacket() - { - PgResponsePacket responsePacket = null; - - try - { - char type = this.receive.ReadChar(); - int length = IPAddress.HostToNetworkOrder(this.receive.ReadInt32()) - 4; - - // Read the message data - byte[] buffer = new byte[length]; - int received = 0; - - while (received < length) - { - received += this.receive.Read(buffer, received, length - received); - } - - responsePacket = new PgResponsePacket(type, this.Encoding, buffer); - } - catch (IOException) - { - throw; - } - - return responsePacket; - } - - private void ProcessResponsePacket(PgResponsePacket packet) - { - switch (packet.Message) - { - case PgBackendCodes.AUTHENTICATION: - this.ProcessAuthPacket(packet); - break; - - case PgBackendCodes.PARAMETER_STATUS: - this.ProcessParameterStatus(packet); - break; - - case PgBackendCodes.READY_FOR_QUERY: - this.transactionStatus = packet.ReadChar(); - break; - - case PgBackendCodes.BACKEND_KEY_DATA: - // BackendKeyData - this.handle = packet.ReadInt32(); - this.secretKey = packet.ReadInt32(); - break; - } - } - - private void ProcessParameterStatus(PgResponsePacket packet) - { - string parameterName = packet.ReadNullString(); - string parameterValue = packet.ReadNullString(); - - this.ParameterStatus.Add(parameterName, parameterValue); - - switch (parameterName) - { - case "client_encoding": - this.encoding = Charactersets[parameterValue].Encoding; - break; - } - } - - private void ProcessAuthPacket(PgResponsePacket packet) - { - // Authentication response - int authType = packet.ReadInt32(); - - PgOutputPacket outPacket = new PgOutputPacket(this.Encoding); - - switch (authType) - { - case PgCodes.AUTH_OK: - // Authentication successful - return; - - case PgCodes.AUTH_KERBEROS_V4: - // Kerberos V4 authentication is required - break; - - case PgCodes.AUTH_KERBEROS_V5: - // Kerberos V5 authentication is required - break; - - case PgCodes.AUTH_CLEARTEXT_PASSWORD: - // Cleartext password is required - outPacket.WriteNullString(this.options.Password); - break; - - case PgCodes.AUTH_CRYPT_PASSWORD: - // crypt()-encrypted password is required - break; - - case PgCodes.AUTH_MD5_PASSWORD: - // MD5-encrypted password is required - - // First read salt to use when encrypting the password - byte[] salt = packet.ReadBytes(4); - - // Second calculate md5 of password + user - string userHash = MD5Authentication.GetMD5Hash( - this.Encoding.GetBytes(this.options.UserID), this.options.Password); - - // Third calculate real MD5 hash - string hash = MD5Authentication.GetMD5Hash(salt, userHash); - - // Finally write the md5 hash to the packet - outPacket.WriteNullString(PgCodes.MD5_PREFIX + hash); - break; - - case PgCodes.AUTH_SCM_CREDENTIAL: - // SCM credentials message is required - break; - } - - // Send the packet to the server - this.SendPacket(outPacket, PgFrontEndCodes.PASSWORD_MESSAGE); - } - - private PgClientException ProcessErrorPacket(PgResponsePacket packet) - { - char type = ' '; - PgClientError error = new PgClientError(); - - while (type != PgErrorCodes.END) - { - type = packet.ReadChar(); - switch (type) - { - case PgErrorCodes.SEVERITY: - error.Severity = packet.ReadNullString(); - break; - - case PgErrorCodes.CODE: - error.Code = packet.ReadNullString(); - break; - - case PgErrorCodes.MESSAGE: - error.Message = packet.ReadNullString(); - break; - - case PgErrorCodes.DETAIL: - error.Detail = packet.ReadNullString(); - break; - - case PgErrorCodes.HINT: - error.Hint = packet.ReadNullString(); - break; - - case PgErrorCodes.POSITION: - error.Position = packet.ReadNullString(); - break; - - case PgErrorCodes.WHERE: - error.Where = packet.ReadNullString(); - break; - - case PgErrorCodes.FILE: - error.File = packet.ReadNullString(); - break; - - case PgErrorCodes.LINE: - error.Line = Convert.ToInt32(packet.ReadNullString()); - break; - - case PgErrorCodes.ROUTINE: - error.Routine = packet.ReadNullString(); - break; - } - } - - PgClientException exception = new PgClientException(error.Message); - - exception.Errors.Add(error); - - return exception; - } - - private void ProcessNotificationResponse(PgResponsePacket packet) - { - int processID = packet.ReadInt32(); - string condition = packet.ReadNullString(); - string additional = packet.ReadNullString(); - - if (this.Notification != null) - { - this.Notification(processID, condition, additional); - } - } - - #endregion - - #region \xB7 Transaction Methods \xB7 - - public void BeginTransaction(IsolationLevel isolationLevel) - { - string sql = "START TRANSACTION ISOLATION LEVEL "; - - switch (isolationLevel) - { - case IsolationLevel.ReadCommitted: - sql += "READ COMMITTED"; - break; - - case IsolationLevel.ReadUncommitted: - throw new NotSupportedException("Read uncommitted transaction isolation is not supported"); - - case IsolationLevel.RepeatableRead: - throw new NotSupportedException("Repeatable read transaction isolation is not supported"); - - case IsolationLevel.Serializable: - sql += "SERIALIZABLE"; - break; - } - - PgStatement stmt = CreateStatement(sql); - stmt.Query(); - - if (stmt.Tag != "START TRANSACTION") - { - throw new PgClientException("A transaction is currently active. Parallel transactions are not supported."); - } - - this.transactionStatus = stmt.TransactionStatus; - } - - public void CommitTransaction() - { - PgStatement stmt = CreateStatement("COMMIT TRANSACTION"); - stmt.Query(); - - if (stmt.Tag != "COMMIT") - { - throw new PgClientException("There are no transaction for commit."); - } - - this.transactionStatus = stmt.TransactionStatus; - } - - public void RollbackTransction() - { - PgStatement stmt = CreateStatement("ROLLBACK TRANSACTION"); - stmt.Query(); - - if (stmt.Tag != "ROLLBACK") - { - throw new PgClientException("There are no transaction for rollback."); - } - - this.transactionStatus = stmt.TransactionStatus; - } - - #endregion - - #region \xB7 Client Methods \xB7 - - public void Flush() - { - lock (this) - { - try - { - PgOutputPacket packet = new PgOutputPacket(this.Encoding); - - // Send packet to the server - this.SendPacket(packet, PgFrontEndCodes.FLUSH); - } - catch (Exception) - { - throw; - } - } - } - - public void Sync() - { - lock (this) - { - try - { - PgOutputPacket packet = new PgOutputPacket(this.Encoding); - - // Send packet to the server - this.SendPacket(packet, PgFrontEndCodes.SYNC); - - // Receive response - PgResponsePacket response = null; - - do - { - response = this.ReceiveResponsePacket(); - this.ProcessResponsePacket(response); - } - while (!response.IsReadyForQuery); - } - catch - { - PgResponsePacket response = null; - - do - { - response = this.ReceiveResponsePacket(); - this.ProcessResponsePacket(response); - } - while (!response.IsReadyForQuery); - - throw; - } - } - } - - public void CancelRequest() - { - lock (this) - { - try - { - PgOutputPacket packet = new PgOutputPacket(); - - packet.Write((int)16); - packet.Write(PgCodes.CANCEL_REQUEST); - packet.Write(this.Handle); - packet.Write(this.SecretKey); - - // Send packet to the server - this.SendSimplePacket(packet); - } - catch (Exception) - { - throw; - } - } - } - - public bool SslRequest() - { - bool sslAvailable = false; - - lock (this) - { - try - { - PgOutputPacket packet = new PgOutputPacket(); - - packet.Write(PgCodes.SSL_REQUEST); - - // Send packet to the server - this.SendSimplePacket(packet); - - // Receive server response - switch (Convert.ToChar(this.networkStream.ReadByte())) - { - case 'S': - sslAvailable = true; - break; - - default: - sslAvailable = false; - break; - } - } - catch - { - throw; - } - } - - return sslAvailable; - } - - #endregion - - #region \xB7 Methods \xB7 - - public void SendInfoMessage(PgClientException exception) - { - if (this.InfoMessage != null) - { - this.InfoMessage(exception); - } - } - - public PgStatement CreateStatement() - { - return new PgStatement(this); - } - - public PgStatement CreateStatement(string stmtText) - { - return new PgStatement(this, stmtText); - } - - public PgStatement CreateStatement(string parseName, string portalName) - { - return new PgStatement(this, parseName, portalName); - } - - public PgStatement CreateStatement(string parseName, string portalName, string stmtText) - { - return new PgStatement(this, parseName, portalName, stmtText); - } - - #endregion - - #region \xB7 Private Methods \xB7 - - private void InitializeSocket() - { - IPAddress hostadd = Dns.GetHostEntry(this.options.DataSource).AddressList[0]; - - this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - // Set Receive Buffer size. - this.socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, this.options.PacketSize); - - // Set Send Buffer size. - this.socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, this.options.PacketSize); - - // Disables the Nagle algorithm for send coalescing. - this.socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1); - - // Make the socket to connect to the Server - this.socket.Connect(new IPEndPoint(hostadd, this.options.PortNumber)); - this.networkStream = new NetworkStream(socket, true); - - // Create objects for read & write - this.receive = new BinaryReader(new BufferedStream(this.networkStream)); - this.send = new BinaryWriter(new BufferedStream(this.networkStream)); - - // The socket and stream shouldn't be automatically collected by the GC - GC.SuppressFinalize(this.socket); - GC.SuppressFinalize(this.networkStream); - GC.SuppressFinalize(this.receive); - GC.SuppressFinalize(this.send); - } - - private void Detach() - { - // Close streams - if (this.secureStream != null) - { - try - { - this.secureStream.Close(); - } - catch - { - } - } - if (this.networkStream != null) - { - this.networkStream.Close(); - } - if (this.socket != null) - { - this.socket.Close(); - } - } - - #endregion - } -} Modified: pgsqlclient/source/PostgreSql/Data/Protocol/PgOutputPacket.cs =================================================================== --- pgsqlclient/source/PostgreSql/Data/Protocol/PgOutputPacket.cs 2006-03-13 21:42:55 UTC (rev 22) +++ pgsqlclient/source/PostgreSql/Data/Protocol/PgOutputPacket.cs 2006-03-13 21:45:11 UTC (rev 23) @@ -271,7 +271,7 @@ System.Array array = (System.Array)parameter.Value; // Get array elements type info - PgType elementType = PgDbClient.DataTypes[parameter.DataType.ElementType]; + PgType elementType = PgDatabase.DataTypes[parameter.DataType.ElementType]; size = elementType.Size; // Create a new packet for write array parameter information Modified: pgsqlclient/source/PostgreSql/Data/Protocol/PgParameter.cs =================================================================== --- pgsqlclient/source/PostgreSql/Data/Protocol/PgParameter.cs 2006-03-13 21:42:55 UTC (rev 22) +++ pgsqlclient/source/PostgreSql/Data/Protocol/PgParameter.cs 2006-03-13 21:45:11 UTC (rev 23) @@ -52,7 +52,7 @@ public PgParameter(int dataType) { - this.dataType = PgDbClient.DataTypes[dataType]; + this.dataType = PgDatabase.DataTypes[dataType]; } public PgParameter(int dataType, object data) : this(dataType) Modified: pgsqlclient/source/PostgreSql/Data/Protocol/PgResponsePacket.cs =================================================================== --- pgsqlclient/source/PostgreSql/Data/Protocol/PgResponsePacket.cs 2006-03-13 21:42:55 UTC (rev 22) +++ pgsqlclient/source/PostgreSql/Data/Protocol/PgResponsePacket.cs 2006-03-13 21:45:11 UTC (rev 23) @@ -283,7 +283,7 @@ } // Read array element type - PgType elementType = PgDbClient.DataTypes[this.ReadInt32()]; + PgType elementType = PgDatabase.DataTypes[this.ReadInt32()]; // Read array lengths and lower bounds for (int i = 0; i < dimensions; i++) @@ -306,7 +306,7 @@ public Array ReadVector(PgType type, int length) { - PgType elementType = PgDbClient.DataTypes[type.ElementType]; + PgType elementType = PgDatabase.DataTypes[type.ElementType]; Array data = null; data = Array.CreateInstance(elementType.SystemType, PgCodes.INDEX_MAX_KEYS); @@ -592,7 +592,7 @@ private Array ReadStringArray(PgType type, int length) { - PgType elementType = PgDbClient.DataTypes[type.ElementType]; + PgType elementType = PgDatabase.DataTypes[type.ElementType]; Array data = null; string contents = ReadString(length); Modified: pgsqlclient/source/PostgreSql/Data/Protocol/PgStatement.cs =================================================================== --- pgsqlclient/source/PostgreSql/Data/Protocol/PgStatement.cs 2006-03-13 21:42:55 UTC (rev 22) +++ pgsqlclient/source/PostgreSql/Data/Protocol/PgStatement.cs 2006-03-13 21:45:11 UTC (rev 23) @@ -26,8 +26,7 @@ { #region \xB7 Fields \xB7 - private PgDbClient db; - + private PgDatabase db; private string stmtText; private bool hasRows; private string tag; @@ -49,7 +48,7 @@ #region \xB7 Properties \xB7 - public PgDbClient DbHandle + public PgDatabase DbHandle { get { return this.db; } set { this.db = value; } @@ -127,15 +126,18 @@ { } - public PgStatement(PgDbClient db) : this(db, null, null) + public PgStatement(PgDatabase db) + : this(db, null, null) { } - public PgStatement(PgDbClient db, string parseName, string portalName) : this(db, parseName, portalName, null) + public PgStatement(PgDatabase db, string parseName, string portalName) + : this(db, parseName, portalName, null) { } - public PgStatement(PgDbClient db, string stmtText) : this(db, null, null, stmtText) + public PgStatement(PgDatabase db, string stmtText) + : this(db, null, null, stmtText) { } @@ -143,7 +145,7 @@ { } - public PgStatement(PgDbClient db, string parseName, string portalName, string stmtText) + public PgStatement(PgDatabase db, string parseName, string portalName, string stmtText) { this.db = db; this.outParameter = new PgParameter(); @@ -698,7 +700,7 @@ this.rowDescriptor.Fields[i].FieldName = packet.ReadNullString(); this.rowDescriptor.Fields[i].OidTable = packet.ReadInt32(); this.rowDescriptor.Fields[i].OidNumber = packet.ReadInt16(); - this.rowDescriptor.Fields[i].DataType = PgDbClient.DataTypes[packet.ReadInt32()]; + this.rowDescriptor.Fields[i].DataType = PgDatabase.DataTypes[packet.ReadInt32()]; this.rowDescriptor.Fields[i].DataTypeSize = packet.ReadInt16(); this.rowDescriptor.Fields[i].TypeModifier = packet.ReadInt32(); this.rowDescriptor.Fields[i].FormatCode = (PgTypeFormat)packet.ReadInt16(); Modified: pgsqlclient/source/PostgreSql/Data/Protocol/PgType.cs =================================================================== --- pgsqlclient/source/PostgreSql/Data/Protocol/PgType.cs 2006-03-13 21:42:55 UTC (rev 22) +++ pgsqlclient/source/PostgreSql/Data/Protocol/PgType.cs 2006-03-13 21:45:11 UTC (rev 23) @@ -62,9 +62,9 @@ { int type = elementType; - while (PgDbClient.DataTypes[type].DataType == PgDataType.Array) + while (PgDatabase.DataTypes[type].DataType == PgDataType.Array) { - type = PgDbClient.DataTypes[type].ElementType; + type = PgDatabase.DataTypes[type].ElementType; } return type; Modified: pgsqlclient/source/PostgreSql.Data.PostgreSqlClient.suo =================================================================== (Binary files differ) Modified: pgsqlclient/source/SecureSocketLayer/SecureSocketLayer.csproj =================================================================== --- pgsqlclient/source/SecureSocketLayer/SecureSocketLayer.csproj 2006-03-13 21:42:55 UTC (rev 22) +++ pgsqlclient/source/SecureSocketLayer/SecureSocketLayer.csproj 2006-03-13 21:45:11 UTC (rev 23) @@ -11,8 +11,7 @@ <AssemblyKeyContainerName> </AssemblyKeyContainerName> <AssemblyName>SecureSocketLayer</AssemblyName> - <AssemblyOriginatorKeyFile> - </AssemblyOriginatorKeyFile> + <AssemblyOriginatorKeyFile>SecureSocketLayer.snk</AssemblyOriginatorKeyFile> <DefaultClientScript>JScript</DefaultClientScript> <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout> <DefaultTargetSchema>IE50</DefaultTargetSchema> @@ -26,6 +25,7 @@ </FileUpgradeFlags> <UpgradeBackupLocation> </UpgradeBackupLocation> + <SignAssembly>true</SignAssembly> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <OutputPath>bin\Debug\</OutputPath>... [truncated message content] |