예제 #1
0
            public void ReadMetadata()
            {
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (state)
                        {
                        case ParserState.Start:
                            // Assumption:
                            // - skip the soap response tags
                            if ((reader.LocalName == "QueryXmlResponse") ||
                                (reader.LocalName == "QueryXmlResult"))
                            {
                                continue;
                            }

                            if (string.CompareOrdinal(reader.LocalName, "queryResult") == 0)
                            {
                                state = ParserState.Root;
                            }
                            else
                            {
                                throw new InvalidOperationException(
                                          "Expecting <queryResult> element but found " + reader.LocalName);
                            }
                            break;

                        case ParserState.Root:
                            if (string.CompareOrdinal(reader.LocalName, "queryPlan") == 0)
                            {
                                QueryPlan = new XmlDocument();
                                QueryPlan.Load(reader.ReadSubtree());
                            }
                            // obsolete since 2016.2 - the statistics was put after data
                            else if (string.CompareOrdinal(reader.LocalName, "statistics") == 0)
                            {
                                QueryStats = new XmlDocument();
                                QueryStats.Load(reader.ReadSubtree());
                            }
                            else if (string.CompareOrdinal(reader.LocalName, "template") == 0)
                            {
                                state = ParserState.Template;
                            }
                            else if (string.CompareOrdinal(reader.LocalName, "data") == 0)
                            {
                                state   = ParserState.Data;
                                hasRows = true;
                                string totalRowsAttr = reader.GetAttribute("totalRows");
                                if (!string.IsNullOrEmpty(totalRowsAttr))
                                {
                                    TotalRows = Convert.ToInt64(totalRowsAttr, CultureInfo.InvariantCulture);
                                }

                                return;
                            }
                            else
                            {
                                throw new InvalidOperationException("Unexepected element " + reader.LocalName);
                            }
                            break;

                        case ParserState.Template:
                            if (string.CompareOrdinal(reader.LocalName, "resultset") == 0)
                            {
                                if (columns != null)
                                {
                                    throw new InvalidOperationException("Only one resultset is supported");
                                }

                                state = ParserState.ResultSet;
                            }
                            break;

                        case ParserState.ResultSet:
                            if (string.CompareOrdinal(reader.LocalName, "column") != 0)
                            {
                                throw new InvalidOperationException(
                                          "Only <column> elements are expected as children of a <resultset> element");
                            }

                            if (columns == null)
                            {
                                columns = new List <ColumnInfo>();
                            }

                            ColumnInfo columnInfo = new ColumnInfo(reader["name"], reader["type"],
                                                                   Int32.Parse(reader["ordinal"], CultureInfo.InvariantCulture));

                            // TODO: this should be define in column definition
                            columnInfo.DateTimeMode = DateTimeMode;

                            while (reader.MoveToNextAttribute())
                            {
                                var name = reader.Name;
                                if (!name.Equals("name", StringComparison.OrdinalIgnoreCase) && !name.Equals("type", StringComparison.OrdinalIgnoreCase) && !name.Equals("ordinal", StringComparison.OrdinalIgnoreCase))
                                {
                                    columnInfo.AddMetadata(name, reader.Value);
                                }
                            }
                            reader.MoveToElement();

                            columns.Add(columnInfo);

                            // Sometime empty elements come with an end element, adjust the statemachine state accordingly
                            if (!reader.IsEmptyElement)
                            {
                                state = ParserState.PropertyTemplate;
                            }
                            break;

                        default:
                            throw new InvalidOperationException("Unexpected state " + state);
                        }
                        break;

                    case XmlNodeType.EndElement:
                        switch (state)
                        {
                        case ParserState.Root:
                            if (string.CompareOrdinal(reader.LocalName, "queryResult") != 0)
                            {
                                throw new InvalidOperationException(
                                          string.Format("Not expecting element {0} while in state {1}",
                                                        reader.LocalName, state));
                            }
                            return;

                        case ParserState.Template:
                            ValidateEndElement(reader.LocalName, "template", ParserState.Root);
                            break;

                        case ParserState.ResultSet:
                            ValidateEndElement(reader.LocalName, "resultset", ParserState.Template);
                            break;

                        case ParserState.PropertyTemplate:
                            ValidateEndElement(reader.LocalName, "column", ParserState.ResultSet);
                            break;

                        default:
                            throw new InvalidOperationException(
                                      string.Format("Not expecting element {0} while in state {1}", reader.LocalName,
                                                    state));
                        }
                        break;
                    }
                }

                throw new InvalidOperationException("Malformed Xml result");
            }