@@ -74,11 +74,47 @@ func NewCSVBibliographyRepository(filePath string) *CSVBibliographyRepository {
7474// without any locking mechanism. Acceptable for single-user CLI usage, but consider file locking
7575// or using a database with proper transaction support for production use.
7676func (r * CSVBibliographyRepository ) Save (b * domain.Bibliography ) error {
77- all , err := r . FindAll ( )
77+ records , err := ReadCSV ( r . FilePath )
7878 if err != nil {
7979 return err
8080 }
8181
82+ // Skip header
83+ if len (records ) > 0 {
84+ records = records [1 :]
85+ }
86+
87+ iter := NewCSVRecordIterator (records , 0 , 0 )
88+ var all []* domain.Bibliography
89+
90+ for iter .Next () {
91+ record := iter .Record ()
92+ if len (record ) < 9 {
93+ continue
94+ }
95+ bibRecord := & BibliographyRecord {
96+ ID : record [0 ],
97+ BibIndex : record [1 ],
98+ Code : record [2 ],
99+ Type : record [3 ],
100+ Title : record [4 ],
101+ Author : record [5 ],
102+ Publisher : record [6 ],
103+ ISBN : record [7 ],
104+ PublishedDate : record [8 ],
105+ }
106+ bib , err := recordToBibliography (bibRecord )
107+ if err != nil {
108+ slog .Error ("Failed to convert bibliography record" , "err" , err )
109+ continue
110+ }
111+ all = append (all , bib )
112+ }
113+
114+ if iter .Err () != nil {
115+ return iter .Err ()
116+ }
117+
82118 updated := false
83119 for i , existing := range all {
84120 if existing .ID == b .ID {
@@ -94,19 +130,22 @@ func (r *CSVBibliographyRepository) Save(b *domain.Bibliography) error {
94130 return r .writeAll (all )
95131}
96132
97- func (r * CSVBibliographyRepository ) FindAll () ([]* domain.Bibliography , error ) {
133+ func (r * CSVBibliographyRepository ) FindAll (limit , offset int ) ([]* domain.Bibliography , error ) {
98134 records , err := ReadCSV (r .FilePath )
99135 if err != nil {
100136 return nil , err
101137 }
102138
103- var bibliographies []* domain.Bibliography
104139 // Skip header
105140 if len (records ) > 0 {
106141 records = records [1 :]
107142 }
108143
109- for _ , record := range records {
144+ iter := NewCSVRecordIterator (records , limit , offset )
145+ var bibliographies []* domain.Bibliography
146+
147+ for iter .Next () {
148+ record := iter .Record ()
110149 if len (record ) < 9 {
111150 continue
112151 }
@@ -131,39 +170,87 @@ func (r *CSVBibliographyRepository) FindAll() ([]*domain.Bibliography, error) {
131170
132171 bibliographies = append (bibliographies , bib )
133172 }
134- return bibliographies , nil
173+
174+ return bibliographies , iter .Err ()
135175}
136176
137177// FindByBibIndex implements domain.BibliographyRepository.FindByBibIndex
138- // Performance Note: This method calls FindAll() which reads and parses the entire CSV file.
139- // For large datasets, consider implementing caching or using a database for production use.
140178func (r * CSVBibliographyRepository ) FindByBibIndex (bibIndex string ) (* domain.Bibliography , error ) {
141- all , err := r . FindAll ( )
179+ records , err := ReadCSV ( r . FilePath )
142180 if err != nil {
143181 return nil , err
144182 }
145- for _ , b := range all {
146- if b .BibIndex == bibIndex {
147- return b , nil
183+
184+ // Skip header
185+ if len (records ) > 0 {
186+ records = records [1 :]
187+ }
188+
189+ iter := NewCSVRecordIterator (records , 0 , 0 )
190+
191+ for iter .Next () {
192+ record := iter .Record ()
193+ if len (record ) < 9 {
194+ continue
195+ }
196+ // Optimization: Check BibIndex (index 1) before full conversion
197+ if record [1 ] == bibIndex {
198+ bibRecord := & BibliographyRecord {
199+ ID : record [0 ],
200+ BibIndex : record [1 ],
201+ Code : record [2 ],
202+ Type : record [3 ],
203+ Title : record [4 ],
204+ Author : record [5 ],
205+ Publisher : record [6 ],
206+ ISBN : record [7 ],
207+ PublishedDate : record [8 ],
208+ }
209+ return recordToBibliography (bibRecord )
148210 }
149211 }
150- return nil , nil
212+
213+ return nil , iter .Err ()
151214}
152215
153216// FindByID implements domain.BibliographyRepository.FindByID
154- // Performance Note: This method calls FindAll() which reads and parses the entire CSV file.
155- // For large datasets, consider implementing caching or using a database for production use.
156217func (r * CSVBibliographyRepository ) FindByID (id domain.BibliographyID ) (* domain.Bibliography , error ) {
157- all , err := r . FindAll ( )
218+ records , err := ReadCSV ( r . FilePath )
158219 if err != nil {
159220 return nil , err
160221 }
161- for _ , b := range all {
162- if b .ID == id {
163- return b , nil
222+
223+ // Skip header
224+ if len (records ) > 0 {
225+ records = records [1 :]
226+ }
227+
228+ iter := NewCSVRecordIterator (records , 0 , 0 )
229+ idStr := id .String ()
230+
231+ for iter .Next () {
232+ record := iter .Record ()
233+ if len (record ) < 9 {
234+ continue
235+ }
236+ // Optimization: Check ID (index 0) before full conversion
237+ if record [0 ] == idStr {
238+ bibRecord := & BibliographyRecord {
239+ ID : record [0 ],
240+ BibIndex : record [1 ],
241+ Code : record [2 ],
242+ Type : record [3 ],
243+ Title : record [4 ],
244+ Author : record [5 ],
245+ Publisher : record [6 ],
246+ ISBN : record [7 ],
247+ PublishedDate : record [8 ],
248+ }
249+ return recordToBibliography (bibRecord )
164250 }
165251 }
166- return nil , nil
252+
253+ return nil , iter .Err ()
167254}
168255
169256func (r * CSVBibliographyRepository ) writeAll (bibliographies []* domain.Bibliography ) error {
0 commit comments