5 #include <exec/types.h>
6 #include <graphics/gels.h>
7 #include <graphics/rastport.h>
8 #include <scalos/scalosgfx.h>
12 #include <proto/dos.h>
13 #include <proto/exec.h>
14 #include <proto/graphics.h>
15 #include <proto/utility.h>
16 #include <proto/timer.h>
19 #include <proto/scalosgfx.h>
20 #include <proto/scalos.h>
21 #include <proto/sqlite3.h>
23 #include <clib/alib_protos.h>
32 #include "scalos_structures.h"
33 #include "FsAbstraction.h"
34 #include "functions.h"
35 #include "Variables.h"
37 //-----------------------------------------------------------------------
39 #define THUMBNAIL_TABLE_NAME_OLD "ScalosThumbNailTable"
40 #define THUMBNAIL_TABLE_NAME "ScalosThumbNailTableV2"
42 // column inidecs for use with SQLite3Column_***()
43 #define COLUMN_THUMBNAIL_ENDOFLIFE 0
44 #define COLUMN_THUMBNAIL_FILENAME 1
45 #define COLUMN_THUMBNAIL_DEPTH 2
46 #define COLUMN_THUMBNAIL_PREFSWIDTH 3
47 #define COLUMN_THUMBNAIL_PREFSHEIGHT 4
48 #define COLUMN_THUMBNAIL_FILEDATE 5
49 #define COLUMN_THUMBNAIL_IMAGEDATA 6
51 //-----------------------------------------------------------------------
53 struct CachedThumbnail
55 struct DateStamp ctn_FileDate
;
57 ULONG ctn_ThumbnailDepth
;
60 UBYTE
*ctn_ThumbnailData
;
61 size_t ctn_ThumbnailDataSize
;
64 //-----------------------------------------------------------------------
68 //-----------------------------------------------------------------------
70 static int ThumbnailCacheAddEntry(sqlite3
*db
, CONST_STRPTR FileName
,
71 const struct DateStamp
*FileDate
, ULONG Depth
,
72 void *ThumbnailData
, size_t ThumbnailDataSize
, ULONG LifetimeDays
);
73 static BOOL
ThumbnailCacheFindEntry(sqlite3
*db
, CONST_STRPTR FileName
,
74 struct CachedThumbnail
*ctn
, ULONG LifetimeDays
);
75 static BOOL
ThumbnailCacheDeleteEntry(sqlite3
*db
, CONST_STRPTR FileName
);
76 static BOOL
ThumbnailCacheUpdateEndOfLife(sqlite3
*db
, CONST_STRPTR FileName
, const T_TIMEVAL
*tv
);
77 static STRPTR
ThumbnailCacheGetFileNameFromLock(BPTR fLock
);
78 static BOOL
ThumbnailCacheIsSameDay(ULONG sec1
, ULONG sec2
);
79 static int ThumbnailCacheSetMode(sqlite3
*db
);
80 static int ThumbnailCacheCreateTable(sqlite3
*db
);
81 static void ThumbnailCacheGetEndOfLife(T_TIMEVAL
*tv
, ULONG LifetimeDays
);
82 static void ThumbnailCacheFileExists(sqlite3_context
*context
, LONG x
, sqlite3_value
**pVal
);
83 static int ThumbnailCacheSetTempDir(sqlite3
*db
, CONST_STRPTR DirName
);
85 //-----------------------------------------------------------------------
87 BOOL
ThumbnailCacheInit(void)
92 d1(KPrintF("%s/%s/%ld: START SQLite3Base=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Base
));
97 if (NULL
== SQLite3Base
)
99 if (strlen(CurrentPrefs
.pref_ThumbDatabasePath
) < 1)
102 rc
= SQLite3Open(CurrentPrefs
.pref_ThumbDatabasePath
, &db
);
103 d1(KPrintF("%s/%s/%ld: rc=%ld db=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, rc
, db
));
106 d1(KPrintF("%s/%s/%ld: SQLite3Open() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
110 rc
= SQLite3BusyTimeout(db
, 100);
111 if (SQLITE_OK
!= rc
)
113 d1(KPrintF("%s/%s/%ld: SQLite3BusyTimeout() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
117 // try to create our table
118 rc
= ThumbnailCacheCreateTable(db
);
119 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
120 if (SQLITE_OK
!= rc
)
122 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errcode(db
)));
126 rc
= ThumbnailCacheSetMode(db
);
127 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
128 if (SQLITE_OK
!= rc
)
130 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errcode(db
)));
135 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
146 void CleanupThumbnailCache(void)
148 d1(KPrintF("%s/%s/%ld: START \n", __FILE__
, __FUNC__
, __LINE__
));
152 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
155 //-----------------------------------------------------------------------
157 BOOL
ThumbnailCacheOpen(APTR
*pThumbnailCacheHandle
)
159 BOOL Success
= FALSE
;
162 d1(KPrintF("%s/%s/%ld: START \n", __FILE__
, __FUNC__
, __LINE__
));
163 *pThumbnailCacheHandle
= NULL
;
168 if (NULL
== SQLite3Base
)
170 if (strlen(CurrentPrefs
.pref_ThumbDatabasePath
) < 1)
173 rc
= SQLite3Open(CurrentPrefs
.pref_ThumbDatabasePath
, &db
);
174 d1(KPrintF("%s/%s/%ld: db=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, db
));
177 d1(KPrintF("%s/%s/%ld: SQLite3Open() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
181 rc
= ThumbnailCacheCreateTable(db
);
182 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
185 d1(KPrintF("%s/%s/%ld: ThumbnailCacheCreateTable() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
189 rc
= ThumbnailCacheSetTempDir(db
, CurrentPrefs
.pref_SQLiteTempDir
);
192 d1(KPrintF("%s/%s/%ld: ThumbnailCacheSetTempDir() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
197 *pThumbnailCacheHandle
= (APTR
) db
;
202 ThumbnailCacheClose(pThumbnailCacheHandle
);
205 d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Success
));
211 void ThumbnailCacheClose(APTR
*pThumbnailCacheHandle
)
213 sqlite3
*db
= (sqlite3
*) *pThumbnailCacheHandle
;
215 d1(KPrintF("%s/%s/%ld: START db=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, db
));
216 if (SQLite3Base
&& db
)
219 *pThumbnailCacheHandle
= NULL
;
221 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
224 //-----------------------------------------------------------------------
226 static int ThumbnailCacheAddEntry(sqlite3
*db
, CONST_STRPTR FileName
,
227 const struct DateStamp
*FileDate
, ULONG Depth
,
228 void *ThumbnailData
, size_t ThumbnailDataSize
, ULONG LifetimeDays
)
232 d1(KPrintF("%s/%s/%ld: START FileName=<%s> ThumbnailData=%08lx ThumbnailDataSize=%lu\n", \
233 __FILE__
, __FUNC__
, __LINE__
, FileName
, ThumbnailData
, ThumbnailDataSize
));
237 sqlite3_stmt
*pStmt
= NULL
;
238 CONST_STRPTR Tail
= NULL
;
239 static CONST_STRPTR Cmd
=
240 "INSERT OR REPLACE INTO " THUMBNAIL_TABLE_NAME
" "
241 "VALUES(:endoflife, :path, :depth, "
242 ":prefwidth, :prefheight, :filedate, :thumbnail);";
244 rc
= SQLite3PrepareV2(db
,
248 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
251 d1(KPrintF("%s/%s/%ld: SQLite3PrepareV2() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
256 ThumbnailCacheGetEndOfLife(&tv
, LifetimeDays
);
258 rc
= SQLite3BindInt(pStmt
, 1, tv
.tv_secs
);
259 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
264 rc
= SQLite3BindText(pStmt
, 2,
265 FileName
, strlen(FileName
),
267 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
272 rc
= SQLite3BindInt(pStmt
, 3, Depth
);
273 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
278 rc
= SQLite3BindInt(pStmt
, 4, CurrentPrefs
.pref_ThumbNailWidth
);
279 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
284 rc
= SQLite3BindInt(pStmt
, 5, CurrentPrefs
.pref_ThumbNailHeight
);
285 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
290 rc
= SQLite3BindBlob(pStmt
, 6,
291 (void *) FileDate
, sizeof(struct DateStamp
),
293 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
298 rc
= SQLite3BindBlob(pStmt
, 7,
299 ThumbnailData
, ThumbnailDataSize
,
301 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
306 rc
= SQLite3Step(pStmt
);
307 if (SQLITE_BUSY
== rc
)
309 } while (SQLITE_ROW
== rc
|| SQLITE_BUSY
== rc
);
311 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
312 if (SQLITE_DONE
!= rc
)
315 rc
= SQLite3Finalize(pStmt
);
316 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
321 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
326 //-----------------------------------------------------------------------
328 static BOOL
ThumbnailCacheFindEntry(sqlite3
*db
, CONST_STRPTR FileName
,
329 struct CachedThumbnail
*ctn
, ULONG LifetimeDays
)
331 sqlite3_stmt
*pStmt
= NULL
;
335 ctn
->ctn_ThumbnailDepth
= 0;
336 ctn
->ctn_prefWidth
= ctn
->ctn_prefHeight
= 0;
337 ctn
->ctn_ThumbnailDataSize
= 0;
338 ctn
->ctn_ThumbnailData
= NULL
;
340 d1(KPrintF("%s/%s/%ld: START FileName=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, FileName
));
343 const void *BlobData
;
344 const struct DateStamp
*CachedFileDate
;
347 CONST_STRPTR Tail
= NULL
;
348 static CONST_STRPTR SelectCmd
=
349 "SELECT * FROM " THUMBNAIL_TABLE_NAME
" "
350 "WHERE IconPath = :path;";
352 rc
= SQLite3PrepareV2(db
,
353 SelectCmd
, strlen(SelectCmd
),
356 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
359 d1(KPrintF("%s/%s/%ld: SQLite3PrepareV2() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
363 rc
= SQLite3BindText(pStmt
, 1,
364 FileName
, strlen(FileName
),
366 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
371 rc
= SQLite3Step(pStmt
);
372 if (SQLITE_BUSY
== rc
)
374 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
375 } while (SQLITE_BUSY
== rc
);
377 // rc is SQLITE_ROW if a record had been found
378 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
379 if (SQLITE_ROW
!= rc
)
382 // check if there are rows available
383 DataCount
= SQLite3DataCount(pStmt
);
384 Found
= DataCount
> 0;
385 d1(KPrintF("%s/%s/%ld: DataCount=%ld Found=%ld\n", __FILE__
, __FUNC__
, __LINE__
, DataCount
, Found
));
389 // return last access
390 ctn
->ctn_EndOfLife
= SQLite3ColumnInt(pStmt
, COLUMN_THUMBNAIL_ENDOFLIFE
);
392 // return stored nominal thumbnail width+height
393 ctn
->ctn_prefWidth
= SQLite3ColumnInt(pStmt
, COLUMN_THUMBNAIL_PREFSWIDTH
);
394 ctn
->ctn_prefHeight
= SQLite3ColumnInt(pStmt
, COLUMN_THUMBNAIL_PREFSHEIGHT
);
396 // return depth of stored thumbnail
397 ctn
->ctn_ThumbnailDepth
= SQLite3ColumnInt(pStmt
, COLUMN_THUMBNAIL_DEPTH
);
400 ColumnBytes
= SQLite3ColumnBytes(pStmt
, COLUMN_THUMBNAIL_FILEDATE
);
401 d1(KPrintF("%s/%s/%ld: ColumnBytes=%ld\n", __FILE__
, __FUNC__
, __LINE__
, ColumnBytes
));
402 if (sizeof(struct DateStamp
) != ColumnBytes
)
404 CachedFileDate
= SQLite3ColumnBlob(pStmt
, COLUMN_THUMBNAIL_FILEDATE
);
405 d1(KPrintF("%s/%s/%ld: CachedFileDate=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, CachedFileDate
));
407 ctn
->ctn_FileDate
= *CachedFileDate
;
411 // return copy of thumbnail image data
412 BlobData
= SQLite3ColumnBlob(pStmt
, COLUMN_THUMBNAIL_IMAGEDATA
);
413 ctn
->ctn_ThumbnailDataSize
= SQLite3ColumnBytes(pStmt
, COLUMN_THUMBNAIL_IMAGEDATA
);
415 d1(KPrintF("%s/%s/%ld: ctn_ThumbnailDataSize=%lu\n", __FILE__
, __FUNC__
, __LINE__
, ctn
->ctn_ThumbnailDataSize
));
417 if (ctn
->ctn_ThumbnailDataSize
)
419 ctn
->ctn_ThumbnailData
= ScalosAlloc(ctn
->ctn_ThumbnailDataSize
);
420 if (ctn
->ctn_ThumbnailData
)
421 memcpy(ctn
->ctn_ThumbnailData
, BlobData
, ctn
->ctn_ThumbnailDataSize
);
423 ctn
->ctn_ThumbnailDataSize
= 0;
429 /*rc =*/ SQLite3Finalize(pStmt
);
430 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
434 d1(KPrintF("%s/%s/%ld: END Found=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Found
));
436 return (BOOL
) (Found
&& ctn
->ctn_ThumbnailDataSize
);
439 //-----------------------------------------------------------------------
441 static BOOL
ThumbnailCacheDeleteEntry(sqlite3
*db
, CONST_STRPTR FileName
)
444 BOOL Success
= FALSE
;
446 d1(KPrintF("%s/%s/%ld: FileName=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, FileName
));
449 sqlite3_stmt
*pStmt
= NULL
;
450 CONST_STRPTR Tail
= NULL
;
451 static CONST_STRPTR Cmd
=
452 "DELETE " THUMBNAIL_TABLE_NAME
" "
453 "WHERE IconPath = :path;";
455 rc
= SQLite3PrepareV2(db
,
459 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
462 d1(KPrintF("%s/%s/%ld: SQLite3PrepareV2() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
467 rc
= SQLite3BindText(pStmt
, 1,
468 FileName
, strlen(FileName
),
470 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
475 rc
= SQLite3Step(pStmt
);
476 if (SQLITE_BUSY
== rc
)
478 } while (SQLITE_ROW
== rc
|| SQLITE_BUSY
== rc
);
480 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
481 if (SQLITE_DONE
!= rc
)
484 rc
= SQLite3Finalize(pStmt
);
485 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
492 d1(KPrintF("%s/%s/%ld: Success=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Success
));
497 //-----------------------------------------------------------------------
499 static BOOL
ThumbnailCacheUpdateEndOfLife(sqlite3
*db
, CONST_STRPTR FileName
, const T_TIMEVAL
*tv
)
502 BOOL Success
= FALSE
;
504 d1(KPrintF("%s/%s/%ld: FileName=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, FileName
));
507 CONST_STRPTR Tail
= NULL
;
508 sqlite3_stmt
*pStmt
= NULL
;
509 static CONST_STRPTR Cmd
=
510 "UPDATE " THUMBNAIL_TABLE_NAME
" "
511 "SET EndOfLife = :endoflife "
512 "WHERE IconPath = :path;";
514 rc
= SQLite3PrepareV2(db
,
518 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
521 d1(KPrintF("%s/%s/%ld: SQLite3PrepareV2() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
526 rc
= SQLite3BindInt(pStmt
, 1, tv
->tv_secs
);
527 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
532 rc
= SQLite3BindText(pStmt
, 2,
533 FileName
, strlen(FileName
),
535 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
540 rc
= SQLite3Step(pStmt
);
541 if (SQLITE_BUSY
== rc
)
543 } while (SQLITE_ROW
== rc
|| SQLITE_BUSY
== rc
);
545 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
546 if (SQLITE_DONE
!= rc
)
549 rc
= SQLite3Finalize(pStmt
);
550 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
557 d1(KPrintF("%s/%s/%ld: Success=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Success
));
562 //-----------------------------------------------------------------------
564 void ThumbnailCacheAddARGB(BPTR fLock
, APTR ThumbnailCacheHandle
,
565 const struct ARGBHeader
*argbh
, ULONG LifetimeDays
)
567 sqlite3
*db
= (sqlite3
*) ThumbnailCacheHandle
;
568 T_ExamineData
*fib
= NULL
;
569 STRPTR FileName
= NULL
;
570 UBYTE
*Buffer
= NULL
;
572 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
576 size_t ImageDataSize
;
580 break; // fail if thumbnail database is not available
582 if (!ScalosExamineBegin(&fib
))
585 if (!ScalosExamineLock(fLock
, &fib
))
588 FileName
= ThumbnailCacheGetFileNameFromLock(fLock
);
589 if (NULL
== FileName
)
592 ImageDataSize
= argbh
->argb_Width
* argbh
->argb_Height
* sizeof(struct ARGB
);
593 BuffLength
= sizeof(struct ARGBHeader
) + ImageDataSize
;
595 Buffer
= ScalosAlloc(BuffLength
);
599 memcpy(Buffer
, argbh
, sizeof(struct ARGBHeader
));
600 memcpy(Buffer
+ sizeof(struct ARGBHeader
), argbh
->argb_ImageData
, ImageDataSize
);
602 ThumbnailCacheAddEntry(db
, FileName
,
603 ScalosExamineGetDate(fib
), 24,
604 Buffer
, BuffLength
, LifetimeDays
);
610 FreePathBuffer(FileName
);
611 ScalosExamineEnd(&fib
);
613 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
616 //-----------------------------------------------------------------------
618 void ThumbnailCacheAddRemapped(BPTR fLock
, APTR ThumbnailCacheHandle
,
619 const struct ScalosBitMapAndColor
*sac
, ULONG LifetimeDays
)
621 sqlite3
*db
= (sqlite3
*) ThumbnailCacheHandle
;
622 T_ExamineData
*fib
= NULL
;
623 STRPTR FileName
= NULL
;
624 UBYTE
*Buffer
= NULL
;
625 struct RastPort TempRp
;
627 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
629 memset(&TempRp
, 0, sizeof(TempRp
));
633 size_t PixelArrayLength
;
634 size_t ColorTableLength
;
635 struct RastPort SrcRp
;
639 break; // fail if thumbnail database is not available
641 if (!ScalosExamineBegin(&fib
))
644 if (!ScalosExamineLock(fLock
, &fib
))
647 FileName
= ThumbnailCacheGetFileNameFromLock(fLock
);
648 if (NULL
== FileName
)
651 ColorTableLength
= 3 * sizeof(ULONG
) * sac
->sac_NumColors
;
652 PixelArrayLength
= PIXELARRAY8_BUFFERSIZE(sac
->sac_Width
, sac
->sac_Height
);
653 BuffLength
= sizeof(struct ScalosBitMapAndColor
)
654 + PixelArrayLength
+ ColorTableLength
;
656 Buffer
= ScalosAlloc(BuffLength
);
660 InitRastPort(&SrcRp
);
661 SrcRp
.BitMap
= (struct BitMap
*) sac
->sac_BitMap
;
663 memcpy(Buffer
, sac
, sizeof(struct ScalosBitMapAndColor
));
665 InitRastPort(&TempRp
);
666 TempRp
.BitMap
= AllocBitMap(TEMPRP_WIDTH(sac
->sac_Width
), 1, 8, 0, NULL
);
667 if (NULL
== TempRp
.BitMap
)
670 // Blit BitMap data to buffer
671 ReadPixelArray8(&SrcRp
,
673 sac
->sac_Width
- 1, sac
->sac_Height
- 1,
674 Buffer
+ sizeof(struct ScalosBitMapAndColor
),
677 // Copy ColorTable to buffer
678 ColorTable
= (ULONG
*) (Buffer
+ sizeof(struct ScalosBitMapAndColor
) + PixelArrayLength
);
679 memcpy(ColorTable
, sac
->sac_ColorTable
, ColorTableLength
);
681 ThumbnailCacheAddEntry(db
, FileName
,
682 ScalosExamineGetDate(fib
), sac
->sac_Depth
,
683 Buffer
, BuffLength
, LifetimeDays
);
688 FreeBitMap(TempRp
.BitMap
);
689 TempRp
.BitMap
= NULL
;
694 FreePathBuffer(FileName
);
695 ScalosExamineEnd(&fib
);
697 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
700 //-----------------------------------------------------------------------
702 BOOL
ThumbnailCacheFindARGB(BPTR fLock
, APTR ThumbnailCacheHandle
,
703 struct ARGBHeader
*argbh
, ULONG LifetimeDays
)
705 sqlite3
*db
= (sqlite3
*) ThumbnailCacheHandle
;
706 T_ExamineData
*fib
= NULL
;
707 STRPTR FileName
= NULL
;
708 struct CachedThumbnail ctn
;
710 BOOL ShouldDeleteEntry
= FALSE
;
712 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
715 memset(&ctn
, 0, sizeof(ctn
));
719 size_t ImageDataSize
;
722 break; // fail if thumbnail database is not available
724 FileName
= ThumbnailCacheGetFileNameFromLock(fLock
);
725 if (NULL
== FileName
)
728 if (!ScalosExamineBegin(&fib
))
731 if (!ScalosExamineLock(fLock
, &fib
))
734 if (!ThumbnailCacheFindEntry(db
, FileName
, &ctn
, LifetimeDays
))
737 if (0 == ctn
.ctn_ThumbnailDataSize
|| NULL
== ctn
.ctn_ThumbnailData
)
740 // check if we have an ARGB thumbnail here
741 d1(KPrintF("%s/%s/%ld: ThumbnailDepth=%lu\n", __FILE__
, __FUNC__
, __LINE__
, ctn
.ctn_ThumbnailDepth
));
742 if (ctn
.ctn_ThumbnailDepth
!= 24)
745 if (ctn
.ctn_prefWidth
!= CurrentPrefs
.pref_ThumbNailWidth
746 || ctn
.ctn_prefHeight
!= CurrentPrefs
.pref_ThumbNailHeight
)
748 // Cached thumbnail size doesn't match current settings
749 // mark it for deletion
750 ShouldDeleteEntry
= TRUE
;
751 d1(KPrintF("%s/%s/%ld: width/height mismatch w=%lu h=%lu\n", \
752 __FILE__
, __FUNC__
, __LINE__
, ctn
.ctn_prefWidth
, ctn
.ctn_prefHeight
));
756 if (0 != CompareDates(&ctn
.ctn_FileDate
, ScalosExamineGetDate(fib
)))
758 // cache entry is outdated
759 // mark it for deletion
760 d1(KPrintF("%s/%s/%ld: FileDate mismatch\n", __FILE__
, __FUNC__
, __LINE__
));
761 ShouldDeleteEntry
= TRUE
;
766 memcpy(argbh
, ctn
.ctn_ThumbnailData
, sizeof(struct ARGBHeader
));
768 // allocate ARGB image data
769 argbh
->argb_ImageData
= ScalosGfxCreateARGB(argbh
->argb_Width
, argbh
->argb_Height
, NULL
);
770 if (NULL
== argbh
->argb_ImageData
)
773 ImageDataSize
= argbh
->argb_Width
* argbh
->argb_Height
* sizeof(struct ARGB
);
776 memcpy(argbh
->argb_ImageData
, ctn
.ctn_ThumbnailData
+ sizeof(struct ARGBHeader
), ImageDataSize
);
778 // Check if database entry access date should be updated
779 // Since updating takes time, entries are updated no more than once a day.
780 ThumbnailCacheGetEndOfLife(&tv
, LifetimeDays
);
782 d1(KPrintF("%s/%s/%ld: tv_secs=%lu ctn_EndOfLife=%lu\n", \
783 __FILE__
, __FUNC__
, __LINE__
, tv
.tv_secs
, ctn
.ctn_EndOfLife
));
785 if (!ThumbnailCacheIsSameDay(tv
.tv_secs
, ctn
.ctn_EndOfLife
))
786 ThumbnailCacheUpdateEndOfLife(db
, FileName
, &tv
);
791 if (FileName
&& ShouldDeleteEntry
)
792 ThumbnailCacheDeleteEntry(db
, FileName
);
794 if (ctn
.ctn_ThumbnailData
)
795 ScalosFree(ctn
.ctn_ThumbnailData
);
797 FreePathBuffer(FileName
);
798 ScalosExamineEnd(&fib
);
800 d1(KPrintF("%s/%s/%ld: END Found=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Found
));
805 //-----------------------------------------------------------------------
807 struct ScalosBitMapAndColor
*ThumbnailCacheFindRemapped(BPTR fLock
,
808 APTR ThumbnailCacheHandle
, ULONG LifetimeDays
)
810 sqlite3
*db
= (sqlite3
*) ThumbnailCacheHandle
;
811 struct RastPort TempRp
;
812 T_ExamineData
*fib
= NULL
;
813 STRPTR FileName
= NULL
;
815 BOOL ShouldDeleteEntry
= FALSE
;
816 struct CachedThumbnail ctn
;
817 struct ScalosBitMapAndColor
*newsac
= NULL
;
819 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
822 memset(&TempRp
, 0, sizeof(TempRp
));
823 memset(&ctn
, 0, sizeof(ctn
));
827 size_t ColorTableLength
;
828 size_t PixelArrayLength
;
829 const UBYTE
*PixelArray
;
830 const ULONG
*ColorTable
;
831 struct RastPort DestRp
;
832 struct ScalosBitMapAndColor sac
;
834 memset(&sac
, 0, sizeof(struct ScalosBitMapAndColor
));
837 break; // fail if thumbnail database is not available
839 InitRastPort(&DestRp
);
841 FileName
= ThumbnailCacheGetFileNameFromLock(fLock
);
842 if (NULL
== FileName
)
845 if (!ScalosExamineBegin(&fib
))
848 if (!ScalosExamineLock(fLock
, &fib
))
851 if (!ThumbnailCacheFindEntry(db
, FileName
, &ctn
, LifetimeDays
))
854 if (0 == ctn
.ctn_ThumbnailDataSize
|| NULL
== ctn
.ctn_ThumbnailData
)
857 // check if we have a SAC thumbnail here
858 d1(KPrintF("%s/%s/%ld: ThumbnailDepth=%lu\n", __FILE__
, __FUNC__
, __LINE__
, ctn
.ctn_ThumbnailDepth
));
859 if (ctn
.ctn_ThumbnailDepth
> 8)
862 if (ctn
.ctn_prefWidth
!= CurrentPrefs
.pref_ThumbNailWidth
863 || ctn
.ctn_prefHeight
!= CurrentPrefs
.pref_ThumbNailHeight
)
865 // Cached thumbnail size doesn't match current settings
866 // mark it for deletion
867 ShouldDeleteEntry
= TRUE
;
868 d1(KPrintF("%s/%s/%ld: width/height mismatch w=%lu h=%lu\n", \
869 __FILE__
, __FUNC__
, __LINE__
, ctn
.ctn_prefWidth
, ctn
.ctn_prefHeight
));
873 if (0 != CompareDates(&ctn
.ctn_FileDate
, ScalosExamineGetDate(fib
)))
875 // cache entry is outdated
876 // mark it for deletion
877 d1(KPrintF("%s/%s/%ld: FileDate mismatch\n", __FILE__
, __FUNC__
, __LINE__
));
878 ShouldDeleteEntry
= TRUE
;
882 // copy ScalosBitMapAndColor
883 memcpy(&sac
, ctn
.ctn_ThumbnailData
, sizeof(struct ScalosBitMapAndColor
));
885 d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld Depth=%ld TransparentColor=%ld NumColors=%ld\n", \
886 __FILE__
, __FUNC__
, __LINE__
, sac
.sac_Width
, sac
.sac_Height
, sac
.sac_Depth
, \
887 sac
.sac_TransparentColor
, sac
.sac_NumColors
));
889 ColorTableLength
= 3 * sizeof(ULONG
) * sac
.sac_NumColors
;
890 PixelArrayLength
= PIXELARRAY8_BUFFERSIZE(sac
.sac_Width
, sac
.sac_Height
);
892 PixelArray
= ctn
.ctn_ThumbnailData
+ sizeof(struct ScalosBitMapAndColor
);
893 ColorTable
= (ULONG
*) (ctn
.ctn_ThumbnailData
+ sizeof(struct ScalosBitMapAndColor
) + PixelArrayLength
);
895 d1(KPrintF("%s/%s/%ld: PixelArray=%08lx ColorTable=%08lx\n", \
896 __FILE__
, __FUNC__
, __LINE__
, PixelArray
, ColorTable
));
897 d1(KPrintF("%s/%s/%ld: PixelArrayLength=%lu ColorTableLength=%lu\n", \
898 __FILE__
, __FUNC__
, __LINE__
, PixelArrayLength
, ColorTableLength
));
900 newsac
= ScalosGfxCreateSAC(sac
.sac_Width
, sac
.sac_Height
, sac
.sac_Depth
, NULL
, NULL
);
901 d1(KPrintF("%s/%s/%ld: newsac=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, newsac
));
905 newsac
->sac_TransparentColor
= sac
.sac_TransparentColor
;
907 // Copy data into colortable
908 memcpy(newsac
->sac_ColorTable
, ColorTable
, ColorTableLength
);
910 // Initialize temporary RastPort
911 InitRastPort(&TempRp
);
912 TempRp
.BitMap
= AllocBitMap(TEMPRP_WIDTH(newsac
->sac_Width
), 1, 8, 0, NULL
);
913 if (NULL
== TempRp
.BitMap
)
916 d1(KPrintF("%s/%s/%ld: TempRp.BitMap=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, TempRp
.BitMap
));
918 // Blit image data to BitMap
919 DestRp
.BitMap
= newsac
->sac_BitMap
;
920 WritePixelArray8(&DestRp
,
922 newsac
->sac_Width
- 1, newsac
->sac_Height
- 1,
923 (UBYTE
*) PixelArray
,
926 // Check if database entry access date should be updated
927 // Since updating takes time, entries are updated only once a day.
928 ThumbnailCacheGetEndOfLife(&tv
, LifetimeDays
);
930 d1(KPrintF("%s/%s/%ld: tv_secs=%lu ctn_EndOfLife=%lu\n", \
931 __FILE__
, __FUNC__
, __LINE__
, tv
.tv_secs
, ctn
.ctn_EndOfLife
));
933 if (!ThumbnailCacheIsSameDay(tv
.tv_secs
, ctn
.ctn_EndOfLife
))
934 ThumbnailCacheUpdateEndOfLife(db
, FileName
, &tv
);
940 if (FileName
&& ShouldDeleteEntry
)
941 ThumbnailCacheDeleteEntry(db
, FileName
);
944 FreeBitMap(TempRp
.BitMap
);
945 if (ctn
.ctn_ThumbnailData
)
946 ScalosFree(ctn
.ctn_ThumbnailData
);
948 FreePathBuffer(FileName
);
949 ScalosExamineEnd(&fib
);
953 // cleanup allocated newsac if not found
954 ScalosGfxFreeSAC(newsac
);
958 d1(KPrintF("%s/%s/%ld: END Found=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Found
));
963 //-----------------------------------------------------------------------
965 static STRPTR
ThumbnailCacheGetFileNameFromLock(BPTR fLock
)
969 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
972 FileName
= AllocPathBuffer();
975 if (!NameFromLock(fLock
, FileName
, Max_PathLen
))
977 FreePathBuffer(FileName
);
982 d1(KPrintF("%s/%s/%ld: END FileName=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, FileName
));
987 //-----------------------------------------------------------------------
989 static BOOL
ThumbnailCacheIsSameDay(ULONG sec1
, ULONG sec2
)
991 return (BOOL
) (abs(sec1
- sec2
) <= 60 * 60 * 24);
994 //-----------------------------------------------------------------------
996 BOOL
ThumbnailCacheRemoveEntry(BPTR DirLock
, CONST_STRPTR FileName
)
998 APTR ThumbnailCacheHandle
;
999 BOOL Success
= FALSE
;
1002 d1(KPrintF("%s/%s/%ld: START FileName=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, FileName
));
1007 FullPath
= AllocPathBuffer();
1008 if (NULL
== FullPath
)
1011 if (!ThumbnailCacheOpen(&ThumbnailCacheHandle
))
1014 db
= (sqlite3
*) ThumbnailCacheHandle
;
1018 if (!NameFromLock(DirLock
, FullPath
, Max_PathLen
))
1021 if (!AddPart(FullPath
, FileName
, Max_PathLen
))
1024 Success
= ThumbnailCacheDeleteEntry(db
, FullPath
);
1028 FreePathBuffer(FullPath
);
1030 ThumbnailCacheClose(&ThumbnailCacheHandle
);
1032 d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Success
));
1037 //-----------------------------------------------------------------------
1039 // Cleanup thumbnail cache -- remove all entries that
1040 // have not been accessed for a defined time.
1042 BOOL
ThumbnailCacheCleanup(APTR ThumbnailCacheHandle
)
1044 sqlite3
*db
= (sqlite3
*) ThumbnailCacheHandle
;
1045 sqlite3_stmt
*pStmt
= NULL
;
1046 int rc
= SQLITE_DONE
;
1048 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
1052 CONST_STRPTR Tail
= NULL
;
1054 static CONST_STRPTR SelectCmd
=
1055 "DELETE FROM " THUMBNAIL_TABLE_NAME
" "
1056 "WHERE EndOfLife < :accessdate OR NOT FILEXISTS(IconPath);";
1059 break; // fail if thumbnail database is not available
1061 d1(KPrintF("%s/%s/%ld: db=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, db
));
1063 rc
= SQLite3ExtendedResultCodes(db
, TRUE
);
1064 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1065 if (SQLITE_OK
!= rc
)
1067 d1(KPrintF("%s/%s/%ld: SQLite3ExtendedResultCodes() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
1071 // Delete old V1 table if exists
1072 /* rc = */SQLite3Exec(db
,
1073 "DROP TABLE IF EXISTS " THUMBNAIL_TABLE_NAME_OLD
";",
1077 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1081 // Register custom "FILEEXISTS" function
1082 rc
= SQLite3CreateFunction(db
,
1087 ThumbnailCacheFileExists
,
1090 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1091 if (SQLITE_OK
!= rc
)
1093 d1(KPrintF("%s/%s/%ld: SQLite3CreateFunction() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
1097 rc
= SQLite3PrepareV2(db
,
1098 SelectCmd
, strlen(SelectCmd
),
1101 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1102 if (SQLITE_OK
!= rc
)
1104 d1(KPrintF("%s/%s/%ld: SQLite3PrepareV2() failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
1108 rc
= SQLite3BindInt(pStmt
, 1, tv
.tv_secs
);
1109 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1110 if (SQLITE_OK
!= rc
)
1114 rc
= SQLite3Step(pStmt
);
1115 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1116 if (SQLITE_BUSY
== rc
)
1118 } while (SQLITE_ROW
== rc
|| SQLITE_BUSY
== rc
);
1120 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1121 if (SQLITE_DONE
!= rc
)
1124 rc
= SQLite3Finalize(pStmt
);
1125 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1126 if (SQLITE_OK
!= rc
)
1131 // Check how many records have been deleted
1132 Changes
= SQLite3Changes(db
);
1133 d1(KPrintF("%s/%s/%ld: Changes=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Changes
));
1138 // If records have been deleted, compress the database now
1140 rc
= SQLite3Exec(db
,
1145 if (SQLITE_DONE
!= rc
&& SQLITE_OK
!= rc
)
1147 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1148 d1(KPrintF("%s/%s/%ld: VACUUM failed: <%s>\n", __FILE__
, __FUNC__
, __LINE__
, SQLite3Errmsg(db
)));
1155 /*rc =*/ SQLite3Finalize(pStmt
);
1156 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1160 d1(KPrintF("%s/%s/%ld: END rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1162 return (BOOL
) (SQLITE_DONE
== rc
|| SQLITE_OK
== rc
);
1165 //-----------------------------------------------------------------------
1167 static int ThumbnailCacheSetMode(sqlite3
*db
)
1171 d1(KPrintF("%s/%s/%ld: START db=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, db
));
1174 rc
= SQLite3Exec(db
,
1175 "PRAGMA journal_mode=wal;",
1179 d1(KPrintF("%s/%s/%ld: PRAGMA journal_mode=wal returns rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1180 if (SQLITE_DONE
!= rc
&& SQLITE_OK
!= rc
)
1183 rc
= SQLite3EnableSharedCache(TRUE
);
1184 d1(KPrintF("%s/%s/%ld: SQLite3EnableSharedCache() returns rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1185 if (SQLITE_DONE
!= rc
&& SQLITE_OK
!= rc
)
1190 d1(KPrintF("%s/%s/%ld: END rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1196 //-----------------------------------------------------------------------
1198 static int ThumbnailCacheCreateTable(sqlite3
*db
)
1202 d1(KPrintF("%s/%s/%ld: START db=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, db
));
1205 rc
= SQLite3Exec(db
,
1206 "CREATE TABLE IF NOT EXISTS " THUMBNAIL_TABLE_NAME
"("
1207 "EndOfLife integer DEFAULT CURRENT_DATESTAMP,"
1208 "IconPath text PRIMARY KEY UNIQUE ON CONFLICT REPLACE,"
1209 "ThumbnailDepth integer,"
1210 "PrefThumbnailWidth integer,"
1211 "PrefThumbnailHeight integer,"
1218 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1219 if (SQLITE_DONE
!= rc
&& SQLITE_OK
!= rc
)
1222 rc
= SQLite3Exec(db
,
1223 "CREATE INDEX IF NOT EXISTS EolIndex "
1224 "ON " THUMBNAIL_TABLE_NAME
"(EndOfLife);",
1228 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1229 if (SQLITE_DONE
!= rc
&& SQLITE_OK
!= rc
)
1232 rc
= SQLite3Exec(db
,
1233 "CREATE UNIQUE INDEX IF NOT EXISTS PathIndex "
1234 "ON " THUMBNAIL_TABLE_NAME
"(IconPath);",
1238 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1239 if (SQLITE_DONE
!= rc
&& SQLITE_OK
!= rc
)
1243 d1(KPrintF("%s/%s/%ld: END rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1248 //-----------------------------------------------------------------------
1250 BOOL
ThumbnailCacheBegin(APTR ThumbnailCacheHandle
)
1253 sqlite3
*db
= (sqlite3
*) ThumbnailCacheHandle
;
1254 int rc
= SQLITE_DONE
;
1256 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
1257 if (SQLite3Base
&& db
)
1259 rc
= SQLite3Exec(db
,
1260 "BEGIN DEFERRED TRANSACTION;",
1265 d1(KPrintF("%s/%s/%ld: END rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1267 return (BOOL
) (SQLITE_DONE
== rc
|| SQLITE_OK
== rc
);
1273 //-----------------------------------------------------------------------
1275 BOOL
ThumbnailCacheFinish(APTR ThumbnailCacheHandle
)
1278 sqlite3
*db
= (sqlite3
*) ThumbnailCacheHandle
;
1279 int rc
= SQLITE_DONE
;
1281 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
1283 if (SQLite3Base
&& db
)
1285 rc
= SQLite3Exec(db
,
1290 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1293 d1(KPrintF("%s/%s/%ld: END rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1295 return (BOOL
) (SQLITE_DONE
== rc
|| SQLITE_OK
== rc
);
1301 //-----------------------------------------------------------------------
1303 static void ThumbnailCacheGetEndOfLife(T_TIMEVAL
*tv
, ULONG LifetimeDays
)
1307 tv
->tv_secs
+= 24 * 60 * 60 * LifetimeDays
;
1309 tv
->tv_secs
= ULONG_MAX
; // forever
1312 //-----------------------------------------------------------------------
1314 static void ThumbnailCacheFileExists(sqlite3_context
*context
, LONG x
, sqlite3_value
**pVal
)
1316 BOOL fileExists
= FALSE
;
1319 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
1323 Path
= SQLite3ValueText(*pVal
);
1324 d1(KPrintF("%s/%s/%ld: Path=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, Path
? Path
: (CONST_STRPTR
) ""));
1326 if (Path
&& strlen(Path
) > 0)
1330 fLock
= Lock(Path
, ACCESS_READ
);
1331 d1(KPrintF("%s/%s/%ld: fLock=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, fLock
));
1339 LONG ErrCode
= IoErr();
1341 if (ERROR_DEVICE_NOT_MOUNTED
== ErrCode
)
1346 SQLite3ResultInt(context
, fileExists
);
1348 d1(KPrintF("%s/%s/%ld: END fileExists=%ld\n", __FILE__
, __FUNC__
, __LINE__
, fileExists
));
1351 //-----------------------------------------------------------------------
1353 static int ThumbnailCacheSetTempDir(sqlite3
*db
, CONST_STRPTR DirName
)
1358 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
1362 static CONST_STRPTR Cmd
=
1363 "PRAGMA temp_store_directory = \"%s\";";
1365 Length
= 1 + strlen(Cmd
) + strlen(DirName
);
1367 CmdStr
= ScalosAlloc(Length
);
1374 snprintf(CmdStr
, Length
, Cmd
, DirName
);
1376 rc
= SQLite3Exec(db
,
1381 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1387 d1(KPrintF("%s/%s/%ld: END rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1392 //-----------------------------------------------------------------------