11package com.philkes.notallyx.data.dao
22
3+ import android.content.ContextWrapper
34import androidx.room.Dao
45import androidx.room.Transaction
56import com.philkes.notallyx.data.NotallyDatabase
7+ import com.philkes.notallyx.data.dao.BaseNoteDao.Companion.MAX_BODY_CHAR_LENGTH
68import com.philkes.notallyx.data.model.BaseNote
79import com.philkes.notallyx.data.model.Label
810import com.philkes.notallyx.data.model.LabelsInBaseNote
11+ import com.philkes.notallyx.data.model.SpanRepresentation
12+ import com.philkes.notallyx.data.model.Type
913import com.philkes.notallyx.data.model.createNoteUrl
1014import com.philkes.notallyx.data.model.getNoteIdFromUrl
1115import com.philkes.notallyx.data.model.getNoteTypeFromUrl
1216import com.philkes.notallyx.data.model.isNoteUrl
17+ import com.philkes.notallyx.utils.NoteSplitUtils
1318
1419@Dao
1520abstract class CommonDao (private val database : NotallyDatabase ) {
@@ -40,8 +45,20 @@ abstract class CommonDao(private val database: NotallyDatabase) {
4045 }
4146
4247 @Transaction
43- open suspend fun importBackup (baseNotes : List <BaseNote >, labels : List <Label >) {
44- database.getBaseNoteDao().insert(baseNotes)
48+ open suspend fun importBackup (
49+ context : ContextWrapper ,
50+ baseNotes : List <BaseNote >,
51+ labels : List <Label >,
52+ ) {
53+ val dao = database.getBaseNoteDao()
54+ // Insert notes, splitting oversized text notes instead of truncating
55+ baseNotes.forEach { note ->
56+ if (note.type == Type .NOTE && note.body.length > MAX_BODY_CHAR_LENGTH ) {
57+ NoteSplitUtils .splitAndInsertForImport(note, dao)
58+ } else {
59+ dao.insert(note.copy(id = 0 ))
60+ }
61+ }
4562 database.getLabelDao().insert(labels)
4663 }
4764
@@ -57,21 +74,31 @@ abstract class CommonDao(private val database: NotallyDatabase) {
5774 labels : List <Label >,
5875 ) {
5976 val baseNoteDao = database.getBaseNoteDao()
60- val newIds = baseNoteDao.insert(baseNotes)
61- // Build old->new mapping using positional correspondence
77+
78+ // 1) Insert notes with splitting; build mapping from original id -> first-part new id
6279 val idMap = HashMap <Long , Long >(originalIds.size)
63- val count = minOf(originalIds.size, newIds.size)
64- for (i in 0 until count) {
65- idMap[originalIds[i]] = newIds[i]
66- }
80+ // Keep all inserted note ids with their spans for remapping pass
81+ val insertedParts = ArrayList <Pair <Long , List <SpanRepresentation >>>()
6782
68- // Remap note links in spans where necessary
6983 for (i in baseNotes.indices) {
70- val note = baseNotes[i]
71- val newId = newIds.getOrNull(i) ? : continue
84+ val original = baseNotes[i]
85+ val (firstId, parts) =
86+ if (original.type == Type .NOTE && original.body.length > MAX_BODY_CHAR_LENGTH ) {
87+ NoteSplitUtils .splitAndInsertForImport(original, baseNoteDao)
88+ } else {
89+ val newId = baseNoteDao.insert(original.copy(id = 0 ))
90+ Pair (newId, listOf (Pair (newId, original.spans)))
91+ }
92+ val oldId = originalIds.getOrNull(i)
93+ if (oldId != null ) idMap[oldId] = firstId
94+ insertedParts.addAll(parts)
95+ }
96+
97+ // 2) Remap note links in spans for all inserted notes
98+ for ((noteId, spans) in insertedParts) {
7299 var changed = false
73- val updatedSpans =
74- note. spans.map { span ->
100+ val updated =
101+ spans.map { span ->
75102 if (span.link && span.linkData?.isNoteUrl() == true ) {
76103 val url = span.linkData!!
77104 val oldTargetId = url.getNoteIdFromUrl()
@@ -80,13 +107,11 @@ abstract class CommonDao(private val database: NotallyDatabase) {
80107 if (newTargetId != null ) {
81108 changed = true
82109 span.copy(linkData = newTargetId.createNoteUrl(type))
83- } else {
84- span
85- }
110+ } else span
86111 } else span
87112 }
88113 if (changed) {
89- baseNoteDao.updateSpans(newId, updatedSpans )
114+ baseNoteDao.updateSpans(noteId, updated )
90115 }
91116 }
92117
0 commit comments