Search code examples
c++sqlitecompressionzlib

Cannot decompress a compressed string selected from an sql table using sqlite3 and C++


Description

I am trying to insert compressed data into an sql table, then extract and decompress it. At first I compress a string then insert it into a table (section 1). Compression works fine. Even When I try to decompress it before insertion I get the string back. The problem comes after inserting the string and trying to extract it back later on.

As you can see in section 2 of the code. The decompression doesn't work anymore. I don't know why it doesn't work anymore after I extract it from the table.


Source code

#include <zlc/zlibcomplete.hpp>
#include <string>
#include "3rdparty/sqlite_modern_cpp.h"

using namespace std;
using namespace zlibcomplete;

int main()
{
   //SECTION 1
   database db("data.db");
   db << "CREATE TABLE IF NOT EXISTS paragraph(ID INTEGER PRIMARY KEY, LINE TEXT);";
   string line = "hello world!";
   //Compress string by using zlib
   GZipCompressor compressor(9, auto_flush);
   string compressed_line = compressor.compress(line);
   compressor.finish();
   
   //IF I DECOMPRESS STRING HERE IT WORKS FINE!!!
   GZipDecompressor decompressor;
   string output = decompressor.decompress(line);
  
   //insert compressed string into table paragraph
   db <<"insert into paragraph(ID,LINE) VALUES (?,?);"
      << 1
      << compressed_line;


  //SECTION 2: Problem starts here where I try to return the compressed value
   db <<"select line from paragraph where id = ?;"
      << "1"
      >>[&](string line)
      {
        //Decompress string by using zlib
        GZipDecompressor decompressor;
        string output = decompressor.decompress(line);
        //out is empty I don't know why???
        cout << output  << endl;
      }; 
   return 0;
}

Update after correction

First download base64 classes as pointed out in this solution.

#include <zlc/zlibcomplete.hpp>
#include <string>
#include "3rdparty/sqlite_modern_cpp.h"
#include "base64.h"

using namespace std;
using namespace zlibcomplete;

int main()
{
   //SECTION 1
   database db("data.db");
   db << "CREATE TABLE IF NOT EXISTS paragraph(ID INTEGER PRIMARY KEY, LINE TEXT);";
   string line = "hello world!";
   //Compress string by using zlib
   GZipCompressor compressor(9, auto_flush);
   string compressed_line = compressor.compress(line);
   compressor.finish();
  std::string compressed = base64_encode(reinterpret_cast<const unsigned char*>(compressed_line.c_str()), compressed_line.length());
  
   //insert compressed string into table paragraph
   db <<"insert into paragraph(ID,LINE) VALUES (?,?);"
      << 1
      << compressed;


   db <<"select line from paragraph where id = ?;"
      << "1"
      >>[&](string line)
      {
        //decode HERE
        std::string compressed_decoded = base64_decode(line);
        //Decompress string by using zlib
        GZipDecompressor decompressor;
        string output = decompressor.decompress(line);
        cout << output  << endl;
      }; 
   return 0;
}

Solution

  • Your code is unable to handle zeros in the compressed string. If the compressed string has a character 0 then text gets truncated and is no longer possible to make the reverse operation.