1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.Components
.Binder
18 using System
.Collections
;
19 using System
.Collections
.Specialized
;
25 public class DataReaderTreeBuilder
30 /// <param name="reader"></param>
31 /// <param name="prefix"></param>
32 /// <returns></returns>
33 public CompositeNode
BuildSourceNode(IDataReader reader
, String prefix
)
35 CompositeNode root
= new CompositeNode("root");
37 PopulateTree(root
, reader
, prefix
);
45 /// <param name="root"></param>
46 /// <param name="reader"></param>
47 /// <param name="prefix"></param>
48 public void PopulateTree(CompositeNode root
, IDataReader reader
, String prefix
)
50 string[] fields
= GetFields(reader
);
52 int[] indexesToSkip
= FindDuplicateFields(fields
);
54 IndexedNode indexNode
= new IndexedNode(prefix
);
60 CompositeNode node
= new CompositeNode(row
.ToString());
62 for(int i
=0; i
<reader
.FieldCount
; i
++)
64 // Is in the skip list?
65 if (Array
.IndexOf(indexesToSkip
, i
) >= 0) continue;
68 if (reader
.IsDBNull(i
)) continue;
70 Type fieldType
= reader
.GetFieldType(i
);
72 node
.AddChildNode(new LeafNode(fieldType
, fields
[i
], reader
.GetValue(i
)));
75 indexNode
.AddChildNode(node
);
80 root
.AddChildNode(indexNode
);
83 private string[] GetFields(IDataReader reader
)
85 String
[] fields
= new String
[reader
.FieldCount
];
87 for(int i
=0; i
< reader
.FieldCount
; i
++)
89 fields
[i
] = reader
.GetName(i
);
96 /// Check the fields for duplicates.
98 /// <param name="fields"></param>
99 /// <returns></returns>
101 /// I have to add this check as some stored procedures
102 /// return duplicate columns (doh!) and this isn't good
105 private int[] FindDuplicateFields(string[] fields
)
107 HybridDictionary dict
= new HybridDictionary(fields
.Length
, true);
108 ArrayList duplicateList
= new ArrayList();
110 for(int i
=0; i
< fields
.Length
; i
++)
112 String field
= fields
[i
];
114 if (dict
.Contains(field
))
116 duplicateList
.Add(i
);
120 dict
.Add(field
, String
.Empty
);
123 return (int[]) duplicateList
.ToArray(typeof(int));