1 // created on 12/6/2002 at 20:29
3 // Npgsql.NpgsqlRowDescription.cs
6 // Francisco Jr. (fxjrlists@yahoo.com.br)
8 // Copyright (C) 2002 The Npgsql Development Team
9 // npgsql-general@gborg.postgresql.org
10 // http://gborg.postgresql.org/project/npgsql/projdisplay.php
12 // This library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation; either
15 // version 2.1 of the License, or (at your option) any later version.
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Lesser General Public License for more details.
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library; if not, write to the Free Software
24 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 using System
.Collections
;
39 /// This struct represents the internal data of the RowDescription message.
42 // [FIXME] Is this name OK? Does it represent well the struct intent?
43 // Should it be a struct or a class?
44 internal struct NpgsqlRowDescriptionFieldData
46 public String name
; // Protocol 2/3
47 public Int32 table_oid
; // Protocol 3
48 public Int16 column_attribute_number
; // Protocol 3
49 public Int32 type_oid
; // Protocol 2/3
50 public Int16 type_size
; // Protocol 2/3
51 public Int32 type_modifier
; // Protocol 2/3
52 public FormatCode format_code
; // Protocol 3. 0 text, 1 binary
53 public NpgsqlBackendTypeInfo type_info
; // everything we know about this field type
57 /// This class represents a RowDescription message sent from
61 internal sealed class NpgsqlRowDescription
63 // Logging related values
64 private static readonly String CLASSNAME
= "NpgsqlRowDescription";
67 private ArrayList fields_data
= new ArrayList();
68 private ArrayList fields_index
= new ArrayList();
70 private ProtocolVersion protocol_version
;
72 public NpgsqlRowDescription(ProtocolVersion protocolVersion
)
74 protocol_version
= protocolVersion
;
77 public void ReadFromStream(Stream input_stream
, Encoding encoding
, NpgsqlBackendTypeMapping type_mapping
)
79 switch (protocol_version
)
81 case ProtocolVersion
.Version2
:
82 ReadFromStream_Ver_2(input_stream
, encoding
, type_mapping
);
85 case ProtocolVersion
.Version3
:
86 ReadFromStream_Ver_3(input_stream
, encoding
, type_mapping
);
92 private void ReadFromStream_Ver_2(Stream input_stream
, Encoding encoding
, NpgsqlBackendTypeMapping type_mapping
)
94 NpgsqlEventLog
.LogMethodEnter(LogLevel
.Debug
, CLASSNAME
, "ReadFromStream_Ver_2");
96 Byte
[] input_buffer
= new Byte
[10]; // Max read will be 4 + 2 + 4
98 // Read the number of fields.
99 input_stream
.Read(input_buffer
, 0, 2);
100 Int16 num_fields
= IPAddress
.NetworkToHostOrder(BitConverter
.ToInt16(input_buffer
, 0));
103 // Temporary FieldData object to get data from stream and put in array.
104 NpgsqlRowDescriptionFieldData fd
;
106 // Now, iterate through each field getting its data.
107 for (Int16 i
= 0; i
< num_fields
; i
++)
109 fd
= new NpgsqlRowDescriptionFieldData();
112 fd
.name
= PGUtil
.ReadString(input_stream
, encoding
);
114 // Read type_oid(Int32), type_size(Int16), type_modifier(Int32)
115 input_stream
.Read(input_buffer
, 0, 4 + 2 + 4);
117 fd
.type_oid
= IPAddress
.NetworkToHostOrder(BitConverter
.ToInt32(input_buffer
, 0));
118 fd
.type_info
= type_mapping
[fd
.type_oid
];
119 fd
.type_size
= IPAddress
.NetworkToHostOrder(BitConverter
.ToInt16(input_buffer
, 4));
120 fd
.type_modifier
= IPAddress
.NetworkToHostOrder(BitConverter
.ToInt32(input_buffer
, 6));
122 // Add field data to array.
125 fields_index
.Add(fd
.name
);
129 private void ReadFromStream_Ver_3(Stream input_stream
, Encoding encoding
, NpgsqlBackendTypeMapping type_mapping
)
131 NpgsqlEventLog
.LogMethodEnter(LogLevel
.Debug
, CLASSNAME
, "ReadFromStream_Ver_3");
133 Byte
[] input_buffer
= new Byte
[4]; // Max read will be 4 + 2 + 4 + 2 + 4 + 2
135 // Read the length of message.
136 // [TODO] Any use for now?
137 PGUtil
.ReadInt32(input_stream
, input_buffer
);
138 Int16 num_fields
= PGUtil
.ReadInt16(input_stream
, input_buffer
);
140 // Temporary FieldData object to get data from stream and put in array.
141 NpgsqlRowDescriptionFieldData fd
;
143 for (Int16 i
= 0; i
< num_fields
; i
++)
145 fd
= new NpgsqlRowDescriptionFieldData();
147 fd
.name
= PGUtil
.ReadString(input_stream
, encoding
);
148 fd
.table_oid
= PGUtil
.ReadInt32(input_stream
, input_buffer
);
149 fd
.column_attribute_number
= PGUtil
.ReadInt16(input_stream
, input_buffer
);
150 fd
.type_oid
= PGUtil
.ReadInt32(input_stream
, input_buffer
);
151 fd
.type_info
= type_mapping
[fd
.type_oid
];
152 fd
.type_size
= PGUtil
.ReadInt16(input_stream
, input_buffer
);
153 fd
.type_modifier
= PGUtil
.ReadInt32(input_stream
, input_buffer
);
154 fd
.format_code
= (FormatCode
)PGUtil
.ReadInt16(input_stream
, input_buffer
);
157 fields_index
.Add(fd
.name
);
161 public NpgsqlRowDescriptionFieldData
this[Int32 index
]
165 return (NpgsqlRowDescriptionFieldData
)fields_data
[index
];
169 public Int16 NumFields
173 return (Int16
)fields_data
.Count
;
177 public Int16
FieldIndex(String fieldName
)
181 // First try to find the index with IndexOf (case-sensitive)
182 result
= (Int16
)fields_index
.IndexOf(fieldName
);
192 foreach (String name
in fields_index
)
195 if (name
.ToLower().Equals(fieldName
.ToLower()))
204 throw new ArgumentOutOfRangeException("fieldName", fieldName
, "Field name not found");