[pgsqlclient-checkins] pgsqlclient_10/source/PostgreSql/Data/Protocol InfoMessageCallback.cs,NONE,1.
Status: Inactive
Brought to you by:
carlosga_fb
Update of /cvsroot/pgsqlclient/pgsqlclient_10/source/PostgreSql/Data/Protocol In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7345/Data/Protocol Added Files: InfoMessageCallback.cs NotificationCallback.cs PgAuthMethods.cs PgBackendCodes.cs PgCharSet.cs PgCharSetCollection.cs PgClientError.cs PgClientErrorCollection.cs PgClientException.cs PgClientMessageEventArgs.cs PgClientMessageEventHandler.cs PgClientNotificationEventArgs.cs PgClientNotificationEventHandler.cs PgCodes.cs PgConnectionParams.cs PgDataType.cs PgDbClient.cs PgErrorCodes.cs PgFieldDescriptor.cs PgFrontEndCodes.cs PgOutputPacket.cs PgParameter.cs PgResponsePacket.cs PgRowDescriptor.cs PgStatement.cs PgStatementStatus.cs PgType.cs PgTypeCollection.cs PgTypeFormat.cs PgTypeStringFormats.cs SslConnectionCallback.cs Log Message: Started the reorganization of the CVS module --- NEW FILE: PgTypeFormat.cs --- (This appears to be a binary file; contents omitted.) --- NEW FILE: PgStatement.cs --- /* PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ * Copyright (c) 2003-2005 Carlos Guzman Alvarez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ using System; using System.Text; using System.Data; using System.Collections; namespace PostgreSql.Data.Protocol { internal class PgStatement { #region · Fields · private PgDbClient db; private string stmtText; private bool hasRows; private string tag; private string parseName; private string portalName; private int fetchSize; private bool allRowsFetched; private PgRowDescriptor rowDescriptor; private object[] rows; private int rowIndex; private PgParameter[] parameters; private PgParameter outParameter; private int recordsAffected; private char transactionStatus; private PgStatementStatus status; #endregion #region · Properties · public PgDbClient DbHandle { get { return this.db; } set { this.db = value; } } public string StmtText { get { return this.stmtText; } set { this.stmtText = value; } } public bool HasRows { get { return this.hasRows; } } public string Tag { get { return this.tag; } } public string ParseName { get { return this.parseName; } set { this.parseName = value; } } public string PortalName { get { return this.portalName; } set { this.portalName = value; } } public PgRowDescriptor RowDescriptor { get { return this.rowDescriptor; } } public object[] Rows { get { return this.rows; } } public PgParameter[] Parameters { get { return this.parameters; } } public PgParameter OutParameter { get { return this.outParameter; } set { this.outParameter = value; } } public int RecordsAffected { get { return this.recordsAffected; } } public PgStatementStatus Status { get { return this.status; } } public char TransactionStatus { get { return this.transactionStatus; } } #endregion #region · Constructors · public PgStatement() : this(null) { } public PgStatement(PgDbClient db) : this(db, null, null) { } public PgStatement(PgDbClient db, string parseName, string portalName) : this(db, parseName, portalName, null) { } public PgStatement(PgDbClient db, string stmtText) : this(db, null, null, stmtText) { } public PgStatement(string parseName, string portalName) : this(null, parseName, portalName, null) { } public PgStatement(PgDbClient db, string parseName, string portalName, string stmtText) { this.db = db; this.outParameter = new PgParameter(); this.rows = null; this.rowIndex = 0; this.parseName = parseName; this.portalName = portalName; this.recordsAffected = -1; this.status = PgStatementStatus.Initial; this.fetchSize = 200; this.stmtText = stmtText; GC.SuppressFinalize(this); } #endregion #region · Methods · public void Parse() { lock (this.db) { try { // Clear actual row list this.rows = null; this.rowIndex = 0; // Initialize RowDescriptor and Parameters this.rowDescriptor = new PgRowDescriptor(0); this.parameters = new PgParameter[0]; PgOutputPacket packet = new PgOutputPacket(this.db.Settings.Encoding); packet.WriteNullString(this.ParseName); packet.WriteNullString(this.stmtText); packet.WriteShort(0); // Send packet to the server this.db.SendPacket(packet, PgFrontEndCodes.PARSE); // Update status this.status = PgStatementStatus.Parsed; } catch (PgClientException) { // Update status this.status = PgStatementStatus.Error; // Throw exception throw; } } } public void Describe() { this.Describe('S'); } public void DescribePortal() { this.Describe('P'); } private void Describe(char stmtType) { lock (this.db) { try { string name = ((stmtType == 'S') ? this.ParseName : this.PortalName); PgOutputPacket packet = new PgOutputPacket(this.db.Settings.Encoding); packet.Write((byte)stmtType); packet.WriteNullString(name); // Send packet to the server this.db.SendPacket(packet, PgFrontEndCodes.DESCRIBE); // Flush pending messages this.db.Flush(); // Receive Describe response PgResponsePacket response = new PgResponsePacket(); while ((response.Message != PgBackendCodes.ROW_DESCRIPTION && response.Message != PgBackendCodes.NODATA)) { response = this.db.ReceiveResponsePacket(); this.ProcessSqlPacket(response); } // Update status this.status = PgStatementStatus.Described; } catch (Exception) { // Update status this.status = PgStatementStatus.Error; // Throw exception throw; } } } public void Bind() { lock (this.db) { try { PgOutputPacket packet = new PgOutputPacket(this.db.Settings.Encoding); // Destination portal name packet.WriteNullString(this.PortalName); // Prepared statement name packet.WriteNullString(this.ParseName); // Send parameters format code. packet.WriteShort((short)parameters.Length); for (int i = 0; i < parameters.Length; i++) { packet.WriteShort((short)this.parameters[i].DataType.FormatCode); } // Send parameter values packet.WriteShort((short)parameters.Length); for (int i = 0; i < parameters.Length; i++) { packet.WriteParameter(this.parameters[i]); } // Send column information packet.WriteShort((short)this.rowDescriptor.Fields.Length); for (int i = 0; i < this.rowDescriptor.Fields.Length; i++) { packet.WriteShort((short)this.rowDescriptor.Fields[i].DataType.FormatCode); } // Send packet to the server this.db.SendPacket(packet, PgFrontEndCodes.BIND); // Update status this.status = PgStatementStatus.Parsed; } catch (Exception) { // Update status this.status = PgStatementStatus.Error; // Throw exception throw; } } } public void Execute() { lock (this.db) { try { PgOutputPacket packet = new PgOutputPacket(this.db.Settings.Encoding); packet.WriteNullString(this.PortalName); packet.WriteInt(this.fetchSize); // Rows to retrieve ( 0 = nolimit ) // Send packet to the server this.db.SendPacket(packet, PgFrontEndCodes.EXECUTE); // Flush pending messages this.db.Flush(); // Receive response PgResponsePacket response = new PgResponsePacket(); while (response.Message != PgBackendCodes.READY_FOR_QUERY && response.Message != PgBackendCodes.PORTAL_SUSPENDED && response.Message != PgBackendCodes.COMMAND_COMPLETE) { response = this.db.ReceiveResponsePacket(); this.ProcessSqlPacket(response); } // reset rowIndex this.rowIndex = 0; // If the command is finished and has returned rows // set all rows are received if ((response.Message == PgBackendCodes.READY_FOR_QUERY || response.Message == PgBackendCodes.COMMAND_COMPLETE) && this.hasRows) { this.allRowsFetched = true; } // If all rows are received or the command doesn't return // rows perform a Sync. if (!this.hasRows || this.allRowsFetched) { this.db.Sync(); } // Update status this.status = PgStatementStatus.Executed; } catch (Exception) { // Update status this.status = PgStatementStatus.Error; // Throw exception throw; } } } public void ExecuteFunction(int id) { lock (this.db) { try { PgOutputPacket packet = new PgOutputPacket(this.db.Settings.Encoding); // Function id packet.WriteInt(id); // Send parameters format code. packet.WriteShort((short)this.parameters.Length); for (int i = 0; i < this.parameters.Length; i++) { packet.WriteShort((short)this.parameters[i].DataType.FormatCode); } // Send parameter values packet.WriteShort((short)this.parameters.Length); for (int i = 0; i < this.parameters.Length; i++) { packet.WriteParameter(this.parameters[i]); } // Send the format code for the function result packet.WriteShort(PgCodes.BINARY_FORMAT); // Send packet to the server this.db.SendPacket(packet, PgFrontEndCodes.FUNCTION_CALL); // Receive response PgResponsePacket response = new PgResponsePacket(); while (response.Message != PgBackendCodes.READY_FOR_QUERY) { response = this.db.ReceiveResponsePacket(); this.ProcessSqlPacket(response); } // Update status this.status = PgStatementStatus.Executed; } catch (Exception) { // Update status this.status = PgStatementStatus.Error; // Throw exception throw; } } } public void Query() { ArrayList innerRows = new ArrayList(); lock (this.db) { try { PgOutputPacket packet = new PgOutputPacket(this.db.Settings.Encoding); packet.WriteNullString(this.stmtText); // Send packet to the server this.db.SendPacket(packet, PgFrontEndCodes.QUERY); // Update Status this.status = PgStatementStatus.OnQuery; // Set fetch size this.fetchSize = 1; // Receive response PgResponsePacket response = new PgResponsePacket(); while (response.Message != PgBackendCodes.READY_FOR_QUERY) { response = this.db.ReceiveResponsePacket(); this.ProcessSqlPacket(response); if (this.hasRows && response.Message == PgBackendCodes.DATAROW) { innerRows.Add(this.rows[0]); this.rowIndex = 0; } } if (this.hasRows) { // Obtain all the rows this.rows = (object[])innerRows.ToArray(typeof(object)); // reset rowIndex this.rowIndex = 0; // Set allRowsFetched flag this.allRowsFetched = true; } // reset fetch size this.fetchSize = 200; // Update status this.status = PgStatementStatus.Executed; } catch (Exception) { // Update status this.status = PgStatementStatus.Error; // Throw exception throw; } } } public object[] FetchRow() { object[] row = null; if ((!this.allRowsFetched && this.rows == null) || (!this.allRowsFetched && this.rows.Length == 0) || (!this.allRowsFetched && this.rowIndex >= this.fetchSize)) { lock (this) { // Retrieve next group of rows this.Execute(); } } if (this.rows != null && this.rows.Length > 0 && this.rows[this.rowIndex] != null) { // Return always first row row = (object[])this.rows[this.rowIndex++]; } if (this.rows != null && (this.rowIndex >= this.fetchSize || this.rowIndex >= this.rows.Length || this.rows[this.rowIndex] == null)) { this.rows = null; } return row; } public void Close() { this.Close('S'); } public void ClosePortal() { this.Close('P'); } private void Close(char stmtType) { lock (this.db) { try { string name = ((stmtType == 'S') ? this.ParseName : this.PortalName); PgOutputPacket packet = new PgOutputPacket(this.db.Settings.Encoding); packet.Write((byte)stmtType); packet.WriteNullString(name); // Send packet to the server this.db.SendPacket(packet, PgFrontEndCodes.CLOSE); // Sync server and client this.db.Flush(); // Read until CLOSE COMPLETE message is received PgResponsePacket response = new PgResponsePacket(); while (response.Message != PgBackendCodes.CLOSE_COMPLETE) { response = this.db.ReceiveResponsePacket(); this.ProcessSqlPacket(response); } // Clear rows this.rows = null; this.rowIndex = 0; // Update Status this.status = PgStatementStatus.Initial; } catch (Exception) { // Update Status this.status = PgStatementStatus.Error; // Throw exception throw; } } } #endregion #region · Misc Methods · public string GetPlan(bool verbose) { lock (db) { try { PgStatement getPlan = new PgStatement(); getPlan.DbHandle = this.db; getPlan.StmtText = "EXPLAIN ANALYZE "; if (verbose) { getPlan.StmtText += "VERBOSE "; } getPlan.StmtText += stmtText; getPlan.Query(); StringBuilder stmtPlan = new StringBuilder(); foreach (object[] row in getPlan.Rows) { stmtPlan.AppendFormat("{0} \r\n", row[0]); } getPlan.Close(); return stmtPlan.ToString(); } catch (PgClientException) { throw; } } } #endregion #region · Response Methods · private void ProcessSqlPacket(PgResponsePacket packet) { switch (packet.Message) { case PgBackendCodes.READY_FOR_QUERY: this.transactionStatus = packet.ReadChar(); break; case PgBackendCodes.FUNCTION_CALL_RESPONSE: this.ProcessFunctionResult(packet); break; case PgBackendCodes.ROW_DESCRIPTION: this.ProcessRowDescription(packet); break; case PgBackendCodes.DATAROW: this.hasRows = true; this.ProcessDataRow(packet); break; case PgBackendCodes.EMPTY_QUERY_RESPONSE: case PgBackendCodes.NODATA: this.hasRows = false; this.rows = null; this.rowIndex = 0; break; case PgBackendCodes.COMMAND_COMPLETE: this.ProcessTag(packet); break; case PgBackendCodes.PARAMETER_DESCRIPTION: this.ProcessParameterDescription(packet); break; case PgBackendCodes.BIND_COMPLETE: case PgBackendCodes.PARSE_COMPLETE: case PgBackendCodes.CLOSE_COMPLETE: break; } } private void ProcessTag(PgResponsePacket packet) { string[] elements = null; tag = packet.ReadNullString(); elements = tag.Split(' '); switch (elements[0]) { case "FETCH": case "SELECT": this.recordsAffected = -1; break; case "INSERT": this.recordsAffected = Int32.Parse(elements[2]); break; case "UPDATE": case "DELETE": case "MOVE": this.recordsAffected = Int32.Parse(elements[1]); break; } } private void ProcessFunctionResult(PgResponsePacket packet) { int length = packet.ReadInt(); outParameter.Value = packet.ReadValue(outParameter.DataType, length); } private void ProcessRowDescription(PgResponsePacket packet) { this.rowDescriptor = new PgRowDescriptor(packet.ReadShort()); for (int i = 0; i < rowDescriptor.Fields.Length; i++) { this.rowDescriptor.Fields[i] = new PgFieldDescriptor(); this.rowDescriptor.Fields[i].FieldName = packet.ReadNullString(); this.rowDescriptor.Fields[i].OidTable = packet.ReadInt(); this.rowDescriptor.Fields[i].OidNumber = packet.ReadShort(); this.rowDescriptor.Fields[i].DataType = PgDbClient.Types[packet.ReadInt()]; this.rowDescriptor.Fields[i].DataTypeSize = packet.ReadShort(); this.rowDescriptor.Fields[i].TypeModifier = packet.ReadInt(); this.rowDescriptor.Fields[i].FormatCode = (PgTypeFormat)packet.ReadShort(); } } private void ProcessParameterDescription(PgResponsePacket packet) { this.parameters = new PgParameter[packet.ReadShort()]; for (int i = 0; i < parameters.Length; i++) { this.parameters[i] = new PgParameter(packet.ReadInt()); } } private void ProcessDataRow(PgResponsePacket packet) { int fieldCount = packet.ReadShort(); object[] values = new object[fieldCount]; if (this.rows == null) { this.rows = new object[fetchSize]; this.rowIndex = 0; } for (int i = 0; i < values.Length; i++) { int length = packet.ReadInt(); switch (length) { case -1: values[i] = System.DBNull.Value; break; default: if (this.status == PgStatementStatus.OnQuery) { values[i] = packet.ReadValueFromString( this.rowDescriptor.Fields[i].DataType, length); } else { values[i] = packet.ReadValue( this.rowDescriptor.Fields[i].DataType, length); } break; } } this.rows[this.rowIndex++] = values; } #endregion } } --- NEW FILE: PgOutputPacket.cs --- /* PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ * Copyright (c) 2003-2005 Carlos Guzman Alvarez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ using System; using System.Data; using System.Net; using System.IO; using System.Text; using System.Globalization; using PostgreSql.Data.PgTypes; namespace PostgreSql.Data.Protocol { internal class PgOutputPacket : BinaryWriter { #region · Fields · private Encoding encoding; #endregion #region · Properties · public long Position { get { return ((MemoryStream)this.BaseStream).Position; } } public long Length { get { return ((MemoryStream)this.BaseStream).Length; } } #endregion #region · Constructors · public PgOutputPacket() : base(new MemoryStream()) { this.encoding = Encoding.Default; this.Write(new byte[0]); } public PgOutputPacket(Encoding encoding) : base(new MemoryStream(), encoding) { this.encoding = encoding; this.Write(new byte[0]); } #endregion #region · Stream Methods · public int GetByteCount() { return (int)((MemoryStream)this.BaseStream).Length; } public byte[] ToArray() { return ((MemoryStream)this.BaseStream).ToArray(); } public void Reset() { ((MemoryStream)this.BaseStream).SetLength(0); ((MemoryStream)this.BaseStream).Position = 0; } #endregion #region · String Types · public void WriteNullString(string data) { if (!data.EndsWith(PgCodes.NULL_TERMINATOR.ToString())) { data += PgCodes.NULL_TERMINATOR; } this.Write(this.encoding.GetBytes(data)); } public void WriteString(string data) { byte[] buffer = this.encoding.GetBytes(data); this.WriteInt(buffer.Length); this.Write(buffer); } #endregion #region · Numeric Types · public void WriteShort(short val) { this.Write((short)IPAddress.HostToNetworkOrder(val)); } public void WriteInt(int val) { this.Write((int)IPAddress.HostToNetworkOrder(val)); } public void WriteLong(long val) { this.Write((long)IPAddress.HostToNetworkOrder(val)); } public void WriteFloat(float val) { byte[] buffer = BitConverter.GetBytes(val); this.Write(BitConverter.ToInt32(buffer, 0)); } public void WriteDouble(double val) { byte[] buffer = BitConverter.GetBytes(val); this.WriteLong(BitConverter.ToInt64(buffer, 0)); } #endregion #region · Date & Time Types · public void WriteDate(DateTime date) { TimeSpan days = date.Subtract(PgCodes.BASE_DATE); this.WriteInt(days.Days); } public void WriteInterval(TimeSpan interval) { int months = (interval.Days / 30); int days = (interval.Days % 30); this.WriteDouble(interval.Subtract(TimeSpan.FromDays(months * 30)).TotalSeconds); this.WriteInt(months); } public void WriteTime(DateTime time) { this.WriteString(time.ToString("HH:mm:ss.fff")); } public void WriteTimeWithTZ(DateTime time) { this.WriteString(time.ToString("HH:mm:ss.fff zz")); } public void WriteTimestamp(DateTime timestamp) { this.WriteString(timestamp.ToString("yyyy/MM/dd HH:mm:ss.fff")); } public void WriteTimestampWithTZ(DateTime timestamp) { this.WriteString(timestamp.ToString("yyyy/MM/dd HH:mm:ss.fff zz")); } #endregion #region · Geometric Types · public void WritePoint(PgPoint point) { this.WriteDouble(point.X); this.WriteDouble(point.Y); } public void WriteCircle(PgCircle circle) { this.WritePoint(circle.Center); this.WriteDouble(circle.Radius); } public void WriteLine(PgLine line) { this.WritePoint(line.StartPoint); this.WritePoint(line.EndPoint); } public void WriteLSeg(PgLSeg lseg) { this.WritePoint(lseg.StartPoint); this.WritePoint(lseg.EndPoint); } public void WriteBox(PgBox box) { this.WritePoint(box.UpperRight); this.WritePoint(box.LowerLeft); } public void WritePolygon(PgPolygon polygon) { this.WriteInt(polygon.Points.Length); for (int i = 0; i < polygon.Points.Length; i++) { this.WritePoint(polygon.Points[i]); } } public void WritePath(PgPath path) { this.Write(path.IsClosedPath); this.WriteInt(path.Points.Length); for (int i = 0; i < path.Points.Length; i++) { this.WritePoint(path.Points[i]); } } #endregion #region · Parameters · public void WriteParameter(PgParameter parameter) { int size = parameter.DataType.Size; if (parameter.Value == System.DBNull.Value || parameter.Value == null) { // -1 indicates a NULL argument value this.WriteInt(-1); } else { if (parameter.DataType.DataType == PgDataType.Array || parameter.DataType.DataType == PgDataType.Vector) { // Handle this type as Array values System.Array array = (System.Array)parameter.Value; // Get array elements type info PgType elementType = PgDbClient.Types[parameter.DataType.ElementType]; size = elementType.Size; // Create a new packet for write array parameter information PgOutputPacket packet = new PgOutputPacket(); // Write the number of dimensions packet.WriteInt(array.Rank); // Write flags (always 0) packet.WriteInt(0); // Write base type of the array elements packet.WriteInt(parameter.DataType.ElementType); // Write lengths and lower bounds for (int i = 0; i < array.Rank; i ++) { packet.WriteInt(array.GetLength(i)); packet.WriteInt(array.GetLowerBound(i) + 1); } // Write array values foreach (object element in array) { this.WriteParameter(packet, elementType.DataType, size, element); } // Write parameter size this.WriteInt(packet.GetByteCount()); // Write parameter data this.Write(packet.ToArray()); } else { this.WriteParameter(this, parameter.DataType.DataType, size, parameter.Value); } } } #endregion #region · Packet Methods · public byte[] GetSimplePacketBytes() { PgOutputPacket packet = new PgOutputPacket(); // Write packet contents packet.WriteInt(GetByteCount() + 4); packet.Write(ToArray()); return packet.ToArray(); } public byte[] GetPacketBytes(char format) { PgOutputPacket packet = new PgOutputPacket(); packet.Write((byte)format); packet.WriteInt(GetByteCount() + 4); packet.Write(ToArray()); return packet.ToArray(); } #endregion #region · Private Methods · private void WriteParameter(PgOutputPacket packet, PgDataType dataType, int size, object value) { switch (dataType) { case PgDataType.Binary: packet.WriteInt(((byte[])value).Length); packet.Write((byte[])value); break; case PgDataType.Byte: packet.WriteInt(size); packet.Write((byte)value); break; case PgDataType.Boolean: packet.WriteInt(size); packet.Write(Convert.ToByte((bool)value)); break; case PgDataType.Char: case PgDataType.VarChar: { string paramValue = value.ToString() + PgCodes.NULL_TERMINATOR; packet.WriteString(paramValue); } break; case PgDataType.Int2: packet.WriteInt(size); packet.WriteShort(Convert.ToInt16(value)); break; case PgDataType.Int4: packet.WriteInt(size); packet.WriteInt(Convert.ToInt32(value)); break; case PgDataType.Int8: packet.WriteInt(size); packet.WriteLong(Convert.ToInt64(value)); break; case PgDataType.Interval: packet.WriteInt(size); packet.WriteInterval(TimeSpan.Parse(value.ToString())); break; case PgDataType.Decimal: { string paramValue = value.ToString(); packet.WriteInt(encoding.GetByteCount(paramValue)); packet.Write(paramValue.ToCharArray()); } break; case PgDataType.Double: packet.WriteInt(size); packet.WriteDouble(Convert.ToDouble(value)); break; case PgDataType.Float: packet.WriteInt(size); packet.WriteFloat(Convert.ToSingle(value)); break; case PgDataType.Currency: packet.WriteInt(size); packet.WriteInt(Convert.ToInt32(Convert.ToSingle(value) * 100)); break; case PgDataType.Date: packet.WriteInt(size); packet.WriteDate(Convert.ToDateTime(value)); break; case PgDataType.Time: packet.WriteTime(Convert.ToDateTime(value)); break; case PgDataType.TimeWithTZ: packet.WriteTimeWithTZ(Convert.ToDateTime(value)); break; case PgDataType.Timestamp: packet.WriteTimestamp(Convert.ToDateTime(value)); break; case PgDataType.TimestampWithTZ: packet.WriteTimestampWithTZ(Convert.ToDateTime(value)); break; case PgDataType.Point: packet.WriteInt(size); packet.WritePoint((PgPoint)value); break; case PgDataType.Circle: packet.WriteInt(size); packet.WriteCircle((PgCircle)value); break; case PgDataType.Line: packet.WriteInt(size); packet.WriteLine((PgLine)value); break; case PgDataType.LSeg: packet.WriteInt(size); packet.WriteLSeg((PgLSeg)value); break; case PgDataType.Box: packet.WriteInt(size); packet.WriteBox((PgBox)value); break; case PgDataType.Polygon: PgPolygon polygon = (PgPolygon)value; packet.WriteInt((size * polygon.Points.Length) + 4); packet.WritePolygon(polygon); break; case PgDataType.Path: PgPath path = (PgPath)value; packet.WriteInt((size * path.Points.Length) + 5); packet.WritePath(path); break; } } #endregion } } --- NEW FILE: PgClientError.cs --- /* PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ * Copyright (c) 2003-2005 Carlos Guzman Alvarez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ using System; namespace PostgreSql.Data.Protocol { internal sealed class PgClientError { #region · Fields · private string severity; private string code; private string message; private string detail; private string hint; private string where; private string position; private string file; private int line; private string routine; #endregion #region · Properties · public string Severity { get { return this.severity; } set { this.severity = value; } } public string Message { get { return this.message; } set { this.message = value; } } public string Code { get { return this.code; } set { this.code = value; } } public string Detail { get { return this.detail; } set { this.detail = value; } } public string Hint { get { return this.hint; } set { this.hint = value; } } public string Where { get { return this.where; } set { this.where = value; } } public string Position { get { return this.position; } set { this.position = value; } } public string File { get { return this.file; } set { this.file = value; } } public int Line { get { return this.line; } set { this.line = value; } } public string Routine { get { return this.routine; } set { this.routine = value; } } #endregion #region · Constructors · public PgClientError() { } public PgClientError(string message) { this.message = message; } public PgClientError(string severity, string code, string message) { this.severity = severity; this.code = code; this.message = message; } #endregion } } --- NEW FILE: PgParameter.cs --- /* PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ * Copyright (c) 2003-2005 Carlos Guzman Alvarez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ using System; namespace PostgreSql.Data.Protocol { internal class PgParameter { #region · Fields · private PgType dataType; private object data; #endregion #region · Properties · public PgType DataType { get { return this.dataType; } set { this.dataType = value; } } public object Value { get { return this.data; } set { this.data = value; } } #endregion #region · Constructors · public PgParameter() { } public PgParameter(int dataType) { this.dataType = PgDbClient.Types[dataType]; } public PgParameter(int dataType, object data) : this(dataType) { this.data = data; } #endregion } } --- NEW FILE: PgBackendCodes.cs --- (This appears to be a binary file; contents omitted.) --- NEW FILE: PgDataType.cs --- /* PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ * Copyright (c) 2003-2005 Carlos Guzman Alvarez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ using System; namespace PostgreSql.Data.Protocol { // This is a exact copy of PgDbType enum for // allow a better and more simple handling of // data types in the protocol implementation. internal enum PgDataType { Array , Binary , Boolean , Box , Byte , Char , Circle , Currency , Date , Decimal , Double , Float , Int2 , Int4 , Int8 , Interval , Line , LSeg , Numeric , Path , Point , Polygon , Text , Time , TimeWithTZ , Timestamp , TimestampWithTZ , VarChar , Vector } } --- NEW FILE: PgResponsePacket.cs --- /* PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ * Copyright (c) 2003-2005 Carlos Guzman Alvarez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ using System; using System.Data; using System.Globalization; using System.IO; using System.Text; using System.Net; using PostgreSql.Data.PgTypes; namespace PostgreSql.Data.Protocol { internal class PgResponsePacket : BinaryReader { #region · Fields · private char message; private Encoding encoding; #endregion #region · Properties · public char Message { get { return this.message; } set { this.message = value; } } public Encoding Encoding { get { return this.encoding; } set { this.encoding = value; } } public long Length { get { return ((MemoryStream)this.BaseStream).Length; } } public long Position { get { return ((MemoryStream)this.BaseStream).Position; } } public bool EOF { get { if (this.Position < this.Length) { return false; } else { return true; } } } public long Pending { get { return this.Length - this.Position; } } #endregion #region · Constructors · public PgResponsePacket() : base(new MemoryStream()) { } public PgResponsePacket(byte[] contents) : base(new MemoryStream(contents)) { } public PgResponsePacket(char message, byte[] contents) : base(new MemoryStream(contents)) { this.message = message; } #endregion #region · Stream Methods · public void Reset() { ((MemoryStream)this.BaseStream).SetLength(0); ((MemoryStream)this.BaseStream).Position = 0; } public byte[] ToArray() { return ((MemoryStream)this.BaseStream).ToArray(); } #endregion #region · String Types · public string ReadNullString() { StringBuilder cString = new StringBuilder(); char c; while ((c = ReadChar()) != PgCodes.NULL_TERMINATOR ) { cString.Append(c); } return cString.ToString(); } public string ReadString(int length) { byte[] buffer = new byte[length]; this.Read(buffer, 0, length); return this.encoding.GetString(buffer); } public new string ReadString() { int length = this.ReadInt(); byte[] buffer = new byte[length]; this.Read(buffer, 0, length); return this.encoding.GetString(buffer); } #endregion #region · Numeric Types · public short ReadShort() { short val = base.ReadInt16(); return IPAddress.HostToNetworkOrder(val); } public int ReadInt() { int val = base.ReadInt32(); return IPAddress.HostToNetworkOrder(val); } public long ReadLong() { return IPAddress.HostToNetworkOrder(base.ReadInt64()); } public override float ReadSingle() { return BitConverter.ToSingle(BitConverter.GetBytes(this.ReadInt()), 0); } public float ReadCurrency() { float val = (float)this.ReadInt(); return val/100; } public override double ReadDouble() { byte[] buffer = BitConverter.GetBytes(this.ReadLong()); return BitConverter.ToDouble(buffer, 0); } #endregion #region · Date & Time Types · public DateTime ReadDate() { int days = this.ReadInt(); DateTime date = new DateTime(days); return PgCodes.BASE_DATE.AddDays(days); } public TimeSpan ReadInterval() { double intervalTime = this.ReadDouble(); int intervalMonth = this.ReadInt(); TimeSpan interval = TimeSpan.FromSeconds(intervalTime); return interval.Add(TimeSpan.FromDays(intervalMonth*30)); } public DateTime ReadTime(int length) { return DateTime.ParseExact(this.ReadString(length), PgTypeStringFormats.TimeFormats, CultureInfo.CurrentCulture, DateTimeStyles.None); } public DateTime ReadTimeWithTZ(int length) { return DateTime.Parse(this.ReadString(length)); } public DateTime ReadTimestamp(int length) { return DateTime.Parse(this.ReadString(length)); } public DateTime ReadTimestampWithTZ(int length) { return DateTime.Parse(this.ReadString(length)); } #endregion #region · Array & Vector Types · public Array ReadArray(PgType type, int length) { if (type.FormatCode == 0) { return this.ReadStringArray(type, length); } else { int[] lengths; int[] lowerBounds; // Read number of dimensions int dimensions = this.ReadInt(); // Initialize arrays for lengths and lower bounds lengths = new int[dimensions]; lowerBounds = new int[dimensions]; // Read flags value int flags = this.ReadInt(); if (flags != 0) { throw new NotSupportedException("Invalid flags value"); } // Read array element type PgType elementType = PgDbClient.Types[this.ReadInt()]; // Read array lengths and lower bounds for (int i = 0; i < dimensions; i++) { lengths[i] = this.ReadInt(); lowerBounds[i] = this.ReadInt(); } // Read Array data if (type.SystemType.IsPrimitive) { return this.ReadPrimitiveArray(elementType, length, dimensions, flags, lengths, lowerBounds); } else { return this.ReadNonPrimitiveArray(elementType, length, dimensions, flags, lengths, lowerBounds); } } } public Array ReadVector(PgType type, int length) { PgType elementType = PgDbClient.Types[type.ElementType]; Array data = null; data = Array.CreateInstance(elementType.SystemType, PgCodes.INDEX_MAX_KEYS); for (int i = 0; i < data.Length; i++ ) { object elementValue = ReadValue(elementType, elementType.Size); data.SetValue(elementValue, i); } return data; } #endregion #region · Geometric Types · public PgPoint ReadPoint() { double x = this.ReadDouble(); double y = this.ReadDouble(); return new PgPoint(x, y); } public PgCircle ReadCircle() { return new PgCircle(this.ReadPoint(), this.ReadDouble()); } public PgLine ReadLine() { return new PgLine(this.ReadPoint(), this.ReadPoint()); } public PgLSeg ReadLSeg() { return new PgLSeg(this.ReadPoint(), this.ReadPoint()); } public PgBox ReadBox() { PgPoint upperRight = this.ReadPoint(); PgPoint lowerLeft = this.ReadPoint(); return new PgBox(lowerLeft, upperRight); } public PgPolygon ReadPolygon() { PgPoint[] points = new PgPoint[this.ReadInt()]; for (int i = 0; i < points.Length; i++) { points[i] = this.ReadPoint(); } return new PgPolygon(points); } public PgPath ReadPath() { bool isClosedPath = this.ReadBoolean(); PgPoint[] points = new PgPoint[this.ReadInt()]; for (int i = 0; i < points.Length; i++) { points[i] = this.ReadPoint(); } return new PgPath(isClosedPath, points); } #endregion #region · Common Methods · public object ReadValue(PgType type, int length) { switch (type.DataType) { case PgDataType.Array: return this.ReadArray(type, length); case PgDataType.Vector: return this.ReadVector(type, length); case PgDataType.Binary: return this.ReadBytes(length); case PgDataType.Char: case PgDataType.VarChar: return this.ReadString(length); case PgDataType.Boolean: return this.ReadBoolean(); case PgDataType.Byte: return this.ReadByte(); case PgDataType.Decimal: return Decimal.Parse( this.ReadString(length), NumberFormatInfo.InvariantInfo); case PgDataType.Currency: return this.ReadCurrency(); case PgDataType.Float: return this.ReadSingle(); case PgDataType.Double: return this.ReadDouble(); case PgDataType.Int2: return this.ReadShort(); case PgDataType.Int4: return this.ReadInt(); case PgDataType.Int8: return this.ReadLong(); case PgDataType.Interval: return this.ReadInterval(); case PgDataType.Date: return this.ReadDate(); case PgDataType.Time: return this.ReadTime(length); case PgDataType.TimeWithTZ: return this.ReadTimeWithTZ(length); case PgDataType.Timestamp: return this.ReadTimestamp(length); case PgDataType.TimestampWithTZ: return this.ReadTimestampWithTZ(length); case PgDataType.Point: return this.ReadPoint(); case PgDataType.Circle: return this.ReadCircle(); case PgDataType.Line: return this.ReadLine(); case PgDataType.LSeg: return this.ReadLSeg(); case PgDataType.Box: return this.ReadBox(); case PgDataType.Polygon: return this.ReadPolygon(); case PgDataType.Path: return this.ReadPath(); default: return this.ReadBytes(length); } } public object ReadValueFromString(PgType type, int length) { string stringValue = this.ReadString(length); switch (type.DataType) { case PgDataType.Array: return null; case PgDataType.Vector: return null; case PgDataType.Binary: return null; case PgDataType.Char: case PgDataType.VarChar: return stringValue; case PgDataType.Boolean: switch (stringValue.ToLower()) { case "t": case "true": case "y": case "yes": case "1": return true; default: return false; } case PgDataType.Byte: return Byte.Parse(stringValue); case PgDataType.Decimal: return Decimal.Parse( stringValue, NumberFormatInfo.InvariantInfo); case PgDataType.Currency: case PgDataType.Float: return Single.Parse( stringValue, NumberFormatInfo.InvariantInfo); case PgDataType.Double: return Double.Parse( stringValue, NumberFormatInfo.InvariantInfo); case PgDataType.Int2: return Int16.Parse( stringValue, NumberFormatInfo.InvariantInfo); case PgDataType.Int4: return Int32.Parse( stringValue, NumberFormatInfo.InvariantInfo); case PgDataType.Int8: return Int64.Parse( stringValue, NumberFormatInfo.InvariantInfo); case PgDataType.Interval: return null; case PgDataType.Date: case PgDataType.Timestamp: case PgDataType.Time: case PgDataType.TimeWithTZ: case PgDataType.TimestampWithTZ: return DateTime.Parse(stringValue); case PgDataType.Point: return PgPoint.Parse(stringValue); case PgDataType.Circle: return PgCircle.Parse(stringValue); case PgDataType.Line: return PgLine.Parse(stringValue); case PgDataType.LSeg: return PgLSeg.Parse(stringValue); case PgDataType.Box: return PgBox.Parse(stringValue); case PgDataType.Polygon: return PgPolygon.Parse(stringValue); case PgDataType.Path: return PgPath.Parse(stringValue); default: return ReadBytes(length); } } #endregion #region · Array Handling Methods · private Array ReadPrimitiveArray(PgType elementType, int length, int dimensions, int flags, int[] lengths, int[] lowerBounds) { Array data = Array.CreateInstance(elementType.SystemType, lengths, lowerBounds); // Read array data byte[] sourceArray = this.DecodeArrayData(elementType, data.Length, length); Buffer.BlockCopy(sourceArray, 0, data, 0, sourceArray.Length); return data; } private Array ReadNonPrimitiveArray(PgType elementType, int length, int dimensions, int flags, int[] lengths, int[] lowerBounds) { Array data = Array.CreateInstance(elementType.SystemType, lengths, lowerBounds); for (int i = data.GetLowerBound(0); i <= data.GetUpperBound(0); i++) { int elementLen = this.ReadInt(); data.SetValue(this.ReadValue(elementType, elementType.Size), i); } return data; } private Array ReadStringArray(PgType type, int length) { PgType elementType = PgDbClient.Types[type.ElementType]; Array data = null; string contents = ReadString(length); contents = contents.Substring(1, contents.Length - 2); string[] elements = contents.Split(','); data = Array.CreateInstance(elementType.SystemType, elements.Length); for (int i = 0; i < elements.Length; i++) { data.SetValue(elements[i], i); } return data; } private byte[] DecodeArrayData(PgType type, int elementCount, int length) { byte[] data = new byte[length]; int element = 0; int index = 0; while (element < elementCount) { byte[] elementData = null; int elementLen = this.ReadInt(); switch (type.DataType) { case PgDataType.Boolean: elementData = BitConverter.GetBytes(this.ReadBoolean()); break; case PgDataType.Float: elementData = BitConverter.GetBytes(this.ReadSingle()); break; case PgDataType.Double: elementData = BitConverter.GetBytes(this.ReadDouble()); break; case PgDataType.Int2: elementData = BitConverter.GetBytes(this.ReadShort()); break; case PgDataType.Int4: elementData = BitConverter.GetBytes(this.ReadInt()); break; case PgDataType.Int8: elementData = BitConverter.GetBytes(this.ReadLong()); break; } // Copy element data to dest array elementData.CopyTo(data, index); // Increment counters element++; index += elementData.Length; } byte[] destArray = new byte[index]; System.Array.Copy(data, 0, destArray, 0, destArray.Length); return destArray; } #endregion } } --- NEW FILE: PgType.cs --- /* PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ * Copyright (c) 2003-2005 Carlos Guzman Alvarez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ using System; using System.Data; namespace PostgreSql.Data.Protocol { internal class PgType { #region · Fields · private int oid; private string name; private PgDataType dataType; private Type systemType; private int elementType; private PgTypeFormat formatCode; private int size; #endregion #region · Properties · public int Oid { get { return this.oid; } } public PgDataType DataType { get { return this.dataType; } } public string Name { get { return this.name; } } public Type SystemType { get { return this.systemType; } } public int ElementType { get { int type = elementType; while (PgDbClient.Types[type].DataType == PgDataType.Array) { type = PgDbClient.Types[type].ElementType; } return type; } } public PgTypeFormat FormatCode { get { return this.formatCode; } } public int Size { get { return this.size; } } #endregion #region · Constructors · public PgType(int oid, string name, PgDataType dataType, int elementType, PgTypeFormat formatCode, int size) { this.oid = oid; this.name = name; this.dataType = dataType; this.elementType = elementType; this.formatCode = formatCode; this.size = size; this.systemType = this.InferSystemType(); } #endregion #region · Methods · public bool IsNumeric() { bool returnValue = false; if (this.dataType == PgDataType.Currency || this.dataType == PgDataType.Int2 || this.dataType == PgDataType.Int4 || this.dataType == PgDataType.Int8 || this.dataType == PgDataType.Float || this.dataType == PgDataType.Double || this.dataType == PgDataType.Decimal || this.dataType == PgDataType.Byte) { returnValue = true; } return returnValue; } public bool IsLong() { bool returnValue = false; if (this.dataType == PgDataType.Binary) { returnValue = true; } return returnValue; } #endregion #region · Private Methods · private Type InferSystemType() { switch (this.dataType) { case PgDataType.Array: case PgDataType.Binary: case PgDataType.Vector: return Type.GetType("System.Array"); case PgDataType.Boolean: return Type.GetType("System.Boolean"); case PgDataType.Box: return Type.GetType("PostgreSql.Data.PgTypes.PgBox"); case PgDataType.Circle: return Type.GetType("PostgreSql.Data.PgTypes.PgCircle"); case PgDataType.Line: return Type.GetType("PostgreSql.Data.PgTypes.PgLine"); case PgDataType.LSeg: return Type.GetType("PostgreSql.Data.PgTypes.PgLSeg"); case PgDataType.Path: return Type.GetType("PostgreSql.Data.PgTypes.PgPath"); case PgDataType.Point: return Type.GetType("PostgreSql.Data.PgTypes.PgPoint"); case PgDataType.Polygon: return Type.GetType("PostgreSql.Data.PgTypes.PgPolygon"); case PgDataType.Byte: return Type.GetType("System.Byte"); case PgDataType.Char: case PgDataType.Text: case PgDataType.VarChar: return Type.GetType("System.String"); case PgDataType.Currency: case PgDataType.Decimal: case PgDataType.Numeric: return Type.GetType("System.Decimal"); case PgDataType.Date: case PgDataType.Time: case PgDataType.TimeWithTZ: case PgDataType.Timestamp: case PgDataType.TimestampWithTZ: return Type.GetType("System.DateTime"); case PgDataType.Double: return Type.GetType("System.Double"); case PgDataType.Float: return Type.GetType("System.Single"); case PgDataType.Int2: return Type.GetType("System.Int16"); case PgDataType.Int4: return Type.GetType("System.Int32"); case PgDataType.Int8: return Type.GetType("System.Int64"); default: return Type.GetType("System.Object"); } } #endregion } } --- NEW FILE: PgCodes.cs --- /* PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ * Copyright (c) 2003-2005 Carlos Guzman Alvarez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ using System; namespace PostgreSql.Data.Protocol { internal class PgCodes { // Protocol version 3.0 public const int PROTOCOL_VERSION2_MAYOR = 2; public const int PROTOCOL_VERSION2_MINOR = 0; public const int PROTOCOL_VERSION2 = (PROTOCOL_VERSION2_MAYOR << 16) | PROTOCOL_VERSION2_MINOR; // Protocol version 3.0 public const int PROTOCOL_VERSION3_MAYOR = 3; public const int PROTOCOL_VERSION3_MINOR = 0; public const int PROTOCOL_VERSION3 = (PROTOCOL_VERSION3_MAYOR << 16) | PROTOCOL_VERSION3_MINOR; // SSL Request code public const int SSL_REQUEST_MOST = 1234; public const int SSL_REQUEST_LEAST = 5679; public const int SSL_REQUEST = (SSL_REQUEST_MOST << 16) | SSL_REQUEST_LEAST; // Cancel request code public const int CANCEL_REQUEST_MOST = 1234; public const int CANCEL_REQUEST_LEAST = 5678; public const int CANCEL_REQUEST = (CANCEL_REQUEST_MOST << 16) | CANCEL_REQUEST_LEAST; // Backend & FrontEnd Message Formats public const int COPY_DATA = 'd'; public const int COPY_DONE = 'c'; // Authentication values public const int AUTH_OK = 0; public const int AUTH_KERBEROS_V4 = 1; public const int AUTH_KERBEROS_V5 = 2; public const int AUTH_CLEARTEXT_PASSWORD = 3; public const int AUTH_CRYPT_PASSWORD = 4; public const int AUTH_MD5_PASSWORD = 5; public const int AUTH_SCM_CREDENTIAL = 6; // Max keys for vector data type public const int INDEX_MAX_KEYS = 32; // public const char NULL_TERMINATOR = '\0'; // public static readonly DateTime BASE_DATE = new DateTime(2000, 1, 1); // MD5 prefix public static string MD5_PREFIX = "md5"; // Format codes public const int TEXT_FORMAT = 0; public const int BINARY_FORMAT = 1; // Date & Time codes public const string DATE_STYLE = "ISO"; // Numeric data type public const int NUMERIC_SIGN_MASK = 0xC000; public const int NUMERIC_POS = 0x0000; public const int NUMERIC_NEG = 0x4000; public const int NUMERIC_NAN = 0xC000; public const int NUMERIC_MAX_PRECISION = 1000; public const int NUMERIC_DSCALE_MASK = 0x3FFF; public const int NUMERIC_HDRSZ = 10; } } --- NEW FILE: PgCharSetCollection.cs --- /* PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ * Copyright (c) 2003-2005 Carlos Guzman Alvarez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ using System; using System.Data; using System.Collections; using System.Globalization; namespace PostgreSql.Data.Protocol { internal class PgCharSetCollection : ArrayList { #region · Properties · public new PgCharSet this[int index] { get { return (PgCharSet)base[index]; } set { base[index] = (PgCharSet)value; } } public PgCharSet this[string name] { get { return (PgCharSet)this[IndexOf(name)]; } set { this[IndexOf(name)] = (PgCharSet)value; } } #endregion #region · Methods · public bool Contains(string charset) { return (-1 != this.IndexOf(charset)); } public int IndexOf(string charset) { int index = 0; foreach (PgCharSet item in this) { if (this.CultureAwareCompare(item.CharSet, charset)) { return index; } index++; } return -1; } public void RemoveAt(string charset) { this.RemoveAt(IndexOf(charset)); } public PgCharSet Add(PgCharSet charset) { base.Add(charset); return charset; } public PgCharSet Add(string charset, string systemCharset) { PgCharSet charSet = new PgCharSet(charset, systemCharset); base.Add(charSet); return charSet; } public PgCharSet Add(string charset, int cp) { PgCharSet charSet = new PgCharSet(charset, cp); base.Add(charSet); return charSet; } #endregion #region · Private Methods · private bool CultureAwareCompare(string strA, string strB) { return CultureInfo.CurrentCulture.CompareInfo.Compare( strA, strB, CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase) == 0 ? true : false; } #endregion } } --- NEW FILE: PgClientMessageEventArgs.cs --- /* PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ * Copyright (c) 2003-2005 Carlos Guzman Alvarez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License ... [truncated message content] |