content_db_to_berkeley_db_btree.pl 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #!/usr/bin/perl
  2. # Author: Trizen
  3. # Date: 03 April 2023
  4. # https://github.com/trizen
  5. # Convert a GDBM database to a Berkeley database, and use JSON for encoding in order to make it portable.
  6. use 5.036;
  7. use DB_File;
  8. use GDBM_File;
  9. no warnings 'once';
  10. use JSON::XS qw(encode_json);
  11. use Storable qw(thaw);
  12. use constant {
  13. # Compress the values of the content database with Zstandard.
  14. # When enabled, the content database will be ~3x smaller.
  15. USE_ZSTD => 1,
  16. };
  17. scalar(@ARGV) == 2 or die "usage: $0 [input.dbm] [output.dbm]";
  18. my $input_file = $ARGV[0];
  19. my $output_file = $ARGV[1];
  20. if (not -f $input_file) {
  21. die "Input file <<$input_file>> does not exist!\n";
  22. }
  23. if (-e $output_file) {
  24. die "Output file <<$output_file>> already exists!\n";
  25. }
  26. tie(my %input, 'GDBM_File', $input_file, &GDBM_READER, 0555)
  27. or die "Can't access database <<$input_file>>: $!";
  28. tie(my %output, 'DB_File', $output_file, O_CREAT | O_RDWR, 0666, $DB_BTREE)
  29. or die "Can't create database <<$output_file>>: $!";
  30. if (USE_ZSTD) {
  31. require IO::Compress::Zstd;
  32. require IO::Uncompress::UnZstd;
  33. }
  34. sub zstd_encode ($data) {
  35. IO::Compress::Zstd::zstd(\$data, \my $zstd_data)
  36. or die "zstd failed: $IO::Compress::Zstd::ZstdError\n";
  37. return $zstd_data;
  38. }
  39. sub zstd_decode ($zstd_data) {
  40. IO::Uncompress::UnZstd::unzstd(\$zstd_data, \my $decoded_data)
  41. or die "unzstd failed: $IO::Uncompress::UnZstd::UnZstdError\n";
  42. return $decoded_data;
  43. }
  44. sub decode_content_entry ($entry) {
  45. my $data = $entry;
  46. if (USE_ZSTD) {
  47. $data = zstd_decode($data);
  48. }
  49. return thaw($data);
  50. }
  51. sub encode_content_entry ($entry) {
  52. my $data = encode_json($entry);
  53. if (USE_ZSTD) {
  54. $data = zstd_encode($data);
  55. }
  56. return $data;
  57. }
  58. while (my ($key, $value) = each %input) {
  59. $output{$key} = encode_content_entry(decode_content_entry($value));
  60. }
  61. untie(%input);
  62. untie(%output);