001 /*
002 // $Id: //open/mondrian-release/3.0/src/main/mondrian/olap/SchemaReader.java#3 $
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-2007 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-release/3.0/src/main/mondrian/olap/SchemaReader.java#3 $
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 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 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 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 Member[] getMemberChildren(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 Member[] getMemberChildren(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].[Product Department].[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].[Product Department].[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 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 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 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