001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2006-2009 Pentaho and others
008// All Rights Reserved.
009*/
010package mondrian.olap;
011
012import java.io.PrintWriter;
013import java.util.List;
014import java.util.Map;
015import javax.sql.DataSource;
016
017/**
018 * API for controlling the contents of the cell cache and the member cache.
019 * A {@link CellRegion} denotes a portion of the cell cache, and a
020 * {@link MemberSet} denotes a portion of the member cache. Both caches can be
021 * flushed, and the member cache can be edited.
022 *
023 * <p>To create an instance of this interface, use
024 * {@link mondrian.olap.Connection#getCacheControl}.</p>
025 *
026 * <p>Methods concerning cell cache:<ul>
027 * <li>{@link #createMemberRegion(Member, boolean)}</li>
028 * <li>{@link #createMemberRegion(boolean, Member, boolean, Member, boolean)}</li>
029 * <li>{@link #createUnionRegion(mondrian.olap.CacheControl.CellRegion[])}</li>
030 * <li>{@link #createCrossjoinRegion(mondrian.olap.CacheControl.CellRegion[])}</li>
031 * <li>{@link #createMeasuresRegion(Cube)}</li>
032 * <li>{@link #flush(mondrian.olap.CacheControl.CellRegion)}</li>
033 * </ul></p>
034 *
035 * <p>Methods concerning member cache:<ul>
036 * <li>{@link #createMemberSet(Member, boolean)}</li>
037 * <li>{@link #createMemberSet(boolean, Member, boolean, Member, boolean)}</li>
038 * <li>{@link #createAddCommand(Member)}</li>
039 * <li>{@link #createDeleteCommand(Member)}</li>
040 * <li>{@link #createDeleteCommand(mondrian.olap.CacheControl.MemberSet)}</li>
041 * <li>{@link #createCompoundCommand(java.util.List)}</li>
042 * <li>{@link #createCompoundCommand(mondrian.olap.CacheControl.MemberEditCommand[])}</li>
043 * <li>{@link #createSetPropertyCommand(Member, String, Object)}</li>
044 * <li>{@link #createSetPropertyCommand(mondrian.olap.CacheControl.MemberSet,java.util.Map)}</li>
045 * <li>{@link #flush(mondrian.olap.CacheControl.MemberSet)}</li>
046 * <li>{@link #execute(mondrian.olap.CacheControl.MemberEditCommand)}</li>
047 * </ul></p>
048 *
049 * @author jhyde
050 * @since Sep 27, 2006
051 */
052public interface CacheControl {
053
054    // cell cache control
055
056    /**
057     * Creates a cell region consisting of a single member.
058     *
059     * @param member the member
060     * @param descendants When true, include descendants of the member in the
061     *   region.
062     * @return the new cell region
063     */
064    CellRegion createMemberRegion(Member member, boolean descendants);
065
066    /**
067     * Creates a cell region consisting of a range between two members.
068     *
069     * <p>The members must belong to the same level of the same hierarchy.
070     * One of the bounds may be null.
071     *
072     * <p>For example, given
073     *
074     * <code><pre>Member member97Q3; // [Time].[1997].[Q3]
075     * Member member98Q2; // [Time].[1998].[Q2]
076     * </pre></code>
077     *
078     * then
079     *
080     * <table border="1">
081     * <tr>
082     * <th>Expression</th>
083     * <th>Meaning</th>
084     * </tr>
085     *
086     * <tr>
087     * <td>
088     * <code>createMemberRegion(true, member97Q3, true, member98Q2,
089     * false)</code>
090     * </td>
091     * <td>The members between 97Q3 and 98Q2, inclusive:<br/>
092     * [Time].[1997].[Q3],<br/>
093     * [Time].[1997].[Q4],<br/>
094     * [Time].[1998].[Q1],<br/>
095     * [Time].[1998].[Q2]</td>
096     * </tr>
097     *
098     * <tr>
099     * <td>
100     * <code>createMemberRegion(true, member97Q3, false, member98Q2,
101     * false)</code>
102     * </td>
103     * <td>The members between 97Q3 and 98Q2, exclusive:<br/>
104     * [Time].[1997].[Q4],<br/>
105     * [Time].[1998].[Q1]</td>
106     * </tr>
107     *
108     * <tr>
109     * <td>
110     * <code>createMemberRegion(true, member97Q3, false, member98Q2,
111     * false)</code>
112     * </td>
113     * <td>The members between 97Q3 and 98Q2, including their descendants, and
114     * including the lower bound but not the upper bound:<br/>
115     * [Time].[1997].[Q3],<br/>
116     * [Time].[1997].[Q3].[7],<br/>
117     * [Time].[1997].[Q3].[8],<br/>
118     * [Time].[1997].[Q3].[9],<br/>
119     * [Time].[1997].[Q4],<br/>
120     * [Time].[1997].[Q4].[10],<br/>
121     * [Time].[1997].[Q4].[11],<br/>
122     * [Time].[1997].[Q4].[12],<br/>
123     * [Time].[1998].[Q1],<br/>
124     * [Time].[1998].[Q1].[1],<br/>
125     * [Time].[1998].[Q1].[2],<br/>
126     * [Time].[1998].[Q1].[3]</td>
127     * </tr>
128     * </table>
129     *
130     * @param lowerInclusive whether the the range includes the lower bound;
131     *   ignored if the lower bound is not specified
132     * @param lowerMember lower bound member.
133     *   If null, takes all preceding members
134     * @param upperInclusive whether the the range includes the upper bound;
135     *   ignored if the upper bound is not specified
136     * @param upperMember upper bound member.
137     *   If null, takes all preceding members
138     * @param descendants when true, include descendants of the member in the
139     *   region
140     * @return the new cell region
141     */
142    CellRegion createMemberRegion(
143        boolean lowerInclusive,
144        Member lowerMember,
145        boolean upperInclusive,
146        Member upperMember,
147        boolean descendants);
148
149    /**
150     * Forms the cartesian product of two or more cell regions.
151     * @param regions the operands
152     * @return the cartesian product of the operands
153     */
154    CellRegion createCrossjoinRegion(CellRegion... regions);
155
156    /**
157     * Forms the union of two or more cell regions.
158     * The regions must have the same dimensionality.
159     *
160     * @param regions the operands
161     * @return the cartesian product of the operands
162
163     */
164    CellRegion createUnionRegion(CellRegion... regions);
165
166    /**
167     * Creates a region consisting of all measures in a given cube.
168     * @param cube a cube
169     * @return the region
170     */
171    CellRegion createMeasuresRegion(Cube cube);
172
173    /**
174     * Atomically flushes all the cells in the cell cache that correspond to
175     * measures in a cube and to a given region.
176     *
177     * @param region a region
178     */
179    void flush(CellRegion region);
180
181    /**
182     * Prints the state of the cell cache as it pertains to a given region.
183     * @param pw the output target
184     * @param region the CellRegion of interest
185     */
186    void printCacheState(PrintWriter pw, CellRegion region);
187
188    // member cache control
189
190    /**
191     * Creates a member set containing either a single member, or a member and
192     * its descendants.
193     * @param member a member
194     * @param descendants when true, include descendants in the set
195     * @return the set
196     */
197    MemberSet createMemberSet(Member member, boolean descendants);
198
199    /**
200     * Creates a member set consisting of a range between two members.
201     * The members must belong to the same level of the same hierarchy. One of
202     * the bounds may be null. (Similar to {@link #createMemberRegion(boolean,
203     * Member, boolean, Member, boolean)}, which see for examples.)
204     *
205     * @param lowerInclusive whether the the range includes the lower bound;
206     *   ignored if the lower bound is not specified
207     * @param lowerMember lower bound member.
208     *   If null, takes all preceding members
209     * @param upperInclusive whether the the range includes the upper bound;
210     *   ignored if the upper bound is not specified
211     * @param upperMember upper bound member.
212     *   If null, takes all preceding members
213     * @param descendants when true, include descendants of the member in the
214     *   region
215     * @return the set
216     */
217    MemberSet createMemberSet(
218        boolean lowerInclusive,
219        Member lowerMember,
220        boolean upperInclusive,
221        Member upperMember,
222        boolean descendants);
223
224    /**
225     * Forms the union of two or more member sets.
226     *
227     * @param sets the operands
228     * @return the union of the operands
229     */
230    MemberSet createUnionSet(MemberSet... sets);
231
232    /**
233     * Filters a member set, keeping all members at a given Level.
234     *
235     * @param level Level
236     * @param baseSet Member set
237     * @return Member set with members not at the given level removed
238     */
239    MemberSet filter(Level level, MemberSet baseSet);
240
241    /**
242     * Atomically flushes all members in the member cache which belong to a
243     * given set.
244     *
245     * @param set a set of members
246     */
247    void flush(MemberSet set);
248
249    /**
250     * Prints the state of the member cache as it pertains to a given member
251     * set.
252     * @param pw the output target
253     * @param set the MemberSet of interest
254     */
255    void printCacheState(PrintWriter pw, MemberSet set);
256
257
258    // edit member cache contents
259
260    /**
261     * Executes a command that edits the member cache.
262     * @param cmd the command
263     */
264    void execute(MemberEditCommand cmd);
265
266    /**
267     * Builds a compound command which is executed atomically.
268     *
269     * @param cmds a list of the component commands
270     * @return the compound command
271     */
272    MemberEditCommand createCompoundCommand(List<MemberEditCommand> cmds);
273
274    /**
275     * Builds a compound command which is executed atomically.
276     * @param cmds the component commands
277     * @return the compound command
278     */
279    MemberEditCommand createCompoundCommand(MemberEditCommand... cmds);
280
281    // commands to change the structure of the member cache
282
283    /**
284     * Creates a command to delete a member and its descendants from the member
285     * cache.
286     *
287     * @param member the member
288     * @return the command
289     */
290    MemberEditCommand createDeleteCommand(Member member);
291
292    /**
293     * Creates a command to delete a set of members from the member cache.
294     *
295     * @param memberSet the set
296     * @return the command
297     */
298    MemberEditCommand createDeleteCommand(MemberSet memberSet);
299
300    /**
301     * Creates a command to add a member to the cache. The added member and its
302     * parent must have the same Dimension and the correct Levels, Null parent
303     * means add to the top level of its Dimension.
304     *
305     * <p>The ordinal position of the new member among its siblings is implied
306     * by its properties.</p>
307     *
308     * @param member the new member
309     * @return the command
310     *
311     * @throws IllegalArgumentException if member null
312     * or if member belongs to a parent-child hierarchy
313     */
314    MemberEditCommand createAddCommand(
315        Member member) throws IllegalArgumentException;
316
317    /**
318     * Creates a command to Move a member (with its descendants) to a new
319     * location, that is to a new parent.
320     * @param member the member moved
321     * @param loc    the new parent
322     * @return the command
323     *
324     * @throws IllegalArgumentException if member is null,
325     * or loc is null,
326     * or member belongs to a parent-child hierarchy,
327     * or if loc is incompatible with member
328     */
329    MemberEditCommand createMoveCommand(
330        Member member,
331        Member loc) throws IllegalArgumentException;
332
333    // commands to change member properties
334
335    /**
336     * Creates a command to change one property of a member.
337     *
338     * @param member the member
339     * @param name the property name
340     * @param value the property value
341     * @return the command
342     * @throws IllegalArgumentException if the property is invalid for the
343     *  member
344     */
345    MemberEditCommand createSetPropertyCommand(
346        Member member,
347        String name,
348        Object value) throws IllegalArgumentException;
349
350    /**
351     * Creates a command to several properties changes over a set of
352     * members. All members must belong to the same Level.
353     *
354     * @param set the set of members
355     * @param propertyValues Collection of property-value pairs
356     * @return the command
357     * @throws IllegalArgumentException for an invalid property, or if all
358     * members in the set do not belong to the same Level.
359     */
360    MemberEditCommand createSetPropertyCommand(
361        MemberSet set,
362        Map<String, Object> propertyValues)
363        throws IllegalArgumentException;
364
365    // other
366
367    /**
368     * Prints a debug message.
369     *
370     * @param message the message
371     */
372    void trace(String message);
373
374    /**
375     * Tells if tracing is enabled.
376     */
377    boolean isTraceEnabled();
378
379    /**
380     * Flushes the cache which maps schema URLs to metadata.
381     *
382     * <p>This cache is referenced only when creating a new connection, so
383     * existing connections will continue to use the same schema definition.
384     *
385     * <p>Flushing the schema cache will flush all aggregations and segments
386     * associated to it as well.
387     */
388    void flushSchemaCache();
389
390    /**
391     * Flushes the given Schema instance from the pool. It resolves the
392     * schema to flush by using its catalog URL, connection key and
393     * JDBC username.
394     *
395     * <p>Flushing the schema cache will flush all aggregations and segments
396     * associated to it as well.
397     */
398    void flushSchema(
399        final String catalogUrl,
400        final String connectionKey,
401        final String jdbcUser,
402        String dataSourceStr);
403
404    /**
405     * Flushes the given Schema instance from the pool. It resolves the
406     * schema to flush by using its catalog URL and DataSource object.
407     *
408     * <p>Flushing the schema cache will flush all aggregations and segments
409     * associated to it as well.
410     */
411    void flushSchema(
412        String catalogUrl,
413        DataSource dataSource);
414
415    /**
416     * Flushes the given Schema instance from the pool
417     *
418     * <p>Flushing the schema cache will flush all aggregations and segments
419     * associated to it as well.
420     *
421     * @param schema Schema
422     */
423    void flushSchema(Schema schema);
424
425    /** a region of cells in the cell cache */
426    public interface CellRegion {
427        /**
428         * Returns the dimensionality of a region.
429         * @return a list of {@link mondrian.olap.Dimension} objects.
430         */
431        List<Dimension> getDimensionality();
432    }
433
434    /**
435     * A specification of a set of members in the member cache.
436     *
437     * <p>Member sets can be created using methods
438     * {@link CacheControl#createMemberSet(Member, boolean)},
439     * {@link CacheControl#createMemberSet(boolean, Member, boolean, Member, boolean)},
440     * {@link CacheControl#createUnionSet(mondrian.olap.CacheControl.MemberSet[])}.
441     */
442    public interface MemberSet {
443    }
444
445    /**
446     * An operation to be applied to the member cache. The operation does not
447     * take effect until {@link CacheControl#execute} is called.
448     */
449    public interface MemberEditCommand {
450    }
451
452}
453
454// End CacheControl.java