//TODO vjerojatno ponekad ne treba ignorirati expression public string GetQuerySourceFromExpression(string name, Type type, Expression fromExpression) { var me = fromExpression as MemberExpression; if (me != null) { var qse = me.Expression as QuerySourceReferenceExpression; if (qse != null) { return(@"TABLE(""{0}"".""{1}"") ""{2}""".With( qse.ReferencedQuerySource.ItemName, me.Member.Name, name)); } } var sqe = fromExpression as SubQueryExpression; if (sqe != null) { if (sqe.QueryModel.CanUseMain()) { return(GetQuerySourceFromExpression(name, type, sqe.QueryModel.MainFromClause.FromExpression)); } //TODO hack za replaceanje generiranog id-a var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(sqe.QueryModel, this, ContextName, Context.Select()); var grouping = sqe.QueryModel.ResultOperators.FirstOrDefault(it => it is GroupResultOperator) as GroupResultOperator; if (grouping == null && subquery.Selects.Count == 1) { if (sqe.QueryModel.ResultOperators.Any(it => it is UnionResultOperator || it is ConcatResultOperator)) { var ind = subquery.Selects[0].Sql.IndexOf(" AS "); if (ind > 0) { var asName = subquery.Selects[0].Sql.Substring(ind + 4).Trim().Replace("\"", ""); if (asName != name) { subquery.Selects[0].Sql = subquery.Selects[0].Sql.Substring(0, ind + 4) + "\"" + name + "\""; } } else { subquery.Selects[0].Sql = subquery.Selects[0].Sql + " AS \"" + name + "\""; } return("(" + subquery.BuildSqlString(true) + ") \"" + name + "\""); } return("(" + subquery.BuildSqlString(true).Replace("\"" + sqe.QueryModel.MainFromClause.ItemName + "\"", "\"" + name + "\"") + ") \"" + name + "\""); } return("(" + subquery.BuildSqlString(true) + ") \"" + name + "\""); } var ce = fromExpression as ConstantExpression; if (ce != null) { var queryable = ce.Value as IQueryable; if (queryable != null) { return(GetQueryableExpression(name, queryable)); } var ien = ce.Value as IEnumerable; var array = ien != null?ien.Cast <object>().ToArray() : null; var firstElem = array != null?array.FirstOrDefault(it => it != null) : null; var elementType = firstElem != null?firstElem.GetType() : ce.Type.IsArray ? ce.Type.GetElementType() : ce.Type.IsGenericType ? ce.Type.GetGenericArguments()[0] : null; if (Context.CanUseParams && elementType != null) { var factory = ConverterFactory.GetVarrayParameterFactory(elementType); if (factory != null) { var p = Parameters.Add(factory(ce.Value as IEnumerable)); return(@"(SELECT sq$.OBJECT_VALUE as ""{1}"" FROM TABLE({0}) sq$)".With(p, name)); } } if (ce.Type.IsArray || ce.Value is Array) { return(FormatStringArray(ce.Value, name, ce.Type)); } else if (ce.Value is IEnumerable) { return(FormatStringEnumerable(ce.Value, name, ce.Type)); } //TODO: sql injection!? return("(SELECT {0} AS \"{1}\" FROM dual) \"{1}\"".With(ce.Value, name)); } var nae = fromExpression as NewArrayExpression; if (nae != null) { if (nae.Expressions.Count == 0) { //TODO support for zero throw new NotImplementedException("Expecting NewArrayExpression arguments. None found."); } var inner = string.Join(" UNION ALL ", nae.Expressions.Select(it => "SELECT {0} AS \"{1}\"".With(GetSqlExpression(it), name))); return("(" + inner + ") \"{0}\" ".With(name)); } if (fromExpression is QuerySourceReferenceExpression && fromExpression.Type.IsGrouping()) { var qse = fromExpression as QuerySourceReferenceExpression; //TODO: convert to Oracle version return ("(SELECT (\"{0}\".\"Values\")[i].* FROM generate_series(1, array_upper(\"{0}\".\"Values\", 1)) i) AS \"{1}\"".With( qse.ReferencedQuerySource.ItemName, name)); } var pe = fromExpression as ParameterExpression; if (pe != null) { return("TABLE({0}\"{1}\") \"{2}\"".With(ContextName, pe.Name, name)); } return(FromSqlSource(name, type)); }
//TODO vjerojatno ponekad ne treba ignorirati expression public string GetQuerySourceFromExpression(string name, Type type, Expression fromExpression) { var me = fromExpression as MemberExpression; if (me != null) { var qse = me.Expression as QuerySourceReferenceExpression; if (qse != null) { return(@"TABLE(""{0}"".""{1}"") ""{2}""".With( qse.ReferencedQuerySource.ItemName, me.Member.Name, name)); } } var sqe = fromExpression as SubQueryExpression; if (sqe != null) { if (sqe.QueryModel.CanUseMain()) { return(GetQuerySourceFromExpression(name, type, sqe.QueryModel.MainFromClause.FromExpression)); } //TODO hack za replaceanje generiranog id-a var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(sqe.QueryModel, this, ContextName, Context.Select()); var sql = "({0}) \"{1}\"".With(subquery.BuildSqlString(true), name); var grouping = sqe.QueryModel.ResultOperators.FirstOrDefault(it => it is GroupResultOperator) as GroupResultOperator; if (grouping == null && subquery.Selects.Count == 1) { return(sql.Replace("\"" + sqe.QueryModel.MainFromClause.ItemName + "\"", "\"" + name + "\"")); } return(sql); } var ce = fromExpression as ConstantExpression; if (ce != null) { var queryable = ce.Value as IQueryable; if (queryable != null) { return(GetQueryableExpression(name, queryable)); } if (Context.CanUseParams) { var factory = ConverterFactory.GetVarrayParameterFactory(ce.Type); if (factory != null) { return(Parameters.Add(factory(ce.Value as IEnumerable))); } } if (ce.Type.IsArray || ce.Value is Array) { return(FormatStringArray(ce.Value, name, ce.Type)); } else if (ce.Value is IEnumerable) { return(FormatStringEnumerable(ce.Value, name, ce.Type)); } //TODO: sql injection!? return("(SELECT {0} AS \"{1}\" FROM dual) \"{1}\"".With(ce.Value, name)); } var nae = fromExpression as NewArrayExpression; if (nae != null) { if (nae.Expressions.Count == 0) { //TODO support for zero throw new NotImplementedException("Expecting NewArrayExpression arguments. None found."); } var inner = string.Join(" UNION ALL ", nae.Expressions.Select(it => "SELECT {0} AS \"{1}\"".With(GetSqlExpression(it), name))); return("(" + inner + ") \"{0}\" ".With(name)); } if (fromExpression is QuerySourceReferenceExpression && fromExpression.Type.IsGrouping()) { var qse = fromExpression as QuerySourceReferenceExpression; return ("(SELECT (\"{0}\".\"Values\")[i].* FROM generate_series(1, array_upper(\"{0}\".\"Values\", 1)) i) AS \"{1}\"".With( qse.ReferencedQuerySource.ItemName, name)); } var pe = fromExpression as ParameterExpression; if (pe != null) { return("TABLE({0}\"{1}\") \"{2}\"".With(ContextName, pe.Name, name)); } return(FromSqlSource(name, type)); }