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