001    /*
002    // This software is subject to the terms of the Common Public License
003    // Agreement, available at the following URL:
004    // http://www.opensource.org/licenses/cpl.html.
005    // Copyright (C) 2004-2005 TONBELLER AG
006    // All Rights Reserved.
007    // You must accept the terms of that agreement to use this software.
008    */
009    package mondrian.rolap;
010    
011    import java.util.List;
012    
013    import mondrian.olap.Id;
014    import mondrian.olap.Evaluator;
015    import mondrian.olap.Level;
016    import mondrian.olap.MondrianProperties;
017    import mondrian.rolap.sql.MemberChildrenConstraint;
018    import mondrian.rolap.sql.TupleConstraint;
019    
020    /**
021     * Creates the right constraint for common tasks.
022     *
023     * @author av
024     * @since Nov 21, 2005
025     */
026    public class SqlConstraintFactory {
027    
028        boolean enabled = MondrianProperties.instance().EnableNativeNonEmpty.get();
029    
030        private static final SqlConstraintFactory instance = new SqlConstraintFactory();
031    
032        /** singleton */
033        private SqlConstraintFactory() {
034        }
035    
036        public static SqlConstraintFactory instance() {
037            return instance;
038        }
039    
040        public MemberChildrenConstraint getMemberChildrenConstraint(Evaluator context) {
041            if (!enabled || !SqlContextConstraint.isValidContext(context))
042                return DefaultMemberChildrenConstraint.instance();
043            return new SqlContextConstraint((RolapEvaluator) context, false);
044        }
045    
046        public TupleConstraint getLevelMembersConstraint(Evaluator context) {
047            boolean[] satisfied = {false};
048            return getLevelMembersConstraint(context, null, satisfied);
049        }
050    
051        /**
052         * Returns a constraint that restricts the members of a level to those that
053         * are non-empty in the given context. If the constraint cannot be
054         * implemented (say if native constraints are disabled) returns null.
055         *
056         * @param context Context within which members must be non-empty
057         * @param levels levels being referenced in the current context
058         * @param satisfied Set to false if constraint does not satisfy non-empty
059         * context and caller still has to do it
060         * @return Constraint
061         */
062        public TupleConstraint getLevelMembersConstraint(
063            Evaluator context,
064            Level [] levels,
065            boolean[] satisfied)
066        {
067            if (context == null) {
068                satisfied[0] = true;
069                return DefaultTupleConstraint.instance();
070            }
071            if (!enabled) {
072                // Cannot implement constraint in SQL; caller must still implement
073                // it
074                satisfied[0] = false;
075                return DefaultTupleConstraint.instance();
076            }
077            satisfied[0] = true;
078            if (!SqlContextConstraint.isValidContext(context, false, levels)) {
079                return DefaultTupleConstraint.instance();
080            }
081            return new SqlContextConstraint((RolapEvaluator) context, false);
082        }
083    
084        public MemberChildrenConstraint getChildByNameConstraint(
085            RolapMember parent,
086            Id.Segment childName)
087        {
088            // Ragged hierarchies span multiple levels, so SQL WHERE does not work
089            // there
090            if (!enabled || parent.getHierarchy().isRagged()) {
091                return DefaultMemberChildrenConstraint.instance();
092            }
093            return new ChildByNameConstraint(childName);
094        }
095    
096        /**
097         * Returns a constraint that allows to read all children of multiple parents
098         * at once using a LevelMember query style. This does not work
099         * for parent/child hierarchies.
100         *
101         * @param parentMembers List of parents (all must belong to same level)
102         * @param mcc           The constraint that would return the children for
103         *                      each single parent
104         * @return constraint
105         */
106        public TupleConstraint getDescendantsConstraint(
107            List<RolapMember> parentMembers,
108            MemberChildrenConstraint mcc)
109        {
110            return new DescendantsConstraint(parentMembers, mcc);
111        }
112    }
113    
114    // End SqlConstraintFactory.java