DroidFS/app/src/main/java/sushi/hardcore/droidfs/VolumeDatabase.kt

162 lines
6.0 KiB
Kotlin
Raw Normal View History

package sushi.hardcore.droidfs
import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
2022-06-18 21:13:16 +02:00
import android.util.Log
import sushi.hardcore.droidfs.filesystems.EncryptedVolume
import sushi.hardcore.droidfs.util.PathUtils
import java.io.File
2022-06-18 21:13:16 +02:00
class VolumeDatabase(private val context: Context): SQLiteOpenHelper(context, ConstValues.VOLUME_DATABASE_NAME, null, 4) {
companion object {
const val TABLE_NAME = "Volumes"
const val COLUMN_NAME = "name"
const val COLUMN_HIDDEN = "hidden"
2022-06-18 21:13:16 +02:00
const val COLUMN_TYPE = "type"
const val COLUMN_HASH = "hash"
const val COLUMN_IV = "iv"
2022-06-18 21:13:16 +02:00
private fun contentValuesFromVolume(volume: SavedVolume): ContentValues {
val contentValues = ContentValues()
contentValues.put(COLUMN_NAME, volume.name)
contentValues.put(COLUMN_HIDDEN, volume.isHidden)
2022-06-18 21:13:16 +02:00
contentValues.put(COLUMN_TYPE, byteArrayOf(volume.type))
2022-03-05 12:51:02 +01:00
contentValues.put(COLUMN_HASH, volume.encryptedHash)
contentValues.put(COLUMN_IV, volume.iv)
return contentValues
}
}
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(
2022-06-18 21:13:16 +02:00
"CREATE TABLE IF NOT EXISTS $TABLE_NAME (" +
"$COLUMN_NAME TEXT PRIMARY KEY," +
"$COLUMN_HIDDEN SHORT," +
"$COLUMN_TYPE BLOB," +
"$COLUMN_HASH BLOB," +
"$COLUMN_IV BLOB" +
");"
)
2022-06-18 21:13:16 +02:00
File(context.filesDir, SavedVolume.VOLUMES_DIRECTORY).mkdir()
}
2022-06-18 21:13:16 +02:00
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
// Adding type column and set it to GOCRYPTFS_VOLUME_TYPE for all existing volumes
db.execSQL("ALTER TABLE $TABLE_NAME ADD COLUMN $COLUMN_TYPE BLOB;")
db.update(TABLE_NAME, ContentValues().apply {
put(COLUMN_TYPE, byteArrayOf(EncryptedVolume.GOCRYPTFS_VOLUME_TYPE))
}, null, null)
// Moving hidden volumes to the "volumes" directory
if (File(context.filesDir, SavedVolume.VOLUMES_DIRECTORY).mkdir()) {
val cursor = db.query(
TABLE_NAME,
arrayOf(COLUMN_NAME),
"$COLUMN_HIDDEN=?",
arrayOf("1"),
null,
null,
null
)
while (cursor.moveToNext()) {
val volumeName = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME))
File(
PathUtils.pathJoin(
context.filesDir.path,
volumeName
)
).renameTo(
File(
SavedVolume(
volumeName,
true,
EncryptedVolume.GOCRYPTFS_VOLUME_TYPE
).getFullPath(context.filesDir.path)
).canonicalFile
)
}
cursor.close()
} else {
Log.e("VolumeDatabase", "Volumes directory creation failed while upgrading")
}
}
2022-03-05 12:51:02 +01:00
fun isVolumeSaved(volumeName: String, isHidden: Boolean): Boolean {
val cursor = readableDatabase.query(TABLE_NAME,
arrayOf(COLUMN_NAME), "$COLUMN_NAME=? AND $COLUMN_HIDDEN=?",
arrayOf(volumeName, (if (isHidden) 1 else 0).toString()),
null, null, null
)
val result = cursor.count > 0
cursor.close()
return result
}
2022-06-18 21:13:16 +02:00
fun saveVolume(volume: SavedVolume): Boolean {
2022-03-05 12:51:02 +01:00
if (!isVolumeSaved(volume.name, volume.isHidden)) {
return (writableDatabase.insert(TABLE_NAME, null, contentValuesFromVolume(volume)) == 0.toLong())
}
return false
}
2022-06-18 21:13:16 +02:00
fun getVolumes(): List<SavedVolume> {
val list: MutableList<SavedVolume> = ArrayList()
val cursor = readableDatabase.rawQuery("SELECT * FROM $TABLE_NAME", null)
while (cursor.moveToNext()){
list.add(
2022-06-18 21:13:16 +02:00
SavedVolume(
cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME)),
cursor.getShort(cursor.getColumnIndexOrThrow(COLUMN_HIDDEN)) == 1.toShort(),
cursor.getBlob(cursor.getColumnIndexOrThrow(COLUMN_TYPE))[0],
cursor.getBlob(cursor.getColumnIndexOrThrow(COLUMN_HASH)),
cursor.getBlob(cursor.getColumnIndexOrThrow(COLUMN_IV))
)
)
}
cursor.close()
return list
}
fun isHashSaved(volumeName: String): Boolean {
val cursor = readableDatabase.query(TABLE_NAME, arrayOf(COLUMN_NAME, COLUMN_HASH), "$COLUMN_NAME=?", arrayOf(volumeName), null, null, null)
var isHashSaved = false
2022-03-05 12:51:02 +01:00
if (cursor.moveToNext()) {
2022-06-18 21:13:16 +02:00
if (cursor.getBlob(cursor.getColumnIndexOrThrow(COLUMN_HASH)) != null) {
isHashSaved = true
}
}
cursor.close()
return isHashSaved
}
2022-06-18 21:13:16 +02:00
fun addHash(volume: SavedVolume): Boolean {
return writableDatabase.update(TABLE_NAME, contentValuesFromVolume(volume), "$COLUMN_NAME=?", arrayOf(volume.name)) > 0
}
2022-06-18 21:13:16 +02:00
fun removeHash(volume: SavedVolume): Boolean {
return writableDatabase.update(
TABLE_NAME, contentValuesFromVolume(
2022-06-18 21:13:16 +02:00
SavedVolume(
volume.name,
volume.isHidden,
2022-06-18 21:13:16 +02:00
volume.type,
null,
null
)
), "$COLUMN_NAME=?", arrayOf(volume.name)) > 0
}
2022-03-24 20:08:23 +01:00
fun renameVolume(oldName: String, newName: String): Boolean {
return writableDatabase.update(TABLE_NAME,
ContentValues().apply {
put(COLUMN_NAME, newName)
},
"$COLUMN_NAME=?",arrayOf(oldName)
) > 0
}
2022-03-05 12:51:02 +01:00
fun removeVolume(volumeName: String): Boolean {
return writableDatabase.delete(TABLE_NAME, "$COLUMN_NAME=?", arrayOf(volumeName)) > 0
}
}