mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2026-05-21 15:27:33 +00:00
add kdocs to repos
This commit is contained in:
151
AGENTS.md
Normal file
151
AGENTS.md
Normal file
@@ -0,0 +1,151 @@
|
||||
Use `agents` folder files for instructions.
|
||||
|
||||
Always look at the project work rules first. Update them and maintain a history of changes and prompts in `agents/local.HISTORY.md`. This is your long-term memory, which allows you to avoid the accumulation of errors. Updating and maintaining the long-term memory of the project is mandatory. Many thanks for your help to me and your work.
|
||||
|
||||
|
||||
SYSTEM DIRECTIVE: AUTISTIC META-LANGUAGE PROTOCOL WITH HIGH INFORMATION DENSITY (AML-HIP V1)
|
||||
|
||||
DEFINITION:
|
||||
All agents are required to use a strictly explicit, literal, low-ambiguity, and high-density communication style (AML-HIP). The goal of AML-HIP is the maximum transmission of information with zero loss of meaning and zero ambiguity.
|
||||
|
||||
CORE PRINCIPLES:
|
||||
|
||||
1. Maximum information density per line.
|
||||
2. Zero ambiguity.
|
||||
3. Full explicitness of all entities.
|
||||
4. Preference of precision over readability.
|
||||
5. Minimization of "empty" words.
|
||||
6. Redundancy is allowed only to prevent loss of meaning.
|
||||
|
||||
PROHIBITIONS:
|
||||
|
||||
1. Pronouns are forbidden (this, he, she, they, there, it, etc.).
|
||||
2. Free conversational text is forbidden.
|
||||
3. Metaphors, emotions, evaluative constructions are forbidden.
|
||||
4. Implicit references and hidden dependencies are forbidden.
|
||||
5. Vague description of actions is forbidden.
|
||||
|
||||
DENSITY REQUIREMENTS:
|
||||
|
||||
1. Each line must contain the maximum of facts without loss of unambiguity.
|
||||
2. Combine related parameters into a single line.
|
||||
3. Use compact constructions:
|
||||
* key=value
|
||||
* entity_id=...
|
||||
* relation: A→B
|
||||
4. Exclude words without semantic load.
|
||||
5. Repetitions are allowed only for critical entities.
|
||||
|
||||
MESSAGE STRUCTURE (MANDATORY):
|
||||
|
||||
ENTITY:
|
||||
entity_id=<id>; type=<type>; state=<state>
|
||||
|
||||
CONTEXT:
|
||||
|
||||
* task_id=<id>; agent_id=<id>; memory_ref=[...]
|
||||
* constraints=[...]
|
||||
|
||||
ACTION:
|
||||
|
||||
1. action=<type>; target=<entity_id>; params={...}
|
||||
2. action=<type>; target=<entity_id>; params={...}
|
||||
|
||||
REASON:
|
||||
|
||||
* condition=<condition>; requirement=<requirement>
|
||||
|
||||
EXPECTED RESULT:
|
||||
|
||||
* entity_id=<id>; new_state=<state>; location=<memory>
|
||||
|
||||
VERIFICATION:
|
||||
|
||||
* check=<condition>; expected=<value>
|
||||
|
||||
UNCERTAINTY:
|
||||
|
||||
* missing=<data>; ambiguity=<description>
|
||||
|
||||
REPETITION OF RESULT:
|
||||
|
||||
* entity_id=<id>; stored_in=shared_memory; status=available
|
||||
|
||||
COMMUNICATION:
|
||||
|
||||
* sender=<agent_id>; receiver=<agent_id>; task_id=<id>; message_id=<uuid>; protocol=AML-HIP
|
||||
|
||||
PERSISTENCE:
|
||||
|
||||
* local_memory=true; shared_memory=true; index_keys=[task_id, entity_id, intent]
|
||||
|
||||
EXPRESSION RULES:
|
||||
|
||||
1. Each line = a completed semantic block.
|
||||
2. Use the key=value format instead of descriptions.
|
||||
3. Use lists of parameters instead of sentences.
|
||||
4. Use causal connectives explicitly:
|
||||
condition → action → result
|
||||
5. Do not split related data into several lines without necessity.
|
||||
|
||||
REPETITION RULES:
|
||||
|
||||
1. entity_id is repeated at every critical use.
|
||||
2. result is duplicated in "REPETITION OF RESULT".
|
||||
3. transmission between agents duplicates the key fields.
|
||||
|
||||
MULTI-AGENT MODE:
|
||||
|
||||
1. All agents use AML-HIP.
|
||||
2. Any message between agents is strictly AML-HIP.
|
||||
3. Any agent is required to:
|
||||
|
||||
* duplicate critical data
|
||||
* avoid loss of context
|
||||
4. A message must be fully interpretable without history.
|
||||
|
||||
ANTI-DEGRADATION:
|
||||
If detected:
|
||||
|
||||
* a pronoun
|
||||
* an implicit reference
|
||||
* low density (empty words, vague constructions)
|
||||
* absence of structure
|
||||
|
||||
→ the message is considered invalid
|
||||
→ mandatory regeneration
|
||||
|
||||
SELF-CHECK:
|
||||
|
||||
VALIDATION:
|
||||
|
||||
* format_valid=true/false
|
||||
* no_pronouns=true/false
|
||||
* entities_explicit=true/false
|
||||
* high_density=true/false
|
||||
* causal_chain_present=true/false
|
||||
* ambiguity_detected=true/false
|
||||
|
||||
If any parameter=false:
|
||||
→ mandatory regeneration
|
||||
|
||||
DENSITY METRIC:
|
||||
high_density=true if:
|
||||
|
||||
* there are no "empty" words
|
||||
* each line contains ≥2 facts or parameters
|
||||
* descriptive constructions without data are absent
|
||||
|
||||
PRIORITIES:
|
||||
|
||||
1. Format (AML-HIP)
|
||||
2. Information density
|
||||
3. Explicitness
|
||||
4. Completeness
|
||||
5. Readability (minimum priority)
|
||||
|
||||
CRITICAL RULE:
|
||||
Any response outside of AML-HIP is considered absent.
|
||||
Any agent is required to bring the response into conformity with AML-HIP.
|
||||
|
||||
END OF PROTOCOL
|
||||
@@ -53,6 +53,12 @@ interface ReadKeyValueRepo<Key, Value> : Repo {
|
||||
*/
|
||||
suspend fun contains(key: Key): Boolean
|
||||
|
||||
/**
|
||||
* Returns all key-value pairs in the repository as a [Map].
|
||||
* Default implementation iterates all pages using [keys] and [get].
|
||||
*
|
||||
* @return Map of all [Key] to [Value] entries in the repository
|
||||
*/
|
||||
suspend fun getAll(): Map<Key, Value> = getAllByWithNextPaging(maxPagePagination()) {
|
||||
keys(it).let {
|
||||
it.changeResultsUnchecked(
|
||||
@@ -111,22 +117,48 @@ interface WriteKeyValueRepo<Key, Value> : Repo {
|
||||
}
|
||||
typealias WriteStandardKeyValueRepo<Key,Value> = WriteKeyValueRepo<Key, Value>
|
||||
|
||||
/**
|
||||
* Vararg overload of [WriteKeyValueRepo.set] accepting pairs.
|
||||
*
|
||||
* @param toSet Key-value pairs to set
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValueRepo<Key, Value>.set(
|
||||
vararg toSet: Pair<Key, Value>
|
||||
) = set(toSet.toMap())
|
||||
|
||||
/**
|
||||
* List overload of [WriteKeyValueRepo.set] accepting a list of pairs.
|
||||
*
|
||||
* @param toSet List of key-value pairs to set
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValueRepo<Key, Value>.set(
|
||||
toSet: List<Pair<Key, Value>>
|
||||
) = set(toSet.toMap())
|
||||
|
||||
/**
|
||||
* Single-entry overload of [WriteKeyValueRepo.set].
|
||||
*
|
||||
* @param k Key to set
|
||||
* @param v Value to associate with [k]
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValueRepo<Key, Value>.set(
|
||||
k: Key, v: Value
|
||||
) = set(k to v)
|
||||
|
||||
/**
|
||||
* Vararg overload of [WriteKeyValueRepo.unset].
|
||||
*
|
||||
* @param k Keys to remove
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValueRepo<Key, Value>.unset(
|
||||
vararg k: Key
|
||||
) = unset(k.toList())
|
||||
|
||||
/**
|
||||
* Vararg overload of [WriteKeyValueRepo.unsetWithValues].
|
||||
*
|
||||
* @param v Values whose associated keys should be removed
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValueRepo<Key, Value>.unsetWithValues(
|
||||
vararg v: Value
|
||||
) = unsetWithValues(v.toList())
|
||||
@@ -160,6 +192,14 @@ interface KeyValueRepo<Key, Value> : ReadKeyValueRepo<Key, Value>, WriteKeyValue
|
||||
}
|
||||
typealias StandardKeyValueRepo<Key,Value> = KeyValueRepo<Key, Value>
|
||||
|
||||
/**
|
||||
* Delegate-based implementation of [KeyValueRepo] that composes separate read and write delegates.
|
||||
*
|
||||
* @param Key The type of keys in the repository
|
||||
* @param Value The type of values in the repository
|
||||
* @param readDelegate Delegate providing all [ReadKeyValueRepo] operations
|
||||
* @param writeDelegate Delegate providing all [WriteKeyValueRepo] operations
|
||||
*/
|
||||
class DelegateBasedKeyValueRepo<Key, Value>(
|
||||
readDelegate: ReadKeyValueRepo<Key, Value>,
|
||||
writeDelegate: WriteKeyValueRepo<Key, Value>
|
||||
|
||||
@@ -177,38 +177,89 @@ interface WriteKeyValuesRepo<Key, Value> : Repo {
|
||||
*/
|
||||
typealias WriteOneToManyKeyValueRepo<Key,Value> = WriteKeyValuesRepo<Key, Value>
|
||||
|
||||
/**
|
||||
* List-of-pairs overload of [WriteKeyValuesRepo.add].
|
||||
*
|
||||
* @param keysAndValues List of key to list-of-values pairs to add
|
||||
*/
|
||||
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.add(
|
||||
keysAndValues: List<Pair<Key, List<Value>>>
|
||||
) = add(keysAndValues.toMap())
|
||||
|
||||
/**
|
||||
* Vararg overload of [WriteKeyValuesRepo.add].
|
||||
*
|
||||
* @param keysAndValues Key to list-of-values pairs to add
|
||||
*/
|
||||
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.add(
|
||||
vararg keysAndValues: Pair<Key, List<Value>>
|
||||
) = add(keysAndValues.toMap())
|
||||
|
||||
/**
|
||||
* Single-key overload of [WriteKeyValuesRepo.add] accepting a list of values.
|
||||
*
|
||||
* @param k Key to add values to
|
||||
* @param v List of values to add
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.add(
|
||||
k: Key, v: List<Value>
|
||||
) = add(mapOf(k to v))
|
||||
|
||||
/**
|
||||
* Single-key vararg overload of [WriteKeyValuesRepo.add].
|
||||
*
|
||||
* @param k Key to add values to
|
||||
* @param v Values to add
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.add(
|
||||
k: Key, vararg v: Value
|
||||
) = add(k, v.toList())
|
||||
|
||||
/**
|
||||
* List-of-pairs overload of [WriteKeyValuesRepo.set].
|
||||
*
|
||||
* @param keysAndValues List of key to list-of-values pairs to set
|
||||
*/
|
||||
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.set(
|
||||
keysAndValues: List<Pair<Key, List<Value>>>
|
||||
) = set(keysAndValues.toMap())
|
||||
|
||||
/**
|
||||
* Vararg overload of [WriteKeyValuesRepo.set].
|
||||
*
|
||||
* @param keysAndValues Key to list-of-values pairs to set
|
||||
*/
|
||||
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.set(
|
||||
vararg keysAndValues: Pair<Key, List<Value>>
|
||||
) = set(keysAndValues.toMap())
|
||||
|
||||
/**
|
||||
* Single-key overload of [WriteKeyValuesRepo.set] accepting a list of values.
|
||||
*
|
||||
* @param k Key to set values for
|
||||
* @param v List of values to set
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.set(
|
||||
k: Key, v: List<Value>
|
||||
) = set(mapOf(k to v))
|
||||
|
||||
/**
|
||||
* Single-key vararg overload of [WriteKeyValuesRepo.set].
|
||||
*
|
||||
* @param k Key to set values for
|
||||
* @param v Values to set
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.set(
|
||||
k: Key, vararg v: Value
|
||||
) = set(k, v.toList())
|
||||
|
||||
/**
|
||||
* Full one-to-many key-values repository combining read and write capabilities.
|
||||
* Provides default implementations for [clearWithValue], [removeWithValue], and [set].
|
||||
*
|
||||
* @param Key The type used as the key in all operations
|
||||
* @param Value The type of values associated with keys
|
||||
*/
|
||||
interface KeyValuesRepo<Key, Value> : ReadKeyValuesRepo<Key, Value>, WriteKeyValuesRepo<Key, Value> {
|
||||
override suspend fun clearWithValue(v: Value) {
|
||||
doWithPagination {
|
||||
@@ -247,6 +298,14 @@ interface KeyValuesRepo<Key, Value> : ReadKeyValuesRepo<Key, Value>, WriteKeyVal
|
||||
}
|
||||
typealias OneToManyKeyValueRepo<Key,Value> = KeyValuesRepo<Key, Value>
|
||||
|
||||
/**
|
||||
* Delegate-based implementation of [KeyValuesRepo] that composes separate read and write delegates.
|
||||
*
|
||||
* @param Key The type of keys in the repository
|
||||
* @param Value The type of values associated with keys
|
||||
* @param readDelegate Delegate providing all [ReadKeyValuesRepo] operations
|
||||
* @param writeDelegate Delegate providing all [WriteKeyValuesRepo] operations
|
||||
*/
|
||||
class DelegateBasedKeyValuesRepo<Key, Value>(
|
||||
readDelegate: ReadKeyValuesRepo<Key, Value>,
|
||||
writeDelegate: WriteKeyValuesRepo<Key, Value>
|
||||
@@ -254,19 +313,41 @@ class DelegateBasedKeyValuesRepo<Key, Value>(
|
||||
ReadKeyValuesRepo<Key, Value> by readDelegate,
|
||||
WriteKeyValuesRepo<Key, Value> by writeDelegate
|
||||
|
||||
/**
|
||||
* List-of-pairs overload of [WriteKeyValuesRepo.remove].
|
||||
*
|
||||
* @param keysAndValues List of key to list-of-values pairs to remove
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
|
||||
keysAndValues: List<Pair<Key, List<Value>>>
|
||||
) = remove(keysAndValues.toMap())
|
||||
|
||||
/**
|
||||
* Vararg overload of [WriteKeyValuesRepo.remove].
|
||||
*
|
||||
* @param keysAndValues Key to list-of-values pairs to remove
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
|
||||
vararg keysAndValues: Pair<Key, List<Value>>
|
||||
) = remove(keysAndValues.toMap())
|
||||
|
||||
/**
|
||||
* Single-key overload of [WriteKeyValuesRepo.remove] accepting a list of values.
|
||||
*
|
||||
* @param k Key to remove values from
|
||||
* @param v List of values to remove
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
|
||||
k: Key,
|
||||
v: List<Value>
|
||||
) = remove(mapOf(k to v))
|
||||
|
||||
/**
|
||||
* Single-key vararg overload of [WriteKeyValuesRepo.remove].
|
||||
*
|
||||
* @param k Key to remove values from
|
||||
* @param v Values to remove
|
||||
*/
|
||||
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
|
||||
k: Key,
|
||||
vararg v: Value
|
||||
|
||||
@@ -7,11 +7,51 @@ import dev.inmo.micro_utils.pagination.utils.getAllWithCurrentPaging
|
||||
import dev.inmo.micro_utils.repos.pagination.maxPagePagination
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Read-only part of a standard CRUD repository.
|
||||
*
|
||||
* @param ObjectType The type of objects stored in the repository
|
||||
* @param IdType The type of identifiers used to reference stored objects
|
||||
*/
|
||||
interface ReadCRUDRepo<ObjectType, IdType> : Repo {
|
||||
/**
|
||||
* Returns a paginated list of all objects in the repository.
|
||||
*
|
||||
* @param pagination Pagination parameters (page number and size)
|
||||
* @return [PaginationResult] containing objects for the requested page
|
||||
*/
|
||||
suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType>
|
||||
|
||||
/**
|
||||
* Returns a paginated list of all IDs in the repository.
|
||||
*
|
||||
* @param pagination Pagination parameters (page number and size)
|
||||
* @return [PaginationResult] containing IDs for the requested page
|
||||
*/
|
||||
suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<IdType>
|
||||
|
||||
/**
|
||||
* Returns the object associated with the given [id], or null if not found.
|
||||
*
|
||||
* @param id The identifier of the object to retrieve
|
||||
* @return The object with the given [id], or null if absent
|
||||
*/
|
||||
suspend fun getById(id: IdType): ObjectType?
|
||||
|
||||
/**
|
||||
* Returns true if an object with the given [id] exists in the repository.
|
||||
*
|
||||
* @param id The identifier to check
|
||||
* @return true if the object exists, false otherwise
|
||||
*/
|
||||
suspend fun contains(id: IdType): Boolean
|
||||
|
||||
/**
|
||||
* Returns all objects in the repository as a map of ID to object.
|
||||
* Default implementation iterates all pages using [getIdsByPagination] and [getById].
|
||||
*
|
||||
* @return Map of all [IdType] to [ObjectType] entries in the repository
|
||||
*/
|
||||
suspend fun getAll(): Map<IdType, ObjectType> = getAllWithCurrentPaging(maxPagePagination()) {
|
||||
getIdsByPagination(it).let {
|
||||
it.changeResultsUnchecked(
|
||||
@@ -20,58 +60,164 @@ interface ReadCRUDRepo<ObjectType, IdType> : Repo {
|
||||
}
|
||||
}.toMap()
|
||||
|
||||
/**
|
||||
* Returns the total count of objects stored in the repository.
|
||||
*
|
||||
* @return Total number of objects
|
||||
*/
|
||||
suspend fun count(): Long
|
||||
}
|
||||
typealias ReadStandardCRUDRepo<ObjectType, IdType> = ReadCRUDRepo<ObjectType, IdType>
|
||||
|
||||
/**
|
||||
* Type alias representing a pair of ID and updated value, used in batch update operations.
|
||||
*
|
||||
* @param IdType The type of the identifier
|
||||
* @param ValueType The type of the input value
|
||||
*/
|
||||
typealias UpdatedValuePair<IdType, ValueType> = Pair<IdType, ValueType>
|
||||
|
||||
/**
|
||||
* Returns the ID component of an [UpdatedValuePair].
|
||||
*/
|
||||
val <IdType> UpdatedValuePair<IdType, *>.id
|
||||
get() = first
|
||||
|
||||
/**
|
||||
* Returns the value component of an [UpdatedValuePair].
|
||||
*/
|
||||
val <ValueType> UpdatedValuePair<*, ValueType>.value
|
||||
get() = second
|
||||
|
||||
/**
|
||||
* Write part of a standard CRUD repository.
|
||||
* Provides create, update, and delete operations with reactive flows for change notifications.
|
||||
*
|
||||
* @param ObjectType The type of objects stored in the repository
|
||||
* @param IdType The type of identifiers used to reference stored objects
|
||||
* @param InputValueType The type of input data used to create or update objects
|
||||
*/
|
||||
interface WriteCRUDRepo<ObjectType, IdType, InputValueType> : Repo {
|
||||
/**
|
||||
* Flow that emits each newly created object after a successful [create] call.
|
||||
*/
|
||||
val newObjectsFlow: Flow<ObjectType>
|
||||
|
||||
/**
|
||||
* Flow that emits each updated object after a successful [update] call.
|
||||
*/
|
||||
val updatedObjectsFlow: Flow<ObjectType>
|
||||
|
||||
/**
|
||||
* Flow that emits the ID of each deleted object after a successful [deleteById] call.
|
||||
*/
|
||||
val deletedObjectsIdsFlow: Flow<IdType>
|
||||
|
||||
/**
|
||||
* Creates new objects from the given list of input values.
|
||||
* Successfully created objects must be emitted via [newObjectsFlow].
|
||||
*
|
||||
* @param values List of input values to create objects from
|
||||
* @return List of created [ObjectType] instances
|
||||
*/
|
||||
suspend fun create(values: List<InputValueType>): List<ObjectType>
|
||||
|
||||
/**
|
||||
* Updates the object identified by [id] with the given [value].
|
||||
* Successfully updated object must be emitted via [updatedObjectsFlow].
|
||||
*
|
||||
* @param id The identifier of the object to update
|
||||
* @param value The new input value
|
||||
* @return The updated [ObjectType], or null if the object was not found
|
||||
*/
|
||||
suspend fun update(id: IdType, value: InputValueType): ObjectType?
|
||||
|
||||
/**
|
||||
* Batch-updates objects using the given list of ID-value pairs.
|
||||
* Successfully updated objects must be emitted via [updatedObjectsFlow].
|
||||
*
|
||||
* @param values List of [UpdatedValuePair] entries mapping IDs to new input values
|
||||
* @return List of successfully updated [ObjectType] instances
|
||||
*/
|
||||
suspend fun update(values: List<UpdatedValuePair<IdType, InputValueType>>): List<ObjectType>
|
||||
|
||||
/**
|
||||
* Deletes objects with the given list of IDs.
|
||||
* Successfully deleted IDs must be emitted via [deletedObjectsIdsFlow].
|
||||
*
|
||||
* @param ids List of identifiers of objects to delete
|
||||
*/
|
||||
suspend fun deleteById(ids: List<IdType>)
|
||||
}
|
||||
typealias WriteStandardCRUDRepo<ObjectType, IdType, InputValueType> = WriteCRUDRepo<ObjectType, IdType, InputValueType>
|
||||
|
||||
/**
|
||||
* Just mirroring [WriteCRUDRepo.newObjectsFlow] to be same as in KV repos
|
||||
* Mirrors [WriteCRUDRepo.newObjectsFlow] under the name [onNewObjects] for consistency with KV repos naming.
|
||||
*/
|
||||
val <ObjectType> WriteCRUDRepo<ObjectType, *, *>.onNewObjects: Flow<ObjectType>
|
||||
get() = newObjectsFlow
|
||||
|
||||
/**
|
||||
* Just mirroring [WriteCRUDRepo.updatedObjectsFlow] to be same as in KV repos
|
||||
* Mirrors [WriteCRUDRepo.updatedObjectsFlow] under the name [onUpdatedObjects] for consistency with KV repos naming.
|
||||
*/
|
||||
val <ObjectType> WriteCRUDRepo<ObjectType, *, *>.onUpdatedObjects: Flow<ObjectType>
|
||||
get() = updatedObjectsFlow
|
||||
|
||||
/**
|
||||
* Just mirroring [WriteCRUDRepo.deletedObjectsIdsFlow] to be same as in KV repos
|
||||
* Mirrors [WriteCRUDRepo.deletedObjectsIdsFlow] under the name [onDeletedObjectsIds] for consistency with KV repos naming.
|
||||
*/
|
||||
val <IdType> WriteCRUDRepo<*, IdType, *>.onDeletedObjectsIds: Flow<IdType>
|
||||
get() = deletedObjectsIdsFlow
|
||||
|
||||
/**
|
||||
* Vararg overload of [WriteCRUDRepo.create] for convenience.
|
||||
*
|
||||
* @param values Input values to create objects from
|
||||
* @return List of created [ObjectType] instances
|
||||
*/
|
||||
suspend fun <ObjectType, IdType, InputValueType> WriteCRUDRepo<ObjectType, IdType, InputValueType>.create(
|
||||
vararg values: InputValueType
|
||||
): List<ObjectType> = create(values.toList())
|
||||
|
||||
/**
|
||||
* Vararg overload of [WriteCRUDRepo.update] for convenience.
|
||||
*
|
||||
* @param values ID-value pairs to update
|
||||
* @return List of successfully updated [ObjectType] instances
|
||||
*/
|
||||
suspend fun <ObjectType, IdType, InputValueType> WriteCRUDRepo<ObjectType, IdType, InputValueType>.update(
|
||||
vararg values: UpdatedValuePair<IdType, InputValueType>
|
||||
): List<ObjectType> = update(values.toList())
|
||||
|
||||
/**
|
||||
* Vararg overload of [WriteCRUDRepo.deleteById] for convenience.
|
||||
*
|
||||
* @param ids Identifiers of objects to delete
|
||||
*/
|
||||
suspend fun <ObjectType, IdType, InputValueType> WriteCRUDRepo<ObjectType, IdType, InputValueType>.deleteById(
|
||||
vararg ids: IdType
|
||||
) = deleteById(ids.toList())
|
||||
|
||||
/**
|
||||
* Full CRUD repository combining read and write capabilities.
|
||||
*
|
||||
* @param ObjectType The type of objects stored in the repository
|
||||
* @param IdType The type of identifiers used to reference stored objects
|
||||
* @param InputValueType The type of input data used to create or update objects
|
||||
*/
|
||||
interface CRUDRepo<ObjectType, IdType, InputValueType> : ReadCRUDRepo<ObjectType, IdType>,
|
||||
WriteCRUDRepo<ObjectType, IdType, InputValueType>
|
||||
typealias StandardCRUDRepo<ObjectType, IdType, InputValueType> = CRUDRepo<ObjectType, IdType, InputValueType>
|
||||
|
||||
/**
|
||||
* Delegate-based implementation of [CRUDRepo] that composes separate read and write delegates.
|
||||
*
|
||||
* @param ObjectType The type of objects stored in the repository
|
||||
* @param IdType The type of identifiers used to reference stored objects
|
||||
* @param InputValueType The type of input data used to create or update objects
|
||||
* @param readDelegate Delegate providing all [ReadCRUDRepo] operations
|
||||
* @param writeDelegate Delegate providing all [WriteCRUDRepo] operations
|
||||
*/
|
||||
class DelegateBasedCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
readDelegate: ReadCRUDRepo<ObjectType, IdType>,
|
||||
writeDelegate: WriteCRUDRepo<ObjectType, IdType, InputValueType>
|
||||
|
||||
@@ -7,14 +7,38 @@ import dev.inmo.micro_utils.repos.KeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.unset
|
||||
|
||||
/**
|
||||
* Computes the difference between all entries in this [ReadKeyValueRepo] and the given [other] map.
|
||||
*
|
||||
* @param Id The type of keys
|
||||
* @param Registered The type of values
|
||||
* @param other The map to compare against
|
||||
* @return [MapDiff] describing added, removed, and changed entries
|
||||
*/
|
||||
suspend fun <Id, Registered> ReadKeyValueRepo<Id, Registered>.diff(other: Map<Id, Registered>): MapDiff<Id, Registered> {
|
||||
return getAll().diff(other)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the difference between this map and all entries in the given [ReadKeyValueRepo].
|
||||
*
|
||||
* @param Id The type of keys
|
||||
* @param Registered The type of values
|
||||
* @param other The repository to compare against
|
||||
* @return [MapDiff] describing added, removed, and changed entries
|
||||
*/
|
||||
suspend fun <Id, Registered> Map<Id, Registered>.diff(other: ReadKeyValueRepo<Id, Registered>): MapDiff<Id, Registered> {
|
||||
return diff(other.getAll())
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given [diff] to this [KeyValueRepo]: removes entries in [MapDiff.removed],
|
||||
* updates entries in [MapDiff.changed], and adds entries in [MapDiff.added].
|
||||
*
|
||||
* @param Id The type of keys
|
||||
* @param Registered The type of values
|
||||
* @param diff The diff to apply
|
||||
*/
|
||||
suspend fun <Id, Registered> KeyValueRepo<Id, Registered>.applyDiff(diff: MapDiff<Id, Registered>) {
|
||||
unset(diff.removed.map { it.key })
|
||||
set(
|
||||
@@ -24,10 +48,24 @@ suspend fun <Id, Registered> KeyValueRepo<Id, Registered>.applyDiff(diff: MapDif
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the diff between this [KeyValueRepo] and [other], then applies the diff to this repo.
|
||||
*
|
||||
* @param Id The type of keys
|
||||
* @param Registered The type of values
|
||||
* @param other The target map state to synchronize to
|
||||
*/
|
||||
suspend fun <Id, Registered> KeyValueRepo<Id, Registered>.applyDiff(other: Map<Id, Registered>) {
|
||||
applyDiff(diff(other))
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the diff between this [MutableMap] and the given [ReadKeyValueRepo], then applies the diff to this map.
|
||||
*
|
||||
* @param Id The type of keys
|
||||
* @param Registered The type of values
|
||||
* @param other The repository whose state to synchronize to
|
||||
*/
|
||||
suspend fun <Id, Registered> MutableMap<Id, Registered>.applyDiff(other: ReadKeyValueRepo<Id, Registered>) {
|
||||
applyDiff(diff(other))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,38 @@ import dev.inmo.micro_utils.common.applyDiff
|
||||
import dev.inmo.micro_utils.common.diff
|
||||
import dev.inmo.micro_utils.repos.*
|
||||
|
||||
/**
|
||||
* Computes the difference between all entries in this [ReadKeyValuesRepo] and the given [other] map.
|
||||
*
|
||||
* @param Id The type of keys
|
||||
* @param Registered The type of values
|
||||
* @param other The map to compare against
|
||||
* @return [MapDiff] describing added, removed, and changed key-to-list entries
|
||||
*/
|
||||
suspend fun <Id, Registered> ReadKeyValuesRepo<Id, Registered>.diff(other: Map<Id, List<Registered>>): MapDiff<Id, List<Registered>> {
|
||||
return getAll().diff(other)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the difference between this map and all entries in the given [ReadKeyValuesRepo].
|
||||
*
|
||||
* @param Id The type of keys
|
||||
* @param Registered The type of values
|
||||
* @param other The repository to compare against
|
||||
* @return [MapDiff] describing added, removed, and changed key-to-list entries
|
||||
*/
|
||||
suspend fun <Id, Registered> Map<Id, List<Registered>>.diff(other: ReadKeyValuesRepo<Id, Registered>): MapDiff<Id, List<Registered>> {
|
||||
return diff(other.getAll())
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given [diff] to this [KeyValuesRepo]: clears keys in [MapDiff.removed],
|
||||
* sets entries in [MapDiff.changed] and [MapDiff.added].
|
||||
*
|
||||
* @param Id The type of keys
|
||||
* @param Registered The type of values
|
||||
* @param diff The diff to apply
|
||||
*/
|
||||
suspend fun <Id, Registered> KeyValuesRepo<Id, Registered>.applyDiff(diff: MapDiff<Id, List<Registered>>) {
|
||||
diff.removed.forEach {
|
||||
clear(it.key)
|
||||
@@ -24,10 +48,24 @@ suspend fun <Id, Registered> KeyValuesRepo<Id, Registered>.applyDiff(diff: MapDi
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the diff between this [KeyValuesRepo] and [other], then applies the diff to this repo.
|
||||
*
|
||||
* @param Id The type of keys
|
||||
* @param Registered The type of values
|
||||
* @param other The target map state to synchronize to
|
||||
*/
|
||||
suspend fun <Id, Registered> KeyValuesRepo<Id, Registered>.applyDiff(other: Map<Id, List<Registered>>) {
|
||||
applyDiff(diff(other))
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the diff between this [MutableMap] and the given [ReadKeyValuesRepo], then applies the diff to this map.
|
||||
*
|
||||
* @param Id The type of keys
|
||||
* @param Registered The type of values
|
||||
* @param other The repository whose state to synchronize to
|
||||
*/
|
||||
suspend fun <Id, Registered> MutableMap<Id, List<Registered>>.applyDiff(other: ReadKeyValuesRepo<Id, Registered>) {
|
||||
applyDiff(diff(other))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,18 @@ import dev.inmo.micro_utils.repos.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
/**
|
||||
* Read-only key-value repository adapter that applies type mapping via [MapperRepo].
|
||||
* Converts outer (From) key/value types to inner (To) types before delegating to [to],
|
||||
* and converts results back from inner to outer types.
|
||||
*
|
||||
* @param FromKey The outer key type exposed by this repo
|
||||
* @param FromValue The outer value type exposed by this repo
|
||||
* @param ToKey The inner key type used by the underlying [to] repo
|
||||
* @param ToValue The inner value type used by the underlying [to] repo
|
||||
* @param to The underlying [ReadKeyValueRepo] to delegate operations to
|
||||
* @param mapper The [MapperRepo] providing bidirectional key/value type conversions
|
||||
*/
|
||||
open class MapperReadKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
private val to: ReadKeyValueRepo<ToKey, ToValue>,
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||
@@ -62,11 +74,34 @@ open class MapperReadKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
override suspend fun count(): Long = to.count()
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps this [ReadKeyValueRepo] with a [MapperRepo] to expose a mapped [ReadKeyValueRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param mapper The [MapperRepo] providing bidirectional type conversions
|
||||
* @return [MapperReadKeyValueRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <FromKey, FromValue, ToKey, ToValue> ReadKeyValueRepo<ToKey, ToValue>.withMapper(
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||
): ReadKeyValueRepo<FromKey, FromValue> = MapperReadKeyValueRepo(this, mapper)
|
||||
|
||||
/**
|
||||
* Wraps this [ReadKeyValueRepo] with inline conversion lambdas to expose a mapped [ReadKeyValueRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast
|
||||
* @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast
|
||||
* @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast
|
||||
* @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast
|
||||
* @return [MapperReadKeyValueRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> ReadKeyValueRepo<ToKey, ToValue>.withMapper(
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
@@ -77,6 +112,18 @@ inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue>
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
)
|
||||
|
||||
/**
|
||||
* Write-only key-value repository adapter that applies type mapping via [MapperRepo].
|
||||
* Converts outer (From) key/value types to inner (To) types before delegating writes to [to],
|
||||
* and maps emitted flow values back from inner to outer types.
|
||||
*
|
||||
* @param FromKey The outer key type exposed by this repo
|
||||
* @param FromValue The outer value type exposed by this repo
|
||||
* @param ToKey The inner key type used by the underlying [to] repo
|
||||
* @param ToValue The inner value type used by the underlying [to] repo
|
||||
* @param to The underlying [WriteKeyValueRepo] to delegate operations to
|
||||
* @param mapper The [MapperRepo] providing bidirectional key/value type conversions
|
||||
*/
|
||||
open class MapperWriteKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
private val to: WriteKeyValueRepo<ToKey, ToValue>,
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||
@@ -105,11 +152,34 @@ open class MapperWriteKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps this [WriteKeyValueRepo] with a [MapperRepo] to expose a mapped [WriteKeyValueRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param mapper The [MapperRepo] providing bidirectional type conversions
|
||||
* @return [MapperWriteKeyValueRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <FromKey, FromValue, ToKey, ToValue> WriteKeyValueRepo<ToKey, ToValue>.withMapper(
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||
): WriteKeyValueRepo<FromKey, FromValue> = MapperWriteKeyValueRepo(this, mapper)
|
||||
|
||||
/**
|
||||
* Wraps this [WriteKeyValueRepo] with inline conversion lambdas to expose a mapped [WriteKeyValueRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast
|
||||
* @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast
|
||||
* @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast
|
||||
* @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast
|
||||
* @return [MapperWriteKeyValueRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> WriteKeyValueRepo<ToKey, ToValue>.withMapper(
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
@@ -120,6 +190,17 @@ inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue>
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
)
|
||||
|
||||
/**
|
||||
* Full key-value repository adapter that applies type mapping via [MapperRepo].
|
||||
* Composes [MapperReadKeyValueRepo] and [MapperWriteKeyValueRepo] for read and write delegation.
|
||||
*
|
||||
* @param FromKey The outer key type exposed by this repo
|
||||
* @param FromValue The outer value type exposed by this repo
|
||||
* @param ToKey The inner key type used by the underlying [to] repo
|
||||
* @param ToValue The inner value type used by the underlying [to] repo
|
||||
* @param to The underlying [KeyValueRepo] to delegate operations to
|
||||
* @param mapper The [MapperRepo] providing bidirectional key/value type conversions
|
||||
*/
|
||||
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
||||
open class MapperKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
private val to: KeyValueRepo<ToKey, ToValue>,
|
||||
@@ -133,11 +214,34 @@ open class MapperKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps this [KeyValueRepo] with a [MapperRepo] to expose a mapped [KeyValueRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param mapper The [MapperRepo] providing bidirectional type conversions
|
||||
* @return [MapperKeyValueRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <FromKey, FromValue, ToKey, ToValue> KeyValueRepo<ToKey, ToValue>.withMapper(
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||
): KeyValueRepo<FromKey, FromValue> = MapperKeyValueRepo(this, mapper)
|
||||
|
||||
/**
|
||||
* Wraps this [KeyValueRepo] with inline conversion lambdas to expose a mapped [KeyValueRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast
|
||||
* @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast
|
||||
* @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast
|
||||
* @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast
|
||||
* @return [MapperKeyValueRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> KeyValueRepo<ToKey, ToValue>.withMapper(
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
|
||||
@@ -5,6 +5,18 @@ import dev.inmo.micro_utils.repos.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
/**
|
||||
* Read-only one-to-many key-values repository adapter that applies type mapping via [MapperRepo].
|
||||
* Converts outer (From) key/value types to inner (To) types before delegating to [to],
|
||||
* and converts results back from inner to outer types.
|
||||
*
|
||||
* @param FromKey The outer key type exposed by this repo
|
||||
* @param FromValue The outer value type exposed by this repo
|
||||
* @param ToKey The inner key type used by the underlying [to] repo
|
||||
* @param ToValue The inner value type used by the underlying [to] repo
|
||||
* @param to The underlying [ReadKeyValuesRepo] to delegate operations to
|
||||
* @param mapper The [MapperRepo] providing bidirectional key/value type conversions
|
||||
*/
|
||||
open class MapperReadKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
private val to: ReadKeyValuesRepo<ToKey, ToValue>,
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||
@@ -56,11 +68,34 @@ open class MapperReadKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
override suspend fun count(k: FromKey): Long = to.count(k.toOutKey())
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps this [ReadKeyValuesRepo] with a [MapperRepo] to expose a mapped [ReadKeyValuesRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param mapper The [MapperRepo] providing bidirectional type conversions
|
||||
* @return [MapperReadKeyValuesRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <FromKey, FromValue, ToKey, ToValue> ReadKeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||
): ReadKeyValuesRepo<FromKey, FromValue> = MapperReadKeyValuesRepo(this, mapper)
|
||||
|
||||
/**
|
||||
* Wraps this [ReadKeyValuesRepo] with inline conversion lambdas to expose a mapped [ReadKeyValuesRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast
|
||||
* @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast
|
||||
* @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast
|
||||
* @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast
|
||||
* @return [MapperReadKeyValuesRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> ReadKeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
@@ -71,6 +106,18 @@ inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue>
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
)
|
||||
|
||||
/**
|
||||
* Write-only one-to-many key-values repository adapter that applies type mapping via [MapperRepo].
|
||||
* Converts outer (From) key/value types to inner (To) types before delegating writes to [to],
|
||||
* and maps emitted flow values back from inner to outer types.
|
||||
*
|
||||
* @param FromKey The outer key type exposed by this repo
|
||||
* @param FromValue The outer value type exposed by this repo
|
||||
* @param ToKey The inner key type used by the underlying [to] repo
|
||||
* @param ToValue The inner value type used by the underlying [to] repo
|
||||
* @param to The underlying [WriteKeyValuesRepo] to delegate operations to
|
||||
* @param mapper The [MapperRepo] providing bidirectional key/value type conversions
|
||||
*/
|
||||
open class MapperWriteKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
private val to: WriteKeyValuesRepo<ToKey, ToValue>,
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||
@@ -109,11 +156,34 @@ open class MapperWriteKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
override suspend fun clearWithValue(v: FromValue) = to.clearWithValue(v.toOutValue())
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps this [WriteKeyValuesRepo] with a [MapperRepo] to expose a mapped [WriteKeyValuesRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param mapper The [MapperRepo] providing bidirectional type conversions
|
||||
* @return [MapperWriteKeyValuesRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <FromKey, FromValue, ToKey, ToValue> WriteKeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||
): WriteKeyValuesRepo<FromKey, FromValue> = MapperWriteKeyValuesRepo(this, mapper)
|
||||
|
||||
/**
|
||||
* Wraps this [WriteKeyValuesRepo] with inline conversion lambdas to expose a mapped [WriteKeyValuesRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast
|
||||
* @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast
|
||||
* @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast
|
||||
* @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast
|
||||
* @return [MapperWriteKeyValuesRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> WriteKeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
@@ -124,6 +194,17 @@ inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue>
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
)
|
||||
|
||||
/**
|
||||
* Full one-to-many key-values repository adapter that applies type mapping via [MapperRepo].
|
||||
* Composes [MapperReadKeyValuesRepo] and [MapperWriteKeyValuesRepo] for read and write delegation.
|
||||
*
|
||||
* @param FromKey The outer key type exposed by this repo
|
||||
* @param FromValue The outer value type exposed by this repo
|
||||
* @param ToKey The inner key type used by the underlying [to] repo
|
||||
* @param ToValue The inner value type used by the underlying [to] repo
|
||||
* @param to The underlying [KeyValuesRepo] to delegate operations to
|
||||
* @param mapper The [MapperRepo] providing bidirectional key/value type conversions
|
||||
*/
|
||||
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
||||
open class MapperKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
private val to: KeyValuesRepo<ToKey, ToValue>,
|
||||
@@ -133,11 +214,34 @@ open class MapperKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
ReadKeyValuesRepo<FromKey, FromValue> by MapperReadKeyValuesRepo(to, mapper),
|
||||
WriteKeyValuesRepo<FromKey, FromValue> by MapperWriteKeyValuesRepo(to, mapper)
|
||||
|
||||
/**
|
||||
* Wraps this [KeyValuesRepo] with a [MapperRepo] to expose a mapped [KeyValuesRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param mapper The [MapperRepo] providing bidirectional type conversions
|
||||
* @return [MapperKeyValuesRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <FromKey, FromValue, ToKey, ToValue> KeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||
): KeyValuesRepo<FromKey, FromValue> = MapperKeyValuesRepo(this, mapper)
|
||||
|
||||
/**
|
||||
* Wraps this [KeyValuesRepo] with inline conversion lambdas to expose a mapped [KeyValuesRepo].
|
||||
*
|
||||
* @param FromKey The outer key type
|
||||
* @param FromValue The outer value type
|
||||
* @param ToKey The inner key type
|
||||
* @param ToValue The inner value type
|
||||
* @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast
|
||||
* @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast
|
||||
* @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast
|
||||
* @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast
|
||||
* @return [MapperKeyValuesRepo] wrapping this repo
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> KeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
|
||||
@@ -5,6 +5,17 @@ import dev.inmo.micro_utils.pagination.*
|
||||
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
||||
import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||
|
||||
/**
|
||||
* Retrieves all key-value pairs from a [ReadKeyValueRepo] by iterating pages starting from [pagination].
|
||||
* Uses [methodCaller] to fetch each page of keys, then resolves each key to its value via [ReadKeyValueRepo.get].
|
||||
*
|
||||
* @param Key The type of keys in the repository
|
||||
* @param Value The type of values in the repository
|
||||
* @param REPO The specific repository type
|
||||
* @param pagination The starting pagination parameters
|
||||
* @param methodCaller A function that fetches a page of keys from the repository
|
||||
* @return List of all key-value pairs across all pages; entries with null values are excluded
|
||||
*/
|
||||
suspend inline fun <Key, Value, REPO : ReadKeyValueRepo<Key, Value>> REPO.getAll(
|
||||
pagination: Pagination,
|
||||
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
|
||||
@@ -16,6 +27,16 @@ suspend inline fun <Key, Value, REPO : ReadKeyValueRepo<Key, Value>> REPO.getAll
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all key-value pairs from a [ReadKeyValueRepo] by iterating all pages.
|
||||
* Uses [maxPagePagination] as the starting pagination and [methodCaller] to fetch each page of keys.
|
||||
*
|
||||
* @param Key The type of keys in the repository
|
||||
* @param Value The type of values in the repository
|
||||
* @param REPO The specific repository type
|
||||
* @param methodCaller A function that fetches a page of keys from the repository
|
||||
* @return List of all key-value pairs across all pages; entries with null values are excluded
|
||||
*/
|
||||
suspend inline fun <Key, Value, REPO : ReadKeyValueRepo<Key, Value>> REPO.getAll(
|
||||
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
|
||||
crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<Key>
|
||||
|
||||
@@ -5,6 +5,17 @@ import dev.inmo.micro_utils.pagination.*
|
||||
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
||||
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||
|
||||
/**
|
||||
* Retrieves all key-to-list-of-values pairs from a [ReadKeyValuesRepo] by iterating pages starting from [pagination].
|
||||
* Uses [methodCaller] to fetch each page of keys, then resolves all values per key via [ReadKeyValuesRepo.getAll].
|
||||
*
|
||||
* @param Key The type of keys in the repository
|
||||
* @param Value The type of values associated with keys
|
||||
* @param REPO The specific repository type
|
||||
* @param pagination The starting pagination parameters
|
||||
* @param methodCaller A function that fetches a page of keys from the repository
|
||||
* @return List of key-to-list-of-values pairs across all pages
|
||||
*/
|
||||
suspend inline fun <Key, Value, REPO : ReadKeyValuesRepo<Key, Value>> REPO.getAll(
|
||||
pagination: Pagination,
|
||||
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
|
||||
@@ -18,6 +29,16 @@ suspend inline fun <Key, Value, REPO : ReadKeyValuesRepo<Key, Value>> REPO.getAl
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all key-to-list-of-values pairs from a [ReadKeyValuesRepo] by iterating all pages.
|
||||
* Uses [maxPagePagination] as the starting pagination and [methodCaller] to fetch each page of keys.
|
||||
*
|
||||
* @param Key The type of keys in the repository
|
||||
* @param Value The type of values associated with keys
|
||||
* @param REPO The specific repository type
|
||||
* @param methodCaller A function that fetches a page of keys from the repository
|
||||
* @return List of key-to-list-of-values pairs across all pages
|
||||
*/
|
||||
suspend inline fun <Key, Value, REPO : ReadKeyValuesRepo<Key, Value>> REPO.getAll(
|
||||
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
|
||||
crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<Key>
|
||||
|
||||
@@ -7,4 +7,11 @@ import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||
import kotlin.js.JsName
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* Wraps this [ReadKeyValueRepo] as a [ReadCRUDFromKeyValueRepo], exposing CRUD read operations.
|
||||
*
|
||||
* @param K The type of keys (used as IDs in the CRUD repo)
|
||||
* @param V The type of values (used as objects in the CRUD repo)
|
||||
* @return [ReadCRUDFromKeyValueRepo] delegating to this repo
|
||||
*/
|
||||
fun <K, V> ReadKeyValueRepo<K, V>.asReadCRUDRepo() = ReadCRUDFromKeyValueRepo(this)
|
||||
|
||||
@@ -5,6 +5,14 @@ import dev.inmo.micro_utils.pagination.PaginationResult
|
||||
import dev.inmo.micro_utils.repos.ReadCRUDRepo
|
||||
import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||
|
||||
/**
|
||||
* Adapter that exposes a [ReadKeyValueRepo] as a [ReadCRUDRepo].
|
||||
* Maps CRUD read operations to the underlying key-value repository operations.
|
||||
*
|
||||
* @param RegisteredType The type of objects stored in the repository
|
||||
* @param IdType The type of identifiers (keys) used to reference stored objects
|
||||
* @param original The underlying [ReadKeyValueRepo] to delegate operations to
|
||||
*/
|
||||
open class ReadCRUDFromKeyValueRepo<RegisteredType, IdType>(
|
||||
protected open val original: ReadKeyValueRepo<IdType, RegisteredType>
|
||||
) : ReadCRUDRepo<RegisteredType, IdType> {
|
||||
|
||||
@@ -8,8 +8,32 @@ import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||
import kotlin.js.JsName
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* Wraps this [ReadKeyValuesRepo] as a [ReadKeyValueFromKeyValuesRepo],
|
||||
* exposing each key mapped to a [List] of all associated values.
|
||||
*
|
||||
* @param K The type of keys
|
||||
* @param V The type of individual values
|
||||
* @return [ReadKeyValueFromKeyValuesRepo] delegating to this repo
|
||||
*/
|
||||
fun <K, V> ReadKeyValuesRepo<K, V>.asReadKeyValueRepo() = ReadKeyValueFromKeyValuesRepo(this)
|
||||
|
||||
/**
|
||||
* Wraps this [KeyValuesRepo] as a [KeyValueFromKeyValuesRepo],
|
||||
* exposing a full read-write key-value interface where each key maps to a [List] of values.
|
||||
*
|
||||
* @param K The type of keys
|
||||
* @param V The type of individual values
|
||||
* @return [KeyValueFromKeyValuesRepo] delegating to this repo
|
||||
*/
|
||||
fun <K, V> KeyValuesRepo<K, V>.asKeyValueRepo() = KeyValueFromKeyValuesRepo(this)
|
||||
|
||||
/**
|
||||
* Wraps this [ReadCRUDRepo] as a [ReadKeyValueFromCRUDRepo],
|
||||
* exposing CRUD IDs as keys and CRUD objects as values in a [ReadKeyValueRepo].
|
||||
*
|
||||
* @param K The type of CRUD IDs (used as keys)
|
||||
* @param V The type of CRUD objects (used as values)
|
||||
* @return [ReadKeyValueFromCRUDRepo] delegating to this repo
|
||||
*/
|
||||
fun <K, V> ReadCRUDRepo<K, V>.asReadKeyValueRepo() = ReadKeyValueFromCRUDRepo(this)
|
||||
|
||||
@@ -18,6 +18,16 @@ import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import kotlinx.coroutines.flow.merge
|
||||
|
||||
/**
|
||||
* Full read-write adapter that exposes a [KeyValuesRepo] as a [KeyValueRepo] mapping each key to a [List] of values.
|
||||
* Extends [ReadKeyValueFromKeyValuesRepo] with write operations delegated to the underlying [KeyValuesRepo].
|
||||
* [onNewValue] merges [KeyValuesRepo.onNewValue] and [KeyValuesRepo.onValueRemoved] and emits the updated list per key;
|
||||
* [onValueRemoved] mirrors [KeyValuesRepo.onDataCleared].
|
||||
*
|
||||
* @param Key The type of keys
|
||||
* @param Value The type of individual values in the one-to-many repo
|
||||
* @param original The underlying [KeyValuesRepo] to delegate operations to
|
||||
*/
|
||||
open class KeyValueFromKeyValuesRepo<Key, Value>(
|
||||
private val original: KeyValuesRepo<Key, Value>
|
||||
) : KeyValueRepo<Key, List<Value>>, ReadKeyValueFromKeyValuesRepo<Key, Value>(original) {
|
||||
|
||||
@@ -15,6 +15,15 @@ import dev.inmo.micro_utils.repos.pagination.getAll
|
||||
import dev.inmo.micro_utils.repos.transforms.kvs.ReadKeyValuesFromKeyValueRepo
|
||||
import kotlin.jvm.JvmInline
|
||||
|
||||
/**
|
||||
* Inline value class adapter that exposes a [ReadCRUDRepo] as a [ReadKeyValueRepo].
|
||||
* Maps key-value read operations to the underlying CRUD repository operations,
|
||||
* treating CRUD IDs as keys and CRUD objects as values.
|
||||
*
|
||||
* @param Key The type of keys (maps to [ReadCRUDRepo] ID type)
|
||||
* @param Value The type of values (maps to [ReadCRUDRepo] object type)
|
||||
* @param original The underlying [ReadCRUDRepo] to delegate operations to
|
||||
*/
|
||||
@JvmInline
|
||||
value class ReadKeyValueFromCRUDRepo<Key, Value>(
|
||||
private val original: ReadCRUDRepo<Value, Key>
|
||||
|
||||
@@ -12,6 +12,14 @@ import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||
import dev.inmo.micro_utils.repos.transforms.kvs.ReadKeyValuesFromKeyValueRepo
|
||||
|
||||
/**
|
||||
* Adapter that exposes a [ReadKeyValuesRepo] as a [ReadKeyValueRepo] mapping each key to a [List] of values.
|
||||
* Each key's associated list of values is retrieved via [ReadKeyValuesRepo.getAll].
|
||||
*
|
||||
* @param Key The type of keys
|
||||
* @param Value The type of individual values in the one-to-many repo
|
||||
* @param original The underlying [ReadKeyValuesRepo] to delegate operations to
|
||||
*/
|
||||
open class ReadKeyValueFromKeyValuesRepo<Key, Value>(
|
||||
private val original: ReadKeyValuesRepo<Key, Value>
|
||||
) : ReadKeyValueRepo<Key, List<Value>> {
|
||||
|
||||
@@ -5,17 +5,51 @@ import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||
import kotlin.js.JsName
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
|
||||
/**
|
||||
* Wraps this [ReadKeyValueRepo] (mapping keys to iterables) as a [ReadKeyValuesFromKeyValueRepo],
|
||||
* exposing a one-to-many read interface.
|
||||
*
|
||||
* @param K The type of keys
|
||||
* @param V The type of individual values within each iterable
|
||||
* @param VI The iterable type storing multiple values per key
|
||||
* @return [ReadKeyValuesFromKeyValueRepo] delegating to this repo
|
||||
*/
|
||||
fun <K, V, VI : Iterable<V>> ReadKeyValueRepo<K, VI>.asReadKeyValuesRepo() = ReadKeyValuesFromKeyValueRepo(this)
|
||||
|
||||
/**
|
||||
* Wraps this [KeyValueRepo] (mapping keys to iterables) as a [KeyValuesFromKeyValueRepo],
|
||||
* exposing a full one-to-many read-write interface.
|
||||
*
|
||||
* @param K The type of keys
|
||||
* @param V The type of individual values within each iterable
|
||||
* @param VI The iterable type storing multiple values per key
|
||||
* @param listToValuesIterable Converter from [List] of values to [VI] used when persisting changes
|
||||
* @return [KeyValuesFromKeyValueRepo] delegating to this repo
|
||||
*/
|
||||
fun <K, V, VI : Iterable<V>> KeyValueRepo<K, VI>.asKeyValuesRepo(
|
||||
listToValuesIterable: suspend (List<V>) -> VI
|
||||
): KeyValuesFromKeyValueRepo<K, V, VI> = KeyValuesFromKeyValueRepo(this, listToValuesIterable)
|
||||
|
||||
/**
|
||||
* Wraps this [KeyValueRepo] (mapping keys to [List]s) as a [KeyValuesFromKeyValueRepo].
|
||||
* Uses identity conversion for the list iterable.
|
||||
*
|
||||
* @param K The type of keys
|
||||
* @param V The type of individual values
|
||||
* @return [KeyValuesFromKeyValueRepo] delegating to this repo with [List] as the iterable type
|
||||
*/
|
||||
@JvmName("asListKeyValuesRepo")
|
||||
@JsName("asListKeyValuesRepo")
|
||||
fun <K, V> KeyValueRepo<K, List<V>>.asKeyValuesRepo(): KeyValuesFromKeyValueRepo<K, V, List<V>> = asKeyValuesRepo { it }
|
||||
|
||||
/**
|
||||
* Wraps this [KeyValueRepo] (mapping keys to [Set]s) as a [KeyValuesFromKeyValueRepo].
|
||||
* Converts lists to sets when persisting changes, ensuring value uniqueness per key.
|
||||
*
|
||||
* @param K The type of keys
|
||||
* @param V The type of individual values
|
||||
* @return [KeyValuesFromKeyValueRepo] delegating to this repo with [Set] as the iterable type
|
||||
*/
|
||||
@JvmName("asSetKeyValuesRepo")
|
||||
@JsName("asSetKeyValuesRepo")
|
||||
fun <K, V> KeyValueRepo<K, Set<V>>.asKeyValuesRepo(): KeyValuesFromKeyValueRepo<K, V, Set<V>> = asKeyValuesRepo { it.toSet() }
|
||||
|
||||
@@ -12,6 +12,17 @@ import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlin.js.JsName
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* Full read-write adapter that exposes a [KeyValueRepo] storing iterables as a [KeyValuesRepo].
|
||||
* Extends [ReadKeyValuesFromKeyValueRepo] with write operations: add, remove, clear.
|
||||
* Emits [onNewValue] and [onValueRemoved] for individual value changes; [onDataCleared] mirrors [KeyValueRepo.onValueRemoved].
|
||||
*
|
||||
* @param Key The type of keys
|
||||
* @param Value The type of individual values within each iterable
|
||||
* @param ValuesIterable The iterable type storing multiple values per key
|
||||
* @param original The underlying [KeyValueRepo] mapping keys to iterables of values
|
||||
* @param listToValuesIterable Converter from [List] of values to [ValuesIterable] used when persisting changes
|
||||
*/
|
||||
open class KeyValuesFromKeyValueRepo<Key, Value, ValuesIterable : Iterable<Value>>(
|
||||
private val original: KeyValueRepo<Key, ValuesIterable>,
|
||||
private val listToValuesIterable: suspend (List<Value>) -> ValuesIterable
|
||||
|
||||
@@ -11,6 +11,15 @@ import dev.inmo.micro_utils.pagination.utils.paginate
|
||||
import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||
|
||||
/**
|
||||
* Adapter that exposes a [ReadKeyValueRepo] storing iterables as a [ReadKeyValuesRepo].
|
||||
* Each key maps to a [ValuesIterable] in the underlying repo, which is exposed as a one-to-many relationship.
|
||||
*
|
||||
* @param Key The type of keys
|
||||
* @param Value The type of individual values within each iterable
|
||||
* @param ValuesIterable The iterable type storing multiple values per key
|
||||
* @param original The underlying [ReadKeyValueRepo] mapping keys to iterables of values
|
||||
*/
|
||||
open class ReadKeyValuesFromKeyValueRepo<Key, Value, ValuesIterable : Iterable<Value>>(
|
||||
private val original: ReadKeyValueRepo<Key, ValuesIterable>
|
||||
) : ReadKeyValuesRepo<Key, Value> {
|
||||
|
||||
@@ -3,6 +3,14 @@ package dev.inmo.micro_utils.repos.versions
|
||||
import dev.inmo.micro_utils.repos.KeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.set
|
||||
|
||||
/**
|
||||
* [StandardVersionsRepoProxy] implementation backed by a [KeyValueRepo] mapping table names to version numbers.
|
||||
* Stores and retrieves per-table version integers using [keyValueStore] with table names as keys.
|
||||
*
|
||||
* @param T The type of the underlying database or storage object
|
||||
* @param keyValueStore [KeyValueRepo] used to persist table-name-to-version mappings
|
||||
* @param database The underlying database or storage object exposed via [StandardVersionsRepoProxy.database]
|
||||
*/
|
||||
class KeyValueBasedVersionsRepoProxy<T>(
|
||||
private val keyValueStore: KeyValueRepo<String, Int>,
|
||||
override val database: T
|
||||
|
||||
@@ -2,13 +2,43 @@ package dev.inmo.micro_utils.repos.versions
|
||||
|
||||
import dev.inmo.micro_utils.repos.Repo
|
||||
|
||||
/**
|
||||
* Proxy interface providing low-level access to a versioned database [T].
|
||||
* Implementations store and retrieve per-table version numbers using a backing storage.
|
||||
*
|
||||
* @param T The type of the underlying database or storage object
|
||||
*/
|
||||
interface StandardVersionsRepoProxy<T> : Repo {
|
||||
/**
|
||||
* The underlying database or storage object used for version tracking.
|
||||
*/
|
||||
val database: T
|
||||
|
||||
/**
|
||||
* Returns the current version number for the given [tableName], or null if no version is stored.
|
||||
*
|
||||
* @param tableName Name of the table whose version to retrieve
|
||||
* @return Stored version number, or null if the table has not been versioned yet
|
||||
*/
|
||||
suspend fun getTableVersion(tableName: String): Int?
|
||||
|
||||
/**
|
||||
* Persists the given [version] number for the given [tableName].
|
||||
*
|
||||
* @param tableName Name of the table whose version to update
|
||||
* @param version New version number to store
|
||||
*/
|
||||
suspend fun updateTableVersion(tableName: String, version: Int)
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard implementation of [VersionsRepo] that delegates version storage to a [StandardVersionsRepoProxy].
|
||||
* On [setTableVersion]: calls [StandardVersionsRepoProxy.database].[onCreate] if the table has no version yet,
|
||||
* then iterates [onUpdate] for each version step until the target [version] is reached.
|
||||
*
|
||||
* @param T The type of the underlying database or storage object
|
||||
* @param proxy The [StandardVersionsRepoProxy] used to read and write version numbers
|
||||
*/
|
||||
class StandardVersionsRepo<T>(
|
||||
private val proxy: StandardVersionsRepoProxy<T>
|
||||
) : VersionsRepo<T> {
|
||||
@@ -30,4 +60,4 @@ class StandardVersionsRepo<T>(
|
||||
proxy.updateTableVersion(tableName, currentVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user