You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Database.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*
  2. Copyright (c) 2013 James Ahlborn
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package com.healthmarketscience.jackcess;
  14. import java.io.Closeable;
  15. import java.io.File;
  16. import java.io.Flushable;
  17. import java.io.IOException;
  18. import java.nio.charset.Charset;
  19. import java.util.ConcurrentModificationException;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Set;
  24. import java.util.TimeZone;
  25. import com.healthmarketscience.jackcess.query.Query;
  26. import com.healthmarketscience.jackcess.impl.DatabaseImpl;
  27. import com.healthmarketscience.jackcess.util.ColumnValidatorFactory;
  28. import com.healthmarketscience.jackcess.util.ErrorHandler;
  29. import com.healthmarketscience.jackcess.util.LinkResolver;
  30. import com.healthmarketscience.jackcess.util.TableIterableBuilder;
  31. /**
  32. * An Access database instance. A new instance can be instantiated by opening
  33. * an existing database file ({@link DatabaseBuilder#open(File)}) or creating
  34. * a new database file ({@link DatabaseBuilder#create(Database.FileFormat,File)}) (for
  35. * more advanced opening/creating use {@link DatabaseBuilder}). Once a
  36. * Database has been opened, you can interact with the data via the relevant
  37. * {@link Table}. When a Database instance is no longer useful, it should
  38. * <b>always</b> be closed ({@link #close}) to avoid corruption.
  39. * <p/>
  40. * Database instances (and all the related objects) are <i>not</i>
  41. * thread-safe. However, separate Database instances (and their respective
  42. * objects) can be used by separate threads without a problem.
  43. * <p/>
  44. * Database instances do not implement any "transactional" support, and
  45. * therefore concurrent editing of the same database file by multiple Database
  46. * instances (or with outside programs such as MS Access) <i>will generally
  47. * result in database file corruption</i>.
  48. *
  49. * @author James Ahlborn
  50. * @usage _general_class_
  51. */
  52. public interface Database extends Iterable<Table>, Closeable, Flushable
  53. {
  54. /** default value for the auto-sync value ({@code true}). this is slower,
  55. * but leaves more chance of a useable database in the face of failures.
  56. * @usage _general_field_
  57. */
  58. public static final boolean DEFAULT_AUTO_SYNC = true;
  59. /**
  60. * the default sort order for table columns.
  61. * @usage _intermediate_field_
  62. */
  63. public static final Table.ColumnOrder DEFAULT_COLUMN_ORDER =
  64. Table.ColumnOrder.DATA;
  65. /** system property which can be used to set the default TimeZone used for
  66. * date calculations.
  67. * @usage _general_field_
  68. */
  69. public static final String TIMEZONE_PROPERTY =
  70. "com.healthmarketscience.jackcess.timeZone";
  71. /** system property prefix which can be used to set the default Charset
  72. * used for text data (full property includes the JetFormat version).
  73. * @usage _general_field_
  74. */
  75. public static final String CHARSET_PROPERTY_PREFIX =
  76. "com.healthmarketscience.jackcess.charset.";
  77. /** system property which can be used to set the path from which classpath
  78. * resources are loaded (must end with a "/" if non-empty). Default value
  79. * is {@value com.healthmarketscience.jackcess.impl.DatabaseImpl#DEFAULT_RESOURCE_PATH}
  80. * if unspecified.
  81. * @usage _general_field_
  82. */
  83. public static final String RESOURCE_PATH_PROPERTY =
  84. "com.healthmarketscience.jackcess.resourcePath";
  85. /** (boolean) system property which can be used to indicate that the current
  86. * vm has a poor nio implementation (specifically for
  87. * {@code FileChannel.transferFrom})
  88. * @usage _intermediate_field_
  89. */
  90. public static final String BROKEN_NIO_PROPERTY =
  91. "com.healthmarketscience.jackcess.brokenNio";
  92. /** system property which can be used to set the default sort order for
  93. * table columns. Value should be one {@link Table.ColumnOrder} enum
  94. * values.
  95. * @usage _intermediate_field_
  96. */
  97. public static final String COLUMN_ORDER_PROPERTY =
  98. "com.healthmarketscience.jackcess.columnOrder";
  99. /** system property which can be used to set the default enforcement of
  100. * foreign-key relationships. Defaults to {@code true}.
  101. * @usage _general_field_
  102. */
  103. public static final String FK_ENFORCE_PROPERTY =
  104. "com.healthmarketscience.jackcess.enforceForeignKeys";
  105. /**
  106. * Enum which indicates which version of Access created the database.
  107. * @usage _general_class_
  108. */
  109. public enum FileFormat {
  110. V1997(".mdb"),
  111. V2000(".mdb"),
  112. V2003(".mdb"),
  113. V2007(".accdb"),
  114. V2010(".accdb"),
  115. MSISAM(".mny");
  116. private final String _ext;
  117. private FileFormat(String ext) {
  118. _ext = ext;
  119. }
  120. /**
  121. * @return the file extension used for database files with this format.
  122. */
  123. public String getFileExtension() { return _ext; }
  124. @Override
  125. public String toString() {
  126. return name() + " [" + DatabaseImpl.getFileFormatDetails(this).getFormat() + "]";
  127. }
  128. }
  129. /**
  130. * Returns the File underlying this Database
  131. */
  132. public File getFile();
  133. /**
  134. * @return The names of all of the user tables
  135. * @usage _general_method_
  136. */
  137. public Set<String> getTableNames() throws IOException;
  138. /**
  139. * @return The names of all of the system tables (String). Note, in order
  140. * to read these tables, you must use {@link #getSystemTable}.
  141. * <i>Extreme care should be taken if modifying these tables
  142. * directly!</i>.
  143. * @usage _intermediate_method_
  144. */
  145. public Set<String> getSystemTableNames() throws IOException;
  146. /**
  147. * @return an unmodifiable Iterator of the user Tables in this Database.
  148. * @throws RuntimeIOException if an IOException is thrown by one of the
  149. * operations, the actual exception will be contained within
  150. * @throws ConcurrentModificationException if a table is added to the
  151. * database while an Iterator is in use.
  152. * @usage _general_method_
  153. */
  154. public Iterator<Table> iterator();
  155. /**
  156. * Convenience method for constructing a new TableIterableBuilder for this
  157. * cursor. A TableIterableBuilder provides a variety of options for more
  158. * flexible iteration of Tables.
  159. */
  160. public TableIterableBuilder newIterable();
  161. /**
  162. * @param name Table name (case-insensitive)
  163. * @return The table, or null if it doesn't exist
  164. * @usage _general_method_
  165. */
  166. public Table getTable(String name) throws IOException;
  167. /**
  168. * Finds all the relationships in the database between the given tables.
  169. * @usage _intermediate_method_
  170. */
  171. public List<Relationship> getRelationships(Table table1, Table table2)
  172. throws IOException;
  173. /**
  174. * Finds all the relationships in the database for the given table.
  175. * @usage _intermediate_method_
  176. */
  177. public List<Relationship> getRelationships(Table table) throws IOException;
  178. /**
  179. * Finds all the relationships in the database in <i>non-system</i> tables.
  180. * </p>
  181. * Warning, this may load <i>all</i> the Tables (metadata, not data) in the
  182. * database which could cause memory issues.
  183. * @usage _intermediate_method_
  184. */
  185. public List<Relationship> getRelationships() throws IOException;
  186. /**
  187. * Finds <i>all</i> the relationships in the database, <i>including system
  188. * tables</i>.
  189. * </p>
  190. * Warning, this may load <i>all</i> the Tables (metadata, not data) in the
  191. * database which could cause memory issues.
  192. * @usage _intermediate_method_
  193. */
  194. public List<Relationship> getSystemRelationships()
  195. throws IOException;
  196. /**
  197. * Finds all the queries in the database.
  198. * @usage _intermediate_method_
  199. */
  200. public List<Query> getQueries() throws IOException;
  201. /**
  202. * Returns a reference to <i>any</i> available table in this access
  203. * database, including system tables.
  204. * <p>
  205. * Warning, this method is not designed for common use, only for the
  206. * occassional time when access to a system table is necessary. Messing
  207. * with system tables can strip the paint off your house and give your whole
  208. * family a permanent, orange afro. You have been warned.
  209. *
  210. * @param tableName Table name, may be a system table
  211. * @return The table, or {@code null} if it doesn't exist
  212. * @usage _intermediate_method_
  213. */
  214. public Table getSystemTable(String tableName) throws IOException;
  215. /**
  216. * @return the core properties for the database
  217. * @usage _general_method_
  218. */
  219. public PropertyMap getDatabaseProperties() throws IOException;
  220. /**
  221. * @return the summary properties for the database
  222. * @usage _general_method_
  223. */
  224. public PropertyMap getSummaryProperties() throws IOException;
  225. /**
  226. * @return the user-defined properties for the database
  227. * @usage _general_method_
  228. */
  229. public PropertyMap getUserDefinedProperties() throws IOException;
  230. /**
  231. * @return the current database password, or {@code null} if none set.
  232. * @usage _general_method_
  233. */
  234. public String getDatabasePassword() throws IOException;
  235. /**
  236. * Create a new table in this database
  237. * @param name Name of the table to create in this database
  238. * @param linkedDbName path to the linked database
  239. * @param linkedTableName name of the table in the linked database
  240. * @usage _general_method_
  241. */
  242. public void createLinkedTable(String name, String linkedDbName,
  243. String linkedTableName)
  244. throws IOException;
  245. /**
  246. * Flushes any current changes to the database file (and any linked
  247. * databases) to disk.
  248. * @usage _general_method_
  249. */
  250. public void flush() throws IOException;
  251. /**
  252. * Close the database file (and any linked databases). A Database
  253. * <b>must</b> be closed after use or changes could be lost and the Database
  254. * file corrupted. A Database instance should be treated like any other
  255. * external resource which would be closed in a finally block (e.g. an
  256. * OutputStream or jdbc Connection).
  257. * @usage _general_method_
  258. */
  259. public void close() throws IOException;
  260. /**
  261. * Gets the currently configured ErrorHandler (always non-{@code null}).
  262. * This will be used to handle all errors unless overridden at the Table or
  263. * Cursor level.
  264. * @usage _intermediate_method_
  265. */
  266. public ErrorHandler getErrorHandler();
  267. /**
  268. * Sets a new ErrorHandler. If {@code null}, resets to the
  269. * {@link ErrorHandler#DEFAULT}.
  270. * @usage _intermediate_method_
  271. */
  272. public void setErrorHandler(ErrorHandler newErrorHandler);
  273. /**
  274. * Gets the currently configured LinkResolver (always non-{@code null}).
  275. * This will be used to handle all linked database loading.
  276. * @usage _intermediate_method_
  277. */
  278. public LinkResolver getLinkResolver();
  279. /**
  280. * Sets a new LinkResolver. If {@code null}, resets to the
  281. * {@link LinkResolver#DEFAULT}.
  282. * @usage _intermediate_method_
  283. */
  284. public void setLinkResolver(LinkResolver newLinkResolver);
  285. /**
  286. * Returns an unmodifiable view of the currently loaded linked databases,
  287. * mapped from the linked database file name to the linked database. This
  288. * information may be useful for implementing a LinkResolver.
  289. * @usage _intermediate_method_
  290. */
  291. public Map<String,Database> getLinkedDatabases();
  292. /**
  293. * Returns {@code true} if this Database links to the given Table, {@code
  294. * false} otherwise.
  295. * @usage _general_method_
  296. */
  297. public boolean isLinkedTable(Table table) throws IOException;
  298. /**
  299. * Gets currently configured TimeZone (always non-{@code null}).
  300. * @usage _intermediate_method_
  301. */
  302. public TimeZone getTimeZone();
  303. /**
  304. * Sets a new TimeZone. If {@code null}, resets to the default value.
  305. * @usage _intermediate_method_
  306. */
  307. public void setTimeZone(TimeZone newTimeZone);
  308. /**
  309. * Gets currently configured Charset (always non-{@code null}).
  310. * @usage _intermediate_method_
  311. */
  312. public Charset getCharset();
  313. /**
  314. * Sets a new Charset. If {@code null}, resets to the default value.
  315. * @usage _intermediate_method_
  316. */
  317. public void setCharset(Charset newCharset);
  318. /**
  319. * Gets currently configured {@link Table.ColumnOrder} (always non-{@code
  320. * null}).
  321. * @usage _intermediate_method_
  322. */
  323. public Table.ColumnOrder getColumnOrder();
  324. /**
  325. * Sets a new Table.ColumnOrder. If {@code null}, resets to the default value.
  326. * @usage _intermediate_method_
  327. */
  328. public void setColumnOrder(Table.ColumnOrder newColumnOrder);
  329. /**
  330. * Gets current foreign-key enforcement policy.
  331. * @usage _intermediate_method_
  332. */
  333. public boolean isEnforceForeignKeys();
  334. /**
  335. * Sets a new foreign-key enforcement policy. If {@code null}, resets to
  336. * the default value.
  337. * @usage _intermediate_method_
  338. */
  339. public void setEnforceForeignKeys(Boolean newEnforceForeignKeys);
  340. /**
  341. * Gets currently configured ColumnValidatorFactory (always non-{@code null}).
  342. * @usage _intermediate_method_
  343. */
  344. public ColumnValidatorFactory getColumnValidatorFactory();
  345. /**
  346. * Sets a new ColumnValidatorFactory. If {@code null}, resets to the
  347. * default value. The configured ColumnValidatorFactory will be used to
  348. * create ColumnValidator instances on any <i>user</i> tables loaded from
  349. * this point onward (this will not be used for system tables).
  350. * @usage _intermediate_method_
  351. */
  352. public void setColumnValidatorFactory(ColumnValidatorFactory newFactory);
  353. /**
  354. * Returns the FileFormat of this database (which may involve inspecting the
  355. * database itself).
  356. * @throws IllegalStateException if the file format cannot be determined
  357. * @usage _general_method_
  358. */
  359. public FileFormat getFileFormat() throws IOException;
  360. }