152 lines
6.1 KiB
Java
152 lines
6.1 KiB
Java
package androidx.room;
|
|
|
|
import android.content.Context;
|
|
import android.util.Log;
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.annotation.RequiresApi;
|
|
import androidx.room.util.CopyLock;
|
|
import androidx.room.util.DBUtil;
|
|
import androidx.room.util.FileUtil;
|
|
import androidx.sqlite.db.SupportSQLiteDatabase;
|
|
import androidx.sqlite.db.SupportSQLiteOpenHelper;
|
|
import c.d.b.a.a;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.nio.channels.Channels;
|
|
import java.nio.channels.ReadableByteChannel;
|
|
public class SQLiteCopyOpenHelper implements SupportSQLiteOpenHelper {
|
|
@NonNull
|
|
private final Context mContext;
|
|
@Nullable
|
|
private final String mCopyFromAssetPath;
|
|
@Nullable
|
|
private final File mCopyFromFile;
|
|
@Nullable
|
|
private DatabaseConfiguration mDatabaseConfiguration;
|
|
private final int mDatabaseVersion;
|
|
@NonNull
|
|
private final SupportSQLiteOpenHelper mDelegate;
|
|
private boolean mVerified;
|
|
|
|
public SQLiteCopyOpenHelper(@NonNull Context context, @Nullable String str, @Nullable File file, int i, @NonNull SupportSQLiteOpenHelper supportSQLiteOpenHelper) {
|
|
this.mContext = context;
|
|
this.mCopyFromAssetPath = str;
|
|
this.mCopyFromFile = file;
|
|
this.mDatabaseVersion = i;
|
|
this.mDelegate = supportSQLiteOpenHelper;
|
|
}
|
|
|
|
private void copyDatabaseFile(File file) throws IOException {
|
|
ReadableByteChannel readableByteChannel;
|
|
if (this.mCopyFromAssetPath != null) {
|
|
readableByteChannel = Channels.newChannel(this.mContext.getAssets().open(this.mCopyFromAssetPath));
|
|
} else if (this.mCopyFromFile != null) {
|
|
readableByteChannel = new FileInputStream(this.mCopyFromFile).getChannel();
|
|
} else {
|
|
throw new IllegalStateException("copyFromAssetPath and copyFromFile == null!");
|
|
}
|
|
File createTempFile = File.createTempFile("room-copy-helper", ".tmp", this.mContext.getCacheDir());
|
|
createTempFile.deleteOnExit();
|
|
FileUtil.copy(readableByteChannel, new FileOutputStream(createTempFile).getChannel());
|
|
File parentFile = file.getParentFile();
|
|
if (parentFile != null && !parentFile.exists() && !parentFile.mkdirs()) {
|
|
StringBuilder L = a.L("Failed to create directories for ");
|
|
L.append(file.getAbsolutePath());
|
|
throw new IOException(L.toString());
|
|
} else if (!createTempFile.renameTo(file)) {
|
|
StringBuilder L2 = a.L("Failed to move intermediate file (");
|
|
L2.append(createTempFile.getAbsolutePath());
|
|
L2.append(") to destination (");
|
|
L2.append(file.getAbsolutePath());
|
|
L2.append(").");
|
|
throw new IOException(L2.toString());
|
|
}
|
|
}
|
|
|
|
private void verifyDatabaseFile() {
|
|
String databaseName = getDatabaseName();
|
|
File databasePath = this.mContext.getDatabasePath(databaseName);
|
|
DatabaseConfiguration databaseConfiguration = this.mDatabaseConfiguration;
|
|
CopyLock copyLock = new CopyLock(databaseName, this.mContext.getFilesDir(), databaseConfiguration == null || databaseConfiguration.multiInstanceInvalidation);
|
|
try {
|
|
copyLock.lock();
|
|
if (!databasePath.exists()) {
|
|
try {
|
|
copyDatabaseFile(databasePath);
|
|
} catch (IOException e) {
|
|
throw new RuntimeException("Unable to copy database file.", e);
|
|
}
|
|
} else if (this.mDatabaseConfiguration == null) {
|
|
copyLock.unlock();
|
|
} else {
|
|
try {
|
|
int readVersion = DBUtil.readVersion(databasePath);
|
|
int i = this.mDatabaseVersion;
|
|
if (readVersion == i) {
|
|
copyLock.unlock();
|
|
} else if (this.mDatabaseConfiguration.isMigrationRequired(readVersion, i)) {
|
|
copyLock.unlock();
|
|
} else {
|
|
if (this.mContext.deleteDatabase(databaseName)) {
|
|
try {
|
|
copyDatabaseFile(databasePath);
|
|
} catch (IOException e2) {
|
|
Log.w("ROOM", "Unable to copy database file.", e2);
|
|
}
|
|
} else {
|
|
Log.w("ROOM", "Failed to delete database file (" + databaseName + ") for a copy destructive migration.");
|
|
}
|
|
copyLock.unlock();
|
|
}
|
|
} catch (IOException e3) {
|
|
Log.w("ROOM", "Unable to read database version.", e3);
|
|
copyLock.unlock();
|
|
}
|
|
}
|
|
} finally {
|
|
copyLock.unlock();
|
|
}
|
|
}
|
|
|
|
@Override // androidx.sqlite.db.SupportSQLiteOpenHelper, java.io.Closeable, java.lang.AutoCloseable
|
|
public synchronized void close() {
|
|
this.mDelegate.close();
|
|
this.mVerified = false;
|
|
}
|
|
|
|
@Override // androidx.sqlite.db.SupportSQLiteOpenHelper
|
|
public String getDatabaseName() {
|
|
return this.mDelegate.getDatabaseName();
|
|
}
|
|
|
|
@Override // androidx.sqlite.db.SupportSQLiteOpenHelper
|
|
public synchronized SupportSQLiteDatabase getReadableDatabase() {
|
|
if (!this.mVerified) {
|
|
verifyDatabaseFile();
|
|
this.mVerified = true;
|
|
}
|
|
return this.mDelegate.getReadableDatabase();
|
|
}
|
|
|
|
@Override // androidx.sqlite.db.SupportSQLiteOpenHelper
|
|
public synchronized SupportSQLiteDatabase getWritableDatabase() {
|
|
if (!this.mVerified) {
|
|
verifyDatabaseFile();
|
|
this.mVerified = true;
|
|
}
|
|
return this.mDelegate.getWritableDatabase();
|
|
}
|
|
|
|
public void setDatabaseConfiguration(@Nullable DatabaseConfiguration databaseConfiguration) {
|
|
this.mDatabaseConfiguration = databaseConfiguration;
|
|
}
|
|
|
|
@Override // androidx.sqlite.db.SupportSQLiteOpenHelper
|
|
@RequiresApi(api = 16)
|
|
public void setWriteAheadLoggingEnabled(boolean z2) {
|
|
this.mDelegate.setWriteAheadLoggingEnabled(z2);
|
|
}
|
|
}
|