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