*/
public ISqlJetFile open(final File path, final SqlJetFileType type, final Set<SqlJetFileOpenPermission> permissions)
throws SqlJetException {
if (null == type)
throw new SqlJetException(SqlJetErrorCode.BAD_PARAMETER, "File type must not be null to open file");
if (null == permissions || permissions.isEmpty())
throw new SqlJetException(SqlJetErrorCode.BAD_PARAMETER,
"Permissions must not be null or empty to open file");
boolean isExclusive = permissions.contains(SqlJetFileOpenPermission.EXCLUSIVE);
boolean isDelete = permissions.contains(SqlJetFileOpenPermission.DELETEONCLOSE);
boolean isCreate = permissions.contains(SqlJetFileOpenPermission.CREATE);
boolean isReadonly = permissions.contains(SqlJetFileOpenPermission.READONLY);
boolean isReadWrite = permissions.contains(SqlJetFileOpenPermission.READWRITE);
/*
* Check the following statements are true:
*
* (a) Exactly one of the READWRITE and READONLY flags must be set, and
* (b) if CREATE is set, then READWRITE must also be set, and (c) if
* EXCLUSIVE is set, then CREATE must also be set. (d) if DELETEONCLOSE
* is set, then CREATE must also be set.
*/
assert ((!isReadonly || !isReadWrite) && (isReadWrite || isReadonly));
assert (!isCreate || isReadWrite);
assert (!isExclusive || isCreate);
assert (!isDelete || isCreate);
/*
* The main DB, main journal, and master journal are never automatically
* deleted
*/
assert (SqlJetFileType.MAIN_DB != type || !isDelete);
assert (SqlJetFileType.MAIN_JOURNAL != type || !isDelete);
assert (SqlJetFileType.MASTER_JOURNAL != type || !isDelete);
final File filePath;
if (null != path) {
try {
filePath = path.getCanonicalFile();
} catch (IOException e) {
// TODO may through exception for missing file.
throw new SqlJetException(SqlJetErrorCode.CANTOPEN, e);
}
} else {
assert (isDelete && !(isCreate && (SqlJetFileType.MASTER_JOURNAL == type || SqlJetFileType.MAIN_JOURNAL == type)));
try {
filePath = getTempFile();
} catch (IOException e) {
throw new SqlJetException(SqlJetErrorCode.CANTOPEN, e);
}
assert (null != filePath);
}
if (!isReadWrite && !(filePath.isFile() && filePath.canRead())) {
throw new SqlJetException(SqlJetErrorCode.CANTOPEN);
}
String mode = "rw";
if (isReadonly && !isReadWrite && !isCreate && !isExclusive) {
mode = "r";
} else if (isReadWrite && !isExclusive && filePath.isFile() && !filePath.canWrite() && filePath.canRead()) {
// force opening as read only.
Set<SqlJetFileOpenPermission> ro = EnumSet.copyOf(permissions);
ro.remove(SqlJetFileOpenPermission.READWRITE);
ro.remove(SqlJetFileOpenPermission.CREATE);
ro.add(SqlJetFileOpenPermission.READONLY);
return open(filePath, type, ro);
}
RandomAccessFile file = null;
try {
file = SqlJetFileUtil.openFile(filePath, mode);
} catch (FileNotFoundException e) {
if (isReadWrite && !isExclusive) {
/* Failed to open the file for read/write access. Try read-only. */
Set<SqlJetFileOpenPermission> ro = EnumSet.copyOf(permissions);
ro.remove(SqlJetFileOpenPermission.READWRITE);
ro.remove(SqlJetFileOpenPermission.CREATE);
ro.add(SqlJetFileOpenPermission.READONLY);
return open(filePath, type, ro);
}
throw new SqlJetException(SqlJetErrorCode.CANTOPEN);
}
boolean noLock = SqlJetFileType.MAIN_DB != type;
return new SqlJetFile(this, file, filePath, type, permissions, noLock);