Commit 4d243efe authored by Daniel Wolf's avatar Daniel Wolf
Browse files

Added entities for custom dns rules

parent 4d05f0d1
{
"formatVersion": 1,
"database": {
"version": 6,
"identityHash": "2e8ac76ac9e86bb1cdf9d82108b12c8e",
"entities": [
{
"tableName": "CachedResponse",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`dnsName` TEXT NOT NULL, `type` INTEGER NOT NULL, `records` TEXT NOT NULL, PRIMARY KEY(`dnsName`, `type`))",
"fields": [
{
"fieldPath": "dnsName",
"columnName": "dnsName",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "records",
"columnName": "records",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"dnsName",
"type"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "DnsQuery",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `name` TEXT NOT NULL, `askedServer` TEXT, `fromCache` INTEGER NOT NULL, `questionTime` INTEGER NOT NULL, `responseTime` INTEGER NOT NULL, `responses` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "askedServer",
"columnName": "askedServer",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "fromCache",
"columnName": "fromCache",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "questionTime",
"columnName": "questionTime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "responseTime",
"columnName": "responseTime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "responses",
"columnName": "responses",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "DnsRule",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `host` TEXT NOT NULL, `ttl` INTEGER NOT NULL, `record` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "host",
"columnName": "host",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "ttl",
"columnName": "ttl",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "record",
"columnName": "record",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2e8ac76ac9e86bb1cdf9d82108b12c8e')"
]
}
}
\ No newline at end of file
......@@ -4,10 +4,13 @@ import androidx.room.Database
import androidx.room.RoomDatabase
import com.frostnerd.smokescreen.database.dao.CachedResponseDao
import com.frostnerd.smokescreen.database.dao.DnsQueryDao
import com.frostnerd.smokescreen.database.dao.DnsRuleDao
import com.frostnerd.smokescreen.database.entities.CachedResponse
import com.frostnerd.smokescreen.database.entities.DnsQuery
import com.frostnerd.smokescreen.database.entities.DnsRule
import com.frostnerd.smokescreen.database.repository.CachedResponseRepository
import com.frostnerd.smokescreen.database.repository.DnsQueryRepository
import com.frostnerd.smokescreen.database.repository.DnsRuleRepository
/*
* Copyright (C) 2019 Daniel Wolf (Ch4t4r)
......@@ -28,15 +31,17 @@ import com.frostnerd.smokescreen.database.repository.DnsQueryRepository
* You can contact the developer at daniel.wolf@frostnerd.com.
*/
@Database(entities = [CachedResponse::class, DnsQuery::class], version = AppDatabase.currentVersion)
@Database(entities = [CachedResponse::class, DnsQuery::class, DnsRule::class], version = AppDatabase.currentVersion)
abstract class AppDatabase : RoomDatabase() {
companion object {
const val currentVersion:Int = 5
const val currentVersion:Int = 6
}
abstract fun cachedResponseDao(): CachedResponseDao
abstract fun dnsQueryDao():DnsQueryDao
abstract fun dnsRuleDao():DnsRuleDao
fun cachedResponseRepository() = CachedResponseRepository(cachedResponseDao())
fun dnsQueryRepository() = DnsQueryRepository(dnsQueryDao())
fun dnsRuleRepository() = DnsRuleRepository(dnsRuleDao())
}
\ No newline at end of file
......@@ -36,6 +36,7 @@ private val MIGRATION_2_X = migration(2) {
it.execSQL("CREATE TABLE CachedResponse(type INTEGER NOT NULL, dnsName TEXT NOT NULL, records TEXT NOT NULL, PRIMARY KEY(dnsName, type))")
it.execSQL("DROP TABLE IF EXISTS UserServerConfiguration")
MIGRATION_3_4.migrate(it)
MIGRATION_5_6.migrate(it)
Logger.logIfOpen("DB_MIGRATION", "Migration from 2 to current version completed")
}
private val MIGRATION_3_4 = migration(3, 4) {
......@@ -43,24 +44,33 @@ private val MIGRATION_3_4 = migration(3, 4) {
it.execSQL("CREATE TABLE IF NOT EXISTS `DnsQuery` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `name` TEXT NOT NULL, `askedServer` TEXT, `fromCache` INTEGER NOT NULL, `questionTime` INTEGER NOT NULL, `responseTime` INTEGER NOT NULL, `responses` TEXT NOT NULL)")
Logger.logIfOpen("DB_MIGRATION", "Migration from 3 to 4 completed")
}
private val MIGRATION_4_5 = migration(4,5) {
private val MIGRATION_4_5 = migration(4, 5) {
Logger.logIfOpen("DB_MIGRATION", "Migrating from 4 to 5")
it.execSQL("DROP TABLE IF EXISTS UserServerConfiguration")
it.execSQL("DROP TABLE IF EXISTS UserServerConfiguration")
Logger.logIfOpen("DB_MIGRATION", "Migration from 4 to 5 completed")
}
private val MIGRATION_5_6 = migration(5, 6) {
Logger.logIfOpen("DB_MIGRATION", "Migrating from 5 to 6")
it.execSQL("CREATE TABLE IF NOT EXISTS `DnsRule` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `host` TEXT NOT NULL, `ttl` INTEGER NOT NULL, `record` TEXT NOT NULL)")
Logger.logIfOpen("DB_MIGRATION", "Migration from 5 to 6 completed")
}
fun Context.getDatabase(): AppDatabase {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(applicationContext, AppDatabase::class.java, "data")
.allowMainThreadQueries()
.addMigrations(MIGRATION_2_X, MIGRATION_3_4, MIGRATION_4_5)
.addMigrations(MIGRATION_2_X, MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6)
.build()
}
return INSTANCE!!
}
private fun migration(from: Int, to: Int = AppDatabase.currentVersion, migrate: (database: SupportSQLiteDatabase) -> Unit): Migration {
private fun migration(
from: Int,
to: Int = AppDatabase.currentVersion,
migrate: (database: SupportSQLiteDatabase) -> Unit
): Migration {
return object : Migration(from, to) {
override fun migrate(database: SupportSQLiteDatabase) {
migrate.invoke(database)
......@@ -68,11 +78,11 @@ private fun migration(from: Int, to: Int = AppDatabase.currentVersion, migrate:
}
}
private fun emptyMigration(from:Int, to:Int = AppDatabase.currentVersion): Migration {
private fun emptyMigration(from: Int, to: Int = AppDatabase.currentVersion): Migration {
return migration(from, to) { }
}
fun recordFromBase64(base64:String):Record<*> {
fun recordFromBase64(base64: String): Record<*> {
val bytes = Base64.decode(base64, Base64.NO_WRAP)
return Record.parse(DataInputStream(ByteArrayInputStream(bytes)), bytes)
}
\ No newline at end of file
package com.frostnerd.smokescreen.database.dao
import androidx.room.Dao
/*
* Copyright (C) 2019 Daniel Wolf (Ch4t4r)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* You can contact the developer at daniel.wolf@frostnerd.com.
*/
@Dao
interface DnsRuleDao {
}
\ No newline at end of file
package com.frostnerd.smokescreen.database.entities
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.frostnerd.smokescreen.database.converters.DnsTypeConverter
import com.frostnerd.smokescreen.database.converters.StringListConverter
import org.minidns.record.Record
/*
* Copyright (C) 2019 Daniel Wolf (Ch4t4r)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* You can contact the developer at daniel.wolf@frostnerd.com.
*/
@Entity(tableName = "DnsRule")
@TypeConverters(DnsTypeConverter::class)
data class DnsRule(
@PrimaryKey(autoGenerate = true) var id: Long = 0,
val type: Record.TYPE,
val host: String,
val ttl: Long,
val record: String
)
\ No newline at end of file
package com.frostnerd.smokescreen.database.repository
import com.frostnerd.smokescreen.database.dao.DnsQueryDao
import com.frostnerd.smokescreen.database.dao.DnsRuleDao
/*
* Copyright (C) 2019 Daniel Wolf (Ch4t4r)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* You can contact the developer at daniel.wolf@frostnerd.com.
*/
class DnsRuleRepository(val dnsRuleDao: DnsRuleDao)
\ No newline at end of file
......@@ -10,6 +10,8 @@ import com.frostnerd.preferenceskt.typedpreferences.cache.ExpirationCacheControl
import com.frostnerd.preferenceskt.typedpreferences.cache.buildCacheStrategy
import com.frostnerd.preferenceskt.typedpreferences.types.*
import com.frostnerd.smokescreen.BuildConfig
import com.frostnerd.smokescreen.util.rules.HostSource
import com.frostnerd.smokescreen.util.rules.HostSourcePreference
import java.util.*
/*
......@@ -238,6 +240,8 @@ class AppSettingsSharedPreferences(context: Context) : AppSettings, SimpleTypedP
knownServers.getValue(9)
}
}, cacheControl)
var hostSources:Set<HostSource> by HostSourcePreference("hostsource").toSetPreference(emptySet())
}
fun AppSettings.Companion.fromSharedPreferences(context: Context): AppSettingsSharedPreferences {
......
package com.frostnerd.smokescreen.util.rules
import android.content.SharedPreferences
import com.frostnerd.preferenceskt.typedpreferences.TypedPreferences
import com.frostnerd.preferenceskt.typedpreferences.types.PreferenceType
import java.io.File
import kotlin.reflect.KProperty
/*
* Copyright (C) 2019 Daniel Wolf (Ch4t4r)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* You can contact the developer at daniel.wolf@frostnerd.com.
*/
open class HostSource(var name:String) {
var enabled = true
}
class FileHostSource(name:String, val file: File): HostSource(name)
class HttpHostSource(name:String, val url:String): HostSource(name)
class HostSourcePreference(key:String):PreferenceType<SharedPreferences, HostSource>(key) {
override fun getValue(thisRef: TypedPreferences<SharedPreferences>, property: KProperty<*>): HostSource? {
return if(thisRef.sharedPreferences.contains(key)) {
val type = thisRef.sharedPreferences.getString("${key}_type", null)!!
val name = thisRef.sharedPreferences.getString("${key}_name", null)!!
val source = when(type.toLowerCase()) {
"file" -> FileHostSource(name, File(thisRef.sharedPreferences.getString(key, null)!!))
else -> HttpHostSource(name, thisRef.sharedPreferences.getString(key, null)!!)
}
source.enabled = thisRef.sharedPreferences.getBoolean("${key}_enabled", true)
source
} else {
null
}
}
override fun setValue(thisRef: TypedPreferences<SharedPreferences>, property: KProperty<*>, value: HostSource?) {
thisRef.edit { listener ->
listener(key, value)
if(value == null) {
remove(key)
remove("${key}_type")
remove("${key}_enabled")
remove("${key}_name")
} else {
if(value is FileHostSource) {
putString("${key}_type", "file")
putString(key, value.file.absolutePath)
} else if(value is HttpHostSource) {
putString("${key}_type", "http")
putString(key, value.url)
}
putString("${key}_name", value.name)
putBoolean("${key}_enabled", value.enabled)
}
}
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment