public void CreateGenerics( QueryProtocol[] queryItems )
        {
            if( queryItems == null)
                throw new ArgumentNullException("queryItems");

            ParseQueryItemsToGenerics( queryItems, null );
        }
        public DataSet ExecuteDataSet(QueryProtocol[] queryItems)
        {
            if (queryItems == null)
                throw new ArgumentNullException("queryItems");

            ClarifyGenericSrvQueryParser parser = new ClarifyGenericSrvQueryParser(dataSet);
            parser.CreateGenerics(queryItems);

            // run generic query
            dataSet.Query(GetRootGenericsToQuery(queryItems));

            DataSet ds = new DataSet("ClarifyGenericQuery");

            CreateDataTables(ds, queryItems);
            FillDataTables(ds, queryItems, null, null);

            return ds;
        }
        public string Query( QueryProtocol[] generics, bool includeSchema )
        {
            if( generics == null)
            {
                throw new ArgumentNullException("generics");
            }

            ClarifySession session = Global.GetSession( AuthHeader );

            ClarifyGenericSrvQuery query = new ClarifyGenericSrvQuery(session);
            DataSet ds = query.ExecuteDataSet( generics );

            using(System.IO.StringWriter sw = new System.IO.StringWriter() )
            {
                System.Xml.XmlTextWriter xmlWriter = new System.Xml.XmlTextWriter(sw);
                ds.WriteXml(xmlWriter, includeSchema ? XmlWriteMode.WriteSchema : XmlWriteMode.IgnoreSchema);
                sw.Flush();

                return sw.ToString();
            }
        }
        private void CreateDataTable(DataSet ds, QueryProtocol queryItem)
        {
            queryItem.ResultDataTable = new DataTable(GetTableName(queryItem));
            ds.Tables.Add(queryItem.ResultDataTable);

            SchemaFieldBase[] fields = GetTableFields(queryItem.ObjectName, queryItem.DataFields);

            DataColumn column;

            foreach (SchemaFieldBase field in fields)
            {
                column = queryItem.ResultDataTable.Columns.Add(field.Name, field.ObjectType);
                column.ColumnMapping = MappingType.Attribute;
            }

            column = queryItem.ResultDataTable.Columns.Add("_id", typeof (int));
            column.ColumnMapping = MappingType.Hidden;
            column.AutoIncrement = true;
            column.Unique = true;

            if (queryItem.Parent != null)
            {
                column = queryItem.ResultDataTable.Columns.Add("_parentid", typeof (int));
                column.ColumnMapping = MappingType.Hidden;

                DataRelation dataRel = new DataRelation(
                    queryItem.TraverseRelation,
                    queryItem.Parent.ResultDataTable.Columns["_id"],
                    queryItem.ResultDataTable.Columns["_parentid"], false);

                dataRel.Nested = true;
                ds.Relations.Add(dataRel);
            }

            if (queryItem.ChildGenerics != null)
                CreateDataTables(ds, queryItem.ChildGenerics);
        }
        private void ParseQueryItemsToGenerics( QueryProtocol[] queryItems, QueryProtocol parentQueryItem )
        {
            bool isRootGeneric = parentQueryItem == null;

            foreach(QueryProtocol queryItem in queryItems)
            {
                if( isRootGeneric )
                {
                    if(!ClarifyApplication.Instance.SchemaCache.IsValidTableOrView( queryItem.ObjectName ))
                    {
                        throw new ApplicationException(
                            string.Format("'{0}' is not a table or view.", queryItem.ObjectName));
                    }

                    queryItem.ClarifyGeneric = this.dataSet.CreateGeneric( queryItem.ObjectName );
                }
                else
                {
                    // Link up child / parents
                    queryItem.Parent = parentQueryItem;

                    if(!ClarifyApplication.Instance.SchemaCache.IsValidRelation( parentQueryItem.ObjectName, queryItem.TraverseRelation ))
                    {
                        throw new ApplicationException(
                            string.Format("'{0}' is not a valid relation for object '{1}'.", queryItem.TraverseRelation, parentQueryItem.ObjectName));
                    }

                    SchemaRelation rel = ClarifyApplication.Instance.SchemaCache.GetRelation(
                        parentQueryItem.ObjectName, queryItem.TraverseRelation );

                    if( parentQueryItem.ObjectName.ToLower() == rel.ChildTable.Name.ToLower() )
                    {
                        queryItem.ObjectName = rel.ParentTable.Name;
                    }
                    else
                    {
                        queryItem.ObjectName = rel.ChildTable.Name;
                    }

                    queryItem.ClarifyGeneric = parentQueryItem.ClarifyGeneric.Traverse(
                        queryItem.TraverseRelation);
                }

                ParseQueryItem( queryItem );
            }
        }
        private void ParseQueryItemSorts( QueryProtocol queryItem )
        {
            foreach(SortProtocol sort in queryItem.Sorts)
            {
                if( !ClarifyApplication.Instance.SchemaCache.IsValidField(
                    queryItem.ObjectName, sort.Field ) )
                {
                    throw new ApplicationException(string.Format("'{0}' is not a valid field for object '{0}'.",
                        sort.Field, queryItem.ObjectName));
                }

                queryItem.ClarifyGeneric.AppendSort(sort.Field, sort.IsAscending);
            }
        }
        private void ParseQueryItemFiltersInList( QueryProtocol queryItem )
        {
            foreach( FilterInListProtocol filter in queryItem.FiltersInList )
            {
                if( !ClarifyApplication.Instance.SchemaCache.IsValidField(
                    queryItem.ObjectName, filter.Field ) )
                {
                    throw new ApplicationException(string.Format("'{0}' is not a valid field for object '{1}'.",
                        filter.Field, queryItem.ObjectName));
                }

                SchemaFieldBase field = ClarifyApplication.Instance.SchemaCache.GetField( queryItem.ObjectName, filter.Field );

                switch( field.CommonType )
                {
                    case (int)SchemaCommonType.String:
                        queryItem.ClarifyGeneric.AppendFilterInList( filter.Field, filter.IsIn, filter.Values );
                        break;

                    case (int)SchemaCommonType.Date:
                        DateTime[] dateVals = GetParsedFilterInListValueToDateTime( filter, queryItem.ObjectName );

                        queryItem.ClarifyGeneric.AppendFilterInList( filter.Field, filter.IsIn, dateVals );
                        break;

                    case (int)SchemaCommonType.Float:
                    case (int)SchemaCommonType.Double:
                    case (int)SchemaCommonType.Decimal:
                        Decimal[] decVals = GetParsedFilterInListValueToDecimal( filter, queryItem.ObjectName );

                        queryItem.ClarifyGeneric.AppendFilterInList( filter.Field, filter.IsIn, decVals );
                        break;

                    case (int)SchemaCommonType.Integer:
                        int[] intVals = GetParsedFilterInListValueToInetger( filter, queryItem.ObjectName );

                        queryItem.ClarifyGeneric.AppendFilterInList( filter.Field, filter.IsIn, intVals );
                        break;

                    default:
                        throw new InvalidOperationException(string.Format("Parse logic not implemented for SchemaCommonType.{0}", field.CommonType));
                }

            }
        }
        private void ParseQueryItemFilters( QueryProtocol queryItem )
        {
            foreach( FilterProtocol filter in queryItem.Filters )
            {
                if( !ClarifyApplication.Instance.SchemaCache.IsValidField(
                    queryItem.ObjectName, filter.Field ) )
                {
                    throw new ApplicationException(string.Format("'{0}' is not a valid field for object '{1}'.",
                        filter.Field, queryItem.ObjectName));
                }

                SchemaFieldBase field = ClarifyApplication.Instance.SchemaCache.GetField( queryItem.ObjectName, filter.Field );

                NumberOps numberOp;
                switch( field.CommonType )
                {
                    case (int)SchemaCommonType.String:
                        StringOps strOp = (StringOps)GetParsedFilterOperation( typeof(StringOps), filter, queryItem.ObjectName );
                        queryItem.ClarifyGeneric.AppendFilter( filter.Field, strOp, filter.Value );
                        break;

                    case (int)SchemaCommonType.Date:
                        DateOps dateOp = (DateOps)GetParsedFilterOperation( typeof(DateOps), filter, queryItem.ObjectName );
                        DateTime dateVal = GetParsedFilterValueToDateTime( filter, queryItem.ObjectName );

                        queryItem.ClarifyGeneric.AppendFilter( filter.Field, dateOp, dateVal );
                        break;

                    case (int)SchemaCommonType.Float:
                    case (int)SchemaCommonType.Double:
                    case (int)SchemaCommonType.Decimal:
                        numberOp = (NumberOps)GetParsedFilterOperation( typeof(NumberOps), filter, queryItem.ObjectName );
                        Decimal decVal = GetParsedFilterValueToDecimal( filter, queryItem.ObjectName );

                        queryItem.ClarifyGeneric.AppendFilter( filter.Field, numberOp, decVal );
                        break;

                    case (int)SchemaCommonType.Integer:
                        numberOp = (NumberOps)GetParsedFilterOperation( typeof(NumberOps), filter, queryItem.ObjectName );
                        int intVal = GetParsedFilterValueToInetger( filter, queryItem.ObjectName );

                        queryItem.ClarifyGeneric.AppendFilter( filter.Field, numberOp, intVal );
                        break;

                    default:
                        throw new InvalidOperationException(string.Format("Parse logic not implemented for SchemaCommonType.{0}", field.CommonType));
                }

            }
        }
        private void ParseQueryItem( QueryProtocol queryItem )
        {
            // Parse DataFields
            if( queryItem.DataFields != null )
            {
                foreach( string dataField in queryItem.DataFields)
                    queryItem.ClarifyGeneric.DataFields.Add( dataField );
            }

            if( queryItem.Filters != null)
                ParseQueryItemFilters( queryItem );

            if( queryItem.FiltersInList != null)
                ParseQueryItemFiltersInList( queryItem );

            if( queryItem.Sorts != null)
                ParseQueryItemSorts( queryItem );

            if( queryItem.ChildGenerics != null)
                ParseQueryItemsToGenerics( queryItem.ChildGenerics, queryItem );
        }
        private void FillDataTable(DataSet ds, QueryProtocol queryItem, ClarifyDataRow parentClarifyRow, DataRow parentRow)
        {
            IEnumerator clarifyRowEnumerator;

            if (parentClarifyRow == null)
            {
                clarifyRowEnumerator = queryItem.ClarifyGeneric.Rows.GetEnumerator();
            }
            else
            {
                clarifyRowEnumerator = parentClarifyRow.RelatedRows(queryItem.ClarifyGeneric).GetEnumerator();
            }

            while (clarifyRowEnumerator.MoveNext())
            {
                ClarifyDataRow clarifyRow = (ClarifyDataRow) clarifyRowEnumerator.Current;

                DataRow row = queryItem.ResultDataTable.NewRow();
                queryItem.ResultDataTable.Rows.Add(row);

                for (int t = 0; t < row.Table.Columns.Count; t++)
                {
                    if (row.Table.Columns[t].ColumnName == "_parentid")
                        row[t] = parentRow["_id"];
                    else if (row.Table.Columns[t].ColumnName != "_id")
                        row[t] = clarifyRow[row.Table.Columns[t].ColumnName];
                }

                if (queryItem.ChildGenerics != null)
                    FillDataTables(ds, queryItem.ChildGenerics, clarifyRow, row);
            }
        }
 private void CreateDataTables(DataSet ds, QueryProtocol[] queryItems)
 {
     foreach (QueryProtocol queryItem in queryItems)
     {
         CreateDataTable(ds, queryItem);
     }
 }
 private string GetTableName(QueryProtocol queryItem)
 {
     return queryItem.ResultTableName != null
            && queryItem.ResultTableName.Trim().Length > 0
            	? queryItem.ResultTableName.Trim()
            	: queryItem.ObjectName.Trim();
 }
        private ClarifyGeneric[] GetRootGenericsToQuery(QueryProtocol[] queryItems)
        {
            ClarifyGeneric[] generics = new ClarifyGeneric[queryItems.Length];

            for (int i = 0; i < generics.Length; i++)
                generics[i] = queryItems[i].ClarifyGeneric;

            return generics;
        }
 private void FillDataTables(DataSet ds, QueryProtocol[] queryItems, ClarifyDataRow parentClarifyRow, DataRow parentRow)
 {
     foreach (QueryProtocol queryItem in queryItems)
     {
         FillDataTable(ds, queryItem, parentClarifyRow, parentRow);
     }
 }