3131#include <string.h>
3232#include <apr_getopt.h>
3333#include <apr_pools.h>
34+ #include <apr_time.h>
35+ #include <apr_date.h>
36+ #include <apr_strings.h>
3437#include "lmdb.h"
3538
3639void fail (const char * msg , int rc ) {
@@ -41,6 +44,7 @@ void fail(const char *msg, int rc) {
4144static const apr_getopt_option_t options [] = {
4245 { "dbpath" , 'd' , TRUE, "Path to the LMDB database directory" },
4346 { "summary" , 's' , FALSE, "Print only the total number of keys" },
47+ { "extended" , 'e' , FALSE, "Show extended info (timestamp, size)" },
4448 { "help" , 'h' , FALSE, "Show help" },
4549 { NULL , 0 , 0 , NULL }
4650};
@@ -77,6 +81,7 @@ int main(int argc, const char * const *argv) {
7781 MDB_dbi dbi ;
7882 MDB_val value ;
7983 int summary_flag = 0 ;
84+ int extended_flag = 0 ;
8085 MDB_stat stat ;
8186 apr_pool_t * pool = NULL ;
8287 apr_getopt_t * opt ;
@@ -98,6 +103,9 @@ int main(int argc, const char * const *argv) {
98103 case 's' :
99104 summary_flag = 1 ;
100105 break ;
106+ case 'e' :
107+ extended_flag = 1 ;
108+ break ;
101109 }
102110 }
103111
@@ -154,7 +162,50 @@ int main(int argc, const char * const *argv) {
154162
155163 // Iterate over keys
156164 while ((rc = mdb_cursor_get (cursor , & key , & value , MDB_NEXT )) == 0 ) {
157- fwrite (key .mv_data , 1 , key .mv_size , stdout );
165+ // Print the key itself, without the null terminator
166+ fwrite (key .mv_data , 1 , key .mv_size - 1 , stdout );
167+
168+ if (extended_flag ) {
169+ apr_time_t timestamp ;
170+ size_t data_size ;
171+
172+ // Check for special blank tile encoding ('#' marker)
173+ if (value .mv_size > 1 && ((char * )value .mv_data )[0 ] == '#' ) {
174+ if (value .mv_size == 5 + sizeof (apr_time_t )) {
175+ memcpy (& timestamp , (char * )value .mv_data + 5 , sizeof (apr_time_t ));
176+ data_size = 4 ; // RGBA color
177+ } else {
178+ // Unexpected size, cannot parse
179+ timestamp = 0 ;
180+ data_size = 0 ;
181+ }
182+ } else if (value .mv_size >= sizeof (apr_time_t )) {
183+ // Regular tile data
184+ data_size = value .mv_size - sizeof (apr_time_t );
185+ memcpy (& timestamp , (char * )value .mv_data + data_size , sizeof (apr_time_t ));
186+ } else {
187+ // Data is too small, cannot parse
188+ timestamp = 0 ;
189+ data_size = value .mv_size ;
190+ }
191+
192+ if (timestamp > 0 ) {
193+ apr_time_exp_t exploded_time ;
194+ char iso_time_str [30 ];
195+ apr_time_exp_gmt (& exploded_time , timestamp );
196+ apr_snprintf (iso_time_str , sizeof (iso_time_str ),
197+ "%d-%02d-%02dT%02d:%02d:%02dZ" ,
198+ exploded_time .tm_year + 1900 ,
199+ exploded_time .tm_mon + 1 ,
200+ exploded_time .tm_mday ,
201+ exploded_time .tm_hour ,
202+ exploded_time .tm_min ,
203+ exploded_time .tm_sec );
204+ printf (",%s,%zu" , iso_time_str , data_size );
205+ } else {
206+ printf (",,%zu" , data_size ); // Print size even if timestamp is unknown
207+ }
208+ }
158209 printf ("\n" );
159210 }
160211
0 commit comments