*Reorganized files with astyle utility.
*NpgsqlState.cs, NpgsqlClosedState.cs, NpgsqlReadState.cs, NpgsqlStartupState.cs:
Changed code to use a buffered stream on demand instead of using the cached BufferedStream. It as giving hangs.
*NpgsqlEventLog.cs:
Removed the obsolete warning from file and changed the signature of the method from public to private. This make the building cleaner.
*NpgsqlCommand.cs, NpgsqlDataReader.cs:
Added support for CloseCommand behavior.
*NpgsqlConnection.cs:
Removed the cached BufferedStream. Now only uses the raw Stream.
*NpgsqlParameter:
Fixed a small bug which prevented the parameter name and its value from being set if the value of parameter was null.
svn path=/trunk/mcs/; revision=21079
// 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
// Copyright 2001 by Matthew S. Ford.
// Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
//
-// Comment: Adapted to the Project from Mono CVS as Sebastien Pouliot suggested to enable
+// Comment: Adapted to the Project from Mono CVS as Sebastien Pouliot suggested to enable
// support of Npgsql MD5 authentication in platforms which don't have support for MD5 algorithm.
-//
+//
using System;
namespace Npgsql
{
-
-
- // Comment: Removed the ICryptoTransform implementation as this interface may be not supported by
- // all platforms.
-
- internal abstract class HashAlgorithm : IDisposable{
- protected byte[] HashValue; // Caches the hash after it is calculated. Accessed through the Hash property.
- protected int HashSizeValue; // The size of the hash in bits.
- protected int State; // nonzero when in use; zero when not in use
- private bool disposed;
-
- /// <summary>
- /// Called from constructor of derived class.
- /// </summary>
- protected HashAlgorithm ()
- {
- disposed = false;
- }
-
- /// <summary>
- /// Finalizer for HashAlgorithm
- /// </summary>
- ~HashAlgorithm () {
- Dispose(false);
- }
-
- /// <summary>
- /// Get whether or not the hash can transform multiple blocks at a time.
- /// Note: MUST be overriden if descendant can transform multiple block
- /// on a single call!
- /// </summary>
- public virtual bool CanTransformMultipleBlocks {
- get { return true; }
- }
-
- public virtual bool CanReuseTransform {
- get { return true; }
- }
-
- public void Clear()
- {
- // same as System.IDisposable.Dispose() which is documented
- Dispose (true);
- }
-
- /// <summary>
- /// Computes the entire hash of all the bytes in the byte array.
- /// </summary>
- public byte[] ComputeHash (byte[] input)
- {
- return ComputeHash (input, 0, input.Length);
- }
-
- public byte[] ComputeHash (byte[] buffer, int offset, int count)
- {
- if (disposed)
- throw new ObjectDisposedException ("HashAlgorithm");
-
- HashCore (buffer, offset, count);
- HashValue = HashFinal ();
- Initialize ();
-
- return HashValue;
- }
-
- public byte[] ComputeHash (Stream inputStream)
- {
- // don't read stream unless object is ready to use
- if (disposed)
- throw new ObjectDisposedException ("HashAlgorithm");
-
- int l = (int) (inputStream.Length - inputStream.Position);
- byte[] buffer = new byte [l];
- inputStream.Read (buffer, 0, l);
-
- return ComputeHash (buffer, 0, l);
- }
-
- // Commented out because it uses the CryptoConfig which can't be available in all platforms
-
- /// <summary>
- /// Creates the default implementation of the default hash algorithm (SHA1).
- /// </summary>
- /*public static HashAlgorithm Create ()
- {
- return Create ("System.Security.Cryptography.HashAlgorithm");
- }*/
-
- /// <summary>
- /// Creates a specific implementation of the general hash idea.
- /// </summary>
- /// <param name="hashName">Specifies which derived class to create.</param>
- /*public static HashAlgorithm Create (string hashName)
- {
- return (HashAlgorithm) CryptoConfig.CreateFromName (hashName);
- }*/
-
-
-
- // Changed Exception type because it uses the CryptographicUnexpectedOperationException
- // which can't be available in all platforms.
- /// <summary>
- /// Gets the previously computed hash.
- /// </summary>
- public virtual byte[] Hash {
- get {
- if (HashValue == null)
- throw new Exception("HashValue is null");
- return HashValue;
- }
- }
-
- /// <summary>
- /// When overridden in a derived class, drives the hashing function.
- /// </summary>
- /// <param name="rgb"></param>
- /// <param name="start"></param>
- /// <param name="size"></param>
- protected abstract void HashCore (byte[] rgb, int start, int size);
-
- /// <summary>
- /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.
- /// </summary>
- protected abstract byte[] HashFinal ();
-
- /// <summary>
- /// Returns the size in bits of the hash.
- /// </summary>
- public virtual int HashSize {
- get { return HashSizeValue; }
- }
-
- /// <summary>
- /// When overridden in a derived class, initializes the object to prepare for hashing.
- /// </summary>
- public abstract void Initialize ();
-
- protected virtual void Dispose (bool disposing)
- {
- disposed = true;
- }
-
- /// <summary>
- /// Must be overriden if not 1
- /// </summary>
- public virtual int InputBlockSize {
- get { return 1; }
- }
-
- /// <summary>
- /// Must be overriden if not 1
- /// </summary>
- public virtual int OutputBlockSize {
- get { return 1; }
- }
-
- void IDisposable.Dispose ()
- {
- Dispose (true);
- GC.SuppressFinalize (this); // Finalization is now unnecessary
- }
-
- /// <summary>
- /// Used for stream chaining. Computes hash as data passes through it.
- /// </summary>
- /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
- /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
- /// <param name="inputCount">The number of bytes to be copied.</param>
- /// <param name="outputBuffer">The buffer to write the copied data to.</param>
- /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>
- public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
- {
- Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
- HashCore (inputBuffer, inputOffset, inputCount);
-
- return inputCount;
- }
-
- /// <summary>
- /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash.
- /// </summary>
- /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
- /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
- /// <param name="inputCount">The number of bytes to be copied.</param>
- public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
- {
- byte[] outputBuffer = new byte[inputCount];
-
- Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount);
-
- HashCore (inputBuffer, inputOffset, inputCount);
- HashValue = HashFinal ();
- Initialize ();
-
- return outputBuffer;
- }
- }
-
+
+
+ // Comment: Removed the ICryptoTransform implementation as this interface may be not supported by
+ // all platforms.
+
+ internal abstract class HashAlgorithm : IDisposable
+ {
+ protected byte[] HashValue; // Caches the hash after it is calculated. Accessed through the Hash property.
+ protected int HashSizeValue; // The size of the hash in bits.
+ protected int State; // nonzero when in use; zero when not in use
+ private bool disposed;
+
+ /// <summary>
+ /// Called from constructor of derived class.
+ /// </summary>
+ protected HashAlgorithm ()
+ {
+ disposed = false;
+ }
+
+ /// <summary>
+ /// Finalizer for HashAlgorithm
+ /// </summary>
+ ~HashAlgorithm ()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Get whether or not the hash can transform multiple blocks at a time.
+ /// Note: MUST be overriden if descendant can transform multiple block
+ /// on a single call!
+ /// </summary>
+ public virtual bool CanTransformMultipleBlocks {
+ get
+ {
+ return true;
+ }
+ }
+
+ public virtual bool CanReuseTransform {
+ get
+ {
+ return true;
+ }
+ }
+
+ public void Clear()
+ {
+ // same as System.IDisposable.Dispose() which is documented
+ Dispose (true);
+ }
+
+ /// <summary>
+ /// Computes the entire hash of all the bytes in the byte array.
+ /// </summary>
+ public byte[] ComputeHash (byte[] input)
+ {
+ return ComputeHash (input, 0, input.Length);
+ }
+
+ public byte[] ComputeHash (byte[] buffer, int offset, int count)
+ {
+ if (disposed)
+ throw new ObjectDisposedException ("HashAlgorithm");
+
+ HashCore (buffer, offset, count);
+ HashValue = HashFinal ();
+ Initialize ();
+
+ return HashValue;
+ }
+
+ public byte[] ComputeHash (Stream inputStream)
+ {
+ // don't read stream unless object is ready to use
+ if (disposed)
+ throw new ObjectDisposedException ("HashAlgorithm");
+
+ int l = (int) (inputStream.Length - inputStream.Position);
+ byte[] buffer = new byte [l];
+ inputStream.Read (buffer, 0, l);
+
+ return ComputeHash (buffer, 0, l);
+ }
+
+ // Commented out because it uses the CryptoConfig which can't be available in all platforms
+
+ /// <summary>
+ /// Creates the default implementation of the default hash algorithm (SHA1).
+ /// </summary>
+ /*public static HashAlgorithm Create ()
+ {
+ return Create ("System.Security.Cryptography.HashAlgorithm");
+ }*/
+
+ /// <summary>
+ /// Creates a specific implementation of the general hash idea.
+ /// </summary>
+ /// <param name="hashName">Specifies which derived class to create.</param>
+ /*public static HashAlgorithm Create (string hashName)
+ {
+ return (HashAlgorithm) CryptoConfig.CreateFromName (hashName);
+ }*/
+
+
+
+ // Changed Exception type because it uses the CryptographicUnexpectedOperationException
+ // which can't be available in all platforms.
+ /// <summary>
+ /// Gets the previously computed hash.
+ /// </summary>
+ public virtual byte[] Hash {
+ get
+ {
+ if (HashValue == null)
+ throw new Exception("HashValue is null");
+ return HashValue;
+ }
+ }
+
+ /// <summary>
+ /// When overridden in a derived class, drives the hashing function.
+ /// </summary>
+ /// <param name="rgb"></param>
+ /// <param name="start"></param>
+ /// <param name="size"></param>
+ protected abstract void HashCore (byte[] rgb, int start, int size);
+
+ /// <summary>
+ /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.
+ /// </summary>
+ protected abstract byte[] HashFinal ();
+
+ /// <summary>
+ /// Returns the size in bits of the hash.
+ /// </summary>
+ public virtual int HashSize {
+ get
+ {
+ return HashSizeValue;
+ }
+ }
+
+ /// <summary>
+ /// When overridden in a derived class, initializes the object to prepare for hashing.
+ /// </summary>
+ public abstract void Initialize ();
+
+ protected virtual void Dispose (bool disposing)
+ {
+ disposed = true;
+ }
+
+ /// <summary>
+ /// Must be overriden if not 1
+ /// </summary>
+ public virtual int InputBlockSize {
+ get
+ {
+ return 1;
+ }
+ }
+
+ /// <summary>
+ /// Must be overriden if not 1
+ /// </summary>
+ public virtual int OutputBlockSize {
+ get
+ {
+ return 1;
+ }
+ }
+
+ void IDisposable.Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this); // Finalization is now unnecessary
+ }
+
+ /// <summary>
+ /// Used for stream chaining. Computes hash as data passes through it.
+ /// </summary>
+ /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
+ /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
+ /// <param name="inputCount">The number of bytes to be copied.</param>
+ /// <param name="outputBuffer">The buffer to write the copied data to.</param>
+ /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>
+ public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+ {
+ Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
+ HashCore (inputBuffer, inputOffset, inputCount);
+
+ return inputCount;
+ }
+
+ /// <summary>
+ /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash.
+ /// </summary>
+ /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
+ /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
+ /// <param name="inputCount">The number of bytes to be copied.</param>
+ public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ byte[] outputBuffer = new byte[inputCount];
+
+ Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount);
+
+ HashCore (inputBuffer, inputOffset, inputCount);
+ HashValue = HashFinal ();
+ Initialize ();
+
+ return outputBuffer;
+ }
+ }
+
}
// created on 20/02/2003
// Npgsql.MD5.cs
-//
+//
//
// 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
// Copyright 2001 by Matthew S. Ford.
// Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
//
-// Comment: Adapted to the Project from Mono CVS as Sebastien Pouliot suggested to enable
+// Comment: Adapted to the Project from Mono CVS as Sebastien Pouliot suggested to enable
// support of Npgsql MD5 authentication in platforms which don't have support for MD5 algorithm.
-//
-//
+//
+//
//
namespace Npgsql
{
-
-
- /// <summary>
- /// Common base class for all derived MD5 implementations.
- /// </summary>
- internal abstract class MD5 : HashAlgorithm {
- /// <summary>
- /// Called from constructor of derived class.
- /// </summary>
- // Why is it protected when others abstract hash classes are public ?
- protected MD5 ()
- {
- HashSizeValue = 128;
- }
-
- /// <summary>
- /// Creates the default derived class.
- /// </summary>
- public static MD5 Create ()
- {
- //return Create ("System.Security.Cryptography.MD5");
- return new MD5CryptoServiceProvider();
- }
-
-
- // Commented out because it uses the CryptoConfig which can't be available in all
- // platforms.
- /// <summary>
- /// Creates a new derived implementation.
- /// </summary>
- /// <param name="hashName">Specifies which derived class to create</param>
- /*public static new MD5 Create (string hashName)
- {
- return (MD5) CryptoConfig.CreateFromName (hashName);
- }*/
-
- }
+
+
+ /// <summary>
+ /// Common base class for all derived MD5 implementations.
+ /// </summary>
+ internal abstract class MD5 : HashAlgorithm
+ {
+ /// <summary>
+ /// Called from constructor of derived class.
+ /// </summary>
+ // Why is it protected when others abstract hash classes are public ?
+ protected MD5 ()
+ {
+ HashSizeValue = 128;
+ }
+
+ /// <summary>
+ /// Creates the default derived class.
+ /// </summary>
+ public static MD5 Create ()
+ {
+ //return Create ("System.Security.Cryptography.MD5");
+ return new MD5CryptoServiceProvider();
+ }
+
+
+ // Commented out because it uses the CryptoConfig which can't be available in all
+ // platforms.
+ /// <summary>
+ /// Creates a new derived implementation.
+ /// </summary>
+ /// <param name="hashName">Specifies which derived class to create</param>
+ /*public static new MD5 Create (string hashName)
+ {
+ return (MD5) CryptoConfig.CreateFromName (hashName);
+ }*/
+
+ }
}
//
// Copyright 2001 by Matthew S. Ford.
//
-// Comment: Adapted to the Project from Mono CVS as Sebastien Pouliot suggested to enable
+// Comment: Adapted to the Project from Mono CVS as Sebastien Pouliot suggested to enable
// support of Npgsql MD5 authentication in platforms which don't have support for MD5 algorithm.
-//
+//
using System;
namespace Npgsql
{
- /// <summary>
- /// C# implementation of the MD5 cryptographic hash function.
- /// </summary>
- #if USE_VERSION_1_0
- internal class MD5CryptoServiceProvider : MD5 {
- #else
- internal sealed class MD5CryptoServiceProvider : MD5 {
- #endif
- private const int BLOCK_SIZE_BYTES = 64;
- private const int HASH_SIZE_BYTES = 16;
- private const int HASH_SIZE_BITS = 128;
- [CLSCompliant(false)] private uint[] _H;
- [CLSCompliant(false)] private uint count;
- private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
- private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
-
- /// <summary>
- /// Creates a new MD5CryptoServiceProvider.
- /// </summary>
- public MD5CryptoServiceProvider ()
- {
- _H = new uint[4];
- HashSizeValue = HASH_SIZE_BITS;
- _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
-
- Initialize();
- }
-
- ~MD5CryptoServiceProvider ()
- {
- Dispose (false);
- }
-
- protected override void Dispose (bool disposing)
- {
- // nothing to do (managed implementation)
- }
-
- /// <summary>
- /// Drives the hashing function.
- /// </summary>
- /// <param name="rgb">Byte array containing the data to hash.</param>
- /// <param name="start">Where in the input buffer to start.</param>
- /// <param name="size">Size in bytes of the data in the buffer to hash.</param>
- protected override void HashCore (byte[] rgb, int start, int size)
- {
- int i;
- State = 1;
-
- if (_ProcessingBufferCount != 0) {
- if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {
- System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);
- _ProcessingBufferCount += size;
- return;
- }
- else {
- i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
- System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);
- ProcessBlock (_ProcessingBuffer, 0);
- _ProcessingBufferCount = 0;
- start += i;
- size -= i;
- }
- }
-
- for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {
- ProcessBlock (rgb, start+i);
- }
-
- if (size%BLOCK_SIZE_BYTES != 0) {
- System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);
- _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;
- }
- }
-
- /// <summary>
- /// This finalizes the hash. Takes the data from the chaining variables and returns it.
- /// </summary>
- protected override byte[] HashFinal ()
- {
- byte[] hash = new byte[16];
- int i, j;
-
- ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);
-
- for (i=0; i<4; i++) {
- for (j=0; j<4; j++) {
- hash[i*4+j] = (byte)(_H[i] >> j*8);
- }
- }
-
- return hash;
- }
-
- /// <summary>
- /// Resets the class after use. Called automatically after hashing is done.
- /// </summary>
- public override void Initialize ()
- {
- count = 0;
- _ProcessingBufferCount = 0;
-
- _H[0] = 0x67452301;
- _H[1] = 0xefcdab89;
- _H[2] = 0x98badcfe;
- _H[3] = 0x10325476;
- }
-
- /// <summary>
- /// This is the meat of the hash function. It is what processes each block one at a time.
- /// </summary>
- /// <param name="inputBuffer">Byte array to process data from.</param>
- /// <param name="inputOffset">Where in the byte array to start processing.</param>
- private void ProcessBlock (byte[] inputBuffer, int inputOffset)
- {
- uint[] buff = new uint[16];
- uint a, b, c, d;
- int i;
-
- count += BLOCK_SIZE_BYTES;
-
- for (i=0; i<16; i++) {
- buff[i] = (uint)(inputBuffer[inputOffset+4*i])
- | (((uint)(inputBuffer[inputOffset+4*i+1])) << 8)
- | (((uint)(inputBuffer[inputOffset+4*i+2])) << 16)
- | (((uint)(inputBuffer[inputOffset+4*i+3])) << 24);
- }
-
- a = _H[0];
- b = _H[1];
- c = _H[2];
- d = _H[3];
-
- // This function was unrolled because it seems to be doubling our performance with current compiler/VM.
- // Possibly roll up if this changes.
-
-
- // ---- Round 1 --------
-
- a += (((c ^ d) & b) ^ d) + (uint) Constants.C0 + buff [0];
- a = (a << 7) | (a >> 25);
- a += b;
-
- d += (((b ^ c) & a) ^ c) + (uint) Constants.C1 + buff [1];
- d = (d << 12) | (d >> 20);
- d += a;
-
- c += (((a ^ b) & d) ^ b) + (uint) Constants.C2 + buff [2];
- c = (c << 17) | (c >> 15);
- c += d;
-
- b += (((d ^ a) & c) ^ a) + (uint) Constants.C3 + buff [3];
- b = (b << 22) | (b >> 10);
- b += c;
-
- a += (((c ^ d) & b) ^ d) + (uint) Constants.C4 + buff [4];
- a = (a << 7) | (a >> 25);
- a += b;
-
- d += (((b ^ c) & a) ^ c) + (uint) Constants.C5 + buff [5];
- d = (d << 12) | (d >> 20);
- d += a;
-
- c += (((a ^ b) & d) ^ b) + (uint) Constants.C6 + buff [6];
- c = (c << 17) | (c >> 15);
- c += d;
-
- b += (((d ^ a) & c) ^ a) + (uint) Constants.C7 + buff [7];
- b = (b << 22) | (b >> 10);
- b += c;
-
- a += (((c ^ d) & b) ^ d) + (uint) Constants.C8 + buff [8];
- a = (a << 7) | (a >> 25);
- a += b;
-
- d += (((b ^ c) & a) ^ c) + (uint) Constants.C9 + buff [9];
- d = (d << 12) | (d >> 20);
- d += a;
-
- c += (((a ^ b) & d) ^ b) + (uint) Constants.C10 + buff [10];
- c = (c << 17) | (c >> 15);
- c += d;
-
- b += (((d ^ a) & c) ^ a) + (uint) Constants.C11 + buff [11];
- b = (b << 22) | (b >> 10);
- b += c;
-
- a += (((c ^ d) & b) ^ d) + (uint) Constants.C12 + buff [12];
- a = (a << 7) | (a >> 25);
- a += b;
-
- d += (((b ^ c) & a) ^ c) + (uint) Constants.C13 + buff [13];
- d = (d << 12) | (d >> 20);
- d += a;
-
- c += (((a ^ b) & d) ^ b) + (uint) Constants.C14 + buff [14];
- c = (c << 17) | (c >> 15);
- c += d;
-
- b += (((d ^ a) & c) ^ a) + (uint) Constants.C15 + buff [15];
- b = (b << 22) | (b >> 10);
- b += c;
-
-
- // ---- Round 2 --------
-
- a += (((b ^ c) & d) ^ c) + (uint) Constants.C16 + buff [1];
- a = (a << 5) | (a >> 27);
- a += b;
-
- d += (((a ^ b) & c) ^ b) + (uint) Constants.C17 + buff [6];
- d = (d << 9) | (d >> 23);
- d += a;
-
- c += (((d ^ a) & b) ^ a) + (uint) Constants.C18 + buff [11];
- c = (c << 14) | (c >> 18);
- c += d;
-
- b += (((c ^ d) & a) ^ d) + (uint) Constants.C19 + buff [0];
- b = (b << 20) | (b >> 12);
- b += c;
-
- a += (((b ^ c) & d) ^ c) + (uint) Constants.C20 + buff [5];
- a = (a << 5) | (a >> 27);
- a += b;
-
- d += (((a ^ b) & c) ^ b) + (uint) Constants.C21 + buff [10];
- d = (d << 9) | (d >> 23);
- d += a;
-
- c += (((d ^ a) & b) ^ a) + (uint) Constants.C22 + buff [15];
- c = (c << 14) | (c >> 18);
- c += d;
-
- b += (((c ^ d) & a) ^ d) + (uint) Constants.C23 + buff [4];
- b = (b << 20) | (b >> 12);
- b += c;
-
- a += (((b ^ c) & d) ^ c) + (uint) Constants.C24 + buff [9];
- a = (a << 5) | (a >> 27);
- a += b;
-
- d += (((a ^ b) & c) ^ b) + (uint) Constants.C25 + buff [14];
- d = (d << 9) | (d >> 23);
- d += a;
-
- c += (((d ^ a) & b) ^ a) + (uint) Constants.C26 + buff [3];
- c = (c << 14) | (c >> 18);
- c += d;
-
- b += (((c ^ d) & a) ^ d) + (uint) Constants.C27 + buff [8];
- b = (b << 20) | (b >> 12);
- b += c;
-
- a += (((b ^ c) & d) ^ c) + (uint) Constants.C28 + buff [13];
- a = (a << 5) | (a >> 27);
- a += b;
-
- d += (((a ^ b) & c) ^ b) + (uint) Constants.C29 + buff [2];
- d = (d << 9) | (d >> 23);
- d += a;
-
- c += (((d ^ a) & b) ^ a) + (uint) Constants.C30 + buff [7];
- c = (c << 14) | (c >> 18);
- c += d;
-
- b += (((c ^ d) & a) ^ d) + (uint) Constants.C31 + buff [12];
- b = (b << 20) | (b >> 12);
- b += c;
-
-
- // ---- Round 3 --------
-
- a += (b ^ c ^ d) + (uint) Constants.C32 + buff [5];
- a = (a << 4) | (a >> 28);
- a += b;
-
- d += (a ^ b ^ c) + (uint) Constants.C33 + buff [8];
- d = (d << 11) | (d >> 21);
- d += a;
-
- c += (d ^ a ^ b) + (uint) Constants.C34 + buff [11];
- c = (c << 16) | (c >> 16);
- c += d;
-
- b += (c ^ d ^ a) + (uint) Constants.C35 + buff [14];
- b = (b << 23) | (b >> 9);
- b += c;
-
- a += (b ^ c ^ d) + (uint) Constants.C36 + buff [1];
- a = (a << 4) | (a >> 28);
- a += b;
-
- d += (a ^ b ^ c) + (uint) Constants.C37 + buff [4];
- d = (d << 11) | (d >> 21);
- d += a;
-
- c += (d ^ a ^ b) + (uint) Constants.C38 + buff [7];
- c = (c << 16) | (c >> 16);
- c += d;
-
- b += (c ^ d ^ a) + (uint) Constants.C39 + buff [10];
- b = (b << 23) | (b >> 9);
- b += c;
-
- a += (b ^ c ^ d) + (uint) Constants.C40 + buff [13];
- a = (a << 4) | (a >> 28);
- a += b;
-
- d += (a ^ b ^ c) + (uint) Constants.C41 + buff [0];
- d = (d << 11) | (d >> 21);
- d += a;
-
- c += (d ^ a ^ b) + (uint) Constants.C42 + buff [3];
- c = (c << 16) | (c >> 16);
- c += d;
-
- b += (c ^ d ^ a) + (uint) Constants.C43 + buff [6];
- b = (b << 23) | (b >> 9);
- b += c;
-
- a += (b ^ c ^ d) + (uint) Constants.C44 + buff [9];
- a = (a << 4) | (a >> 28);
- a += b;
-
- d += (a ^ b ^ c) + (uint) Constants.C45 + buff [12];
- d = (d << 11) | (d >> 21);
- d += a;
-
- c += (d ^ a ^ b) + (uint) Constants.C46 + buff [15];
- c = (c << 16) | (c >> 16);
- c += d;
-
- b += (c ^ d ^ a) + (uint) Constants.C47 + buff [2];
- b = (b << 23) | (b >> 9);
- b += c;
-
-
- // ---- Round 4 --------
-
- a += (((~d) | b) ^ c) + (uint) Constants.C48 + buff [0];
- a = (a << 6) | (a >> 26);
- a += b;
-
- d += (((~c) | a) ^ b) + (uint) Constants.C49 + buff [7];
- d = (d << 10) | (d >> 22);
- d += a;
-
- c += (((~b) | d) ^ a) + (uint) Constants.C50 + buff [14];
- c = (c << 15) | (c >> 17);
- c += d;
-
- b += (((~a) | c) ^ d) + (uint) Constants.C51 + buff [5];
- b = (b << 21) | (b >> 11);
- b += c;
-
- a += (((~d) | b) ^ c) + (uint) Constants.C52 + buff [12];
- a = (a << 6) | (a >> 26);
- a += b;
-
- d += (((~c) | a) ^ b) + (uint) Constants.C53 + buff [3];
- d = (d << 10) | (d >> 22);
- d += a;
-
- c += (((~b) | d) ^ a) + (uint) Constants.C54 + buff [10];
- c = (c << 15) | (c >> 17);
- c += d;
-
- b += (((~a) | c) ^ d) + (uint) Constants.C55 + buff [1];
- b = (b << 21) | (b >> 11);
- b += c;
-
- a += (((~d) | b) ^ c) + (uint) Constants.C56 + buff [8];
- a = (a << 6) | (a >> 26);
- a += b;
-
- d += (((~c) | a) ^ b) + (uint) Constants.C57 + buff [15];
- d = (d << 10) | (d >> 22);
- d += a;
-
- c += (((~b) | d) ^ a) + (uint) Constants.C58 + buff [6];
- c = (c << 15) | (c >> 17);
- c += d;
-
- b += (((~a) | c) ^ d) + (uint) Constants.C59 + buff [13];
- b = (b << 21) | (b >> 11);
- b += c;
-
- a += (((~d) | b) ^ c) + (uint) Constants.C60 + buff [4];
- a = (a << 6) | (a >> 26);
- a += b;
-
- d += (((~c) | a) ^ b) + (uint) Constants.C61 + buff [11];
- d = (d << 10) | (d >> 22);
- d += a;
-
- c += (((~b) | d) ^ a) + (uint) Constants.C62 + buff [2];
- c = (c << 15) | (c >> 17);
- c += d;
-
- b += (((~a) | c) ^ d) + (uint) Constants.C63 + buff [9];
- b = (b << 21) | (b >> 11);
- b += c;
-
-
- _H[0] += a;
- _H[1] += b;
- _H[2] += c;
- _H[3] += d;
- }
-
- /// <summary>
- /// Pads and then processes the final block.
- /// </summary>
- /// <param name="inputBuffer">Buffer to grab data from.</param>
- /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>
- /// <param name="inputCount">How much data in bytes in the buffer to use.</param>
- private void ProcessFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
- {
- byte[] fooBuffer;
- int paddingSize;
- int i;
- uint size;
-
- paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);
-
- if (paddingSize < 1)
- paddingSize += BLOCK_SIZE_BYTES;
-
-
- fooBuffer = new byte[inputCount+paddingSize+8];
-
- for (i=0; i<inputCount; i++) {
- fooBuffer[i] = inputBuffer[i+inputOffset];
- }
-
- fooBuffer[inputCount] = 0x80;
- for (i=inputCount+1; i<inputCount+paddingSize; i++) {
- fooBuffer[i] = 0x00;
- }
-
- size = (uint)(count+inputCount);
- size *= 8;
- fooBuffer[inputCount+paddingSize] = (byte)((size) >> 0);
- fooBuffer[inputCount+paddingSize+1] = (byte)((size) >> 8);
- fooBuffer[inputCount+paddingSize+2] = (byte)((size) >> 16);
- fooBuffer[inputCount+paddingSize+3] = (byte)((size) >> 24);
-
- fooBuffer[inputCount+paddingSize+4] = 0x00;
- fooBuffer[inputCount+paddingSize+5] = 0x00;
- fooBuffer[inputCount+paddingSize+6] = 0x00;
- fooBuffer[inputCount+paddingSize+7] = 0x00;
-
- ProcessBlock(fooBuffer, 0);
-
- if (inputCount+paddingSize+8 == 128) {
- ProcessBlock(fooBuffer, 64);
- }
- }
-
- private enum Constants : uint {
- C0 = 0xd76aa478, C1 = 0xe8c7b756, C2 = 0x242070db,
- C3 = 0xc1bdceee, C4 = 0xf57c0faf, C5 = 0x4787c62a,
- C6 = 0xa8304613, C7 = 0xfd469501, C8 = 0x698098d8,
- C9 = 0x8b44f7af,C10 = 0xffff5bb1,C11 = 0x895cd7be,
- C12 = 0x6b901122,C13 = 0xfd987193,C14 = 0xa679438e,
- C15 = 0x49b40821,C16 = 0xf61e2562,C17 = 0xc040b340,
- C18 = 0x265e5a51,C19 = 0xe9b6c7aa,C20 = 0xd62f105d,
- C21 = 0x02441453,C22 = 0xd8a1e681,C23 = 0xe7d3fbc8,
- C24 = 0x21e1cde6,C25 = 0xc33707d6,C26 = 0xf4d50d87,
- C27 = 0x455a14ed,C28 = 0xa9e3e905,C29 = 0xfcefa3f8,
- C30 = 0x676f02d9,C31 = 0x8d2a4c8a,C32 = 0xfffa3942,
- C33 = 0x8771f681,C34 = 0x6d9d6122,C35 = 0xfde5380c,
- C36 = 0xa4beea44,C37 = 0x4bdecfa9,C38 = 0xf6bb4b60,
- C39 = 0xbebfbc70,C40 = 0x289b7ec6,C41 = 0xeaa127fa,
- C42 = 0xd4ef3085,C43 = 0x04881d05,C44 = 0xd9d4d039,
- C45 = 0xe6db99e5,C46 = 0x1fa27cf8,C47 = 0xc4ac5665,
- C48 = 0xf4292244,C49 = 0x432aff97,C50 = 0xab9423a7,
- C51 = 0xfc93a039,C52 = 0x655b59c3,C53 = 0x8f0ccc92,
- C54 = 0xffeff47d,C55 = 0x85845dd1,C56 = 0x6fa87e4f,
- C57 = 0xfe2ce6e0,C58 = 0xa3014314,C59 = 0x4e0811a1,
- C60 = 0xf7537e82,C61 = 0xbd3af235,C62 = 0x2ad7d2bb,
- C63 = 0xeb86d391
- }
-
- }
+ /// <summary>
+ /// C# implementation of the MD5 cryptographic hash function.
+ /// </summary>
+#if USE_VERSION_1_0
+ internal class MD5CryptoServiceProvider : MD5
+ {
+#else
+ internal sealed class MD5CryptoServiceProvider : MD5
+ {
+#endif
+ private const int BLOCK_SIZE_BYTES = 64;
+ private const int HASH_SIZE_BYTES = 16;
+ private const int HASH_SIZE_BITS = 128;
+ [CLSCompliant(false)] private uint[] _H;
+ [CLSCompliant(false)] private uint count;
+ private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
+ private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
+
+ /// <summary>
+ /// Creates a new MD5CryptoServiceProvider.
+ /// </summary>
+ public MD5CryptoServiceProvider ()
+ {
+ _H = new uint[4];
+ HashSizeValue = HASH_SIZE_BITS;
+ _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
+
+ Initialize();
+ }
+
+ ~MD5CryptoServiceProvider ()
+ {
+ Dispose (false);
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ // nothing to do (managed implementation)
+ }
+
+ /// <summary>
+ /// Drives the hashing function.
+ /// </summary>
+ /// <param name="rgb">Byte array containing the data to hash.</param>
+ /// <param name="start">Where in the input buffer to start.</param>
+ /// <param name="size">Size in bytes of the data in the buffer to hash.</param>
+ protected override void HashCore (byte[] rgb, int start, int size)
+ {
+ int i;
+ State = 1;
+
+ if (_ProcessingBufferCount != 0)
+ {
+ if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount))
+ {
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);
+ _ProcessingBufferCount += size;
+ return;
+ }
+ else
+ {
+ i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);
+ ProcessBlock (_ProcessingBuffer, 0);
+ _ProcessingBufferCount = 0;
+ start += i;
+ size -= i;
+ }
+ }
+
+ for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES)
+ {
+ ProcessBlock (rgb, start+i);
+ }
+
+ if (size%BLOCK_SIZE_BYTES != 0)
+ {
+ System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);
+ _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;
+ }
+ }
+
+ /// <summary>
+ /// This finalizes the hash. Takes the data from the chaining variables and returns it.
+ /// </summary>
+ protected override byte[] HashFinal ()
+ {
+ byte[] hash = new byte[16];
+ int i, j;
+
+ ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);
+
+ for (i=0; i<4; i++)
+ {
+ for (j=0; j<4; j++)
+ {
+ hash[i*4+j] = (byte)(_H[i] >> j*8);
+ }
+ }
+
+ return hash;
+ }
+
+ /// <summary>
+ /// Resets the class after use. Called automatically after hashing is done.
+ /// </summary>
+ public override void Initialize ()
+ {
+ count = 0;
+ _ProcessingBufferCount = 0;
+
+ _H[0] = 0x67452301;
+ _H[1] = 0xefcdab89;
+ _H[2] = 0x98badcfe;
+ _H[3] = 0x10325476;
+ }
+
+ /// <summary>
+ /// This is the meat of the hash function. It is what processes each block one at a time.
+ /// </summary>
+ /// <param name="inputBuffer">Byte array to process data from.</param>
+ /// <param name="inputOffset">Where in the byte array to start processing.</param>
+ private void ProcessBlock (byte[] inputBuffer, int inputOffset)
+ {
+ uint[] buff = new uint[16];
+ uint a, b, c, d;
+ int i;
+
+ count += BLOCK_SIZE_BYTES;
+
+ for (i=0; i<16; i++)
+ {
+ buff[i] = (uint)(inputBuffer[inputOffset+4*i])
+ | (((uint)(inputBuffer[inputOffset+4*i+1])) << 8)
+ | (((uint)(inputBuffer[inputOffset+4*i+2])) << 16)
+ | (((uint)(inputBuffer[inputOffset+4*i+3])) << 24);
+ }
+
+ a = _H[0];
+ b = _H[1];
+ c = _H[2];
+ d = _H[3];
+
+ // This function was unrolled because it seems to be doubling our performance with current compiler/VM.
+ // Possibly roll up if this changes.
+
+
+ // ---- Round 1 --------
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C0 + buff [0];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C1 + buff [1];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C2 + buff [2];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C3 + buff [3];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C4 + buff [4];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C5 + buff [5];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C6 + buff [6];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C7 + buff [7];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C8 + buff [8];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C9 + buff [9];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C10 + buff [10];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C11 + buff [11];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C12 + buff [12];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C13 + buff [13];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C14 + buff [14];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C15 + buff [15];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+
+ // ---- Round 2 --------
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C16 + buff [1];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C17 + buff [6];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C18 + buff [11];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C19 + buff [0];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C20 + buff [5];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C21 + buff [10];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C22 + buff [15];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C23 + buff [4];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C24 + buff [9];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C25 + buff [14];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C26 + buff [3];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C27 + buff [8];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C28 + buff [13];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C29 + buff [2];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C30 + buff [7];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C31 + buff [12];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+
+ // ---- Round 3 --------
+
+ a += (b ^ c ^ d) + (uint) Constants.C32 + buff [5];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C33 + buff [8];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C34 + buff [11];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C35 + buff [14];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+ a += (b ^ c ^ d) + (uint) Constants.C36 + buff [1];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C37 + buff [4];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C38 + buff [7];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C39 + buff [10];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+ a += (b ^ c ^ d) + (uint) Constants.C40 + buff [13];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C41 + buff [0];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C42 + buff [3];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C43 + buff [6];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+ a += (b ^ c ^ d) + (uint) Constants.C44 + buff [9];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C45 + buff [12];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C46 + buff [15];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C47 + buff [2];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+
+ // ---- Round 4 --------
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C48 + buff [0];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C49 + buff [7];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C50 + buff [14];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C51 + buff [5];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C52 + buff [12];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C53 + buff [3];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C54 + buff [10];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C55 + buff [1];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C56 + buff [8];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C57 + buff [15];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C58 + buff [6];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C59 + buff [13];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C60 + buff [4];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C61 + buff [11];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C62 + buff [2];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C63 + buff [9];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+
+ _H[0] += a;
+ _H[1] += b;
+ _H[2] += c;
+ _H[3] += d;
+ }
+
+ /// <summary>
+ /// Pads and then processes the final block.
+ /// </summary>
+ /// <param name="inputBuffer">Buffer to grab data from.</param>
+ /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>
+ /// <param name="inputCount">How much data in bytes in the buffer to use.</param>
+ private void ProcessFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ byte[] fooBuffer;
+ int paddingSize;
+ int i;
+ uint size;
+
+ paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);
+
+ if (paddingSize < 1)
+ paddingSize += BLOCK_SIZE_BYTES;
+
+
+ fooBuffer = new byte[inputCount+paddingSize+8];
+
+ for (i=0; i<inputCount; i++)
+ {
+ fooBuffer[i] = inputBuffer[i+inputOffset];
+ }
+
+ fooBuffer[inputCount] = 0x80;
+ for (i=inputCount+1; i<inputCount+paddingSize; i++)
+ {
+ fooBuffer[i] = 0x00;
+ }
+
+ size = (uint)(count+inputCount);
+ size *= 8;
+ fooBuffer[inputCount+paddingSize] = (byte)((size) >> 0);
+ fooBuffer[inputCount+paddingSize+1] = (byte)((size) >> 8);
+ fooBuffer[inputCount+paddingSize+2] = (byte)((size) >> 16);
+ fooBuffer[inputCount+paddingSize+3] = (byte)((size) >> 24);
+
+ fooBuffer[inputCount+paddingSize+4] = 0x00;
+ fooBuffer[inputCount+paddingSize+5] = 0x00;
+ fooBuffer[inputCount+paddingSize+6] = 0x00;
+ fooBuffer[inputCount+paddingSize+7] = 0x00;
+
+ ProcessBlock(fooBuffer, 0);
+
+ if (inputCount+paddingSize+8 == 128)
+ {
+ ProcessBlock(fooBuffer, 64);
+ }
+ }
+
+ private enum Constants :
+ uint {
+ C0 = 0xd76aa478, C1 = 0xe8c7b756, C2 = 0x242070db,
+ C3 = 0xc1bdceee, C4 = 0xf57c0faf, C5 = 0x4787c62a,
+ C6 = 0xa8304613, C7 = 0xfd469501, C8 = 0x698098d8,
+ C9 = 0x8b44f7af,C10 = 0xffff5bb1,C11 = 0x895cd7be,
+ C12 = 0x6b901122,C13 = 0xfd987193,C14 = 0xa679438e,
+ C15 = 0x49b40821,C16 = 0xf61e2562,C17 = 0xc040b340,
+ C18 = 0x265e5a51,C19 = 0xe9b6c7aa,C20 = 0xd62f105d,
+ C21 = 0x02441453,C22 = 0xd8a1e681,C23 = 0xe7d3fbc8,
+ C24 = 0x21e1cde6,C25 = 0xc33707d6,C26 = 0xf4d50d87,
+ C27 = 0x455a14ed,C28 = 0xa9e3e905,C29 = 0xfcefa3f8,
+ C30 = 0x676f02d9,C31 = 0x8d2a4c8a,C32 = 0xfffa3942,
+ C33 = 0x8771f681,C34 = 0x6d9d6122,C35 = 0xfde5380c,
+ C36 = 0xa4beea44,C37 = 0x4bdecfa9,C38 = 0xf6bb4b60,
+ C39 = 0xbebfbc70,C40 = 0x289b7ec6,C41 = 0xeaa127fa,
+ C42 = 0xd4ef3085,C43 = 0x04881d05,C44 = 0xd9d4d039,
+ C45 = 0xe6db99e5,C46 = 0x1fa27cf8,C47 = 0xc4ac5665,
+ C48 = 0xf4292244,C49 = 0x432aff97,C50 = 0xab9423a7,
+ C51 = 0xfc93a039,C52 = 0x655b59c3,C53 = 0x8f0ccc92,
+ C54 = 0xffeff47d,C55 = 0x85845dd1,C56 = 0x6fa87e4f,
+ C57 = 0xfe2ce6e0,C58 = 0xa3014314,C59 = 0x4e0811a1,
+ C60 = 0xf7537e82,C61 = 0xbd3af235,C62 = 0x2ad7d2bb,
+ C63 = 0xeb86d391
+ }
+
+ }
}
-
+
// created on 13/6/2002 at 21:06
// Npgsql.NpgsqlAsciiRow.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- /// <summary>
- /// This class represents the AsciiRow message sent from PostgreSQL
- /// server.
- /// </summary>
- ///
- internal sealed class NpgsqlAsciiRow
- {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlAsciiRow";
-
- private ArrayList data;
- private Byte[] null_map_array;
- private Int16 num_fields;
- private readonly Int16 READ_BUFFER_SIZE = 300; //[FIXME] Is this enough??
- private NpgsqlRowDescription row_desc;
- private Hashtable oid_to_name_mapping;
- private Int32 protocol_version;
-
-
-
- public NpgsqlAsciiRow(NpgsqlRowDescription rowDesc, Hashtable oidToNameMapping, Int32 protocolVersion)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
-
- data = new ArrayList();
- row_desc = rowDesc;
- null_map_array = new Byte[(row_desc.NumFields + 7)/8];
- oid_to_name_mapping = oidToNameMapping;
- protocol_version = protocolVersion;
-
- //num_fields = numFields;
-
-
- }
-
-
- public void ReadFromStream(Stream inputStream, Encoding encoding)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream()");
-
- Byte[] input_buffer = new Byte[READ_BUFFER_SIZE];
-
-
- if (protocol_version == ProtocolVersion.Version2)
- {
-
- Array.Clear(null_map_array, 0, null_map_array.Length);
-
- // Read the null fields bitmap.
- PGUtil.CheckedStreamRead(inputStream, null_map_array, 0, null_map_array.Length );
-
- // Get the data.
- for (Int16 field_count = 0; field_count < row_desc.NumFields; field_count++)
- {
-
- // Check if this field isn't null
- if (IsNull(field_count))
- {
- // Field is null just keep next field.
-
- //[FIXME] See this[] method.
- data.Add(null);
- continue;
- }
-
- // Read the first data of the first row.
-
- PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, 4);
-
- Int32 field_value_size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
- field_value_size -= 4;
- Int32 bytes_left = field_value_size;
-
- StringBuilder result = new StringBuilder();
-
- while (bytes_left > READ_BUFFER_SIZE)
- {
- // Now, read just the field value.
- PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, READ_BUFFER_SIZE);
-
- // Read the bytes as string.
- result.Append(new String(encoding.GetChars(input_buffer, 0, READ_BUFFER_SIZE)));
-
- bytes_left -= READ_BUFFER_SIZE;
- }
-
- // Now, read just the field value.
- PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, bytes_left);
-
- // Read the bytes as string.
- result.Append(new String(encoding.GetChars(input_buffer, 0, bytes_left)));
-
-
- // Add them to the AsciiRow data.
- data.Add(NpgsqlTypesHelper.ConvertBackendStringToSystemType(oid_to_name_mapping, result.ToString(), row_desc[field_count].type_oid, row_desc[field_count].type_modifier));
-
- }
- }
- else
- {
-
- PGUtil.ReadInt32(inputStream, input_buffer);
- Int16 numCols = PGUtil.ReadInt16(inputStream, input_buffer);
-
- for (Int16 field_count = 0; field_count < numCols; field_count++)
- {
- Int32 field_value_size = PGUtil.ReadInt32(inputStream, input_buffer);
-
- if (field_value_size == -1) // Null value
- {
- // Field is null just keep next field.
-
- //[FIXME] See this[] method.
- data.Add(null);
- continue;
-
- }
- Int32 bytes_left = field_value_size;
-
- StringBuilder result = new StringBuilder();
-
- while (bytes_left > READ_BUFFER_SIZE)
- {
- // Now, read just the field value.
- PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, READ_BUFFER_SIZE);
-
- // Read the bytes as string.
- result.Append(new String(encoding.GetChars(input_buffer, 0, READ_BUFFER_SIZE)));
-
- bytes_left -= READ_BUFFER_SIZE;
- }
-
- // Now, read just the field value.
- PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, bytes_left);
-
- if (row_desc[field_count].format_code == FormatCode.Text)
- {
- // Read the bytes as string.
- result.Append(new String(encoding.GetChars(input_buffer, 0, bytes_left)));
- // Add them to the AsciiRow data.
- data.Add(NpgsqlTypesHelper.ConvertBackendStringToSystemType(oid_to_name_mapping, result.ToString(), row_desc[field_count].type_oid, row_desc[field_count].type_modifier));
- }
- else
- data.Add(NpgsqlTypesHelper.ConvertBackendBytesToStytemType(oid_to_name_mapping, input_buffer, encoding, field_value_size, row_desc[field_count].type_oid, row_desc[field_count].type_modifier));
- }
-
- }
-
- }
-
-
- public Boolean IsNull(Int32 index)
- {
-
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IsNull", index);
- // [FIXME] Check more optimized way of doing this.
- // Should this be public or internal?
-
- // Check valid index range.
- if ((index < 0) || (index >= row_desc.NumFields))
- throw new ArgumentOutOfRangeException("index");
-
- // Check if the value (index) of the field is null
-
- // Get the byte that holds the bit index position.
- Byte test_byte = null_map_array[index/8];
-
- // Now, check if index bit is set.
- // To this, get its position in the byte, shift to
- // MSB and test it with the byte 10000000.
- return (((test_byte << (index%8)) & 0x80) == 0);
- }
-
-
- public Object this[Int32 index]
- {
- get
- {
-
- NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
-
- if ((index < 0) || (index >= row_desc.NumFields))
- throw new ArgumentOutOfRangeException("this[] index value");
- // [FIXME] Should return null or something else
- // more meaningful?
-
- //[FIXME] This code assumes that the data arraylist has the null and non null values
- // in order, but just the non-null values are added.
- // It is necessary to map the index value with the elements in the array list.
- // For now, the workaround is to insert the null values in the array list.
- // But this is a hack. :)
-
- //return (IsNull(index) ? null : data[index]);
- return data[index];
-
-
-
- }
- }
- }
-
+
+ /// <summary>
+ /// This class represents the AsciiRow message sent from PostgreSQL
+ /// server.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlAsciiRow
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlAsciiRow";
+
+ private ArrayList data;
+ private Byte[] null_map_array;
+ private Int16 num_fields;
+ private readonly Int16 READ_BUFFER_SIZE = 300; //[FIXME] Is this enough??
+ private NpgsqlRowDescription row_desc;
+ private Hashtable oid_to_name_mapping;
+ private Int32 protocol_version;
+
+
+
+ public NpgsqlAsciiRow(NpgsqlRowDescription rowDesc, Hashtable oidToNameMapping, Int32 protocolVersion)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
+
+ data = new ArrayList();
+ row_desc = rowDesc;
+ null_map_array = new Byte[(row_desc.NumFields + 7)/8];
+ oid_to_name_mapping = oidToNameMapping;
+ protocol_version = protocolVersion;
+
+ //num_fields = numFields;
+
+
+ }
+
+
+ public void ReadFromStream(Stream inputStream, Encoding encoding)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream()");
+
+ Byte[] input_buffer = new Byte[READ_BUFFER_SIZE];
+
+
+ if (protocol_version == ProtocolVersion.Version2)
+ {
+
+ Array.Clear(null_map_array, 0, null_map_array.Length);
+
+ // Read the null fields bitmap.
+ PGUtil.CheckedStreamRead(inputStream, null_map_array, 0, null_map_array.Length );
+
+ // Get the data.
+ for (Int16 field_count = 0; field_count < row_desc.NumFields; field_count++)
+ {
+
+ // Check if this field isn't null
+ if (IsNull(field_count))
+ {
+ // Field is null just keep next field.
+
+ //[FIXME] See this[] method.
+ data.Add(null);
+ continue;
+ }
+
+ // Read the first data of the first row.
+
+ PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, 4);
+
+ Int32 field_value_size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
+ field_value_size -= 4;
+ Int32 bytes_left = field_value_size;
+
+ StringBuilder result = new StringBuilder();
+
+ while (bytes_left > READ_BUFFER_SIZE)
+ {
+ // Now, read just the field value.
+ PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, READ_BUFFER_SIZE);
+
+ // Read the bytes as string.
+ result.Append(new String(encoding.GetChars(input_buffer, 0, READ_BUFFER_SIZE)));
+
+ bytes_left -= READ_BUFFER_SIZE;
+ }
+
+ // Now, read just the field value.
+ PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, bytes_left);
+
+ // Read the bytes as string.
+ result.Append(new String(encoding.GetChars(input_buffer, 0, bytes_left)));
+
+
+ // Add them to the AsciiRow data.
+ data.Add(NpgsqlTypesHelper.ConvertBackendStringToSystemType(oid_to_name_mapping, result.ToString(), row_desc[field_count].type_oid, row_desc[field_count].type_modifier));
+
+ }
+ }
+ else
+ {
+
+ PGUtil.ReadInt32(inputStream, input_buffer);
+ Int16 numCols = PGUtil.ReadInt16(inputStream, input_buffer);
+
+ for (Int16 field_count = 0; field_count < numCols; field_count++)
+ {
+ Int32 field_value_size = PGUtil.ReadInt32(inputStream, input_buffer);
+
+ if (field_value_size == -1) // Null value
+ {
+ // Field is null just keep next field.
+
+ //[FIXME] See this[] method.
+ data.Add(null);
+ continue;
+
+ }
+ Int32 bytes_left = field_value_size;
+
+ StringBuilder result = new StringBuilder();
+
+ while (bytes_left > READ_BUFFER_SIZE)
+ {
+ // Now, read just the field value.
+ PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, READ_BUFFER_SIZE);
+
+ // Read the bytes as string.
+ result.Append(new String(encoding.GetChars(input_buffer, 0, READ_BUFFER_SIZE)));
+
+ bytes_left -= READ_BUFFER_SIZE;
+ }
+
+ // Now, read just the field value.
+ PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, bytes_left);
+
+ if (row_desc[field_count].format_code == FormatCode.Text)
+ {
+ // Read the bytes as string.
+ result.Append(new String(encoding.GetChars(input_buffer, 0, bytes_left)));
+ // Add them to the AsciiRow data.
+ data.Add(NpgsqlTypesHelper.ConvertBackendStringToSystemType(oid_to_name_mapping, result.ToString(), row_desc[field_count].type_oid, row_desc[field_count].type_modifier));
+ }
+ else
+ data.Add(NpgsqlTypesHelper.ConvertBackendBytesToStytemType(oid_to_name_mapping, input_buffer, encoding, field_value_size, row_desc[field_count].type_oid, row_desc[field_count].type_modifier));
+ }
+
+ }
+
+ }
+
+
+ public Boolean IsNull(Int32 index)
+ {
+
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IsNull", index);
+ // [FIXME] Check more optimized way of doing this.
+ // Should this be public or internal?
+
+ // Check valid index range.
+ if ((index < 0) || (index >= row_desc.NumFields))
+ throw new ArgumentOutOfRangeException("index");
+
+ // Check if the value (index) of the field is null
+
+ // Get the byte that holds the bit index position.
+ Byte test_byte = null_map_array[index/8];
+
+ // Now, check if index bit is set.
+ // To this, get its position in the byte, shift to
+ // MSB and test it with the byte 10000000.
+ return (((test_byte << (index%8)) & 0x80) == 0);
+ }
+
+
+ public Object this[Int32 index]
+ {
+ get
+ {
+
+ NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
+
+ if ((index < 0) || (index >= row_desc.NumFields))
+ throw new ArgumentOutOfRangeException("this[] index value");
+ // [FIXME] Should return null or something else
+ // more meaningful?
+
+ //[FIXME] This code assumes that the data arraylist has the null and non null values
+ // in order, but just the non-null values are added.
+ // It is necessary to map the index value with the elements in the array list.
+ // For now, the workaround is to insert the null values in the array list.
+ // But this is a hack. :)
+
+ //return (IsNull(index) ? null : data[index]);
+ return data[index];
+
+
+
+ }
+ }
+ }
+
}
// created on 11/6/2002 at 11:53
// Npgsql.NpgsqlBackEndKeyData.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
- /// <summary>
- /// This class represents a BackEndKeyData message received
- /// from PostgreSQL
- /// </summary>
- internal sealed class NpgsqlBackEndKeyData
- {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlBackEndKeyData";
-
- private Int32 _processId;
- private Int32 _secretKey;
-
- private Int32 _protocolVersion;
-
- public NpgsqlBackEndKeyData(Int32 protocolVersion)
- {
- _protocolVersion = protocolVersion;
- _processId = -1;
- _secretKey = -1;
- }
-
-
- public void ReadFromStream(Stream inputStream)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
-
- Byte[] inputBuffer = new Byte[8];
-
- // Read the BackendKeyData message contents. Two Int32 integers = 8 Bytes.
- // For protocol version 3.0 they are three integers. The first one is just the size of message
- // so, just read it.
- if (_protocolVersion >= ProtocolVersion.Version3)
- inputStream.Read(inputBuffer, 0, 4);
-
- inputStream.Read(inputBuffer, 0, 8);
- _processId = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(inputBuffer, 0));
- _secretKey = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(inputBuffer, 4));
-
- }
-
- public Int32 ProcessID
- {
- get
- {
+ /// <summary>
+ /// This class represents a BackEndKeyData message received
+ /// from PostgreSQL
+ /// </summary>
+ internal sealed class NpgsqlBackEndKeyData
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlBackEndKeyData";
+
+ private Int32 _processId;
+ private Int32 _secretKey;
+
+ private Int32 _protocolVersion;
+
+ public NpgsqlBackEndKeyData(Int32 protocolVersion)
+ {
+ _protocolVersion = protocolVersion;
+ _processId = -1;
+ _secretKey = -1;
+ }
+
+
+ public void ReadFromStream(Stream inputStream)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
+
+ Byte[] inputBuffer = new Byte[8];
+
+ // Read the BackendKeyData message contents. Two Int32 integers = 8 Bytes.
+ // For protocol version 3.0 they are three integers. The first one is just the size of message
+ // so, just read it.
+ if (_protocolVersion >= ProtocolVersion.Version3)
+ inputStream.Read(inputBuffer, 0, 4);
+
+ inputStream.Read(inputBuffer, 0, 8);
+ _processId = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(inputBuffer, 0));
+ _secretKey = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(inputBuffer, 4));
+
+ }
+
+ public Int32 ProcessID
+ {
+ get
+ {
NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "ProcessID");
- return _processId;
- }
- }
-
- public Int32 SecretKey
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "SecretKey");
- return _secretKey;
- }
- }
- }
+ return _processId;
+ }
+ }
+
+ public Int32 SecretKey
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "SecretKey");
+ return _secretKey;
+ }
+ }
+ }
}
// created on 4/3/2003 at 19:45
// Npgsql.NpgsqlBinaryRow.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- /// <summary>
- /// This class represents the AsciiRow message sent from PostgreSQL
- /// server.
- /// </summary>
- ///
- internal sealed class NpgsqlBinaryRow
- {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlBinaryRow";
-
- private ArrayList data;
- private Byte[] null_map_array;
- private readonly Int16 READ_BUFFER_SIZE = 300; //[FIXME] Is this enough??
- private NpgsqlRowDescription row_desc;
-
- public NpgsqlBinaryRow(NpgsqlRowDescription rowDesc)
- {
+
+ /// <summary>
+ /// This class represents the AsciiRow message sent from PostgreSQL
+ /// server.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlBinaryRow
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlBinaryRow";
+
+ private ArrayList data;
+ private Byte[] null_map_array;
+ private readonly Int16 READ_BUFFER_SIZE = 300; //[FIXME] Is this enough??
+ private NpgsqlRowDescription row_desc;
+
+ public NpgsqlBinaryRow(NpgsqlRowDescription rowDesc)
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
-
- data = new ArrayList();
- row_desc = rowDesc;
- null_map_array = new Byte[(row_desc.NumFields + 7)/8];
-
-
- }
-
-
- public void ReadFromStream(Stream inputStream, Encoding encoding)
- {
+
+ data = new ArrayList();
+ row_desc = rowDesc;
+ null_map_array = new Byte[(row_desc.NumFields + 7)/8];
+
+
+ }
+
+
+ public void ReadFromStream(Stream inputStream, Encoding encoding)
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream");
-
- //Byte[] input_buffer = new Byte[READ_BUFFER_SIZE];
- Byte[] input_buffer = null;
-
- Array.Clear(null_map_array, 0, null_map_array.Length);
-
- // Read the null fields bitmap.
- inputStream.Read(null_map_array, 0, null_map_array.Length );
-
- // Get the data.
- for (Int16 field_count = 0; field_count < row_desc.NumFields; field_count++)
- {
-
- // Check if this field isn't null
- if (IsNull(field_count))
- {
- // Field is null just keep next field.
-
- //[FIXME] See this[] method.
- data.Add(null);
- continue;
- }
-
- // Read the first data of the first row.
-
- PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, 4);
-
- Int32 field_value_size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
-
- Int32 bytes_left = field_value_size; //Size of data is the value read.
-
- input_buffer = new Byte[bytes_left];
-
-
- //StringBuilder result = new StringBuilder();
-
- /*while (bytes_left > READ_BUFFER_SIZE)
- {
- // Now, read just the field value.
- PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, READ_BUFFER_SIZE);
-
- // Read the bytes as string.
- result.Append(new String(encoding.GetChars(input_buffer, 0, READ_BUFFER_SIZE)));
-
- bytes_left -= READ_BUFFER_SIZE;
- }
- */
- // Now, read just the field value.
- PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, bytes_left);
-
- // Read the bytes as string.
- //result.Append(new String(encoding.GetChars(input_buffer, 0, bytes_left)));
-
-
- // Add them to the BinaryRow data.
- //data.Add(NpgsqlTypesHelper.ConvertStringToNpgsqlType(result.ToString(), row_desc[field_count].type_oid));
- data.Add(input_buffer);
-
- }
-
- }
-
-
- public Boolean IsNull(Int32 index)
- {
+
+ //Byte[] input_buffer = new Byte[READ_BUFFER_SIZE];
+ Byte[] input_buffer = null;
+
+ Array.Clear(null_map_array, 0, null_map_array.Length);
+
+ // Read the null fields bitmap.
+ inputStream.Read(null_map_array, 0, null_map_array.Length );
+
+ // Get the data.
+ for (Int16 field_count = 0; field_count < row_desc.NumFields; field_count++)
+ {
+
+ // Check if this field isn't null
+ if (IsNull(field_count))
+ {
+ // Field is null just keep next field.
+
+ //[FIXME] See this[] method.
+ data.Add(null);
+ continue;
+ }
+
+ // Read the first data of the first row.
+
+ PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, 4);
+
+ Int32 field_value_size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
+
+ Int32 bytes_left = field_value_size; //Size of data is the value read.
+
+ input_buffer = new Byte[bytes_left];
+
+
+ //StringBuilder result = new StringBuilder();
+
+ /*while (bytes_left > READ_BUFFER_SIZE)
+ {
+ // Now, read just the field value.
+ PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, READ_BUFFER_SIZE);
+
+ // Read the bytes as string.
+ result.Append(new String(encoding.GetChars(input_buffer, 0, READ_BUFFER_SIZE)));
+
+ bytes_left -= READ_BUFFER_SIZE;
+ }
+ */
+ // Now, read just the field value.
+ PGUtil.CheckedStreamRead(inputStream, input_buffer, 0, bytes_left);
+
+ // Read the bytes as string.
+ //result.Append(new String(encoding.GetChars(input_buffer, 0, bytes_left)));
+
+
+ // Add them to the BinaryRow data.
+ //data.Add(NpgsqlTypesHelper.ConvertStringToNpgsqlType(result.ToString(), row_desc[field_count].type_oid));
+ data.Add(input_buffer);
+
+ }
+
+ }
+
+
+ public Boolean IsNull(Int32 index)
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IsNull");
- // [FIXME] Check more optimized way of doing this.
- // Should this be public or internal?
-
- // Check valid index range.
- if ((index < 0) || (index >= row_desc.NumFields))
- throw new ArgumentOutOfRangeException("index");
-
- // Check if the value (index) of the field is null
-
- // Get the byte that holds the bit index position.
- Byte test_byte = null_map_array[index/8];
-
- // Now, check if index bit is set.
- // To this, get its position in the byte, shift to
- // MSB and test it with the byte 10000000.
- return (((test_byte << (index%8)) & 0x80) == 0);
- }
-
-
- public Object this[Int32 index]
- {
- get
- {
- NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
- if ((index < 0) || (index >= row_desc.NumFields))
- throw new ArgumentOutOfRangeException("this[] index value");
- // [FIXME] Should return null or something else
- // more meaningful?
-
- //[FIXME] This code assumes that the data arraylist has the null and non null values
- // in order, but just the non-null values are added.
- // It is necessary to map the index value with the elements in the array list.
- // For now, the workaround is to insert the null values in the array list.
- // But this is a hack. :)
-
- //return (IsNull(index) ? null : data[index]);
- return data[index];
-
-
-
- }
- }
- }
-
+ // [FIXME] Check more optimized way of doing this.
+ // Should this be public or internal?
+
+ // Check valid index range.
+ if ((index < 0) || (index >= row_desc.NumFields))
+ throw new ArgumentOutOfRangeException("index");
+
+ // Check if the value (index) of the field is null
+
+ // Get the byte that holds the bit index position.
+ Byte test_byte = null_map_array[index/8];
+
+ // Now, check if index bit is set.
+ // To this, get its position in the byte, shift to
+ // MSB and test it with the byte 10000000.
+ return (((test_byte << (index%8)) & 0x80) == 0);
+ }
+
+
+ public Object this[Int32 index]
+ {
+ get
+ {
+ NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
+ if ((index < 0) || (index >= row_desc.NumFields))
+ throw new ArgumentOutOfRangeException("this[] index value");
+ // [FIXME] Should return null or something else
+ // more meaningful?
+
+ //[FIXME] This code assumes that the data arraylist has the null and non null values
+ // in order, but just the non-null values are added.
+ // It is necessary to map the index value with the elements in the array list.
+ // For now, the workaround is to insert the null values in the array list.
+ // But this is a hack. :)
+
+ //return (IsNull(index) ? null : data[index]);
+ return data[index];
+
+
+
+ }
+ }
+ }
+
}
// created on 29/6/2003 at 13:28
// Npgsql.NpgsqlBind.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- /// <summary>
- /// This class represents the Bind message sent to PostgreSQL
- /// server.
- /// </summary>
- ///
- internal sealed class NpgsqlBind
- {
-
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlBind";
-
- private String _portalName;
- private String _preparedStatementName;
- private Int16[] _parameterFormatCodes;
- private Object[] _parameterValues;
- private Int16[] _resultFormatCodes;
-
-
- public NpgsqlBind(String portalName,
- String preparedStatementName,
- Int16[] parameterFormatCodes,
- Object[] parameterValues,
- Int16[] resultFormatCodes)
- {
-
- _portalName = portalName;
- _preparedStatementName = preparedStatementName;
- _parameterFormatCodes = parameterFormatCodes;
- _parameterValues = parameterValues;
- _resultFormatCodes = resultFormatCodes;
-
-
- }
-
- public String PortalName
- {
- get
- {
- return _portalName;
- }
- }
-
- public Int16[] ParameterFormatCodes
- {
- get
- {
- return _parameterFormatCodes;
- }
-
- set
- {
- _parameterFormatCodes = value;
- }
- }
-
- public Object[] ParameterValues
- {
- get
- {
- return _parameterValues;
- }
-
- set
- {
- _parameterValues = value;
- }
- }
-
-
- public void WriteToStream(Stream outputStream, Encoding encoding)
- {
-
-
-
- Int32 messageLength = 4 +
- encoding.GetByteCount(_portalName) + 1 +
- encoding.GetByteCount(_preparedStatementName) + 1 +
- 2 +
- (_parameterFormatCodes.Length * 2) +
- 2;
-
-
- // Get size of parameter values.
- Int32 i;
-
- if (_parameterValues != null)
- for (i = 0; i < _parameterValues.Length; i++)
- {
- messageLength += 4;
- if ( _parameterValues[i] != null)
- if ( ((_parameterFormatCodes.Length == 1) && (_parameterFormatCodes[0] == (Int16) FormatCode.Binary)) ||
- ((_parameterFormatCodes.Length != 1) && (_parameterFormatCodes[i] == (Int16) FormatCode.Binary)) )
- messageLength += ((Byte[])_parameterValues[i]).Length;
- else
- messageLength += encoding.GetByteCount((String)_parameterValues[i]);
-
- }
-
- messageLength += 2 + (_resultFormatCodes.Length * 2);
-
-
- outputStream.WriteByte((Byte)'B');
-
- PGUtil.WriteInt32(outputStream, messageLength);
- PGUtil.WriteString(_portalName, outputStream, encoding);
- PGUtil.WriteString(_preparedStatementName, outputStream, encoding);
-
- PGUtil.WriteInt16(outputStream, (Int16)_parameterFormatCodes.Length);
-
- for (i = 0; i < _parameterFormatCodes.Length; i++)
- PGUtil.WriteInt16(outputStream, _parameterFormatCodes[i]);
-
- if (_parameterValues != null)
- {
- PGUtil.WriteInt16(outputStream, (Int16)_parameterValues.Length);
-
- for (i = 0; i < _parameterValues.Length; i++)
- {
- if ( ((_parameterFormatCodes.Length == 1) && (_parameterFormatCodes[0] == (Int16) FormatCode.Binary)) ||
- ((_parameterFormatCodes.Length != 1) && (_parameterFormatCodes[i] == (Int16) FormatCode.Binary)) )
- {
-
- Byte[] parameterValue = (Byte[])_parameterValues[i];
- if (parameterValue == null)
- PGUtil.WriteInt32(outputStream, -1);
- else
- {
- PGUtil.WriteInt32(outputStream, parameterValue.Length);
- outputStream.Write(parameterValue, 0, parameterValue.Length);
- }
- }
- else
- {
- String parameterValue = (String)_parameterValues[i];
- if (parameterValue == null)
- PGUtil.WriteInt32(outputStream, -1);
- else
- {
- PGUtil.WriteInt32(outputStream, encoding.GetByteCount(parameterValue));
- outputStream.Write(encoding.GetBytes(parameterValue), 0, encoding.GetByteCount(parameterValue));
- }
- }
-
- }
- }
- else
- PGUtil.WriteInt16(outputStream, 0);
-
- PGUtil.WriteInt16(outputStream, (Int16)_resultFormatCodes.Length);
- for (i = 0; i < _resultFormatCodes.Length; i++)
- PGUtil.WriteInt16(outputStream, _resultFormatCodes[i]);
-
-
-
- }
-
- }
+
+ /// <summary>
+ /// This class represents the Bind message sent to PostgreSQL
+ /// server.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlBind
+ {
+
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlBind";
+
+ private String _portalName;
+ private String _preparedStatementName;
+ private Int16[] _parameterFormatCodes;
+ private Object[] _parameterValues;
+ private Int16[] _resultFormatCodes;
+
+
+ public NpgsqlBind(String portalName,
+ String preparedStatementName,
+ Int16[] parameterFormatCodes,
+ Object[] parameterValues,
+ Int16[] resultFormatCodes)
+ {
+
+ _portalName = portalName;
+ _preparedStatementName = preparedStatementName;
+ _parameterFormatCodes = parameterFormatCodes;
+ _parameterValues = parameterValues;
+ _resultFormatCodes = resultFormatCodes;
+
+
+ }
+
+ public String PortalName
+ {
+ get
+ {
+ return _portalName;
+ }
+ }
+
+ public Int16[] ParameterFormatCodes
+ {
+ get
+ {
+ return _parameterFormatCodes;
+ }
+
+ set
+ {
+ _parameterFormatCodes = value;
+ }
+ }
+
+ public Object[] ParameterValues
+ {
+ get
+ {
+ return _parameterValues;
+ }
+
+ set
+ {
+ _parameterValues = value;
+ }
+ }
+
+
+ public void WriteToStream(Stream outputStream, Encoding encoding)
+ {
+
+
+
+ Int32 messageLength = 4 +
+ encoding.GetByteCount(_portalName) + 1 +
+ encoding.GetByteCount(_preparedStatementName) + 1 +
+ 2 +
+ (_parameterFormatCodes.Length * 2) +
+ 2;
+
+
+ // Get size of parameter values.
+ Int32 i;
+
+ if (_parameterValues != null)
+ for (i = 0; i < _parameterValues.Length; i++)
+ {
+ messageLength += 4;
+ if ( _parameterValues[i] != null)
+ if ( ((_parameterFormatCodes.Length == 1) && (_parameterFormatCodes[0] == (Int16) FormatCode.Binary)) ||
+ ((_parameterFormatCodes.Length != 1) && (_parameterFormatCodes[i] == (Int16) FormatCode.Binary)) )
+ messageLength += ((Byte[])_parameterValues[i]).Length;
+ else
+ messageLength += encoding.GetByteCount((String)_parameterValues[i]);
+
+ }
+
+ messageLength += 2 + (_resultFormatCodes.Length * 2);
+
+
+ outputStream.WriteByte((Byte)'B');
+
+ PGUtil.WriteInt32(outputStream, messageLength);
+ PGUtil.WriteString(_portalName, outputStream, encoding);
+ PGUtil.WriteString(_preparedStatementName, outputStream, encoding);
+
+ PGUtil.WriteInt16(outputStream, (Int16)_parameterFormatCodes.Length);
+
+ for (i = 0; i < _parameterFormatCodes.Length; i++)
+ PGUtil.WriteInt16(outputStream, _parameterFormatCodes[i]);
+
+ if (_parameterValues != null)
+ {
+ PGUtil.WriteInt16(outputStream, (Int16)_parameterValues.Length);
+
+ for (i = 0; i < _parameterValues.Length; i++)
+ {
+ if ( ((_parameterFormatCodes.Length == 1) && (_parameterFormatCodes[0] == (Int16) FormatCode.Binary)) ||
+ ((_parameterFormatCodes.Length != 1) && (_parameterFormatCodes[i] == (Int16) FormatCode.Binary)) )
+ {
+
+ Byte[] parameterValue = (Byte[])_parameterValues[i];
+ if (parameterValue == null)
+ PGUtil.WriteInt32(outputStream, -1);
+ else
+ {
+ PGUtil.WriteInt32(outputStream, parameterValue.Length);
+ outputStream.Write(parameterValue, 0, parameterValue.Length);
+ }
+ }
+ else
+ {
+ String parameterValue = (String)_parameterValues[i];
+ if (parameterValue == null)
+ PGUtil.WriteInt32(outputStream, -1);
+ else
+ {
+ PGUtil.WriteInt32(outputStream, encoding.GetByteCount(parameterValue));
+ outputStream.Write(encoding.GetBytes(parameterValue), 0, encoding.GetByteCount(parameterValue));
+ }
+ }
+
+ }
+ }
+ else
+ PGUtil.WriteInt16(outputStream, 0);
+
+ PGUtil.WriteInt16(outputStream, (Int16)_resultFormatCodes.Length);
+ for (i = 0; i < _resultFormatCodes.Length; i++)
+ PGUtil.WriteInt16(outputStream, _resultFormatCodes[i]);
+
+
+
+ }
+
+ }
}
// Npgsql.NpgsqlClosedState.cs
-//
+//
// Author:
// Dave Joyner <d4ljoyn@yahoo.com>
//
// 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.Resources;
using Mono.Security.Protocol.Tls;
-namespace Npgsql {
-
- internal sealed class NpgsqlClosedState : NpgsqlState {
+namespace Npgsql
+{
- private static NpgsqlClosedState _instance = null;
+ internal sealed class NpgsqlClosedState : NpgsqlState
+ {
+
+ private static NpgsqlClosedState _instance = null;
private static readonly String CLASSNAME = "NpgsqlClosedState";
- private NpgsqlClosedState() : base() { }
-
- public static NpgsqlClosedState Instance {
- get {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Instance");
- if (_instance == null) {
- _instance = new NpgsqlClosedState();
- }
- return _instance;
- }
- }
+ private NpgsqlClosedState() : base()
+ { }
+
+ public static NpgsqlClosedState Instance {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Instance");
+ if (_instance == null)
+ {
+ _instance = new NpgsqlClosedState();
+ }
+ return _instance;
+ }
+ }
- public override void Open(NpgsqlConnection context) {
+ public override void Open(NpgsqlConnection context)
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open");
-
- IPEndPoint serverEndPoint;
- // Open the connection to the backend.
- // context.TcpClient = new TcpClient();
- // If it was specified an IP address in doted notation
- // (i.e.:192.168.0.1), there may be a long delay trying
- // resolve it when it is not necessary.
- // So, try first connect as if it was a dotted ip address.
- try {
- IPAddress ipserver = IPAddress.Parse(context.ServerName);
- serverEndPoint = new IPEndPoint(ipserver, Int32.Parse(context.ServerPort));
- }
- catch(FormatException) { // The exception isn't used.
- // Server isn't in dotted decimal format. Just connect using DNS resolves.
- IPHostEntry serverHostEntry = Dns.GetHostByName(context.ServerName);
- serverEndPoint = new IPEndPoint(serverHostEntry.AddressList[0], Int32.Parse(context.ServerPort));
- }
// Create a new TLS Session
- try {
- TcpClient tcpc = new TcpClient(context.ServerName, Int32.Parse(context.ServerPort));
- Stream stream = tcpc.GetStream();
- // If the PostgreSQL server has SSL connections enabled Open SslClientStream if (response == 'S') {
- if (context.SSL == "yes") {
- PGUtil.WriteInt32(stream, 8);
- PGUtil.WriteInt32(stream,80877103);
- // Receive response
- Char response = (Char)stream.ReadByte();
- if (response == 'S') {
- stream = new SslClientStream(tcpc.GetStream(), context.ServerName, true, Mono.Security.Protocol.Tls.SecurityProtocolType.Default);
- }
- }
- context.NormalStream = stream;
- context.BufferedStream = new BufferedStream(stream);
- }
- catch (TlsException e) {
- throw new NpgsqlException(e.ToString());
- }
- NpgsqlEventLog.LogMsg(resman, "Log_ConnectedTo", LogLevel.Normal, serverEndPoint.Address, serverEndPoint.Port);
- ChangeState(context, NpgsqlConnectedState.Instance);
- context.Startup();
- }
+ try
+ {
+ TcpClient tcpc = new TcpClient(context.ServerName, Int32.Parse(context.ServerPort));
+ Stream stream = tcpc.GetStream();
+ // If the PostgreSQL server has SSL connections enabled Open SslClientStream if (response == 'S') {
+ if (context.SSL == "yes")
+ {
+ PGUtil.WriteInt32(stream, 8);
+ PGUtil.WriteInt32(stream,80877103);
+ // Receive response
+ Char response = (Char)stream.ReadByte();
+ if (response == 'S')
+ {
+ stream = new SslClientStream(tcpc.GetStream(), context.ServerName, true, Mono.Security.Protocol.Tls.SecurityProtocolType.Default);
+ }
+ }
+ context.Stream = stream;
+
+ }
+ catch (TlsException e)
+ {
+ throw new NpgsqlException(e.ToString());
+ }
+ NpgsqlEventLog.LogMsg(resman, "Log_ConnectedTo", LogLevel.Normal, context.ServerName, context.ServerPort);
+ ChangeState(context, NpgsqlConnectedState.Instance);
+ context.Startup();
+ }
- }
+ }
}
// created on 21/5/2002 at 20:03
// Npgsql.NpgsqlCommand.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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 NpgsqlTypes;
using Npgsql.Design;
-namespace Npgsql {
- /// <summary>
- /// Represents a SQL statement or function (stored procedure) to execute against a PostgreSQL database. This class cannot be inherited.
- /// </summary>
- [System.Drawing.ToolboxBitmapAttribute(typeof(NpgsqlCommand)), ToolboxItem(true)]
- public sealed class NpgsqlCommand : Component, IDbCommand, IDisposable {
-
- private NpgsqlConnection connection;
- private NpgsqlTransaction transaction;
- private String text;
- private Int32 timeout;
- private CommandType type;
- private NpgsqlParameterCollection parameters;
- private String planName;
- private static Int32 planIndex = 0;
- private static Int32 portalIndex = 0;
-
- private NpgsqlParse parse;
- private NpgsqlBind bind;
-
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlCommand";
- private System.Resources.ResourceManager resman;
-
- // Constructors
-
- /// <summary>
- /// Initializes a new instance of the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> class.
- /// </summary>
- public NpgsqlCommand() : this(String.Empty, null, null){}
- /// <summary>
- /// Initializes a new instance of the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> class with the text of the query.
- /// </summary>
- /// <param name="cmdText">The text of the query.</param>
- public NpgsqlCommand(String cmdText) : this(cmdText, null, null){}
- /// <summary>
- /// Initializes a new instance of the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> class with the text of the query and a <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>.
- /// </summary>
- /// <param name="cmdText">The text of the query.</param>
- /// <param name="connection">A <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see> that represents the connection to a PostgreSQL server.</param>
- public NpgsqlCommand(String cmdText, NpgsqlConnection connection) : this(cmdText, connection, null){}
- /// <summary>
- /// Initializes a new instance of the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> class with the text of the query, a <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>, and the <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>.
- /// </summary>
- /// <param name="cmdText">The text of the query.</param>
- /// <param name="connection">A <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see> that represents the connection to a PostgreSQL server.</param>
- /// <param name="transaction">The <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see> in which the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> executes.</param>
- public NpgsqlCommand(String cmdText, NpgsqlConnection connection, NpgsqlTransaction transaction) {
- resman = new System.Resources.ResourceManager(this.GetType());
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
-
- planName = String.Empty;
- text = cmdText;
- this.connection = connection;
- parameters = new NpgsqlParameterCollection();
- timeout = 20;
- type = CommandType.Text;
- this.Transaction = transaction;
- }
-
- /// <summary>
- /// Finalizer for <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>.
- /// </summary>
- ~NpgsqlCommand () {
- Dispose(false);
- }
-
- // Public properties.
- /// <summary>
- /// Gets or sets the SQL statement or function (stored procedure) to execute at the data source.
- /// </summary>
- /// <value>The Transact-SQL statement or stored procedure to execute. The default is an empty string.</value>
- [Category("Data"), DefaultValue("")]
- public String CommandText {
- get {
- return text;
- }
-
- set {
- // [TODO] Validate commandtext.
- NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "CommandText", value);
- text = value;
- planName = String.Empty;
- parse = null;
- bind = null;
- }
- }
-
- /// <summary>
- /// Gets or sets the wait time before terminating the attempt
- /// to execute a command and generating an error.
- /// </summary>
- /// <value>The time (in seconds) to wait for the command to execute.
- /// The default is 20 seconds.</value>
- [DefaultValue(20)]
- public Int32 CommandTimeout {
- get {
- return timeout;
- }
-
- set {
- if (value < 0)
- throw new ArgumentException(resman.GetString("Exception_CommandTimeoutLessZero"));
-
- timeout = value;
- NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "CommandTimeout", value);
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating how the
- /// <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> property is to be interpreted.
- /// </summary>
- /// <value>One of the <see cref="System.Data.CommandType">CommandType</see> values. The default is <see cref="System.Data.CommandType">CommandType.Text</see>.</value>
- [Category("Data"), DefaultValue(CommandType.Text)]
- public CommandType CommandType {
- get {
- return type;
- }
-
- set {
- type = value;
- NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "CommandType", value);
- }
-
- }
-
- IDbConnection IDbCommand.Connection {
- get {
- return Connection;
- }
-
- set {
- connection = (NpgsqlConnection) value;
- NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "IDbCommand.Connection", value);
- }
- }
-
- /// <summary>
- /// Gets or sets the <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>
- /// used by this instance of the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>.
- /// </summary>
- /// <value>The connection to a data source. The default value is a null reference.</value>
- [Category("Behavior"), DefaultValue(null)]
- public NpgsqlConnection Connection {
- get {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Connection");
- return connection;
- }
-
- set {
- if (this.transaction != null && this.transaction.Connection == null)
- this.transaction = null;
- if (this.connection != null && this.connection.InTransaction == true)
- throw new NpgsqlException(resman.GetString("Exception_SetConnectionInTransaction"));
- this.connection = value;
- NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "Connection", value);
- }
- }
-
- IDataParameterCollection IDbCommand.Parameters {
- get {
- return Parameters;
- }
- }
-
- /// <summary>
- /// Gets the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see>.
- /// </summary>
- /// <value>The parameters of the SQL statement or function (stored procedure). The default is an empty collection.</value>
- [Category("Data"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
- public NpgsqlParameterCollection Parameters {
- get {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Parameters");
- return parameters;
- }
- }
-
- /// <summary>
- /// Gets or sets the <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>
- /// within which the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> executes.
- /// </summary>
- /// <value>The <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>.
- /// The default value is a null reference.</value>
- [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public IDbTransaction Transaction {
- get {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Transaction");
- //throw new NotImplementedException();
- if (this.transaction != null && this.transaction.Connection == null){
- this.transaction = null;
- }
- return this.transaction;
- }
-
- set {
- NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "Transaction" ,value);
- //throw new NotImplementedException();
- /*if (this.connection != null && this.connection.InTransaction == true){
- throw new NpgsqlException(resman.GetString("Exception_SetTransactionInTransaction"));
- }*/
- this.transaction = (NpgsqlTransaction) value;
- }
- }
-
- /// <summary>
- /// Gets or sets how command results are applied to the <see cref="System.Data.DataRow">DataRow</see>
- /// when used by the <see cref="System.Data.Common.DbDataAdapter.Update">Update</see>
- /// method of the <see cref="System.Data.Common.DbDataAdapter">DbDataAdapter</see>.
- /// </summary>
- /// <value>One of the <see cref="System.Data.UpdateRowSource">UpdateRowSource</see> values.</value>
- [Category("Behavior"), DefaultValue(UpdateRowSource.Both)]
- public UpdateRowSource UpdatedRowSource {
- get {
-
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "UpdatedRowSource");
- // [FIXME] Strange, the line below doesn't appears in the stack trace.
-
- //throw new NotImplementedException();
- return UpdateRowSource.Both;
- }
-
- set {
- throw new NotImplementedException();
- }
- }
-
- private void CheckNotification() {
- if (connection.Mediator.Notifications.Count > 0)
- for (int i=0; i < connection.Mediator.Notifications.Count; i++)
- connection.Notify((NpgsqlNotificationEventArgs) connection.Mediator.Notifications[i]);
-
- }
-
- /// <summary>
- /// Attempts to cancel the execution of a <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>.
- /// </summary>
- /// <remarks>This Method isn't implemented yet.</remarks>
- public void Cancel() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Cancel");
-
- // [TODO] Finish method implementation.
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Creates a new instance of an <see cref="System.Data.IDbDataParameter">IDbDataParameter</see> object.
- /// </summary>
- /// <returns>An <see cref="System.Data.IDbDataParameter">IDbDataParameter</see> object.</returns>
- IDbDataParameter IDbCommand.CreateParameter() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbCommand.CreateParameter");
-
- return (NpgsqlParameter) CreateParameter();
- }
-
- /// <summary>
- /// Creates a new instance of a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.
- /// </summary>
- /// <returns>A <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
- public NpgsqlParameter CreateParameter() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CreateParameter");
-
- return new NpgsqlParameter();
- }
-
- /// <summary>
- /// Executes a SQL statement against the connection and returns the number of rows affected.
- /// </summary>
- /// <returns>The number of rows affected.</returns>
- public Int32 ExecuteNonQuery() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ExecuteNonQuery");
-
- // Check the connection state.
- CheckConnectionState();
-
- /*if ((type == CommandType.Text) || (type == CommandType.StoredProcedure))
- if (parse == null)
- connection.Query(this);
- else
- {
- BindParameters();
- connection.Execute(new NpgsqlExecute(bind.PortalName, 0));
- }
- else
- throw new NotImplementedException(resman.GetString("Exception_CommandTypeTableDirect"));
- */
-
- ExecuteCommand();
-
- // Check if there were any errors.
- if (connection.Mediator.Errors.Count > 0) {
- StringWriter sw = new StringWriter();
- sw.WriteLine(String.Format(resman.GetString("Exception_MediatorErrors"), "ExecuteNonQuery"));
- uint i = 1;
- foreach(string error in connection.Mediator.Errors){
- sw.WriteLine("{0}. {1}", i++, error);
- }
- throw new NpgsqlException(sw.ToString());
- }
-
- CheckNotification();
-
-
-
- // The only expected result is the CompletedResponse result.
- // If nothing is returned, just return -1.
-
- if(connection.Mediator.GetCompletedResponses().Count == 0)
- return -1;
-
- String[] ret_string_tokens = ((String)connection.Mediator.GetCompletedResponses()[0]).Split(null); // whitespace separator.
-
- // Check if the command was insert, delete or update.
- // Only theses commands return rows affected.
- // [FIXME] Is there a better way to check this??
- if ((String.Compare(ret_string_tokens[0], "INSERT", true) == 0) ||
- (String.Compare(ret_string_tokens[0], "UPDATE", true) == 0) ||
- (String.Compare(ret_string_tokens[0], "DELETE", true) == 0))
-
- // The number of rows affected is in the third token for insert queries
- // and in the second token for update and delete queries.
- // In other words, it is the last token in the 0-based array.
-
- return Int32.Parse(ret_string_tokens[ret_string_tokens.Length - 1]);
- else
- return -1;
-
- }
-
- /// <summary>
- /// Sends the <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> to
- /// the <see cref="Npgsql.NpgsqlConnection">Connection</see> and builds a
- /// <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see>.
- /// </summary>
- /// <returns>A <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see> object.</returns>
- IDataReader IDbCommand.ExecuteReader() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbCommand.ExecuteReader");
-
- return (NpgsqlDataReader) ExecuteReader();
- }
-
- /// <summary>
- /// Sends the <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> to
- /// the <see cref="Npgsql.NpgsqlConnection">Connection</see> and builds a
- /// <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see>
- /// using one of the <see cref="System.Data.CommandBehavior">CommandBehavior</see> values.
- /// </summary>
- /// <param name="cb">One of the <see cref="System.Data.CommandBehavior">CommandBehavior</see> values.</param>
- /// <returns>A <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see> object.</returns>
- IDataReader IDbCommand.ExecuteReader(CommandBehavior cb) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbCommand.ExecuteReader", cb);
-
- return (NpgsqlDataReader) ExecuteReader(cb);
-
- }
-
- /// <summary>
- /// Sends the <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> to
- /// the <see cref="Npgsql.NpgsqlConnection">Connection</see> and builds a
- /// <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see>.
- /// </summary>
- /// <returns>A <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see> object.</returns>
- public NpgsqlDataReader ExecuteReader() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ExecuteReader");
-
-
- return ExecuteReader(CommandBehavior.Default);
-
- }
-
- /// <summary>
- /// Sends the <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> to
- /// the <see cref="Npgsql.NpgsqlConnection">Connection</see> and builds a
- /// <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see>
- /// using one of the <see cref="System.Data.CommandBehavior">CommandBehavior</see> values.
- /// </summary>
- /// <param name="cb">One of the <see cref="System.Data.CommandBehavior">CommandBehavior</see> values.</param>
- /// <returns>A <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see> object.</returns>
- /// <remarks>Currently the CommandBehavior parameter is ignored.</remarks>
- public NpgsqlDataReader ExecuteReader(CommandBehavior cb) {
- // [FIXME] No command behavior handling.
-
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ExecuteReader", cb);
-
- // Check the connection state.
- CheckConnectionState();
-
- /*if ((type == CommandType.Text) || (type == CommandType.StoredProcedure))
- if (parse == null)
- connection.Query(this);
- else
- {
- BindParameters();
- connection.Execute(new NpgsqlExecute(bind.PortalName, 0));
- }
- else
- throw new NotImplementedException(resman.GetString("Exception_CommandTypeTableDirect"));
- */
-
- ExecuteCommand();
-
- // Check if there were any errors.
- if (connection.Mediator.Errors.Count > 0) {
- StringWriter sw = new StringWriter();
- sw.WriteLine(String.Format(resman.GetString("Exception_MediatorErrors_1P"), "ExecuteReader", cb));
- uint i = 1;
- foreach(string error in connection.Mediator.Errors){
- sw.WriteLine("{0}. {1}", i++, error);
- }
- throw new NpgsqlException(sw.ToString());
- }
-
- CheckNotification();
-
-
- // Get the resultsets and create a Datareader with them.
- return new NpgsqlDataReader(connection.Mediator.GetResultSets(), connection.Mediator.GetCompletedResponses(), connection);
- }
-
-
- ///<summary>
- /// This method binds the parameters from parameters collection to the bind
- /// message.
- /// </summary>
- private void BindParameters()
- {
-
- if (parameters.Count != 0)
- {
- Object[] parameterValues = new Object[parameters.Count];
- for (Int32 i = 0; i < parameters.Count; i++)
- {
- parameterValues[i] = NpgsqlTypesHelper.ConvertNpgsqlParameterToBackendStringValue(parameters[i]);
- }
- bind.ParameterValues = parameterValues;
- }
-
- connection.Bind(bind);
- connection.Flush();
-
- }
-
-
- /// <summary>
- /// Executes the query, and returns the first column of the first row
- /// in the result set returned by the query. Extra columns or rows are ignored.
- /// </summary>
- /// <returns>The first column of the first row in the result set,
- /// or a null reference if the result set is empty.</returns>
- public Object ExecuteScalar() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ExecuteScalar");
-
-
- // Check the connection state.
- CheckConnectionState();
-
- /*if ((type == CommandType.Text) || (type == CommandType.StoredProcedure))
- if (parse == null)
- connection.Query(this);
- else
- {
- BindParameters();
- connection.Execute(new NpgsqlExecute(bind.PortalName, 0));
- }
- else
- throw new NotImplementedException(resman.GetString("Exception_CommandTypeTableDirect"));
- */
-
- ExecuteCommand();
-
- // Check if there were any errors.
- // [FIXME] Just check the first error.
- if (connection.Mediator.Errors.Count > 0) {
- StringWriter sw = new StringWriter();
- sw.WriteLine(String.Format(resman.GetString("Exception_MediatorErrors"), "ExecuteScalar"));
- uint i = 1;
- foreach(string error in connection.Mediator.Errors){
- sw.WriteLine("{0}. {1}", i++, error);
- }
- throw new NpgsqlException(sw.ToString());
- }
-
- CheckNotification();
-
- //ArrayList results = connection.Mediator.Data;
-
- //Object result = null; // Result of the ExecuteScalar().
-
-
- // Now get the results.
- // Only the first column of the first row must be returned.
-
- // Get ResultSets.
- ArrayList resultSets = connection.Mediator.GetResultSets();
-
-
- // First data is the RowDescription object.
- //NpgsqlRowDescription rd = (NpgsqlRowDescription)results[0];
-
- NpgsqlResultSet firstResultSet = (NpgsqlResultSet)resultSets[0];
-
- NpgsqlRowDescription rd = firstResultSet.RowDescription;
-
- NpgsqlAsciiRow ascii_row = (NpgsqlAsciiRow)firstResultSet[0];
-
- return ascii_row[0];
-
-
- }
-
- /// <summary>
- /// Creates a prepared version of the command on a PostgreSQL server.
- /// </summary>
- public void Prepare() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Prepare");
-
- // Check the connection state.
- CheckConnectionState();
-
- if (!connection.SupportsPrepare)
- return; // Do nothing.
-
-
-
- // [TODO] Finish method implementation.
- //throw new NotImplementedException();
-
- //NpgsqlCommand command = new NpgsqlCommand("prepare plan1 as " + GetCommandText(), connection );
-
- if (connection.BackendProtocolVersion == ProtocolVersion.Version2)
- {
- NpgsqlCommand command = new NpgsqlCommand(GetPrepareCommandText(), connection );
- command.ExecuteNonQuery();
- }
- else
- {
- // Use the extended query parsing...
- planName = "NpgsqlPlan" + System.Threading.Interlocked.Increment(ref planIndex);
- String portalName = "NpgsqlPortal" + System.Threading.Interlocked.Increment(ref portalIndex);
-
- parse = new NpgsqlParse(planName, GetParseCommandText(), new Int32[] {});
-
- connection.Parse(parse);
- connection.Flush();
-
- bind = new NpgsqlBind(portalName, planName, new Int16[] {0}, null, new Int16[] {0});
-
- }
- }
-
- /// <summary>
- /// Releases the resources used by the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>.
- /// </summary>
- protected override void Dispose (bool disposing) {
- if (disposing) {
- if (connection != null) {
- connection.Dispose();
- }
- base.Dispose(disposing);
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Dispose");
- }
- }
-
- ///<summary>
- /// This method checks the connection state to see if the connection
- /// is set or it is open. If one of this conditions is not met, throws
- /// an InvalidOperationException
- ///</summary>
- private void CheckConnectionState() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CheckConnectionState");
-
- // Check the connection state.
- if (connection == null)
- throw new InvalidOperationException(resman.GetString("Exception_ConnectionNull"));
- if (connection.State != ConnectionState.Open)
- throw new InvalidOperationException(resman.GetString("Exception_ConnectionNotOpen"));
-
- }
-
- /// <summary>
- /// This method substitutes the <see cref="Npgsql.NpgsqlCommand.Parameters">Parameters</see>, if exist, in the command
- /// to their actual values.
- /// The parameter name format is <b>:ParameterName</b>.
- /// </summary>
- /// <returns>A version of <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> with the <see cref="Npgsql.NpgsqlCommand.Parameters">Parameters</see> inserted.</returns>
- internal String GetCommandText() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetCommandText");
-
- if (planName == String.Empty)
- return GetClearCommandText();
- else
- return GetPreparedCommandText();
-
-
- }
-
-
- private String GetClearCommandText() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetClearCommandText");
-
-
- String result = text;
-
- if (type == CommandType.StoredProcedure)
- if (connection.SupportsPrepare)
- result = "select * from " + result; // This syntax is only available in 7.3+ as well SupportsPrepare.
- else
- result = "select " + result; // Only a single result return supported. 7.2 and earlier.
- else if (type == CommandType.TableDirect)
- return "select * from " + result; // There is no parameter support on table direct.
-
- if (parameters.Count == 0)
- return result;
-
-
- //CheckParameters();
-
- String parameterName;
-
- for (Int32 i = 0; i < parameters.Count; i++) {
- parameterName = parameters[i].ParameterName;
-
- result = ReplaceParameterValue(result, parameterName, NpgsqlTypesHelper.ConvertNpgsqlParameterToBackendStringValue(parameters[i]));
-
- }
-
- return result;
-
- }
-
-
-
- private String GetPreparedCommandText() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetPreparedCommandText");
-
- if (parameters.Count == 0)
- return "execute " + planName;
-
-
- StringBuilder result = new StringBuilder("execute " + planName + '(');
-
-
- for (Int32 i = 0; i < parameters.Count; i++) {
- result.Append(NpgsqlTypesHelper.ConvertNpgsqlParameterToBackendStringValue(parameters[i]) + ',');
- }
-
- result = result.Remove(result.Length - 1, 1);
- result.Append(')');
-
- return result.ToString();
-
- }
-
-
-
- private String GetParseCommandText()
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetParseCommandText");
-
- String parseCommand = text;
-
- if (type == CommandType.StoredProcedure)
- parseCommand = "select * from " + parseCommand; // This syntax is only available in 7.3+ as well SupportsPrepare.
- else if (type == CommandType.TableDirect)
- return "select * from " + parseCommand; // There is no parameter support on TableDirect.
-
- if (parameters.Count > 0)
- {
- // The ReplaceParameterValue below, also checks if the parameter is present.
-
- String parameterName;
- Int32 i;
-
- for (i = 0; i < parameters.Count; i++)
- {
- //result = result.Replace(":" + parameterName, parameters[i].Value.ToString());
- parameterName = parameters[i].ParameterName;
- //textCommand = textCommand.Replace(':' + parameterName, "$" + (i+1));
- parseCommand = ReplaceParameterValue(parseCommand, parameterName, "$" + (i+1));
-
- }
- }
-
- return parseCommand;
-
- }
-
-
- private String GetPrepareCommandText() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetPrepareCommandText");
-
-
-
- planName = "NpgsqlPlan" + System.Threading.Interlocked.Increment(ref planIndex);
-
- StringBuilder command = new StringBuilder("prepare " + planName);
-
- String textCommand = text;
-
- if (type == CommandType.StoredProcedure)
- textCommand = "select * from " + textCommand;
- else if (type == CommandType.TableDirect)
- return "select * from " + textCommand; // There is no parameter support on TableDirect.
-
-
- if (parameters.Count > 0) {
- // The ReplaceParameterValue below, also checks if the parameter is present.
-
- String parameterName;
- Int32 i;
-
- for (i = 0; i < parameters.Count; i++) {
- //result = result.Replace(":" + parameterName, parameters[i].Value.ToString());
- parameterName = parameters[i].ParameterName;
- // The space in front of '$' fixes a parsing problem in 7.3 server
- // which gives errors of operator when finding the caracters '=$' in
- // prepare text
- textCommand = ReplaceParameterValue(textCommand, parameterName, " $" + (i+1));
-
- }
-
- //[TODO] Check if there is any missing parameters in the query.
- // For while, an error is thrown saying about the ':' char.
-
- command.Append('(');
-
- for (i = 0; i < parameters.Count; i++) {
- command.Append(NpgsqlTypesHelper.GetBackendTypeNameFromDbType(parameters[i].DbType));
-
- command.Append(',');
- }
-
- command = command.Remove(command.Length - 1, 1);
- command.Append(')');
-
- }
-
- command.Append(" as ");
- command.Append(textCommand);
-
-
- return command.ToString();
-
- }
-
-
- private String ReplaceParameterValue(String result, String parameterName, String paramVal) {
- Int32 resLen = result.Length;
- Int32 paramStart = result.IndexOf(parameterName);
- Int32 paramLen = parameterName.Length;
- Int32 paramEnd = paramStart + paramLen;
- Boolean found = false;
-
- while(paramStart > -1) {
- if((resLen > paramEnd) &&
- (result[paramEnd] == ' ' ||
- result[paramEnd] == ',' ||
- result[paramEnd] == ')' ||
- result[paramEnd] == ';')) {
- result = result.Substring(0, paramStart) + paramVal + result.Substring(paramEnd);
- found = true;
- }
- else if(resLen == paramEnd) {
- result = result.Substring(0, paramStart)+ paramVal;
- found = true;
- }
- else
- break;
- resLen = result.Length;
- paramStart = result.IndexOf(parameterName, paramStart);
- paramEnd = paramStart + paramLen;
-
- }//while
- if(!found)
- throw new NpgsqlException(String.Format(resman.GetString("Exception_ParamNotInQuery"), parameterName));
-
- return result;
- }//ReplaceParameterValue
-
-
- private void ExecuteCommand()
- {
- //if ((type == CommandType.Text) || (type == CommandType.StoredProcedure))
- if (parse == null)
- connection.Query(this);
- else
- {
- BindParameters();
- connection.Execute(new NpgsqlExecute(bind.PortalName, 0));
- }
- /* else
- throw new NotImplementedException(resman.GetString("Exception_CommandTypeTableDirect"));*/
-
- }
-
-
- }
-
+namespace Npgsql
+{
+ /// <summary>
+ /// Represents a SQL statement or function (stored procedure) to execute against a PostgreSQL database. This class cannot be inherited.
+ /// </summary>
+ [System.Drawing.ToolboxBitmapAttribute(typeof(NpgsqlCommand)), ToolboxItem(true)]
+ public sealed class NpgsqlCommand : Component, IDbCommand, IDisposable
+ {
+
+ private NpgsqlConnection connection;
+ private NpgsqlTransaction transaction;
+ private String text;
+ private Int32 timeout;
+ private CommandType type;
+ private NpgsqlParameterCollection parameters;
+ private String planName;
+ private static Int32 planIndex = 0;
+ private static Int32 portalIndex = 0;
+
+ private NpgsqlParse parse;
+ private NpgsqlBind bind;
+
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlCommand";
+ private System.Resources.ResourceManager resman;
+
+ // Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> class.
+ /// </summary>
+ public NpgsqlCommand() : this(String.Empty, null, null)
+ {}
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> class with the text of the query.
+ /// </summary>
+ /// <param name="cmdText">The text of the query.</param>
+ public NpgsqlCommand(String cmdText) : this(cmdText, null, null)
+ {}
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> class with the text of the query and a <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>.
+ /// </summary>
+ /// <param name="cmdText">The text of the query.</param>
+ /// <param name="connection">A <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see> that represents the connection to a PostgreSQL server.</param>
+ public NpgsqlCommand(String cmdText, NpgsqlConnection connection) : this(cmdText, connection, null)
+ {}
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> class with the text of the query, a <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>, and the <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>.
+ /// </summary>
+ /// <param name="cmdText">The text of the query.</param>
+ /// <param name="connection">A <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see> that represents the connection to a PostgreSQL server.</param>
+ /// <param name="transaction">The <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see> in which the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> executes.</param>
+ public NpgsqlCommand(String cmdText, NpgsqlConnection connection, NpgsqlTransaction transaction)
+ {
+ resman = new System.Resources.ResourceManager(this.GetType());
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
+
+ planName = String.Empty;
+ text = cmdText;
+ this.connection = connection;
+ parameters = new NpgsqlParameterCollection();
+ timeout = 20;
+ type = CommandType.Text;
+ this.Transaction = transaction;
+ }
+
+ /// <summary>
+ /// Finalizer for <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>.
+ /// </summary>
+ ~NpgsqlCommand ()
+ {
+ Dispose(false);
+ }
+
+ // Public properties.
+ /// <summary>
+ /// Gets or sets the SQL statement or function (stored procedure) to execute at the data source.
+ /// </summary>
+ /// <value>The Transact-SQL statement or stored procedure to execute. The default is an empty string.</value>
+ [Category("Data"), DefaultValue("")]
+ public String CommandText {
+ get
+ {
+ return text;
+ }
+
+ set
+ {
+ // [TODO] Validate commandtext.
+ NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "CommandText", value);
+ text = value;
+ planName = String.Empty;
+ parse = null;
+ bind = null;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the wait time before terminating the attempt
+ /// to execute a command and generating an error.
+ /// </summary>
+ /// <value>The time (in seconds) to wait for the command to execute.
+ /// The default is 20 seconds.</value>
+ [DefaultValue(20)]
+ public Int32 CommandTimeout {
+ get
+ {
+ return timeout;
+ }
+
+ set
+ {
+ if (value < 0)
+ throw new ArgumentException(resman.GetString("Exception_CommandTimeoutLessZero"));
+
+ timeout = value;
+ NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "CommandTimeout", value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating how the
+ /// <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> property is to be interpreted.
+ /// </summary>
+ /// <value>One of the <see cref="System.Data.CommandType">CommandType</see> values. The default is <see cref="System.Data.CommandType">CommandType.Text</see>.</value>
+ [Category("Data"), DefaultValue(CommandType.Text)]
+ public CommandType CommandType {
+ get
+ {
+ return type;
+ }
+
+ set
+ {
+ type = value;
+ NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "CommandType", value);
+ }
+
+ }
+
+ IDbConnection IDbCommand.Connection {
+ get
+ {
+ return Connection;
+ }
+
+ set
+ {
+ connection = (NpgsqlConnection) value;
+ NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "IDbCommand.Connection", value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>
+ /// used by this instance of the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>.
+ /// </summary>
+ /// <value>The connection to a data source. The default value is a null reference.</value>
+ [Category("Behavior"), DefaultValue(null)]
+ public NpgsqlConnection Connection {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Connection");
+ return connection;
+ }
+
+ set
+ {
+ if (this.transaction != null && this.transaction.Connection == null)
+ this.transaction = null;
+ if (this.connection != null && this.connection.InTransaction == true)
+ throw new NpgsqlException(resman.GetString("Exception_SetConnectionInTransaction"));
+ this.connection = value;
+ NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "Connection", value);
+ }
+ }
+
+ IDataParameterCollection IDbCommand.Parameters {
+ get
+ {
+ return Parameters;
+ }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see>.
+ /// </summary>
+ /// <value>The parameters of the SQL statement or function (stored procedure). The default is an empty collection.</value>
+ [Category("Data"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ public NpgsqlParameterCollection Parameters {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Parameters");
+ return parameters;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>
+ /// within which the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> executes.
+ /// </summary>
+ /// <value>The <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>.
+ /// The default value is a null reference.</value>
+ [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public IDbTransaction Transaction {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Transaction");
+ //throw new NotImplementedException();
+ if (this.transaction != null && this.transaction.Connection == null)
+ {
+ this.transaction = null;
+ }
+ return this.transaction;
+ }
+
+ set
+ {
+ NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "Transaction" ,value);
+ //throw new NotImplementedException();
+ /*if (this.connection != null && this.connection.InTransaction == true){
+ throw new NpgsqlException(resman.GetString("Exception_SetTransactionInTransaction"));
+ }*/
+ this.transaction = (NpgsqlTransaction) value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets how command results are applied to the <see cref="System.Data.DataRow">DataRow</see>
+ /// when used by the <see cref="System.Data.Common.DbDataAdapter.Update">Update</see>
+ /// method of the <see cref="System.Data.Common.DbDataAdapter">DbDataAdapter</see>.
+ /// </summary>
+ /// <value>One of the <see cref="System.Data.UpdateRowSource">UpdateRowSource</see> values.</value>
+ [Category("Behavior"), DefaultValue(UpdateRowSource.Both)]
+ public UpdateRowSource UpdatedRowSource {
+ get
+ {
+
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "UpdatedRowSource");
+ // [FIXME] Strange, the line below doesn't appears in the stack trace.
+
+ //throw new NotImplementedException();
+ return UpdateRowSource.Both;
+ }
+
+ set
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ private void CheckNotification()
+ {
+ if (connection.Mediator.Notifications.Count > 0)
+ for (int i=0; i < connection.Mediator.Notifications.Count; i++)
+ connection.Notify((NpgsqlNotificationEventArgs) connection.Mediator.Notifications[i]);
+
+ }
+
+ /// <summary>
+ /// Attempts to cancel the execution of a <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>.
+ /// </summary>
+ /// <remarks>This Method isn't implemented yet.</remarks>
+ public void Cancel()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Cancel");
+
+ // [TODO] Finish method implementation.
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Creates a new instance of an <see cref="System.Data.IDbDataParameter">IDbDataParameter</see> object.
+ /// </summary>
+ /// <returns>An <see cref="System.Data.IDbDataParameter">IDbDataParameter</see> object.</returns>
+ IDbDataParameter IDbCommand.CreateParameter()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbCommand.CreateParameter");
+
+ return (NpgsqlParameter) CreateParameter();
+ }
+
+ /// <summary>
+ /// Creates a new instance of a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.
+ /// </summary>
+ /// <returns>A <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
+ public NpgsqlParameter CreateParameter()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CreateParameter");
+
+ return new NpgsqlParameter();
+ }
+
+ /// <summary>
+ /// Executes a SQL statement against the connection and returns the number of rows affected.
+ /// </summary>
+ /// <returns>The number of rows affected.</returns>
+ public Int32 ExecuteNonQuery()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ExecuteNonQuery");
+
+ // Check the connection state.
+ CheckConnectionState();
+
+ ExecuteCommand();
+
+ // Check if there were any errors.
+ if (connection.Mediator.Errors.Count > 0)
+ {
+ StringWriter sw = new StringWriter();
+ sw.WriteLine(String.Format(resman.GetString("Exception_MediatorErrors"), "ExecuteNonQuery"));
+ uint i = 1;
+ foreach(string error in connection.Mediator.Errors)
+ {
+ sw.WriteLine("{0}. {1}", i++, error);
+ }
+ throw new NpgsqlException(sw.ToString());
+ }
+
+ CheckNotification();
+
+
+
+ // The only expected result is the CompletedResponse result.
+ // If nothing is returned, just return -1.
+
+ if(connection.Mediator.GetCompletedResponses().Count == 0)
+ return -1;
+
+
+ // Check if the response is available.
+ String firstCompletedResponse = (String)connection.Mediator.GetCompletedResponses()[0];
+
+ if (firstCompletedResponse == null)
+ return -1;
+
+ String[] ret_string_tokens = firstCompletedResponse.Split(null); // whitespace separator.
+
+
+ // Check if the command was insert, delete or update.
+ // Only theses commands return rows affected.
+ // [FIXME] Is there a better way to check this??
+ if ((String.Compare(ret_string_tokens[0], "INSERT", true) == 0) ||
+ (String.Compare(ret_string_tokens[0], "UPDATE", true) == 0) ||
+ (String.Compare(ret_string_tokens[0], "DELETE", true) == 0))
+
+ // The number of rows affected is in the third token for insert queries
+ // and in the second token for update and delete queries.
+ // In other words, it is the last token in the 0-based array.
+
+ return Int32.Parse(ret_string_tokens[ret_string_tokens.Length - 1]);
+ else
+ return -1;
+
+ }
+
+ /// <summary>
+ /// Sends the <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> to
+ /// the <see cref="Npgsql.NpgsqlConnection">Connection</see> and builds a
+ /// <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see>.
+ /// </summary>
+ /// <returns>A <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see> object.</returns>
+ IDataReader IDbCommand.ExecuteReader()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbCommand.ExecuteReader");
+
+ return (NpgsqlDataReader) ExecuteReader();
+ }
+
+ /// <summary>
+ /// Sends the <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> to
+ /// the <see cref="Npgsql.NpgsqlConnection">Connection</see> and builds a
+ /// <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see>
+ /// using one of the <see cref="System.Data.CommandBehavior">CommandBehavior</see> values.
+ /// </summary>
+ /// <param name="cb">One of the <see cref="System.Data.CommandBehavior">CommandBehavior</see> values.</param>
+ /// <returns>A <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see> object.</returns>
+ IDataReader IDbCommand.ExecuteReader(CommandBehavior cb)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbCommand.ExecuteReader", cb);
+
+ return (NpgsqlDataReader) ExecuteReader(cb);
+
+ }
+
+ /// <summary>
+ /// Sends the <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> to
+ /// the <see cref="Npgsql.NpgsqlConnection">Connection</see> and builds a
+ /// <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see>.
+ /// </summary>
+ /// <returns>A <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see> object.</returns>
+ public NpgsqlDataReader ExecuteReader()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ExecuteReader");
+
+
+ return ExecuteReader(CommandBehavior.Default);
+
+ }
+
+ /// <summary>
+ /// Sends the <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> to
+ /// the <see cref="Npgsql.NpgsqlConnection">Connection</see> and builds a
+ /// <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see>
+ /// using one of the <see cref="System.Data.CommandBehavior">CommandBehavior</see> values.
+ /// </summary>
+ /// <param name="cb">One of the <see cref="System.Data.CommandBehavior">CommandBehavior</see> values.</param>
+ /// <returns>A <see cref="Npgsql.NpgsqlDataReader">NpgsqlDataReader</see> object.</returns>
+ /// <remarks>Currently the CommandBehavior parameter is ignored.</remarks>
+ public NpgsqlDataReader ExecuteReader(CommandBehavior cb)
+ {
+ // [FIXME] No command behavior handling.
+
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ExecuteReader", cb);
+
+ // Check the connection state.
+ CheckConnectionState();
+
+
+ ExecuteCommand();
+
+ // Check if there were any errors.
+ if (connection.Mediator.Errors.Count > 0)
+ {
+ StringWriter sw = new StringWriter();
+ sw.WriteLine(String.Format(resman.GetString("Exception_MediatorErrors_1P"), "ExecuteReader", cb));
+ uint i = 1;
+ foreach(string error in connection.Mediator.Errors)
+ {
+ sw.WriteLine("{0}. {1}", i++, error);
+ }
+ throw new NpgsqlException(sw.ToString());
+ }
+
+ CheckNotification();
+
+
+ // Get the resultsets and create a Datareader with them.
+ return new NpgsqlDataReader(connection.Mediator.GetResultSets(), connection.Mediator.GetCompletedResponses(), connection, cb);
+ }
+
+
+ ///<summary>
+ /// This method binds the parameters from parameters collection to the bind
+ /// message.
+ /// </summary>
+ private void BindParameters()
+ {
+
+ if (parameters.Count != 0)
+ {
+ Object[] parameterValues = new Object[parameters.Count];
+ for (Int32 i = 0; i < parameters.Count; i++)
+ {
+ parameterValues[i] = NpgsqlTypesHelper.ConvertNpgsqlParameterToBackendStringValue(parameters[i]);
+ }
+ bind.ParameterValues = parameterValues;
+ }
+
+ connection.Bind(bind);
+ connection.Flush();
+
+ }
+
+
+ /// <summary>
+ /// Executes the query, and returns the first column of the first row
+ /// in the result set returned by the query. Extra columns or rows are ignored.
+ /// </summary>
+ /// <returns>The first column of the first row in the result set,
+ /// or a null reference if the result set is empty.</returns>
+ public Object ExecuteScalar()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ExecuteScalar");
+
+
+ // Check the connection state.
+ CheckConnectionState();
+
+ /*if ((type == CommandType.Text) || (type == CommandType.StoredProcedure))
+ if (parse == null)
+ connection.Query(this);
+ else
+ {
+ BindParameters();
+ connection.Execute(new NpgsqlExecute(bind.PortalName, 0));
+ }
+ else
+ throw new NotImplementedException(resman.GetString("Exception_CommandTypeTableDirect"));
+ */
+
+ ExecuteCommand();
+
+ // Check if there were any errors.
+ // [FIXME] Just check the first error.
+ if (connection.Mediator.Errors.Count > 0)
+ {
+ StringWriter sw = new StringWriter();
+ sw.WriteLine(String.Format(resman.GetString("Exception_MediatorErrors"), "ExecuteScalar"));
+ uint i = 1;
+ foreach(string error in connection.Mediator.Errors)
+ {
+ sw.WriteLine("{0}. {1}", i++, error);
+ }
+ throw new NpgsqlException(sw.ToString());
+ }
+
+ CheckNotification();
+
+ //ArrayList results = connection.Mediator.Data;
+
+ //Object result = null; // Result of the ExecuteScalar().
+
+
+ // Now get the results.
+ // Only the first column of the first row must be returned.
+
+ // Get ResultSets.
+ ArrayList resultSets = connection.Mediator.GetResultSets();
+
+
+ // First data is the RowDescription object.
+ //NpgsqlRowDescription rd = (NpgsqlRowDescription)results[0];
+
+ NpgsqlResultSet firstResultSet = (NpgsqlResultSet)resultSets[0];
+
+ NpgsqlRowDescription rd = firstResultSet.RowDescription;
+
+ NpgsqlAsciiRow ascii_row = (NpgsqlAsciiRow)firstResultSet[0];
+
+ return ascii_row[0];
+
+
+ }
+
+ /// <summary>
+ /// Creates a prepared version of the command on a PostgreSQL server.
+ /// </summary>
+ public void Prepare()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Prepare");
+
+ // Check the connection state.
+ CheckConnectionState();
+
+ if (!connection.SupportsPrepare)
+ return; // Do nothing.
+
+
+
+ // [TODO] Finish method implementation.
+ //throw new NotImplementedException();
+
+ //NpgsqlCommand command = new NpgsqlCommand("prepare plan1 as " + GetCommandText(), connection );
+
+ if (connection.BackendProtocolVersion == ProtocolVersion.Version2)
+ {
+ NpgsqlCommand command = new NpgsqlCommand(GetPrepareCommandText(), connection );
+ command.ExecuteNonQuery();
+ }
+ else
+ {
+ // Use the extended query parsing...
+ planName = "NpgsqlPlan" + System.Threading.Interlocked.Increment(ref planIndex);
+ String portalName = "NpgsqlPortal" + System.Threading.Interlocked.Increment(ref portalIndex);
+
+ parse = new NpgsqlParse(planName, GetParseCommandText(), new Int32[] {});
+
+ connection.Parse(parse);
+ connection.Flush();
+
+ bind = new NpgsqlBind(portalName, planName, new Int16[] {0}, null, new Int16[] {0});
+
+ }
+ }
+
+ /// <summary>
+ /// Releases the resources used by the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>.
+ /// </summary>
+ protected override void Dispose (bool disposing)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Dispose");
+ if (disposing)
+ {
+ if (connection != null)
+ {
+ connection.Dispose();
+ }
+ base.Dispose(disposing);
+
+ }
+ }
+
+ ///<summary>
+ /// This method checks the connection state to see if the connection
+ /// is set or it is open. If one of this conditions is not met, throws
+ /// an InvalidOperationException
+ ///</summary>
+ private void CheckConnectionState()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CheckConnectionState");
+
+ // Check the connection state.
+ if (connection == null)
+ throw new InvalidOperationException(resman.GetString("Exception_ConnectionNull"));
+ if (connection.State != ConnectionState.Open)
+ throw new InvalidOperationException(resman.GetString("Exception_ConnectionNotOpen"));
+
+ }
+
+ /// <summary>
+ /// This method substitutes the <see cref="Npgsql.NpgsqlCommand.Parameters">Parameters</see>, if exist, in the command
+ /// to their actual values.
+ /// The parameter name format is <b>:ParameterName</b>.
+ /// </summary>
+ /// <returns>A version of <see cref="Npgsql.NpgsqlCommand.CommandText">CommandText</see> with the <see cref="Npgsql.NpgsqlCommand.Parameters">Parameters</see> inserted.</returns>
+ internal String GetCommandText()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetCommandText");
+
+ if (planName == String.Empty)
+ return GetClearCommandText();
+ else
+ return GetPreparedCommandText();
+
+
+ }
+
+
+ private String GetClearCommandText()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetClearCommandText");
+
+
+ String result = text;
+
+ if (type == CommandType.StoredProcedure)
+ if (connection.SupportsPrepare)
+ result = "select * from " + result; // This syntax is only available in 7.3+ as well SupportsPrepare.
+ else
+ result = "select " + result; // Only a single result return supported. 7.2 and earlier.
+ else if (type == CommandType.TableDirect)
+ return "select * from " + result; // There is no parameter support on table direct.
+
+ if (parameters.Count == 0)
+ return result;
+
+
+ //CheckParameters();
+
+ String parameterName;
+
+ for (Int32 i = 0; i < parameters.Count; i++)
+ {
+ parameterName = parameters[i].ParameterName;
+
+ result = ReplaceParameterValue(result, parameterName, NpgsqlTypesHelper.ConvertNpgsqlParameterToBackendStringValue(parameters[i]));
+
+ }
+
+ return result;
+
+ }
+
+
+
+ private String GetPreparedCommandText()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetPreparedCommandText");
+
+ if (parameters.Count == 0)
+ return "execute " + planName;
+
+
+ StringBuilder result = new StringBuilder("execute " + planName + '(');
+
+
+ for (Int32 i = 0; i < parameters.Count; i++)
+ {
+ result.Append(NpgsqlTypesHelper.ConvertNpgsqlParameterToBackendStringValue(parameters[i]) + ',');
+ }
+
+ result = result.Remove(result.Length - 1, 1);
+ result.Append(')');
+
+ return result.ToString();
+
+ }
+
+
+
+ private String GetParseCommandText()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetParseCommandText");
+
+ String parseCommand = text;
+
+ if (type == CommandType.StoredProcedure)
+ parseCommand = "select * from " + parseCommand; // This syntax is only available in 7.3+ as well SupportsPrepare.
+ else if (type == CommandType.TableDirect)
+ return "select * from " + parseCommand; // There is no parameter support on TableDirect.
+
+ if (parameters.Count > 0)
+ {
+ // The ReplaceParameterValue below, also checks if the parameter is present.
+
+ String parameterName;
+ Int32 i;
+
+ for (i = 0; i < parameters.Count; i++)
+ {
+ //result = result.Replace(":" + parameterName, parameters[i].Value.ToString());
+ parameterName = parameters[i].ParameterName;
+ //textCommand = textCommand.Replace(':' + parameterName, "$" + (i+1));
+ parseCommand = ReplaceParameterValue(parseCommand, parameterName, "$" + (i+1));
+
+ }
+ }
+
+ return parseCommand;
+
+ }
+
+
+ private String GetPrepareCommandText()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetPrepareCommandText");
+
+
+
+ planName = "NpgsqlPlan" + System.Threading.Interlocked.Increment(ref planIndex);
+
+ StringBuilder command = new StringBuilder("prepare " + planName);
+
+ String textCommand = text;
+
+ if (type == CommandType.StoredProcedure)
+ textCommand = "select * from " + textCommand;
+ else if (type == CommandType.TableDirect)
+ return "select * from " + textCommand; // There is no parameter support on TableDirect.
+
+
+ if (parameters.Count > 0)
+ {
+ // The ReplaceParameterValue below, also checks if the parameter is present.
+
+ String parameterName;
+ Int32 i;
+
+ for (i = 0; i < parameters.Count; i++)
+ {
+ //result = result.Replace(":" + parameterName, parameters[i].Value.ToString());
+ parameterName = parameters[i].ParameterName;
+ // The space in front of '$' fixes a parsing problem in 7.3 server
+ // which gives errors of operator when finding the caracters '=$' in
+ // prepare text
+ textCommand = ReplaceParameterValue(textCommand, parameterName, " $" + (i+1));
+
+ }
+
+ //[TODO] Check if there is any missing parameters in the query.
+ // For while, an error is thrown saying about the ':' char.
+
+ command.Append('(');
+
+ for (i = 0; i < parameters.Count; i++)
+ {
+ command.Append(NpgsqlTypesHelper.GetBackendTypeNameFromDbType(parameters[i].DbType));
+
+ command.Append(',');
+ }
+
+ command = command.Remove(command.Length - 1, 1);
+ command.Append(')');
+
+ }
+
+ command.Append(" as ");
+ command.Append(textCommand);
+
+
+ return command.ToString();
+
+ }
+
+
+ private String ReplaceParameterValue(String result, String parameterName, String paramVal)
+ {
+ Int32 resLen = result.Length;
+ Int32 paramStart = result.IndexOf(parameterName);
+ Int32 paramLen = parameterName.Length;
+ Int32 paramEnd = paramStart + paramLen;
+ Boolean found = false;
+
+ while(paramStart > -1)
+ {
+ if((resLen > paramEnd) &&
+ (result[paramEnd] == ' ' ||
+ result[paramEnd] == ',' ||
+ result[paramEnd] == ')' ||
+ result[paramEnd] == ';'))
+ {
+ result = result.Substring(0, paramStart) + paramVal + result.Substring(paramEnd);
+ found = true;
+ }
+ else if(resLen == paramEnd)
+ {
+ result = result.Substring(0, paramStart)+ paramVal;
+ found = true;
+ }
+ else
+ break;
+ resLen = result.Length;
+ paramStart = result.IndexOf(parameterName, paramStart);
+ paramEnd = paramStart + paramLen;
+
+ }//while
+ if(!found)
+ throw new NpgsqlException(String.Format(resman.GetString("Exception_ParamNotInQuery"), parameterName));
+
+ return result;
+ }//ReplaceParameterValue
+
+
+ private void ExecuteCommand()
+ {
+ //if ((type == CommandType.Text) || (type == CommandType.StoredProcedure))
+ if (parse == null)
+ connection.Query(this);
+ else
+ {
+ BindParameters();
+ connection.Execute(new NpgsqlExecute(bind.PortalName, 0));
+ }
+ /* else
+ throw new NotImplementedException(resman.GetString("Exception_CommandTypeTableDirect"));*/
+
+ }
+
+
+ }
+
}
using System.Data;
using System.ComponentModel;
-namespace Npgsql {
-
- public sealed class NpgsqlCommandBuilder : Component {
-
- bool disposed = false;
-
- private NpgsqlDataAdapter data_adapter;
- private NpgsqlCommand insert_command;
- private NpgsqlCommand update_command;
- private NpgsqlCommand delete_command;
-
- private string table_name = String.Empty;
-
- public NpgsqlCommandBuilder () {
- }
-
- public NpgsqlCommandBuilder (NpgsqlDataAdapter adapter) {
- DataAdapter = adapter;
- }
-
- public NpgsqlDataAdapter DataAdapter {
- get {
- return data_adapter;
- }
- set {
- if (data_adapter != null) {
- throw new Exception ("DataAdapter is already set");
- }
- data_adapter = value;
- string select_text = data_adapter.SelectCommand.CommandText;
- string[] words = select_text.Split(new char [] {' '});
- bool from_found = false;
- for (int i = 0; i < words.Length; i++) {
- if (from_found && (words[i] != String.Empty)) {
- table_name = words[i];
- break;
- }
- if (words[i].ToLower() == "from") {
- from_found = true;
- }
- }
- }
- }
-
- public string QuotePrefix {
- get { return ""; }
- set { }
- }
-
- public string QuoteSuffix {
- get { return ""; }
- set { }
- }
-
- public static void DeriveParameters (NpgsqlCommand command) {
- }
-
- public NpgsqlCommand GetInsertCommand (DataRow row) {
- if (insert_command == null) {
- string fields = "";
- string values = "";
- for (int i = 0; i < row.Table.Columns.Count; i++) {
- DataColumn column = row.Table.Columns[i];
- if (i != 0) {
- fields += ", ";
- values += ", ";
- }
- fields += column.ColumnName;
- values += ":param_" + column.ColumnName;
- }
- if (table_name == String.Empty) {
- table_name = row.Table.TableName;
- }
- NpgsqlCommand cmdaux = new NpgsqlCommand("insert into " + table_name + " (" + fields + ") values (" + values + ")", data_adapter.SelectCommand.Connection);
- foreach (DataColumn column in row.Table.Columns) {
- NpgsqlParameter aux = new NpgsqlParameter("param_" + column.ColumnName, row[column]);
- aux.Direction = ParameterDirection.Input;
- aux.SourceColumn = column.ColumnName;
- cmdaux.Parameters.Add(aux);
- }
- insert_command = cmdaux;
- }
- return insert_command;
- }
-
- public NpgsqlCommand GetUpdateCommand (DataRow row) {
- if (update_command == null) {
- string sets = "";
- string wheres = "";
- for (int i = 0; i < row.Table.Columns.Count; i++) {
- if (i != 0) {
- sets += ", ";
- wheres += " and ";
- }
- DataColumn column = row.Table.Columns[i];
- sets += String.Format("{0} = :s_param_{0}", column.ColumnName);
- wheres += String.Format("(({0} is null) or ({0} = :w_param_{0}))", column.ColumnName);
- }
- if (table_name == String.Empty) {
- table_name = row.Table.TableName;
- }
- NpgsqlCommand cmdaux = new NpgsqlCommand("update " + table_name + " set " + sets + " where ( " + wheres + " )", data_adapter.SelectCommand.Connection);
- foreach (DataColumn column in row.Table.Columns) {
- NpgsqlParameter aux = new NpgsqlParameter("s_param_" + column.ColumnName, row[column]);
- aux.Direction = ParameterDirection.Input;
- aux.SourceColumn = column.ColumnName;
- aux.SourceVersion = DataRowVersion.Current;
- cmdaux.Parameters.Add(aux);
- }
- foreach (DataColumn column in row.Table.Columns) {
- NpgsqlParameter aux = new NpgsqlParameter("w_param_" + column.ColumnName, row[column]);
- aux.Direction = ParameterDirection.Input;
- aux.SourceColumn = column.ColumnName;
- aux.SourceVersion = DataRowVersion.Original;
- cmdaux.Parameters.Add(aux);
- }
- update_command = cmdaux;
-
- }
- return update_command;
- }
-
- public NpgsqlCommand GetDeleteCommand (DataRow row) {
- if (delete_command == null) {
- string wheres = "";
- for (int i = 0; i < row.Table.Columns.Count; i++) {
- DataColumn column = row.Table.Columns[i];
- if (i != 0) {
- wheres += " and ";
- }
- wheres += String.Format("(({0} is null) or ({0} = :param_{0}))", column.ColumnName);
- }
- if (table_name == String.Empty) {
- table_name = row.Table.TableName;
- }
- NpgsqlCommand cmdaux = new NpgsqlCommand("delete from " + table_name + " where ( " + wheres + " )", data_adapter.SelectCommand.Connection);
- foreach (DataColumn column in row.Table.Columns) {
- NpgsqlParameter aux = new NpgsqlParameter("param_" + column.ColumnName, row[column,DataRowVersion.Original]);
- aux.Direction = ParameterDirection.Input;
- aux.SourceColumn = column.ColumnName;
- aux.SourceVersion = DataRowVersion.Original;
- cmdaux.Parameters.Add(aux);
- }
- delete_command = cmdaux;
- }
- return delete_command;
- }
-
- public void RefreshSchema () {
- insert_command = null;
- update_command = null;
- delete_command = null;
- }
-
- protected override void Dispose (bool disposing) {
- if (!disposed) {
- if (disposing) {
- if (insert_command != null) {
- insert_command.Dispose();
- }
- if (update_command != null) {
- update_command.Dispose();
- }
- if (delete_command != null) {
- delete_command.Dispose();
- }
- }
- }
- }
-
- ~NpgsqlCommandBuilder () {
- Dispose(false);
- }
-
- }
+namespace Npgsql
+{
+
+ public sealed class NpgsqlCommandBuilder : Component
+ {
+
+ bool disposed = false;
+
+ private NpgsqlDataAdapter data_adapter;
+ private NpgsqlCommand insert_command;
+ private NpgsqlCommand update_command;
+ private NpgsqlCommand delete_command;
+
+ private string table_name = String.Empty;
+
+ public NpgsqlCommandBuilder ()
+ {}
+
+ public NpgsqlCommandBuilder (NpgsqlDataAdapter adapter)
+ {
+ DataAdapter = adapter;
+ }
+
+ public NpgsqlDataAdapter DataAdapter {
+ get
+ {
+ return data_adapter;
+ }
+ set
+ {
+ if (data_adapter != null)
+ {
+ throw new Exception ("DataAdapter is already set");
+ }
+ data_adapter = value;
+ string select_text = data_adapter.SelectCommand.CommandText;
+ string[] words = select_text.Split(new char [] {' '});
+ bool from_found = false;
+ for (int i = 0; i < words.Length; i++)
+ {
+ if (from_found && (words[i] != String.Empty))
+ {
+ table_name = words[i];
+ break;
+ }
+ if (words[i].ToLower() == "from")
+ {
+ from_found = true;
+ }
+ }
+ }
+ }
+
+ public string QuotePrefix {
+ get
+ {
+ return "";
+ }
+ set
+ { }
+ }
+
+ public string QuoteSuffix {
+ get
+ {
+ return "";
+ }
+ set
+ { }
+ }
+
+ public static void DeriveParameters (NpgsqlCommand command)
+ {}
+
+ public NpgsqlCommand GetInsertCommand (DataRow row)
+ {
+ if (insert_command == null)
+ {
+ string fields = "";
+ string values = "";
+ for (int i = 0; i < row.Table.Columns.Count; i++)
+ {
+ DataColumn column = row.Table.Columns[i];
+ if (i != 0)
+ {
+ fields += ", ";
+ values += ", ";
+ }
+ fields += column.ColumnName;
+ values += ":param_" + column.ColumnName;
+ }
+ if (table_name == String.Empty)
+ {
+ table_name = row.Table.TableName;
+ }
+ NpgsqlCommand cmdaux = new NpgsqlCommand("insert into " + table_name + " (" + fields + ") values (" + values + ")", data_adapter.SelectCommand.Connection);
+ foreach (DataColumn column in row.Table.Columns)
+ {
+ NpgsqlParameter aux = new NpgsqlParameter("param_" + column.ColumnName, row[column]);
+ aux.Direction = ParameterDirection.Input;
+ aux.SourceColumn = column.ColumnName;
+ cmdaux.Parameters.Add(aux);
+ }
+ insert_command = cmdaux;
+ }
+ return insert_command;
+ }
+
+ public NpgsqlCommand GetUpdateCommand (DataRow row)
+ {
+ if (update_command == null)
+ {
+ string sets = "";
+ string wheres = "";
+ for (int i = 0; i < row.Table.Columns.Count; i++)
+ {
+ if (i != 0)
+ {
+ sets += ", ";
+ wheres += " and ";
+ }
+ DataColumn column = row.Table.Columns[i];
+ sets += String.Format("{0} = :s_param_{0}", column.ColumnName);
+ wheres += String.Format("(({0} is null) or ({0} = :w_param_{0}))", column.ColumnName);
+ }
+ if (table_name == String.Empty)
+ {
+ table_name = row.Table.TableName;
+ }
+ NpgsqlCommand cmdaux = new NpgsqlCommand("update " + table_name + " set " + sets + " where ( " + wheres + " )", data_adapter.SelectCommand.Connection);
+ foreach (DataColumn column in row.Table.Columns)
+ {
+ NpgsqlParameter aux = new NpgsqlParameter("s_param_" + column.ColumnName, row[column]);
+ aux.Direction = ParameterDirection.Input;
+ aux.SourceColumn = column.ColumnName;
+ aux.SourceVersion = DataRowVersion.Current;
+ cmdaux.Parameters.Add(aux);
+ }
+ foreach (DataColumn column in row.Table.Columns)
+ {
+ NpgsqlParameter aux = new NpgsqlParameter("w_param_" + column.ColumnName, row[column]);
+ aux.Direction = ParameterDirection.Input;
+ aux.SourceColumn = column.ColumnName;
+ aux.SourceVersion = DataRowVersion.Original;
+ cmdaux.Parameters.Add(aux);
+ }
+ update_command = cmdaux;
+
+ }
+ return update_command;
+ }
+
+ public NpgsqlCommand GetDeleteCommand (DataRow row)
+ {
+ if (delete_command == null)
+ {
+ string wheres = "";
+ for (int i = 0; i < row.Table.Columns.Count; i++)
+ {
+ DataColumn column = row.Table.Columns[i];
+ if (i != 0)
+ {
+ wheres += " and ";
+ }
+ wheres += String.Format("(({0} is null) or ({0} = :param_{0}))", column.ColumnName);
+ }
+ if (table_name == String.Empty)
+ {
+ table_name = row.Table.TableName;
+ }
+ NpgsqlCommand cmdaux = new NpgsqlCommand("delete from " + table_name + " where ( " + wheres + " )", data_adapter.SelectCommand.Connection);
+ foreach (DataColumn column in row.Table.Columns)
+ {
+ NpgsqlParameter aux = new NpgsqlParameter("param_" + column.ColumnName, row[column,DataRowVersion.Original]);
+ aux.Direction = ParameterDirection.Input;
+ aux.SourceColumn = column.ColumnName;
+ aux.SourceVersion = DataRowVersion.Original;
+ cmdaux.Parameters.Add(aux);
+ }
+ delete_command = cmdaux;
+ }
+ return delete_command;
+ }
+
+ public void RefreshSchema ()
+ {
+ insert_command = null;
+ update_command = null;
+ delete_command = null;
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ if (!disposed)
+ {
+ if (disposing)
+ {
+ if (insert_command != null)
+ {
+ insert_command.Dispose();
+ }
+ if (update_command != null)
+ {
+ update_command.Dispose();
+ }
+ if (delete_command != null)
+ {
+ delete_command.Dispose();
+ }
+ }
+ }
+ }
+
+ ~NpgsqlCommandBuilder ()
+ {
+ Dispose(false);
+ }
+
+ }
}
-
// Npgsql.NpgsqlConnectedState.cs
-//
+//
// Author:
// Dave Joyner <d4ljoyn@yahoo.com>
//
// 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
namespace Npgsql
{
- internal sealed class NpgsqlConnectedState : NpgsqlState
- {
-
- private static NpgsqlConnectedState _instance = null;
-
- private NpgsqlConnectedState()
- {
- }
- public static NpgsqlConnectedState Instance
- {
- get
- {
- if ( _instance == null )
- {
- _instance = new NpgsqlConnectedState();
- }
- return _instance;
- }
- }
- public override void Startup(NpgsqlConnection context)
- {
- if (context.BackendProtocolVersion == ProtocolVersion.Version3)
- {
-
- NpgsqlStartupPacket startupPacket = new NpgsqlStartupPacket(296, //Not used.
- 3,
- 0,
- context.DatabaseName,
- context.UserName,
- "",
- "",
- "");
-
- startupPacket.WriteToStream( context.BufferedStream, context.Encoding );
- ProcessBackendResponses( context );
- }
- else if (context.BackendProtocolVersion == ProtocolVersion.Version2)
- {
-
- NpgsqlStartupPacket startupPacket = new NpgsqlStartupPacket(296,
- 2,
- 0,
- context.DatabaseName,
- context.UserName,
- "",
- "",
- "");
-
- startupPacket.WriteToStream( new BufferedStream(context.NormalStream), context.Encoding );
- ProcessBackendResponses( context );
-
-
- }
-
- }
-
- }
+ internal sealed class NpgsqlConnectedState : NpgsqlState
+ {
+
+ private static NpgsqlConnectedState _instance = null;
+
+ private NpgsqlConnectedState()
+ {}
+ public static NpgsqlConnectedState Instance
+ {
+ get
+ {
+ if ( _instance == null )
+ {
+ _instance = new NpgsqlConnectedState();
+ }
+ return _instance;
+ }
+ }
+ public override void Startup(NpgsqlConnection context)
+ {
+ if (context.BackendProtocolVersion == ProtocolVersion.Version3)
+ {
+
+ NpgsqlStartupPacket startupPacket = new NpgsqlStartupPacket(296, //Not used.
+ 3,
+ 0,
+ context.DatabaseName,
+ context.UserName,
+ "",
+ "",
+ "");
+
+ startupPacket.WriteToStream( new BufferedStream(context.Stream), context.Encoding );
+ ProcessBackendResponses( context );
+ }
+ else if (context.BackendProtocolVersion == ProtocolVersion.Version2)
+ {
+
+ NpgsqlStartupPacket startupPacket = new NpgsqlStartupPacket(296,
+ 2,
+ 0,
+ context.DatabaseName,
+ context.UserName,
+ "",
+ "",
+ "");
+
+ startupPacket.WriteToStream( new BufferedStream(context.Stream), context.Encoding );
+ ProcessBackendResponses( context );
+
+
+ }
+
+ }
+
+ }
}
// created on 10/5/2002 at 23:01
// Npgsql.NpgsqlConnection.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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 Npgsql.Design;
-namespace Npgsql {
- /// <summary>
- /// Represents the method that handles the <see cref="Npgsql.NpgsqlConnection.Notification">Notification</see> events.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">A <see cref="Npgsql.NpgsqlNotificationEventArgs">NpgsqlNotificationEventArgs</see> that contains the event data.</param>
- public delegate void NotificationEventHandler(Object sender, NpgsqlNotificationEventArgs e);
-
- /// <summary>
- /// This class represents a connection to a
- /// PostgreSQL server.
- /// </summary>
- [System.Drawing.ToolboxBitmapAttribute(typeof(NpgsqlConnection))]
- public sealed class NpgsqlConnection : Component, IDbConnection, IDisposable {
- //Changed the Name of this event because events usually don't start with 'On' in the .Net-Framework
- // (but their handlers do ;-)
- /// <summary>
- /// Occurs on NotificationResponses from the PostgreSQL backend.
- /// </summary>
- public event NotificationEventHandler Notification;
-
-
- private NpgsqlState state;
-
- private ConnectionState connection_state;
- private String connection_string;
- internal ListDictionary connection_string_values;
- // some of the following constants are needed
- // for designtime support so I made them 'internal'
- // as I didn't want to add another interface for internal access
- // --brar
- // In the connection string
- internal readonly Char CONN_DELIM = ';'; // Delimeter
- internal readonly Char CONN_ASSIGN = '=';
- internal readonly String CONN_SERVER = "SERVER";
- internal readonly String CONN_USERID = "USER ID";
- internal readonly String CONN_PASSWORD = "PASSWORD";
- internal readonly String CONN_DATABASE = "DATABASE";
- internal readonly String CONN_PORT = "PORT";
- internal readonly String SSL_ENABLED = "SSL";
- // Postgres default port
- internal readonly String PG_PORT = "5432";
-
- // These are for ODBC connection string compatibility
- internal readonly String ODBC_USERID = "UID";
- internal readonly String ODBC_PASSWORD = "PWD";
-
- // Values for possible CancelRequest messages.
- private NpgsqlBackEndKeyData backend_keydata;
-
- // Flag for transaction status.
- private Boolean _inTransaction = false;
-
- // Mediator which will hold data generated from backend
- private NpgsqlMediator _mediator;
-
- // Logging related values
- private readonly String CLASSNAME = "NpgsqlConnection";
-
+namespace Npgsql
+{
+ /// <summary>
+ /// Represents the method that handles the <see cref="Npgsql.NpgsqlConnection.Notification">Notification</see> events.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">A <see cref="Npgsql.NpgsqlNotificationEventArgs">NpgsqlNotificationEventArgs</see> that contains the event data.</param>
+ public delegate void NotificationEventHandler(Object sender, NpgsqlNotificationEventArgs e);
+
+ /// <summary>
+ /// This class represents a connection to a
+ /// PostgreSQL server.
+ /// </summary>
+ [System.Drawing.ToolboxBitmapAttribute(typeof(NpgsqlConnection))]
+ public sealed class NpgsqlConnection : Component, IDbConnection, IDisposable
+ {
+ //Changed the Name of this event because events usually don't start with 'On' in the .Net-Framework
+ // (but their handlers do ;-)
+ /// <summary>
+ /// Occurs on NotificationResponses from the PostgreSQL backend.
+ /// </summary>
+ public event NotificationEventHandler Notification;
+
+
+ private NpgsqlState state;
+
+ private ConnectionState connection_state;
+ private String connection_string;
+ internal ListDictionary connection_string_values;
+ // some of the following constants are needed
+ // for designtime support so I made them 'internal'
+ // as I didn't want to add another interface for internal access
+ // --brar
+ // In the connection string
+ internal readonly Char CONN_DELIM = ';'; // Delimeter
+ internal readonly Char CONN_ASSIGN = '=';
+ internal readonly String CONN_SERVER = "SERVER";
+ internal readonly String CONN_USERID = "USER ID";
+ internal readonly String CONN_PASSWORD = "PASSWORD";
+ internal readonly String CONN_DATABASE = "DATABASE";
+ internal readonly String CONN_PORT = "PORT";
+ internal readonly String SSL_ENABLED = "SSL";
+ // Postgres default port
+ internal readonly String PG_PORT = "5432";
+
+ // These are for ODBC connection string compatibility
+ internal readonly String ODBC_USERID = "UID";
+ internal readonly String ODBC_PASSWORD = "PWD";
+
+ // Values for possible CancelRequest messages.
+ private NpgsqlBackEndKeyData backend_keydata;
+
+ // Flag for transaction status.
+ private Boolean _inTransaction = false;
+
+ // Mediator which will hold data generated from backend
+ private NpgsqlMediator _mediator;
+
+ // Logging related values
+ private readonly String CLASSNAME = "NpgsqlConnection";
+
private Stream stream;
- private BufferedStream bstream;
-
- private Encoding connection_encoding;
-
- private Boolean _supportsPrepare = false;
-
- private String _serverVersion; // Contains string returned from select version();
-
- private Hashtable _oidToNameMapping;
-
- private System.Resources.ResourceManager resman;
-
- private Int32 _backendProtocolVersion;
-
-
- /// <summary>
- /// Initializes a new instance of the
- /// <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see> class.
- /// </summary>
- public NpgsqlConnection() : this(String.Empty){}
-
- /// <summary>
- /// Initializes a new instance of the
- /// <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see> class
- /// and sets the <see cref="Npgsql.NpgsqlConnection.ConnectionString">ConnectionString</see>.
- /// </summary>
- /// <param name="ConnectionString">The connection used to open the PostgreSQL database.</param>
- public NpgsqlConnection(String ConnectionString) {
- resman = new System.Resources.ResourceManager(this.GetType());
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, ConnectionString);
-
- connection_state = ConnectionState.Closed;
- state = NpgsqlClosedState.Instance;
- connection_string = ConnectionString;
- connection_string_values = new ListDictionary();
- connection_encoding = Encoding.Default;
- _backendProtocolVersion = ProtocolVersion.Version3;
-
- _mediator = new NpgsqlMediator();
- _oidToNameMapping = new Hashtable();
-
- if (connection_string != String.Empty)
- ParseConnectionString();
- }
-
- /// <summary>
- /// Finalizer for NpgsqlConnection
- /// </summary>
- ~NpgsqlConnection () {
- Dispose(false);
- }
-
- /// <summary>
- /// Gets or sets the string used to open a SQL Server database.
- /// </summary>
- /// <value>The connection string that includes the server name,
- /// the database name, and other parameters needed to establish
- /// the initial connection. The default value is an empty string.
- /// </value>
- [RefreshProperties(RefreshProperties.All), DefaultValue(""), RecommendedAsConfigurable(true)]
- [NpgsqlSysDescription("Description_ConnectionString", typeof(NpgsqlConnection)), Category("Data")]
- [Editor(typeof(ConnectionStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
- public String ConnectionString {
- get {
- return connection_string;
- }
- set {
- NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "ConnectionString", value);
- connection_string = value;
- if (connection_string != String.Empty)
- ParseConnectionString();
- }
- }
-
- /// <summary>
- /// Gets the time to wait while trying to establish a connection
- /// before terminating the attempt and generating an error.
- /// </summary>
- /// <value>The time (in seconds) to wait for a connection to open. The default value is 15 seconds.</value>
- /// <remarks>This property currently always returns zero</remarks>
- [NpgsqlSysDescription("Description_ConnectionTimeout", typeof(NpgsqlConnection))]
- public Int32 ConnectionTimeout {
- get {
- return 0;
- }
- }
-
- ///<summary>
- /// Gets the name of the current database or the database to be used after a connection is opened.
- /// </summary>
- /// <value>The name of the current database or the name of the database to be
- /// used after a connection is opened. The default value is an empty string.</value>
- [NpgsqlSysDescription("Description_Database", typeof(NpgsqlConnection))]
- public String Database {
- get {
- return DatabaseName;
- }
- }
-
- /// <summary>
- /// Gets the current state of the connection.
- /// </summary>
- /// <value>A bitwise combination of the <see cref="System.Data.ConnectionState">ConnectionState</see> values. The default is <b>Closed</b>.</value>
- [Browsable(false)]
- public ConnectionState State {
- get {
- return connection_state;
- }
- }
-
- /// <summary>
- /// Begins a database transaction.
- /// </summary>
- /// <returns>An <see cref="System.Data.IDbTransaction">IDbTransaction</see>
- /// object representing the new transaction.</returns>
- /// <remarks>
- /// Currently there's no support for nested transactions.
- /// </remarks>
- IDbTransaction IDbConnection.BeginTransaction() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbConnection.BeginTransaction");
- //throw new NotImplementedException();
- return BeginTransaction();
- }
-
- /// <summary>
- /// Begins a database transaction with the specified isolation level.
- /// </summary>
- /// <param name="level">The <see cref="System.Data.IsolationLevel">isolation level</see> under which the transaction should run.</param>
- /// <returns>An <see cref="System.Data.IDbTransaction">IDbTransaction</see>
- /// object representing the new transaction.</returns>
- /// <remarks>
- /// Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend.
- /// There's no support for nested transactions.
- /// </remarks>
- IDbTransaction IDbConnection.BeginTransaction(IsolationLevel level) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbConnection.BeginTransaction", level);
- //throw new NotImplementedException();
- return BeginTransaction(level);
- }
-
-
- // I had to rename this Method from Notification to Notify due to the renaming of OnNotification to Notification
- /// <summary>
- /// Creates a Notification event
- /// </summary>
- /// <param name="e">The <see cref="Npgsql.NpgsqlNotificationEventArgs">NpgsqlNotificationEventArgs</see> that contains the event data.</param>
- internal void Notify(NpgsqlNotificationEventArgs e) {
- if (Notification != null)
- Notification(this, e);
- }
-
- /// <summary>
- /// Begins a database transaction.
- /// </summary>
- /// <returns>A <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>
- /// object representing the new transaction.</returns>
- /// <remarks>
- /// Currently there's no support for nested transactions.
- /// </remarks>
- public NpgsqlTransaction BeginTransaction() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "BeginTransaction");
- return this.BeginTransaction(IsolationLevel.ReadCommitted);
- }
-
- /// <summary>
- /// Begins a database transaction with the specified isolation level.
- /// </summary>
- /// <param name="level">The <see cref="System.Data.IsolationLevel">isolation level</see> under which the transaction should run.</param>
- /// <returns>A <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>
- /// object representing the new transaction.</returns>
- /// <remarks>
- /// Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend.
- /// There's no support for nested transactions.
- /// </remarks>
- public NpgsqlTransaction BeginTransaction(IsolationLevel level) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "BeginTransaction", level);
-
- if (_inTransaction)
- throw new InvalidOperationException(resman.GetString("Exception_NoNestedTransactions"));
-
-
- return new NpgsqlTransaction(this, level);
- }
-
- /// <summary>
- /// This method changes the current database by disconnecting from the actual
- /// database and connecting to the specified.
- /// </summary>
- /// <param name="dbName">The name of the database to use in place of the current database.</param>
- public void ChangeDatabase(String dbName) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ChangeDatabase", dbName);
- //throw new NotImplementedException();
-
- if (dbName == null)
- throw new ArgumentNullException("dbName");
-
- if (dbName == String.Empty)
- throw new ArgumentException(String.Format(resman.GetString("Exception_InvalidDbName"), dbName), "dbName");
-
- if(this.connection_state != ConnectionState.Open)
- throw new InvalidOperationException(resman.GetString("Exception_ChangeDatabaseOnOpenConn"));
-
- String oldDatabaseName = (String)connection_string_values[CONN_DATABASE];
- Close();
-
- connection_string_values[CONN_DATABASE] = dbName;
-
- Open();
-
-
-
- }
-
- /// <summary>
- /// Opens a database connection with the property settings specified by the
- /// <see cref="Npgsql.NpgsqlConnection.ConnectionString">ConnectionString</see>.
- /// </summary>
- public void Open() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open");
-
- // I moved this here from ParseConnectionString as there is no need to validate the
- // ConnectionString before we open the connection.
- // See: http://gborg.postgresql.org/pipermail/npgsql-hackers/2003-March/000019.html
- // In fact it makes it possible to parse incomplete ConnectionStrings for designtime support
- // -- brar
- //
- // Now check if there is any missing argument.
- if (connection_string == String.Empty)
- throw new InvalidOperationException(resman.GetString("Exception_ConnStrEmpty"));
- if (connection_string_values[CONN_SERVER] == null)
- throw new ArgumentException(resman.GetString("Exception_MissingConnStrArg"), CONN_SERVER);
- if ((connection_string_values[CONN_USERID] == null) & (connection_string_values[ODBC_USERID] == null))
- throw new ArgumentException(resman.GetString("Exception_MissingConnStrArg"), CONN_USERID);
- if ((connection_string_values[CONN_PASSWORD] == null) & (connection_string_values[ODBC_PASSWORD] == null))
- throw new ArgumentException(resman.GetString("Exception_MissingConnStrArg"), CONN_PASSWORD);
- if (connection_string_values[CONN_DATABASE] == null)
- // Database is optional. "[...] defaults to the user name if empty"
- connection_string_values[CONN_DATABASE] = connection_string_values[CONN_USERID];
- if (connection_string_values[CONN_PORT] == null)
- // Port is optional. Defaults to PG_PORT.
- connection_string_values[CONN_PORT] = PG_PORT;
- if (connection_string_values[SSL_ENABLED] == null)
- connection_string_values[SSL_ENABLED] = "no";
-
- try {
-
- // Check if the connection is already open.
- if (connection_state == ConnectionState.Open)
- throw new NpgsqlException(resman.GetString("Exception_ConnOpen"));
-
-
- // Try first connect using the 3.0 protocol...
- CurrentState.Open(this);
-
-
- // Check if there were any errors.
- if (_mediator.Errors.Count > 0)
- {
- // Check if there is an error of protocol not supported...
- // As the message can be localized, just check the initial unlocalized part of the
- // message. If it is an error other than protocol error, when connecting using
- // version 2.0 we shall catch the error again.
- if (((String)_mediator.Errors[0]).StartsWith("FATAL"))
- {
- // Try using the 2.0 protocol.
- _mediator.Reset();
- CurrentState = NpgsqlClosedState.Instance;
- BackendProtocolVersion = ProtocolVersion.Version2;
- CurrentState.Open(this);
- }
-
- // Keep checking for errors...
- if(_mediator.Errors.Count > 0)
- {
- StringWriter sw = new StringWriter();
- sw.WriteLine(resman.GetString("Exception_OpenError"));
- uint i = 1;
- foreach(string error in _mediator.Errors)
- {
- sw.WriteLine("{0}. {1}", i++, error);
- }
- CurrentState = NpgsqlClosedState.Instance;
- _mediator.Reset();
- throw new NpgsqlException(sw.ToString());
- }
- }
-
- backend_keydata = _mediator.GetBackEndKeyData();
-
- // Change the state of connection to open.
- connection_state = ConnectionState.Open;
-
- // Get version information to enable/disable server version features.
- // Only for protocol 2.0.
- if (BackendProtocolVersion == ProtocolVersion.Version2)
- {
- NpgsqlCommand command = new NpgsqlCommand("select version();set DATESTYLE TO ISO;", this);
- _serverVersion = (String) command.ExecuteScalar();
- }
-
-
- //NpgsqlCommand commandEncoding = new NpgsqlCommand("show client_encoding", this);
- //String serverEncoding = (String)commandEncoding.ExecuteScalar();
-
- //if (serverEncoding.Equals("UNICODE"))
- // connection_encoding = Encoding.UTF8;
-
-
-
- ProcessServerVersion();
- _oidToNameMapping = NpgsqlTypesHelper.LoadTypesMapping(this);
-
-
-
- }
-
-
-
-
-
- catch(IOException e) {
- // This exception was thrown by StartupPacket handling functions.
- // So, close the connection and throw the exception.
- // [TODO] Better exception handling. :)
- Close();
-
- throw new NpgsqlException(resman.GetString("Exception_OpenError"), e);
- }
-
- }
-
- /// <summary>
- /// Closes the connection to the database.
- /// </summary>
- public void Close() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Close");
-
- try {
- if ((connection_state == ConnectionState.Open)) {
- CurrentState.Close(this);
- }
- }
- catch (IOException e) {
- throw new NpgsqlException(resman.GetString("Exception_CloseError"), e);
- }
- finally {
- // Even if an exception occurs, let object in a consistent state.
- if (stream != null)
- stream.Close();
- connection_state = ConnectionState.Closed;
- }
- }
-
- /// <summary>
- /// Creates and returns a <see cref="System.Data.IDbCommand">IDbCommand</see>
- /// object associated with the <see cref="System.Data.IDbConnection">IDbConnection</see>.
- /// </summary>
- /// <returns>A <see cref="System.Data.IDbCommand">IDbCommand</see> object.</returns>
- IDbCommand IDbConnection.CreateCommand() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbConnection.CreateCommand");
- return (NpgsqlCommand) CreateCommand();
- }
-
- /// <summary>
- /// Creates and returns a <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>
- /// object associated with the <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>.
- /// </summary>
- /// <returns>A <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> object.</returns>
- public NpgsqlCommand CreateCommand() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CreateCommand");
- return new NpgsqlCommand("", this);
- }
-
- /// <summary>
- /// Releases the unmanaged resources used by the
- /// <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>
- /// and optionally releases the managed resources.
- /// </summary>
- /// <param name="disposing"><b>true</b> to release both managed and unmanaged resources;
- /// <b>false</b> to release only unmanaged resources.</param>
- protected override void Dispose(bool disposing) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Dispose", disposing);
- if (disposing == true){
- if (this.connection_state == ConnectionState.Open)
- this.Close();
- this.connection_string = null;
- }
- base.Dispose (disposing);
- }
-
- // Private util methods
-
- /// <summary>
- /// This method parses the connection string.
- /// It translates it to a list of key-value pairs.
- /// Valid values are:
- /// Server - Address/Name of Postgresql Server
- /// Port - Port to connect to.
- /// Database - Database name. Defaults to user name if not specified
- /// User - User name
- /// Password - Password for clear text authentication
- /// </summary>
- private void ParseConnectionString() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ParseConnectionString");
-
- connection_string_values.Clear();
-
- // Get the key-value pairs delimited by CONN_DELIM
- String[] pairs = connection_string.Split(new Char[] {CONN_DELIM});
-
- String[] keyvalue;
- // Now, for each pair, get its key-value.
- foreach(String s in pairs) {
- // This happen when there are trailling/empty CONN_DELIMs
- // Just ignore them.
- if (s == "")
- continue;
-
- keyvalue = s.Split(new Char[] {CONN_ASSIGN});
-
- // Check if there is a key-value pair.
- if (keyvalue.Length != 2)
- throw new ArgumentException(resman.GetString("Exception_WrongKeyVal"), connection_string);
-
- // Shift the key to upper case, and substitute ODBC style keys
- keyvalue[0] = keyvalue[0].ToUpper();
- if (keyvalue[0] == ODBC_USERID)
- keyvalue[0] = CONN_USERID;
- if (keyvalue[0] == ODBC_PASSWORD)
- keyvalue[0] = CONN_PASSWORD;
-
- // Add the pair to the dictionary. The key is shifted to upper
- // case for case insensitivity.
-
- NpgsqlEventLog.LogMsg(resman, "Log_ConnectionStringValues", LogLevel.Debug, keyvalue[0], keyvalue[1]);
- connection_string_values.Add(keyvalue[0], keyvalue[1]);
- }
- }
-
-
- /// <summary>
- /// This method is required to set all the version dependent features flags.
- /// SupportsPrepare means the server can use prepared query plans (7.3+)
- /// </summary>
- private void ProcessServerVersion () {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ProcessServerVersion");
-
- if (BackendProtocolVersion == ProtocolVersion.Version2) {
- SupportsPrepare = (_serverVersion.IndexOf("PostgreSQL 7.3") != -1);
- }
- else {
- // 3.0+ version is set by ParameterStatus message.
- SupportsPrepare = (_serverVersion.IndexOf("7.4") != -1);
- }
- }
-
- internal BufferedStream BufferedStream {
- get {
- return bstream;
- }
- set {
- bstream = value;
- }
- }
-
- internal Stream NormalStream {
- get {
- return stream;
- }
- set {
- stream = value;
- }
- }
- /*
- public bool useSSL()
- {
- if (SSL_ENABLED=="yes")
- return true;
-
- return false;
- }
- */
-
- // State
- internal void Query (NpgsqlCommand queryCommand) {
- CurrentState.Query(this, queryCommand );
- }
-
- internal void Authenticate (string password) {
- CurrentState.Authenticate(this, password );
- }
-
- internal void Startup () {
- CurrentState.Startup(this);
- }
-
- internal void Parse (NpgsqlParse parse) {
- CurrentState.Parse(this, parse);
- }
-
- internal void Flush () {
- CurrentState.Flush(this);
- }
-
- internal void Sync () {
- CurrentState.Sync(this);
- }
-
- internal void Bind (NpgsqlBind bind) {
- CurrentState.Bind(this, bind);
- }
-
- internal void Execute (NpgsqlExecute execute) {
- CurrentState.Execute(this, execute);
- }
-
- internal NpgsqlState CurrentState {
- get {
- return state;
- }
- set {
- state = value;
- }
- }
-
- internal NpgsqlBackEndKeyData BackEndKeyData {
- get {
- return backend_keydata;
- }
- set {
- backend_keydata = value;
- }
- }
-
- internal String ServerName {
- get {
- return (String)connection_string_values[CONN_SERVER];
- }
- }
-
- internal String ServerPort {
- get {
- return (String)connection_string_values[CONN_PORT];
- }
- }
-
- internal String DatabaseName {
- get {
- return (String)connection_string_values[CONN_DATABASE];
- }
- }
-
- internal String UserName {
- get {
- return (String)connection_string_values[CONN_USERID];
- }
- }
-
- internal String ServerPassword {
- get {
- return (String)connection_string_values[CONN_PASSWORD];
- }
- }
+ private Encoding connection_encoding;
+
+ private Boolean _supportsPrepare = false;
+
+ private String _serverVersion; // Contains string returned from select version();
+
+ private Hashtable _oidToNameMapping;
+
+ private System.Resources.ResourceManager resman;
+
+ private Int32 _backendProtocolVersion;
+
+
+ /// <summary>
+ /// Initializes a new instance of the
+ /// <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see> class.
+ /// </summary>
+ public NpgsqlConnection() : this(String.Empty)
+ {}
+
+ /// <summary>
+ /// Initializes a new instance of the
+ /// <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see> class
+ /// and sets the <see cref="Npgsql.NpgsqlConnection.ConnectionString">ConnectionString</see>.
+ /// </summary>
+ /// <param name="ConnectionString">The connection used to open the PostgreSQL database.</param>
+ public NpgsqlConnection(String ConnectionString)
+ {
+ resman = new System.Resources.ResourceManager(this.GetType());
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, ConnectionString);
+
+ connection_state = ConnectionState.Closed;
+ state = NpgsqlClosedState.Instance;
+ connection_string = ConnectionString;
+ connection_string_values = new ListDictionary();
+ connection_encoding = Encoding.Default;
+ _backendProtocolVersion = ProtocolVersion.Version3;
+
+ _mediator = new NpgsqlMediator();
+ _oidToNameMapping = new Hashtable();
+
+ if (connection_string != String.Empty)
+ ParseConnectionString();
+ }
+
+ /// <summary>
+ /// Finalizer for NpgsqlConnection
+ /// </summary>
+ ~NpgsqlConnection ()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Gets or sets the string used to open a SQL Server database.
+ /// </summary>
+ /// <value>The connection string that includes the server name,
+ /// the database name, and other parameters needed to establish
+ /// the initial connection. The default value is an empty string.
+ /// </value>
+ [RefreshProperties(RefreshProperties.All), DefaultValue(""), RecommendedAsConfigurable(true)]
+ [NpgsqlSysDescription("Description_ConnectionString", typeof(NpgsqlConnection)), Category("Data")]
+ [Editor(typeof(ConnectionStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
+ public String ConnectionString {
+ get
+ {
+ return connection_string;
+ }
+ set
+ {
+ NpgsqlEventLog.LogPropertySet(LogLevel.Debug, CLASSNAME, "ConnectionString", value);
+ connection_string = value;
+ if (connection_string != String.Empty)
+ ParseConnectionString();
+ }
+ }
+
+ /// <summary>
+ /// Gets the time to wait while trying to establish a connection
+ /// before terminating the attempt and generating an error.
+ /// </summary>
+ /// <value>The time (in seconds) to wait for a connection to open. The default value is 15 seconds.</value>
+ /// <remarks>This property currently always returns zero</remarks>
+ [NpgsqlSysDescription("Description_ConnectionTimeout", typeof(NpgsqlConnection))]
+ public Int32 ConnectionTimeout {
+ get
+ {
+ return 0;
+ }
+ }
+
+ ///<summary>
+ /// Gets the name of the current database or the database to be used after a connection is opened.
+ /// </summary>
+ /// <value>The name of the current database or the name of the database to be
+ /// used after a connection is opened. The default value is an empty string.</value>
+ [NpgsqlSysDescription("Description_Database", typeof(NpgsqlConnection))]
+ public String Database {
+ get
+ {
+ return DatabaseName;
+ }
+ }
+
+ /// <summary>
+ /// Gets the current state of the connection.
+ /// </summary>
+ /// <value>A bitwise combination of the <see cref="System.Data.ConnectionState">ConnectionState</see> values. The default is <b>Closed</b>.</value>
+ [Browsable(false)]
+ public ConnectionState State {
+ get
+ {
+ return connection_state;
+ }
+ }
+
+ /// <summary>
+ /// Begins a database transaction.
+ /// </summary>
+ /// <returns>An <see cref="System.Data.IDbTransaction">IDbTransaction</see>
+ /// object representing the new transaction.</returns>
+ /// <remarks>
+ /// Currently there's no support for nested transactions.
+ /// </remarks>
+ IDbTransaction IDbConnection.BeginTransaction()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbConnection.BeginTransaction");
+ //throw new NotImplementedException();
+ return BeginTransaction();
+ }
+
+ /// <summary>
+ /// Begins a database transaction with the specified isolation level.
+ /// </summary>
+ /// <param name="level">The <see cref="System.Data.IsolationLevel">isolation level</see> under which the transaction should run.</param>
+ /// <returns>An <see cref="System.Data.IDbTransaction">IDbTransaction</see>
+ /// object representing the new transaction.</returns>
+ /// <remarks>
+ /// Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend.
+ /// There's no support for nested transactions.
+ /// </remarks>
+ IDbTransaction IDbConnection.BeginTransaction(IsolationLevel level)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbConnection.BeginTransaction", level);
+ //throw new NotImplementedException();
+ return BeginTransaction(level);
+ }
+
+
+ // I had to rename this Method from Notification to Notify due to the renaming of OnNotification to Notification
+ /// <summary>
+ /// Creates a Notification event
+ /// </summary>
+ /// <param name="e">The <see cref="Npgsql.NpgsqlNotificationEventArgs">NpgsqlNotificationEventArgs</see> that contains the event data.</param>
+ internal void Notify(NpgsqlNotificationEventArgs e)
+ {
+ if (Notification != null)
+ Notification(this, e);
+ }
+
+ /// <summary>
+ /// Begins a database transaction.
+ /// </summary>
+ /// <returns>A <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>
+ /// object representing the new transaction.</returns>
+ /// <remarks>
+ /// Currently there's no support for nested transactions.
+ /// </remarks>
+ public NpgsqlTransaction BeginTransaction()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "BeginTransaction");
+ return this.BeginTransaction(IsolationLevel.ReadCommitted);
+ }
+
+ /// <summary>
+ /// Begins a database transaction with the specified isolation level.
+ /// </summary>
+ /// <param name="level">The <see cref="System.Data.IsolationLevel">isolation level</see> under which the transaction should run.</param>
+ /// <returns>A <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>
+ /// object representing the new transaction.</returns>
+ /// <remarks>
+ /// Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend.
+ /// There's no support for nested transactions.
+ /// </remarks>
+ public NpgsqlTransaction BeginTransaction(IsolationLevel level)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "BeginTransaction", level);
+
+ if (_inTransaction)
+ throw new InvalidOperationException(resman.GetString("Exception_NoNestedTransactions"));
+
+
+ return new NpgsqlTransaction(this, level);
+ }
+
+ /// <summary>
+ /// This method changes the current database by disconnecting from the actual
+ /// database and connecting to the specified.
+ /// </summary>
+ /// <param name="dbName">The name of the database to use in place of the current database.</param>
+ public void ChangeDatabase(String dbName)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ChangeDatabase", dbName);
+ //throw new NotImplementedException();
+
+ if (dbName == null)
+ throw new ArgumentNullException("dbName");
+
+ if (dbName == String.Empty)
+ throw new ArgumentException(String.Format(resman.GetString("Exception_InvalidDbName"), dbName), "dbName");
+
+ if(this.connection_state != ConnectionState.Open)
+ throw new InvalidOperationException(resman.GetString("Exception_ChangeDatabaseOnOpenConn"));
+
+ String oldDatabaseName = (String)connection_string_values[CONN_DATABASE];
+ Close();
+
+ connection_string_values[CONN_DATABASE] = dbName;
+
+ Open();
+
+
+
+ }
+
+ /// <summary>
+ /// Opens a database connection with the property settings specified by the
+ /// <see cref="Npgsql.NpgsqlConnection.ConnectionString">ConnectionString</see>.
+ /// </summary>
+ public void Open()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open");
+
+ // I moved this here from ParseConnectionString as there is no need to validate the
+ // ConnectionString before we open the connection.
+ // See: http://gborg.postgresql.org/pipermail/npgsql-hackers/2003-March/000019.html
+ // In fact it makes it possible to parse incomplete ConnectionStrings for designtime support
+ // -- brar
+ //
+ // Now check if there is any missing argument.
+ if (connection_string == String.Empty)
+ throw new InvalidOperationException(resman.GetString("Exception_ConnStrEmpty"));
+ if (connection_string_values[CONN_SERVER] == null)
+ throw new ArgumentException(resman.GetString("Exception_MissingConnStrArg"), CONN_SERVER);
+ if ((connection_string_values[CONN_USERID] == null) & (connection_string_values[ODBC_USERID] == null))
+ throw new ArgumentException(resman.GetString("Exception_MissingConnStrArg"), CONN_USERID);
+ if ((connection_string_values[CONN_PASSWORD] == null) & (connection_string_values[ODBC_PASSWORD] == null))
+ throw new ArgumentException(resman.GetString("Exception_MissingConnStrArg"), CONN_PASSWORD);
+ if (connection_string_values[CONN_DATABASE] == null)
+ // Database is optional. "[...] defaults to the user name if empty"
+ connection_string_values[CONN_DATABASE] = connection_string_values[CONN_USERID];
+ if (connection_string_values[CONN_PORT] == null)
+ // Port is optional. Defaults to PG_PORT.
+ connection_string_values[CONN_PORT] = PG_PORT;
+ if (connection_string_values[SSL_ENABLED] == null)
+ connection_string_values[SSL_ENABLED] = "no";
+
+ try
+ {
+
+ // Check if the connection is already open.
+ if (connection_state == ConnectionState.Open)
+ throw new NpgsqlException(resman.GetString("Exception_ConnOpen"));
+
+
+ // Try first connect using the 3.0 protocol...
+ CurrentState.Open(this);
+
+
+ // Check if there were any errors.
+ if (_mediator.Errors.Count > 0)
+ {
+ // Check if there is an error of protocol not supported...
+ // As the message can be localized, just check the initial unlocalized part of the
+ // message. If it is an error other than protocol error, when connecting using
+ // version 2.0 we shall catch the error again.
+ if (((String)_mediator.Errors[0]).StartsWith("FATAL"))
+ {
+ // Try using the 2.0 protocol.
+ _mediator.Reset();
+ CurrentState = NpgsqlClosedState.Instance;
+ BackendProtocolVersion = ProtocolVersion.Version2;
+ CurrentState.Open(this);
+ }
+
+ // Keep checking for errors...
+ if(_mediator.Errors.Count > 0)
+ {
+ StringWriter sw = new StringWriter();
+ sw.WriteLine(resman.GetString("Exception_OpenError"));
+ uint i = 1;
+ foreach(string error in _mediator.Errors)
+ {
+ sw.WriteLine("{0}. {1}", i++, error);
+ }
+ CurrentState = NpgsqlClosedState.Instance;
+ _mediator.Reset();
+ throw new NpgsqlException(sw.ToString());
+ }
+ }
+
+ backend_keydata = _mediator.GetBackEndKeyData();
+
+ // Change the state of connection to open.
+ connection_state = ConnectionState.Open;
+
+ // Get version information to enable/disable server version features.
+ // Only for protocol 2.0.
+ if (BackendProtocolVersion == ProtocolVersion.Version2)
+ {
+ NpgsqlCommand command = new NpgsqlCommand("select version();set DATESTYLE TO ISO;", this);
+ _serverVersion = (String) command.ExecuteScalar();
+ }
+
+
+ //NpgsqlCommand commandEncoding = new NpgsqlCommand("show client_encoding", this);
+ //String serverEncoding = (String)commandEncoding.ExecuteScalar();
+
+ //if (serverEncoding.Equals("UNICODE"))
+ // connection_encoding = Encoding.UTF8;
+
+
+
+ ProcessServerVersion();
+ _oidToNameMapping = NpgsqlTypesHelper.LoadTypesMapping(this);
+
+
+
+ }
+
+
+
+
+
+ catch(IOException e)
+ {
+ // This exception was thrown by StartupPacket handling functions.
+ // So, close the connection and throw the exception.
+ // [TODO] Better exception handling. :)
+ Close();
+
+ throw new NpgsqlException(resman.GetString("Exception_OpenError"), e);
+ }
+
+ }
+
+ /// <summary>
+ /// Closes the connection to the database.
+ /// </summary>
+ public void Close()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Close");
+
+ try
+ {
+ if ((connection_state == ConnectionState.Open))
+ {
+ CurrentState.Close(this);
+ }
+ }
+ catch (IOException e)
+ {
+ throw new NpgsqlException(resman.GetString("Exception_CloseError"), e);
+ }
+ finally
+ {
+ // Even if an exception occurs, let object in a consistent state.
+ if (stream != null)
+ stream.Close();
+ connection_state = ConnectionState.Closed;
+ }
+ }
+
+ /// <summary>
+ /// Creates and returns a <see cref="System.Data.IDbCommand">IDbCommand</see>
+ /// object associated with the <see cref="System.Data.IDbConnection">IDbConnection</see>.
+ /// </summary>
+ /// <returns>A <see cref="System.Data.IDbCommand">IDbCommand</see> object.</returns>
+ IDbCommand IDbConnection.CreateCommand()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IDbConnection.CreateCommand");
+ return (NpgsqlCommand) CreateCommand();
+ }
+
+ /// <summary>
+ /// Creates and returns a <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>
+ /// object associated with the <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>.
+ /// </summary>
+ /// <returns>A <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see> object.</returns>
+ public NpgsqlCommand CreateCommand()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CreateCommand");
+ return new NpgsqlCommand("", this);
+ }
+
+ /// <summary>
+ /// Releases the unmanaged resources used by the
+ /// <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>
+ /// and optionally releases the managed resources.
+ /// </summary>
+ /// <param name="disposing"><b>true</b> to release both managed and unmanaged resources;
+ /// <b>false</b> to release only unmanaged resources.</param>
+ protected override void Dispose(bool disposing)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Dispose", disposing);
+ if (disposing == true)
+ {
+ if (this.connection_state == ConnectionState.Open)
+ this.Close();
+ this.connection_string = null;
+ }
+ base.Dispose (disposing);
+ }
+
+ // Private util methods
+
+ /// <summary>
+ /// This method parses the connection string.
+ /// It translates it to a list of key-value pairs.
+ /// Valid values are:
+ /// Server - Address/Name of Postgresql Server
+ /// Port - Port to connect to.
+ /// Database - Database name. Defaults to user name if not specified
+ /// User - User name
+ /// Password - Password for clear text authentication
+ /// </summary>
+ private void ParseConnectionString()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ParseConnectionString");
+
+ connection_string_values.Clear();
+
+ // Get the key-value pairs delimited by CONN_DELIM
+ String[] pairs = connection_string.Split(new Char[] {CONN_DELIM});
+
+ String[] keyvalue;
+ // Now, for each pair, get its key-value.
+ foreach(String s in pairs)
+ {
+ // This happen when there are trailling/empty CONN_DELIMs
+ // Just ignore them.
+ if (s == "")
+ continue;
+
+ keyvalue = s.Split(new Char[] {CONN_ASSIGN});
+
+ // Check if there is a key-value pair.
+ if (keyvalue.Length != 2)
+ throw new ArgumentException(resman.GetString("Exception_WrongKeyVal"), connection_string);
+
+ // Shift the key to upper case, and substitute ODBC style keys
+ keyvalue[0] = keyvalue[0].ToUpper();
+ if (keyvalue[0] == ODBC_USERID)
+ keyvalue[0] = CONN_USERID;
+ if (keyvalue[0] == ODBC_PASSWORD)
+ keyvalue[0] = CONN_PASSWORD;
+
+ // Add the pair to the dictionary. The key is shifted to upper
+ // case for case insensitivity.
+
+ NpgsqlEventLog.LogMsg(resman, "Log_ConnectionStringValues", LogLevel.Debug, keyvalue[0], keyvalue[1]);
+ connection_string_values.Add(keyvalue[0], keyvalue[1]);
+ }
+ }
+
+
+ /// <summary>
+ /// This method is required to set all the version dependent features flags.
+ /// SupportsPrepare means the server can use prepared query plans (7.3+)
+ /// </summary>
+ private void ProcessServerVersion ()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ProcessServerVersion");
+
+ if (BackendProtocolVersion == ProtocolVersion.Version2)
+ {
+ SupportsPrepare = (_serverVersion.IndexOf("PostgreSQL 7.3") != -1);
+ }
+ else
+ {
+ // 3.0+ version is set by ParameterStatus message.
+ SupportsPrepare = (_serverVersion.IndexOf("7.4") != -1);
+ }
+ }
+
+ internal Stream Stream {
+ get
+ {
+ return stream;
+ }
+ set
+ {
+ stream = value;
+ }
+ }
+
+ /*
+ public bool useSSL()
+ {
+ if (SSL_ENABLED=="yes")
+ return true;
+
+ return false;
+ }
+ */
+
+ // State
+ internal void Query (NpgsqlCommand queryCommand)
+ {
+ CurrentState.Query(this, queryCommand );
+ }
+
+ internal void Authenticate (string password)
+ {
+ CurrentState.Authenticate(this, password );
+ }
+
+ internal void Startup ()
+ {
+ CurrentState.Startup(this);
+ }
+
+ internal void Parse (NpgsqlParse parse)
+ {
+ CurrentState.Parse(this, parse);
+ }
+
+ internal void Flush ()
+ {
+ CurrentState.Flush(this);
+ }
+
+ internal void Sync ()
+ {
+ CurrentState.Sync(this);
+ }
+
+ internal void Bind (NpgsqlBind bind)
+ {
+ CurrentState.Bind(this, bind);
+ }
+
+ internal void Execute (NpgsqlExecute execute)
+ {
+ CurrentState.Execute(this, execute);
+ }
+
+ internal NpgsqlState CurrentState {
+ get
+ {
+ return state;
+ }
+ set
+ {
+ state = value;
+ }
+ }
+
+ internal NpgsqlBackEndKeyData BackEndKeyData {
+ get
+ {
+ return backend_keydata;
+ }
+ set
+ {
+ backend_keydata = value;
+ }
+ }
+
+ internal String ServerName {
+ get
+ {
+ return (String)connection_string_values[CONN_SERVER];
+ }
+ }
+
+ internal String ServerPort {
+ get
+ {
+ return (String)connection_string_values[CONN_PORT];
+ }
+ }
+
+ internal String DatabaseName {
+ get
+ {
+ return (String)connection_string_values[CONN_DATABASE];
+ }
+ }
+
+ internal String UserName {
+ get
+ {
+ return (String)connection_string_values[CONN_USERID];
+ }
+ }
+
+ internal String ServerPassword {
+ get
+ {
+ return (String)connection_string_values[CONN_PASSWORD];
+ }
+ }
internal String SSL {
- get {
- return (String)connection_string_values[SSL_ENABLED];
- }
- }
-
- internal Encoding Encoding {
- get {
- return connection_encoding;
- }
- }
-
- internal NpgsqlMediator Mediator {
- get {
- return _mediator;
- }
- }
-
- internal Boolean InTransaction {
- get {
- return _inTransaction;
- }
- set {
- _inTransaction = value;
- }
- }
-
- internal Boolean SupportsPrepare {
- get {
- return _supportsPrepare;
- }
- set {
- _supportsPrepare = value;
- }
- }
-
- internal String ServerVersion {
- get {
- return _serverVersion;
- }
- set {
- _serverVersion = value;
- }
- }
-
- internal Hashtable OidToNameMapping {
- get {
- return _oidToNameMapping;
- }
- set {
- _oidToNameMapping = value;
- }
-
- }
-
- internal Int32 BackendProtocolVersion {
- get {
- return _backendProtocolVersion;
- }
- set {
- _backendProtocolVersion = value;
- }
- }
-
- }
+ get
+ {
+ return (String)connection_string_values[SSL_ENABLED];
+ }
+ }
+
+ internal Encoding Encoding {
+ get
+ {
+ return connection_encoding;
+ }
+ }
+
+ internal NpgsqlMediator Mediator {
+ get
+ {
+ return _mediator;
+ }
+ }
+
+ internal Boolean InTransaction {
+ get
+ {
+ return _inTransaction;
+ }
+ set
+ {
+ _inTransaction = value;
+ }
+ }
+
+ internal Boolean SupportsPrepare {
+ get
+ {
+ return _supportsPrepare;
+ }
+ set
+ {
+ _supportsPrepare = value;
+ }
+ }
+
+ internal String ServerVersion {
+ get
+ {
+ return _serverVersion;
+ }
+ set
+ {
+ _serverVersion = value;
+ }
+ }
+
+ internal Hashtable OidToNameMapping {
+ get
+ {
+ return _oidToNameMapping;
+ }
+ set
+ {
+ _oidToNameMapping = value;
+ }
+
+ }
+
+ internal Int32 BackendProtocolVersion {
+ get
+ {
+ return _backendProtocolVersion;
+ }
+ set
+ {
+ _backendProtocolVersion = value;
+ }
+ }
+
+ }
}
// 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
namespace Npgsql
{
- /// <summary>
- /// !!! Helper class, for compilation only.
- /// </summary>
- internal class Socket
- {
- internal void Open() { return; }
- internal void Close() { return; }
- }
-
- /// <summary>
- /// Connector implements the logic for the Connection Objects to
- /// access the physical connection to the database, and isolate
- /// the application developer from connection pooling internals.
- /// </summary>
- internal class Connector
- {
- /// <value>Buffer for the public Pooled property</value>
- private bool mPooled;
-
- /// <value>Chain references for implementing a double linked
- /// list</value>
- /// <remarks>!!! This is a quick hack in order to get things
- /// going faster. A connector list should better be based on
- /// System.Collections.DictionaryBase...</remarks>
- internal Connector Next;
- internal Connector Prev;
-
- /// <value>Controls the pooling of the connector.</value>
- /// <remarks>It this is reset, then the physical connection is
- /// closed and the connector is <b>not</b> added to the
- /// pooled connectors list upon Release(). Can only be cleared
- /// if connector is not shared.</remarks>
- internal bool Pooled
- {
- get { return this.mPooled; }
- set
- {
- if ( this.mShared && ! value) return;
- this.mPooled = value;
- }
- }
-
- /// <value>Buffer for the public Shared property</value>
- private bool mShared;
-
- /// <value>Controls the physical connection sharing.</value>
- /// <remarks>Set true if this connector is shared among multiple
- /// connections. Can only be set if the connector is pooled
- /// and not yet opened.</remarks>
- internal bool Shared
- {
- get { return this.mShared; }
- set
- {
- if ( ! this.mPooled && value && ! mOpen ) return;
- mShared = value;
- }
- }
-
- /// <value>Counts the numbers of Connections that share
- /// this Connector. Used in Release() to decide wether this
- /// connector is to be moved to the PooledConnectors list.</value>
- internal int mShareCount;
-
- /// <value>Private Buffer for the connection string property.</value>
- /// <remarks>Compared to the requested connection string in the
- /// ConnectorPool.RequestConnector() function.
- /// Should not be modified if physical connection is open.</remarks>
- private string mConnectString;
-
- /// <summary>Used to connect to the database server. </summary>
- public string ConnectString
- {
- get { return mConnectString; }
- set
- {
- if ( this.mOpen ) // uuuuugh, bad habits...
- {
- throw new Npgsql.NpgsqlException( "Connection strings "
- + " cannot be modified if connection is open." );
- }
- mConnectString = value;
- }
- }
-
- /// <value>Provides physical access to the server</value>
- // !!! to be fixed
- private Npgsql.Socket Socket;
-
- /// <value>True if the physical connection is open.</value>
- private bool mOpen;
-
- /// <summary>
- /// Default constructor. Creates a pooled Connector by default.
- /// </summary>
- public Connector()
- {
- this.Pooled = true;
- }
-
- /// <summary>
- /// Construcor, initializes the Connector object.
- /// </summary>
- internal Connector( string ConnectString, bool Shared )
- {
- this.ConnectString = ConnectString;
- this.Shared = Shared;
- this.Pooled = true;
- }
-
- /// <summary>
- /// Opens the physical connection to the server.
- /// </summary>
- /// <remarks>Usually called by the RequestConnector
- /// Method of the connection pool manager.</remarks>
- internal void Open()
- {
- this.Socket = new Npgsql.Socket();
- this.Socket.Open(); // !!! to be fixed
- this.mOpen = true;
- }
-
- /// <summary>
- /// Releases a connector back to the pool manager's garding. Or to the
- /// garbage collection.
- /// </summary>
- /// <remarks>The Shared and Pooled properties are no longer needed after
- /// evaluation inside this method, so they are left in their current state.
- /// They get new meaning again when the connector is requested from the
- /// pool manager later. </remarks>
- public void Release()
- {
- if ( this.mShared )
- {
- // A shared connector is returned to the pooled connectors
- // list only if it is not used by any Connection object.
- // Otherwise the job is done by simply decrementing the
- // usage counter:
- if ( --this.mShareCount == 0 )
- {
- Npgsql.ConnectorPool.ConnectorPoolMgr.CutOutConnector( this );
- // Shared connectors are *always* pooled after usage.
- // Depending on the Pooled property at this point
- // might introduce a lot of trouble into an application...
- Npgsql.ConnectorPool.ConnectorPoolMgr.InsertPooledConnector( this );
- }
- }
- else // it is a nonshared connector
- {
- if ( this.Pooled )
- {
- // Pooled connectors are simply put in the
- // PooledConnectors list for later recycling
- Npgsql.ConnectorPool.ConnectorPoolMgr.InsertPooledConnector( this );
- }
- else
- {
- // Unpooled private connectors get the physical
- // connection closed, they are *not* recyled later.
- // Instead they are (implicitly) handed over to the
- // garbage collection.
- // !!! to be fixed
- this.Socket.Close();
- }
- }
- }
- }
+ /// <summary>
+ /// !!! Helper class, for compilation only.
+ /// </summary>
+ internal class Socket
+ {
+ internal void Open()
+ {
+ return;
+ }
+ internal void Close()
+ {
+ return;
+ }
+ }
+
+ /// <summary>
+ /// Connector implements the logic for the Connection Objects to
+ /// access the physical connection to the database, and isolate
+ /// the application developer from connection pooling internals.
+ /// </summary>
+ internal class Connector
+ {
+ /// <value>Buffer for the public Pooled property</value>
+ private bool mPooled;
+
+ /// <value>Chain references for implementing a double linked
+ /// list</value>
+ /// <remarks>!!! This is a quick hack in order to get things
+ /// going faster. A connector list should better be based on
+ /// System.Collections.DictionaryBase...</remarks>
+ internal Connector Next;
+ internal Connector Prev;
+
+ /// <value>Controls the pooling of the connector.</value>
+ /// <remarks>It this is reset, then the physical connection is
+ /// closed and the connector is <b>not</b> added to the
+ /// pooled connectors list upon Release(). Can only be cleared
+ /// if connector is not shared.</remarks>
+ internal bool Pooled
+ {
+ get
+ {
+ return this.mPooled;
+ }
+ set
+ {
+ if ( this.mShared && ! value)
+ return;
+ this.mPooled = value;
+ }
+ }
+
+ /// <value>Buffer for the public Shared property</value>
+ private bool mShared;
+
+ /// <value>Controls the physical connection sharing.</value>
+ /// <remarks>Set true if this connector is shared among multiple
+ /// connections. Can only be set if the connector is pooled
+ /// and not yet opened.</remarks>
+ internal bool Shared
+ {
+ get
+ {
+ return this.mShared;
+ }
+ set
+ {
+ if ( ! this.mPooled && value && ! mOpen )
+ return;
+ mShared = value;
+ }
+ }
+
+ /// <value>Counts the numbers of Connections that share
+ /// this Connector. Used in Release() to decide wether this
+ /// connector is to be moved to the PooledConnectors list.</value>
+ internal int mShareCount;
+
+ /// <value>Private Buffer for the connection string property.</value>
+ /// <remarks>Compared to the requested connection string in the
+ /// ConnectorPool.RequestConnector() function.
+ /// Should not be modified if physical connection is open.</remarks>
+ private string mConnectString;
+
+ /// <summary>Used to connect to the database server. </summary>
+ public string ConnectString
+ {
+ get
+ {
+ return mConnectString;
+ }
+ set
+ {
+ if ( this.mOpen ) // uuuuugh, bad habits...
+ {
+ throw new Npgsql.NpgsqlException( "Connection strings "
+ + " cannot be modified if connection is open." );
+ }
+ mConnectString = value;
+ }
+ }
+
+ /// <value>Provides physical access to the server</value>
+ // !!! to be fixed
+ private Npgsql.Socket Socket;
+
+ /// <value>True if the physical connection is open.</value>
+ private bool mOpen;
+
+ /// <summary>
+ /// Default constructor. Creates a pooled Connector by default.
+ /// </summary>
+ public Connector()
+ {
+ this.Pooled = true;
+ }
+
+ /// <summary>
+ /// Construcor, initializes the Connector object.
+ /// </summary>
+ internal Connector( string ConnectString, bool Shared )
+ {
+ this.ConnectString = ConnectString;
+ this.Shared = Shared;
+ this.Pooled = true;
+ }
+
+ /// <summary>
+ /// Opens the physical connection to the server.
+ /// </summary>
+ /// <remarks>Usually called by the RequestConnector
+ /// Method of the connection pool manager.</remarks>
+ internal void Open()
+ {
+ this.Socket = new Npgsql.Socket();
+ this.Socket.Open(); // !!! to be fixed
+ this.mOpen = true;
+ }
+
+ /// <summary>
+ /// Releases a connector back to the pool manager's garding. Or to the
+ /// garbage collection.
+ /// </summary>
+ /// <remarks>The Shared and Pooled properties are no longer needed after
+ /// evaluation inside this method, so they are left in their current state.
+ /// They get new meaning again when the connector is requested from the
+ /// pool manager later. </remarks>
+ public void Release()
+ {
+ if ( this.mShared )
+ {
+ // A shared connector is returned to the pooled connectors
+ // list only if it is not used by any Connection object.
+ // Otherwise the job is done by simply decrementing the
+ // usage counter:
+ if ( --this.mShareCount == 0 )
+ {
+ Npgsql.ConnectorPool.ConnectorPoolMgr.CutOutConnector( this );
+ // Shared connectors are *always* pooled after usage.
+ // Depending on the Pooled property at this point
+ // might introduce a lot of trouble into an application...
+ Npgsql.ConnectorPool.ConnectorPoolMgr.InsertPooledConnector( this );
+ }
+ }
+ else // it is a nonshared connector
+ {
+ if ( this.Pooled )
+ {
+ // Pooled connectors are simply put in the
+ // PooledConnectors list for later recycling
+ Npgsql.ConnectorPool.ConnectorPoolMgr.InsertPooledConnector( this );
+ }
+ else
+ {
+ // Unpooled private connectors get the physical
+ // connection closed, they are *not* recyled later.
+ // Instead they are (implicitly) handed over to the
+ // garbage collection.
+ // !!! to be fixed
+ this.Socket.Close();
+ }
+ }
+ }
+ }
}
// 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
namespace Npgsql
{
- internal class ConnectorPool
- {
- /// <value>Unique static instance of the connector pool
- /// mamager.</value>
- internal static ConnectorPool ConnectorPoolMgr = new Npgsql.ConnectorPool();
+ internal class ConnectorPool
+ {
+ /// <value>Unique static instance of the connector pool
+ /// mamager.</value>
+ internal static ConnectorPool ConnectorPoolMgr = new Npgsql.ConnectorPool();
- /// <value>List of unused, pooled connectors avaliable to the
- /// next RequestConnector() call.</value>
- /// <remarks>Points to the head of a double linked list</remarks>
- internal Npgsql.Connector PooledConnectors;
+ /// <value>List of unused, pooled connectors avaliable to the
+ /// next RequestConnector() call.</value>
+ /// <remarks>Points to the head of a double linked list</remarks>
+ internal Npgsql.Connector PooledConnectors;
- /// <value>List of used, shared conncetors.</value>
- /// <remarks>Points to the head of a double linked list</remarks>
- private Npgsql.Connector SharedConnectors;
+ /// <value>List of used, shared conncetors.</value>
+ /// <remarks>Points to the head of a double linked list</remarks>
+ private Npgsql.Connector SharedConnectors;
- /// <summary>
- /// Cuts out a connector from the the list it is in.
- /// </summary>
- /// <param name="Connector">The connector object to be cut out.</param>
- /// <remarks>Shall be replaced if the lists will be based on
- /// Collections.DictionaryBase classs </remarks>
- internal void CutOutConnector( Npgsql.Connector Connector )
- {
- if ( Connector.Prev != null ) Connector.Prev.Next = Connector.Next;
- if ( Connector.Next != null ) Connector.Next.Prev = Connector.Prev;
- }
+ /// <summary>
+ /// Cuts out a connector from the the list it is in.
+ /// </summary>
+ /// <param name="Connector">The connector object to be cut out.</param>
+ /// <remarks>Shall be replaced if the lists will be based on
+ /// Collections.DictionaryBase classs </remarks>
+ internal void CutOutConnector( Npgsql.Connector Connector )
+ {
+ if ( Connector.Prev != null )
+ Connector.Prev.Next = Connector.Next;
+ if ( Connector.Next != null )
+ Connector.Next.Prev = Connector.Prev;
+ }
- /// <summary>
- /// Inserts a connector at the head of a shared connector list.
- /// </summary>
- /// <param name="Connector">The connctor to be inserted</param>
- internal void InsertSharedConnector( Npgsql.Connector Connector )
- {
- if ( this.SharedConnectors == null ) // the list is empty
- {
- // make the connector the only member
- Connector.Prev = Connector.Next = null;
- }
- else // the list is not empty
- {
- // Make the connector the new list head
- Connector.Next = this.SharedConnectors;
- this.SharedConnectors.Prev = Connector;
- Connector.Prev = null;
- }
- // point the list to the new head
- this.SharedConnectors = Connector;
- }
+ /// <summary>
+ /// Inserts a connector at the head of a shared connector list.
+ /// </summary>
+ /// <param name="Connector">The connctor to be inserted</param>
+ internal void InsertSharedConnector( Npgsql.Connector Connector )
+ {
+ if ( this.SharedConnectors == null ) // the list is empty
+ {
+ // make the connector the only member
+ Connector.Prev = Connector.Next = null;
+ }
+ else // the list is not empty
+ {
+ // Make the connector the new list head
+ Connector.Next = this.SharedConnectors;
+ this.SharedConnectors.Prev = Connector;
+ Connector.Prev = null;
+ }
+ // point the list to the new head
+ this.SharedConnectors = Connector;
+ }
- /// <summary>
- /// Inserts a connector at the head of a pooled connector list.
- /// </summary>
- /// <param name="Connector">The connctor to be inserted</param>
- internal void InsertPooledConnector( Npgsql.Connector Connector )
- {
- if ( this.PooledConnectors == null ) // the list is empty
- {
- // make the connector the only member
- Connector.Prev = Connector.Next = null;
- }
- else // the list is not empty
- {
- // Make the connector the new list head
- Connector.Next = this.PooledConnectors;
- this.PooledConnectors.Prev = Connector;
- Connector.Prev = null;
- }
- // point the list to the new head
- this.PooledConnectors = Connector;
- }
+ /// <summary>
+ /// Inserts a connector at the head of a pooled connector list.
+ /// </summary>
+ /// <param name="Connector">The connctor to be inserted</param>
+ internal void InsertPooledConnector( Npgsql.Connector Connector )
+ {
+ if ( this.PooledConnectors == null ) // the list is empty
+ {
+ // make the connector the only member
+ Connector.Prev = Connector.Next = null;
+ }
+ else // the list is not empty
+ {
+ // Make the connector the new list head
+ Connector.Next = this.PooledConnectors;
+ this.PooledConnectors.Prev = Connector;
+ Connector.Prev = null;
+ }
+ // point the list to the new head
+ this.PooledConnectors = Connector;
+ }
- /// <summary>
- /// Searches the shared and pooled connector lists for a
- /// matching connector object or creates a new one.
- /// </summary>
- /// <param name="ConnectString">used to connect to the
- /// database server</param>
- /// <param name="Shared">Allows multiple connections
- /// on a single connector. </param>
- /// <returns>A pooled connector object.</returns>
- internal Npgsql.Connector RequestConnector ( string ConnectString,
- bool Shared )
- {
- Npgsql.Connector Connector;
+ /// <summary>
+ /// Searches the shared and pooled connector lists for a
+ /// matching connector object or creates a new one.
+ /// </summary>
+ /// <param name="ConnectString">used to connect to the
+ /// database server</param>
+ /// <param name="Shared">Allows multiple connections
+ /// on a single connector. </param>
+ /// <returns>A pooled connector object.</returns>
+ internal Npgsql.Connector RequestConnector ( string ConnectString,
+ bool Shared )
+ {
+ Npgsql.Connector Connector;
- if ( Shared )
- {
- // if a shared connector is requested then the
- // Shared Connector List is searched first
+ if ( Shared )
+ {
+ // if a shared connector is requested then the
+ // Shared Connector List is searched first
- for ( Connector = Npgsql.ConnectorPool.ConnectorPoolMgr.SharedConnectors;
- Connector != null; Connector = Connector.Next )
- {
- if ( Connector.ConnectString == ConnectString )
- { // Bingo!
- // Return the shared connector to caller
- Connector.mShareCount++;
- return Connector;
- }
- }
- }
- else
- {
- // if a shared connector could not be found or a
- // nonshared connector is requested, then the pooled
- // (unused) connectors are beeing searched.
+ for ( Connector = Npgsql.ConnectorPool.ConnectorPoolMgr.SharedConnectors;
+ Connector != null; Connector = Connector.Next )
+ {
+ if ( Connector.ConnectString == ConnectString )
+ { // Bingo!
+ // Return the shared connector to caller
+ Connector.mShareCount++;
+ return Connector;
+ }
+ }
+ }
+ else
+ {
+ // if a shared connector could not be found or a
+ // nonshared connector is requested, then the pooled
+ // (unused) connectors are beeing searched.
- for ( Connector = Npgsql.ConnectorPool.ConnectorPoolMgr.PooledConnectors;
- Connector != null; Connector = Connector.Next )
- {
- if ( Connector.ConnectString == ConnectString )
- { // Bingo!
- // Remove the Connector from the pooled connectors list.
- this.CutOutConnector( Connector );
- }
- Connector.Shared = Shared;
- if ( Shared )
- {
- // Shared Connectors are then put in the shared
- // connectors list in order to be used by
- // additional clients.
- this.InsertSharedConnector( Connector );
- Connector.mShareCount++;
- }
- // done...
- return Connector;
- }
- }
+ for ( Connector = Npgsql.ConnectorPool.ConnectorPoolMgr.PooledConnectors;
+ Connector != null; Connector = Connector.Next )
+ {
+ if ( Connector.ConnectString == ConnectString )
+ { // Bingo!
+ // Remove the Connector from the pooled connectors list.
+ this.CutOutConnector( Connector );
+ }
+ Connector.Shared = Shared;
+ if ( Shared )
+ {
+ // Shared Connectors are then put in the shared
+ // connectors list in order to be used by
+ // additional clients.
+ this.InsertSharedConnector( Connector );
+ Connector.mShareCount++;
+ }
+ // done...
+ return Connector;
+ }
+ }
- // No suitable connector could be found, so create new one
- Connector = new Npgsql.Connector( ConnectString, Shared );
+ // No suitable connector could be found, so create new one
+ Connector = new Npgsql.Connector( ConnectString, Shared );
- // Shared connections are added to the shared connectors list
- if ( Shared )
- {
- this.InsertSharedConnector( Connector );
- Connector.mShareCount++;
- }
+ // Shared connections are added to the shared connectors list
+ if ( Shared )
+ {
+ this.InsertSharedConnector( Connector );
+ Connector.mShareCount++;
+ }
- // and then returned to the caller
- return Connector;
- }
- }
+ // and then returned to the caller
+ return Connector;
+ }
+ }
}
// created on 1/8/2002 at 23:02
-//
+//
// Npgsql.NpgsqlDataAdapter.cs
//
// Author:
// 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
namespace Npgsql
{
- public sealed class NpgsqlDataAdapter : DbDataAdapter, IDbDataAdapter
- {
-
- private NpgsqlCommand _selectCommand;
- private NpgsqlCommand _updateCommand;
- private NpgsqlCommand _deleteCommand;
- private NpgsqlCommand _insertCommand;
-
- private NpgsqlCommandBuilder cmd_builder;
-
- // Log support
- private static readonly String CLASSNAME = "NpgsqlDataAdapter";
-
- public NpgsqlDataAdapter() {}
-
- public NpgsqlDataAdapter(NpgsqlCommand selectCommand)
- {
+ public sealed class NpgsqlDataAdapter : DbDataAdapter, IDbDataAdapter
+ {
+
+ private NpgsqlCommand _selectCommand;
+ private NpgsqlCommand _updateCommand;
+ private NpgsqlCommand _deleteCommand;
+ private NpgsqlCommand _insertCommand;
+
+ private NpgsqlCommandBuilder cmd_builder;
+
+ // Log support
+ private static readonly String CLASSNAME = "NpgsqlDataAdapter";
+
+ public NpgsqlDataAdapter()
+ {}
+
+ public NpgsqlDataAdapter(NpgsqlCommand selectCommand)
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
_selectCommand = selectCommand;
- cmd_builder = new NpgsqlCommandBuilder(this);
- }
-
- public NpgsqlDataAdapter(String selectCommandText, NpgsqlConnection selectConnection) : this(new NpgsqlCommand(selectCommandText, selectConnection)){}
-
- public NpgsqlDataAdapter(String selectCommandText, String selectConnectionString) : this(selectCommandText, new NpgsqlConnection(selectConnectionString)){}
-
-
- protected override RowUpdatedEventArgs CreateRowUpdatedEvent(
- DataRow dataRow,
- IDbCommand command,
- StatementType statementType,
- DataTableMapping tableMapping
- )
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CreateRowUpdatedEvent");
- return new NpgsqlRowUpdatedEventArgs(dataRow, command, statementType, tableMapping);
-
-
-
- }
-
- protected override RowUpdatingEventArgs CreateRowUpdatingEvent(
- DataRow dataRow,
- IDbCommand command,
- StatementType statementType,
- DataTableMapping tableMapping
- )
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CreateRowUpdatingEvent");
- return new NpgsqlRowUpdatingEventArgs(dataRow, command, statementType, tableMapping);
- }
-
- protected override void OnRowUpdated(
- RowUpdatedEventArgs value
- )
- {
+ cmd_builder = new NpgsqlCommandBuilder(this);
+ }
+
+ public NpgsqlDataAdapter(String selectCommandText, NpgsqlConnection selectConnection) : this(new NpgsqlCommand(selectCommandText, selectConnection))
+ {}
+
+ public NpgsqlDataAdapter(String selectCommandText, String selectConnectionString) : this(selectCommandText, new NpgsqlConnection(selectConnectionString))
+ {}
+
+
+ protected override RowUpdatedEventArgs CreateRowUpdatedEvent(
+ DataRow dataRow,
+ IDbCommand command,
+ StatementType statementType,
+ DataTableMapping tableMapping
+ )
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CreateRowUpdatedEvent");
+ return new NpgsqlRowUpdatedEventArgs(dataRow, command, statementType, tableMapping);
+
+
+
+ }
+
+ protected override RowUpdatingEventArgs CreateRowUpdatingEvent(
+ DataRow dataRow,
+ IDbCommand command,
+ StatementType statementType,
+ DataTableMapping tableMapping
+ )
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CreateRowUpdatingEvent");
+ return new NpgsqlRowUpdatingEventArgs(dataRow, command, statementType, tableMapping);
+ }
+
+ protected override void OnRowUpdated(
+ RowUpdatedEventArgs value
+ )
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "OnRowUpdated");
- //base.OnRowUpdated(value);
-
- }
-
- protected override void OnRowUpdating(
- RowUpdatingEventArgs value
- )
- {
+ //base.OnRowUpdated(value);
+
+ }
+
+ protected override void OnRowUpdating(
+ RowUpdatingEventArgs value
+ )
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "OnRowUpdating");
- switch (value.StatementType) {
- case StatementType.Insert:
- value.Command = cmd_builder.GetInsertCommand(value.Row);
- break;
- case StatementType.Update:
- value.Command = cmd_builder.GetUpdateCommand(value.Row);
- break;
- case StatementType.Delete:
- value.Command = cmd_builder.GetDeleteCommand(value.Row);
- break;
- }
- DataColumnMappingCollection columnMappings = value.TableMapping.ColumnMappings;
- foreach (IDataParameter parameter in value.Command.Parameters) {
-
- string dsColumnName = parameter.SourceColumn;
- if (columnMappings.Contains(parameter.SourceColumn)) {
- DataColumnMapping mapping = columnMappings[parameter.SourceColumn];
- if (mapping != null) {
- dsColumnName = mapping.DataSetColumn;
- }
- }
- DataRowVersion rowVersion = DataRowVersion.Default;
- if (value.StatementType == StatementType.Update) rowVersion = parameter.SourceVersion;
- if (value.StatementType == StatementType.Delete) rowVersion = DataRowVersion.Original;
- parameter.Value = value.Row [dsColumnName, rowVersion];
- }
- value.Row.AcceptChanges ();
- }
-
- ITableMappingCollection IDataAdapter.TableMappings
- {
- get
- {
- return TableMappings;
- }
- }
-
- IDbCommand IDbDataAdapter.DeleteCommand
- {
- get
- {
+ switch (value.StatementType)
+ {
+ case StatementType.Insert:
+ value.Command = cmd_builder.GetInsertCommand(value.Row);
+ break;
+ case StatementType.Update:
+ value.Command = cmd_builder.GetUpdateCommand(value.Row);
+ break;
+ case StatementType.Delete:
+ value.Command = cmd_builder.GetDeleteCommand(value.Row);
+ break;
+ }
+ DataColumnMappingCollection columnMappings = value.TableMapping.ColumnMappings;
+ foreach (IDataParameter parameter in value.Command.Parameters)
+ {
+
+ string dsColumnName = parameter.SourceColumn;
+ if (columnMappings.Contains(parameter.SourceColumn))
+ {
+ DataColumnMapping mapping = columnMappings[parameter.SourceColumn];
+ if (mapping != null)
+ {
+ dsColumnName = mapping.DataSetColumn;
+ }
+ }
+ DataRowVersion rowVersion = DataRowVersion.Default;
+ if (value.StatementType == StatementType.Update)
+ rowVersion = parameter.SourceVersion;
+ if (value.StatementType == StatementType.Delete)
+ rowVersion = DataRowVersion.Original;
+ parameter.Value = value.Row [dsColumnName, rowVersion];
+ }
+ value.Row.AcceptChanges ();
+ }
+
+ ITableMappingCollection IDataAdapter.TableMappings
+ {
+ get
+ {
+ return TableMappings;
+ }
+ }
+
+ IDbCommand IDbDataAdapter.DeleteCommand
+ {
+ get
+ {
NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IDbDataAdapter.DeleteCommand");
- return (NpgsqlCommand) DeleteCommand;
- }
-
- set
- {
- DeleteCommand = (NpgsqlCommand) value;
- }
- }
-
-
- public NpgsqlCommand DeleteCommand
- {
- get
- {
- return _deleteCommand;
- }
-
- set
- {
- _deleteCommand = value;
- }
- }
-
- IDbCommand IDbDataAdapter.SelectCommand
- {
- get
- {
- return (NpgsqlCommand) SelectCommand;
- }
-
- set
- {
- SelectCommand = (NpgsqlCommand) value;
- }
- }
-
-
- public NpgsqlCommand SelectCommand
- {
- get
- {
- return _selectCommand;
- }
-
- set
- {
- _selectCommand = value;
- }
- }
-
- IDbCommand IDbDataAdapter.UpdateCommand
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IDbDataAdapter.UpdateCommand");
- return (NpgsqlCommand) UpdateCommand;
- }
-
- set
- {
- UpdateCommand = (NpgsqlCommand) value;
- }
- }
-
-
- public NpgsqlCommand UpdateCommand
- {
- get
- {
- return _updateCommand;
- }
-
- set
- {
- _updateCommand = value;
- }
- }
-
- IDbCommand IDbDataAdapter.InsertCommand
- {
- get
- {
- return (NpgsqlCommand) InsertCommand;
- }
-
- set
- {
- InsertCommand = (NpgsqlCommand) value;
- }
- }
-
-
- public NpgsqlCommand InsertCommand
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "InsertCommand");
- return _insertCommand;
- }
-
- set
- {
- _insertCommand = value;
- }
- }
-
-
- }
+ return (NpgsqlCommand) DeleteCommand;
+ }
+
+ set
+ {
+ DeleteCommand = (NpgsqlCommand) value;
+ }
+ }
+
+
+ public NpgsqlCommand DeleteCommand
+ {
+ get
+ {
+ return _deleteCommand;
+ }
+
+ set
+ {
+ _deleteCommand = value;
+ }
+ }
+
+ IDbCommand IDbDataAdapter.SelectCommand
+ {
+ get
+ {
+ return (NpgsqlCommand) SelectCommand;
+ }
+
+ set
+ {
+ SelectCommand = (NpgsqlCommand) value;
+ }
+ }
+
+
+ public NpgsqlCommand SelectCommand
+ {
+ get
+ {
+ return _selectCommand;
+ }
+
+ set
+ {
+ _selectCommand = value;
+ }
+ }
+
+ IDbCommand IDbDataAdapter.UpdateCommand
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IDbDataAdapter.UpdateCommand");
+ return (NpgsqlCommand) UpdateCommand;
+ }
+
+ set
+ {
+ UpdateCommand = (NpgsqlCommand) value;
+ }
+ }
+
+
+ public NpgsqlCommand UpdateCommand
+ {
+ get
+ {
+ return _updateCommand;
+ }
+
+ set
+ {
+ _updateCommand = value;
+ }
+ }
+
+ IDbCommand IDbDataAdapter.InsertCommand
+ {
+ get
+ {
+ return (NpgsqlCommand) InsertCommand;
+ }
+
+ set
+ {
+ InsertCommand = (NpgsqlCommand) value;
+ }
+ }
+
+
+ public NpgsqlCommand InsertCommand
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "InsertCommand");
+ return _insertCommand;
+ }
+
+ set
+ {
+ _insertCommand = value;
+ }
+ }
+
+
+ }
}
public class NpgsqlRowUpdatingEventArgs : RowUpdatingEventArgs
{
- public NpgsqlRowUpdatingEventArgs (
- DataRow dataRow,
- IDbCommand command,
- StatementType statementType,
- DataTableMapping tableMapping
- ) : base(dataRow, command, statementType, tableMapping)
-
- {
-
- }
-
+ public NpgsqlRowUpdatingEventArgs (
+ DataRow dataRow,
+ IDbCommand command,
+ StatementType statementType,
+ DataTableMapping tableMapping
+ ) : base(dataRow, command, statementType, tableMapping)
+
+ {
+ }
+
}
public class NpgsqlRowUpdatedEventArgs : RowUpdatedEventArgs
{
- public NpgsqlRowUpdatedEventArgs (
- DataRow dataRow,
- IDbCommand command,
- StatementType statementType,
- DataTableMapping tableMapping
- ) : base(dataRow, command, statementType, tableMapping)
-
- {
-
- }
-
+ public NpgsqlRowUpdatedEventArgs (
+ DataRow dataRow,
+ IDbCommand command,
+ StatementType statementType,
+ DataTableMapping tableMapping
+ ) : base(dataRow, command, statementType, tableMapping)
+
+ {
+ }
+
}
// Npgsql.NpgsqlDataReader.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- public class NpgsqlDataReader : IDataReader, IEnumerable
- {
-
-
-
- private NpgsqlConnection _connection;
- private ArrayList _resultsets;
- private ArrayList _responses;
- private Int32 _rowIndex;
- private Int32 _resultsetIndex;
- private NpgsqlResultSet _currentResultset;
- private DataTable _currentResultsetSchema;
-
-
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlDataReader";
-
- internal NpgsqlDataReader( ArrayList resultsets, ArrayList responses, NpgsqlConnection connection)
- {
- _resultsets = resultsets;
- _responses = responses;
- _connection = connection;
- _rowIndex = -1;
- _resultsetIndex = 0;
- if (_resultsets.Count > 0)
- _currentResultset = (NpgsqlResultSet)_resultsets[_resultsetIndex];
-
-
-
- }
-
- private Boolean CanRead()
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CanRead");
- /*if (_currentResultset == null)
- return false;*/
- return ((_currentResultset != null) && (_currentResultset.Count > 0));
-
- }
-
- private void CheckCanRead()
- {
- if (!CanRead())
- throw new InvalidOperationException("Cannot read data");
- }
-
- public void Dispose()
- {
-
- }
- public Int32 Depth
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Depth");
- return 0;
- }
- }
-
- public Boolean IsClosed
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsClosed");
- return false;
- }
- }
-
- public Int32 RecordsAffected
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "RecordsAffected");
-
- /*if (_currentResultset == null)
- return 0; //[FIXME] Get the actual number of rows deleted, updated or inserted.
- return -1;
- */
-
- if (CanRead())
- return -1;
-
- String[] ret_string_tokens = ((String)_responses[_resultsetIndex]).Split(null); // whitespace separator.
-
- return Int32.Parse(ret_string_tokens[ret_string_tokens.Length - 1]);
- }
-
- }
-
- public void Close()
- {
-
- }
-
- public Boolean NextResult()
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "NextResult");
- //throw new NotImplementedException();
-
- //[FIXME] Should the currentResultset not be modified
- // in case there aren't any more resultsets?
- // SqlClient modify to a invalid resultset and throws exceptions
- // when trying to access any data.
-
-
- if((_resultsetIndex + 1) < _resultsets.Count)
- {
- _resultsetIndex++;
- _rowIndex = -1;
- _currentResultset = (NpgsqlResultSet)_resultsets[_resultsetIndex];
- return true;
- }
- else
- return false;
-
- }
-
- public Boolean Read()
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Read");
-
- if (!CanRead())
- return false;
-
- _rowIndex++;
- return (_rowIndex < _currentResultset.Count);
- }
-
- public DataTable GetSchemaTable()
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetSchemaTable");
-
- if(_currentResultsetSchema == null)
- _currentResultsetSchema = GetResultsetSchema();
-
- return _currentResultsetSchema;
-
- }
-
-
- public Int32 FieldCount
- {
- get
- {
-
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "FieldCount");
- //return ((_currentResultset == null) ? 0 : _currentResultset.RowDescription.NumFields);
-
- /*if (CanRead())
- return _currentResultset.RowDescription.NumFields;
- else
- return -1;*/
-
- if (_currentResultset == null) //Executed a non return rows query.
- return -1;
- else
- return _currentResultset.RowDescription.NumFields;
-
-
- }
-
- }
-
- public String GetName(Int32 i)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetName");
-
- if (_currentResultset == null)
- return String.Empty;
- else
- return _currentResultset.RowDescription[i].name;
- }
-
- public String GetDataTypeName(Int32 i)
- {
- // FIXME: have a type name instead of the oid
- if (_currentResultset == null)
- return String.Empty;
- else
- return (_currentResultset.RowDescription[i].type_oid).ToString();
- }
-
- public Type GetFieldType(Int32 i)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetFieldType");
-
-
- if (_currentResultset == null)
- return null;
- else
- return NpgsqlTypesHelper.GetSystemTypeFromTypeOid(_connection.OidToNameMapping, _currentResultset.RowDescription[i].type_oid);
- }
-
- public Object GetValue(Int32 i)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetValue");
-
- CheckCanRead();
-
- if (i < 0 || _rowIndex < 0)
- throw new InvalidOperationException("Cannot read data.");
- return ((NpgsqlAsciiRow)_currentResultset[_rowIndex])[i];
-
-
- }
-
-
- public Int32 GetValues(Object[] values)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetValues");
-
- CheckCanRead();
-
- // Only the number of elements in the array are filled.
- // It's also possible to pass an array with more that FieldCount elements.
- Int32 maxColumnIndex = (values.Length < FieldCount) ? values.Length : FieldCount;
-
- for (Int32 i = 0; i < maxColumnIndex; i++)
- values[i] = GetValue(i);
-
- return maxColumnIndex;
-
- }
-
- public Int32 GetOrdinal(String name)
- {
- CheckCanRead();
- return _currentResultset.RowDescription.FieldIndex(name);
- }
-
- public Object this [ Int32 i ]
- {
- get
- {
- NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, i);
- return GetValue(i);
- }
- }
-
- public Object this [ String name ]
- {
- get
- {
- //throw new NotImplementedException();
- NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, name);
- return GetValue(_currentResultset.RowDescription.FieldIndex(name));
- }
- }
-
- public Boolean GetBoolean(Int32 i)
- {
- // Should this be done using the GetValue directly and not by converting to String
- // and parsing from there?
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetBoolean");
-
-
- return (Boolean) GetValue(i);
-
- }
-
- public Byte GetByte(Int32 i)
- {
- throw new NotImplementedException();
- }
-
- public Int64 GetBytes(Int32 i, Int64 fieldOffset, Byte[] buffer, Int32 bufferoffset, Int32 length)
- {
-
- Byte[] result;
-
- result = (Byte[]) GetValue(i);
-
- // [TODO] Implement blob support.
- if (buffer != null)
- {
- result.CopyTo(buffer, 0);
- }
-
- return result.Length;
-
- }
-
- public Char GetChar(Int32 i)
- {
- throw new NotImplementedException();
- }
-
- public Int64 GetChars(Int32 i, Int64 fieldoffset, Char[] buffer, Int32 bufferoffset, Int32 length)
- {
- String str;
-
- str = GetString(i);
- if (buffer == null)
- return str.Length;
-
- str.ToCharArray(bufferoffset, length).CopyTo(buffer, 0);
- return buffer.GetLength(0);
- }
-
- public Guid GetGuid(Int32 i)
- {
- throw new NotImplementedException();
- }
-
- public Int16 GetInt16(Int32 i)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetInt16");
-
- return (Int16) GetValue(i);
-
- }
-
-
- public Int32 GetInt32(Int32 i)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetInt32");
-
- return (Int32) GetValue(i);
-
- }
-
-
- public Int64 GetInt64(Int32 i)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetInt64");
-
- return (Int64) GetValue(i);
- }
-
- public Single GetFloat(Int32 i)
- {
- // Should this be done using the GetValue directly and not by converting to String
- // and parsing from there?
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetFloat");
- /*try
- {
- return Single.Parse((String) this[i]);
- } catch (System.FormatException)
- {
- throw new System.InvalidCastException();
- }*/
- return (Single) GetValue(i);
- }
-
- public Double GetDouble(Int32 i)
- {
- // Should this be done using the GetValue directly and not by converting to String
- // and parsing from there?
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetDouble");
- /*try
- {
- return Double.Parse((String) this[i]);
- } catch (System.FormatException)
- {
- throw new System.InvalidCastException();
- }*/
- return (Double) GetValue(i);
- }
-
- public String GetString(Int32 i)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetString");
-
- return (String) GetValue(i);
- }
-
- public Decimal GetDecimal(Int32 i)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetDecimal");
-
- return (Decimal) GetValue(i);
- }
-
- public DateTime GetDateTime(Int32 i)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetDateTime");
-
- return (DateTime) GetValue(i);
- }
-
- public IDataReader GetData(Int32 i)
- {
- throw new NotImplementedException();
- }
-
- public Boolean IsDBNull(Int32 i)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IsDBNull");
-
- CheckCanRead();
-
- return ((NpgsqlAsciiRow)_currentResultset[_rowIndex]).IsNull(i);
- }
-
- private DataTable GetResultsetSchema()
- {
-
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetResultsetSchema");
- DataTable result = null;
-
- NpgsqlRowDescription rd = _currentResultset.RowDescription;
- Int16 numFields = rd.NumFields;
- if(numFields > 0) {
- result = new DataTable("SchemaTable");
-
- result.Columns.Add ("ColumnName", typeof (string));
- result.Columns.Add ("ColumnOrdinal", typeof (int));
- result.Columns.Add ("ColumnSize", typeof (int));
- result.Columns.Add ("NumericPrecision", typeof (int));
- result.Columns.Add ("NumericScale", typeof (int));
- result.Columns.Add ("IsUnique", typeof (bool));
- result.Columns.Add ("IsKey", typeof (bool));
- DataColumn dc = result.Columns["IsKey"];
- dc.AllowDBNull = true; // IsKey can have a DBNull
- result.Columns.Add ("BaseCatalogName", typeof (string));
- result.Columns.Add ("BaseColumnName", typeof (string));
- result.Columns.Add ("BaseSchemaName", typeof (string));
- result.Columns.Add ("BaseTableName", typeof (string));
- result.Columns.Add ("DataType", typeof(Type));
- result.Columns.Add ("AllowDBNull", typeof (bool));
- result.Columns.Add ("ProviderType", typeof (int));
- result.Columns.Add ("IsAliased", typeof (bool));
- result.Columns.Add ("IsExpression", typeof (bool));
- result.Columns.Add ("IsIdentity", typeof (bool));
- result.Columns.Add ("IsAutoIncrement", typeof (bool));
- result.Columns.Add ("IsRowVersion", typeof (bool));
- result.Columns.Add ("IsHidden", typeof (bool));
- result.Columns.Add ("IsLong", typeof (bool));
- result.Columns.Add ("IsReadOnly", typeof (bool));
-
- DataRow row;
-
- for (Int16 i = 0; i < numFields; i++) {
- row = result.NewRow();
-
- row["ColumnName"] = GetName(i);
- row["ColumnOrdinal"] = i + 1;
- row["ColumnSize"] = (int) rd[i].type_size;
- row["NumericPrecision"] = 0;
- row["NumericScale"] = 0;
- row["IsUnique"] = false;
- row["IsKey"] = DBNull.Value;
- row["BaseCatalogName"] = "";
- row["BaseColumnName"] = GetName(i);
- row["BaseSchemaName"] = "";
- row["BaseTableName"] = "";
- row["DataType"] = GetFieldType(i);
- row["AllowDBNull"] = false;
- row["ProviderType"] = (int) rd[i].type_oid;
- row["IsAliased"] = false;
- row["IsExpression"] = false;
- row["IsIdentity"] = false;
- row["IsAutoIncrement"] = false;
- row["IsRowVersion"] = false;
- row["IsHidden"] = false;
- row["IsLong"] = false;
- row["IsReadOnly"] = false;
-
- result.Rows.Add(row);
- }
- }
-
- return result;
-
- }
-
-
-
- IEnumerator IEnumerable.GetEnumerator ()
- {
- return new System.Data.Common.DbEnumerator (this);
- }
- }
+
+ public class NpgsqlDataReader : IDataReader, IEnumerable
+ {
+
+
+
+ private NpgsqlConnection _connection;
+ private ArrayList _resultsets;
+ private ArrayList _responses;
+ private Int32 _rowIndex;
+ private Int32 _resultsetIndex;
+ private NpgsqlResultSet _currentResultset;
+ private DataTable _currentResultsetSchema;
+ private CommandBehavior _behavior;
+ private Boolean _isClosed;
+
+
+
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlDataReader";
+
+ internal NpgsqlDataReader( ArrayList resultsets, ArrayList responses, NpgsqlConnection connection, CommandBehavior behavior)
+ {
+ _resultsets = resultsets;
+ _responses = responses;
+ _connection = connection;
+ _rowIndex = -1;
+ _resultsetIndex = 0;
+
+ if (_resultsets.Count > 0)
+ _currentResultset = (NpgsqlResultSet)_resultsets[_resultsetIndex];
+
+ _behavior = behavior;
+ _isClosed = false;
+
+ }
+
+ private Boolean CanRead()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CanRead");
+ /*if (_currentResultset == null)
+ return false;*/
+ return ((_currentResultset != null) && (_currentResultset.Count > 0));
+
+ }
+
+ private void CheckCanRead()
+ {
+ if (!CanRead())
+ throw new InvalidOperationException("Cannot read data");
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ /// <summary>
+ /// Releases the resources used by the <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>.
+ /// </summary>
+ protected void Dispose (bool disposing)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Dispose");
+ if (disposing)
+ {
+ this.Close();
+ }
+ }
+ public Int32 Depth
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Depth");
+ return 0;
+ }
+ }
+
+ public Boolean IsClosed
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsClosed");
+ return _isClosed;
+ }
+ }
+
+ public Int32 RecordsAffected
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "RecordsAffected");
+
+
+ if (CanRead())
+ return -1;
+
+ String[] ret_string_tokens = ((String)_responses[_resultsetIndex]).Split(null); // whitespace separator.
+
+ return Int32.Parse(ret_string_tokens[ret_string_tokens.Length - 1]);
+ }
+
+ }
+
+ public void Close()
+ {
+ if ((_behavior & CommandBehavior.CloseConnection) == CommandBehavior.CloseConnection)
+ {
+ _connection.Close();
+ _isClosed = true;
+ }
+
+ }
+
+ public Boolean NextResult()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "NextResult");
+ //throw new NotImplementedException();
+
+ //[FIXME] Should the currentResultset not be modified
+ // in case there aren't any more resultsets?
+ // SqlClient modify to a invalid resultset and throws exceptions
+ // when trying to access any data.
+
+
+ if((_resultsetIndex + 1) < _resultsets.Count)
+ {
+ _resultsetIndex++;
+ _rowIndex = -1;
+ _currentResultset = (NpgsqlResultSet)_resultsets[_resultsetIndex];
+ return true;
+ }
+ else
+ return false;
+
+ }
+
+ public Boolean Read()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Read");
+
+ if (!CanRead())
+ return false;
+
+ _rowIndex++;
+ return (_rowIndex < _currentResultset.Count);
+ }
+
+ public DataTable GetSchemaTable()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetSchemaTable");
+
+ if(_currentResultsetSchema == null)
+ _currentResultsetSchema = GetResultsetSchema();
+
+ return _currentResultsetSchema;
+
+ }
+
+
+ public Int32 FieldCount
+ {
+ get
+ {
+
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "FieldCount");
+
+ if (_currentResultset == null) //Executed a non return rows query.
+ return -1;
+ else
+ return _currentResultset.RowDescription.NumFields;
+
+
+ }
+
+ }
+
+ public String GetName(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetName");
+
+ if (_currentResultset == null)
+ return String.Empty;
+ else
+ return _currentResultset.RowDescription[i].name;
+ }
+
+ public String GetDataTypeName(Int32 i)
+ {
+ // FIXME: have a type name instead of the oid
+ if (_currentResultset == null)
+ return String.Empty;
+ else
+ return (_currentResultset.RowDescription[i].type_oid).ToString();
+ }
+
+ public Type GetFieldType(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetFieldType");
+
+
+ if (_currentResultset == null)
+ return null;
+ else
+ return NpgsqlTypesHelper.GetSystemTypeFromTypeOid(_connection.OidToNameMapping, _currentResultset.RowDescription[i].type_oid);
+ }
+
+ public Object GetValue(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetValue");
+
+ CheckCanRead();
+
+ if (i < 0 || _rowIndex < 0)
+ throw new InvalidOperationException("Cannot read data.");
+ return ((NpgsqlAsciiRow)_currentResultset[_rowIndex])[i];
+
+
+ }
+
+
+ public Int32 GetValues(Object[] values)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetValues");
+
+ CheckCanRead();
+
+ // Only the number of elements in the array are filled.
+ // It's also possible to pass an array with more that FieldCount elements.
+ Int32 maxColumnIndex = (values.Length < FieldCount) ? values.Length : FieldCount;
+
+ for (Int32 i = 0; i < maxColumnIndex; i++)
+ values[i] = GetValue(i);
+
+ return maxColumnIndex;
+
+ }
+
+ public Int32 GetOrdinal(String name)
+ {
+ CheckCanRead();
+ return _currentResultset.RowDescription.FieldIndex(name);
+ }
+
+ public Object this [ Int32 i ]
+ {
+ get
+ {
+ NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, i);
+ return GetValue(i);
+ }
+ }
+
+ public Object this [ String name ]
+ {
+ get
+ {
+ //throw new NotImplementedException();
+ NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, name);
+ return GetValue(_currentResultset.RowDescription.FieldIndex(name));
+ }
+ }
+
+ public Boolean GetBoolean(Int32 i)
+ {
+ // Should this be done using the GetValue directly and not by converting to String
+ // and parsing from there?
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetBoolean");
+
+
+ return (Boolean) GetValue(i);
+
+ }
+
+ public Byte GetByte(Int32 i)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Int64 GetBytes(Int32 i, Int64 fieldOffset, Byte[] buffer, Int32 bufferoffset, Int32 length)
+ {
+
+ Byte[] result;
+
+ result = (Byte[]) GetValue(i);
+
+ // [TODO] Implement blob support.
+ if (buffer != null)
+ {
+ result.CopyTo(buffer, 0);
+ }
+
+ return result.Length;
+
+ }
+
+ public Char GetChar(Int32 i)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Int64 GetChars(Int32 i, Int64 fieldoffset, Char[] buffer, Int32 bufferoffset, Int32 length)
+ {
+ String str;
+
+ str = GetString(i);
+ if (buffer == null)
+ return str.Length;
+
+ str.ToCharArray(bufferoffset, length).CopyTo(buffer, 0);
+ return buffer.GetLength(0);
+ }
+
+ public Guid GetGuid(Int32 i)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Int16 GetInt16(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetInt16");
+
+ return (Int16) GetValue(i);
+
+ }
+
+
+ public Int32 GetInt32(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetInt32");
+
+ return (Int32) GetValue(i);
+
+ }
+
+
+ public Int64 GetInt64(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetInt64");
+
+ return (Int64) GetValue(i);
+ }
+
+ public Single GetFloat(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetFloat");
+
+ return (Single) GetValue(i);
+ }
+
+ public Double GetDouble(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetDouble");
+
+ return (Double) GetValue(i);
+ }
+
+ public String GetString(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetString");
+
+ return (String) GetValue(i);
+ }
+
+ public Decimal GetDecimal(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetDecimal");
+
+ return (Decimal) GetValue(i);
+ }
+
+ public DateTime GetDateTime(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetDateTime");
+
+ return (DateTime) GetValue(i);
+ }
+
+ public IDataReader GetData(Int32 i)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Boolean IsDBNull(Int32 i)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IsDBNull");
+
+ CheckCanRead();
+
+ return ((NpgsqlAsciiRow)_currentResultset[_rowIndex]).IsNull(i);
+ }
+
+ private DataTable GetResultsetSchema()
+ {
+
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetResultsetSchema");
+ DataTable result = null;
+
+ NpgsqlRowDescription rd = _currentResultset.RowDescription;
+ Int16 numFields = rd.NumFields;
+ if(numFields > 0)
+ {
+ result = new DataTable("SchemaTable");
+
+ result.Columns.Add ("ColumnName", typeof (string));
+ result.Columns.Add ("ColumnOrdinal", typeof (int));
+ result.Columns.Add ("ColumnSize", typeof (int));
+ result.Columns.Add ("NumericPrecision", typeof (int));
+ result.Columns.Add ("NumericScale", typeof (int));
+ result.Columns.Add ("IsUnique", typeof (bool));
+ result.Columns.Add ("IsKey", typeof (bool));
+ DataColumn dc = result.Columns["IsKey"];
+ dc.AllowDBNull = true; // IsKey can have a DBNull
+ result.Columns.Add ("BaseCatalogName", typeof (string));
+ result.Columns.Add ("BaseColumnName", typeof (string));
+ result.Columns.Add ("BaseSchemaName", typeof (string));
+ result.Columns.Add ("BaseTableName", typeof (string));
+ result.Columns.Add ("DataType", typeof(Type));
+ result.Columns.Add ("AllowDBNull", typeof (bool));
+ result.Columns.Add ("ProviderType", typeof (int));
+ result.Columns.Add ("IsAliased", typeof (bool));
+ result.Columns.Add ("IsExpression", typeof (bool));
+ result.Columns.Add ("IsIdentity", typeof (bool));
+ result.Columns.Add ("IsAutoIncrement", typeof (bool));
+ result.Columns.Add ("IsRowVersion", typeof (bool));
+ result.Columns.Add ("IsHidden", typeof (bool));
+ result.Columns.Add ("IsLong", typeof (bool));
+ result.Columns.Add ("IsReadOnly", typeof (bool));
+
+ DataRow row;
+
+ for (Int16 i = 0; i < numFields; i++)
+ {
+ row = result.NewRow();
+
+ row["ColumnName"] = GetName(i);
+ row["ColumnOrdinal"] = i + 1;
+ row["ColumnSize"] = (int) rd[i].type_size;
+ row["NumericPrecision"] = 0;
+ row["NumericScale"] = 0;
+ row["IsUnique"] = false;
+ row["IsKey"] = DBNull.Value;
+ row["BaseCatalogName"] = "";
+ row["BaseColumnName"] = GetName(i);
+ row["BaseSchemaName"] = "";
+ row["BaseTableName"] = "";
+ row["DataType"] = GetFieldType(i);
+ row["AllowDBNull"] = false;
+ row["ProviderType"] = (int) rd[i].type_oid;
+ row["IsAliased"] = false;
+ row["IsExpression"] = false;
+ row["IsIdentity"] = false;
+ row["IsAutoIncrement"] = false;
+ row["IsRowVersion"] = false;
+ row["IsHidden"] = false;
+ row["IsLong"] = false;
+ row["IsReadOnly"] = false;
+
+ result.Rows.Add(row);
+ }
+ }
+
+ return result;
+
+ }
+
+
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return new System.Data.Common.DbEnumerator (this);
+ }
+ }
}
// created on 1/7/2003 at 20:48
// Npgsql.NpgsqlDescribe.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- /// <summary>
- /// This class represents the Parse message sent to PostgreSQL
- /// server.
- /// </summary>
- ///
- internal sealed class NpgsqlDescribe
- {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlDescribe";
-
- private Char _whatToDescribe;
- private String _portalName;
-
- public NpgsqlDescribe(Char whatToDescribe, String portalName)
- {
- _whatToDescribe = whatToDescribe;
- _portalName = portalName;
-
- }
-
- public void WriteToStream(Stream outputStream, Encoding encoding)
- {
- outputStream.WriteByte((Byte)'D');
-
- PGUtil.WriteInt32(outputStream, 4 +
- 1 +
- encoding.GetByteCount(_portalName) + 1);
-
- outputStream.WriteByte((Byte)_whatToDescribe);
- PGUtil.WriteString(_portalName, outputStream, encoding);
-
-
- }
-
- }
+
+ /// <summary>
+ /// This class represents the Parse message sent to PostgreSQL
+ /// server.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlDescribe
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlDescribe";
+
+ private Char _whatToDescribe;
+ private String _portalName;
+
+ public NpgsqlDescribe(Char whatToDescribe, String portalName)
+ {
+ _whatToDescribe = whatToDescribe;
+ _portalName = portalName;
+
+ }
+
+ public void WriteToStream(Stream outputStream, Encoding encoding)
+ {
+ outputStream.WriteByte((Byte)'D');
+
+ PGUtil.WriteInt32(outputStream, 4 +
+ 1 +
+ encoding.GetByteCount(_portalName) + 1);
+
+ outputStream.WriteByte((Byte)_whatToDescribe);
+ PGUtil.WriteString(_portalName, outputStream, encoding);
+
+
+ }
+
+ }
}
-
+
// created on 12/7/2003 at 18:36
// Npgsql.NpgsqlError.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- /// <summary>
- /// This class represents the ErrorResponse message sent from PostgreSQL
- /// server.
- /// </summary>
- ///
- internal sealed class NpgsqlError
- {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlError";
-
- private Int32 _protocolVersion;
- private String _severity;
- private String _code;
- private String _message;
- private String _detail;
- private String _hint;
- private String _position;
- private String _where;
- private String _file;
- private String _line;
- private String _routine;
-
-
-
- public String Message
- {
- get
- {
- return _message;
- }
- }
-
-
-
-
- public NpgsqlError(Int32 protocolVersion)
- {
- _protocolVersion = protocolVersion;
-
- }
-
- public void ReadFromStream(Stream inputStream, Encoding encoding)
- {
-
- if (_protocolVersion == ProtocolVersion.Version2)
- {
- _message = PGUtil.ReadString(inputStream, encoding);
-
- }
- else
- {
- Int32 messageLength = PGUtil.ReadInt32(inputStream, new Byte[4]);
-
- //[TODO] Would this be the right way to do?
- // Check the messageLength value. If it is 1178686529, this would be the
- // "FATA" string, which would mean a protocol 2.0 error string.
-
- if (messageLength == 1178686529)
- {
- _message = "FATA" + PGUtil.ReadString(inputStream, encoding);
- return;
- }
-
- Char field;
- String fieldValue;
-
- field = (Char) inputStream.ReadByte();
-
- // Now start to read fields.
- while (field != 0)
- {
-
- fieldValue = PGUtil.ReadString(inputStream, encoding);
-
- switch (field)
- {
- case 'S':
- _severity = fieldValue;
- break;
- case 'C':
- _code = fieldValue;
- break;
- case 'M':
- _message = fieldValue;
- break;
- case 'D':
- _detail = fieldValue;
- break;
- case 'H':
- _hint = fieldValue;
- break;
- case 'P':
- _position = fieldValue;
- break;
- case 'W':
- _where = fieldValue;
- break;
- case 'F':
- _file = fieldValue;
- break;
- case 'L':
- _line = fieldValue;
- break;
- case 'R':
- _routine = fieldValue;
- break;
-
- }
-
- field = (Char) inputStream.ReadByte();
-
- }
-
- // Read 0 byte terminator.
- //inputStream.ReadByte();
- }
-
- }
- }
+
+ /// <summary>
+ /// This class represents the ErrorResponse message sent from PostgreSQL
+ /// server.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlError
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlError";
+
+ private Int32 _protocolVersion;
+ private String _severity;
+ private String _code;
+ private String _message;
+ private String _detail;
+ private String _hint;
+ private String _position;
+ private String _where;
+ private String _file;
+ private String _line;
+ private String _routine;
+
+
+
+ public String Message
+ {
+ get
+ {
+ return _message;
+ }
+ }
+
+
+
+
+ public NpgsqlError(Int32 protocolVersion)
+ {
+ _protocolVersion = protocolVersion;
+
+ }
+
+ public void ReadFromStream(Stream inputStream, Encoding encoding)
+ {
+
+ if (_protocolVersion == ProtocolVersion.Version2)
+ {
+ _message = PGUtil.ReadString(inputStream, encoding);
+
+ }
+ else
+ {
+ Int32 messageLength = PGUtil.ReadInt32(inputStream, new Byte[4]);
+
+ //[TODO] Would this be the right way to do?
+ // Check the messageLength value. If it is 1178686529, this would be the
+ // "FATA" string, which would mean a protocol 2.0 error string.
+
+ if (messageLength == 1178686529)
+ {
+ _message = "FATA" + PGUtil.ReadString(inputStream, encoding);
+ return;
+ }
+
+ Char field;
+ String fieldValue;
+
+ field = (Char) inputStream.ReadByte();
+
+ // Now start to read fields.
+ while (field != 0)
+ {
+
+ fieldValue = PGUtil.ReadString(inputStream, encoding);
+
+ switch (field)
+ {
+ case 'S':
+ _severity = fieldValue;
+ break;
+ case 'C':
+ _code = fieldValue;
+ break;
+ case 'M':
+ _message = fieldValue;
+ break;
+ case 'D':
+ _detail = fieldValue;
+ break;
+ case 'H':
+ _hint = fieldValue;
+ break;
+ case 'P':
+ _position = fieldValue;
+ break;
+ case 'W':
+ _where = fieldValue;
+ break;
+ case 'F':
+ _file = fieldValue;
+ break;
+ case 'L':
+ _line = fieldValue;
+ break;
+ case 'R':
+ _routine = fieldValue;
+ break;
+
+ }
+
+ field = (Char) inputStream.ReadByte();
+
+ }
+
+ // Read 0 byte terminator.
+ //inputStream.ReadByte();
+ }
+
+ }
+ }
}
// created on 07/06/2002 at 09:34
// Npgsql.NpgsqlEventLog.cs
-//
+//
// Author:
// Dave Page (dpage@postgresql.org)
//
// 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.Resources;
-namespace Npgsql {
+namespace Npgsql
+{
+
+ /// <summary>
+ /// The level of verbosity of the NpgsqlEventLog
+ /// </summary>
+ public enum LogLevel {
+ /// <summary>
+ /// Don't log at all
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// Only log the most common issues
+ /// </summary>
+ Normal = 1,
+ /// <summary>
+ /// Log everything
+ /// </summary>
+ Debug = 2
+ }
+
+
+ /// <summary>
+ /// This class handles all the Npgsql event and debug logging
+ /// </summary>
+ public class NpgsqlEventLog
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlEventLog";
+ private static String logfile;
+ private static LogLevel level;
+ private static Boolean echomessages;
+
+ private static ResourceManager LogResMan;
+
+ private NpgsqlEventLog()
+ {}
+ // static constructor
+ static NpgsqlEventLog()
+ {
+ LogResMan = new ResourceManager(typeof(NpgsqlEventLog));
+ }
+
+ ///<summary>
+ /// Sets/Returns the level of information to log to the logfile.
+ /// </summary>
+ /// <value>The current <see cref="Npgsql.LogLevel">LogLevel</see></value>
+ public static LogLevel Level {
+ get
+ {
+ LogPropertyGet(LogLevel.Debug, CLASSNAME, "LogLevel");
+ return level;
+ }
+ set
+ {
+ LogPropertySet(LogLevel.Debug, CLASSNAME, "LogLevel", value);
+ level = value;
+ }
+ }
+
+ ///<summary>
+ /// Sets/Returns the filename to use for logging.
+ /// </summary>
+ /// <value>The filename of the current Log file.</value>
+ public static String LogName {
+ get
+ {
+ LogPropertyGet(LogLevel.Debug, CLASSNAME, "LogName");
+ return logfile;
+ }
+ set
+ {
+ LogPropertySet(LogLevel.Normal, CLASSNAME, "LogName", value);
+ logfile = value;
+ }
+ }
- /// <summary>
- /// The level of verbosity of the NpgsqlEventLog
- /// </summary>
- public enum LogLevel {
- /// <summary>
- /// Don't log at all
- /// </summary>
- None = 0,
- /// <summary>
- /// Only log the most common issues
- /// </summary>
- Normal = 1,
- /// <summary>
- /// Log everything
- /// </summary>
- Debug = 2
- }
+ ///<summary>
+ /// Sets/Returns whether Log messages should be echoed to the console
+ /// </summary>
+ /// <value><b>true</b> if Log messages are echoed to the console, otherwise <b>false</b></value>
+ public static Boolean EchoMessages {
+ get
+ {
+ LogPropertyGet(LogLevel.Debug, CLASSNAME, "EchoMessages");
+ return echomessages;
+ }
+ set
+ {
+ LogPropertySet(LogLevel.Normal, CLASSNAME, "EchoMessages", value);
+ echomessages = value;
+ }
+ }
+ // Event/Debug Logging
+ // This method should be private and only used by the internal methods that support localization.
+ /// <summary>
+ /// Writes a string to the Npgsql event log if msglevel is bigger then <see cref="Npgsql.NpgsqlEventLog.Level">NpgsqlEventLog.Level</see>
+ /// </summary>
+ /// <remarks>
+ /// This method is obsolete and should no longer be used.
+ /// It is likely to be removed in future versions of Npgsql
+ /// </remarks>
+ /// <param name="message">The message to write to the event log</param>
+ /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
+ private static void LogMsg(String message, LogLevel msglevel)
+ {
+ if (msglevel > level)
+ return;
- /// <summary>
- /// This class handles all the Npgsql event and debug logging
- /// </summary>
- public class NpgsqlEventLog {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlEventLog";
- private static String logfile;
- private static LogLevel level;
- private static Boolean echomessages;
+ Process proc = Process.GetCurrentProcess();
- private static ResourceManager LogResMan;
+ if (echomessages)
+ {
+ Console.WriteLine(message);
+ }
- private NpgsqlEventLog() {}
- // static constructor
- static NpgsqlEventLog() {
- LogResMan = new ResourceManager(typeof(NpgsqlEventLog));
- }
-
- ///<summary>
- /// Sets/Returns the level of information to log to the logfile.
- /// </summary>
- /// <value>The current <see cref="Npgsql.LogLevel">LogLevel</see></value>
- public static LogLevel Level {
- get {
- LogPropertyGet(LogLevel.Debug, CLASSNAME, "LogLevel");
- return level;
- }
- set {
- LogPropertySet(LogLevel.Debug, CLASSNAME, "LogLevel", value);
- level = value;
- }
- }
-
- ///<summary>
- /// Sets/Returns the filename to use for logging.
- /// </summary>
- /// <value>The filename of the current Log file.</value>
- public static String LogName {
- get {
- LogPropertyGet(LogLevel.Debug, CLASSNAME, "LogName");
- return logfile;
- }
- set {
- LogPropertySet(LogLevel.Normal, CLASSNAME, "LogName", value);
- logfile = value;
- }
- }
+ if (logfile != null)
+ {
+ if (logfile != "")
+ {
- ///<summary>
- /// Sets/Returns whether Log messages should be echoed to the console
- /// </summary>
- /// <value><b>true</b> if Log messages are echoed to the console, otherwise <b>false</b></value>
- public static Boolean EchoMessages {
- get {
- LogPropertyGet(LogLevel.Debug, CLASSNAME, "EchoMessages");
- return echomessages;
- }
- set {
- LogPropertySet(LogLevel.Normal, CLASSNAME, "EchoMessages", value);
- echomessages = value;
- }
- }
-
- // Event/Debug Logging
- // This method should be private and only used by the internal methods that support localization.
- /// <summary>
- /// Writes a string to the Npgsql event log if msglevel is bigger then <see cref="Npgsql.NpgsqlEventLog.Level">NpgsqlEventLog.Level</see>
- /// </summary>
- /// <remarks>
- /// This method is obsolete and should no longer be used.
- /// It is likely to be removed in future versions of Npgsql
- /// </remarks>
- /// <param name="message">The message to write to the event log</param>
- /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
- [Obsolete("This method will be private and should only used by the internal methods that support localization.")]
- public static void LogMsg(String message, LogLevel msglevel) {
- if (msglevel > level)
- return;
-
- Process proc = Process.GetCurrentProcess();
-
- if (echomessages) {
- Console.WriteLine(message);
- }
-
- if (logfile != null) {
- if (logfile != "") {
-
- StreamWriter writer = new StreamWriter(logfile, true);
-
- // The format of the logfile is
- // [Date] [Time] [PID] [Level] [Message]
- writer.WriteLine(System.DateTime.Now + "\t" + proc.Id + "\t" + msglevel + "\t" + message);
- writer.Close();
- }
- }
- }
+ StreamWriter writer = new StreamWriter(logfile, true);
- /// <summary>
- /// Writes a string to the Npgsql event log if msglevel is bigger then <see cref="Npgsql.NpgsqlEventLog.Level">NpgsqlEventLog.Level</see>
- /// </summary>
- /// <param name="resman">The <see cref="System.Resources.ResourceManager">ResourceManager</see> to get the localized resources</param>
- /// <param name="ResourceString">The name of the resource that should be fetched by the <see cref="System.Resources.ResourceManager">ResourceManager</see></param>
- /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
- /// <param name="Parameters">The additional parameters that shall be included into the log-message (must be compatible with the string in the resource):</param>
- internal static void LogMsg(ResourceManager resman, string ResourceString, LogLevel msglevel, params Object[] Parameters) {
- if (msglevel > level)
- return;
-
- if(Parameters.Length == 0){
- string message = resman.GetString(ResourceString);
- LogMsg(message, msglevel);
- }else{
- string message = String.Format(resman.GetString(ResourceString), Parameters);
- LogMsg(message, msglevel);
- }
- }
+ // The format of the logfile is
+ // [Date] [Time] [PID] [Level] [Message]
+ writer.WriteLine(System.DateTime.Now + "\t" + proc.Id + "\t" + msglevel + "\t" + message);
+ writer.Close();
+ }
+ }
+ }
- /// <summary>
- /// Writes the default log-message for the action of calling the Get-part of an Indexer to the log file.
- /// </summary>
- /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
- /// <param name="ClassName">The name of the class that contains the Indexer</param>
- /// <param name="IndexerParam">The parameter given to the Indexer</param>
- internal static void LogIndexerGet(LogLevel msglevel, string ClassName, object IndexerParam){
- if (msglevel > level)
- return;
- string message = String.Format(LogResMan.GetString("Indexer_Get"), ClassName, IndexerParam);
- LogMsg(message, msglevel);
- }
+ /// <summary>
+ /// Writes a string to the Npgsql event log if msglevel is bigger then <see cref="Npgsql.NpgsqlEventLog.Level">NpgsqlEventLog.Level</see>
+ /// </summary>
+ /// <param name="resman">The <see cref="System.Resources.ResourceManager">ResourceManager</see> to get the localized resources</param>
+ /// <param name="ResourceString">The name of the resource that should be fetched by the <see cref="System.Resources.ResourceManager">ResourceManager</see></param>
+ /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
+ /// <param name="Parameters">The additional parameters that shall be included into the log-message (must be compatible with the string in the resource):</param>
+ internal static void LogMsg(ResourceManager resman, string ResourceString, LogLevel msglevel, params Object[] Parameters)
+ {
+ if (msglevel > level)
+ return;
- /// <summary>
- /// Writes the default log-message for the action of calling the Set-part of an Indexer to the logfile.
- /// </summary>
- /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
- /// <param name="ClassName">The name of the class that contains the Indexer</param>
- /// <param name="IndexerParam">The parameter given to the Indexer</param>
- /// <param name="value">The value the Indexer is set to</param>
- internal static void LogIndexerSet(LogLevel msglevel, string ClassName, object IndexerParam, object value){
- if (msglevel > level)
- return;
- string message = String.Format(LogResMan.GetString("Indexer_Set"), ClassName, IndexerParam, value);
- LogMsg(message, msglevel);
- }
+ if(Parameters.Length == 0)
+ {
+ string message = resman.GetString(ResourceString);
+ LogMsg(message, msglevel);
+ }
+ else
+ {
+ string message = String.Format(resman.GetString(ResourceString), Parameters);
+ LogMsg(message, msglevel);
+ }
+ }
- /// <summary>
- /// Writes the default log-message for the action of calling the Get-part of a Property to the logfile.
- /// </summary>
- /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
- /// <param name="ClassName">The name of the class that contains the Property</param>
- /// <param name="PropertyName">The name of the Property</param>
- internal static void LogPropertyGet(LogLevel msglevel, string ClassName, string PropertyName){
- if (msglevel > level)
- return;
- string message = String.Format(LogResMan.GetString("Property_Get"), ClassName, PropertyName);
- LogMsg(message, msglevel);
- }
+ /// <summary>
+ /// Writes the default log-message for the action of calling the Get-part of an Indexer to the log file.
+ /// </summary>
+ /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
+ /// <param name="ClassName">The name of the class that contains the Indexer</param>
+ /// <param name="IndexerParam">The parameter given to the Indexer</param>
+ internal static void LogIndexerGet(LogLevel msglevel, string ClassName, object IndexerParam)
+ {
+ if (msglevel > level)
+ return;
+ string message = String.Format(LogResMan.GetString("Indexer_Get"), ClassName, IndexerParam);
+ LogMsg(message, msglevel);
+ }
+
+ /// <summary>
+ /// Writes the default log-message for the action of calling the Set-part of an Indexer to the logfile.
+ /// </summary>
+ /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
+ /// <param name="ClassName">The name of the class that contains the Indexer</param>
+ /// <param name="IndexerParam">The parameter given to the Indexer</param>
+ /// <param name="value">The value the Indexer is set to</param>
+ internal static void LogIndexerSet(LogLevel msglevel, string ClassName, object IndexerParam, object value)
+ {
+ if (msglevel > level)
+ return;
+ string message = String.Format(LogResMan.GetString("Indexer_Set"), ClassName, IndexerParam, value);
+ LogMsg(message, msglevel);
+ }
+
+ /// <summary>
+ /// Writes the default log-message for the action of calling the Get-part of a Property to the logfile.
+ /// </summary>
+ /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
+ /// <param name="ClassName">The name of the class that contains the Property</param>
+ /// <param name="PropertyName">The name of the Property</param>
+ internal static void LogPropertyGet(LogLevel msglevel, string ClassName, string PropertyName)
+ {
+ if (msglevel > level)
+ return;
+ string message = String.Format(LogResMan.GetString("Property_Get"), ClassName, PropertyName);
+ LogMsg(message, msglevel);
+ }
- /// <summary>
- /// Writes the default log-message for the action of calling the Set-part of a Property to the logfile.
- /// </summary>
- /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
- /// <param name="ClassName">The name of the class that contains the Property</param>
- /// <param name="PropertyName">The name of the Property</param>
- /// <param name="value">The value the Property is set to</param>
- internal static void LogPropertySet(LogLevel msglevel, string ClassName, string PropertyName, object value){
- if (msglevel > level)
- return;
- string message = String.Format(LogResMan.GetString("Property_Set"), ClassName, PropertyName, value);
- LogMsg(message, msglevel);
- }
+ /// <summary>
+ /// Writes the default log-message for the action of calling the Set-part of a Property to the logfile.
+ /// </summary>
+ /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
+ /// <param name="ClassName">The name of the class that contains the Property</param>
+ /// <param name="PropertyName">The name of the Property</param>
+ /// <param name="value">The value the Property is set to</param>
+ internal static void LogPropertySet(LogLevel msglevel, string ClassName, string PropertyName, object value)
+ {
+ if (msglevel > level)
+ return;
+ string message = String.Format(LogResMan.GetString("Property_Set"), ClassName, PropertyName, value);
+ LogMsg(message, msglevel);
+ }
- /// <summary>
- /// Writes the default log-message for the action of calling a Method without Arguments to the logfile.
- /// </summary>
- /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
- /// <param name="ClassName">The name of the class that contains the Method</param>
- /// <param name="MethodName">The name of the Method</param>
- internal static void LogMethodEnter(LogLevel msglevel, string ClassName, string MethodName){
- if (msglevel > level)
- return;
- string message = String.Format(LogResMan.GetString("Method_0P_Enter"), ClassName, MethodName);
- LogMsg(message, msglevel);
- }
+ /// <summary>
+ /// Writes the default log-message for the action of calling a Method without Arguments to the logfile.
+ /// </summary>
+ /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
+ /// <param name="ClassName">The name of the class that contains the Method</param>
+ /// <param name="MethodName">The name of the Method</param>
+ internal static void LogMethodEnter(LogLevel msglevel, string ClassName, string MethodName)
+ {
+ if (msglevel > level)
+ return;
+ string message = String.Format(LogResMan.GetString("Method_0P_Enter"), ClassName, MethodName);
+ LogMsg(message, msglevel);
+ }
- /// <summary>
- /// Writes the default log-message for the action of calling a Method with one Argument to the logfile.
- /// </summary>
- /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
- /// <param name="ClassName">The name of the class that contains the Method</param>
- /// <param name="MethodName">The name of the Method</param>
- /// <param name="MethodParameter">The value of the Argument of the Method</param>
- internal static void LogMethodEnter(LogLevel msglevel, string ClassName, string MethodName, object MethodParameter){
- if (msglevel > level)
- return;
- string message = String.Format(LogResMan.GetString("Method_1P_Enter"), ClassName, MethodName, MethodParameter);
- LogMsg(message, msglevel);
- }
+ /// <summary>
+ /// Writes the default log-message for the action of calling a Method with one Argument to the logfile.
+ /// </summary>
+ /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
+ /// <param name="ClassName">The name of the class that contains the Method</param>
+ /// <param name="MethodName">The name of the Method</param>
+ /// <param name="MethodParameter">The value of the Argument of the Method</param>
+ internal static void LogMethodEnter(LogLevel msglevel, string ClassName, string MethodName, object MethodParameter)
+ {
+ if (msglevel > level)
+ return;
+ string message = String.Format(LogResMan.GetString("Method_1P_Enter"), ClassName, MethodName, MethodParameter);
+ LogMsg(message, msglevel);
+ }
- /// <summary>
- /// Writes the default log-message for the action of calling a Method with two Arguments to the logfile.
- /// </summary>
- /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
- /// <param name="ClassName">The name of the class that contains the Method</param>
- /// <param name="MethodName">The name of the Method</param>
- /// <param name="MethodParameter1">The value of the first Argument of the Method</param>
- /// <param name="MethodParameter2">The value of the second Argument of the Method</param>
- internal static void LogMethodEnter(LogLevel msglevel, string ClassName, string MethodName, object MethodParameter1, object MethodParameter2){
- if (msglevel > level)
- return;
- string message = String.Format(LogResMan.GetString("Method_2P_Enter"), ClassName, MethodName, MethodParameter1, MethodParameter2);
- LogMsg(message, msglevel);
- }
+ /// <summary>
+ /// Writes the default log-message for the action of calling a Method with two Arguments to the logfile.
+ /// </summary>
+ /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
+ /// <param name="ClassName">The name of the class that contains the Method</param>
+ /// <param name="MethodName">The name of the Method</param>
+ /// <param name="MethodParameter1">The value of the first Argument of the Method</param>
+ /// <param name="MethodParameter2">The value of the second Argument of the Method</param>
+ internal static void LogMethodEnter(LogLevel msglevel, string ClassName, string MethodName, object MethodParameter1, object MethodParameter2)
+ {
+ if (msglevel > level)
+ return;
+ string message = String.Format(LogResMan.GetString("Method_2P_Enter"), ClassName, MethodName, MethodParameter1, MethodParameter2);
+ LogMsg(message, msglevel);
+ }
- /// <summary>
- /// Writes the default log-message for the action of calling a Method with three Arguments to the logfile.
- /// </summary>
- /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
- /// <param name="ClassName">The name of the class that contains the Method</param>
- /// <param name="MethodName">The name of the Method</param>
- /// <param name="MethodParameter1">The value of the first Argument of the Method</param>
- /// <param name="MethodParameter2">The value of the second Argument of the Method</param>
- /// <param name="MethodParameter3">The value of the third Argument of the Method</param>
- internal static void LogMethodEnter(LogLevel msglevel, string ClassName, string MethodName, object MethodParameter1, object MethodParameter2, object MethodParameter3){
- if (msglevel > level)
- return;
- string message = String.Format(LogResMan.GetString("Method_3P_Enter"), ClassName, MethodName, MethodParameter1, MethodParameter2, MethodParameter3);
- LogMsg(message, msglevel);
- }
+ /// <summary>
+ /// Writes the default log-message for the action of calling a Method with three Arguments to the logfile.
+ /// </summary>
+ /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
+ /// <param name="ClassName">The name of the class that contains the Method</param>
+ /// <param name="MethodName">The name of the Method</param>
+ /// <param name="MethodParameter1">The value of the first Argument of the Method</param>
+ /// <param name="MethodParameter2">The value of the second Argument of the Method</param>
+ /// <param name="MethodParameter3">The value of the third Argument of the Method</param>
+ internal static void LogMethodEnter(LogLevel msglevel, string ClassName, string MethodName, object MethodParameter1, object MethodParameter2, object MethodParameter3)
+ {
+ if (msglevel > level)
+ return;
+ string message = String.Format(LogResMan.GetString("Method_3P_Enter"), ClassName, MethodName, MethodParameter1, MethodParameter2, MethodParameter3);
+ LogMsg(message, msglevel);
+ }
- /// <summary>
- /// Writes the default log-message for the action of calling a Method with more than three Arguments to the logfile.
- /// </summary>
- /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
- /// <param name="ClassName">The name of the class that contains the Method</param>
- /// <param name="MethodName">The name of the Method</param>
- /// <param name="MethodParameters">A <see cref="System.Object">Object</see>-Array with zero or more Ojects that are Arguments of the Method.</param>
- internal static void LogMethodEnter(LogLevel msglevel, string ClassName, string MethodName, params object[] MethodParameters){
- if (msglevel > level)
- return;
- string message = String.Empty;
- switch (MethodParameters.Length){
- case 4:
- message = String.Format(LogResMan.GetString("Method_4P_Enter"), ClassName, MethodName,
- MethodParameters[0], MethodParameters[1], MethodParameters[2], MethodParameters[3]);
- break;
- case 5:
- message = String.Format(LogResMan.GetString("Method_5P_Enter"), ClassName, MethodName,
- MethodParameters[0], MethodParameters[1], MethodParameters[2], MethodParameters[3], MethodParameters[4]);
- break;
- case 6:
- message = String.Format(LogResMan.GetString("Method_6P_Enter"), ClassName, MethodName,
- MethodParameters[0], MethodParameters[1], MethodParameters[2], MethodParameters[3], MethodParameters[4], MethodParameters[5]);
- break;
- default:
- // should always be true - but who knows ;-)
- if (MethodParameters.Length > 6)
- message = String.Format(LogResMan.GetString("Method_6P+_Enter"), ClassName, MethodName, MethodParameters[0], MethodParameters[1]);
- break;
- }
+ /// <summary>
+ /// Writes the default log-message for the action of calling a Method with more than three Arguments to the logfile.
+ /// </summary>
+ /// <param name="msglevel">The minimum <see cref="Npgsql.LogLevel">LogLevel</see> for which this message should be logged.</param>
+ /// <param name="ClassName">The name of the class that contains the Method</param>
+ /// <param name="MethodName">The name of the Method</param>
+ /// <param name="MethodParameters">A <see cref="System.Object">Object</see>-Array with zero or more Ojects that are Arguments of the Method.</param>
+ internal static void LogMethodEnter(LogLevel msglevel, string ClassName, string MethodName, params object[] MethodParameters)
+ {
+ if (msglevel > level)
+ return;
+ string message = String.Empty;
+ switch (MethodParameters.Length)
+ {
+ case 4:
+ message = String.Format(LogResMan.GetString("Method_4P_Enter"), ClassName, MethodName,
+ MethodParameters[0], MethodParameters[1], MethodParameters[2], MethodParameters[3]);
+ break;
+ case 5:
+ message = String.Format(LogResMan.GetString("Method_5P_Enter"), ClassName, MethodName,
+ MethodParameters[0], MethodParameters[1], MethodParameters[2], MethodParameters[3], MethodParameters[4]);
+ break;
+ case 6:
+ message = String.Format(LogResMan.GetString("Method_6P_Enter"), ClassName, MethodName,
+ MethodParameters[0], MethodParameters[1], MethodParameters[2], MethodParameters[3], MethodParameters[4], MethodParameters[5]);
+ break;
+ default:
+ // should always be true - but who knows ;-)
+ if (MethodParameters.Length > 6)
+ message = String.Format(LogResMan.GetString("Method_6P+_Enter"), ClassName, MethodName, MethodParameters[0], MethodParameters[1]);
+ break;
+ }
LogMsg(message, msglevel);
- }
+ }
- }
+ }
}
// created on 12/5/2002 at 23:10
// Npgsql.NpgsqlException.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
- public class NpgsqlException : Exception
- {
-
+ [Serializable]
+ public class NpgsqlException : Exception
+ {
+
// Logging related values
private static readonly String CLASSNAME = "NpgsqlException";
private static ResourceManager resman = new ResourceManager(typeof(NpgsqlException));
-
- public NpgsqlException()
- {
+
+ public NpgsqlException()
+ {
NpgsqlEventLog.LogMsg(resman, "Log_ExceptionOccured", LogLevel.Normal, "<no message>");
-
- }
-
- public NpgsqlException(String message) : base(message)
- {
- NpgsqlEventLog.LogMsg(resman, "Log_ExceptionOccured", LogLevel.Normal, message);
- }
-
- public NpgsqlException(String message, Exception inner)
- : base(message, inner)
- {
+
+ }
+
+ public NpgsqlException(String message) : base(message)
+ {
+ NpgsqlEventLog.LogMsg(resman, "Log_ExceptionOccured", LogLevel.Normal, message);
+ }
+
+ public NpgsqlException(String message, Exception inner)
+ : base(message, inner)
+ {
NpgsqlEventLog.LogMsg(resman, "Log_ExceptionOccured", LogLevel.Normal, message + " (" + inner.Message + ")");
- }
- }
+ }
+ }
}
// created on 1/7/2003 at 20:03
// Npgsql.NpgsqlExecute.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- /// <summary>
- /// This class represents the Parse message sent to PostgreSQL
- /// server.
- /// </summary>
- ///
- internal sealed class NpgsqlExecute
- {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlExecute";
-
- private String _portalName;
- private Int32 _maxRows;
-
-
- public NpgsqlExecute(String portalName, Int32 maxRows)
- {
- _portalName = portalName;
- _maxRows = maxRows;
- }
-
- public String PortalName
- {
- get
- {
- return _portalName;
- }
- }
-
- public void WriteToStream(Stream outputStream, Encoding encoding)
- {
- outputStream.WriteByte((Byte)'E');
-
- PGUtil.WriteInt32(outputStream, 4 +
- encoding.GetByteCount(_portalName) + 1 +
- 4);
-
- PGUtil.WriteString(_portalName, outputStream, encoding);
- PGUtil.WriteInt32(outputStream, _maxRows);
-
- }
-
- }
+
+ /// <summary>
+ /// This class represents the Parse message sent to PostgreSQL
+ /// server.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlExecute
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlExecute";
+
+ private String _portalName;
+ private Int32 _maxRows;
+
+
+ public NpgsqlExecute(String portalName, Int32 maxRows)
+ {
+ _portalName = portalName;
+ _maxRows = maxRows;
+ }
+
+ public String PortalName
+ {
+ get
+ {
+ return _portalName;
+ }
+ }
+
+ public void WriteToStream(Stream outputStream, Encoding encoding)
+ {
+ outputStream.WriteByte((Byte)'E');
+
+ PGUtil.WriteInt32(outputStream, 4 +
+ encoding.GetByteCount(_portalName) + 1 +
+ 4);
+
+ PGUtil.WriteString(_portalName, outputStream, encoding);
+ PGUtil.WriteInt32(outputStream, _maxRows);
+
+ }
+
+ }
}
-
+
// created on 28/6/2003 at 23:28
// Npgsql.NpgsqlFlush.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- /// <summary>
- /// This class represents the Parse message sent to PostgreSQL
- /// server.
- /// </summary>
- ///
- internal sealed class NpgsqlFlush
- {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlFlush";
-
- public void WriteToStream(Stream outputStream, Encoding encoding)
- {
- outputStream.WriteByte((Byte)'H');
-
- PGUtil.WriteInt32(outputStream, 4);
-
- }
-
- }
+
+ /// <summary>
+ /// This class represents the Parse message sent to PostgreSQL
+ /// server.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlFlush
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlFlush";
+
+ public void WriteToStream(Stream outputStream, Encoding encoding)
+ {
+ outputStream.WriteByte((Byte)'H');
+
+ PGUtil.WriteInt32(outputStream, 4);
+
+ }
+
+ }
}
-
+
// created on 30/7/2002 at 00:31
// Npgsql.NpgsqlMediator.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
- ///<summary>
- /// This class is responsible for serving as bridge between the backend
- /// protocol handling and the core classes. It is used as the mediator for
- /// exchanging data generated/sent from/to backend.
- /// </summary>
- ///
-
- internal sealed class NpgsqlMediator
- {
- private ArrayList _errorMessages;
- private ArrayList _resultSets;
- private ArrayList _responses;
- private ArrayList _notifications;
-
- private NpgsqlRowDescription _rd;
- private ArrayList _rows;
-
-
- public NpgsqlMediator()
- {
- _errorMessages = new ArrayList();
- _resultSets = new ArrayList();
- _responses = new ArrayList();
- _notifications = new ArrayList();
- }
-
- public void Reset()
- {
- _errorMessages.Clear();
- _resultSets.Clear();
- _responses.Clear();
- _notifications.Clear();
- _rd = null;
- }
-
- public ArrayList Errors
- {
- get
- {
- return _errorMessages;
- }
- }
-
- public ArrayList Notifications
- {
- get
- {
- return _notifications;
- }
-
- }
-
- public void AddNotification(NpgsqlNotificationEventArgs data)
- {
- _notifications.Add(data);
- }
-
-
-
- public void AddCompletedResponse(String response)
- {
- if (_rd != null)
- {
- // Finished receiving the resultset. Add it to the buffer.
- _resultSets.Add(new NpgsqlResultSet(_rd, _rows));
-
- // Add a placeholder response.
- _responses.Add(null);
-
- // Discard the RowDescription.
- _rd = null;
- }
- else
- {
- // Add a placeholder resultset.
- _resultSets.Add(null);
- // It was just a non query string. Just add the response.
- _responses.Add(response);
- }
-
- }
-
- public void AddRowDescription(NpgsqlRowDescription rowDescription)
- {
- _rd = rowDescription;
- _rows = new ArrayList();
- }
-
- public void AddAsciiRow(NpgsqlAsciiRow asciiRow)
- {
- _rows.Add(asciiRow);
- }
-
- public void AddBinaryRow(NpgsqlBinaryRow asciiRow)
- {
- _rows.Add(asciiRow);
- }
-
-
- public void AddBackendKeydata(NpgsqlBackEndKeyData keydata)
- {
- _responses.Add(keydata); //hack
- }
-
- public ArrayList GetResultSets()
- {
- return _resultSets;
- }
-
- public ArrayList GetCompletedResponses()
- {
- return _responses;
- }
-
- public NpgsqlBackEndKeyData GetBackEndKeyData()
- {
- return (NpgsqlBackEndKeyData)_responses[0]; //hack
- }
-
-
- }
+ ///<summary>
+ /// This class is responsible for serving as bridge between the backend
+ /// protocol handling and the core classes. It is used as the mediator for
+ /// exchanging data generated/sent from/to backend.
+ /// </summary>
+ ///
+
+ internal sealed class NpgsqlMediator
+ {
+ private ArrayList _errorMessages;
+ private ArrayList _resultSets;
+ private ArrayList _responses;
+ private ArrayList _notifications;
+
+ private NpgsqlRowDescription _rd;
+ private ArrayList _rows;
+
+
+ public NpgsqlMediator()
+ {
+ _errorMessages = new ArrayList();
+ _resultSets = new ArrayList();
+ _responses = new ArrayList();
+ _notifications = new ArrayList();
+ }
+
+ public void Reset()
+ {
+ _errorMessages.Clear();
+ _resultSets.Clear();
+ _responses.Clear();
+ _notifications.Clear();
+ _rd = null;
+ }
+
+ public ArrayList Errors
+ {
+ get
+ {
+ return _errorMessages;
+ }
+ }
+
+ public ArrayList Notifications
+ {
+ get
+ {
+ return _notifications;
+ }
+
+ }
+
+ public void AddNotification(NpgsqlNotificationEventArgs data)
+ {
+ _notifications.Add(data);
+ }
+
+
+
+ public void AddCompletedResponse(String response)
+ {
+ if (_rd != null)
+ {
+ // Finished receiving the resultset. Add it to the buffer.
+ _resultSets.Add(new NpgsqlResultSet(_rd, _rows));
+
+ // Add a placeholder response.
+ _responses.Add(null);
+
+ // Discard the RowDescription.
+ _rd = null;
+ }
+ else
+ {
+ // Add a placeholder resultset.
+ _resultSets.Add(null);
+ // It was just a non query string. Just add the response.
+ _responses.Add(response);
+ }
+
+ }
+
+ public void AddRowDescription(NpgsqlRowDescription rowDescription)
+ {
+ _rd = rowDescription;
+ _rows = new ArrayList();
+ }
+
+ public void AddAsciiRow(NpgsqlAsciiRow asciiRow)
+ {
+ _rows.Add(asciiRow);
+ }
+
+ public void AddBinaryRow(NpgsqlBinaryRow asciiRow)
+ {
+ _rows.Add(asciiRow);
+ }
+
+
+ public void AddBackendKeydata(NpgsqlBackEndKeyData keydata)
+ {
+ _responses.Add(keydata); //hack
+ }
+
+ public ArrayList GetResultSets()
+ {
+ return _resultSets;
+ }
+
+ public ArrayList GetCompletedResponses()
+ {
+ return _responses;
+ }
+
+ public NpgsqlBackEndKeyData GetBackEndKeyData()
+ {
+ return (NpgsqlBackEndKeyData)_responses[0]; //hack
+ }
+
+
+ }
}
// Npgsql.NpgsqlMessageTypes.cs
-//
+//
// Author:
// Dave Joyner <d4ljoyn@yahoo.com>
//
// 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
namespace Npgsql
{
- /// <summary>
- /// Summary description for NpgsqlMessageTypes.
- /// </summary>
- internal sealed class NpgsqlMessageTypes
- {
- private NpgsqlMessageTypes()
- {
- //
- // TODO: Add constructor logic here
- //
- }
- public const Char AsciiRow = 'D';
- public const Char AuthenticationRequest = 'R';
+ /// <summary>
+ /// Summary description for NpgsqlMessageTypes.
+ /// </summary>
+ internal sealed class NpgsqlMessageTypes
+ {
+ private NpgsqlMessageTypes()
+ {
+ //
+ // TODO: Add constructor logic here
+ //
+ }
+ public const Char AsciiRow = 'D';
+ public const Char AuthenticationRequest = 'R';
+
+ // specific Authentication request types
+ public const Int32 AuthenticationOk = 0;
+ public const Int32 AuthenticationKerberosV4 = 1;
+ public const Int32 AuthenticationKerberosV5 = 2;
+ public const Int32 AuthenticationClearTextPassword = 3;
+ public const Int32 AuthenticationCryptPassword = 4;
+ public const Int32 AuthenticationMD5Password = 5;
+ public const Int32 AuthenticationSCMCredential = 6;
+
+ public const Char BackendKeyData = 'K';
+ public const Char BinaryRow = 'B';
+ public const Char BindComplete = '2';
+ public const Char CancelRequest = 'F';
+ public const Char CompletedResponse = 'C';
+ public const Char CopyDataRows = ' ';
+ public const Char CopyInResponse = 'G';
+ public const Char CopyOutResponse = 'H';
+ public const Char CursorResponse = 'P';
+ public const Char EmptyQueryResponse = 'I';
+ public const Char ErrorResponse = 'E';
+ public const Char FunctionCall = 'F';
- // specific Authentication request types
- public const Int32 AuthenticationOk = 0;
- public const Int32 AuthenticationKerberosV4 = 1;
- public const Int32 AuthenticationKerberosV5 = 2;
- public const Int32 AuthenticationClearTextPassword = 3;
- public const Int32 AuthenticationCryptPassword = 4;
- public const Int32 AuthenticationMD5Password = 5;
- public const Int32 AuthenticationSCMCredential = 6;
+ public const Char FunctionResultResponse = 'V';
+ // specific function result responses
+ public const Char FunctionResultNonEmptyResponse = 'G';
+ public const Char FunctionResultVoidResponse = '0';
- public const Char BackendKeyData = 'K';
- public const Char BinaryRow = 'B';
- public const Char BindComplete = '2';
- public const Char CancelRequest = 'F';
- public const Char CompletedResponse = 'C';
- public const Char CopyDataRows = ' ';
- public const Char CopyInResponse = 'G';
- public const Char CopyOutResponse = 'H';
- public const Char CursorResponse = 'P';
- public const Char EmptyQueryResponse = 'I';
- public const Char ErrorResponse = 'E';
- public const Char FunctionCall = 'F';
-
- public const Char FunctionResultResponse = 'V';
- // specific function result responses
- public const Char FunctionResultNonEmptyResponse = 'G';
- public const Char FunctionResultVoidResponse = '0';
-
- public const Char NoticeResponse = 'N';
- public const Char NotificationResponse = 'A';
- public const Char ParameterStatus = 'S';
- public const Char ParseComplete = '1';
- public const Char PasswordPacket = ' ';
- public const Char Query = 'Q';
- public const Char ReadyForQuery = 'Z';
- public const Char RowDescription = 'T';
- public const Char SSLRequest = ' ';
- public const Char StartupPacket = ' ';
+ public const Char NoticeResponse = 'N';
+ public const Char NotificationResponse = 'A';
+ public const Char ParameterStatus = 'S';
+ public const Char ParseComplete = '1';
+ public const Char PasswordPacket = ' ';
+ public const Char Query = 'Q';
+ public const Char ReadyForQuery = 'Z';
+ public const Char RowDescription = 'T';
+ public const Char SSLRequest = ' ';
+ public const Char StartupPacket = ' ';
- }
+ }
}
// Npgsql.NpgsqlNotificationEventArgs.cs
-//
+//
// Author:
// Wojtek Wierzbicki
//
// 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 Npgsql
- {
- /// <summary>
- /// EventArgs class to send Notification parameters.
- /// </summary>
- public class NpgsqlNotificationEventArgs : EventArgs
- {
- public Int32 PID = 0;
- public String Condition = null;
-
- public NpgsqlNotificationEventArgs(Int32 nPID, String nCondition)
- {
- PID = nPID;
- Condition = nCondition;
- }
- }
- }
+using System;
+
+namespace Npgsql
+{
+ /// <summary>
+ /// EventArgs class to send Notification parameters.
+ /// </summary>
+ public class NpgsqlNotificationEventArgs : EventArgs
+ {
+ public Int32 PID = 0;
+ public String Condition = null;
+
+ public NpgsqlNotificationEventArgs(Int32 nPID, String nCondition)
+ {
+ PID = nPID;
+ Condition = nCondition;
+ }
+ }
+}
// created on 18/5/2002 at 01:25
// Npgsql.NpgsqlParameter.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
- ///<summary>
- /// This class represents a parameter to a command that will be sent to server
- ///</summary>
- [TypeConverter(typeof(NpgsqlParameterConverter))]
- public sealed class NpgsqlParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
- {
-
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlParameter";
-
- // Fields to implement IDbDataParameter interface.
- private byte precision = 0;
- private byte scale = 0;
- private Int32 size = 0;
-
- // Fields to implement IDataParameter
- private DbType db_type = DbType.String;
- private ParameterDirection direction = ParameterDirection.Input;
- private Boolean is_nullable = false;
- private String name;
- private String source_column = String.Empty;
- private DataRowVersion source_version = DataRowVersion.Current;
- private Object value;
- private System.Resources.ResourceManager resman;
-
-
-
-
-
- #region Constructors
-
- /// <summary>
-
- /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> class.
- /// </summary>
- public NpgsqlParameter(){
- resman = new System.Resources.ResourceManager(this.GetType());
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
- /// class with the parameter name and a value of the new <b>NpgsqlParameter</b>.
- /// </summary>
- /// <param name="parameterName">The name of the parameter to map.</param>
- /// <param name="value">An <see cref="System.Object">Object</see> that is the value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
- /// <remarks>
- /// <p>When you specify an <see cref="System.Object">Object</see>
- /// in the value parameter, the <see cref="System.Data.DbType">DbType</see> is
- /// inferred from the .NET Framework type of the <b>Object</b>.</p>
- /// <p>Use caution when using this overload of the
- /// <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> constructor
- /// to specify integer parameter values. Because this overload takes a <i>value</i>
- /// of type <b>Object</b>, you must convert the integral value to an <b>Object</b> type when
- /// the value is zero, as the following C# example demonstrates.
- /// <code>Parameter = new SqlParameter("@pname", Convert.ToInt32(0));</code>
- /// If you do not perform this conversion, the compiler will assume you are
- /// attempting to call the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> (string, SqlDbType) constructor overload.</p>
- /// </remarks>
- public NpgsqlParameter(String parameterName, object value) {
- resman = new System.Resources.ResourceManager(this.GetType());
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, parameterName, value);
- // Set db_type according to:
- // http://msdn.microsoft.com/library/en-us/cpguide/html/cpconusingparameterswithdataadapters.asp
- // Should this be in this.Value.set{}?
- //I don't really know so I leave it here where it will not hurt.
- if (value == null) {
- // don't really know what to do - leave default and do further exploration
- return;
- }
- Type type = value.GetType();
- if (type == typeof(bool)) {
- db_type = DbType.Boolean;
- }
- else if (type == typeof(byte)) {
- db_type = DbType.Byte;
- }
- else if (type == typeof(byte[])) {
- db_type = DbType.Binary;
- }
- else if (type == typeof(char)) {
- // There is no DbType.Char
- db_type = DbType.String;
- }
- else if (type == typeof(DateTime)) {
- db_type = DbType.DateTime;
- }
- else if (type == typeof(decimal)) {
- db_type = DbType.Decimal;
- }
- else if (type == typeof(double)) {
- db_type = DbType.Double;
- }
- else if (type == typeof(float)) {
- db_type = DbType.Single;
- }
- else if (type == typeof(Guid)) {
- db_type = DbType.Guid;
- }
- else if (type == typeof(Int16)) {
- db_type = DbType.Int16;
- }
- else if (type == typeof(Int32)) {
- db_type = DbType.Int32;
- }
- else if (type == typeof(Int64)) {
- db_type = DbType.Int64;
- }
- else if (type == typeof(string)) {
- db_type = DbType.String;
- }
- else if (type == typeof(TimeSpan)) {
- db_type = DbType.Time;
- }
- else if (type == typeof(UInt16)) {
- db_type = DbType.UInt16;
- }
- else if (type == typeof(UInt32)) {
- db_type = DbType.UInt32;
- }
- else if (type == typeof(UInt64)) {
- db_type = DbType.UInt64;
- }
- else if (type == typeof(object)) {
- db_type = DbType.Object;
- } else{
- throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), type.ToString()));
- }
-
- this.value = value;
-
- this.ParameterName = parameterName;
-
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
- /// class with the parameter name and the data type.
- /// </summary>
- /// <param name="parameterName">The name of the parameter to map.</param>
- /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
- public NpgsqlParameter(String parameterName, DbType parameterType) : this(parameterName, parameterType, 0, String.Empty){}
-
- /// <summary>
- /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
- /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, and the size.
- /// </summary>
- /// <param name="parameterName">The name of the parameter to map.</param>
- /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
- /// <param name="size">The length of the parameter.</param>
- public NpgsqlParameter(String parameterName, DbType parameterType, Int32 size) : this(parameterName, parameterType, size, String.Empty){}
-
- /// <summary>
- /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
- /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, the size,
- /// and the source column name.
- /// </summary>
- /// <param name="parameterName">The name of the parameter to map.</param>
- /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
- /// <param name="size">The length of the parameter.</param>
- /// <param name="sourceColumn">The name of the source column.</param>
- public NpgsqlParameter(String parameterName, DbType parameterType, Int32 size, String sourceColumn) {
-
- resman = new System.Resources.ResourceManager(this.GetType());
-
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, parameterName, parameterType, size, source_column);
-
- this.ParameterName = parameterName;
- db_type = parameterType;
- this.size = size;
- source_column = sourceColumn;
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
- /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, the size,
- /// the source column name, a <see cref="System.Data.ParameterDirection">ParameterDirection</see>,
- /// the precision of the parameter, the scale of the parameter, a
- /// <see cref="System.Data.DataRowVersion">DataRowVersion</see> to use, and the
- /// value of the parameter.
- /// </summary>
- /// <param name="parameterName">The name of the parameter to map.</param>
- /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
- /// <param name="size">The length of the parameter.</param>
- /// <param name="sourceColumn">The name of the source column.</param>
- /// <param name="direction">One of the <see cref="System.Data.ParameterDirection">ParameterDirection</see> values.</param>
- /// <param name="isNullable"><b>true</b> if the value of the field can be null, otherwise <b>false</b>.</param>
- /// <param name="precision">The total number of digits to the left and right of the decimal point to which
- /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.</param>
- /// <param name="scale">The total number of decimal places to which
- /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.</param>
- /// <param name="sourceVersion">One of the <see cref="System.Data.DataRowVersion">DataRowVersion</see> values.</param>
- /// <param name="value">An <see cref="System.Object">Object</see> that is the value
- /// of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
- public NpgsqlParameter (String parameterName, DbType parameterType, Int32 size, String sourceColumn, ParameterDirection direction, bool isNullable, byte precision, byte scale, DataRowVersion sourceVersion, object value) {
-
- resman = new System.Resources.ResourceManager(this.GetType());
-
-
- this.ParameterName = parameterName;
- this.DbType = parameterType;
- this.Size = size;
- this.SourceColumn = sourceColumn;
- this.Direction = direction;
- this.IsNullable = isNullable;
- this.Precision = precision;
- this.Scale = scale;
- this.SourceVersion = sourceVersion;
- this.Value = value;
- }
-
- #endregion
-
- // Implementation of IDbDataParameter
- /// <summary>
- /// Gets or sets the maximum number of digits used to represent the
- /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> property.
- /// </summary>
- /// <value>The maximum number of digits used to represent the
- /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> property.
- /// The default value is 0, which indicates that the data provider
- /// sets the precision for <b>Value</b>.</value>
- [Category("Data"), DefaultValue((Byte)0)]
- public Byte Precision
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Precision");
- return precision;
- }
-
- set
- {
- NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Precision", value);
- precision = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the number of decimal places to which
- /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.
- /// </summary>
- /// <value>The number of decimal places to which
- /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved. The default is 0.</value>
- [Category("Data"), DefaultValue((Byte)0)]
- public Byte Scale
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Scale");
- return scale;
- }
-
- set
- {
- NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Scale", value);
- scale = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the maximum size, in bytes, of the data within the column.
- /// </summary>
- /// <value>The maximum size, in bytes, of the data within the column.
- /// The default value is inferred from the parameter value.</value>
- [Category("Data"), DefaultValue(0)]
- public Int32 Size
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Size");
- return size;
- }
-
- set
- {
- NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Size", value);
- size = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the <see cref="System.Data.DbType">DbType</see> of the parameter.
- /// </summary>
- /// <value>One of the <see cref="System.Data.DbType">DbType</see> values. The default is <b>String</b>.</value>
- [Category("Data"), RefreshProperties(RefreshProperties.All), DefaultValue(DbType.String)]
- public DbType DbType
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "DbType");
- return db_type;
- }
-
- // [TODO] Validate data type.
- set
- {
- NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "DbType", value);
- db_type = value;
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether the parameter is input-only,
- /// output-only, bidirectional, or a stored procedure return value parameter.
- /// </summary>
- /// <value>One of the <see cref="System.Data.ParameterDirection">ParameterDirection</see>
- /// values. The default is <b>Input</b>.</value>
- [Category("Data"), DefaultValue(ParameterDirection.Input)]
- public ParameterDirection Direction
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "Direction");
- return direction;
- }
-
- set
- {
- NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Direction", value);
- direction = value;
- }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether the parameter accepts null values.
- /// </summary>
- /// <value><b>true</b> if null values are accepted; otherwise, <b>false</b>. The default is <b>false</b>.</value>
- [EditorBrowsable(EditorBrowsableState.Advanced), Browsable(false), DefaultValue(false), DesignOnly(true)]
- public Boolean IsNullable
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsNullable");
- return is_nullable;
- }
-
- set
- {
- NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "IsNullable", value);
- is_nullable = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.
- /// </summary>
- /// <value>The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.
- /// The default is an empty string.</value>
- [DefaultValue("")]
- public String ParameterName
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "ParameterName");
- return name;
- }
-
- set
- {
- name = value;
- if ( (name.Equals(String.Empty)) || (name[0] != ':') )
- name = ':' + name;
- NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "ParameterName", value);
- }
- }
-
- /// <summary>
- /// Gets or sets the name of the source column that is mapped to the
- /// <see cref="System.Data.DataSet">DataSet</see> and used for loading or
- /// returning the <see cref="Npgsql.NpgsqlParameter.Value">Value</see>.
- /// </summary>
- /// <value>The name of the source column that is mapped to the
- /// <see cref="System.Data.DataSet">DataSet</see>. The default is an empty string.</value>
- [Category("Data"), DefaultValue("")]
- public String SourceColumn
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "SourceColumn");
- return source_column;
- }
-
- set
- {
- NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "SourceColumn", value);
- source_column = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the <see cref="System.Data.DataRowVersion">DataRowVersion</see>
- /// to use when loading <see cref="Npgsql.NpgsqlParameter.Value">Value</see>.
- /// </summary>
- /// <value>One of the <see cref="System.Data.DataRowVersion">DataRowVersion</see> values.
- /// The default is <b>Current</b>.</value>
- [Category("Data"), DefaultValue(DataRowVersion.Current)]
- public DataRowVersion SourceVersion
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "SourceVersion");
- return source_version;
- }
-
- set
- {
- NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "SourceVersion", value);
- source_version = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the value of the parameter.
- /// </summary>
- /// <value>An <see cref="System.Object">Object</see> that is the value of the parameter.
- /// The default value is null.</value>
- [TypeConverter(typeof(StringConverter)), Category("Data")]
- public Object Value
- {
- get
- {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "Value");
- return value;
- }
-
- // [TODO] Check and validate data type.
- set
- {
- NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Value", value);
- this.value = value;
- }
- }
-
- /// <summary>
- /// Creates a new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> that
- /// is a copy of the current instance.
- /// </summary>
- /// <returns>A new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> that is a copy of this instance.</returns>
- object System.ICloneable.Clone() {
- return new NpgsqlParameter(this.ParameterName, this.DbType, this.Size, this.SourceColumn, this.Direction, this.IsNullable, this.Precision, this.Scale, this.SourceVersion, this.Value);
- }
-
-
- }
+ ///<summary>
+ /// This class represents a parameter to a command that will be sent to server
+ ///</summary>
+ [TypeConverter(typeof(NpgsqlParameterConverter))]
+ public sealed class NpgsqlParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
+ {
+
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlParameter";
+
+ // Fields to implement IDbDataParameter interface.
+ private byte precision = 0;
+ private byte scale = 0;
+ private Int32 size = 0;
+
+ // Fields to implement IDataParameter
+ private DbType db_type = DbType.String;
+ private ParameterDirection direction = ParameterDirection.Input;
+ private Boolean is_nullable = false;
+ private String name;
+ private String source_column = String.Empty;
+ private DataRowVersion source_version = DataRowVersion.Current;
+ private Object value;
+ private System.Resources.ResourceManager resman;
+
+
+
+
+
+#region Constructors
+
+ /// <summary>
+
+ /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> class.
+ /// </summary>
+ public NpgsqlParameter()
+ {
+ resman = new System.Resources.ResourceManager(this.GetType());
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
+ /// class with the parameter name and a value of the new <b>NpgsqlParameter</b>.
+ /// </summary>
+ /// <param name="parameterName">The name of the parameter to map.</param>
+ /// <param name="value">An <see cref="System.Object">Object</see> that is the value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
+ /// <remarks>
+ /// <p>When you specify an <see cref="System.Object">Object</see>
+ /// in the value parameter, the <see cref="System.Data.DbType">DbType</see> is
+ /// inferred from the .NET Framework type of the <b>Object</b>.</p>
+ /// <p>Use caution when using this overload of the
+ /// <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> constructor
+ /// to specify integer parameter values. Because this overload takes a <i>value</i>
+ /// of type <b>Object</b>, you must convert the integral value to an <b>Object</b> type when
+ /// the value is zero, as the following C# example demonstrates.
+ /// <code>Parameter = new SqlParameter("@pname", Convert.ToInt32(0));</code>
+ /// If you do not perform this conversion, the compiler will assume you are
+ /// attempting to call the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> (string, SqlDbType) constructor overload.</p>
+ /// </remarks>
+ public NpgsqlParameter(String parameterName, object value)
+ {
+ resman = new System.Resources.ResourceManager(this.GetType());
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, parameterName, value);
+
+
+ this.value = value;
+
+ this.ParameterName = parameterName;
+
+
+ // Set db_type according to:
+ // http://msdn.microsoft.com/library/en-us/cpguide/html/cpconusingparameterswithdataadapters.asp
+ // Should this be in this.Value.set{}?
+ //I don't really know so I leave it here where it will not hurt.
+ if ((value == null) || (value == DBNull.Value) )
+ {
+ // don't really know what to do - leave default and do further exploration
+ return;
+ }
+ Type type = value.GetType();
+ if (type == typeof(bool))
+ {
+ db_type = DbType.Boolean;
+ }
+ else if (type == typeof(byte))
+ {
+ db_type = DbType.Byte;
+ }
+ else if (type == typeof(byte[]))
+ {
+ db_type = DbType.Binary;
+ }
+ else if (type == typeof(char))
+ {
+ // There is no DbType.Char
+ db_type = DbType.String;
+ }
+ else if (type == typeof(DateTime))
+ {
+ db_type = DbType.DateTime;
+ }
+ else if (type == typeof(decimal))
+ {
+ db_type = DbType.Decimal;
+ }
+ else if (type == typeof(double))
+ {
+ db_type = DbType.Double;
+ }
+ else if (type == typeof(float))
+ {
+ db_type = DbType.Single;
+ }
+ else if (type == typeof(Guid))
+ {
+ db_type = DbType.Guid;
+ }
+ else if (type == typeof(Int16))
+ {
+ db_type = DbType.Int16;
+ }
+ else if (type == typeof(Int32))
+ {
+ db_type = DbType.Int32;
+ }
+ else if (type == typeof(Int64))
+ {
+ db_type = DbType.Int64;
+ }
+ else if (type == typeof(string))
+ {
+ db_type = DbType.String;
+ }
+ else if (type == typeof(TimeSpan))
+ {
+ db_type = DbType.Time;
+ }
+ else if (type == typeof(UInt16))
+ {
+ db_type = DbType.UInt16;
+ }
+ else if (type == typeof(UInt32))
+ {
+ db_type = DbType.UInt32;
+ }
+ else if (type == typeof(UInt64))
+ {
+ db_type = DbType.UInt64;
+ }
+ else if (type == typeof(object))
+ {
+ db_type = DbType.Object;
+ }
+ else
+ {
+ throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), type.ToString()));
+ }
+
+
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
+ /// class with the parameter name and the data type.
+ /// </summary>
+ /// <param name="parameterName">The name of the parameter to map.</param>
+ /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
+ public NpgsqlParameter(String parameterName, DbType parameterType) : this(parameterName, parameterType, 0, String.Empty)
+ {}
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
+ /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, and the size.
+ /// </summary>
+ /// <param name="parameterName">The name of the parameter to map.</param>
+ /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
+ /// <param name="size">The length of the parameter.</param>
+ public NpgsqlParameter(String parameterName, DbType parameterType, Int32 size) : this(parameterName, parameterType, size, String.Empty)
+ {}
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
+ /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, the size,
+ /// and the source column name.
+ /// </summary>
+ /// <param name="parameterName">The name of the parameter to map.</param>
+ /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
+ /// <param name="size">The length of the parameter.</param>
+ /// <param name="sourceColumn">The name of the source column.</param>
+ public NpgsqlParameter(String parameterName, DbType parameterType, Int32 size, String sourceColumn)
+ {
+
+ resman = new System.Resources.ResourceManager(this.GetType());
+
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, parameterName, parameterType, size, source_column);
+
+ this.ParameterName = parameterName;
+ db_type = parameterType;
+ this.size = size;
+ source_column = sourceColumn;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
+ /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, the size,
+ /// the source column name, a <see cref="System.Data.ParameterDirection">ParameterDirection</see>,
+ /// the precision of the parameter, the scale of the parameter, a
+ /// <see cref="System.Data.DataRowVersion">DataRowVersion</see> to use, and the
+ /// value of the parameter.
+ /// </summary>
+ /// <param name="parameterName">The name of the parameter to map.</param>
+ /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
+ /// <param name="size">The length of the parameter.</param>
+ /// <param name="sourceColumn">The name of the source column.</param>
+ /// <param name="direction">One of the <see cref="System.Data.ParameterDirection">ParameterDirection</see> values.</param>
+ /// <param name="isNullable"><b>true</b> if the value of the field can be null, otherwise <b>false</b>.</param>
+ /// <param name="precision">The total number of digits to the left and right of the decimal point to which
+ /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.</param>
+ /// <param name="scale">The total number of decimal places to which
+ /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.</param>
+ /// <param name="sourceVersion">One of the <see cref="System.Data.DataRowVersion">DataRowVersion</see> values.</param>
+ /// <param name="value">An <see cref="System.Object">Object</see> that is the value
+ /// of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
+ public NpgsqlParameter (String parameterName, DbType parameterType, Int32 size, String sourceColumn, ParameterDirection direction, bool isNullable, byte precision, byte scale, DataRowVersion sourceVersion, object value)
+ {
+
+ resman = new System.Resources.ResourceManager(this.GetType());
+
+
+ this.ParameterName = parameterName;
+ this.DbType = parameterType;
+ this.Size = size;
+ this.SourceColumn = sourceColumn;
+ this.Direction = direction;
+ this.IsNullable = isNullable;
+ this.Precision = precision;
+ this.Scale = scale;
+ this.SourceVersion = sourceVersion;
+ this.Value = value;
+ }
+
+#endregion
+
+ // Implementation of IDbDataParameter
+ /// <summary>
+ /// Gets or sets the maximum number of digits used to represent the
+ /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> property.
+ /// </summary>
+ /// <value>The maximum number of digits used to represent the
+ /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> property.
+ /// The default value is 0, which indicates that the data provider
+ /// sets the precision for <b>Value</b>.</value>
+ [Category("Data"), DefaultValue((Byte)0)]
+ public Byte Precision
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Precision");
+ return precision;
+ }
+
+ set
+ {
+ NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Precision", value);
+ precision = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the number of decimal places to which
+ /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.
+ /// </summary>
+ /// <value>The number of decimal places to which
+ /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved. The default is 0.</value>
+ [Category("Data"), DefaultValue((Byte)0)]
+ public Byte Scale
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Scale");
+ return scale;
+ }
+
+ set
+ {
+ NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Scale", value);
+ scale = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the maximum size, in bytes, of the data within the column.
+ /// </summary>
+ /// <value>The maximum size, in bytes, of the data within the column.
+ /// The default value is inferred from the parameter value.</value>
+ [Category("Data"), DefaultValue(0)]
+ public Int32 Size
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Size");
+ return size;
+ }
+
+ set
+ {
+ NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Size", value);
+ size = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the <see cref="System.Data.DbType">DbType</see> of the parameter.
+ /// </summary>
+ /// <value>One of the <see cref="System.Data.DbType">DbType</see> values. The default is <b>String</b>.</value>
+ [Category("Data"), RefreshProperties(RefreshProperties.All), DefaultValue(DbType.String)]
+ public DbType DbType
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "DbType");
+ return db_type;
+ }
+
+ // [TODO] Validate data type.
+ set
+ {
+ NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "DbType", value);
+ db_type = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the parameter is input-only,
+ /// output-only, bidirectional, or a stored procedure return value parameter.
+ /// </summary>
+ /// <value>One of the <see cref="System.Data.ParameterDirection">ParameterDirection</see>
+ /// values. The default is <b>Input</b>.</value>
+ [Category("Data"), DefaultValue(ParameterDirection.Input)]
+ public ParameterDirection Direction
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "Direction");
+ return direction;
+ }
+
+ set
+ {
+ NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Direction", value);
+ direction = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the parameter accepts null values.
+ /// </summary>
+ /// <value><b>true</b> if null values are accepted; otherwise, <b>false</b>. The default is <b>false</b>.</value>
+ [EditorBrowsable(EditorBrowsableState.Advanced), Browsable(false), DefaultValue(false), DesignOnly(true)]
+ public Boolean IsNullable
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsNullable");
+ return is_nullable;
+ }
+
+ set
+ {
+ NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "IsNullable", value);
+ is_nullable = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.
+ /// </summary>
+ /// <value>The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.
+ /// The default is an empty string.</value>
+ [DefaultValue("")]
+ public String ParameterName
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "ParameterName");
+ return name;
+ }
+
+ set
+ {
+ name = value;
+ if ( (name.Equals(String.Empty)) || (name[0] != ':') )
+ name = ':' + name;
+ NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "ParameterName", value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the name of the source column that is mapped to the
+ /// <see cref="System.Data.DataSet">DataSet</see> and used for loading or
+ /// returning the <see cref="Npgsql.NpgsqlParameter.Value">Value</see>.
+ /// </summary>
+ /// <value>The name of the source column that is mapped to the
+ /// <see cref="System.Data.DataSet">DataSet</see>. The default is an empty string.</value>
+ [Category("Data"), DefaultValue("")]
+ public String SourceColumn
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "SourceColumn");
+ return source_column;
+ }
+
+ set
+ {
+ NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "SourceColumn", value);
+ source_column = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the <see cref="System.Data.DataRowVersion">DataRowVersion</see>
+ /// to use when loading <see cref="Npgsql.NpgsqlParameter.Value">Value</see>.
+ /// </summary>
+ /// <value>One of the <see cref="System.Data.DataRowVersion">DataRowVersion</see> values.
+ /// The default is <b>Current</b>.</value>
+ [Category("Data"), DefaultValue(DataRowVersion.Current)]
+ public DataRowVersion SourceVersion
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "SourceVersion");
+ return source_version;
+ }
+
+ set
+ {
+ NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "SourceVersion", value);
+ source_version = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the value of the parameter.
+ /// </summary>
+ /// <value>An <see cref="System.Object">Object</see> that is the value of the parameter.
+ /// The default value is null.</value>
+ [TypeConverter(typeof(StringConverter)), Category("Data")]
+ public Object Value
+ {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "Value");
+ return value;
+ }
+
+ // [TODO] Check and validate data type.
+ set
+ {
+ NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Value", value);
+ this.value = value;
+ }
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> that
+ /// is a copy of the current instance.
+ /// </summary>
+ /// <returns>A new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> that is a copy of this instance.</returns>
+ object System.ICloneable.Clone()
+ {
+ return new NpgsqlParameter(this.ParameterName, this.DbType, this.Size, this.SourceColumn, this.Direction, this.IsNullable, this.Precision, this.Scale, this.SourceVersion, this.Value);
+ }
+
+
+ }
}
// created on 09/07/2003 at 20:20
// Npgsql.NpgsqlParameterCollection.cs
-//
+//
// Author:
// Brar Piening (brar@gmx.de)
-//
+//
// Rewritten from the scratch to derive from MarshalByRefObject instead of ArrayList.
// Recycled some parts of the original NpgsqlParameterCollection.cs
// by Francisco Jr. (fxjrlists@yahoo.com.br)
// Copyright (C) 2002 The Npgsql Development Team
// npgsql-general@gborg.postgresql.org
// http://gborg.postgresql.org/project/npgsql/projdisplay.php
-//
+//
// 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
namespace Npgsql
{
- /// <summary>
- /// Represents a collection of parameters relevant to a <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>
- /// as well as their respective mappings to columns in a <see cref="System.Data.DataSet">DataSet</see>.
- /// This class cannot be inherited.
- /// </summary>
- [ListBindable(false)]
-// [Editor(typeof(NpgsqlParametersEditor), typeof(System.ComponentModel.Design.CollectionEditor))]
- [Editor(typeof(NpgsqlParametersEditor), typeof(System.Drawing.Design.UITypeEditor))]
- public sealed class NpgsqlParameterCollection : MarshalByRefObject, IDataParameterCollection
- {
- private ArrayList InternalList = new ArrayList();
-
- // Logging related value
- private static readonly String CLASSNAME = "NpgsqlParameterCollection";
-
- // Our resource manager
- private System.Resources.ResourceManager resman;
-
- /// <summary>
- /// Initializes a new instance of the NpgsqlParameterCollection class.
- /// </summary>
- internal NpgsqlParameterCollection(){
- this.resman = new System.Resources.ResourceManager(this.GetType());
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
- }
-
- #region NpgsqlParameterCollection Member
-
- /// <summary>
- /// Gets the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified name.
- /// </summary>
- /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to retrieve.</param>
- /// <value>The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified name, or a null reference if the parameter is not found.</value>
- [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public NpgsqlParameter this[string parameterName] {
- get {
- NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, parameterName);
- return (NpgsqlParameter)this.InternalList[IndexOf(parameterName)];
- }
- set {
- NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, parameterName, value);
- this.InternalList[IndexOf(parameterName)] = value;
- }
- }
-
- /// <summary>
- /// Gets the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> at the specified index.
- /// </summary>
- /// <param name="index">The zero-based index of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to retrieve.</param>
- /// <value>The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> at the specified index.</value>
- [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public NpgsqlParameter this[int index] {
- get {
- NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
- return (NpgsqlParameter)this.InternalList[index];
- }
- set {
- NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, index, value);
- this.InternalList[index] = value;
- }
- }
-
- /// <summary>
- /// Adds the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see>.
- /// </summary>
- /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
- /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
- public NpgsqlParameter Add(NpgsqlParameter value){
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", value);
-
- // Do not allow parameters without name.
- if ((value.ParameterName == null) ||
- (value.ParameterName.Trim() == String.Empty) ||
- (value.ParameterName.Length == 1 && value.ParameterName[0] == ':'))
- throw new NpgsqlException(String.Format(this.resman.GetString("Exception_InvalidParameterName"), value.ParameterName));
-
- this.InternalList.Add(value);
- return value;
- }
-
- /// <summary>
- /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> given the specified parameter name and value.
- /// </summary>
- /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
- /// <param name="value">The Value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
- /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
- /// <remarks>
- /// Use caution when using this overload of the
- /// <b>Add</b> method to specify integer parameter values.
- /// Because this overload takes a <i>value</i> of type Object,
- /// you must convert the integral value to an <b>Object</b>
- /// type when the value is zero, as the following C# example demonstrates.
- /// <code>parameters.Add(":pname", Convert.ToInt32(0));</code>
- /// If you do not perform this conversion, the compiler will assume you
- /// are attempting to call the NpgsqlParameterCollection.Add(string, DbType) overload.
- /// </remarks>
- public NpgsqlParameter Add(string parameterName, object value){
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, value);
- return this.Add(new NpgsqlParameter(parameterName, value));
- }
-
- /// <summary>
- /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> given the parameter name and the data type.
- /// </summary>
- /// <param name="parameterName">The name of the parameter.</param>
- /// <param name="parameterType">One of the DbType values.</param>
- /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
- public NpgsqlParameter Add(string parameterName, DbType parameterType){
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType);
- return this.Add(new NpgsqlParameter(parameterName, parameterType));
- }
-
- /// <summary>
- /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> with the parameter name, the data type, and the column length.
- /// </summary>
- /// <param name="parameterName">The name of the parameter.</param>
- /// <param name="parameterType">One of the DbType values.</param>
- /// <param name="size">The length of the column.</param>
- /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
- public NpgsqlParameter Add(string parameterName, DbType parameterType, int size){
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType, size);
- return this.Add(new NpgsqlParameter(parameterName, parameterType, size));
- }
-
- /// <summary>
- /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> with the parameter name, the data type, the column length, and the source column name.
- /// </summary>
- /// <param name="parameterName">The name of the parameter.</param>
- /// <param name="parameterType">One of the DbType values.</param>
- /// <param name="size">The length of the column.</param>
- /// <param name="sourceColumn">The name of the source column.</param>
- /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
- public NpgsqlParameter Add(string parameterName, DbType parameterType, int size, string sourceColumn){
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType, size, sourceColumn);
- return this.Add(new NpgsqlParameter(parameterName, parameterType, size, sourceColumn));
- }
-
- #endregion
-
- #region IDataParameterCollection Member
-
- object System.Data.IDataParameterCollection.this[string parameterName] {
- get {
- NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, parameterName);
- return this.InternalList[IndexOf(parameterName)];
- }
- set {
- NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, parameterName, value);
- CheckType(value);
- this.InternalList[IndexOf(parameterName)] = value;
- }
- }
-
- /// <summary>
- /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection using the parameter name.
- /// </summary>
- /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to retrieve.</param>
- public void RemoveAt(string parameterName) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "RemoveAt", parameterName);
- this.InternalList.RemoveAt(IndexOf(parameterName));
- }
-
- /// <summary>
- /// Gets a value indicating whether a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified parameter name exists in the collection.
- /// </summary>
- /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
- /// <returns><b>true</b> if the collection contains the parameter; otherwise, <b>false</b>.</returns>
- public bool Contains(string parameterName) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Contains", parameterName);
- return (IndexOf(parameterName) != -1);
- }
-
- /// <summary>
- /// Gets the location of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection with a specific parameter name.
- /// </summary>
- /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
- /// <returns>The zero-based location of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection.</returns>
- public int IndexOf(string parameterName) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IndexOf", parameterName);
-
- // Iterate values to see what is the index of parameter.
+ /// <summary>
+ /// Represents a collection of parameters relevant to a <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>
+ /// as well as their respective mappings to columns in a <see cref="System.Data.DataSet">DataSet</see>.
+ /// This class cannot be inherited.
+ /// </summary>
+ [ListBindable(false)]
+ // [Editor(typeof(NpgsqlParametersEditor), typeof(System.ComponentModel.Design.CollectionEditor))]
+ [Editor(typeof(NpgsqlParametersEditor), typeof(System.Drawing.Design.UITypeEditor))]
+ public sealed class NpgsqlParameterCollection : MarshalByRefObject, IDataParameterCollection
+ {
+ private ArrayList InternalList = new ArrayList();
+
+ // Logging related value
+ private static readonly String CLASSNAME = "NpgsqlParameterCollection";
+
+ // Our resource manager
+ private System.Resources.ResourceManager resman;
+
+ /// <summary>
+ /// Initializes a new instance of the NpgsqlParameterCollection class.
+ /// </summary>
+ internal NpgsqlParameterCollection()
+ {
+ this.resman = new System.Resources.ResourceManager(this.GetType());
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
+ }
+
+#region NpgsqlParameterCollection Member
+
+ /// <summary>
+ /// Gets the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified name.
+ /// </summary>
+ /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to retrieve.</param>
+ /// <value>The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified name, or a null reference if the parameter is not found.</value>
+ [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public NpgsqlParameter this[string parameterName] {
+ get
+ {
+ NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, parameterName);
+ return (NpgsqlParameter)this.InternalList[IndexOf(parameterName)];
+ }
+ set
+ {
+ NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, parameterName, value);
+ this.InternalList[IndexOf(parameterName)] = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to retrieve.</param>
+ /// <value>The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> at the specified index.</value>
+ [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public NpgsqlParameter this[int index] {
+ get
+ {
+ NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
+ return (NpgsqlParameter)this.InternalList[index];
+ }
+ set
+ {
+ NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, index, value);
+ this.InternalList[index] = value;
+ }
+ }
+
+ /// <summary>
+ /// Adds the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see>.
+ /// </summary>
+ /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
+ /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
+ public NpgsqlParameter Add(NpgsqlParameter value)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", value);
+
+ // Do not allow parameters without name.
+ if ((value.ParameterName == null) ||
+ (value.ParameterName.Trim() == String.Empty) ||
+ (value.ParameterName.Length == 1 && value.ParameterName[0] == ':'))
+ throw new NpgsqlException(String.Format(this.resman.GetString("Exception_InvalidParameterName"), value.ParameterName));
+
+ this.InternalList.Add(value);
+ return value;
+ }
+
+ /// <summary>
+ /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> given the specified parameter name and value.
+ /// </summary>
+ /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
+ /// <param name="value">The Value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
+ /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
+ /// <remarks>
+ /// Use caution when using this overload of the
+ /// <b>Add</b> method to specify integer parameter values.
+ /// Because this overload takes a <i>value</i> of type Object,
+ /// you must convert the integral value to an <b>Object</b>
+ /// type when the value is zero, as the following C# example demonstrates.
+ /// <code>parameters.Add(":pname", Convert.ToInt32(0));</code>
+ /// If you do not perform this conversion, the compiler will assume you
+ /// are attempting to call the NpgsqlParameterCollection.Add(string, DbType) overload.
+ /// </remarks>
+ public NpgsqlParameter Add(string parameterName, object value)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, value);
+ return this.Add(new NpgsqlParameter(parameterName, value));
+ }
+
+ /// <summary>
+ /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> given the parameter name and the data type.
+ /// </summary>
+ /// <param name="parameterName">The name of the parameter.</param>
+ /// <param name="parameterType">One of the DbType values.</param>
+ /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
+ public NpgsqlParameter Add(string parameterName, DbType parameterType)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType);
+ return this.Add(new NpgsqlParameter(parameterName, parameterType));
+ }
+
+ /// <summary>
+ /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> with the parameter name, the data type, and the column length.
+ /// </summary>
+ /// <param name="parameterName">The name of the parameter.</param>
+ /// <param name="parameterType">One of the DbType values.</param>
+ /// <param name="size">The length of the column.</param>
+ /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
+ public NpgsqlParameter Add(string parameterName, DbType parameterType, int size)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType, size);
+ return this.Add(new NpgsqlParameter(parameterName, parameterType, size));
+ }
+
+ /// <summary>
+ /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> with the parameter name, the data type, the column length, and the source column name.
+ /// </summary>
+ /// <param name="parameterName">The name of the parameter.</param>
+ /// <param name="parameterType">One of the DbType values.</param>
+ /// <param name="size">The length of the column.</param>
+ /// <param name="sourceColumn">The name of the source column.</param>
+ /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
+ public NpgsqlParameter Add(string parameterName, DbType parameterType, int size, string sourceColumn)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType, size, sourceColumn);
+ return this.Add(new NpgsqlParameter(parameterName, parameterType, size, sourceColumn));
+ }
+
+#endregion
+
+#region IDataParameterCollection Member
+
+ object System.Data.IDataParameterCollection.this[string parameterName] {
+ get
+ {
+ NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, parameterName);
+ return this.InternalList[IndexOf(parameterName)];
+ }
+ set
+ {
+ NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, parameterName, value);
+ CheckType(value);
+ this.InternalList[IndexOf(parameterName)] = value;
+ }
+ }
+
+ /// <summary>
+ /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection using the parameter name.
+ /// </summary>
+ /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to retrieve.</param>
+ public void RemoveAt(string parameterName)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "RemoveAt", parameterName);
+ this.InternalList.RemoveAt(IndexOf(parameterName));
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified parameter name exists in the collection.
+ /// </summary>
+ /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
+ /// <returns><b>true</b> if the collection contains the parameter; otherwise, <b>false</b>.</returns>
+ public bool Contains(string parameterName)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Contains", parameterName);
+ return (IndexOf(parameterName) != -1);
+ }
+
+ /// <summary>
+ /// Gets the location of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection with a specific parameter name.
+ /// </summary>
+ /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
+ /// <returns>The zero-based location of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection.</returns>
+ public int IndexOf(string parameterName)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IndexOf", parameterName);
+
+ // Iterate values to see what is the index of parameter.
Int32 index = 0;
if (parameterName[0] != ':')
- parameterName = ':' + parameterName;
-
- foreach(NpgsqlParameter parameter in this){
- if (parameter.ParameterName == parameterName)
- return index;
- index++;
- }
- return -1;
- }
-
- #endregion
-
- #region IList Member
-
- bool IList.IsReadOnly {
- get {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsReadOnly");
- return this.InternalList.IsReadOnly;
- }
- }
-
- object System.Collections.IList.this[int index] {
- get {
- NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
- return (NpgsqlParameter)this.InternalList[index];
- }
- set {
- NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, index, value);
- CheckType(value);
- this.InternalList[index] = value;
- }
- }
-
- /// <summary>
- /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection using a specific index.
- /// </summary>
- /// <param name="index">The zero-based index of the parameter.</param>
- public void RemoveAt(int index) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "RemoveAt", index);
- this.InternalList.RemoveAt(index);
- }
-
- /// <summary>
- /// Inserts a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> into the collection at the specified index.
- /// </summary>
- /// <param name="index">The zero-based index where the parameter is to be inserted within the collection.</param>
- /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
- public void Insert(int index, object value) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Insert", index, value);
- CheckType(value);
- this.InternalList.Insert(index, value);
- }
-
- /// <summary>
- /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection.
- /// </summary>
- /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to remove from the collection.</param>
- public void Remove(object value) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Remove", value);
- CheckType(value);
- this.InternalList.Remove(value);
- }
-
- /// <summary>
- /// Gets a value indicating whether a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> exists in the collection.
- /// </summary>
- /// <param name="value">The value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
- /// <returns>true if the collection contains the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object; otherwise, false.</returns>
- public bool Contains(object value) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Contains", value);
- CheckType(value);
- return this.InternalList.Contains(value);
- }
-
- /// <summary>
- /// Removes all items from the collection.
- /// </summary>
- public void Clear() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Clear");
- this.InternalList.Clear();
- }
-
- /// <summary>
- /// Gets the location of a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection.
- /// </summary>
- /// <param name="value">The value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
- /// <returns>The zero-based index of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object in the collection.</returns>
- public int IndexOf(object value) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IndexOf", value);
- CheckType(value);
- return this.InternalList.IndexOf(value);
- }
-
- /// <summary>
- /// Adds the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see>.
- /// </summary>
- /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
- /// <returns>The zero-based index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
- public int Add(object value) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", value);
- CheckType(value);
- return this.InternalList.Add(value);
- }
-
- bool IList.IsFixedSize {
- get {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsFixedSize");
- return this.InternalList.IsFixedSize;
- }
- }
-
- #endregion
-
- #region ICollection Member
-
- bool ICollection.IsSynchronized {
- get {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsSynchronized");
- return this.InternalList.IsSynchronized;
- }
- }
-
- /// <summary>
- /// Gets the number of <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects in the collection.
- /// </summary>
- /// <value>The number of <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects in the collection.</value>
- [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public int Count {
- get {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Count");
- return this.InternalList.Count;
- }
- }
-
- /// <summary>
- /// Copies <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects from the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> to the specified array.
- /// </summary>
- /// <param name="array">An <see cref="System.Array">Array</see> to which to copy the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects in the collection.</param>
- /// <param name="index">The starting index of the array.</param>
- public void CopyTo(Array array, int index) {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CopyTo", array, index);
- this.InternalList.CopyTo(array, index);
- }
-
- object ICollection.SyncRoot {
- get {
- NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "SyncRoot");
- return this.InternalList.SyncRoot;
- }
- }
-
- #endregion
-
- #region IEnumerable Member
-
- /// <summary>
- /// Returns an enumerator that can iterate through the collection.
- /// </summary>
- /// <returns>An <see cref="System.Collections.IEnumerator">IEnumerator</see> that can be used to iterate through the collection.</returns>
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetEnumerator");
- return this.InternalList.GetEnumerator();
- }
-
- #endregion
-
- /// <summary>
- /// In methods taking an object as argument this method is used to verify
- /// that the argument has the type <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
- /// </summary>
- /// <param name="Object">The object to verify</param>
- private void CheckType(object Object){
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CheckType", Object);
- if(Object.GetType() != typeof(NpgsqlParameter))
- throw new InvalidCastException(String.Format(this.resman.GetString("Exception_WrongType"), Object.GetType().ToString()));
- }
-
- }
+ parameterName = ':' + parameterName;
+
+ foreach(NpgsqlParameter parameter in this)
+ {
+ if (parameter.ParameterName == parameterName)
+ return index;
+ index++;
+ }
+ return -1;
+ }
+
+#endregion
+
+#region IList Member
+
+ bool IList.IsReadOnly {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsReadOnly");
+ return this.InternalList.IsReadOnly;
+ }
+ }
+
+ object System.Collections.IList.this[int index] {
+ get
+ {
+ NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
+ return (NpgsqlParameter)this.InternalList[index];
+ }
+ set
+ {
+ NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, index, value);
+ CheckType(value);
+ this.InternalList[index] = value;
+ }
+ }
+
+ /// <summary>
+ /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection using a specific index.
+ /// </summary>
+ /// <param name="index">The zero-based index of the parameter.</param>
+ public void RemoveAt(int index)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "RemoveAt", index);
+ this.InternalList.RemoveAt(index);
+ }
+
+ /// <summary>
+ /// Inserts a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> into the collection at the specified index.
+ /// </summary>
+ /// <param name="index">The zero-based index where the parameter is to be inserted within the collection.</param>
+ /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
+ public void Insert(int index, object value)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Insert", index, value);
+ CheckType(value);
+ this.InternalList.Insert(index, value);
+ }
+
+ /// <summary>
+ /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection.
+ /// </summary>
+ /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to remove from the collection.</param>
+ public void Remove(object value)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Remove", value);
+ CheckType(value);
+ this.InternalList.Remove(value);
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> exists in the collection.
+ /// </summary>
+ /// <param name="value">The value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
+ /// <returns>true if the collection contains the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object; otherwise, false.</returns>
+ public bool Contains(object value)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Contains", value);
+ CheckType(value);
+ return this.InternalList.Contains(value);
+ }
+
+ /// <summary>
+ /// Removes all items from the collection.
+ /// </summary>
+ public void Clear()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Clear");
+ this.InternalList.Clear();
+ }
+
+ /// <summary>
+ /// Gets the location of a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection.
+ /// </summary>
+ /// <param name="value">The value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
+ /// <returns>The zero-based index of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object in the collection.</returns>
+ public int IndexOf(object value)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IndexOf", value);
+ CheckType(value);
+ return this.InternalList.IndexOf(value);
+ }
+
+ /// <summary>
+ /// Adds the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see>.
+ /// </summary>
+ /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
+ /// <returns>The zero-based index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
+ public int Add(object value)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", value);
+ CheckType(value);
+ return this.InternalList.Add(value);
+ }
+
+ bool IList.IsFixedSize {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsFixedSize");
+ return this.InternalList.IsFixedSize;
+ }
+ }
+
+#endregion
+
+#region ICollection Member
+
+ bool ICollection.IsSynchronized {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsSynchronized");
+ return this.InternalList.IsSynchronized;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects in the collection.
+ /// </summary>
+ /// <value>The number of <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects in the collection.</value>
+ [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public int Count {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Count");
+ return this.InternalList.Count;
+ }
+ }
+
+ /// <summary>
+ /// Copies <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects from the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> to the specified array.
+ /// </summary>
+ /// <param name="array">An <see cref="System.Array">Array</see> to which to copy the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects in the collection.</param>
+ /// <param name="index">The starting index of the array.</param>
+ public void CopyTo(Array array, int index)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CopyTo", array, index);
+ this.InternalList.CopyTo(array, index);
+ }
+
+ object ICollection.SyncRoot {
+ get
+ {
+ NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "SyncRoot");
+ return this.InternalList.SyncRoot;
+ }
+ }
+
+#endregion
+
+#region IEnumerable Member
+
+ /// <summary>
+ /// Returns an enumerator that can iterate through the collection.
+ /// </summary>
+ /// <returns>An <see cref="System.Collections.IEnumerator">IEnumerator</see> that can be used to iterate through the collection.</returns>
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetEnumerator");
+ return this.InternalList.GetEnumerator();
+ }
+
+#endregion
+
+ /// <summary>
+ /// In methods taking an object as argument this method is used to verify
+ /// that the argument has the type <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
+ /// </summary>
+ /// <param name="Object">The object to verify</param>
+ private void CheckType(object Object)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CheckType", Object);
+ if(Object.GetType() != typeof(NpgsqlParameter))
+ throw new InvalidCastException(String.Format(this.resman.GetString("Exception_WrongType"), Object.GetType().ToString()));
+ }
+
+ }
}
// created on 8/6/2003 at 13:57
// Npgsql.NpgsqlAsciiRow.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- /// <summary>
- /// This class represents the ParameterStatus message sent from PostgreSQL
- /// server.
- /// </summary>
- ///
- internal sealed class NpgsqlParameterStatus
- {
-
- private String _parameter;
- private String _parameterValue;
-
-
- public void ReadFromStream(Stream inputStream, Encoding encoding)
- {
-
- //Read message length
- Byte[] inputBuffer = new Byte[4];
- PGUtil.CheckedStreamRead(inputStream, inputBuffer, 0, 4 );
-
- Int32 messageLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(inputBuffer, 0));
-
- _parameter = PGUtil.ReadString(inputStream, encoding);
- _parameterValue = PGUtil.ReadString(inputStream, encoding);
-
-
- }
-
- public String Parameter
- {
- get
- {
- return _parameter;
- }
- }
-
- public String ParameterValue
- {
- get
- {
- return _parameterValue;
- }
- }
-
-
- }
-
-
+
+ /// <summary>
+ /// This class represents the ParameterStatus message sent from PostgreSQL
+ /// server.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlParameterStatus
+ {
+
+ private String _parameter;
+ private String _parameterValue;
+
+
+ public void ReadFromStream(Stream inputStream, Encoding encoding)
+ {
+
+ //Read message length
+ Byte[] inputBuffer = new Byte[4];
+ PGUtil.CheckedStreamRead(inputStream, inputBuffer, 0, 4 );
+
+ Int32 messageLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(inputBuffer, 0));
+
+ _parameter = PGUtil.ReadString(inputStream, encoding);
+ _parameterValue = PGUtil.ReadString(inputStream, encoding);
+
+
+ }
+
+ public String Parameter
+ {
+ get
+ {
+ return _parameter;
+ }
+ }
+
+ public String ParameterValue
+ {
+ get
+ {
+ return _parameterValue;
+ }
+ }
+
+
+ }
+
+
}
// created on 22/6/2003 at 18:33
// Npgsql.NpgsqlParse.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- /// <summary>
- /// This class represents the Parse message sent to PostgreSQL
- /// server.
- /// </summary>
- ///
- internal sealed class NpgsqlParse
- {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlParse";
-
- private String _prepareName;
- private String _queryString;
- private Int32[] _parameterIDs;
-
-
- public NpgsqlParse(String prepareName, String queryString, Int32[] parameterIDs)
- {
- _prepareName = prepareName;
- _queryString = queryString;
- _parameterIDs = parameterIDs;
-
- }
-
- public void WriteToStream(Stream outputStream, Encoding encoding)
- {
- outputStream.WriteByte((Byte)'P');
-
- // message length =
- // Int32 self
- // name of prepared statement + 1 null string terminator +
- // query string + 1 null string terminator
- // + Int16
- // + Int32 * number of parameters.
- Int32 messageLength = 4 + encoding.GetByteCount(_prepareName) + 1 + encoding.GetByteCount(_queryString) + 1 + 2 + (_parameterIDs.Length * 4);
- //Int32 messageLength = 4 + _prepareName.Length + 1 + _queryString.Length + 1 + 2 + (_parameterIDs.Length * 4);
-
- PGUtil.WriteInt32(outputStream, messageLength);
- PGUtil.WriteString(_prepareName, outputStream, encoding);
- PGUtil.WriteString(_queryString, outputStream, encoding);
- PGUtil.WriteInt16(outputStream, (Int16)_parameterIDs.Length);
-
-
- for(Int32 i = 0; i < _parameterIDs.Length; i++)
- PGUtil.WriteInt32(outputStream, _parameterIDs[i]);
-
-
-
-
- }
- }
+
+ /// <summary>
+ /// This class represents the Parse message sent to PostgreSQL
+ /// server.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlParse
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlParse";
+
+ private String _prepareName;
+ private String _queryString;
+ private Int32[] _parameterIDs;
+
+
+ public NpgsqlParse(String prepareName, String queryString, Int32[] parameterIDs)
+ {
+ _prepareName = prepareName;
+ _queryString = queryString;
+ _parameterIDs = parameterIDs;
+
+ }
+
+ public void WriteToStream(Stream outputStream, Encoding encoding)
+ {
+ outputStream.WriteByte((Byte)'P');
+
+ // message length =
+ // Int32 self
+ // name of prepared statement + 1 null string terminator +
+ // query string + 1 null string terminator
+ // + Int16
+ // + Int32 * number of parameters.
+ Int32 messageLength = 4 + encoding.GetByteCount(_prepareName) + 1 + encoding.GetByteCount(_queryString) + 1 + 2 + (_parameterIDs.Length * 4);
+ //Int32 messageLength = 4 + _prepareName.Length + 1 + _queryString.Length + 1 + 2 + (_parameterIDs.Length * 4);
+
+ PGUtil.WriteInt32(outputStream, messageLength);
+ PGUtil.WriteString(_prepareName, outputStream, encoding);
+ PGUtil.WriteString(_queryString, outputStream, encoding);
+ PGUtil.WriteInt16(outputStream, (Int16)_parameterIDs.Length);
+
+
+ for(Int32 i = 0; i < _parameterIDs.Length; i++)
+ PGUtil.WriteInt32(outputStream, _parameterIDs[i]);
+
+
+
+
+ }
+ }
}
// created on 10/6/2002 at 21:33
// Npgsql.NpgsqlPasswordPacket.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
- /// <summary>
- /// This class represents a PasswordPacket message sent to backend
- /// PostgreSQL.
- /// </summary>
- internal sealed class NpgsqlPasswordPacket
- {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlPasswordPacket";
-
- private String password;
- private Int32 protocolVersion;
-
-
- public NpgsqlPasswordPacket(String password, Int32 protocolVersion)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
-
- this.password = password;
- this.protocolVersion = protocolVersion;
- }
-
- public void WriteToStream(Stream outputStream, Encoding encoding)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteToStream");
-
- if (protocolVersion == ProtocolVersion.Version2)
- { // Write the size of the packet.
- // 4 + (passwordlength + 1) -> Int32 + NULL terminated string.
- //output_stream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(4 + (password.Length + 1))), 0, 4);
-
- PGUtil.WriteInt32(outputStream, 4 + encoding.GetByteCount(password) + 1);
-
- // Write String.
- PGUtil.WriteString(password, outputStream, encoding);
- }
- else
- {
- outputStream.WriteByte((Byte)'p');
- PGUtil.WriteInt32(outputStream, 4 + encoding.GetByteCount(password) + 1);
-
- // Write String.
- PGUtil.WriteString(password, outputStream, encoding);
- }
-
-
- }
- }
-
+ /// <summary>
+ /// This class represents a PasswordPacket message sent to backend
+ /// PostgreSQL.
+ /// </summary>
+ internal sealed class NpgsqlPasswordPacket
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlPasswordPacket";
+
+ private String password;
+ private Int32 protocolVersion;
+
+
+ public NpgsqlPasswordPacket(String password, Int32 protocolVersion)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
+
+ this.password = password;
+ this.protocolVersion = protocolVersion;
+ }
+
+ public void WriteToStream(Stream outputStream, Encoding encoding)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteToStream");
+
+ if (protocolVersion == ProtocolVersion.Version2)
+ { // Write the size of the packet.
+ // 4 + (passwordlength + 1) -> Int32 + NULL terminated string.
+ //output_stream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(4 + (password.Length + 1))), 0, 4);
+
+ PGUtil.WriteInt32(outputStream, 4 + encoding.GetByteCount(password) + 1);
+
+ // Write String.
+ PGUtil.WriteString(password, outputStream, encoding);
+ }
+ else
+ {
+ outputStream.WriteByte((Byte)'p');
+ PGUtil.WriteInt32(outputStream, 4 + encoding.GetByteCount(password) + 1);
+
+ // Write String.
+ PGUtil.WriteString(password, outputStream, encoding);
+ }
+
+
+ }
+ }
+
}
// Npgsql.NpgsqlQuery.cs
-//
+//
// Author:
// Dave Joyner <d4ljoyn@yahoo.com>
//
// 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
namespace Npgsql
{
- /// <summary>
- /// Summary description for NpgsqlQuery
- /// </summary>
- internal sealed class NpgsqlQuery
- {
- private String _commandText;
- private Int32 _protocolVersion;
-
- public NpgsqlQuery(String commandText, Int32 protocolVersion)
- {
- _commandText = commandText;
- _protocolVersion = protocolVersion;
-
- }
- public void WriteToStream( Stream outputStream, Encoding encoding )
- {
- //NpgsqlEventLog.LogMsg( this.ToString() + _commandText, LogLevel.Debug );
-
-
- // Send the query to server.
- // Write the byte 'Q' to identify a query message.
- outputStream.WriteByte((Byte)'Q');
-
-
- if (_protocolVersion == ProtocolVersion.Version3)
- // Write message length. Int32 + string length + null terminator.
- PGUtil.WriteInt32(outputStream, 4 + encoding.GetByteCount(_commandText) + 1);
-
-
-
-
- // Write the query. In this case it is the CommandText text.
- // It is a string terminated by a C NULL character.
-
- PGUtil.WriteString(_commandText, outputStream, encoding);
-
-
-
- }
- }
+ /// <summary>
+ /// Summary description for NpgsqlQuery
+ /// </summary>
+ internal sealed class NpgsqlQuery
+ {
+ private String _commandText;
+ private Int32 _protocolVersion;
+
+ public NpgsqlQuery(String commandText, Int32 protocolVersion)
+ {
+ _commandText = commandText;
+ _protocolVersion = protocolVersion;
+
+ }
+ public void WriteToStream( Stream outputStream, Encoding encoding )
+ {
+ //NpgsqlEventLog.LogMsg( this.ToString() + _commandText, LogLevel.Debug );
+
+
+ // Send the query to server.
+ // Write the byte 'Q' to identify a query message.
+ outputStream.WriteByte((Byte)'Q');
+
+
+ if (_protocolVersion == ProtocolVersion.Version3)
+ // Write message length. Int32 + string length + null terminator.
+ PGUtil.WriteInt32(outputStream, 4 + encoding.GetByteCount(_commandText) + 1);
+
+
+
+
+ // Write the query. In this case it is the CommandText text.
+ // It is a string terminated by a C NULL character.
+
+ PGUtil.WriteString(_commandText, outputStream, encoding);
+
+
+
+ }
+ }
}
// Npgsql.NpgsqlReadyState.cs
-//
+//
// Author:
// Dave Joyner <d4ljoyn@yahoo.com>
//
// 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
namespace Npgsql
{
-
-
- internal sealed class NpgsqlReadyState : NpgsqlState
- {
- private static NpgsqlReadyState _instance = null;
-
-
+
+
+ internal sealed class NpgsqlReadyState : NpgsqlState
+ {
+ private static NpgsqlReadyState _instance = null;
+
+
// Flush and Sync messages. It doesn't need to be created every time it is called.
private static readonly NpgsqlFlush _flushMessage = new NpgsqlFlush();
-
+
private static readonly NpgsqlSync _syncMessage = new NpgsqlSync();
-
+
private readonly String CLASSNAME = "NpgsqlReadyState";
-
- private NpgsqlReadyState() : base() { }
-
- public static NpgsqlReadyState Instance
- {
- get
- {
- if ( _instance == null )
- {
- _instance = new NpgsqlReadyState();
- }
- return _instance;
- }
- }
-
-
-
- public override void Query( NpgsqlConnection context, NpgsqlCommand command )
- {
-
+
+ private NpgsqlReadyState() : base()
+ { }
+
+ public static NpgsqlReadyState Instance
+ {
+ get
+ {
+ if ( _instance == null )
+ {
+ _instance = new NpgsqlReadyState();
+ }
+ return _instance;
+ }
+ }
+
+
+
+ public override void Query( NpgsqlConnection context, NpgsqlCommand command )
+ {
+
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Query");
-
- String commandText = command.GetCommandText();
+
+ String commandText = command.GetCommandText();
NpgsqlEventLog.LogMsg(resman, "Log_QuerySent", LogLevel.Debug, commandText);
-
- // Send the query request to backend.
-
- NpgsqlQuery query = new NpgsqlQuery(commandText, context.BackendProtocolVersion);
- BufferedStream stream = context.BufferedStream;
- query.WriteToStream(stream, context.Encoding);
- stream.Flush();
-
- ProcessBackendResponses(context);
-
- }
-
- public override void Parse(NpgsqlConnection context, NpgsqlParse parse)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Parse");
- BufferedStream stream = context.BufferedStream;
- parse.WriteToStream(stream, context.Encoding);
- stream.Flush();
-
-
- }
-
-
- public override void Sync(NpgsqlConnection context)
- {
+
+ // Send the query request to backend.
+
+ NpgsqlQuery query = new NpgsqlQuery(commandText, context.BackendProtocolVersion);
+ BufferedStream stream = new BufferedStream(context.Stream);
+ query.WriteToStream(stream, context.Encoding);
+ stream.Flush();
+
+ ProcessBackendResponses(context);
+
+ }
+
+ public override void Parse(NpgsqlConnection context, NpgsqlParse parse)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Parse");
+ BufferedStream stream = new BufferedStream(context.Stream);
+ parse.WriteToStream(stream, context.Encoding);
+ stream.Flush();
+
+
+ }
+
+
+ public override void Sync(NpgsqlConnection context)
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Sync");
- _syncMessage.WriteToStream(context.NormalStream, context.Encoding);
- ProcessBackendResponses(context);
- }
-
- public override void Flush(NpgsqlConnection context)
- {
+ _syncMessage.WriteToStream(context.Stream, context.Encoding);
+ ProcessBackendResponses(context);
+ }
+
+ public override void Flush(NpgsqlConnection context)
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Flush");
- _flushMessage.WriteToStream(context.NormalStream, context.Encoding);
+ _flushMessage.WriteToStream(context.Stream, context.Encoding);
ProcessBackendResponses(context);
- }
-
- public override void Bind(NpgsqlConnection context, NpgsqlBind bind)
- {
+ }
+
+ public override void Bind(NpgsqlConnection context, NpgsqlBind bind)
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Bind");
- BufferedStream stream = context.BufferedStream;
- bind.WriteToStream(stream, context.Encoding);
- stream.Flush();
-
- }
-
- public override void Execute(NpgsqlConnection context, NpgsqlExecute execute)
- {
-
+ BufferedStream stream = new BufferedStream(context.Stream);
+ bind.WriteToStream(stream, context.Encoding);
+ stream.Flush();
+
+ }
+
+ public override void Execute(NpgsqlConnection context, NpgsqlExecute execute)
+ {
+
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Execute");
- NpgsqlDescribe describe = new NpgsqlDescribe('P', execute.PortalName);
- describe.WriteToStream(context.NormalStream, context.Encoding);
- execute.WriteToStream(context.NormalStream, context.Encoding);
- Sync(context);
- }
-
- }
+ NpgsqlDescribe describe = new NpgsqlDescribe('P', execute.PortalName);
+ BufferedStream stream = new BufferedStream(context.Stream);
+ describe.WriteToStream(stream, context.Encoding);
+ execute.WriteToStream(stream, context.Encoding);
+ stream.Flush();
+ Sync(context);
+ }
+
+ }
}
// Npgsql.NpgsqlResultSet.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
- internal sealed class NpgsqlResultSet
- {
- private NpgsqlRowDescription row_desc;
- private ArrayList data;
-
-
- public NpgsqlResultSet(NpgsqlRowDescription rowDesc, ArrayList data)
- {
- this.row_desc = rowDesc;
- this.data = data;
- }
-
- public NpgsqlRowDescription RowDescription
- {
- get
- {
- return row_desc;
- }
- }
-
- public Object this[Int32 index]
- {
- get
- {
- return data[index];
- }
- }
-
- public Int32 Count
- {
- get
- {
- return data.Count;
- }
- }
- }
+ internal sealed class NpgsqlResultSet
+ {
+ private NpgsqlRowDescription row_desc;
+ private ArrayList data;
+
+
+ public NpgsqlResultSet(NpgsqlRowDescription rowDesc, ArrayList data)
+ {
+ this.row_desc = rowDesc;
+ this.data = data;
+ }
+
+ public NpgsqlRowDescription RowDescription
+ {
+ get
+ {
+ return row_desc;
+ }
+ }
+
+ public Object this[Int32 index]
+ {
+ get
+ {
+ return data[index];
+ }
+ }
+
+ public Int32 Count
+ {
+ get
+ {
+ return data.Count;
+ }
+ }
+ }
}
// created on 12/6/2002 at 20:29
// Npgsql.NpgsqlRowDescription.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
-
- /// <summary>
- /// This struct represents the internal data of the RowDescription message.
- /// </summary>
- ///
- // [FIXME] Is this name OK? Does it represent well the struct intent?
- // Should it be a struct or a class?
- internal struct NpgsqlRowDescriptionFieldData
- {
- public String name; // Protocol 2/3
- public Int32 table_oid; // Protocol 3
- public Int16 column_attribute_number; // Protocol 3
- public Int32 type_oid; // Protocol 2/3
- public Int16 type_size; // Protocol 2/3
- public Int32 type_modifier; // Protocol 2/3
- public FormatCode format_code; // Protocol 3. 0 text, 1 binary
- }
-
- /// <summary>
- /// This class represents a RowDescription message sent from
- /// the PostgreSQL.
- /// </summary>
- ///
- internal sealed class NpgsqlRowDescription
- {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlRowDescription";
-
-
- private ArrayList fields_data = new ArrayList();
-
- private Hashtable fields_index = new Hashtable();
-
- private Int32 protocol_version;
-
- public NpgsqlRowDescription(Int32 protocolVersion)
- {
- protocol_version = protocolVersion;
- }
-
- public void ReadFromStream(Stream input_stream, Encoding encoding)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream");
-
-
- if (protocol_version == ProtocolVersion.Version2)
- {
- Byte[] input_buffer = new Byte[10]; // Max read will be 4 + 2 + 4
-
- // Read the number of fields.
- input_stream.Read(input_buffer, 0, 2);
- Int16 num_fields = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(input_buffer, 0));
-
-
- // Temporary FieldData object to get data from stream and put in array.
- NpgsqlRowDescriptionFieldData fd;
-
- // Now, iterate through each field getting its data.
- for (Int16 i = 0; i < num_fields; i++)
- {
- fd = new NpgsqlRowDescriptionFieldData();
-
- // Set field name.
- fd.name = PGUtil.ReadString(input_stream, encoding);
-
- // Read type_oid(Int32), type_size(Int16), type_modifier(Int32)
- input_stream.Read(input_buffer, 0, 4 + 2 + 4);
-
- fd.type_oid = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
- fd.type_size = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(input_buffer, 4));
- fd.type_modifier = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 6));
-
- // Add field data to array.
- fields_data.Add(fd);
-
- fields_index.Add(fd.name, i);
- }
- }
- else
- {
- Byte[] input_buffer = new Byte[4]; // Max read will be 4 + 2 + 4 + 2 + 4 + 2
-
- // Read the length of message.
- // [TODO] Any use for now?
- PGUtil.ReadInt32(input_stream, input_buffer);
- Int16 num_fields = PGUtil.ReadInt16(input_stream, input_buffer);
-
- // Temporary FieldData object to get data from stream and put in array.
- NpgsqlRowDescriptionFieldData fd;
-
- for (Int16 i = 0; i < num_fields; i++)
- {
- fd = new NpgsqlRowDescriptionFieldData();
-
- fd.name = PGUtil.ReadString(input_stream, encoding);
- fd.table_oid = PGUtil.ReadInt32(input_stream, input_buffer);
- fd.column_attribute_number = PGUtil.ReadInt16(input_stream, input_buffer);
- fd.type_oid = PGUtil.ReadInt32(input_stream, input_buffer);
- fd.type_size = PGUtil.ReadInt16(input_stream, input_buffer);
- fd.type_modifier = PGUtil.ReadInt32(input_stream, input_buffer);
- fd.format_code = (FormatCode)PGUtil.ReadInt16(input_stream, input_buffer);
-
- fields_data.Add(fd);
- fields_index.Add(fd.name, i);
- }
-
- }
-
-
- }
-
- public NpgsqlRowDescriptionFieldData this[Int32 index]
- {
- get
- {
- return (NpgsqlRowDescriptionFieldData)fields_data[index];
- }
-
- }
-
- public Int16 NumFields
- {
- get
- {
- return (Int16)fields_data.Count;
- }
- }
-
- public Int16 FieldIndex(String fieldName)
- {
- return (Int16) fields_index[fieldName];
- }
-
- }
-
+
+
+ /// <summary>
+ /// This struct represents the internal data of the RowDescription message.
+ /// </summary>
+ ///
+ // [FIXME] Is this name OK? Does it represent well the struct intent?
+ // Should it be a struct or a class?
+ internal struct NpgsqlRowDescriptionFieldData
+ {
+ public String name; // Protocol 2/3
+ public Int32 table_oid; // Protocol 3
+ public Int16 column_attribute_number; // Protocol 3
+ public Int32 type_oid; // Protocol 2/3
+ public Int16 type_size; // Protocol 2/3
+ public Int32 type_modifier; // Protocol 2/3
+ public FormatCode format_code; // Protocol 3. 0 text, 1 binary
+ }
+
+ /// <summary>
+ /// This class represents a RowDescription message sent from
+ /// the PostgreSQL.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlRowDescription
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlRowDescription";
+
+
+ private ArrayList fields_data = new ArrayList();
+
+ private Hashtable fields_index = new Hashtable();
+
+ private Int32 protocol_version;
+
+ public NpgsqlRowDescription(Int32 protocolVersion)
+ {
+ protocol_version = protocolVersion;
+ }
+
+ public void ReadFromStream(Stream input_stream, Encoding encoding)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream");
+
+
+ if (protocol_version == ProtocolVersion.Version2)
+ {
+ Byte[] input_buffer = new Byte[10]; // Max read will be 4 + 2 + 4
+
+ // Read the number of fields.
+ input_stream.Read(input_buffer, 0, 2);
+ Int16 num_fields = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(input_buffer, 0));
+
+
+ // Temporary FieldData object to get data from stream and put in array.
+ NpgsqlRowDescriptionFieldData fd;
+
+ // Now, iterate through each field getting its data.
+ for (Int16 i = 0; i < num_fields; i++)
+ {
+ fd = new NpgsqlRowDescriptionFieldData();
+
+ // Set field name.
+ fd.name = PGUtil.ReadString(input_stream, encoding);
+
+ // Read type_oid(Int32), type_size(Int16), type_modifier(Int32)
+ input_stream.Read(input_buffer, 0, 4 + 2 + 4);
+
+ fd.type_oid = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
+ fd.type_size = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(input_buffer, 4));
+ fd.type_modifier = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 6));
+
+ // Add field data to array.
+ fields_data.Add(fd);
+
+ fields_index.Add(fd.name, i);
+ }
+ }
+ else
+ {
+ Byte[] input_buffer = new Byte[4]; // Max read will be 4 + 2 + 4 + 2 + 4 + 2
+
+ // Read the length of message.
+ // [TODO] Any use for now?
+ PGUtil.ReadInt32(input_stream, input_buffer);
+ Int16 num_fields = PGUtil.ReadInt16(input_stream, input_buffer);
+
+ // Temporary FieldData object to get data from stream and put in array.
+ NpgsqlRowDescriptionFieldData fd;
+
+ for (Int16 i = 0; i < num_fields; i++)
+ {
+ fd = new NpgsqlRowDescriptionFieldData();
+
+ fd.name = PGUtil.ReadString(input_stream, encoding);
+ fd.table_oid = PGUtil.ReadInt32(input_stream, input_buffer);
+ fd.column_attribute_number = PGUtil.ReadInt16(input_stream, input_buffer);
+ fd.type_oid = PGUtil.ReadInt32(input_stream, input_buffer);
+ fd.type_size = PGUtil.ReadInt16(input_stream, input_buffer);
+ fd.type_modifier = PGUtil.ReadInt32(input_stream, input_buffer);
+ fd.format_code = (FormatCode)PGUtil.ReadInt16(input_stream, input_buffer);
+
+ fields_data.Add(fd);
+ fields_index.Add(fd.name, i);
+ }
+
+ }
+
+
+ }
+
+ public NpgsqlRowDescriptionFieldData this[Int32 index]
+ {
+ get
+ {
+ return (NpgsqlRowDescriptionFieldData)fields_data[index];
+ }
+
+ }
+
+ public Int16 NumFields
+ {
+ get
+ {
+ return (Int16)fields_data.Count;
+ }
+ }
+
+ public Int16 FieldIndex(String fieldName)
+ {
+ return (Int16) fields_index[fieldName];
+ }
+
+ }
+
}
// Npgsql.NpgsqlStartupPacket.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- /// <summary>
- /// This class represents a StartupPacket message of PostgreSQL
- /// protocol.
- /// </summary>
- ///
- internal sealed class NpgsqlStartupPacket
- {
-
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlStartupPacket";
-
- // Private fields.
- private Int32 packet_size;
- private Int32 protocol_version;
- private String database_name;
- private String user_name;
- private String arguments;
- private String unused;
- private String optional_tty;
-
- public NpgsqlStartupPacket(Int32 packet_size,
- Int32 protocol_version_major,
- Int32 protocol_version_minor,
- String database_name,
- String user_name,
- String arguments,
- String unused,
- String optional_tty)
- {
-
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
- // Just copy the values.
-
- // [FIXME] Validate params? We are the only clients, so, hopefully, we
- // know what to send.
-
- this.packet_size = packet_size;
- this.protocol_version = (protocol_version_major<<16) | protocol_version_minor;
- this.database_name = database_name;
- this.user_name = user_name;
- this.arguments = arguments;
- this.unused = unused;
- this.optional_tty = optional_tty;
-
- }
-
-
- public void WriteToStream(Stream output_stream, Encoding encoding)
- {
-
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteToStream");
-
- // [FIXME] Need exception handling ?
-
- if (protocol_version == ProtocolVersion.Version2) // Protocol 2.0
- {
-
- // Packet length = 296
- output_stream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(this.packet_size)), 0, 4);
-
- // Protocol version = 2.0
- output_stream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(this.protocol_version)), 0, 4);
-
- // Database name.
- PGUtil.WriteLimString(this.database_name, 64, output_stream, encoding);
-
- // User name.
- PGUtil.WriteLimString(this.user_name, 32, output_stream, encoding);
-
- // Arguments.
- PGUtil.WriteLimString(this.arguments, 64, output_stream, encoding);
-
- // Unused.
- PGUtil.WriteLimString(this.unused, 64, output_stream, encoding);
-
- // Optional tty.
- PGUtil.WriteLimString(this.optional_tty, 64, output_stream, encoding);
- output_stream.Flush();
-
- }
-
- if (protocol_version >= ProtocolVersion.Version3) // Protocol 3+
- {
- PGUtil.WriteInt32(output_stream, 4 + 4 + 5 + encoding.GetByteCount(user_name) + 1 + 9 + encoding.GetByteCount(database_name) + 1 + 1);
-
- // Protocol version = 3.0
-
- PGUtil.WriteInt32(output_stream, this.protocol_version);
-
- // User name.
-
- PGUtil.WriteString("user", output_stream, encoding);
-
- // User name.
- PGUtil.WriteString(user_name, output_stream, encoding);
-
- // Database name.
- PGUtil.WriteString("database", output_stream, encoding);
-
- // Database name.
- PGUtil.WriteString(database_name, output_stream, encoding);
-
- output_stream.WriteByte(0);
- output_stream.Flush();
-
- }
-
-
-
-
- }
- }
+
+ /// <summary>
+ /// This class represents a StartupPacket message of PostgreSQL
+ /// protocol.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlStartupPacket
+ {
+
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlStartupPacket";
+
+ // Private fields.
+ private Int32 packet_size;
+ private Int32 protocol_version;
+ private String database_name;
+ private String user_name;
+ private String arguments;
+ private String unused;
+ private String optional_tty;
+
+ public NpgsqlStartupPacket(Int32 packet_size,
+ Int32 protocol_version_major,
+ Int32 protocol_version_minor,
+ String database_name,
+ String user_name,
+ String arguments,
+ String unused,
+ String optional_tty)
+ {
+
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
+ // Just copy the values.
+
+ // [FIXME] Validate params? We are the only clients, so, hopefully, we
+ // know what to send.
+
+ this.packet_size = packet_size;
+ this.protocol_version = (protocol_version_major<<16) | protocol_version_minor;
+ this.database_name = database_name;
+ this.user_name = user_name;
+ this.arguments = arguments;
+ this.unused = unused;
+ this.optional_tty = optional_tty;
+
+ }
+
+
+ public void WriteToStream(Stream output_stream, Encoding encoding)
+ {
+
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteToStream");
+
+ // [FIXME] Need exception handling ?
+
+ if (protocol_version == ProtocolVersion.Version2) // Protocol 2.0
+ {
+
+ // Packet length = 296
+ output_stream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(this.packet_size)), 0, 4);
+
+ // Protocol version = 2.0
+ output_stream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(this.protocol_version)), 0, 4);
+
+ // Database name.
+ PGUtil.WriteLimString(this.database_name, 64, output_stream, encoding);
+
+ // User name.
+ PGUtil.WriteLimString(this.user_name, 32, output_stream, encoding);
+
+ // Arguments.
+ PGUtil.WriteLimString(this.arguments, 64, output_stream, encoding);
+
+ // Unused.
+ PGUtil.WriteLimString(this.unused, 64, output_stream, encoding);
+
+ // Optional tty.
+ PGUtil.WriteLimString(this.optional_tty, 64, output_stream, encoding);
+ output_stream.Flush();
+
+ }
+
+ if (protocol_version >= ProtocolVersion.Version3) // Protocol 3+
+ {
+ PGUtil.WriteInt32(output_stream, 4 + 4 + 5 + encoding.GetByteCount(user_name) + 1 + 9 + encoding.GetByteCount(database_name) + 1 + 1);
+
+ // Protocol version = 3.0
+
+ PGUtil.WriteInt32(output_stream, this.protocol_version);
+
+ // User name.
+
+ PGUtil.WriteString("user", output_stream, encoding);
+
+ // User name.
+ PGUtil.WriteString(user_name, output_stream, encoding);
+
+ // Database name.
+ PGUtil.WriteString("database", output_stream, encoding);
+
+ // Database name.
+ PGUtil.WriteString(database_name, output_stream, encoding);
+
+ output_stream.WriteByte(0);
+ output_stream.Flush();
+
+ }
+
+
+
+
+ }
+ }
}
// Npgsql.NpgsqlStartupState.cs
-//
+//
// Author:
// Dave Joyner <d4ljoyn@yahoo.com>
//
// 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
namespace Npgsql
{
-
-
- internal sealed class NpgsqlStartupState : NpgsqlState
- {
- private static NpgsqlStartupState _instance = null;
-
+
+
+ internal sealed class NpgsqlStartupState : NpgsqlState
+ {
+ private static NpgsqlStartupState _instance = null;
+
private readonly String CLASSNAME = "NpgsqlStartupState";
-
- private NpgsqlStartupState() : base() { }
-
- public static NpgsqlStartupState Instance
- {
- get
- {
- if ( _instance == null )
- {
- _instance = new NpgsqlStartupState();
- }
- return _instance;
- }
- }
- public override void Authenticate( NpgsqlConnection context, string password)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Authenticate");
- NpgsqlPasswordPacket pwpck = new NpgsqlPasswordPacket(password, context.BackendProtocolVersion);
- BufferedStream stream = context.BufferedStream;
- pwpck.WriteToStream(stream, context.Encoding);
- stream.Flush();
-
- }
- }
+
+ private NpgsqlStartupState() : base()
+ { }
+
+ public static NpgsqlStartupState Instance
+ {
+ get
+ {
+ if ( _instance == null )
+ {
+ _instance = new NpgsqlStartupState();
+ }
+ return _instance;
+ }
+ }
+ public override void Authenticate( NpgsqlConnection context, string password)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Authenticate");
+ NpgsqlPasswordPacket pwpck = new NpgsqlPasswordPacket(password, context.BackendProtocolVersion);
+ BufferedStream stream = new BufferedStream(context.Stream);
+ pwpck.WriteToStream(stream, context.Encoding);
+ stream.Flush();
+
+ }
+ }
}
// created on 6/14/2002 at 7:56 PM
// Npgsql.NpgsqlState.cs
-//
+//
// Author:
// Dave Joyner <d4ljoyn@yahoo.com>
//
// 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
namespace Npgsql
{
- ///<summary> This class represents the base class for the state pattern design pattern
- /// implementation.
- /// </summary>
- ///
-
- internal abstract class NpgsqlState
- {
+ ///<summary> This class represents the base class for the state pattern design pattern
+ /// implementation.
+ /// </summary>
+ ///
+
+ internal abstract class NpgsqlState
+ {
private readonly String CLASSNAME = "NpgsqlState";
protected ResourceManager resman = null;
-
- public virtual void Open(NpgsqlConnection context) {}
- public virtual void Startup(NpgsqlConnection context) {}
- public virtual void Authenticate(NpgsqlConnection context, string password){}
- public virtual void Query(NpgsqlConnection context, NpgsqlCommand command) {}
- public virtual void Ready( NpgsqlConnection context ) {}
- public virtual void FunctionCall(NpgsqlConnection context, NpgsqlCommand command){}
- public virtual void Parse(NpgsqlConnection context, NpgsqlParse parse){}
- public virtual void Flush(NpgsqlConnection context){}
- public virtual void Sync(NpgsqlConnection context){}
- public virtual void Bind(NpgsqlConnection context, NpgsqlBind bind){}
- public virtual void Execute(NpgsqlConnection context, NpgsqlExecute execute){}
-
+
+ public virtual void Open(NpgsqlConnection context)
+ {}
+ public virtual void Startup(NpgsqlConnection context)
+ {}
+ public virtual void Authenticate(NpgsqlConnection context, string password)
+ {}
+ public virtual void Query(NpgsqlConnection context, NpgsqlCommand command)
+ {}
+ public virtual void Ready( NpgsqlConnection context )
+ {}
+ public virtual void FunctionCall(NpgsqlConnection context, NpgsqlCommand command)
+ {}
+ public virtual void Parse(NpgsqlConnection context, NpgsqlParse parse)
+ {}
+ public virtual void Flush(NpgsqlConnection context)
+ {}
+ public virtual void Sync(NpgsqlConnection context)
+ {}
+ public virtual void Bind(NpgsqlConnection context, NpgsqlBind bind)
+ {}
+ public virtual void Execute(NpgsqlConnection context, NpgsqlExecute execute)
+ {}
+
public NpgsqlState()
{
resman = new ResourceManager(this.GetType());
}
-
- public virtual void Close( NpgsqlConnection context )
- {
+
+ public virtual void Close( NpgsqlConnection context )
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Close");
- if ( context.State == ConnectionState.Open )
- {
- Stream stream = context.NormalStream;
- if ( stream.CanWrite )
- {
- stream.WriteByte((Byte)'X');
- if (context.BackendProtocolVersion >= ProtocolVersion.Version3)
- PGUtil.WriteInt32(stream, 4);
- stream.Flush();
- }
- }
- ChangeState( context, NpgsqlClosedState.Instance );
- }
-
- ///<summary> This method is used by the states to change the state of the context.
- /// </summary>
- ///
-
- protected virtual void ChangeState(NpgsqlConnection context, NpgsqlState newState)
- {
+ if ( context.State == ConnectionState.Open )
+ {
+ Stream stream = context.Stream;
+ if ( stream.CanWrite )
+ {
+ stream.WriteByte((Byte)'X');
+ if (context.BackendProtocolVersion >= ProtocolVersion.Version3)
+ PGUtil.WriteInt32(stream, 4);
+ stream.Flush();
+ }
+ }
+ ChangeState( context, NpgsqlClosedState.Instance );
+ }
+
+ ///<summary> This method is used by the states to change the state of the context.
+ /// </summary>
+ ///
+
+ protected virtual void ChangeState(NpgsqlConnection context, NpgsqlState newState)
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ChangeState");
- context.CurrentState = newState;
- }
-
- ///<summary>
- /// This method is responsible to handle all protocol messages sent from the backend.
- /// It holds all the logic to do it.
- /// To exchange data, it uses a Mediator object from which it reads/writes information
- /// to handle backend requests.
- /// </summary>
- ///
-
- protected virtual void ProcessBackendResponses( NpgsqlConnection context )
- {
+ context.CurrentState = newState;
+ }
+
+ ///<summary>
+ /// This method is responsible to handle all protocol messages sent from the backend.
+ /// It holds all the logic to do it.
+ /// To exchange data, it uses a Mediator object from which it reads/writes information
+ /// to handle backend requests.
+ /// </summary>
+ ///
+
+ protected virtual void ProcessBackendResponses( NpgsqlConnection context )
+ {
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ProcessBackendResponses");
-
- BufferedStream stream = context.BufferedStream;
- Int32 authType;
- Boolean readyForQuery = false;
-
- NpgsqlMediator mediator = context.Mediator;
-
- // Reset the mediator.
- mediator.Reset();
-
- Int16 rowDescNumFields = 0;
- NpgsqlRowDescription rd = null;
-
- Byte[] inputBuffer = new Byte[ 500 ];
-
-
- while (!readyForQuery)
- {
- // Check the first Byte of response.
- switch ( stream.ReadByte() )
- {
- case NpgsqlMessageTypes.ErrorResponse :
-
- NpgsqlError error = new NpgsqlError(context.BackendProtocolVersion);
- error.ReadFromStream(stream, context.Encoding);
-
- //mediator.Errors.Add(errorMessage);
- mediator.Errors.Add(error.Message);
-
- NpgsqlEventLog.LogMsg(resman, "Log_ErrorResponse", LogLevel.Debug, error.Message);
-
- // Return imediately if it is in the startup state or connected state as
- // there is no more messages to consume.
- // Possible error in the NpgsqlStartupState:
- // Invalid password.
- // Possible error in the NpgsqlConnectedState:
- // No pg_hba.conf configured.
-
- if ((context.CurrentState == NpgsqlStartupState.Instance) ||
- (context.CurrentState == NpgsqlConnectedState.Instance))
- return;
-
- break;
-
-
- case NpgsqlMessageTypes.AuthenticationRequest :
-
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "AuthenticationRequest");
-
- stream.Read(inputBuffer, 0, 4);
-
- if (context.BackendProtocolVersion >= ProtocolVersion.Version3)
- stream.Read(inputBuffer, 0, 4);
-
- authType = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(inputBuffer, 0));
-
- if ( authType == NpgsqlMessageTypes.AuthenticationOk )
- {
- NpgsqlEventLog.LogMsg(resman, "Log_AuthenticationOK", LogLevel.Debug);
-
- break;
- }
-
- if ( authType == NpgsqlMessageTypes.AuthenticationClearTextPassword )
- {
- NpgsqlEventLog.LogMsg(resman, "Log_AuthenticationClearTextRequest", LogLevel.Debug);
-
- // Send the PasswordPacket.
-
- ChangeState( context, NpgsqlStartupState.Instance );
- context.Authenticate(context.ServerPassword);
-
- break;
- }
-
-
- if ( authType == NpgsqlMessageTypes.AuthenticationMD5Password )
- {
- NpgsqlEventLog.LogMsg(resman, "Log_AuthenticationMD5Request", LogLevel.Debug);
- // Now do the "MD5-Thing"
- // for this the Password has to be:
- // 1. md5-hashed with the username as salt
- // 2. md5-hashed again with the salt we get from the backend
-
-
- MD5 md5 = MD5.Create();
-
-
- // 1.
- byte[] passwd = context.Encoding.GetBytes(context.ServerPassword);
- byte[] saltUserName = context.Encoding.GetBytes(context.UserName);
-
- byte[] crypt_buf = new byte[passwd.Length + saltUserName.Length];
-
- passwd.CopyTo(crypt_buf, 0);
- saltUserName.CopyTo(crypt_buf, passwd.Length);
-
-
-
- StringBuilder sb = new StringBuilder ();
- byte[] hashResult = md5.ComputeHash(crypt_buf);
- foreach (byte b in hashResult)
- sb.Append (b.ToString ("x2"));
-
-
- String prehash = sb.ToString();
-
- byte[] prehashbytes = context.Encoding.GetBytes(prehash);
-
-
-
- byte[] saltServer = new byte[4];
- stream.Read(saltServer, 0, 4);
- // Send the PasswordPacket.
- ChangeState( context, NpgsqlStartupState.Instance );
-
-
- // 2.
-
- crypt_buf = new byte[prehashbytes.Length + saltServer.Length];
- prehashbytes.CopyTo(crypt_buf, 0);
- saltServer.CopyTo(crypt_buf, prehashbytes.Length);
-
- sb = new StringBuilder ("md5"); // This is needed as the backend expects md5 result starts with "md5"
- hashResult = md5.ComputeHash(crypt_buf);
- foreach (byte b in hashResult)
- sb.Append (b.ToString ("x2"));
-
- context.Authenticate(sb.ToString ());
-
- break;
- }
-
- // Only AuthenticationClearTextPassword and AuthenticationMD5Password supported for now.
+
+ BufferedStream stream = new BufferedStream(context.Stream);
+ Int32 authType;
+ Boolean readyForQuery = false;
+
+ NpgsqlMediator mediator = context.Mediator;
+
+ // Reset the mediator.
+ mediator.Reset();
+
+ Int16 rowDescNumFields = 0;
+ NpgsqlRowDescription rd = null;
+
+ Byte[] inputBuffer = new Byte[ 500 ];
+
+
+ while (!readyForQuery)
+ {
+ // Check the first Byte of response.
+ switch ( stream.ReadByte() )
+ {
+ case NpgsqlMessageTypes.ErrorResponse :
+
+ NpgsqlError error = new NpgsqlError(context.BackendProtocolVersion);
+ error.ReadFromStream(stream, context.Encoding);
+
+ //mediator.Errors.Add(errorMessage);
+ mediator.Errors.Add(error.Message);
+
+ NpgsqlEventLog.LogMsg(resman, "Log_ErrorResponse", LogLevel.Debug, error.Message);
+
+ // Return imediately if it is in the startup state or connected state as
+ // there is no more messages to consume.
+ // Possible error in the NpgsqlStartupState:
+ // Invalid password.
+ // Possible error in the NpgsqlConnectedState:
+ // No pg_hba.conf configured.
+
+ if ((context.CurrentState == NpgsqlStartupState.Instance) ||
+ (context.CurrentState == NpgsqlConnectedState.Instance))
+ return;
+
+ break;
+
+
+ case NpgsqlMessageTypes.AuthenticationRequest :
+
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "AuthenticationRequest");
+
+ stream.Read(inputBuffer, 0, 4);
+
+ if (context.BackendProtocolVersion >= ProtocolVersion.Version3)
+ stream.Read(inputBuffer, 0, 4);
+
+ authType = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(inputBuffer, 0));
+
+ if ( authType == NpgsqlMessageTypes.AuthenticationOk )
+ {
NpgsqlEventLog.LogMsg(resman, "Log_AuthenticationOK", LogLevel.Debug);
- mediator.Errors.Add(String.Format(resman.GetString("Exception_AuthenticationMethodNotSupported"), authType));
- return;
-
- case NpgsqlMessageTypes.RowDescription:
- // This is the RowDescription message.
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "RowDescription");
- rd = new NpgsqlRowDescription(context.BackendProtocolVersion);
- rd.ReadFromStream(stream, context.Encoding);
-
- // Initialize the array list which will contain the data from this rowdescription.
- //rows = new ArrayList();
-
- rowDescNumFields = rd.NumFields;
- mediator.AddRowDescription(rd);
-
-
- // Now wait for the AsciiRow messages.
- break;
-
- case NpgsqlMessageTypes.AsciiRow:
-
- // This is the AsciiRow message.
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "AsciiRow");
- NpgsqlAsciiRow asciiRow = new NpgsqlAsciiRow(rd, context.OidToNameMapping, context.BackendProtocolVersion);
- asciiRow.ReadFromStream(stream, context.Encoding);
-
-
- // Add this row to the rows array.
- //rows.Add(ascii_row);
- mediator.AddAsciiRow(asciiRow);
-
- // Now wait for CompletedResponse message.
- break;
-
- case NpgsqlMessageTypes.BinaryRow:
-
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "BinaryRow");
- NpgsqlBinaryRow binaryRow = new NpgsqlBinaryRow(rd);
- binaryRow.ReadFromStream(stream, context.Encoding);
-
- mediator.AddBinaryRow(binaryRow);
-
- break;
-
- case NpgsqlMessageTypes.ReadyForQuery :
-
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "ReadyForQuery");
- readyForQuery = true;
- ChangeState( context, NpgsqlReadyState.Instance );
- break;
-
- case NpgsqlMessageTypes.BackendKeyData :
-
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "BackendKeyData");
- // BackendKeyData message.
- NpgsqlBackEndKeyData backend_keydata = new NpgsqlBackEndKeyData(context.BackendProtocolVersion);
- backend_keydata.ReadFromStream(stream);
- mediator.AddBackendKeydata(backend_keydata);
-
-
- // Wait for ReadForQuery message
- break;;
-
- case NpgsqlMessageTypes.NoticeResponse :
-
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "NoticeResponse");
- String noticeResponse = PGUtil.ReadString( stream, context.Encoding );
-
- // Wait for ReadForQuery message
- break;
-
- case NpgsqlMessageTypes.CompletedResponse :
- // This is the CompletedResponse message.
- // Get the string returned.
-
-
- if (context.BackendProtocolVersion >= ProtocolVersion.Version3)
- PGUtil.ReadInt32(stream, new Byte[4]);
-
- String result = PGUtil.ReadString(stream, context.Encoding);
-
- NpgsqlEventLog.LogMsg(resman, "Log_CompletedResponse", LogLevel.Debug, result);
- // Add result from the processing.
-
- mediator.AddCompletedResponse(result);
-
- // Now wait for ReadyForQuery message.
- break;
-
- case NpgsqlMessageTypes.CursorResponse :
- // This is the cursor response message.
- // It is followed by a C NULL terminated string with the name of
- // the cursor in a FETCH case or 'blank' otherwise.
- // In this case it should be always 'blank'.
- // [FIXME] Get another name for this function.
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "CursorResponse");
-
- String cursorName = PGUtil.ReadString(stream, context.Encoding);
- // Continue waiting for ReadyForQuery message.
- break;
-
- case NpgsqlMessageTypes.ParseComplete :
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "ParseComplete");
- // Just read up the message length.
- PGUtil.ReadInt32(stream, new Byte[4]);
- readyForQuery = true;
+
+ break;
+ }
+
+ if ( authType == NpgsqlMessageTypes.AuthenticationClearTextPassword )
+ {
+ NpgsqlEventLog.LogMsg(resman, "Log_AuthenticationClearTextRequest", LogLevel.Debug);
+
+ // Send the PasswordPacket.
+
+ ChangeState( context, NpgsqlStartupState.Instance );
+ context.Authenticate(context.ServerPassword);
+
+ break;
+ }
+
+
+ if ( authType == NpgsqlMessageTypes.AuthenticationMD5Password )
+ {
+ NpgsqlEventLog.LogMsg(resman, "Log_AuthenticationMD5Request", LogLevel.Debug);
+ // Now do the "MD5-Thing"
+ // for this the Password has to be:
+ // 1. md5-hashed with the username as salt
+ // 2. md5-hashed again with the salt we get from the backend
+
+
+ MD5 md5 = MD5.Create();
+
+
+ // 1.
+ byte[] passwd = context.Encoding.GetBytes(context.ServerPassword);
+ byte[] saltUserName = context.Encoding.GetBytes(context.UserName);
+
+ byte[] crypt_buf = new byte[passwd.Length + saltUserName.Length];
+
+ passwd.CopyTo(crypt_buf, 0);
+ saltUserName.CopyTo(crypt_buf, passwd.Length);
+
+
+
+ StringBuilder sb = new StringBuilder ();
+ byte[] hashResult = md5.ComputeHash(crypt_buf);
+ foreach (byte b in hashResult)
+ sb.Append (b.ToString ("x2"));
+
+
+ String prehash = sb.ToString();
+
+ byte[] prehashbytes = context.Encoding.GetBytes(prehash);
+
+
+
+ byte[] saltServer = new byte[4];
+ stream.Read(saltServer, 0, 4);
+ // Send the PasswordPacket.
+ ChangeState( context, NpgsqlStartupState.Instance );
+
+
+ // 2.
+
+ crypt_buf = new byte[prehashbytes.Length + saltServer.Length];
+ prehashbytes.CopyTo(crypt_buf, 0);
+ saltServer.CopyTo(crypt_buf, prehashbytes.Length);
+
+ sb = new StringBuilder ("md5"); // This is needed as the backend expects md5 result starts with "md5"
+ hashResult = md5.ComputeHash(crypt_buf);
+ foreach (byte b in hashResult)
+ sb.Append (b.ToString ("x2"));
+
+ context.Authenticate(sb.ToString ());
+
break;
-
- case NpgsqlMessageTypes.BindComplete :
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "BindComplete");
- // Just read up the message length.
+ }
+
+ // Only AuthenticationClearTextPassword and AuthenticationMD5Password supported for now.
+ NpgsqlEventLog.LogMsg(resman, "Log_AuthenticationOK", LogLevel.Debug);
+ mediator.Errors.Add(String.Format(resman.GetString("Exception_AuthenticationMethodNotSupported"), authType));
+ return;
+
+ case NpgsqlMessageTypes.RowDescription:
+ // This is the RowDescription message.
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "RowDescription");
+ rd = new NpgsqlRowDescription(context.BackendProtocolVersion);
+ rd.ReadFromStream(stream, context.Encoding);
+
+ // Initialize the array list which will contain the data from this rowdescription.
+ //rows = new ArrayList();
+
+ rowDescNumFields = rd.NumFields;
+ mediator.AddRowDescription(rd);
+
+
+ // Now wait for the AsciiRow messages.
+ break;
+
+ case NpgsqlMessageTypes.AsciiRow:
+
+ // This is the AsciiRow message.
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "AsciiRow");
+ NpgsqlAsciiRow asciiRow = new NpgsqlAsciiRow(rd, context.OidToNameMapping, context.BackendProtocolVersion);
+ asciiRow.ReadFromStream(stream, context.Encoding);
+
+
+ // Add this row to the rows array.
+ //rows.Add(ascii_row);
+ mediator.AddAsciiRow(asciiRow);
+
+ // Now wait for CompletedResponse message.
+ break;
+
+ case NpgsqlMessageTypes.BinaryRow:
+
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "BinaryRow");
+ NpgsqlBinaryRow binaryRow = new NpgsqlBinaryRow(rd);
+ binaryRow.ReadFromStream(stream, context.Encoding);
+
+ mediator.AddBinaryRow(binaryRow);
+
+ break;
+
+ case NpgsqlMessageTypes.ReadyForQuery :
+
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "ReadyForQuery");
+ readyForQuery = true;
+ ChangeState( context, NpgsqlReadyState.Instance );
+ break;
+
+ case NpgsqlMessageTypes.BackendKeyData :
+
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "BackendKeyData");
+ // BackendKeyData message.
+ NpgsqlBackEndKeyData backend_keydata = new NpgsqlBackEndKeyData(context.BackendProtocolVersion);
+ backend_keydata.ReadFromStream(stream);
+ mediator.AddBackendKeydata(backend_keydata);
+
+
+ // Wait for ReadForQuery message
+ break;
+ ;
+
+ case NpgsqlMessageTypes.NoticeResponse :
+
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "NoticeResponse");
+ String noticeResponse = PGUtil.ReadString( stream, context.Encoding );
+
+ // Wait for ReadForQuery message
+ break;
+
+ case NpgsqlMessageTypes.CompletedResponse :
+ // This is the CompletedResponse message.
+ // Get the string returned.
+
+
+ if (context.BackendProtocolVersion >= ProtocolVersion.Version3)
PGUtil.ReadInt32(stream, new Byte[4]);
- readyForQuery = true;
- break;
-
- case NpgsqlMessageTypes.EmptyQueryResponse :
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "EmptyQueryResponse");
- // This is the EmptyQueryResponse.
- // [FIXME] Just ignore it this way?
- // networkStream.Read(inputBuffer, 0, 1);
- //GetStringFromNetStream(networkStream);
- PGUtil.ReadString(stream, context.Encoding);
- break;
-
- case NpgsqlMessageTypes.NotificationResponse :
-
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "NotificationResponse");
-
- Byte[] input_buffer = new Byte[4];
- stream.Read(input_buffer, 0, 4);
- Int32 PID = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
- String notificationResponse = PGUtil.ReadString( stream, context.Encoding );
- mediator.AddNotification(new NpgsqlNotificationEventArgs(PID, notificationResponse));
-
- // Wait for ReadForQuery message
- break;
-
- case NpgsqlMessageTypes.ParameterStatus :
- NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "ParameterStatus");
- NpgsqlParameterStatus parameterStatus = new NpgsqlParameterStatus();
- parameterStatus.ReadFromStream(stream, context.Encoding);
-
- NpgsqlEventLog.LogMsg(resman, "Log_ParameterStatus", LogLevel.Debug, parameterStatus.Parameter, parameterStatus.ParameterValue);
- if (parameterStatus.Parameter == "server_version")
- context.ServerVersion = parameterStatus.ParameterValue;
- break;
- }
- }
-
- }
- }
-
-
-
+
+ String result = PGUtil.ReadString(stream, context.Encoding);
+
+ NpgsqlEventLog.LogMsg(resman, "Log_CompletedResponse", LogLevel.Debug, result);
+ // Add result from the processing.
+
+ mediator.AddCompletedResponse(result);
+
+ // Now wait for ReadyForQuery message.
+ break;
+
+ case NpgsqlMessageTypes.CursorResponse :
+ // This is the cursor response message.
+ // It is followed by a C NULL terminated string with the name of
+ // the cursor in a FETCH case or 'blank' otherwise.
+ // In this case it should be always 'blank'.
+ // [FIXME] Get another name for this function.
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "CursorResponse");
+
+ String cursorName = PGUtil.ReadString(stream, context.Encoding);
+ // Continue waiting for ReadyForQuery message.
+ break;
+
+ case NpgsqlMessageTypes.ParseComplete :
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "ParseComplete");
+ // Just read up the message length.
+ PGUtil.ReadInt32(stream, new Byte[4]);
+ readyForQuery = true;
+ break;
+
+ case NpgsqlMessageTypes.BindComplete :
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "BindComplete");
+ // Just read up the message length.
+ PGUtil.ReadInt32(stream, new Byte[4]);
+ readyForQuery = true;
+ break;
+
+ case NpgsqlMessageTypes.EmptyQueryResponse :
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "EmptyQueryResponse");
+ // This is the EmptyQueryResponse.
+ // [FIXME] Just ignore it this way?
+ // networkStream.Read(inputBuffer, 0, 1);
+ //GetStringFromNetStream(networkStream);
+ PGUtil.ReadString(stream, context.Encoding);
+ break;
+
+ case NpgsqlMessageTypes.NotificationResponse :
+
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "NotificationResponse");
+
+ Byte[] input_buffer = new Byte[4];
+ stream.Read(input_buffer, 0, 4);
+ Int32 PID = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
+ String notificationResponse = PGUtil.ReadString( stream, context.Encoding );
+ mediator.AddNotification(new NpgsqlNotificationEventArgs(PID, notificationResponse));
+
+ // Wait for ReadForQuery message
+ break;
+
+ case NpgsqlMessageTypes.ParameterStatus :
+ NpgsqlEventLog.LogMsg(resman, "Log_ProtocolMessage", LogLevel.Debug, "ParameterStatus");
+ NpgsqlParameterStatus parameterStatus = new NpgsqlParameterStatus();
+ parameterStatus.ReadFromStream(stream, context.Encoding);
+
+ NpgsqlEventLog.LogMsg(resman, "Log_ParameterStatus", LogLevel.Debug, parameterStatus.Parameter, parameterStatus.ParameterValue);
+ if (parameterStatus.Parameter == "server_version")
+ context.ServerVersion = parameterStatus.ParameterValue;
+ break;
+ }
+ }
+
+ }
+ }
+
+
+
}
// created on 1/7/2003 at 20:58
// Npgsql.NpgsqlSync.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
- /// <summary>
- /// This class represents the Parse message sent to PostgreSQL
- /// server.
- /// </summary>
- ///
- internal sealed class NpgsqlSync
- {
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlSync";
-
- public void WriteToStream(Stream outputStream, Encoding encoding)
- {
- outputStream.WriteByte((Byte)'S');
-
- PGUtil.WriteInt32(outputStream, 4);
-
- }
-
- }
+
+ /// <summary>
+ /// This class represents the Parse message sent to PostgreSQL
+ /// server.
+ /// </summary>
+ ///
+ internal sealed class NpgsqlSync
+ {
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlSync";
+
+ public void WriteToStream(Stream outputStream, Encoding encoding)
+ {
+ outputStream.WriteByte((Byte)'S');
+
+ PGUtil.WriteInt32(outputStream, 4);
+
+ }
+
+ }
}
-
+
// created on 17/11/2002 at 19:04
// Npgsql.NpgsqlTransaction.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
- /// <summary>
-
- /// Represents a transaction to be made in a PostgreSQL database. This class cannot be inherited.
-
- /// </summary>
- public sealed class NpgsqlTransaction : MarshalByRefObject, IDbTransaction
- {
-
- private static readonly String CLASSNAME = "NpgsqlTransaction";
-
- private NpgsqlConnection _conn = null;
- private IsolationLevel _isolation = IsolationLevel.ReadCommitted;
- private bool _disposing = false;
- private System.Resources.ResourceManager resman;
-
-
-
-
- internal NpgsqlTransaction(NpgsqlConnection conn) : this(conn, IsolationLevel.ReadCommitted)
- {
-
- }
-
- internal NpgsqlTransaction(NpgsqlConnection conn, IsolationLevel isolation)
- {
- resman = new System.Resources.ResourceManager(this.GetType());
-
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
- if ((isolation != IsolationLevel.ReadCommitted) &&
- (isolation != IsolationLevel.Serializable))
- throw new ArgumentException(resman.GetString("Exception_UnsopportedIsolationLevel"), "isolation");
-
- _conn = conn;
- _isolation = isolation;
-
- StringBuilder commandText = new StringBuilder("SET TRANSACTION ISOLATION LEVEL ");
-
- if (isolation == IsolationLevel.ReadCommitted)
- commandText.Append("READ COMMITTED");
- else
- commandText.Append("SERIALIZABLE");
-
- commandText.Append("; BEGIN");
-
-
- NpgsqlCommand command = new NpgsqlCommand(commandText.ToString(), conn);
- command.ExecuteNonQuery();
- _conn.InTransaction = true;
-
- }
-
- /// <summary>
- /// Gets the <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>
- /// object associated with the transaction, or a null reference if the
- /// transaction is no longer valid.
- /// </summary>
- /// <value>The <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>
- /// object associated with the transaction.</value>
- public NpgsqlConnection Connection
- {
- get
- {
- return _conn;
- }
-
- }
-
-
- IDbConnection IDbTransaction.Connection
- {
- get
- {
- return Connection;
- }
- }
-
- /// <summary>
- /// Specifies the <see cref="System.Data.IsolationLevel">IsolationLevel</see> for this transaction.
- /// </summary>
- /// <value>The <see cref="System.Data.IsolationLevel">IsolationLevel</see> for this transaction.
- /// The default is <b>ReadCommitted</b>.</value>
- public IsolationLevel IsolationLevel
- {
- get
- {
- return _isolation;
- }
- }
-
- /// <summary>
- /// Releases the unmanaged resources used by the
- /// <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>
- /// and optionally releases the managed resources.
- /// </summary>
- public void Dispose()
- {
- this.Dispose(true);
- }
-
- private void Dispose(bool disposing){
- if(disposing == true && this._conn != null){
- this._disposing = true;
- this.Rollback();
- }
- }
-
- /// <summary>
- /// Commits the database transaction.
- /// </summary>
- public void Commit()
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Commit");
- NpgsqlCommand command = new NpgsqlCommand("COMMIT", _conn);
- command.ExecuteNonQuery();
- _conn.InTransaction = false;
- }
-
- /// <summary>
- /// Rolls back a transaction from a pending state.
- /// </summary>
- public void Rollback()
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Rollback");
- NpgsqlCommand command = new NpgsqlCommand("ROLLBACK", _conn);
- command.ExecuteNonQuery();
- _conn.InTransaction = false;
- }
-
- internal bool Disposing{
- get{
- return _disposing;
- }
- }
- }
+ /// <summary>
+
+ /// Represents a transaction to be made in a PostgreSQL database. This class cannot be inherited.
+
+ /// </summary>
+ public sealed class NpgsqlTransaction : MarshalByRefObject, IDbTransaction
+ {
+
+ private static readonly String CLASSNAME = "NpgsqlTransaction";
+
+ private NpgsqlConnection _conn = null;
+ private IsolationLevel _isolation = IsolationLevel.ReadCommitted;
+ private bool _disposing = false;
+ private System.Resources.ResourceManager resman;
+
+
+
+
+ internal NpgsqlTransaction(NpgsqlConnection conn) : this(conn, IsolationLevel.ReadCommitted)
+ {
+ }
+
+ internal NpgsqlTransaction(NpgsqlConnection conn, IsolationLevel isolation)
+ {
+ resman = new System.Resources.ResourceManager(this.GetType());
+
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
+ if ((isolation != IsolationLevel.ReadCommitted) &&
+ (isolation != IsolationLevel.Serializable))
+ throw new ArgumentException(resman.GetString("Exception_UnsopportedIsolationLevel"), "isolation");
+
+ _conn = conn;
+ _isolation = isolation;
+
+ StringBuilder commandText = new StringBuilder("SET TRANSACTION ISOLATION LEVEL ");
+
+ if (isolation == IsolationLevel.ReadCommitted)
+ commandText.Append("READ COMMITTED");
+ else
+ commandText.Append("SERIALIZABLE");
+
+ commandText.Append("; BEGIN");
+
+
+ NpgsqlCommand command = new NpgsqlCommand(commandText.ToString(), conn);
+ command.ExecuteNonQuery();
+ _conn.InTransaction = true;
+
+ }
+
+ /// <summary>
+ /// Gets the <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>
+ /// object associated with the transaction, or a null reference if the
+ /// transaction is no longer valid.
+ /// </summary>
+ /// <value>The <see cref="Npgsql.NpgsqlConnection">NpgsqlConnection</see>
+ /// object associated with the transaction.</value>
+ public NpgsqlConnection Connection
+ {
+ get
+ {
+ return _conn;
+ }
+
+ }
+
+
+ IDbConnection IDbTransaction.Connection
+ {
+ get
+ {
+ return Connection;
+ }
+ }
+
+ /// <summary>
+ /// Specifies the <see cref="System.Data.IsolationLevel">IsolationLevel</see> for this transaction.
+ /// </summary>
+ /// <value>The <see cref="System.Data.IsolationLevel">IsolationLevel</see> for this transaction.
+ /// The default is <b>ReadCommitted</b>.</value>
+ public IsolationLevel IsolationLevel
+ {
+ get
+ {
+ return _isolation;
+ }
+ }
+
+ /// <summary>
+ /// Releases the unmanaged resources used by the
+ /// <see cref="Npgsql.NpgsqlTransaction">NpgsqlTransaction</see>
+ /// and optionally releases the managed resources.
+ /// </summary>
+ public void Dispose()
+ {
+ this.Dispose(true);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if(disposing == true && this._conn != null)
+ {
+ this._disposing = true;
+ this.Rollback();
+ }
+ }
+
+ /// <summary>
+ /// Commits the database transaction.
+ /// </summary>
+ public void Commit()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Commit");
+ NpgsqlCommand command = new NpgsqlCommand("COMMIT", _conn);
+ command.ExecuteNonQuery();
+ _conn.InTransaction = false;
+ }
+
+ /// <summary>
+ /// Rolls back a transaction from a pending state.
+ /// </summary>
+ public void Rollback()
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Rollback");
+ NpgsqlCommand command = new NpgsqlCommand("ROLLBACK", _conn);
+ command.ExecuteNonQuery();
+ _conn.InTransaction = false;
+ }
+
+ internal bool Disposing{
+ get
+ {
+ return _disposing;
+ }
+ }
+ }
}
// created on 1/6/2002 at 22:27
// Npgsql.PGUtil.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
namespace Npgsql
{
-
-
- internal struct ProtocolVersion
- {
- public const Int32 Version2 = 131072;
- public const Int32 Version3 = 196608;
- }
-
- internal enum FormatCode:short
- {
- Text = 0,
- Binary = 1
- }
-
-
- ///<summary>
- /// This class provides many util methods to handle
- /// reading and writing of PostgreSQL protocol messages.
- /// </summary>
- /// [FIXME] Does this name fully represent the class responsability?
- /// Should it be abstract or with a private constructor to prevent
- /// creating instances?
-
- //
- internal sealed class PGUtil
- {
-
- // Logging related values
- private static readonly String CLASSNAME = "PGUtil";
- private static ResourceManager resman = new ResourceManager(typeof(PGUtil));
-
- ///<summary>
- /// This method gets a C NULL terminated string from the network stream.
- /// It keeps reading a byte in each time until a NULL byte is returned.
- /// It returns the resultant string of bytes read.
- /// This string is sent from backend.
- /// </summary>
-
- public static String ReadString(Stream network_stream, Encoding encoding)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadString");
-
- // [FIXME] Is 512 enough?
- Byte[] buffer = new Byte[512];
- Byte b;
- Int16 counter = 0;
-
-
- // [FIXME] Is this cast always safe?
- b = (Byte)network_stream.ReadByte();
- while(b != 0)
- {
- buffer[counter] = b;
- counter++;
- b = (Byte)network_stream.ReadByte();
- }
- String string_read = encoding.GetString(buffer, 0, counter);
+
+
+ internal struct ProtocolVersion
+ {
+ public const Int32 Version2 = 131072;
+ public const Int32 Version3 = 196608;
+ }
+
+internal enum FormatCode:
+ short
+ {
+ Text = 0,
+ Binary = 1
+ }
+
+
+ ///<summary>
+ /// This class provides many util methods to handle
+ /// reading and writing of PostgreSQL protocol messages.
+ /// </summary>
+ /// [FIXME] Does this name fully represent the class responsability?
+ /// Should it be abstract or with a private constructor to prevent
+ /// creating instances?
+
+ //
+ internal sealed class PGUtil
+ {
+
+ // Logging related values
+ private static readonly String CLASSNAME = "PGUtil";
+ private static ResourceManager resman = new ResourceManager(typeof(PGUtil));
+
+ ///<summary>
+ /// This method gets a C NULL terminated string from the network stream.
+ /// It keeps reading a byte in each time until a NULL byte is returned.
+ /// It returns the resultant string of bytes read.
+ /// This string is sent from backend.
+ /// </summary>
+
+ public static String ReadString(Stream network_stream, Encoding encoding)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadString");
+
+ // [FIXME] Is 512 enough?
+ Byte[] buffer = new Byte[512];
+ Byte b;
+ Int16 counter = 0;
+
+
+ // [FIXME] Is this cast always safe?
+ b = (Byte)network_stream.ReadByte();
+ while(b != 0)
+ {
+ buffer[counter] = b;
+ counter++;
+ b = (Byte)network_stream.ReadByte();
+ }
+ String string_read = encoding.GetString(buffer, 0, counter);
NpgsqlEventLog.LogMsg(resman, "Log_StringRead", LogLevel.Debug, string_read);
- return string_read;
- }
-
- ///<summary>
- /// This method writes a C NULL terminated string to the network stream.
- /// It appends a NULL terminator to the end of the String.
- /// </summary>
-
- public static void WriteString(String the_string, Stream network_stream, Encoding encoding)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteString");
-
- network_stream.Write(encoding.GetBytes(the_string + '\x00') , 0, encoding.GetByteCount(the_string) + 1);
- }
-
- ///<summary>
- /// This method writes a C NULL terminated string limited in length to the
- /// backend server.
- /// It pads the string with null bytes to the size specified.
- /// </summary>
-
- public static void WriteLimString(String the_string, Int32 n, Stream network_stream, Encoding encoding)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteLimString");
-
- // [FIXME] Parameters should be validated. And what about strings
- // larger than or equal to n?
-
- // Pad the string to the specified value.
- String string_padded = the_string.PadRight(n, '\x00');
-
- network_stream.Write(encoding.GetBytes(string_padded), 0, n);
- }
-
- public static void CheckedStreamRead(Stream stream, Byte[] buffer, Int32 offset, Int32 size)
- {
- Int32 bytes_from_stream = 0;
- Int32 total_bytes_read = 0;
- do
- {
- bytes_from_stream = stream.Read(buffer, offset + total_bytes_read, size);
- total_bytes_read += bytes_from_stream;
- size -= bytes_from_stream;
- }
- while(size > 0);
-
- }
-
-
- public static void WriteInt32(Stream stream, Int32 value)
- {
- stream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value)), 0, 4);
- }
-
- public static Int32 ReadInt32(Stream stream, Byte[] buffer)
- {
- CheckedStreamRead(stream, buffer, 0, 4);
- return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, 0));
-
- }
-
- public static void WriteInt16(Stream stream, Int16 value)
- {
- stream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value)), 0, 2);
- }
-
- public static Int16 ReadInt16(Stream stream, Byte[] buffer)
- {
- CheckedStreamRead(stream, buffer, 0, 2);
- return IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, 0));
-
- }
-
-
- /*public static void WriteQueryToStream( String query, Stream stream, Encoding encoding )
- {
- NpgsqlEventLog.LogMsg( CLASSNAME + query, LogLevel.Debug );
- // Send the query to server.
- // Write the byte 'Q' to identify a query message.
- stream.WriteByte((Byte)'Q');
-
- // Write the query. In this case it is the CommandText text.
- // It is a string terminated by a C NULL character.
- stream.Write(encoding.GetBytes(query + '\x00') , 0, query.Length + 1);
-
- // Send bytes.
- stream.Flush();
-
- }
-
- public static Int32 ProtocolVersionMajor(Int32 protocolVersion)
- {
- return (protocolVersion >> 16) & 0xffff;
- }
-
- public static Int32 ProtocolVersionMinor(Int32 protocolVersion)
- {
- return protocolVersion & 0xffff;
- }*/
-
-
-
- }
+ return string_read;
+ }
+
+ ///<summary>
+ /// This method writes a C NULL terminated string to the network stream.
+ /// It appends a NULL terminator to the end of the String.
+ /// </summary>
+
+ public static void WriteString(String the_string, Stream network_stream, Encoding encoding)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteString");
+
+ network_stream.Write(encoding.GetBytes(the_string + '\x00') , 0, encoding.GetByteCount(the_string) + 1);
+ }
+
+ ///<summary>
+ /// This method writes a C NULL terminated string limited in length to the
+ /// backend server.
+ /// It pads the string with null bytes to the size specified.
+ /// </summary>
+
+ public static void WriteLimString(String the_string, Int32 n, Stream network_stream, Encoding encoding)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "WriteLimString");
+
+ // [FIXME] Parameters should be validated. And what about strings
+ // larger than or equal to n?
+
+ // Pad the string to the specified value.
+ String string_padded = the_string.PadRight(n, '\x00');
+
+ network_stream.Write(encoding.GetBytes(string_padded), 0, n);
+ }
+
+ public static void CheckedStreamRead(Stream stream, Byte[] buffer, Int32 offset, Int32 size)
+ {
+ Int32 bytes_from_stream = 0;
+ Int32 total_bytes_read = 0;
+ do
+ {
+ bytes_from_stream = stream.Read(buffer, offset + total_bytes_read, size);
+ total_bytes_read += bytes_from_stream;
+ size -= bytes_from_stream;
+ }
+ while(size > 0);
+
+ }
+
+
+ public static void WriteInt32(Stream stream, Int32 value)
+ {
+ stream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value)), 0, 4);
+ }
+
+ public static Int32 ReadInt32(Stream stream, Byte[] buffer)
+ {
+ CheckedStreamRead(stream, buffer, 0, 4);
+ return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, 0));
+
+ }
+
+ public static void WriteInt16(Stream stream, Int16 value)
+ {
+ stream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value)), 0, 2);
+ }
+
+ public static Int16 ReadInt16(Stream stream, Byte[] buffer)
+ {
+ CheckedStreamRead(stream, buffer, 0, 2);
+ return IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, 0));
+
+ }
+
+
+ /*public static void WriteQueryToStream( String query, Stream stream, Encoding encoding )
+ {
+ NpgsqlEventLog.LogMsg( CLASSNAME + query, LogLevel.Debug );
+ // Send the query to server.
+ // Write the byte 'Q' to identify a query message.
+ stream.WriteByte((Byte)'Q');
+
+ // Write the query. In this case it is the CommandText text.
+ // It is a string terminated by a C NULL character.
+ stream.Write(encoding.GetBytes(query + '\x00') , 0, query.Length + 1);
+
+ // Send bytes.
+ stream.Flush();
+
+ }
+
+ public static Int32 ProtocolVersionMajor(Int32 protocolVersion)
+ {
+ return (protocolVersion >> 16) & 0xffff;
+ }
+
+ public static Int32 ProtocolVersionMinor(Int32 protocolVersion)
+ {
+ return protocolVersion & 0xffff;
+ }*/
+
+
+
+ }
}
// NpgsqlTypes.NpgsqlTypesHelper.cs
-//
+//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// 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
/// <summary>
/// This class contains helper methods for type conversion between
-/// the .Net type system and postgresql.
+/// the .Net type system and postgresql.
/// </summary>
namespace NpgsqlTypes
{
-
- /*internal struct NpgsqlTypeMapping
- {
- public String _backendTypeName;
- public Type _frameworkType;
- public Int32 _typeOid;
- public NpgsqlDbType _npgsqlDbType;
-
- public NpgsqlTypeMapping(String backendTypeName, Type frameworkType, Int32 typeOid, NpgsqlDbType npgsqlDbType)
- {
- _backendTypeName = backendTypeName;
- _frameworkType = frameworkType;
- _typeOid = typeOid;
- _npgsqlDbType = npgsqlDbType;
-
- }
- }*/
-
-
- internal class NpgsqlTypesHelper
- {
-
- private static Hashtable _oidToNameMappings = new Hashtable();
-
- // Logging related values
- private static readonly String CLASSNAME = "NpgsqlDataReader";
- private static ResourceManager resman = new ResourceManager(typeof(NpgsqlTypesHelper));
-
- // From include/utils/datetime.h. Thanks to Carlos Guzman Alvarez
- private static readonly DateTime postgresEpoch = new DateTime(2000, 1, 1);
-
-
-
- public static String GetBackendTypeNameFromDbType(DbType dbType)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetBackendTypeNameFromDbType");
-
- switch (dbType)
- {
- case DbType.Binary:
- return "bytea";
- case DbType.Boolean:
- return "bool";
- case DbType.Single:
- return "float4";
- case DbType.Double:
- return "float8";
- case DbType.Int64:
- return "int8";
- case DbType.Int32:
- return "int4";
- case DbType.Decimal:
- return "numeric";
- case DbType.Int16:
- return "int2";
- case DbType.String:
- case DbType.AnsiString:
- return "text";
- case DbType.DateTime:
- return "timestamp";
- case DbType.Date:
- return "date";
- case DbType.Time:
- return "time";
- default:
- throw new NpgsqlException(String.Format(resman.GetString("Exception_TypeNotSupported"), dbType));
-
- }
- }
-
- public static Object ConvertBackendBytesToStytemType(Hashtable oidToNameMapping, Byte[] data, Encoding encoding, Int32 fieldValueSize, Int32 typeOid, Int32 typeModifier)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ConvertBackendBytesToStytemType");
- //[TODO] Find a way to eliminate this checking. It is just used at bootstrap time
- // when connecting because we don't have yet loaded typeMapping. The switch below
- // crashes with NullPointerReference when it can't find the typeOid.
-
- if (!oidToNameMapping.ContainsKey(typeOid))
- return data;
-
- switch ((DbType)oidToNameMapping[typeOid])
- {
- case DbType.Binary:
- return data;
- case DbType.Boolean:
- return BitConverter.ToBoolean(data, 0);
- case DbType.DateTime:
- return DateTime.MinValue.AddTicks(IPAddress.NetworkToHostOrder(BitConverter.ToInt64(data, 0)));
-
- case DbType.Int16:
- return IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 0));
- case DbType.Int32:
- return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 0));
- case DbType.Int64:
- return IPAddress.NetworkToHostOrder(BitConverter.ToInt64(data, 0));
- case DbType.String:
- case DbType.AnsiString:
- return encoding.GetString(data, 0, fieldValueSize);
- default:
- throw new NpgsqlException("Type not supported in binary format");
- }
-
-
- }
-
-
- public static String ConvertNpgsqlParameterToBackendStringValue(NpgsqlParameter parameter)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ConvertNpgsqlParameterToBackendStringValue");
-
- if ((parameter.Value == DBNull.Value) || (parameter.Value == null))
- return "Null";
-
- switch(parameter.DbType)
- {
- case DbType.Binary:
- return "'" + ConvertByteArrayToBytea((Byte[])parameter.Value) + "'";
- case DbType.Boolean:
- case DbType.Int64:
- case DbType.Int32:
- case DbType.Int16:
- return parameter.Value.ToString();
-
- case DbType.Single:
- // To not have a value implicitly converted to float8, we add quotes.
- return "'" + ((Single)parameter.Value).ToString(NumberFormatInfo.InvariantInfo) + "'";
-
- case DbType.Double:
- return ((Double)parameter.Value).ToString(NumberFormatInfo.InvariantInfo);
-
- case DbType.Date:
- return "'" + ((DateTime)parameter.Value).ToString("yyyy-MM-dd") + "'";
-
- case DbType.DateTime:
- return "'" + ((DateTime)parameter.Value).ToString("yyyy-MM-dd HH:mm:ss.fff") + "'";
-
- case DbType.Decimal:
- return ((Decimal)parameter.Value).ToString(NumberFormatInfo.InvariantInfo);
-
- case DbType.String:
- case DbType.AnsiString:
- return "'" + parameter.Value.ToString().Replace("'", "\\'") + "'";
-
- case DbType.Time:
- return "'" + ((DateTime)parameter.Value).ToString("HH:mm:ss.ffff") + "'";
-
- default:
- // This should not happen!
- throw new NpgsqlException(String.Format(resman.GetString("Exception_TypeNotSupported"), parameter.DbType));
-
-
- }
-
- }
-
-
- ///<summary>
- /// This method is responsible to convert the string received from the backend
- /// to the corresponding NpgsqlType.
- /// </summary>
- ///
- public static Object ConvertBackendStringToSystemType(Hashtable oidToNameMapping, String data, Int32 typeOid, Int32 typeModifier)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ConvertBackendStringToSystemType");
- //[TODO] Find a way to eliminate this checking. It is just used at bootstrap time
- // when connecting because we don't have yet loaded typeMapping. The switch below
- // crashes with NullPointerReference when it can't find the typeOid.
-
- if (!oidToNameMapping.ContainsKey(typeOid))
- return data;
-
- switch ((DbType)oidToNameMapping[typeOid])
- {
- case DbType.Binary:
- return ConvertByteAToByteArray(data);
-
- case DbType.Boolean:
- return (data.ToLower() == "t" ? true : false);
-
- case DbType.Single:
- return Single.Parse(data, NumberFormatInfo.InvariantInfo);
-
- case DbType.Double:
- return Double.Parse(data, NumberFormatInfo.InvariantInfo);
-
- case DbType.Int16:
- return Int16.Parse(data);
- case DbType.Int32:
- return Int32.Parse(data);
-
- case DbType.Int64:
- return Int64.Parse(data);
-
- case DbType.Decimal:
- // Got this manipulation of typemodifier from jdbc driver - file AbstractJdbc1ResultSetMetaData.java.html method getColumnDisplaySize
- {
- typeModifier -= 4;
- //Console.WriteLine("Numeric from server: {0} digitos.digitos {1}.{2}", data, (typeModifier >> 16) & 0xffff, typeModifier & 0xffff);
- return Decimal.Parse(data, NumberFormatInfo.InvariantInfo);
-
- }
-
- case DbType.DateTime:
-
- // Get the date time parsed in all expected formats for timestamp.
- return DateTime.ParseExact(data,
- new String[] {"yyyy-MM-dd HH:mm:ss.fff", "yyyy-MM-dd HH:mm:ss.ff", "yyyy-MM-dd HH:mm:ss.f", "yyyy-MM-dd HH:mm:ss"},
- DateTimeFormatInfo.InvariantInfo,
- DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AllowWhiteSpaces);
-
- case DbType.Date:
- return DateTime.ParseExact(data,
- "yyyy-MM-dd",
- DateTimeFormatInfo.InvariantInfo,
- DateTimeStyles.AllowWhiteSpaces);
-
- case DbType.Time:
-
- return DateTime.ParseExact(data,
- new String[] {"HH:mm:ss.ffff", "HH:mm:ss.fff", "HH:mm:ss.ff", "HH:mm:ss.f", "HH:mm:ss"},
- DateTimeFormatInfo.InvariantInfo,
- DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AllowWhiteSpaces);
-
- case DbType.String:
- case DbType.AnsiString:
- return data;
- default:
- throw new NpgsqlException(String.Format(resman.GetString("Exception_TypeNotSupported"), oidToNameMapping[typeOid]));
-
-
- }
- }
-
-
-
- ///<summary>
- /// This method gets a type oid and return the equivalent
- /// Npgsql type.
- /// </summary>
- ///
-
- public static Type GetSystemTypeFromTypeOid(Hashtable oidToNameMapping, Int32 typeOid)
+
+ /*internal struct NpgsqlTypeMapping
+ {
+ public String _backendTypeName;
+ public Type _frameworkType;
+ public Int32 _typeOid;
+ public NpgsqlDbType _npgsqlDbType;
+
+ public NpgsqlTypeMapping(String backendTypeName, Type frameworkType, Int32 typeOid, NpgsqlDbType npgsqlDbType)
+ {
+ _backendTypeName = backendTypeName;
+ _frameworkType = frameworkType;
+ _typeOid = typeOid;
+ _npgsqlDbType = npgsqlDbType;
+
+ }
+ }*/
+
+
+ internal class NpgsqlTypesHelper
{
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetSystemTypeFromTypeOid");
- // This method gets a db type identifier and return the equivalent
- // system type.
-
- //[TODO] Find a way to eliminate this checking. It is just used at bootstrap time
- // when connecting because we don't have yet loaded typeMapping. The switch below
- // crashes with NullPointerReference when it can't find the typeOid.
-
-
-
- if (!oidToNameMapping.ContainsKey(typeOid))
- return Type.GetType("System.String");
-
- switch ((DbType)oidToNameMapping[typeOid])
- {
- case DbType.Binary:
- return Type.GetType("System.Byte[]");
- case DbType.Boolean:
- return Type.GetType("System.Boolean");
- case DbType.Int16:
- return Type.GetType("System.Int16");
- case DbType.Single:
- return Type.GetType("System.Single");
- case DbType.Double:
- return Type.GetType("System.Double");
- case DbType.Int32:
- return Type.GetType("System.Int32");
- case DbType.Int64:
- return Type.GetType("System.Int64");
- case DbType.Decimal:
- return Type.GetType("System.Decimal");
- case DbType.DateTime:
- case DbType.Date:
- case DbType.Time:
- return Type.GetType("System.DateTime");
- case DbType.String:
- case DbType.AnsiString:
- return Type.GetType("System.String");
- default:
- throw new NpgsqlException(String.Format(resman.GetString("Exception_TypeNotSupported"), oidToNameMapping[typeOid]));
-
- }
-
-
+
+ private static Hashtable _oidToNameMappings = new Hashtable();
+
+ // Logging related values
+ private static readonly String CLASSNAME = "NpgsqlDataReader";
+ private static ResourceManager resman = new ResourceManager(typeof(NpgsqlTypesHelper));
+
+ // From include/utils/datetime.h. Thanks to Carlos Guzman Alvarez
+ private static readonly DateTime postgresEpoch = new DateTime(2000, 1, 1);
+
+
+
+ public static String GetBackendTypeNameFromDbType(DbType dbType)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetBackendTypeNameFromDbType");
+
+ switch (dbType)
+ {
+ case DbType.Binary:
+ return "bytea";
+ case DbType.Boolean:
+ return "bool";
+ case DbType.Single:
+ return "float4";
+ case DbType.Double:
+ return "float8";
+ case DbType.Int64:
+ return "int8";
+ case DbType.Int32:
+ return "int4";
+ case DbType.Decimal:
+ return "numeric";
+ case DbType.Int16:
+ return "int2";
+ case DbType.String:
+ case DbType.AnsiString:
+ return "text";
+ case DbType.DateTime:
+ return "timestamp";
+ case DbType.Date:
+ return "date";
+ case DbType.Time:
+ return "time";
+ default:
+ throw new NpgsqlException(String.Format(resman.GetString("Exception_TypeNotSupported"), dbType));
+
+ }
+ }
+
+ public static Object ConvertBackendBytesToStytemType(Hashtable oidToNameMapping, Byte[] data, Encoding encoding, Int32 fieldValueSize, Int32 typeOid, Int32 typeModifier)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ConvertBackendBytesToStytemType");
+ //[TODO] Find a way to eliminate this checking. It is just used at bootstrap time
+ // when connecting because we don't have yet loaded typeMapping. The switch below
+ // crashes with NullPointerReference when it can't find the typeOid.
+
+ if (!oidToNameMapping.ContainsKey(typeOid))
+ return data;
+
+ switch ((DbType)oidToNameMapping[typeOid])
+ {
+ case DbType.Binary:
+ return data;
+ case DbType.Boolean:
+ return BitConverter.ToBoolean(data, 0);
+ case DbType.DateTime:
+ return DateTime.MinValue.AddTicks(IPAddress.NetworkToHostOrder(BitConverter.ToInt64(data, 0)));
+
+ case DbType.Int16:
+ return IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 0));
+ case DbType.Int32:
+ return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 0));
+ case DbType.Int64:
+ return IPAddress.NetworkToHostOrder(BitConverter.ToInt64(data, 0));
+ case DbType.String:
+ case DbType.AnsiString:
+ return encoding.GetString(data, 0, fieldValueSize);
+ default:
+ throw new NpgsqlException("Type not supported in binary format");
+ }
+
+
+ }
+
+
+ public static String ConvertNpgsqlParameterToBackendStringValue(NpgsqlParameter parameter)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ConvertNpgsqlParameterToBackendStringValue");
+
+ if ((parameter.Value == DBNull.Value) || (parameter.Value == null))
+ return "Null";
+
+ switch(parameter.DbType)
+ {
+ case DbType.Binary:
+ return "'" + ConvertByteArrayToBytea((Byte[])parameter.Value) + "'";
+ case DbType.Boolean:
+ case DbType.Int64:
+ case DbType.Int32:
+ case DbType.Int16:
+ return parameter.Value.ToString();
+
+ case DbType.Single:
+ // To not have a value implicitly converted to float8, we add quotes.
+ return "'" + ((Single)parameter.Value).ToString(NumberFormatInfo.InvariantInfo) + "'";
+
+ case DbType.Double:
+ return ((Double)parameter.Value).ToString(NumberFormatInfo.InvariantInfo);
+
+ case DbType.Date:
+ return "'" + ((DateTime)parameter.Value).ToString("yyyy-MM-dd") + "'";
+
+ case DbType.DateTime:
+ return "'" + ((DateTime)parameter.Value).ToString("yyyy-MM-dd HH:mm:ss.fff") + "'";
+
+ case DbType.Decimal:
+ return ((Decimal)parameter.Value).ToString(NumberFormatInfo.InvariantInfo);
+
+ case DbType.String:
+ case DbType.AnsiString:
+ return "'" + parameter.Value.ToString().Replace("'", "\\'") + "'";
+
+ case DbType.Time:
+ return "'" + ((DateTime)parameter.Value).ToString("HH:mm:ss.ffff") + "'";
+
+ default:
+ // This should not happen!
+ throw new NpgsqlException(String.Format(resman.GetString("Exception_TypeNotSupported"), parameter.DbType));
+
+
+ }
+
+ }
+
+
+ ///<summary>
+ /// This method is responsible to convert the string received from the backend
+ /// to the corresponding NpgsqlType.
+ /// </summary>
+ ///
+ public static Object ConvertBackendStringToSystemType(Hashtable oidToNameMapping, String data, Int32 typeOid, Int32 typeModifier)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ConvertBackendStringToSystemType");
+ //[TODO] Find a way to eliminate this checking. It is just used at bootstrap time
+ // when connecting because we don't have yet loaded typeMapping. The switch below
+ // crashes with NullPointerReference when it can't find the typeOid.
+
+ if (!oidToNameMapping.ContainsKey(typeOid))
+ return data;
+
+ switch ((DbType)oidToNameMapping[typeOid])
+ {
+ case DbType.Binary:
+ return ConvertByteAToByteArray(data);
+
+ case DbType.Boolean:
+ return (data.ToLower() == "t" ? true : false);
+
+ case DbType.Single:
+ return Single.Parse(data, NumberFormatInfo.InvariantInfo);
+
+ case DbType.Double:
+ return Double.Parse(data, NumberFormatInfo.InvariantInfo);
+
+ case DbType.Int16:
+ return Int16.Parse(data);
+ case DbType.Int32:
+ return Int32.Parse(data);
+
+ case DbType.Int64:
+ return Int64.Parse(data);
+
+ case DbType.Decimal:
+ // Got this manipulation of typemodifier from jdbc driver - file AbstractJdbc1ResultSetMetaData.java.html method getColumnDisplaySize
+ {
+ typeModifier -= 4;
+ //Console.WriteLine("Numeric from server: {0} digitos.digitos {1}.{2}", data, (typeModifier >> 16) & 0xffff, typeModifier & 0xffff);
+ return Decimal.Parse(data, NumberFormatInfo.InvariantInfo);
+
+ }
+
+ case DbType.DateTime:
+
+ // Get the date time parsed in all expected formats for timestamp.
+ return DateTime.ParseExact(data,
+ new String[] {"yyyy-MM-dd HH:mm:ss.fff", "yyyy-MM-dd HH:mm:ss.ff", "yyyy-MM-dd HH:mm:ss.f", "yyyy-MM-dd HH:mm:ss"},
+ DateTimeFormatInfo.InvariantInfo,
+ DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AllowWhiteSpaces);
+
+ case DbType.Date:
+ return DateTime.ParseExact(data,
+ "yyyy-MM-dd",
+ DateTimeFormatInfo.InvariantInfo,
+ DateTimeStyles.AllowWhiteSpaces);
+
+ case DbType.Time:
+
+ return DateTime.ParseExact(data,
+ new String[] {"HH:mm:ss.ffff", "HH:mm:ss.fff", "HH:mm:ss.ff", "HH:mm:ss.f", "HH:mm:ss"},
+ DateTimeFormatInfo.InvariantInfo,
+ DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AllowWhiteSpaces);
+
+ case DbType.String:
+ case DbType.AnsiString:
+ return data;
+ default:
+ throw new NpgsqlException(String.Format(resman.GetString("Exception_TypeNotSupported"), oidToNameMapping[typeOid]));
+
+
+ }
+ }
+
+
+
+ ///<summary>
+ /// This method gets a type oid and return the equivalent
+ /// Npgsql type.
+ /// </summary>
+ ///
+
+ public static Type GetSystemTypeFromTypeOid(Hashtable oidToNameMapping, Int32 typeOid)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetSystemTypeFromTypeOid");
+ // This method gets a db type identifier and return the equivalent
+ // system type.
+
+ //[TODO] Find a way to eliminate this checking. It is just used at bootstrap time
+ // when connecting because we don't have yet loaded typeMapping. The switch below
+ // crashes with NullPointerReference when it can't find the typeOid.
+
+
+
+ if (!oidToNameMapping.ContainsKey(typeOid))
+ return Type.GetType("System.String");
+
+ switch ((DbType)oidToNameMapping[typeOid])
+ {
+ case DbType.Binary:
+ return Type.GetType("System.Byte[]");
+ case DbType.Boolean:
+ return Type.GetType("System.Boolean");
+ case DbType.Int16:
+ return Type.GetType("System.Int16");
+ case DbType.Single:
+ return Type.GetType("System.Single");
+ case DbType.Double:
+ return Type.GetType("System.Double");
+ case DbType.Int32:
+ return Type.GetType("System.Int32");
+ case DbType.Int64:
+ return Type.GetType("System.Int64");
+ case DbType.Decimal:
+ return Type.GetType("System.Decimal");
+ case DbType.DateTime:
+ case DbType.Date:
+ case DbType.Time:
+ return Type.GetType("System.DateTime");
+ case DbType.String:
+ case DbType.AnsiString:
+ return Type.GetType("System.String");
+ default:
+ throw new NpgsqlException(String.Format(resman.GetString("Exception_TypeNotSupported"), oidToNameMapping[typeOid]));
+
+ }
+
+
+ }
+
+
+ ///<summary>
+ /// This method is responsible to send query to get the oid-to-name mapping.
+ /// This is needed as from one version to another, this mapping can be changed and
+ /// so we avoid hardcoding them.
+ /// </summary>
+ public static Hashtable LoadTypesMapping(NpgsqlConnection conn)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "LoadTypesMapping");
+
+ // [TODO] Verify another way to get higher concurrency.
+ lock(typeof(NpgsqlTypesHelper))
+ {
+ Hashtable oidToNameMapping = (Hashtable) _oidToNameMappings[conn.ServerVersion];
+
+ if (oidToNameMapping != null)
+ {
+ //conn.OidToNameMapping = oidToNameMapping;
+ return oidToNameMapping;
+ }
+
+
+ oidToNameMapping = new Hashtable();
+ //conn.OidToNameMapping = oidToNameMapping;
+
+ // Bootstrap value as the datareader below will use ConvertStringToNpgsqlType above.
+ //oidToNameMapping.Add(26, "oid");
+
+ NpgsqlCommand command = new NpgsqlCommand("select oid, typname from pg_type where typname in ('bool', 'bytea', 'date', 'float4', 'float8', 'int2', 'int4', 'int8', 'numeric', 'text', 'time', 'timestamp');", conn);
+
+ NpgsqlDataReader dr = command.ExecuteReader();
+
+ // Data was read. Clear the mapping from previous bootstrap value so we don't get
+ // exceptions trying to add duplicate key.
+ // oidToNameMapping.Clear();
+
+ while (dr.Read())
+ {
+ // Add the key as a Int32 value so the switch in ConvertStringToNpgsqlType can use it
+ // in the search. If don't, the key is added as string and the switch doesn't work.
+
+ DbType type;
+ String typeName = (String) dr[1];
+
+ switch (typeName)
+ {
+ case "bool":
+ type = DbType.Boolean;
+ break;
+ case "bytea":
+ type = DbType.Binary;
+ break;
+ case "date":
+ type = DbType.Date;
+ break;
+ case "float4":
+ type = DbType.Single;
+ break;
+ case "float8":
+ type = DbType.Double;
+ break;
+ case "int2":
+ type = DbType.Int16;
+ break;
+ case "int4":
+ type = DbType.Int32;
+ break;
+ case "int8":
+ type = DbType.Int64;
+ break;
+ case "numeric":
+ type = DbType.Decimal;
+ break;
+ case "time":
+ type = DbType.Time;
+ break;
+ case "timestamp":
+ type = DbType.DateTime;
+ break;
+ default:
+ type = DbType.String; // Default dbtype of the oid. Unsupported types will be returned as String.
+ break;
+ }
+
+
+ oidToNameMapping.Add(Int32.Parse((String)dr[0]), type);
+ }
+
+ _oidToNameMappings.Add(conn.ServerVersion, oidToNameMapping);
+ return oidToNameMapping;
+ }
+
+
+ }
+
+
+
+ private static Byte[] ConvertByteAToByteArray(String byteA)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ConvertByteAToByteArray");
+ Int32 octalValue = 0;
+ Int32 byteAPosition = 0;
+
+ Int32 byteAStringLength = byteA.Length;
+
+ MemoryStream ms = new MemoryStream();
+
+ while (byteAPosition < byteAStringLength)
+ {
+
+
+ // The IsDigit is necessary in case we receive a \ as the octal value and not
+ // as the indicator of a following octal value in decimal format.
+ // i.e.: \201\301P\A
+ if (byteA[byteAPosition] == '\\')
+
+ if (byteAPosition + 1 == byteAStringLength)
+ {
+ octalValue = '\\';
+ byteAPosition++;
+ }
+ else if (Char.IsDigit(byteA[byteAPosition + 1]))
+ {
+ octalValue = (Byte.Parse(byteA[byteAPosition + 1].ToString()) << 6);
+ octalValue |= (Byte.Parse(byteA[byteAPosition + 2].ToString()) << 3);
+ octalValue |= Byte.Parse(byteA[byteAPosition + 3].ToString());
+ byteAPosition += 4;
+
+ }
+ else
+ {
+ octalValue = '\\';
+ byteAPosition += 2;
+ }
+
+
+ else
+ {
+ octalValue = (Byte)byteA[byteAPosition];
+ byteAPosition++;
+ }
+
+
+ ms.WriteByte((Byte)octalValue);
+
+ }
+
+ return ms.ToArray();
+
+
+ }
+
+ private static String ConvertByteArrayToBytea(Byte[] byteArray)
+ {
+ NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ConvertByteArrayToBytea");
+ Int32 len = byteArray.Length;
+ Char[] res = new Char [len * 5];
+ for (Int32 i = 0; i <len; i++)
+ {
+ res [(i*5)] = '\\';
+ res [(i*5)+1] = '\\';
+ res [(i*5)+2] = (Char) (((byteArray[i] & 0xC0) >> 6) + '0');
+ res [(i*5)+3] = (Char) (((byteArray[i] & 0x38) >> 3) + '0');
+ res [(i*5)+4] = (Char) ((byteArray[i] & 0x07) + '0');
+ }
+
+ return new String (res);
+
+ }
}
-
-
- ///<summary>
- /// This method is responsible to send query to get the oid-to-name mapping.
- /// This is needed as from one version to another, this mapping can be changed and
- /// so we avoid hardcoding them.
- /// </summary>
- public static Hashtable LoadTypesMapping(NpgsqlConnection conn)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "LoadTypesMapping");
-
- // [TODO] Verify another way to get higher concurrency.
- lock(typeof(NpgsqlTypesHelper))
- {
- Hashtable oidToNameMapping = (Hashtable) _oidToNameMappings[conn.ServerVersion];
-
- if (oidToNameMapping != null)
- {
- //conn.OidToNameMapping = oidToNameMapping;
- return oidToNameMapping;
- }
-
-
- oidToNameMapping = new Hashtable();
- //conn.OidToNameMapping = oidToNameMapping;
-
- // Bootstrap value as the datareader below will use ConvertStringToNpgsqlType above.
- //oidToNameMapping.Add(26, "oid");
-
- NpgsqlCommand command = new NpgsqlCommand("select oid, typname from pg_type where typname in ('bool', 'bytea', 'date', 'float4', 'float8', 'int2', 'int4', 'int8', 'numeric', 'text', 'time', 'timestamp');", conn);
-
- NpgsqlDataReader dr = command.ExecuteReader();
-
- // Data was read. Clear the mapping from previous bootstrap value so we don't get
- // exceptions trying to add duplicate key.
- // oidToNameMapping.Clear();
-
- while (dr.Read())
- {
- // Add the key as a Int32 value so the switch in ConvertStringToNpgsqlType can use it
- // in the search. If don't, the key is added as string and the switch doesn't work.
-
- DbType type;
- String typeName = (String) dr[1];
-
- switch (typeName)
- {
- case "bool":
- type = DbType.Boolean;
- break;
- case "bytea":
- type = DbType.Binary;
- break;
- case "date":
- type = DbType.Date;
- break;
- case "float4":
- type = DbType.Single;
- break;
- case "float8":
- type = DbType.Double;
- break;
- case "int2":
- type = DbType.Int16;
- break;
- case "int4":
- type = DbType.Int32;
- break;
- case "int8":
- type = DbType.Int64;
- break;
- case "numeric":
- type = DbType.Decimal;
- break;
- case "time":
- type = DbType.Time;
- break;
- case "timestamp":
- type = DbType.DateTime;
- break;
- default:
- type = DbType.String; // Default dbtype of the oid. Unsupported types will be returned as String.
- break;
- }
-
-
- oidToNameMapping.Add(Int32.Parse((String)dr[0]), type);
- }
-
- _oidToNameMappings.Add(conn.ServerVersion, oidToNameMapping);
- return oidToNameMapping;
- }
-
-
- }
-
-
-
- private static Byte[] ConvertByteAToByteArray(String byteA)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ConvertByteAToByteArray");
- Int32 octalValue = 0;
- Int32 byteAPosition = 0;
-
- Int32 byteAStringLength = byteA.Length;
-
- MemoryStream ms = new MemoryStream();
-
- while (byteAPosition < byteAStringLength)
- {
-
-
- // The IsDigit is necessary in case we receive a \ as the octal value and not
- // as the indicator of a following octal value in decimal format.
- // i.e.: \201\301P\A
- if (byteA[byteAPosition] == '\\')
-
- if (byteAPosition + 1 == byteAStringLength)
- {
- octalValue = '\\';
- byteAPosition++;
- }
- else if (Char.IsDigit(byteA[byteAPosition + 1]))
- {
- octalValue = (Byte.Parse(byteA[byteAPosition + 1].ToString()) << 6);
- octalValue |= (Byte.Parse(byteA[byteAPosition + 2].ToString()) << 3);
- octalValue |= Byte.Parse(byteA[byteAPosition + 3].ToString());
- byteAPosition += 4;
-
- }
- else
- {
- octalValue = '\\';
- byteAPosition += 2;
- }
-
-
- else
- {
- octalValue = (Byte)byteA[byteAPosition];
- byteAPosition++;
- }
-
-
- ms.WriteByte((Byte)octalValue);
-
- }
-
- return ms.ToArray();
-
-
- }
-
- private static String ConvertByteArrayToBytea(Byte[] byteArray)
- {
- NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ConvertByteArrayToBytea");
- Int32 len = byteArray.Length;
- Char[] res = new Char [len * 5];
- for (Int32 i = 0; i <len; i++)
- {
- res [(i*5)] = '\\';
- res [(i*5)+1] = '\\';
- res [(i*5)+2] = (Char) (((byteArray[i] & 0xC0) >> 6) + '0');
- res [(i*5)+3] = (Char) (((byteArray[i] & 0x38) >> 3) + '0');
- res [(i*5)+4] = (Char) ((byteArray[i] & 0x07) + '0');
- }
-
- return new String (res);
-
- }
-}
}