示例#1
0
        public static SoqlBooleanExpression ClassRestriction(SoqlPathExpression path, SchemaInfo schema, ClassInfo classInfo)
        {
            // returns no additional filter clause for parent (master-parent) class
            if (classInfo.InheritsFromClass == null)
                return null;

            SoqlExpressionCollection literals = new SoqlExpressionCollection();

            foreach (ClassInfo subclass in classInfo.GetSubclassesForSchema(schema))
            {
                if (subclass.SubclassSelectorValue != null)
                {
                    literals.Add(new SoqlLiteralExpression(subclass.SubclassSelectorValue));
                }
            }
            if (classInfo.SubclassSelectorValue != null)
            {
                literals.Add(new SoqlLiteralExpression(classInfo.SubclassSelectorValue));
            }

            // returns false when class is abstract (no SubClassSelectorValue) and there is no subclasses
            if (literals.Count == 0)
                return new SoqlBooleanLiteralExpression(false);

            SoqlBooleanExpression restriction = new SoqlBooleanInExpression(
                new SoqlPathExpression(path, classInfo.SubclassSelectorField.Name),
                literals
            );

            return restriction;
        }
示例#2
0
        public static SoqlBooleanExpression ClassRestriction(SoqlPathExpression path, SchemaInfo schema, ClassInfo classInfo)
        {
            // returns no additional filter clause for parent (master-parent) class
            if (classInfo.InheritsFromClass == null)
            {
                return(null);
            }

            SoqlExpressionCollection literals = new SoqlExpressionCollection();

            foreach (ClassInfo subclass in classInfo.GetSubclassesForSchema(schema))
            {
                if (subclass.SubclassSelectorValue != null)
                {
                    literals.Add(new SoqlLiteralExpression(subclass.SubclassSelectorValue));
                }
            }
            if (classInfo.SubclassSelectorValue != null)
            {
                literals.Add(new SoqlLiteralExpression(classInfo.SubclassSelectorValue));
            }

            // returns false when class is abstract (no SubClassSelectorValue) and there is no subclasses
            if (literals.Count == 0)
            {
                return(new SoqlBooleanLiteralExpression(false));
            }

            SoqlBooleanExpression restriction = new SoqlBooleanInExpression(
                new SoqlPathExpression(path, classInfo.SubclassSelectorField.Name),
                literals
                );

            return(restriction);
        }
示例#3
0
        private SoqlExpression ParsePathLikeExpression(string firstKeyword)
        {
            if (0 == String.Compare(firstKeyword, "soodaclass", true, System.Globalization.CultureInfo.InvariantCulture))
                return new SoqlSoodaClassExpression();

            SoqlPathExpression prop = new SoqlPathExpression(firstKeyword);

            while (tokenizer.TokenType == SoqlTokenType.Dot)
            {
                tokenizer.GetNextToken();
                if (tokenizer.TokenType == SoqlTokenType.Asterisk)
                {
                    tokenizer.GetNextToken();
                    return new SoqlAsteriskExpression(prop);
                }
                else if (tokenizer.IsKeyword("contains")) // lowercase
                {
                    string collectionName = prop.PropertyName;

                    tokenizer.EatKeyword();
                    if (tokenizer.TokenType != SoqlTokenType.LeftParen)
                        throw new SoqlException("'(' expected on Contains()", tokenizer.TokenPosition);
                    SoqlExpression expr = ParseLiteralExpression();
                    return new SoqlContainsExpression(prop.Left, collectionName, expr);
                }
                else if (tokenizer.IsKeyword("count")) // lowercase
                {
                    string collectionName = prop.PropertyName;
                    tokenizer.EatKeyword();
                    return new SoqlCountExpression(prop.Left, collectionName);
                }
                else if (tokenizer.IsKeyword("soodaclass")) // lowercase
                {
                    tokenizer.EatKeyword();
                    return new SoqlSoodaClassExpression(prop);
                }
                else
                {
                    string keyword = tokenizer.EatKeyword();
                    prop = new SoqlPathExpression(prop, keyword);
                }
            }
            if (tokenizer.TokenType == SoqlTokenType.LeftParen)
            {
                tokenizer.GetNextToken();
                string functionName = prop.PropertyName;
                while ((prop = prop.Left) != null)
                    functionName = prop.PropertyName + "." + functionName;

                if (0 == String.Compare(functionName, "rawquery", true, System.Globalization.CultureInfo.InvariantCulture))
                    return ParseRawExpression();

                return ParseFunctionCall(functionName);
            }
            return prop;
        }
        public virtual void Visit(SoqlPathExpression v)
        {
            if (v.Left != null)
            {
                v.Left.Accept(this);
                Output.Write('.');
            }

            Output.Write(v.PropertyName);
        }
        public SoqlPathExpression(string[] parts)
        {
            SoqlPathExpression l = null;

            for (int i = 0; i < parts.Length - 1; ++i)
            {
                l = new SoqlPathExpression(l, parts[i]);
            }
            this.PropertyName = parts[parts.Length - 1];
            this.Left = l;
        }
        public SoqlPathExpression(string[] parts)
        {
            SoqlPathExpression l = null;

            for (int i = 0; i < parts.Length - 1; ++i)
            {
                l = new SoqlPathExpression(l, parts[i]);
            }
            this.PropertyName = parts[parts.Length - 1];
            this.Left         = l;
        }
示例#7
0
        public static SoqlBooleanExpression CollectionFor(CollectionManyToManyInfo coll, SoodaObject parent)
        {
            SoqlPathExpression  needle   = new SoqlPathExpression(coll.GetItemClass().GetFirstPrimaryKeyField().Name);
            RelationInfo        relation = coll.GetRelationInfo();
            SoqlQueryExpression query    = new SoqlQueryExpression();

            query.SelectExpressions.Add(new SoqlPathExpression(relation.Table.Fields[coll.MasterField].Name));
            query.SelectAliases.Add(string.Empty);
            query.From.Add(relation.Name);
            query.FromAliases.Add(string.Empty);
            query.WhereClause = FieldEquals(relation.Table.Fields[1 - coll.MasterField].Name, parent);
            SoqlExpressionCollection haystack = new SoqlExpressionCollection();

            haystack.Add(query);
            return(new SoqlBooleanInExpression(needle, haystack));
        }
示例#8
0
 public SoqlSoodaClassExpression(SoqlPathExpression path)
 {
     this.Path = path;
 }
        private IFieldContainer GenerateTableJoins(SoqlPathExpression expr, out string p, out string firstTableAlias)
        {
            // logger.Debug("GenerateTableJoins({0})", expr);
            IFieldContainer currentContainer;
            SoqlPathExpression e;

            // make the list bi-directional

            for (e = expr; e.Left != null; e = e.Left)
            {
                e.Left.Next = e;
            }

            SoqlPathExpression firstToken = e;
            SoqlPathExpression startingToken;

            // check if the first name on the list is an alias in current context
            if (TableAliases.ContainsKey(firstToken.PropertyName))
            {
                string ta = TableAliases[firstToken.PropertyName];

                currentContainer = Schema.FindContainerByName(ta);
                p = firstToken.PropertyName;
                startingToken = firstToken.Next;
            }
            else
            {
                if (Parent != null && Parent.TableAliases.ContainsKey(firstToken.PropertyName))
                    return Parent.GenerateTableJoins(expr, out p, out firstTableAlias);

                // artificial first token

                // TODO - find default container for current field

                currentContainer = FindStartingContainerByFieldName(firstToken.PropertyName, out p);
                startingToken = firstToken;
            }

            string lastTableAlias = GetTableAliasForExpressionPrefix(p);
            firstTableAlias = lastTableAlias;

            bool nullable = false;

            for (SoqlPathExpression currentToken = startingToken; currentToken != null; currentToken = currentToken.Next)
            {
                lastTableAlias = GetTableAliasForExpressionPrefix(p);
                // logger.Trace("Container: {0} Prop: {1} {2} {3}", currentContainer.Name, currentToken.PropertyName, currentContainer.GetType().FullName, currentToken.GetType().FullName);

                FieldInfo fi = currentContainer.FindFieldByName(currentToken.PropertyName);
                if (fi == null)
                {
                    throw new Exception(String.Format("{0} not found in {1}", currentToken.PropertyName, currentContainer.Name));
                }

                if (p.Length > 0)
                    p += '.';
                p += currentToken.PropertyName;

                if (fi.ReferencedClass == null)
                {
                    currentContainer = null;
                    continue;
                };

                if (fi.IsNullable)
                    nullable = true;

                if (fi.Table.OrdinalInClass > 0)
                {
                    string extPrefix = AddPrimaryKeyJoin(firstTableAlias, (ClassInfo)currentContainer, lastTableAlias, fi);
                    AddRefJoin(firstTableAlias, p, extPrefix, fi, nullable);
                }
                else
                {
                    AddRefJoin(firstTableAlias, p, lastTableAlias, fi, nullable);
                }
                currentContainer = fi.ReferencedClass;
            }

            return currentContainer;
        }
示例#10
0
 public static SoqlBooleanExpression CollectionFor(CollectionManyToManyInfo coll, SoodaObject parent)
 {
     SoqlPathExpression needle = new SoqlPathExpression(coll.GetItemClass().GetFirstPrimaryKeyField().Name);
     RelationInfo relation = coll.GetRelationInfo();
     SoqlQueryExpression query = new SoqlQueryExpression();
     query.SelectExpressions.Add(new SoqlPathExpression(relation.Table.Fields[coll.MasterField].Name));
     query.SelectAliases.Add(string.Empty);
     query.From.Add(relation.Name);
     query.FromAliases.Add(string.Empty);
     query.WhereClause = FieldEquals(relation.Table.Fields[1 - coll.MasterField].Name, parent);
     SoqlExpressionCollection haystack = new SoqlExpressionCollection();
     haystack.Add(query);
     return new SoqlBooleanInExpression(needle, haystack);
 }
 public SoqlContainsExpression(SoqlPathExpression path, string collectionName, SoqlExpression expr)
 {
     this.Path = path;
     this.CollectionName = collectionName;
     this.Expr = expr;
 }
 public SoqlAsteriskExpression(SoqlPathExpression left)
 {
     this.Left = left;
 }
示例#13
0
 public SoqlContainsExpression(SoqlPathExpression path, string collectionName, SoqlExpression expr)
 {
     this.Path           = path;
     this.CollectionName = collectionName;
     this.Expr           = expr;
 }
示例#14
0
        private SoqlExpression ParsePathLikeExpression(string firstKeyword)
        {
            if (0 == String.Compare(firstKeyword, "soodaclass", true, System.Globalization.CultureInfo.InvariantCulture))
            {
                return(new SoqlSoodaClassExpression());
            }

            SoqlPathExpression prop = new SoqlPathExpression(firstKeyword);

            while (tokenizer.TokenType == SoqlTokenType.Dot)
            {
                tokenizer.GetNextToken();
                if (tokenizer.TokenType == SoqlTokenType.Asterisk)
                {
                    tokenizer.GetNextToken();
                    return(new SoqlAsteriskExpression(prop));
                }
                else if (tokenizer.IsKeyword("contains")) // lowercase
                {
                    string collectionName = prop.PropertyName;

                    tokenizer.EatKeyword();
                    if (tokenizer.TokenType != SoqlTokenType.LeftParen)
                    {
                        throw new SoqlException("'(' expected on Contains()", tokenizer.TokenPosition);
                    }
                    SoqlExpression expr = ParseLiteralExpression();
                    return(new SoqlContainsExpression(prop.Left, collectionName, expr));
                }
                else if (tokenizer.IsKeyword("count")) // lowercase
                {
                    string collectionName = prop.PropertyName;
                    tokenizer.EatKeyword();
                    return(new SoqlCountExpression(prop.Left, collectionName));
                }
                else if (tokenizer.IsKeyword("soodaclass")) // lowercase
                {
                    tokenizer.EatKeyword();
                    return(new SoqlSoodaClassExpression(prop));
                }
                else
                {
                    string keyword = tokenizer.EatKeyword();
                    prop = new SoqlPathExpression(prop, keyword);
                }
            }
            if (tokenizer.TokenType == SoqlTokenType.LeftParen)
            {
                tokenizer.GetNextToken();
                string functionName = prop.PropertyName;
                while ((prop = prop.Left) != null)
                {
                    functionName = prop.PropertyName + "." + functionName;
                }

                if (0 == String.Compare(functionName, "rawquery", true, System.Globalization.CultureInfo.InvariantCulture))
                {
                    return(ParseRawExpression());
                }

                return(ParseFunctionCall(functionName));
            }
            return(prop);
        }
 public SoqlPathExpression(SoqlPathExpression left, string propertyName)
 {
     this.Left         = left;
     this.PropertyName = propertyName;
 }
示例#16
0
        public override IDataReader LoadObjectList(SchemaInfo schemaInfo, ClassInfo classInfo, SoodaWhereClause whereClause, SoodaOrderBy orderBy, int startIdx, int pageCount, SoodaSnapshotOptions options, out TableInfo[] tables)
        {
            try
            {
                Queue<_QueueItem> queue = new Queue<_QueueItem>();

                List<TableInfo> tablesArrayList = new List<TableInfo>(classInfo.UnifiedTables.Count);
                SoqlQueryExpression queryExpression = new SoqlQueryExpression();
                queryExpression.StartIdx = startIdx;
                queryExpression.PageCount = pageCount;
                queryExpression.From.Add(classInfo.Name);
                queryExpression.FromAliases.Add("");
                foreach (TableInfo ti in classInfo.UnifiedTables)
                {
                    tablesArrayList.Add(ti);
                    foreach (FieldInfo fi in ti.Fields)
                    {
                        SoqlPathExpression pathExpr = new SoqlPathExpression(fi.Name);
                        queryExpression.SelectExpressions.Add(pathExpr);
                        queryExpression.SelectAliases.Add("");

                        if (fi.ReferencedClass != null && fi.PrefetchLevel > 0 && ((options & SoodaSnapshotOptions.PrefetchRelated) != 0))
                        {
                            _QueueItem item = new _QueueItem();
                            item.classInfo = fi.ReferencedClass;
                            item.level = fi.PrefetchLevel;
                            item.prefix = pathExpr;
                            queue.Enqueue(item);
                        }
                    }
                }

                while (queue.Count > 0)
                {
                    _QueueItem it = queue.Dequeue();

                    foreach (TableInfo ti in it.classInfo.UnifiedTables)
                    {
                        tablesArrayList.Add(ti);

                        foreach (FieldInfo fi in ti.Fields)
                        {
                            // TODO - this relies on the fact that path expressions
                            // are never reconstructed or broken. We simply share previous prefix
                            // perhaps it's cleaner to Clone() the expression here

                            SoqlPathExpression extendedExpression = new SoqlPathExpression(it.prefix, fi.Name);

                            queryExpression.SelectExpressions.Add(extendedExpression);
                            queryExpression.SelectAliases.Add("");

                            if (it.level >= 1 && fi.PrefetchLevel > 0 && fi.ReferencedClass != null)
                            {
                                _QueueItem newItem = new _QueueItem();
                                newItem.classInfo = fi.ReferencedClass;
                                newItem.prefix = extendedExpression;
                                newItem.level = it.level - 1;
                                queue.Enqueue(newItem);
                            }
                        }
                    }
                }

                if (whereClause != null && whereClause.WhereExpression != null)
                {
                    queryExpression.WhereClause = whereClause.WhereExpression;
                }

                if (orderBy != null)
                {
                    queryExpression.SetOrderBy(orderBy);
                }

                string query = SoqlToSql(queryExpression, schemaInfo, false);

                IDbCommand cmd = Connection.CreateCommand();

                try
                {
                    cmd.CommandTimeout = CommandTimeout;
                }
                catch (NotSupportedException e)
                {
                    logger.Debug("CommandTimeout not supported. {0}", e.Message);
                }

                if (Transaction != null)
                    cmd.Transaction = this.Transaction;

                SqlBuilder.BuildCommandWithParameters(cmd, false, query, whereClause.Parameters, false);

                tables = tablesArrayList.ToArray();
                return TimedExecuteReader(cmd);
            }
            catch (Exception ex)
            {
                logger.Error("Exception in LoadObjectList: {0}", ex);
                throw;
            }
        }
示例#17
0
 public SoqlCountExpression(SoqlPathExpression path, string collectionName)
 {
     this.Path           = path;
     this.CollectionName = collectionName;
 }
 public SoqlPathExpression(string p1, string p2, string p3)
 {
     this.Left         = new SoqlPathExpression(p1, p2);
     this.PropertyName = p3;
 }
 void Sooda.QL.ISoqlVisitor.Visit(SoqlPathExpression v)
 {
     v.GetAndAddClassInfo(_rootClass, _result);
 }
 public SoqlPathExpression(SoqlPathExpression left, string propertyName)
 {
     this.Left = left;
     this.PropertyName = propertyName;
 }
示例#21
0
        private string GetLoadingSelectStatement(ClassInfo classInfo, TableInfo tableInfo, out TableInfo[] loadedTables)
        {
            TableLoadingCache cache;
            if (tableLoadingCache.TryGetValue(tableInfo, out cache))
            {
                loadedTables = cache.LoadedTables;
                return cache.SelectStatement;
            }

            Queue<_QueueItem> queue = new Queue<_QueueItem>();
            List<TableInfo> additional = new List<TableInfo>();
            additional.Add(tableInfo);

            SoqlQueryExpression queryExpression = new SoqlQueryExpression();
            queryExpression.From.Add(classInfo.Name);
            queryExpression.FromAliases.Add("");

            foreach (FieldInfo fi in tableInfo.Fields)
            {
                SoqlPathExpression pathExpr = new SoqlPathExpression(fi.Name);
                queryExpression.SelectExpressions.Add(pathExpr);
                queryExpression.SelectAliases.Add("");

                if (fi.ReferencedClass != null && fi.PrefetchLevel > 0)
                {
                    _QueueItem item = new _QueueItem();
                    item.classInfo = fi.ReferencedClass;
                    item.level = fi.PrefetchLevel;
                    item.prefix = pathExpr;
                    queue.Enqueue(item);
                }
            }

            // TODO - add prefetching
            while (queue.Count > 0)
            {
                _QueueItem it = queue.Dequeue();

                foreach (TableInfo ti in it.classInfo.UnifiedTables)
                {
                    additional.Add(ti);

                    foreach (FieldInfo fi in ti.Fields)
                    {
                        // TODO - this relies on the fact that path expressions
                        // are never reconstructed or broken. We simply share previous prefix
                        // perhaps it's cleaner to Clone() the expression here

                        SoqlPathExpression extendedExpression = new SoqlPathExpression(it.prefix, fi.Name);

                        queryExpression.SelectExpressions.Add(extendedExpression);
                        queryExpression.SelectAliases.Add("");

                        if (it.level >= 1 && fi.PrefetchLevel > 0 && fi.ReferencedClass != null)
                        {
                            _QueueItem newItem = new _QueueItem();
                            newItem.classInfo = fi.ReferencedClass;
                            newItem.prefix = extendedExpression;
                            newItem.level = it.level - 1;
                            queue.Enqueue(newItem);
                        }
                    }
                }
            }

            queryExpression.WhereClause = null;

            int parameterPos = 0;

            foreach (FieldInfo fi in tableInfo.Fields)
            {
                if (fi.IsPrimaryKey)
                {
                    SoqlBooleanRelationalExpression expr = Soql.FieldEqualsParam(fi.Name, parameterPos);

                    if (parameterPos == 0)
                    {
                        queryExpression.WhereClause = expr;
                    }
                    else
                    {
                        queryExpression.WhereClause = new SoqlBooleanAndExpression(queryExpression.WhereClause, expr);
                    }
                    parameterPos++;
                }
            }

            string query = SoqlToSql(queryExpression, tableInfo.OwnerClass.Schema, false);

            // logger.Debug("Loading statement for table {0}: {1}", tableInfo.NameToken, query);

            loadedTables = additional.ToArray();
            tableLoadingCache[tableInfo] = new TableLoadingCache(query, loadedTables);
            return query;
        }
 public SoqlPathExpression(string p1, string p2, string p3)
 {
     this.Left = new SoqlPathExpression(p1, p2);
     this.PropertyName = p3;
 }
 public SoqlAsteriskExpression(SoqlPathExpression left)
 {
     this.Left = left;
 }
 public override void Visit(SoqlPathExpression v)
 {
     VisitAndGetFieldInfo(v, true);
 }
 public SoqlCountExpression(SoqlPathExpression path, string collectionName)
 {
     this.Path = path;
     this.CollectionName = collectionName;
 }
        public virtual void Visit(SoqlPathExpression v)
        {
            if (v.Left != null)
            {
                v.Left.Accept(this);
                Output.Write('.');
            }

            Output.Write(v.PropertyName);
        }
 void Sooda.QL.ISoqlVisitor.Visit(SoqlPathExpression v)
 {
     v.GetAndAddClassInfo(_rootClass, _result);
 }
 public SoqlSoodaClassExpression(SoqlPathExpression path)
 {
     this.Path = path;
 }
        private FieldInfo VisitAndGetFieldInfo(SoqlPathExpression v, bool doOutput)
        {
            if (v.Left != null && v.Left.Left == null)
            {
                string firstToken = v.Left.PropertyName;
                string secondToken = v.PropertyName;

                ClassInfo ci = Schema.FindClassByName(firstToken);
                if (ci != null && ci.Constants != null)
                {
                    foreach (ConstantInfo constInfo in ci.Constants)
                    {
                        if (constInfo.Name == secondToken)
                        {
                            switch (ci.GetFirstPrimaryKeyField().DataType)
                            {
                                case FieldDataType.Integer:
                                    OutputLiteral(Convert.ToInt32(constInfo.Key), null);
                                    break;
                                case FieldDataType.String:
                                    OutputLiteral(constInfo.Key, null);
                                    break;
                                case FieldDataType.AnsiString:
                                    OutputLiteral(constInfo.Key, SoqlLiteralValueModifiers.AnsiString);
                                    break;
                                default:
                                    throw new NotSupportedException("Constant of type: " + ci.GetFirstPrimaryKeyField().DataType + " not supported in SOQL");
                            }
                            return null;
                        }
                    }
                }
            }

            IFieldContainer currentContainer;
            string firstTableAlias;
            string p;

            if (v.Left != null)
            {
                currentContainer = GenerateTableJoins(v.Left, out p, out firstTableAlias);
            }
            else
            {
                currentContainer = FindStartingContainerByFieldName(v.PropertyName, out p);
                firstTableAlias = p;
                firstTableAlias = GetTableAliasForExpressionPrefix(p);
            }

            FieldInfo fi = currentContainer.FindFieldByName(v.PropertyName);
            if (fi == null)
            {
                throw new Exception(String.Format("{0} not found in {1}", v.PropertyName, currentContainer.Name));
            }

            if (doOutput)
            {
                if (_generatingOrderBy)
                    Output.Write(_builder.GetSQLOrderBy(fi, true));
                string extPrefix = GetTableAliasForExpressionPrefix(p);
                if (fi.Table.OrdinalInClass > 0)
                    extPrefix = AddPrimaryKeyJoin(firstTableAlias, (ClassInfo)currentContainer, extPrefix, fi);
                OutputColumn(extPrefix, fi);
                if (_generatingOrderBy)
                   Output.Write( _builder.GetSQLOrderBy(fi, false));
            }
            return fi;
        }