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