001    /*
002    // $Id: //open/mondrian/src/main/mondrian/olap/SchemaReader.java#33 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 2003-2008 Julian Hyde
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    //
010    // jhyde, Feb 24, 2003
011    */
012    package mondrian.olap;
013    
014    import mondrian.calc.Calc;
015    
016    import javax.sql.DataSource;
017    import java.util.List;
018    
019    /**
020     * A <code>SchemaReader</code> queries schema objects ({@link Schema},
021     * {@link Cube}, {@link Dimension}, {@link Hierarchy}, {@link Level},
022     * {@link Member}).
023     *
024     * <p>It is generally created using {@link Connection#getSchemaReader}.
025     *
026     * @author jhyde
027     * @since Feb 24, 2003
028     * @version $Id: //open/mondrian/src/main/mondrian/olap/SchemaReader.java#33 $
029     */
030    public interface SchemaReader {
031        /**
032         * Returns the access-control profile that this <code>SchemaReader</code>
033         * is implementing.
034         */
035        Role getRole();
036    
037        /**
038         * Returns an array of the root members of <code>hierarchy</code>.
039         *
040         * @param hierarchy Hierarchy
041         * @see #getCalculatedMembers(Hierarchy)
042         */
043        List<Member> getHierarchyRootMembers(Hierarchy hierarchy);
044    
045        /**
046         * Returns number of children parent of a member,
047         *  if the information can be retrieved from cache.
048         * Otherwise  -1 is returned
049         */
050        int getChildrenCountFromCache(Member member);
051    
052        /**
053         * Returns the number of members in a level, returning an approximation if
054         * acceptable.
055         *
056         * @param level Level
057         * @param approximate Whether an approximation is acceptable
058         * @param materialize Whether to go to disk if no approximation for the count
059         *   is available and the members are not in cache. If false, returns
060         *   {@link Integer#MIN_VALUE} if value is not in cache.
061         */
062        int getLevelCardinality(
063            Level level, boolean approximate, boolean materialize);
064    
065        /**
066         * Substitutes a member with an equivalent member which enforces the
067         * access control policy of this SchemaReader.
068         */
069        Member substitute(Member member);
070    
071        /**
072         * Returns direct children of <code>member</code>.
073         * @pre member != null
074         * @post return != null
075         */
076        List<Member> getMemberChildren(Member member);
077    
078        /**
079         * Returns direct children of <code>member</code>, optimized
080         * for NON EMPTY.
081         * <p>
082         * If <code>context == null</code> then
083         * there is no context and all members are returned - then
084         * its identical to {@link #getMemberChildren(Member)}.
085         * If <code>context</code> is not null, the resulting members
086         * <em>may</em> be restricted to those members that have a
087         * non empty row in the fact table for <code>context</code>.
088         * Wether or not optimization is possible depends
089         * on the SchemaReader implementation.
090         */
091        List<Member> getMemberChildren(Member member, Evaluator context);
092    
093        /**
094         * Returns direct children of each element of <code>members</code>.
095         *
096         * @param members Array of members
097         * @return array of child members
098         *
099         * @pre members != null
100         * @post return != null
101         */
102        List<Member> getMemberChildren(List<Member> members);
103    
104        /**
105         * Returns direct children of each element of <code>members</code>
106         * which is not empty in <code>context</code>.
107         *
108         * @param members Array of members
109         * @param context Evaluation context
110         * @return array of child members
111         *
112         * @pre members != null
113         * @post return != null
114         */
115        List<Member> getMemberChildren(List<Member> members, Evaluator context);
116    
117        /**
118         * Returns the parent of <code>member</code>.
119         *
120         * @param member Member
121         * @pre member != null
122         * @return null if member is a root member
123         */
124        Member getMemberParent(Member member);
125    
126    
127        /**
128         * Returns the depth of a member.
129         *
130         * <p>This may not be the same as
131         * <code>member.{@link Member#getLevel getLevel}().
132         * {@link Level#getDepth getDepth}()</code>
133         * for three reasons:<ol>
134         * <li><b>Access control</b>. The most senior <em>visible</em> member has
135         *   level 0. If the client is not allowed to see the "All" and "Nation"
136         *   levels of the "Store" hierarchy, then members of the "State" level will
137         *   have depth 0.</li>
138         * <li><b>Parent-child hierarchies</b>. Suppose Fred reports to Wilma, and
139         *   Wilma reports to no one. "All Employees" has depth 0, Wilma has depth
140         *   1, and Fred has depth 2. Fred and Wilma are both in the "Employees"
141         *   level, which has depth 1.</li>
142         * <li><b>Ragged hierarchies</b>. If Israel has only one, hidden, province
143         * then the depth of Tel Aviv, Israel is 2, whereas the depth of another
144         * city, San Francisco, CA, USA is 3.</li>
145         * </ol>
146         */
147        int getMemberDepth(Member member);
148    
149        /**
150         * Finds a member based upon its unique name.
151         *
152         * @param uniqueNameParts Unique name of member
153         * @param failIfNotFound Whether to throw an error, as opposed to returning
154         *   <code>null</code>, if there is no such member.
155         * @param matchType indicates the match mode; if not specified, EXACT
156         * @return The member, or null if not found
157         */
158        Member getMemberByUniqueName(
159            List<Id.Segment> uniqueNameParts,
160            boolean failIfNotFound,
161            MatchType matchType);
162    
163        /**
164         * Finds a member based upon its unique name, requiring an exact match.
165         *
166         * <p>This method is equivalent to calling
167         * {@link #getMemberByUniqueName(java.util.List, boolean, MatchType)}
168         * with {@link MatchType#EXACT}.
169         *
170         * @param uniqueNameParts Unique name of member
171         * @param failIfNotFound Whether to throw an error, as opposed to returning
172         *   <code>null</code>, if there is no such member.
173         * @return The member, or null if not found
174         */
175        Member getMemberByUniqueName(
176            List<Id.Segment> uniqueNameParts,
177            boolean failIfNotFound);
178    
179        /**
180         * Looks up an MDX object by name, specifying how to
181         * match if no object exactly matches the name.
182         *
183         * <p>Resolves a name such as
184         * '[Products]&#46;[Product Department]&#46;[Produce]' by resolving the
185         * components ('Products', and so forth) one at a time.
186         *
187         * @param parent Parent element to search in
188         * @param names Exploded compound name, such as {"Products",
189         *     "Product Department", "Produce"}
190         * @param failIfNotFound If the element is not found, determines whether
191         *      to return null or throw an error
192         * @param category Type of returned element, a {@link Category} value;
193         *      {@link Category#Unknown} if it doesn't matter.
194         * @param matchType indicates the match mode; if not specified, EXACT
195         *
196         * @pre parent != null
197         * @post !(failIfNotFound && return == null)
198         */
199        OlapElement lookupCompound(
200            OlapElement parent,
201            List<Id.Segment> names,
202            boolean failIfNotFound,
203            int category,
204            MatchType matchType);
205    
206        /**
207         * Looks up an MDX object by name.
208         *
209         * <p>Resolves a name such as
210         * '[Products]&#46;[Product Department]&#46;[Produce]' by resolving the
211         * components ('Products', and so forth) one at a time.
212         *
213         * @param parent Parent element to search in
214         * @param names Exploded compound name, such as {"Products",
215         *     "Product Department", "Produce"}
216         * @param failIfNotFound If the element is not found, determines whether
217         *      to return null or throw an error
218         * @param category Type of returned element, a {@link Category} value;
219         *      {@link Category#Unknown} if it doesn't matter.
220         *
221         * @pre parent != null
222         * @post !(failIfNotFound && return == null)
223         */
224        OlapElement lookupCompound(
225            OlapElement parent,
226            List<Id.Segment> names,
227            boolean failIfNotFound,
228            int category);
229    
230    
231        /**
232         * Looks up a calculated member by name. If the name is not found in the
233         * current scope, returns null.
234         */
235        Member getCalculatedMember(List<Id.Segment> nameParts);
236    
237        /**
238         * Looks up a set by name. If the name is not found in the current scope,
239         * returns null.
240         */
241        NamedSet getNamedSet(List<Id.Segment> nameParts);
242    
243        /**
244         * Appends to <code>list</code> all members between <code>startMember</code>
245         * and <code>endMember</code> (inclusive) which belong to
246         * <code>level</code>.
247         */
248        void getMemberRange(
249            Level level, Member startMember, Member endMember, List<Member> list);
250    
251        /**
252         * Returns a member <code>n</code> further along in the same level from
253         * <code>member</code>.
254         *
255         * @pre member != null
256         */
257        Member getLeadMember(Member member, int n);
258    
259        /**
260         * Compares a pair of {@link Member}s according to their order in a prefix
261         * traversal. (that is, it
262         * is an ancestor or a earlier), is a sibling, or comes later in a prefix
263         * traversal.
264         * @return A negative integer if <code>m1</code> is an ancestor, an earlier
265         *   sibling of an ancestor, or a descendent of an earlier sibling, of
266         *   <code>m2</code>;
267         *   zero if <code>m1</code> is a sibling of <code>m2</code>;
268         *   a positive integer if <code>m1</code> comes later in the prefix
269         *   traversal then <code>m2</code>.
270         */
271        int compareMembersHierarchically(Member m1, Member m2);
272    
273        /**
274         * Looks up the child of <code>parent</code> called <code>s</code>; returns
275         * null if no element is found.
276         */
277        OlapElement getElementChild(
278            OlapElement parent, Id.Segment name, MatchType matchType);
279    
280        OlapElement getElementChild(OlapElement parent, Id.Segment name);
281    
282        /**
283         * Returns the members of a level, optionally including calculated members.
284         */
285        List<Member> getLevelMembers(Level level, boolean includeCalculated);
286    
287        /**
288         * Returns the members of a level, optionally filtering out members which
289         * are empty.
290         *
291         * @param level Level
292         * @param context Context for filtering
293         * @return Members of this level
294         */
295        List<Member> getLevelMembers(Level level, Evaluator context);
296    
297        /**
298         * Returns the accessible levels of a hierarchy.
299         *
300         * @pre hierarchy != null
301         * @post return.length >= 1
302         */
303        List<Level> getHierarchyLevels(Hierarchy hierarchy);
304    
305        /**
306         * Returns the default member of a hierarchy. If the default member is in
307         * an inaccessible level, returns the nearest ascendant/descendant member.
308         */
309        Member getHierarchyDefaultMember(Hierarchy hierarchy);
310    
311        /**
312         * Returns whether a member has visible children.
313         */
314        boolean isDrillable(Member member);
315    
316        /**
317         * Returns whether a member is visible.
318         */
319        boolean isVisible(Member member);
320    
321        /**
322         * Returns the list of accessible cubes.
323         */
324        Cube[] getCubes();
325    
326        /**
327         * Returns a list of calculated members in a given hierarchy.
328         */
329        List<Member> getCalculatedMembers(Hierarchy hierarchy);
330    
331        /**
332         * Returns a list of calculated members in a given level.
333         */
334        List<Member> getCalculatedMembers(Level level);
335    
336        /**
337         * Returns the list of calculated members.
338         */
339        List<Member> getCalculatedMembers();
340    
341        /**
342         * Finds a child of a member with a given name.
343         */
344        Member lookupMemberChildByName(
345            Member parent, Id.Segment childName, MatchType matchType);
346    
347        Member lookupMemberChildByName(Member parent, Id.Segment childName);
348    
349        /**
350         * Returns an object which can evaluate an expression in native SQL, or
351         * null if this is not possible.
352         *
353         * @param fun Function
354         * @param args Arguments to the function
355         * @param evaluator Evaluator, provides context
356         * @param calc
357         */
358        NativeEvaluator getNativeSetEvaluator(
359                FunDef fun, Exp[] args, Evaluator evaluator, Calc calc);
360    
361        /**
362         * Returns the definition of a parameter with a given name, or null if not
363         * found.
364         */
365        Parameter getParameter(String name);
366    
367        DataSource getDataSource();
368    
369    }
370    
371    // End SchemaReader.java