mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-05-29 21:10:24 +02:00
Unittests and fixes for dbstore
This commit is contained in:
parent
f3c9e0196e
commit
662e94bcee
@ -0,0 +1,159 @@
|
|||||||
|
package com.futo.platformplayer
|
||||||
|
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import com.futo.platformplayer.stores.db.ManagedDBDescriptor
|
||||||
|
import com.futo.platformplayer.stores.db.ManagedDBStore
|
||||||
|
import com.futo.platformplayer.testing.DBTOs
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.Test
|
||||||
|
import java.util.UUID
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import java.util.concurrent.ConcurrentMap
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
class ManagedDBStoreTests {
|
||||||
|
val context = InstrumentationRegistry.getInstrumentation().targetContext;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun startup() {
|
||||||
|
val store = ManagedDBStore.create("test", Descriptor())
|
||||||
|
.load(context, true);
|
||||||
|
store.deleteAll();
|
||||||
|
|
||||||
|
store.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun insert() {
|
||||||
|
val store = ManagedDBStore.create("test", Descriptor())
|
||||||
|
.load(context, true);
|
||||||
|
store.deleteAll();
|
||||||
|
|
||||||
|
val testObj = DBTOs.TestObject();
|
||||||
|
createAndAssert(store, testObj);
|
||||||
|
|
||||||
|
store.shutdown();
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun update() {
|
||||||
|
val store = ManagedDBStore.create("test", Descriptor())
|
||||||
|
.load(context, true);
|
||||||
|
store.deleteAll();
|
||||||
|
|
||||||
|
val testObj = DBTOs.TestObject();
|
||||||
|
val obj = createAndAssert(store, testObj);
|
||||||
|
|
||||||
|
testObj.someStr = "Testing";
|
||||||
|
store.update(obj.id!!, testObj);
|
||||||
|
val obj2 = store.get(obj.id!!);
|
||||||
|
assertIndexEquals(obj2, testObj);
|
||||||
|
|
||||||
|
store.shutdown();
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun delete() {
|
||||||
|
val store = ManagedDBStore.create("test", Descriptor())
|
||||||
|
.load(context, true);
|
||||||
|
store.deleteAll();
|
||||||
|
|
||||||
|
val testObj = DBTOs.TestObject();
|
||||||
|
val obj = createAndAssert(store, testObj);
|
||||||
|
store.delete(obj.id!!);
|
||||||
|
|
||||||
|
Assert.assertEquals(store.count(), 0);
|
||||||
|
Assert.assertNull(store.getOrNull(obj.id!!));
|
||||||
|
|
||||||
|
store.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun withIndex() {
|
||||||
|
val index = ConcurrentHashMap<Any, DBTOs.TestIndex>();
|
||||||
|
val store = ManagedDBStore.create("test", Descriptor())
|
||||||
|
.withIndex({it.someString}, index, true)
|
||||||
|
.load(context, true);
|
||||||
|
store.deleteAll();
|
||||||
|
|
||||||
|
val testObj1 = DBTOs.TestObject();
|
||||||
|
val testObj2 = DBTOs.TestObject();
|
||||||
|
val testObj3 = DBTOs.TestObject();
|
||||||
|
val obj1 = createAndAssert(store, testObj1);
|
||||||
|
val obj2 = createAndAssert(store, testObj2);
|
||||||
|
val obj3 = createAndAssert(store, testObj3);
|
||||||
|
Assert.assertEquals(store.count(), 3);
|
||||||
|
|
||||||
|
Assert.assertTrue(index.containsKey(testObj1.someStr));
|
||||||
|
Assert.assertTrue(index.containsKey(testObj2.someStr));
|
||||||
|
Assert.assertTrue(index.containsKey(testObj3.someStr));
|
||||||
|
Assert.assertEquals(index.size, 3);
|
||||||
|
|
||||||
|
val oldStr = testObj1.someStr;
|
||||||
|
testObj1.someStr = UUID.randomUUID().toString();
|
||||||
|
store.update(obj1.id!!, testObj1);
|
||||||
|
|
||||||
|
Assert.assertEquals(index.size, 3);
|
||||||
|
Assert.assertFalse(index.containsKey(oldStr));
|
||||||
|
Assert.assertTrue(index.containsKey(testObj1.someStr));
|
||||||
|
Assert.assertTrue(index.containsKey(testObj2.someStr));
|
||||||
|
Assert.assertTrue(index.containsKey(testObj3.someStr));
|
||||||
|
|
||||||
|
store.delete(obj2.id!!);
|
||||||
|
Assert.assertEquals(index.size, 2);
|
||||||
|
|
||||||
|
Assert.assertFalse(index.containsKey(oldStr));
|
||||||
|
Assert.assertTrue(index.containsKey(testObj1.someStr));
|
||||||
|
Assert.assertFalse(index.containsKey(testObj2.someStr));
|
||||||
|
Assert.assertTrue(index.containsKey(testObj3.someStr));
|
||||||
|
store.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun withUnique() {
|
||||||
|
val index = ConcurrentHashMap<Any, DBTOs.TestIndex>();
|
||||||
|
val store = ManagedDBStore.create("test", Descriptor())
|
||||||
|
.withIndex({it.someString}, index, false, true)
|
||||||
|
.load(context, true);
|
||||||
|
store.deleteAll();
|
||||||
|
|
||||||
|
val testObj1 = DBTOs.TestObject();
|
||||||
|
val testObj2 = DBTOs.TestObject();
|
||||||
|
val testObj3 = DBTOs.TestObject();
|
||||||
|
val obj1 = createAndAssert(store, testObj1);
|
||||||
|
val obj2 = createAndAssert(store, testObj2);
|
||||||
|
|
||||||
|
testObj3.someStr = testObj2.someStr;
|
||||||
|
Assert.assertEquals(store.insert(testObj3), obj2.id!!);
|
||||||
|
Assert.assertEquals(store.count(), 2);
|
||||||
|
|
||||||
|
store.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private fun createAndAssert(store: ManagedDBStore<DBTOs.TestIndex, DBTOs.TestObject, DBTOs.DB, DBTOs.DBDAO>, obj: DBTOs.TestObject): DBTOs.TestIndex {
|
||||||
|
val id = store.insert(obj);
|
||||||
|
Assert.assertTrue(id > 0);
|
||||||
|
|
||||||
|
val dbObj = store.get(id);
|
||||||
|
assertIndexEquals(dbObj, obj);
|
||||||
|
return dbObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertObjectEquals(obj1: DBTOs.TestObject, obj2: DBTOs.TestObject) {
|
||||||
|
Assert.assertEquals(obj1.someStr, obj2.someStr);
|
||||||
|
Assert.assertEquals(obj1.someNum, obj2.someNum);
|
||||||
|
}
|
||||||
|
private fun assertIndexEquals(obj1: DBTOs.TestIndex, obj2: DBTOs.TestObject) {
|
||||||
|
Assert.assertEquals(obj1.someString, obj2.someStr);
|
||||||
|
Assert.assertEquals(obj1.someNum, obj2.someNum);
|
||||||
|
assertObjectEquals(obj1.obj, obj2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Descriptor: ManagedDBDescriptor<DBTOs.TestObject, DBTOs.TestIndex, DBTOs.DB, DBTOs.DBDAO>() {
|
||||||
|
override val table_name: String = "testing";
|
||||||
|
override fun indexClass(): KClass<DBTOs.TestIndex> = DBTOs.TestIndex::class;
|
||||||
|
override fun dbClass(): KClass<DBTOs.DB> = DBTOs.DB::class;
|
||||||
|
override fun create(obj: DBTOs.TestObject): DBTOs.TestIndex = DBTOs.TestIndex(obj);
|
||||||
|
}
|
||||||
|
}
|
@ -58,7 +58,7 @@ class StatePlaylists {
|
|||||||
|
|
||||||
val historyIndex: ConcurrentMap<Any, DBHistory.Index> = ConcurrentHashMap();
|
val historyIndex: ConcurrentMap<Any, DBHistory.Index> = ConcurrentHashMap();
|
||||||
val _historyDBStore = ManagedDBStore.create("history", DBHistory.Descriptor())
|
val _historyDBStore = ManagedDBStore.create("history", DBHistory.Descriptor())
|
||||||
.withIndex({ it.url }, historyIndex, true)
|
.withIndex({ it.url }, historyIndex, false, true)
|
||||||
.load();
|
.load();
|
||||||
|
|
||||||
val playlistShareDir = FragmentedStorage.getOrCreateDirectory("shares");
|
val playlistShareDir = FragmentedStorage.getOrCreateDirectory("shares");
|
||||||
|
@ -15,6 +15,8 @@ interface ManagedDBDAOBase<T, I: ManagedDBIndex<T>> {
|
|||||||
@RawQuery
|
@RawQuery
|
||||||
fun get(query: SupportSQLiteQuery): I;
|
fun get(query: SupportSQLiteQuery): I;
|
||||||
@RawQuery
|
@RawQuery
|
||||||
|
fun getNullable(query: SupportSQLiteQuery): I?;
|
||||||
|
@RawQuery
|
||||||
fun getMultiple(query: SupportSQLiteQuery): List<I>;
|
fun getMultiple(query: SupportSQLiteQuery): List<I>;
|
||||||
|
|
||||||
@RawQuery
|
@RawQuery
|
||||||
|
@ -13,5 +13,12 @@ open class ManagedDBIndex<T> {
|
|||||||
var serialized: ByteArray? = null;
|
var serialized: ByteArray? = null;
|
||||||
|
|
||||||
@Ignore
|
@Ignore
|
||||||
var obj: T? = null;
|
private var _obj: T? = null;
|
||||||
|
|
||||||
|
@get:Ignore
|
||||||
|
val obj: T get() = _obj ?: throw IllegalStateException("Attempted to access serialized object on a index-only instance");
|
||||||
|
|
||||||
|
fun setInstance(obj: T) {
|
||||||
|
this._obj = obj;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,15 +1,13 @@
|
|||||||
package com.futo.platformplayer.stores.db
|
package com.futo.platformplayer.stores.db
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import androidx.room.migration.Migration
|
|
||||||
import androidx.sqlite.db.SimpleSQLiteQuery
|
import androidx.sqlite.db.SimpleSQLiteQuery
|
||||||
import com.futo.platformplayer.api.media.structures.AdhocPager
|
import com.futo.platformplayer.api.media.structures.AdhocPager
|
||||||
import com.futo.platformplayer.api.media.structures.IPager
|
import com.futo.platformplayer.api.media.structures.IPager
|
||||||
import com.futo.platformplayer.assume
|
import com.futo.platformplayer.assume
|
||||||
import com.futo.platformplayer.models.HistoryVideo
|
|
||||||
import com.futo.platformplayer.states.StateApp
|
import com.futo.platformplayer.states.StateApp
|
||||||
import com.futo.platformplayer.stores.db.types.DBHistory
|
|
||||||
import com.futo.platformplayer.stores.v2.JsonStoreSerializer
|
import com.futo.platformplayer.stores.v2.JsonStoreSerializer
|
||||||
import com.futo.platformplayer.stores.v2.StoreSerializer
|
import com.futo.platformplayer.stores.v2.StoreSerializer
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
@ -37,6 +35,7 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
private val _columnInfo: List<ColumnMetadata>;
|
private val _columnInfo: List<ColumnMetadata>;
|
||||||
|
|
||||||
private val _sqlGet: (Long)-> SimpleSQLiteQuery;
|
private val _sqlGet: (Long)-> SimpleSQLiteQuery;
|
||||||
|
private val _sqlGetIndex: (Long)-> SimpleSQLiteQuery;
|
||||||
private val _sqlGetAll: (LongArray)-> SimpleSQLiteQuery;
|
private val _sqlGetAll: (LongArray)-> SimpleSQLiteQuery;
|
||||||
private val _sqlAll: SimpleSQLiteQuery;
|
private val _sqlAll: SimpleSQLiteQuery;
|
||||||
private val _sqlCount: SimpleSQLiteQuery;
|
private val _sqlCount: SimpleSQLiteQuery;
|
||||||
@ -49,7 +48,7 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
|
|
||||||
val name: String;
|
val name: String;
|
||||||
|
|
||||||
private val _indexes: ArrayList<Pair<(I)->Any, ConcurrentMap<Any, I>>> = arrayListOf();
|
private val _indexes: ArrayList<IndexDescriptor<I>> = arrayListOf();
|
||||||
private val _indexCollection = ConcurrentHashMap<Long, I>();
|
private val _indexCollection = ConcurrentHashMap<Long, I>();
|
||||||
|
|
||||||
private var _withUnique: Pair<(I)->Any, ConcurrentMap<Any, I>>? = null;
|
private var _withUnique: Pair<(I)->Any, ConcurrentMap<Any, I>>? = null;
|
||||||
@ -76,6 +75,7 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
else "";
|
else "";
|
||||||
|
|
||||||
_sqlGet = { SimpleSQLiteQuery("SELECT * FROM ${_dbDescriptor.table_name} WHERE id = ?", arrayOf(it)) };
|
_sqlGet = { SimpleSQLiteQuery("SELECT * FROM ${_dbDescriptor.table_name} WHERE id = ?", arrayOf(it)) };
|
||||||
|
_sqlGetIndex = { SimpleSQLiteQuery("SELECT ${indexColumnNames.joinToString(", ")} FROM ${_dbDescriptor.table_name} WHERE id = ?", arrayOf(it)) };
|
||||||
_sqlGetAll = { SimpleSQLiteQuery("SELECT * FROM ${_dbDescriptor.table_name} WHERE id IN (?)", arrayOf(it)) };
|
_sqlGetAll = { SimpleSQLiteQuery("SELECT * FROM ${_dbDescriptor.table_name} WHERE id IN (?)", arrayOf(it)) };
|
||||||
_sqlAll = SimpleSQLiteQuery("SELECT * FROM ${_dbDescriptor.table_name} ${orderSQL}");
|
_sqlAll = SimpleSQLiteQuery("SELECT * FROM ${_dbDescriptor.table_name} ${orderSQL}");
|
||||||
_sqlCount = SimpleSQLiteQuery("SELECT COUNT(id) FROM ${_dbDescriptor.table_name}");
|
_sqlCount = SimpleSQLiteQuery("SELECT COUNT(id) FROM ${_dbDescriptor.table_name}");
|
||||||
@ -90,10 +90,10 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun withIndex(keySelector: (I)->Any, indexContainer: ConcurrentMap<Any, I>, withUnique: Boolean = false): ManagedDBStore<I, T, D, DA> {
|
fun withIndex(keySelector: (I)->Any, indexContainer: ConcurrentMap<Any, I>, allowChange: Boolean = false, withUnique: Boolean = false): ManagedDBStore<I, T, D, DA> {
|
||||||
if(_sqlIndexed == null)
|
if(_sqlIndexed == null)
|
||||||
throw IllegalStateException("Can only create indexes if sqlIndexOnly is implemented");
|
throw IllegalStateException("Can only create indexes if sqlIndexOnly is implemented");
|
||||||
_indexes.add(Pair(keySelector, indexContainer));
|
_indexes.add(IndexDescriptor(keySelector, indexContainer, allowChange));
|
||||||
|
|
||||||
if(withUnique)
|
if(withUnique)
|
||||||
withUnique(keySelector, indexContainer);
|
withUnique(keySelector, indexContainer);
|
||||||
@ -108,8 +108,11 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
fun load(): ManagedDBStore<I, T, D, DA> {
|
fun load(context: Context? = null, inMemory: Boolean = false): ManagedDBStore<I, T, D, DA> {
|
||||||
_db = Room.databaseBuilder(StateApp.instance.context, _dbDescriptor.dbClass().java, _name)
|
_db = (if(!inMemory)
|
||||||
|
Room.databaseBuilder(context ?: StateApp.instance.context, _dbDescriptor.dbClass().java, _name)
|
||||||
|
else
|
||||||
|
Room.inMemoryDatabaseBuilder(context ?: StateApp.instance.context, _dbDescriptor.dbClass().java))
|
||||||
.fallbackToDestructiveMigration()
|
.fallbackToDestructiveMigration()
|
||||||
.allowMainThreadQueries()
|
.allowMainThreadQueries()
|
||||||
.build()
|
.build()
|
||||||
@ -117,11 +120,17 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
if(_indexes.any()) {
|
if(_indexes.any()) {
|
||||||
val allItems = _dbDaoBase!!.getMultiple(_sqlIndexed!!);
|
val allItems = _dbDaoBase!!.getMultiple(_sqlIndexed!!);
|
||||||
for(index in _indexes)
|
for(index in _indexes)
|
||||||
index.second.putAll(allItems.associateBy(index.first));
|
index.collection.putAll(allItems.associateBy(index.keySelector));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
fun shutdown() {
|
||||||
|
val db = _db;
|
||||||
|
_db = null;
|
||||||
|
_dbDaoBase = null;
|
||||||
|
db?.close();
|
||||||
|
}
|
||||||
|
|
||||||
fun getUnique(obj: I): I? {
|
fun getUnique(obj: I): I? {
|
||||||
if(_withUnique == null)
|
if(_withUnique == null)
|
||||||
@ -142,9 +151,12 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
|
|
||||||
fun insert(obj: T): Long {
|
fun insert(obj: T): Long {
|
||||||
val newIndex = _dbDescriptor.create(obj);
|
val newIndex = _dbDescriptor.create(obj);
|
||||||
val unique = getUnique(newIndex);
|
|
||||||
if(unique != null)
|
if(_withUnique != null) {
|
||||||
return unique.id!!;
|
val unique = getUnique(newIndex);
|
||||||
|
if (unique != null)
|
||||||
|
return unique.id!!;
|
||||||
|
}
|
||||||
|
|
||||||
newIndex.serialized = serialize(obj);
|
newIndex.serialized = serialize(obj);
|
||||||
newIndex.id = dbDaoBase.insert(newIndex);
|
newIndex.id = dbDaoBase.insert(newIndex);
|
||||||
@ -153,13 +165,15 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
|
|
||||||
if(!_indexes.isEmpty()) {
|
if(!_indexes.isEmpty()) {
|
||||||
for (index in _indexes) {
|
for (index in _indexes) {
|
||||||
val key = index.first(newIndex);
|
val key = index.keySelector(newIndex);
|
||||||
index.second.put(key, newIndex);
|
index.collection.put(key, newIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newIndex.id!!;
|
return newIndex.id!!;
|
||||||
}
|
}
|
||||||
fun update(id: Long, obj: T) {
|
fun update(id: Long, obj: T) {
|
||||||
|
val existing = if(_indexes.any { it.checkChange }) _dbDaoBase!!.getNullable(_sqlGetIndex(id)) else null
|
||||||
|
|
||||||
val newIndex = _dbDescriptor.create(obj);
|
val newIndex = _dbDescriptor.create(obj);
|
||||||
newIndex.id = id;
|
newIndex.id = id;
|
||||||
newIndex.serialized = serialize(obj);
|
newIndex.serialized = serialize(obj);
|
||||||
@ -168,8 +182,13 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
|
|
||||||
if(!_indexes.isEmpty()) {
|
if(!_indexes.isEmpty()) {
|
||||||
for (index in _indexes) {
|
for (index in _indexes) {
|
||||||
val key = index.first(newIndex);
|
val key = index.keySelector(newIndex);
|
||||||
index.second.put(key, newIndex);
|
if(index.checkChange && existing != null) {
|
||||||
|
val keyExisting = index.keySelector(existing);
|
||||||
|
if(keyExisting != key)
|
||||||
|
index.collection.remove(keyExisting);
|
||||||
|
}
|
||||||
|
index.collection.put(key, newIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,6 +208,15 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
fun get(id: Long): I {
|
fun get(id: Long): I {
|
||||||
return deserializeIndex(dbDaoBase.get(_sqlGet(id)));
|
return deserializeIndex(dbDaoBase.get(_sqlGet(id)));
|
||||||
}
|
}
|
||||||
|
fun getOrNull(id: Long): I? {
|
||||||
|
val result = dbDaoBase.getNullable(_sqlGet(id));
|
||||||
|
if(result == null)
|
||||||
|
return null;
|
||||||
|
return deserializeIndex(result);
|
||||||
|
}
|
||||||
|
fun getIndexOnlyOrNull(id: Long): I? {
|
||||||
|
return dbDaoBase.get(_sqlGetIndex(id));
|
||||||
|
}
|
||||||
|
|
||||||
fun getAllObjects(vararg id: Long): List<T> = getAll(*id).map { it.obj!! };
|
fun getAllObjects(vararg id: Long): List<T> = getAll(*id).map { it.obj!! };
|
||||||
fun getAll(vararg id: Long): List<I> {
|
fun getAll(vararg id: Long): List<I> {
|
||||||
@ -217,19 +245,20 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
dbDaoBase.delete(item);
|
dbDaoBase.delete(item);
|
||||||
|
|
||||||
for(index in _indexes)
|
for(index in _indexes)
|
||||||
index.second.remove(index.first(item));
|
index.collection.remove(index.keySelector(item));
|
||||||
}
|
}
|
||||||
fun delete(id: Long) {
|
fun delete(id: Long) {
|
||||||
dbDaoBase.action(_sqlDeleteById(id));
|
dbDaoBase.action(_sqlDeleteById(id));
|
||||||
|
|
||||||
for(index in _indexes)
|
for(index in _indexes)
|
||||||
index.second.values.removeIf { it.id == id }
|
index.collection.values.removeIf { it.id == id }
|
||||||
}
|
}
|
||||||
fun deleteAll() {
|
fun deleteAll() {
|
||||||
dbDaoBase.action(_sqlDeleteAll);
|
dbDaoBase.action(_sqlDeleteAll);
|
||||||
|
|
||||||
_indexCollection.clear();
|
_indexCollection.clear();
|
||||||
for(index in _indexes)
|
for(index in _indexes)
|
||||||
index.second.clear();
|
index.collection.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convertObject(index: I): T? {
|
fun convertObject(index: I): T? {
|
||||||
@ -241,7 +270,7 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
fun deserializeIndex(index: I): I {
|
fun deserializeIndex(index: I): I {
|
||||||
if(index.serialized == null) throw IllegalStateException("Cannot deserialize index-only items from [${name}]");
|
if(index.serialized == null) throw IllegalStateException("Cannot deserialize index-only items from [${name}]");
|
||||||
val obj = _serializer.deserialize(_class, index.serialized!!);
|
val obj = _serializer.deserialize(_class, index.serialized!!);
|
||||||
index.obj = obj;
|
index.setInstance(obj);
|
||||||
index.serialized = null;
|
index.serialized = null;
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
@ -260,6 +289,13 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||||||
= ManagedDBStore(name, descriptor, kotlin.reflect.typeOf<T>(), JsonStoreSerializer.create(serializer));
|
= ManagedDBStore(name, descriptor, kotlin.reflect.typeOf<T>(), JsonStoreSerializer.create(serializer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Pair<(I)->Any, ConcurrentMap<Any, I>>
|
||||||
|
class IndexDescriptor<I>(
|
||||||
|
val keySelector: (I) -> Any,
|
||||||
|
val collection: ConcurrentMap<Any, I>,
|
||||||
|
val checkChange: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
class ColumnMetadata(
|
class ColumnMetadata(
|
||||||
val field: Field,
|
val field: Field,
|
||||||
val info: ColumnIndex,
|
val info: ColumnIndex,
|
||||||
|
@ -24,7 +24,6 @@ class DBChannelCache {
|
|||||||
constructor(sCache: SerializedPlatformContent) {
|
constructor(sCache: SerializedPlatformContent) {
|
||||||
id = null;
|
id = null;
|
||||||
serialized = null;
|
serialized = null;
|
||||||
obj = sCache;
|
|
||||||
channelUrl = sCache.author.url;
|
channelUrl = sCache.author.url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,6 @@ class DBHistory {
|
|||||||
url = historyVideo.video.url;
|
url = historyVideo.video.url;
|
||||||
position = historyVideo.position;
|
position = historyVideo.position;
|
||||||
date = historyVideo.date.toEpochSecond();
|
date = historyVideo.date.toEpochSecond();
|
||||||
obj = historyVideo;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
47
app/src/main/java/com/futo/platformplayer/testing/DBTOs.kt
Normal file
47
app/src/main/java/com/futo/platformplayer/testing/DBTOs.kt
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package com.futo.platformplayer.testing
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Database
|
||||||
|
import androidx.room.Entity
|
||||||
|
import com.futo.platformplayer.stores.db.ColumnIndex
|
||||||
|
import com.futo.platformplayer.stores.db.ColumnOrdered
|
||||||
|
import com.futo.platformplayer.stores.db.ManagedDBDAOBase
|
||||||
|
import com.futo.platformplayer.stores.db.ManagedDBDatabase
|
||||||
|
import com.futo.platformplayer.stores.db.ManagedDBIndex
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import java.util.Random
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
class DBTOs {
|
||||||
|
@Dao
|
||||||
|
interface DBDAO: ManagedDBDAOBase<TestObject, TestIndex> {}
|
||||||
|
@Database(entities = [TestIndex::class], version = 2)
|
||||||
|
abstract class DB: ManagedDBDatabase<TestObject, TestIndex, DBDAO>() {
|
||||||
|
abstract override fun base(): DBDAO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Entity("testing")
|
||||||
|
class TestIndex(): ManagedDBIndex<TestObject>() {
|
||||||
|
|
||||||
|
@ColumnIndex
|
||||||
|
var someString: String = "";
|
||||||
|
@ColumnIndex
|
||||||
|
@ColumnOrdered(0)
|
||||||
|
var someNum: Int = 0;
|
||||||
|
|
||||||
|
constructor(obj: TestObject, customInt: Int? = null) : this() {
|
||||||
|
someString = obj.someStr;
|
||||||
|
someNum = customInt ?: obj.someNum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Serializable
|
||||||
|
class TestObject {
|
||||||
|
var someStr = UUID.randomUUID().toString();
|
||||||
|
var someNum = random.nextInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val random = Random();
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user