/// <summary> /// Конструктор /// </summary> /// <param name="tetxw">Поток к оторый будет писаться файл</param> /// <param name="st">Структура хранения разобранного SQL</param> /// <param name="DsName">Имя схемы БД</param> /// <param name="isGroup">Флаг, если true, значит с группировкой</param> public XSL(TextWriter tetxw, SQLStruct st, string DsName, bool isGroup) { tw = tetxw; sql = st; DataSetName = DsName; this.isGroup = isGroup; }
/// <summary> /// Пишет необходимые тэги для всех таблиц из From /// Реализовано как декартовое произведение всех таблиц, т.е. множество вложенных друг в друга for-each /// Так внутри вставлен вызов <see cref="WriteBeginWhere"/> для написания необходимых ограничений /// Так же здесь будет вставлена переменная с именем: "var_TableName" в которй и сохранится выборка из каждой таблицы /// Для каждой таблицы будет вставлено ограничение на кол-во необходимых строк (ONCE или ALL) /// </summary> /// <param name="sql">Схема SQL запроса</param> /// <param name="DataSetName">Имя дата-сета</param> public void WriteFrom(SQLStruct sql, string DataSetName) { //Пробегаем все JOIN for (int i=0;i<sql.from.Count;i++) { string fromName = sql.from[i]; if (sql.alias.GetTableAlias(fromName)!=null) fromName = sql.alias.GetTableAlias(fromName); if (i == 0) { tw.WriteLine("<xsl:for-each select=\"//" + DataSetName + "//" + fromName + "\">"); if (sql.from.Count == 1 && sql.select.selectType == SELECTTYPE.ONCE) { tw.WriteLine("<xsl:if test=\"position() < 2\">"); } } else if (i == sql.from.Count-1 && sql.select.selectType == SELECTTYPE.ONCE) { //Если последний элемент if (i == sql.from.Count-1 && sql.where.Count > 0) { //Тут чуть сложнее.. надо объеденить 2 where... WriteBeginWhere(sql.where, sql.from.GetWhere(i-1), sql.from[i], DataSetName, true); } else { WriteBeginWhere(sql.from.GetWhere(i-1),sql.from[i],DataSetName, true); //tw.WriteLine("\t\t<xsl:for-each select=\"//" + DataSetName + "//" + sql.from[i] + "\">"); } } else { if (i == sql.from.Count-1 && sql.where.Count > 0) { //Тут чуть сложнее.. надо объеденить 2 where... WriteBeginWhere(sql.where, sql.from.GetWhere(i-1),sql.from[i], DataSetName, false); } else { WriteBeginWhere(sql.from.GetWhere(i-1),sql.from[i],DataSetName, false); //tw.WriteLine("\t\t<xsl:for-each select=\"//" + DataSetName + "//" + sql.from[i] + "\">"); } } string TableName = ""; //if (sql.alias.GetTableAlias(sql.from[i]) == null) TableName = sql.from[i]; //else // TableName = sql.alias.GetTableAlias(sql.from[i]); tw.WriteLine("<xsl:variable name=\"var_" + TableName + "\" select=\".\"/>"); } }
/// <summary> /// Конструктор /// </summary> /// <param name="baseSql">Родительский SQL</param> public WhereClass(SQLStruct baseSql) { this.baseSql = baseSql; }
/// <summary> /// К стрингу /// </summary> /// <param name="curenttable">Имя текущей таблицы</param> /// <param name="sql">Родительский запрос</param> /// <returns></returns> public string ToString(string curenttable, SQLStruct sql) { //Aias string AliasTable1 = TableName1; /*if (sql.alias.GetTableAlias(TableName1)!=null) AliasTable1 = sql.alias.GetTableAlias(TableName1);*/ string AliasTable2 = TableName2; /*if (sql.alias.GetTableAlias(TableName2)!=null) AliasTable2 = sql.alias.GetTableAlias(TableName2);*/ string str = ""; if (AliasTable1 != null ) { if (curenttable != AliasTable1) str += "$var_"+ AliasTable1 + "/"; } if (ColumnName1!= null) if (type1 == ColumnType.NAME) str += ColumnName1; else str += "'" + ColumnName1 + "'"; if (op == TypeOper.RAVNO) { str+="="; } //str += " " + this.op + " "; if (AliasTable2 != null ) { if (curenttable != AliasTable2) str += "$var_"+ AliasTable2 + "/"; } if (ColumnName2!= null) if (type2 == ColumnType.NAME) str += ColumnName2; else str += "'" + ColumnName2 + "'"; return str; }
/// <summary> /// Пишет XSLT для SQLStruct /// </summary> /// <param name="sql">Схема SQL</param> /// <param name="prevGroupCount">Номер предыдущей группировки</param> public void WriteXSL(SQLStruct sql, int prevGroupCount) { //tw.WriteLine("<xsl:variable name=\"" + sql.GetSQLUniqueName() + "\">"); if (sql.select.paint.Count > 0) { if (sql.select.KeyCount == 0) tw.WriteLine("<" + sql.As[0] + ">"); GroupBy(sql); WriteFrom(sql, DataSetName); if (sql.select.KeyCount != 0) { tw.Write("<" + sql.As[0] + ">"); for (int i=0;i<sql.select.KeyCount;i++) { string node = sql.select.GetKey(i); //tw.Write("<xsl:value-of select=\"$\"/>"); //string node = select[i]; string val = "$var_"+ sql.select.GetKeyTable(i) + "/" + node; //tw.WriteLine("<xsl:attribute name=\"" + node +"\" select=\"" + val + "\"/>"); tw.WriteLine("<xsl:attribute name=\"" + node +"\">"); tw.WriteLine("<xsl:value-of select=\"" + val + "\"/>"); tw.WriteLine("</xsl:attribute>"); } //tw.WriteLine(">"); } tw.WriteLine("<xsl:choose>"); for (int i=0;i<sql.select.paint.Count; i++) { string name = ""; if (sql.select.paint.By.table != null && sql.select.paint.By.table != "") name+="var_"+sql.select.paint.By.table + "/"; name += sql.select.paint.By.name; tw.WriteLine("<xsl:when test=\"$" + name + "='" + sql.select.paint.Val(i) + "'\">"); if (sql.select.selectType != SELECTTYPE.ONCE && sql.select.KeyCount == 0) { if (sql.select.UseTag == null) tw.WriteLine("<" +sql.select.paint[i] + ">"); else tw.WriteLine("<" + sql.select.UseTag + ">"); } WriteSelect(sql.select,sql); if (sql.select.selectType != SELECTTYPE.ONCE && sql.select.KeyCount == 0) { //tw.WriteLine("</tr-" + sql.from[0] + ">"); if (sql.select.UseTag == null) tw.WriteLine("</" + sql.select.paint[i] + ">"); else tw.WriteLine("</" + sql.select.UseTag + ">"); } tw.WriteLine("</xsl:when>"); } //Other tw.WriteLine("<xsl:otherwise>"); tw.WriteLine("<" + sql.select.paint.Other +">"); WriteSelect(sql.select,sql); tw.WriteLine("</" + sql.select.paint.Other +">"); tw.WriteLine("</xsl:otherwise>"); tw.WriteLine("</xsl:choose>"); if (sql.select.KeyCount != 0) tw.WriteLine("</" + sql.As[0] +">"); WriteFromEnd(sql); GroupByEnd1(sql, prevGroupCount); //Должны распечатать group if (sql.select.KeyCount == 0) tw.WriteLine("</" + sql.As[0] +">"); } else { if (sql.select.KeyCount == 0) tw.WriteLine("<" + sql.As[0] + ">"); GroupBy(sql); WriteFrom(sql, DataSetName); if (sql.select.KeyCount != 0) { tw.WriteLine("<" + sql.As[0] + ">"); for (int i=0;i<sql.select.KeyCount;i++) { string node = sql.select.GetKey(i); //tw.Write("<xsl:value-of select=\"$\"/>"); //string node = select[i]; string val = "$var_"+ sql.select.GetKeyTable(i) + "/" + node; //tw.WriteLine("<xsl:attribute name=\"" + node +"\" select=\"" + val + "\"/>"); tw.WriteLine("<xsl:attribute name=\"" + node +"\">"); tw.WriteLine("<xsl:value-of select=\"" + val + "\"/>"); tw.WriteLine("</xsl:attribute>"); } } if (sql.select.selectType != SELECTTYPE.ONCE && sql.select.KeyCount == 0) { if (sql.select.UseTag == null) { //tw.WriteLine("<tr-" + sql.from[0] + ">"); string trName = sql.GetTr(-1); tw.WriteLine("<" + trName + ">"); } else tw.WriteLine("<" + sql.select.UseTag + ">"); } WriteSelect(sql.select,sql); if (sql.select.selectType != SELECTTYPE.ONCE && sql.select.KeyCount == 0) { //tw.WriteLine("</tr-" + sql.from[0] + ">"); if (sql.select.UseTag == null) { string trName = sql.GetTr(-1); //tw.WriteLine("</tr-" + sql.from[0] + ">"); tw.WriteLine("</" + trName + ">"); } else tw.WriteLine("</" + sql.select.UseTag + ">"); } if (sql.select.KeyCount != 0) tw.WriteLine("</" + sql.As[0] +">"); WriteFromEnd(sql); GroupByEnd1(sql, prevGroupCount); if (sql.select.KeyCount == 0) tw.WriteLine("</" + sql.As[0] +">"); } //tw.WriteLine("</xsl:variable>"); //tw.WriteLine("<xsl:copy-of select=\"$" + sql.GetSQLUniqueName() + "\"/>"); }
/// <summary> /// Пишет SELECT /// </summary> /// <param name="select">SELECT-класс</param> /// <param name="sql">SQL - схема</param> private void WriteSelect(SelectClass select, SQLStruct sql) { //Пишем условие, если у нас стоит тэг ONCE - одна запись for (int i=0;i< select.Count; i++) { if (select.isString(i)) { string node = select[i]; if (select.isKey(node)) continue; string tablename = select.Table(i);//sql.GetTableName(select[i]); string val = "$var_"+ tablename + "/" + select[i]; if (sql.alias.GetColumnAlias(node) != null) { string Col = "$var_"+ tablename + "/" + sql.alias.GetColumnAlias(node).name; //string var_new = "$var_"+ tablename + "/" + select[i]; tw.WriteLine("<" + node + "><xsl:value-of select=\"" + Col + "\"/></" + node + ">"); }else { tw.WriteLine("<" + node + "><xsl:value-of select=\"" + val + "\"/></" + node + ">"); } if (select.IsUsedInChild(i)) { string Col = val; if (sql.alias.GetColumnAlias(node) != null) Col = "$var_"+ tablename + "/" + sql.alias.GetColumnAlias(node).name; tw.WriteLine("<xsl:variable name=\"" + sql.GetSQLUniqueName() +"_select_" + node +"\" select=\"" + Col + "\"/>"); } } else { WriteXSL(select.GetSQL(i), sql.group.Count); } } /*if (select.selectType == SELECTTYPE.ONCE) tw.WriteLine("</xsl:if>");*/ }
/// <summary> /// Устанавливает в качестве выборки SQL-запрос по номеру колонки /// </summary> /// <param name="st">SQL-запрос</param> /// <param name="i">Номер колонки</param> public void Set(SQLStruct st, int i) { if (i >= l.Count) throw new IndexOutOfRangeException("Не существует элемента под номером: " + i.ToString()); l[i] = new Data(st); }
public Data(SQLStruct name) { select = (object) name; typeobj = typeObj.SQL; type = ElementType.STRING; }
/// <summary> /// Конструктор /// </summary> /// <param name="baseSql">Базовый SQL</param> public AsClass(SQLStruct baseSql) { this.baseSql = baseSql; }
/// <summary> /// Группировка данных( всех кроме ALL). Для каждой группировки текущего запроса создается тэг /// xsl:for-each-group и в нем пишется 2 переменные: /// group_key_id - значение ключя по которому идет группировка /// group_value_id - значение текущего узла (поддерево) /// Первый group извлекает данные из group_var_id (сюда были записаны данные из From) /// и последующие будут извлкать данные из current-group() /// /// /// </summary> /// <remarks>for-each-group созается для каждой переменной перечисленной в запросе</remarks> /// <param name="sql">SQL - запрос</param> /// <param name="prev"></param> /// <param name="max">Максимальое кол-во Group-ов (ВСЕ - ALL)</param> public void GroupNotAll(SQLStruct sql, int prev, int max) { string TrName = ""; int id= 0; for (int i=0;i<=max;i++) { TrName = sql.GetTr(i-1); if (TrName!=null) TrName = "/" + TrName; string VarGroupName = "group_" + i.ToString(); string from = "$group_var_" + id.ToString()+ TrName; if (i!=0) from = "current-group()" + TrName; //Далее в цикле мы группируем по каждой колонке для текущего group for (int j=0;j<sql.group[i].Count;j++) { if (j==0) tw.WriteLine("<xsl:for-each-group select=\"" + from + "\" group-by=\"" + sql.group[i].group[j] + "\">"); else tw.WriteLine("<xsl:for-each-group select=\"current-group()\" group-by=\"" + sql.group[i].group[j] + "\">"); tw.WriteLine("<xsl:variable name=\"" + VarGroupName+"_key_" + sql.group[i].group[j] + "\" select=\"current-grouping-key()\"/>"); tw.WriteLine("<xsl:variable name=\"" + VarGroupName+"_value_" + sql.group[i].group[j] + "\" select=\"current-group()\"/>"); } if (sql.group[i].type == TypeGroup.CONTAIN) GroupContain2(sql.group[i], sql.group[i].isAll, VarGroupName, TrName); else if (sql.group[i].type == TypeGroup.HEADER || sql.group[i].type == TypeGroup.HEADERFOOTER) GroupHeader2(sql.group[i], sql.group[i].isAll, VarGroupName, TrName); } }
/// <summary> /// Вызывается для группировки всех группировок кроме Group ALL /// При этом группировки пишутся с конца, начиная с MAX (необходимо потому чтобы отсеять уже сделанные GROUP ALL) /// В процедуре пробегаются все группировки текущего запроса, и для каждой вызываются необходимые функции, в конце дописываю закрывающийся for-each-group /// /// </summary> /// <param name="sql">Схема SQL</param> /// <param name="prev">не использутеся</param> /// <param name="max">Последний элемент</param> public void GroupNotAllEnd(SQLStruct sql, int prev, int max) { for (int i=max; i>=0; i--) { string TrName = ""; for (int j=0;j<=i;j++) { if (sql.GetTr(i-1) != null) { TrName = sql.GetTr(j-1) + "/" +TrName; } //TrName = sql.GetTr(j-1) + "/" +TrName; } string VarGroupName = "group_" + i.ToString(); if (sql.group[i].type == TypeGroup.CONTAIN) GroupContain2End(sql.group[i]); else if (sql.group[i].type == TypeGroup.FOOTER || sql.group[i].type == TypeGroup.HEADERFOOTER) GroupFooter2(sql.group[i], sql.group[i].isAll, VarGroupName, TrName); for (int j=0;j<sql.group[i].Count;j++) tw.WriteLine("</xsl:for-each-group>"); } }
/// <summary> /// Реализуется группировка Group ALL /// Реализовано путем определения типа текущей группировки (FLAT, CONTAIN...) и вызова соотв. функции для нее /// </summary> /// <remarks>Вызывает для написания промежуточного Group ALL (Не последнего). Но как выянилось потом, это не нужно. В точности повторяет <see cref="GroupAllEnd"/> за исключением того что, вызывается <see cref="GroupContain2"/> вместо <see cref="GroupContain2End"/> </remarks> /// <param name="sql">Схема Sql-запроса</param> /// <param name="groupall">Имя переменной из которой будут браться данные для группировки</param> /// <param name="Count">не нужен</param> public void GroupAll(SQLStruct sql, string groupall, int Count) { int idAll = -1; string TrName = ""; for (int i=0;i<sql.group.Count;i++) { //TrName = sql.GetTr(i-1) + "/" +TrName; if (sql.GetTr(i-1) != null) { TrName = sql.GetTr(i-1) + "/" +TrName; } if (sql.group[i].isAll) idAll = i; } if (idAll == -1) return; string VarGroupName = groupall; if (sql.group[idAll].type == TypeGroup.CONTAIN) GroupContain2(sql.group[idAll], true, groupall, TrName); else if (sql.group[idAll].type == TypeGroup.HEADER || sql.group[idAll].type == TypeGroup.HEADERFOOTER) GroupHeader2(sql.group[idAll], true, groupall, TrName); }
/// <summary> /// Реализуется группировка Group ALL /// Реализовано путем определения типа текущей группировки (FLAT, CONTAIN...) и вызова соотв. функции для нее /// </summary> /// <remarks>Вызывает для написания результирующего Group ALL</remarks> /// <param name="sql">Схема Sql-запроса</param> /// <param name="groupall">Имя переменной из которой будут браться данные для группировки</param> public void GroupAllEnd(SQLStruct sql, string groupall) { string VarGroupName = groupall; int idAll = -1; string TrName = ""; for (int i=0;i<sql.group.Count;i++) { TrName = sql.GetTr(i-1) + "/" +TrName; if (sql.group[i].isAll) idAll = i; } if (idAll == -1) return; if (sql.group[idAll].type == TypeGroup.CONTAIN) GroupContain2End(sql.group[idAll]); else if (sql.group[idAll].type == TypeGroup.FOOTER || sql.group[idAll].type == TypeGroup.HEADERFOOTER) GroupFooter2(sql.group[idAll], sql.group[idAll].isAll, groupall, TrName); }
//new!!! доделать!!!!!!!!!!!! /// <summary> /// Старая версия, не используется /// </summary> /// <param name="sql"></param> /// <param name="prev"></param> public void GroupByEnd1(SQLStruct sql, int prev) { /*if (sql.group.Count == 1) { GroupByEnd1(sql,prev); return; }*/ //Если нету group-a, то выходим //int id = 0; if (sql.group.Count <= 0) return; //Закрыввем данные tw.WriteLine("</xsl:variable>"); //Пробегаем по всем group в списке и выделяем номера group-ов где не ALL int count = -1; for (int idGroup =0; idGroup <sql.group.Count; idGroup++) { if (!sql.group[idGroup].isAll) count++; } string groupall = "groupall"; // tw.WriteLine("<xsl:variable name=\"" + groupall+ "\">"); GroupNotAll(sql, prev, count); //Далее мы формируем данные GroupData(null, false); //Закрываем все гроупы GroupNotAllEnd(sql, prev, count); tw.WriteLine("</xsl:variable>"); if (count == -1) groupall = "group_var_0"; //Группируем если надо ALL GroupAll(sql, groupall, count); //Закрываем все гроупы GroupData(groupall, true); GroupAllEnd(sql, groupall); }
/// <summary> /// полное имя /// </summary> /// <param name="st">Схема SQL</param> /// <param name="ColumnName">Имя колонки</param> /// <returns>Полное имя</returns> public string GetFullName(SQLStruct st, string ColumnName) { for (int i=0;i<st.select.Count;i++) { if (st.select.isString(i)) { //Если мы нашли совпадение, то... if (st.select[i] == ColumnName) { st.select.SetUsedInChild(i); return st.GetSQLUniqueName() + "_select_" + ColumnName; } } } //После чего должны обратиться к предку. if (st.parentSQL != null) { return GetFullName(st.parentSQL, ColumnName); } return null; }
/// <summary> /// Конструктор /// </summary> /// <param name="baseSql">Базовый SQL-класс</param> public GroupClass(SQLStruct baseSql) { this.baseSql = baseSql; once = new GroupClassOnce(this); }
/// <summary> /// Пишет закрывающие тэги группировок /// А так же добавляется тэги вставки данных из группировки /// </summary> /// <param name="sql">Схема SQL</param> /// <param name="prev"></param> public void GroupByEnd2(SQLStruct sql, int prev) { //Если нету group-a, то выходим //int id = 0; if (sql.group.Count <= 0) return; //Закрыввем данные tw.WriteLine("</xsl:variable>"); //Получаем имя тега TR (если оно есть) //string TrName = sql. string TrName = ""; for (int idGroup =0; idGroup < sql.group.Count; idGroup++) { //По idGroup получаем TrName = sql.GetTr(idGroup-1) + "/" +TrName; GroupOne(sql.group[idGroup], sql.idSQL, idGroup, prev, TrName); } tw.WriteLine("<xsl:copy-of select=\"$group_"+ sql.idSQL + "_"+ (sql.group.Count-1).ToString() + "\"/>"); }
/// <summary> /// Конструктор /// </summary> /// <param name="baseSql">Базовый класс</param> public SelectClass(SQLStruct baseSql) { this.baseSql = baseSql; }
/// <summary> /// Пишет закрывающийся тэг. Не используется /// </summary> /// <param name="sql"></param> public void GroupByEnd(SQLStruct sql) { TypeFH t = TypeFH.HEADER; int id = 0; if (sql.group.Count <= 0) return; tw.WriteLine("</xsl:variable>"); //Закончили писать в variable. //Далее мы все это должны сгруппировать :) bool All = false; for (int idGroup =0; idGroup <sql.group.Count; idGroup++) { if (sql.group[idGroup].isAll) { All = true; //tw.WriteLine("<xsl:for-each select=\"$group_var_" + id.ToString() + "/*\">"); if (sql.group[idGroup].type == TypeGroup.CONTAIN) { tw.WriteLine("<" + sql.group[idGroup].UseTag(TypeFH.CONTAIN) + ">"); //Пишем все агрегаты. for (int j=0;j< sql.group[idGroup].CountValueRecFooter;j++) { string node = sql.group[idGroup].ValueRec(j,t); string func = sql.group[idGroup].Func(j,t); tw.WriteLine("<" + node + "><xsl:value-of select=\"" + func + "(current()/" + node + ")\"/></" + node + ">"); } } else if (sql.group[idGroup].type == TypeGroup.HEADER) { tw.WriteLine("<" + sql.group[idGroup].UseTag(TypeFH.HEADER) + ">"); //Пишем все агрегаты. for (int j=0;j< sql.group[idGroup].CountValueRecFooter;j++) { //string node = (string) sql.group[idGroup].array[j]; string node = sql.group[idGroup].ValueRec(j,t); string func = sql.group[idGroup].Func(j,t); if (idGroup==0) tw.WriteLine("<" + node + "><xsl:value-of select=\""+func+"($group_var_" + id.ToString() +"/*/" + node + ")\"/></" + node + ">"); else tw.WriteLine("<" + node + "><xsl:value-of select=\""+func+"($current-group()/" + node + ")\"/></" + node + ">"); // tw.WriteLine("<xsl:value-of select=\"sum(current-group()/" + (string) sql.group[idGroup].array[j] + ")\"/>"); } tw.WriteLine("</" + sql.group[idGroup].UseTag(TypeFH.HEADER) + ">"); } if (idGroup==0) tw.WriteLine("<xsl:for-each select=\"$group_var_" + id.ToString() + "/*\" >"); else tw.WriteLine("<xsl:for-each select=\"current-group()\" >"); } else if (idGroup == 0 && sql.group[idGroup].Count > 0) { All = false; for (int i=0;i< sql.group[idGroup].Count; i++) { if (idGroup==0) tw.WriteLine("<xsl:for-each-group select=\"$group_var_" + id.ToString() + "/*\" group-by=\"" + sql.group[idGroup][i]+ "\">"); else tw.WriteLine("<xsl:for-each-group select=\"current-group()\" group-by=\"" + sql.group[idGroup][i] + "\">"); } if (sql.group[idGroup].CountValueRecHeader !=0 && sql.group[idGroup].type == TypeGroup.CONTAIN) { tw.WriteLine("<" + sql.group[idGroup].UseTag(TypeFH.CONTAIN) + ">"); //Пишем все агрегаты. for (int j=0;j< sql.group[idGroup].CountValueRecFooter;j++) { //string node = (string) sql.group[idGroup].array[j]; string node = sql.group[idGroup].ValueRec(j,t); string func = sql.group[idGroup].Func(j,t); tw.WriteLine("<" + node + "><xsl:value-of select=\""+func+"(current-group()/" + node + ")\"/></" + node + ">"); } } else if (sql.group[idGroup].CountValueRecFooter > 0 && sql.group[idGroup].type == TypeGroup.HEADER) { tw.WriteLine("<" + sql.group[idGroup].UseTag(TypeFH.HEADER) + ">"); //Пишем все агрегаты. for (int j=0;j< sql.group[idGroup].CountValueRecFooter;j++) { //string node = (string) sql.group[idGroup].array[j]; string node = sql.group[idGroup].ValueRec(j,t); string func = sql.group[idGroup].Func(j,t); tw.WriteLine("<" + node + "><xsl:value-of select=\""+func+"(current-group()/" + node + ")\"/></" + node + ">"); // tw.WriteLine("<xsl:value-of select=\"sum(current-group()/" + (string) sql.group[idGroup].array[j] + ")\"/>"); } tw.WriteLine("</" + sql.group[idGroup].UseTag(TypeFH.HEADER) + ">"); } } else { All = false; for (int i=0;i< sql.group[idGroup].Count; i++) tw.WriteLine("<xsl:for-each-group select=\"current-group()\" group-by=\"" + sql.group[idGroup][i] + "\">"); } } if (!All) tw.WriteLine("<xsl:copy-of select=\"current-group()\"/>"); else tw.WriteLine("<xsl:copy-of select=\"current()\"/>"); for (int idGroup =sql.group.Count-1; idGroup >=0 ; idGroup--) { if (sql.group[idGroup].isAll) { if (sql.group[idGroup].type == TypeGroup.CONTAIN) { //Пишем все агрегаты. tw.WriteLine("</" + sql.group[idGroup].UseTag(TypeFH.CONTAIN) + ">"); } tw.WriteLine("</xsl:for-each>"); if (sql.group[idGroup].type == TypeGroup.FOOTER) { tw.WriteLine("<" + sql.group[idGroup].UseTag(TypeFH.FOOTER) + ">"); //Пишем все агрегаты. for (int j=0;j< sql.group[idGroup].CountValueRecFooter;j++) { //string node = (string) sql.group[idGroup].array[j]; string node = sql.group[idGroup].ValueRec(j,t); string func = sql.group[idGroup].Func(j,t); if (idGroup==0) tw.WriteLine("<" + node + "><xsl:value-of select=\""+func+"($group_var_" + id.ToString() +"/*/" + node + ")\"/></" + node + ">"); else tw.WriteLine("<" + node + "><xsl:value-of select=\""+func+"($current-group()/" + node + ")\"/></" + node + ">"); // tw.WriteLine("<xsl:value-of select=\"sum(current-group()/" + (string) sql.group[idGroup].array[j] + ")\"/>"); } tw.WriteLine("</" + sql.group[idGroup].UseTag(TypeFH.FOOTER) + ">"); } } else if (idGroup == 0 && sql.group[idGroup].Count > 0) { if (sql.group[idGroup].CountValueRecFooter !=0 && sql.group[idGroup].type == TypeGroup.CONTAIN) { tw.WriteLine("</" + sql.group[idGroup].UseTag(TypeFH.CONTAIN) + ">"); } else if (sql.group[idGroup].type == TypeGroup.FOOTER) { tw.WriteLine("<" + sql.group[idGroup].UseTag(TypeFH.FOOTER) + ">"); //Пишем все агрегаты. for (int j=0;j< sql.group[idGroup].CountValueRecFooter;j++) { //string node = (string) sql.group[idGroup].array[j]; string node = sql.group[idGroup].ValueRec(j,t); string func = sql.group[idGroup].Func(j,t); tw.WriteLine("<" + node + "><xsl:value-of select=\""+func+"(current-group()/" + node + ")\"/></" + node + ">"); // tw.WriteLine("<xsl:value-of select=\"sum(current-group()/" + (string) sql.group[idGroup].array[j] + ")\"/>"); } tw.WriteLine("</" + sql.group[idGroup].UseTag(TypeFH.FOOTER) + ">"); } for (int i=0;i< sql.group[idGroup].Count; i++) { tw.WriteLine("</xsl:for-each-group>"); } } else { if (sql.group[idGroup].type == TypeGroup.FOOTER) { tw.WriteLine("<" + sql.group[idGroup].UseTag(TypeFH.FOOTER) + ">"); //Пишем все агрегаты. for (int j=0;j< sql.group[idGroup].CountValueRecFooter;j++) { //string node = (string) sql.group[idGroup].array[j]; string node = sql.group[idGroup].ValueRec(j,t); string func = sql.group[idGroup].Func(j,t); tw.WriteLine("<" + node + "><xsl:value-of select=\""+func+"(current-group()/" + node + ")\"/></" + node + ">"); // tw.WriteLine("<xsl:value-of select=\"sum(current-group()/" + (string) sql.group[idGroup].array[j] + ")\"/>"); } tw.WriteLine("</" + sql.group[idGroup].UseTag(TypeFH.FOOTER) + ">"); } for (int i=0;i< sql.group[idGroup].Count; i++) tw.WriteLine("</xsl:for-each-group>"); } } }
/// <summary> /// Добавлет в качестве колонки SQL-выражение /// </summary> /// <param name="name"> SQL-выражение</param> public void Add(SQLStruct name) { l.Add(new Data(name)); }
/// <summary> /// Пишет закрывающиеся тэеги для From ///т.е. дописывает все /for-each и /if /// </summary> /// <param name="sql">Схема запроса</param> public void WriteFromEnd(SQLStruct sql) { //Пробегаем все JOIN for (int i=0;i<sql.from.Count;i++) { if (i == 0 && sql.select.selectType == SELECTTYPE.ONCE) tw.WriteLine("</xsl:if>"); tw.WriteLine("</xsl:for-each>"); } }
/// <summary> /// Конструктор /// </summary> /// <param name="baseSql">Схема sql-запроса в котором находится текущий from</param> public FromClass(SQLStruct baseSql) { this.baseSql = baseSql; }
/// <summary> /// Обрамляет переменной для группировки: xsl:variable name="group_var_0" /// </summary> /// <param name="sql"></param> public void GroupBy(SQLStruct sql) { if (sql.group.Count <= 0) return; tw.WriteLine("<xsl:variable name=\"group_var_0\">"); }