Skip to content

Commit d9d7ad0

Browse files
committed
feat: assign tags to the respective links during copying
1 parent 0f6b409 commit d9d7ad0

2 files changed

Lines changed: 94 additions & 43 deletions

File tree

src/main/kotlin/com/sakethh/linkora/data/repository/MultiActionRepoImpl.kt

Lines changed: 91 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.sakethh.linkora.domain.model.WebSocketEvent
1010
import com.sakethh.linkora.domain.repository.FoldersRepo
1111
import com.sakethh.linkora.domain.repository.MultiActionRepo
1212
import com.sakethh.linkora.domain.tables.FoldersTable
13+
import com.sakethh.linkora.domain.tables.LinkTagTable
1314
import com.sakethh.linkora.domain.tables.LinksTable
1415
import com.sakethh.linkora.domain.tables.helper.TombStoneHelper
1516
import com.sakethh.linkora.utils.checkForLWWConflictAndThrow
@@ -22,13 +23,11 @@ import kotlinx.serialization.encodeToString
2223
import kotlinx.serialization.json.Json
2324
import kotlinx.serialization.json.encodeToJsonElement
2425
import org.jetbrains.exposed.v1.core.SqlExpressionBuilder.inList
25-
import org.jetbrains.exposed.v1.core.and
26+
import org.jetbrains.exposed.v1.jdbc.batchInsert
2627
import org.jetbrains.exposed.v1.jdbc.deleteWhere
27-
import org.jetbrains.exposed.v1.jdbc.select
2828
import org.jetbrains.exposed.v1.jdbc.selectAll
2929
import org.jetbrains.exposed.v1.jdbc.transactions.transaction
3030
import org.jetbrains.exposed.v1.jdbc.update
31-
import java.time.Instant
3231

3332
class MultiActionRepoImpl(
3433
private val foldersRepo: FoldersRepo
@@ -172,26 +171,33 @@ class MultiActionRepoImpl(
172171
override suspend fun copyMultipleItems(copyItemsDTO: CopyItemsDTO): Result<CopyItemsHTTPResponseDTO> {
173172
return try {
174173
val eventTimestamp = getSystemEpochSeconds()
175-
lateinit var linkIds: List<Long>
174+
lateinit var newGlobalSelectedLinkIds: List<Long>
176175
println("Remote Links : ${copyItemsDTO.linkIds.values}")
177176
// copy the links based on `copyItemsDTO.linkIds`
178177
val copiedFolderResponse = mutableListOf<CopiedFolderResponse>()
179178
transaction {
180-
this.exec(
181-
"""
182-
INSERT INTO links_table (last_modified,link_type,link_title,url,base_url,img_url,note,id_of_linked_folder,user_agent,media_type,marked_as_important)
183-
SELECT $eventTimestamp AS last_modified,'${copyItemsDTO.linkType.name}' AS link_type,link_title,url,base_url,img_url,note,${copyItemsDTO.newParentFolderId} AS id_of_linked_folder,user_agent,media_type,marked_as_important FROM links_table
184-
WHERE id IN (${copyItemsDTO.linkIds.values.joinToString(separator = ",")});
185-
""".trimIndent()
186-
)
187-
linkIds = LinksTable.select(LinksTable.id).where {
188-
LinksTable.lastModified.eq(eventTimestamp) and LinksTable.linkType.eq(copyItemsDTO.linkType.name) and LinksTable.idOfLinkedFolder.eq(
189-
copyItemsDTO.newParentFolderId
190-
)
191-
}.map { resultRow ->
192-
resultRow[LinksTable.id].value
179+
val sourceGlobalSelectedLinks = LinksTable.selectAll().where {
180+
LinksTable.id inList copyItemsDTO.linkIds.values
193181
}.toList()
194182

183+
newGlobalSelectedLinkIds = LinksTable.copy(
184+
source = sourceGlobalSelectedLinks,
185+
eventTimestamp = eventTimestamp,
186+
parentFolderId = copyItemsDTO.newParentFolderId,
187+
newLinkType = copyItemsDTO.linkType
188+
).map {
189+
it[LinksTable.id].value
190+
}
191+
192+
val sourceGlobalSelectedLinksIds = sourceGlobalSelectedLinks.map {
193+
it[LinksTable.id].value
194+
}
195+
196+
val globalOldToNewLinkIdsMap = sourceGlobalSelectedLinksIds.zip(newGlobalSelectedLinkIds).toMap()
197+
198+
insertNewLinkTags(
199+
oldToNewLinkIdsMap = globalOldToNewLinkIdsMap
200+
)
195201

196202
// initially, we'll insert the root folders
197203
lateinit var copiedRootFolderIds: List<Long>
@@ -222,12 +228,23 @@ class MultiActionRepoImpl(
222228
val sourceLinksOfRootFolder = LinksTable.selectAll().where {
223229
LinksTable.idOfLinkedFolder.eq(folderId)
224230
}.toList()
231+
val sourceLinksIdsOfRootFolder = sourceLinksOfRootFolder.map {
232+
it[LinksTable.id].value
233+
}
225234
val eventTimestamp = getSystemEpochSeconds()
226-
LinksTable.copy(
235+
val newRootFolderLinkIds = LinksTable.copy(
227236
source = sourceLinksOfRootFolder,
228237
eventTimestamp = eventTimestamp,
229238
parentFolderId = copiedRootFolderIds[folderIndex]
230-
).mapIndexed { linkResultRowIndex, resultRow ->
239+
)
240+
241+
insertNewLinkTags(
242+
oldToNewLinkIdsMap = sourceLinksIdsOfRootFolder.zip(newRootFolderLinkIds.map {
243+
it[LinksTable.id].value
244+
}).toMap()
245+
)
246+
247+
newRootFolderLinkIds.mapIndexed { linkResultRowIndex, resultRow ->
231248
FolderLink(
232249
localId = copyItemsDTO.folders[folderIndex].links[linkResultRowIndex].localId,
233250
remoteId = resultRow[LinksTable.id].value
@@ -251,29 +268,38 @@ class MultiActionRepoImpl(
251268
.forEachIndexed { insertedFolderRowIndex, insertedFolderRow ->
252269
val newParentFolderId = insertedFolderRow[FoldersTable.id].value
253270
val sourceParentFolderId = sourceFolders[insertedFolderRowIndex][FoldersTable.id].value
254-
255-
LinksTable.selectAll().where {
271+
val sourceCurrentFolderLinks = LinksTable.selectAll().where {
256272
LinksTable.idOfLinkedFolder.eq(sourceParentFolderId)
273+
}
274+
val sourceCurrentFolderLinkIds = sourceCurrentFolderLinks.map {
275+
it[LinksTable.id].value
276+
}
277+
val newChildFolderLinks = LinksTable.copy(
278+
source = sourceCurrentFolderLinks.toList(),
279+
eventTimestamp = eventTimestamp,
280+
parentFolderId = newParentFolderId
281+
)
282+
283+
insertNewLinkTags(
284+
oldToNewLinkIdsMap = sourceCurrentFolderLinkIds.zip(newChildFolderLinks.map {
285+
it[LinksTable.id].value
286+
}).toMap()
287+
)
288+
289+
newChildFolderLinks.mapIndexed { insertedLinkRowIndex, insertedLinkRow ->
290+
FolderLink(
291+
localId = childFolders[insertedFolderRowIndex].links[insertedLinkRowIndex].localId,
292+
remoteId = insertedLinkRow[LinksTable.id].value
293+
)
257294
}.let {
258-
LinksTable.copy(
259-
source = it.toList(),
260-
eventTimestamp = eventTimestamp,
261-
parentFolderId = newParentFolderId
262-
).mapIndexed { insertedLinkRowIndex, insertedLinkRow ->
263-
FolderLink(
264-
localId = childFolders[insertedFolderRowIndex].links[insertedLinkRowIndex].localId,
265-
remoteId = insertedLinkRow[LinksTable.id].value
266-
)
267-
}.let {
268-
copiedFolderResponse.add(
269-
CopiedFolderResponse(
270-
currentFolder = CurrentFolder(
271-
localId = childFolders[insertedFolderRowIndex].currentFolder.localId,
272-
remoteId = newParentFolderId
273-
), links = it
274-
)
295+
copiedFolderResponse.add(
296+
CopiedFolderResponse(
297+
currentFolder = CurrentFolder(
298+
localId = childFolders[insertedFolderRowIndex].currentFolder.localId,
299+
remoteId = newParentFolderId
300+
), links = it
275301
)
276-
}
302+
)
277303
}
278304
insertChildFolders(
279305
newParentFolderId, childFolders[insertedFolderRowIndex].childFolders
@@ -284,7 +310,7 @@ class MultiActionRepoImpl(
284310
// insert child folders
285311
copyItemsDTO.folders.forEachIndexed { index, parentFolder ->
286312
insertChildFolders(
287-
copiedRootFolderIds[index], parentFolder.childFolders
313+
parentFolderId = copiedRootFolderIds[index], childFolders = parentFolder.childFolders
288314
)
289315
}
290316

@@ -293,7 +319,7 @@ class MultiActionRepoImpl(
293319
response = CopyItemsHTTPResponseDTO(
294320
folders = copiedFolderResponse.toList(), linkIds = copyItemsDTO.linkIds.run {
295321
this.toList().mapIndexed { index, pair ->
296-
pair.first to linkIds[index]
322+
pair.first to newGlobalSelectedLinkIds[index]
297323
}.toMap()
298324
}, correlation = copyItemsDTO.correlation, eventTimestamp = eventTimestamp
299325
), webSocketEvent = WebSocketEvent(
@@ -310,6 +336,30 @@ class MultiActionRepoImpl(
310336
}
311337
}
312338

339+
private fun insertNewLinkTags(oldToNewLinkIdsMap: Map<Long, Long>) {
340+
val eventTimestamp = getSystemEpochSeconds()
341+
val previousAssignedTags = LinkTagTable.selectAll().where {
342+
LinkTagTable.linkId inList oldToNewLinkIdsMap.keys
343+
}.groupBy {
344+
it[LinkTagTable.linkId]
345+
}.mapValues {
346+
it.value.map {
347+
it[LinkTagTable.tagId]
348+
}
349+
}
350+
351+
previousAssignedTags.forEach { (linkId, tagsIds) ->
352+
val newLinkId = oldToNewLinkIdsMap[linkId]
353+
if (newLinkId != null) {
354+
LinkTagTable.batchInsert(tagsIds) {
355+
this[LinkTagTable.tagId] = it
356+
this[LinkTagTable.linkId] = newLinkId
357+
this[LinkTagTable.lastModified] = eventTimestamp
358+
}
359+
}
360+
}
361+
}
362+
313363
override suspend fun markItemsAsRegular(markItemsRegularDTO: MarkItemsRegularDTO): Result<TimeStampBasedResponse> {
314364
return try {
315365
val eventTimestamp = getSystemEpochSeconds()

src/main/kotlin/com/sakethh/linkora/utils/HelperFunctions.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.sakethh.linkora.utils
22

33
import com.sakethh.linkora.domain.LWWConflictException
4+
import com.sakethh.linkora.domain.LinkType
45
import com.sakethh.linkora.domain.Result
56
import com.sakethh.linkora.domain.tables.FoldersTable
67
import com.sakethh.linkora.domain.tables.LinksTable
@@ -54,10 +55,10 @@ fun FoldersTable.copy(source: List<ResultRow>, eventTimestamp: Long, parentFolde
5455
}.toList()
5556
}
5657

57-
fun LinksTable.copy(source: List<ResultRow>, eventTimestamp: Long, parentFolderId: Long?): List<ResultRow> {
58+
fun LinksTable.copy(source: List<ResultRow>, eventTimestamp: Long, parentFolderId: Long?, newLinkType: LinkType? = null): List<ResultRow> {
5859
return batchInsert(source) {
5960
set(lastModified, eventTimestamp)
60-
set(linkType, it[linkType])
61+
set(linkType, newLinkType?.name ?: it[linkType])
6162
set(linkTitle, it[linkTitle])
6263
set(url, it[url])
6364
set(baseURL, it[baseURL])

0 commit comments

Comments
 (0)