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].[Product Department].[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].[Product Department].[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