View Javadoc
1   /*
2   Copyright (c) 2013 James Ahlborn
3   
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7   
8       http://www.apache.org/licenses/LICENSE-2.0
9   
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15  */
16  
17  package com.healthmarketscience.jackcess;
18  
19  import java.io.IOException;
20  import java.io.UncheckedIOException;
21  import java.time.LocalDateTime;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.stream.Stream;
26  import java.util.stream.StreamSupport;
27  
28  import com.healthmarketscience.jackcess.util.ErrorHandler;
29  import com.healthmarketscience.jackcess.util.OleBlob;
30  
31  /**
32   * A single database table.  A Table instance is retrieved from a {@link
33   * Database} instance.  The Table instance provides access to the table
34   * metadata as well as the table data.  There are basic data operations on the
35   * Table interface (i.e. {@link #iterator} {@link #addRow}, {@link #updateRow}
36   * and {@link #deleteRow}), but for advanced search and data manipulation a
37   * {@link Cursor} instance should be used.  New Tables can be created using a
38   * {@link TableBuilder}.  The {@link com.healthmarketscience.jackcess.util.Joiner} utility can be used to traverse
39   * table relationships (e.g. find rows in another table based on a foreign-key
40   * relationship).
41   * <p>
42   * A Table instance is not thread-safe (see {@link Database} for more
43   * thread-safety details).
44   *
45   * @author James Ahlborn
46   * @usage _general_class_
47   */
48  public interface Table extends Iterable<Row>, TableDefinition
49  {
50    /**
51     * enum which controls the ordering of the columns in a table.
52     * @usage _intermediate_class_
53     */
54    public enum ColumnOrder {
55      /** columns are ordered based on the order of the data in the table (this
56          order does not change as columns are added to the table). */
57      DATA,
58      /** columns are ordered based on the "display" order (this order can be
59          changed arbitrarily) */
60      DISPLAY;
61    }
62  
63    /**
64     * @return The name of the table
65     * @usage _general_method_
66     */
67    @Override
68    public String getName();
69  
70    /**
71     * Whether or not this table has been marked as hidden.
72     * @usage _general_method_
73     */
74    @Override
75    public boolean isHidden();
76  
77    /**
78     * Whether or not this table is a system (internal) table.
79     * @usage _general_method_
80     */
81    @Override
82    public boolean isSystem();
83  
84    /**
85     * @usage _general_method_
86     */
87    @Override
88    public int getColumnCount();
89  
90    /**
91     * @usage _general_method_
92     */
93    @Override
94    public Database getDatabase();
95  
96    /**
97     * Gets the currently configured ErrorHandler (always non-{@code null}).
98     * This will be used to handle all errors unless overridden at the Cursor
99     * level.
100    * @usage _intermediate_method_
101    */
102   public ErrorHandler getErrorHandler();
103 
104   /**
105    * Sets a new ErrorHandler.  If {@code null}, resets to using the
106    * ErrorHandler configured at the Database level.
107    * @usage _intermediate_method_
108    */
109   public void setErrorHandler(ErrorHandler newErrorHandler);
110 
111   /**
112    * Gets the currently configured auto number insert policy.
113    * @see Database#isAllowAutoNumberInsert
114    * @usage _intermediate_method_
115    */
116   public boolean isAllowAutoNumberInsert();
117 
118   /**
119    * Sets the new auto number insert policy for the Table.  If {@code null},
120    * resets to using the policy configured at the Database level.
121    * @usage _intermediate_method_
122    */
123   public void setAllowAutoNumberInsert(Boolean allowAutoNumInsert);
124 
125   /**
126    * @return All of the columns in this table (unmodifiable List)
127    * @usage _general_method_
128    */
129   @Override
130   public List<? extends Column> getColumns();
131 
132   /**
133    * @return the column with the given name
134    * @usage _general_method_
135    */
136   @Override
137   public Column getColumn(String name);
138 
139   /**
140    * @return the properties for this table
141    * @usage _general_method_
142    */
143   @Override
144   public PropertyMap getProperties() throws IOException;
145 
146   /**
147    * @return the name map for this table, or {@code null} if the table has
148    *         none
149    * @usage _intermediate_method_
150    */
151   public TableNameMap getNameMap() throws IOException;
152 
153   /**
154    * @return the created date for this table if available
155    * @usage _general_method_
156    */
157   @Override
158   public LocalDateTime getCreatedDate() throws IOException;
159 
160   /**
161    * Note: jackcess <i>does not automatically update the modified date of a
162    * Table</i>.
163    *
164    * @return the last updated date for this table if available
165    * @usage _general_method_
166    */
167   @Override
168   public LocalDateTime getUpdatedDate() throws IOException;
169 
170   /**
171    * @return All of the Indexes on this table (unmodifiable List)
172    * @usage _intermediate_method_
173    */
174   @Override
175   public List<? extends Index> getIndexes();
176 
177   /**
178    * @return the index with the given name
179    * @throws IllegalArgumentException if there is no index with the given name
180    * @usage _intermediate_method_
181    */
182   @Override
183   public Index getIndex(String name);
184 
185   /**
186    * @return the primary key index for this table
187    * @throws IllegalArgumentException if there is no primary key index on this
188    *         table
189    * @usage _intermediate_method_
190    */
191   @Override
192   public Index getPrimaryKeyIndex();
193 
194   /**
195    * @return the foreign key index joining this table to the given other table
196    * @throws IllegalArgumentException if there is no relationship between this
197    *         table and the given table
198    * @usage _intermediate_method_
199    */
200   @Override
201   public Index getForeignKeyIndex(Table otherTable);
202 
203   /**
204    * Converts a map of columnName -&gt; columnValue to an array of row values
205    * appropriate for a call to {@link #addRow(Object...)}.
206    * @usage _general_method_
207    */
208   public Object[] asRow(Map<String,?> rowMap);
209 
210   /**
211    * Converts a map of columnName -&gt; columnValue to an array of row values
212    * appropriate for a call to {@link Cursor#updateCurrentRow(Object...)}.
213    * @usage _general_method_
214    */
215   public Object[] asUpdateRow(Map<String,?> rowMap);
216 
217   /**
218    * @usage _general_method_
219    */
220   public int getRowCount();
221 
222   /**
223    * Adds a single row to this table and writes it to disk.  The values are
224    * expected to be given in the order that the Columns are listed by the
225    * {@link #getColumns} method.  This is by default the storage order of the
226    * Columns in the database, however this order can be influenced by setting
227    * the ColumnOrder via {@link Database#setColumnOrder} prior to opening
228    * the Table.  The {@link #asRow} method can be used to easily convert a row
229    * Map into the appropriate row array for this Table.
230    * <p>
231    * Note, if this table has an auto-number column, the value generated will be
232    * put back into the given row array (assuming the given row array is at
233    * least as long as the number of Columns in this Table).
234    *
235    * @param row row values for a single row.  the given row array will be
236    *            modified if this table contains an auto-number column,
237    *            otherwise it will not be modified.
238    * @return the given row values if long enough, otherwise a new array.  the
239    *         returned array will contain any autonumbers generated
240    * @usage _general_method_
241    */
242   public Object[] addRow(Object... row) throws IOException;
243 
244   /**
245    * Calls {@link #asRow} on the given row map and passes the result to {@link
246    * #addRow}.
247    * <p>
248    * Note, if this table has an auto-number column, the value generated will be
249    * put back into the given row map.
250    * @return the given row map, which will contain any autonumbers generated
251    * @usage _general_method_
252    */
253   public <M extends Map<String,Object>> M addRowFromMap(M row)
254     throws IOException;
255 
256   /**
257    * Add multiple rows to this table, only writing to disk after all
258    * rows have been written, and every time a data page is filled.  This
259    * is much more efficient than calling {@link #addRow} multiple times.
260    * <p>
261    * Note, if this table has an auto-number column, the values written will be
262    * put back into the given row arrays (assuming the given row array is at
263    * least as long as the number of Columns in this Table).
264    * <p>
265    * Most exceptions thrown from this method will be wrapped with a {@link
266    * BatchUpdateException} which gives useful information in the case of a
267    * partially successful write.
268    *
269    * @see #addRow(Object...) for more details on row arrays
270    *
271    * @param rows List of Object[] row values.  the rows will be modified if
272    *             this table contains an auto-number column, otherwise they
273    *             will not be modified.
274    * @return the given row values list (unless row values were to small), with
275    *         appropriately sized row values (the ones passed in if long
276    *         enough).  the returned arrays will contain any autonumbers
277    *         generated
278    * @usage _general_method_
279    */
280   public List<? extends Object[]> addRows(List<? extends Object[]> rows)
281     throws IOException;
282 
283   /**
284    * Calls {@link #asRow} on the given row maps and passes the results to
285    * {@link #addRows}.
286    * <p>
287    * Note, if this table has an auto-number column, the values generated will
288    * be put back into the appropriate row maps.
289    * <p>
290    * Most exceptions thrown from this method will be wrapped with a {@link
291    * BatchUpdateException} which gives useful information in the case of a
292    * partially successful write.
293    *
294    * @return the given row map list, where the row maps will contain any
295    *         autonumbers generated
296    * @usage _general_method_
297    */
298   public <M extends Map<String,Object>> List<M> addRowsFromMaps(List<M> rows)
299     throws IOException;
300 
301   /**
302    * Update the given row.  Provided Row must have previously been returned
303    * from this Table.
304    * @return the given row, updated with the current row values
305    * @throws IllegalStateException if the given row is not valid, or deleted.
306    */
307   public Rowf="../../../com/healthmarketscience/jackcess/Row.html#Row">Row updateRow(Row row) throws IOException;
308 
309   /**
310    * Delete the given row.  Provided Row must have previously been returned
311    * from this Table.
312    * @return the given row
313    * @throws IllegalStateException if the given row is not valid
314    */
315   public Rowf="../../../com/healthmarketscience/jackcess/Row.html#Row">Row deleteRow(Row row) throws IOException;
316 
317   /**
318    * Calls {@link #reset} on this table and returns a modifiable
319    * Iterator which will iterate through all the rows of this table.  Use of
320    * the Iterator follows the same restrictions as a call to
321    * {@link #getNextRow}.
322    * <p>
323    * For more advanced iteration, use the {@link #getDefaultCursor default
324    * cursor} directly.
325    * @throws UncheckedIOException if an IOException is thrown by one of the
326    *         operations, the actual exception will be contained within
327    * @usage _general_method_
328    */
329   @Override
330   public Iterator<Row> iterator();
331 
332   /**
333    * @return a Stream using the default Iterator.
334    */
335   default public Stream<Row> stream() {
336     return StreamSupport.stream(spliterator(), false);
337   }
338 
339   /**
340    * After calling this method, {@link #getNextRow} will return the first row
341    * in the table, see {@link Cursor#reset} (uses the {@link #getDefaultCursor
342    * default cursor}).
343    * @usage _general_method_
344    */
345   public void reset();
346 
347   /**
348    * @return The next row in this table (Column name -&gt; Column value) (uses
349    *         the {@link #getDefaultCursor default cursor})
350    * @usage _general_method_
351    */
352   public Row getNextRow() throws IOException;
353 
354   /**
355    * @return a simple Cursor, initialized on demand and held by this table.
356    *         This cursor backs the row traversal methods available on the
357    *         Table interface.  For advanced Table traversal and manipulation,
358    *         use the Cursor directly.
359    */
360   public Cursor getDefaultCursor();
361 
362   /**
363    * Convenience method for constructing a new CursorBuilder for this Table.
364    */
365   public CursorBuilder newCursor();
366 
367 
368   /**
369    * Convenience method for constructing a new OleBlob.Builder.
370    */
371   default public OleBlob.Builder newBlob() {
372     return new OleBlob.Builder();
373   }
374 }